aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHugo Hörnquist <hugo@lysator.liu.se>2019-02-06 12:08:58 +0100
committerHugo Hörnquist <hugo@lysator.liu.se>2019-02-06 12:08:58 +0100
commitaf3cc906185d7273cf82b1339b63843062898120 (patch)
tree01d9cff85d6c4dfee3185a2402745d721f3636e8
parentRemove GC. (diff)
downloadcalp-af3cc906185d7273cf82b1339b63843062898120.tar.gz
calp-af3cc906185d7273cf82b1339b63843062898120.tar.xz
Code cleanup and add documentation.
-rw-r--r--err.h2
-rw-r--r--linked_list.h6
-rw-r--r--linked_list.inc.h3
-rw-r--r--macro.h28
-rw-r--r--main.c2
-rw-r--r--parse.c38
-rw-r--r--parse.h3
-rw-r--r--strbuf.c12
-rw-r--r--strbuf.h22
-rw-r--r--trie.h5
-rw-r--r--trie.inc.h2
-rw-r--r--vcal.c24
-rw-r--r--vcal.h9
13 files changed, 102 insertions, 54 deletions
diff --git a/err.h b/err.h
index 5689721b..eda79fee 100644
--- a/err.h
+++ b/err.h
@@ -2,8 +2,10 @@
#define ERR_H
#include <stdio.h>
+
#define RED "\x1B[0;31m"
#define RESET "\x1b[m"
+
#define ERR(msg) fprintf(stderr, RED "ERR" RESET " (%s:%i) %s\n", __FILE__, __LINE__, #msg)
#define ERR_F(fmt, ...) fprintf(stderr, RED "ERR" RESET " (%s:%i) " fmt "\n", \
__FILE__, __LINE__, ##__VA_ARGS__)
diff --git a/linked_list.h b/linked_list.h
index 515fa4af..5f9e2711 100644
--- a/linked_list.h
+++ b/linked_list.h
@@ -26,6 +26,12 @@ typedef struct {
#define LAST(lst) (lst)->tail->before
INIT_F ( LLIST(TYPE) );
+
+/*
+ * NOTE freeing a linked list alsa FFREE's all its contents.
+ * TODO some form of shared pointer to ensure nothing is free'd twice
+ * would be a good idea.
+ */
FREE_F ( LLIST(TYPE) );
INIT_F ( LINK(TYPE) );
diff --git a/linked_list.inc.h b/linked_list.inc.h
index 1522a685..e91cdc9f 100644
--- a/linked_list.inc.h
+++ b/linked_list.inc.h
@@ -17,15 +17,12 @@ INIT_F ( LLIST(TYPE) ) {
FREE_F (LINK(TYPE)) {
if (this->before != NULL) this->before->after = NULL;
if (this->after != NULL) this->after->before = NULL;
- // TODO how much of value do I really wanna free?
- // Should I implement some form of shared pointer?
if (this->value != NULL) FFREE(TYPE, this->value);
return 0;
}
FREE_F( LLIST(TYPE) ) {
-
LINK(TYPE) *n, *next;
n = this->head;
while ( n != NULL ) {
diff --git a/macro.h b/macro.h
index dbf4e355..b48a004e 100644
--- a/macro.h
+++ b/macro.h
@@ -24,9 +24,17 @@
#define VA_ARGS_NUM(...) VA_ARGS_NUM_PRIV(-1, ## __VA_ARGS__, 5, 4, 3, 2, 1, 0)
/*
- * Templetize
- * TODO actuall documentatino
- * ᐸElementTᐳ
+ * Templatization macros. Forms symbols on the from name<T>, which
+ * looks really good in debuggers and the like. Unicode characters
+ * written in \U notation since C apparently doesn't support unicode
+ * literals.
+ *
+ * Can be nested (useful for container types).
+ *
+ * Doesn't use ASCII <>, but rather some other ᐸᐳ, meaning that it's
+ * not a reserved character.
+ *
+ * nameᐸTᐳ
*/
#define TEMPL(name, T) TP4(name, \U00001438 , T, \U00001433 )
#define TEMPL_N(name, T, argcount) TP6(name, \U00001438 , T, _, argcount, \U00001433 )
@@ -38,7 +46,11 @@
#define INIT_F(T, ...) \
int __INIT_T(T, VA_ARGS_NUM(__VA_ARGS__)) (T* this __VA_OPT__(,) __VA_ARGS__)
-/* Call the constructor of an object */
+/*
+ * Call the constructor of an object
+ * `int` part of the macro, to ensure that any attempt to call this
+ * function results in an error.
+ */
#define INIT(T, N, ...) \
__INIT_T(T, VA_ARGS_NUM(__VA_ARGS__)) (N __VA_OPT__(,) __VA_ARGS__)
@@ -47,6 +59,9 @@
T* N = malloc(sizeof(*N)); \
INIT(T, N, __VA_ARGS__);
+/*
+ * Reconstructs a object. Use with caution.
+ */
#define RENEW(T, N, ...) do { \
N = malloc(sizeof(*N)); \
INIT(T, N, __VA_ARGS__); \
@@ -67,6 +82,11 @@
/* Declare destructor */
#define FREE_F(T) int FREE(T) (T* this)
+/*
+ * General functions that different container types may implement.
+ * Actuall implementation and type signature is mostly left to
+ * individual implementations.
+ */
#define DEEP_COPY(T) TEMPL(deep_copy , T)
#define RESOLVE(T) TEMPL(resolve , T)
#define APPEND(T) TEMPL(append , T)
diff --git a/main.c b/main.c
index 6ed74323..2a3eb98d 100644
--- a/main.c
+++ b/main.c
@@ -42,7 +42,6 @@ int main (int argc, char* argv[argc]) {
printf("%3lu | %s | %s\n",
i + 1,
filename,
- // get_property(cal.events[i], "SUMMARY")->val.mem);
get_property(cal.events[i], "SUMMARY")->vals.cur->value->mem);
}
} else if (strcmp(args.argv[0], "-g") == 0) {
@@ -55,7 +54,6 @@ int main (int argc, char* argv[argc]) {
strcat(target, ".dot");
create_graph(cal.events[i], target);
}
- // create_graph(cal.events[0], "graph.dot");
} else {
create_graph(cal.events[0], args.argv[0]);
}
diff --git a/parse.c b/parse.c
index 30d7bb79..ed113d47 100644
--- a/parse.c
+++ b/parse.c
@@ -18,25 +18,19 @@ int parse_file(char* fname, FILE* f, vcalendar* cal) {
.scope = s_none,
.skip_to = &skip
};
- // scope_context s_ctx = s_none;
int keylen = 100;
int vallen = 100;
int line = 0;
- // NEW(vevent, ev, fname);
vevent* ev = NULL;
SNEW(content_line, cline, keylen, vallen);
- /*
- * TODO
- * When a file ends with CRLF then ctx_scope == s_none, leading to
- * END:VEVENT erroring as bad start of calendar.
- * */
char c;
while ( (c = fgetc(f)) != EOF) {
+
/*
* A carrige return means that the current line is at an
* end. The following character should always be \n.
@@ -69,19 +63,24 @@ int parse_file(char* fname, FILE* f, vcalendar* cal) {
}
continue;
} else {
+
/* Actuall end of line, handle values. */
+
+ /* Push back the last written character to the stream,
+ * since it's part of the next line.
+ */
if (ungetc(s[1], f) != s[1]) {
ERR_F("%s, %i", "Failed to put character back on FILE", line);
exit (2);
}
- /* At TRUE end of line */
if (str.ptr + 1 > vallen) {
vallen = str.ptr + 1;
strbuf_realloc(cline.vals.cur->value, vallen);
}
strbuf_copy(cline.vals.cur->value, &str);
+ /* TODO when do I actualy cap? */
// strbuf_cap(cline.vals.cur->value);
++line;
@@ -89,8 +88,6 @@ int parse_file(char* fname, FILE* f, vcalendar* cal) {
switch (handle_kv(cal, ev, &cline, line, &ctx)) {
case s_event:
RENEW(vevent, ev, fname);
- // ev = malloc(sizeof(*ev));
- // INIT(vevent, ev, fname);
break;
}
strbuf_soft_reset(&str);
@@ -105,7 +102,16 @@ int parse_file(char* fname, FILE* f, vcalendar* cal) {
} else if (p_ctx == p_key && c == ':') {
if (str.ptr + 1 > keylen) {
keylen = str.ptr + 1;
- // TODO this might break everything
+ /*
+ * Allow for key's longer than 100 octets. It
+ * currently is of no use, since key's can't be
+ * folded.
+ * TODO check if everything should be unfolded at 75
+ * octets, or if that is only for values.
+ *
+ * TODO earlier there was a bug here. Test if that is
+ * fixed and reenable this line.
+ */
// strbuf_realloc(&cline.key, keylen);
}
strbuf_copy(&cline.key, &str);
@@ -149,7 +155,6 @@ int handle_kv(
vevent* ev,
content_line* cline,
int line,
- // scope_context* s_ctx
parse_ctx* ctx
) {
switch (ctx->scope) {
@@ -157,7 +162,6 @@ int handle_kv(
case s_skip:
if (strbuf_c(&cline->key, "END") && strbuf_cmp(cline->vals.cur->value, ctx->skip_to)) {
ctx->scope = s_calendar;
- // FREE(strbuf)(ctx->skip_to);
}
break;
@@ -176,9 +180,15 @@ int handle_kv(
return ctx->scope;
break;
} else {
- // ERR("Unsupported start", line);
+
+ /*
+ * Here we found the start of some form of block
+ * we don't understand. Just skip everything until
+ * we find the matching END
+ */
ctx->scope = s_skip;
strbuf_copy(ctx->skip_to, cline->vals.cur->value);
+
}
} else if (strbuf_c(&cline->key, "END")) {
if (strbuf_c(cline->vals.cur->value, "VCALENDAR")) {
diff --git a/parse.h b/parse.h
index 2752256a..9d95bb22 100644
--- a/parse.h
+++ b/parse.h
@@ -37,8 +37,7 @@ int handle_kv(
vevent* ev,
content_line* cline,
int line,
- // scope_context* s_ctx
- parse_ctx* ctx
+ parse_ctx* ctx
);
int parse_file(char* fname, FILE* f, vcalendar* cal);
diff --git a/strbuf.c b/strbuf.c
index 2f83767f..bf40d7fe 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -24,9 +24,12 @@ INIT_F(strbuf, size_t len) {
int strbuf_realloc(strbuf* str, size_t len) {
#ifdef SAFE_STR
- if (str->mem == NULL /*|| str->alloc == -1*/) {
+ if (str->mem == NULL) {
+ /* NOTE
+ * this isn't an error, since
+ * realloc(NULL, 10) ≡ malloc(10)
+ */
ERR("String memory not initialized");
- // return 1;
}
#endif
str->mem = realloc(str->mem, len);
@@ -34,7 +37,6 @@ int strbuf_realloc(strbuf* str, size_t len) {
return 0;
}
-// int strbuf_free(strbuf* str) {
FREE_F(strbuf) {
#ifdef SAFE_STR
if (this->mem == NULL) return 1;
@@ -46,9 +48,6 @@ FREE_F(strbuf) {
return 0;
}
-/*
- * TODO this should do bounds check
- */
int strbuf_append(strbuf* s, char c) {
#ifdef SAFE_STR
if (s->len > s->alloc) {
@@ -75,6 +74,7 @@ int strbuf_copy(strbuf* dest, strbuf* src) {
#endif
dest->len = src->len;
memcpy(dest->mem, src->mem, src->len);
+
// TODO should this be here?
strbuf_cap(dest);
return 0;
diff --git a/strbuf.h b/strbuf.h
index 8a4de030..77a401b5 100644
--- a/strbuf.h
+++ b/strbuf.h
@@ -4,6 +4,14 @@
#include <stdlib.h>
#include "macro.h"
+/*
+ * A high level string type which holds it's own length, how much
+ * memmory it has allocated for itself, and a seek pointer into the
+ * string.
+ *
+ * Also comes with a number of functions which allow for safe(er)
+ * access to the memmory.
+ */
typedef struct {
char* mem;
/* TODO add support for negative ptr */
@@ -33,7 +41,6 @@ int strbuf_realloc(strbuf* str, size_t len);
/*
* Free's contents of str, but keeps str.
*/
-// int strbuf_free(strbuf* str);
FREE_F(strbuf);
/*
@@ -57,8 +64,21 @@ int strbuf_append(strbuf* s, char c);
* Calls strbuf_append with NULL.
*/
int strbuf_cap(strbuf* s);
+
+/*
+ * Resets the seek for strbuf to 0.
+ */
int strbuf_reset(strbuf* s);
+
+/*
+ * Returns a pointer to character at index. Allows mutation of the
+ * value pointed to by the return address.
+ */
char* charat(strbuf* s, unsigned int idx);
+
+/*
+ * Same as `charat`, But returns the current character.
+ */
char* strbuf_cur(strbuf* s);
/*
diff --git a/trie.h b/trie.h
index 916f672f..77d0020f 100644
--- a/trie.h
+++ b/trie.h
@@ -8,6 +8,11 @@
#define TRIE(T) TEMPL(trie, T)
#define TRIE_NODE(T) TEMPL(trie_node, T)
+/*
+ * TODO
+ * The DOT functions are for generating graphviz framgments. They
+ * realy should be moved away from here.
+ */
#define TRIE_DOT(T) TP(trie_to_dot__, T)
#define TRIE_DOT_HELP(T) TP(trie_to_dot_helper__, T)
diff --git a/trie.inc.h b/trie.inc.h
index fbc3b807..4c42da7a 100644
--- a/trie.inc.h
+++ b/trie.inc.h
@@ -36,7 +36,6 @@ int PUSH(TRIE(TYPE)) ( TRIE(TYPE)* trie, char* key, TYPE* val ) {
cur = last->child;
char* subkey = key;
- // --------------------------------------------------
while (1) {
if (cur == NULL) {
@@ -56,7 +55,6 @@ int PUSH(TRIE(TYPE)) ( TRIE(TYPE)* trie, char* key, TYPE* val ) {
subkey++;
} else if (subkey[0] == '\0') {
/* Key finished */
- // last->value = val;
last->value = RESOLVE(TYPE)(last->value, val);
return 0;
} else if (cur->next != NULL) {
diff --git a/vcal.c b/vcal.c
index a2a0bd90..c837c189 100644
--- a/vcal.c
+++ b/vcal.c
@@ -23,12 +23,6 @@ INIT_F(vevent, char* filename) {
return 0;
}
-/*
- * Resolves a collision in some form of structure (probably a hash-map
- * or a trie). If dest is NULL just return new. Otherwise mutates dest
- * to have the correct form, and returns it. Destroying new in the
- * process.
- */
content_line* RESOLVE(content_line)
(content_line* dest, content_line* new) {
@@ -53,44 +47,46 @@ content_line* get_property (vevent* ev, char* key) {
INIT_F(content_line) {
INIT(strbuf, &this->key);
- // INIT(strbuf, &this->val);
INIT( LLIST(strbuf), &this->vals );
+
// TODO remaining fields
+
return 0;
}
INIT_F(content_line, int keylen, int vallen) {
INIT(strbuf, &this->key, keylen);
- // INIT(strbuf, &this->val, vallen);
INIT( LLIST(strbuf), &this->vals );
NEW(strbuf, s, vallen);
PUSH(LLIST(strbuf))(&this->vals, s);
+
// TODO remaining fields
+
return 0;
}
int content_line_copy (content_line* dest, content_line* src) {
- //strbuf_init_copy(&dest->key, &src->key);
DEEP_COPY(strbuf)(&dest->key, &src->key);
- // strbuf_init_copy(&dest->val, &src->val);
DEEP_COPY(LLIST(strbuf))(&dest->vals, &src->vals);
+
// TODO remaining fields
+
return 0;
}
FREE_F(content_line) {
FREE(strbuf)(&this->key);
- // FREE(strbuf)(&this->val);
- // LLIST_FREE(strbuf)(&this->vals);
FREE(LLIST(strbuf))(&this->vals);
// TODO remaining fields
+
return 0;
}
FREE_F(vevent) {
if (this->filename != NULL) free(this->filename);
+
if (FREE(TRIE(content_line))(&this->clines) != 0) {
fprintf(stderr, "Error freeing vevent belonging to file \n %s \n",
this->filename);
@@ -99,9 +95,6 @@ FREE_F(vevent) {
return 0;
}
-/*
- * TODO change this into PUSH(VCALENDAR) (vevent*) ?
- */
int push_event(vcalendar* cal, vevent* ev) {
ev->calendar = cal;
@@ -112,7 +105,6 @@ int push_event(vcalendar* cal, vevent* ev) {
cal->events = realloc(cal->events, sizeof(*cal->events) * cal->alloc);
}
- // vevent_init_copy(&cal->events[cal->n_events], ev);
cal->events[cal->n_events] = ev;
cal->n_events++;
diff --git a/vcal.h b/vcal.h
index 946b626c..b4b2c017 100644
--- a/vcal.h
+++ b/vcal.h
@@ -29,15 +29,15 @@ INIT_F(content_line);
INIT_F(content_line, int keylen, int vallen);
/*
- * This takes two content lines, and return a content line that is the
- * merge of the two.
- * The function also cleans up the unused memmory between the two.
+ * Resolves a collision in some form of structure (probably a hash-map
+ * or a trie). If dest is NULL just return new. Otherwise mutates dest
+ * to have the correct form, and returns it. Destroying new in the
+ * process.
*/
content_line* RESOLVE(content_line)
(content_line* dest, content_line* new);
#define TYPE content_line
-// #include "hash.h"
#include "trie.h"
#undef TYPE
@@ -70,6 +70,7 @@ int free_vcalendar (vcalendar* cal);
/*
* Appends ev to cal. Doesn't copy ev. So make sure that it wont go
* out of scope.
+ * TODO change this into PUSH(VCALENDAR) (vevent*) ?
*/
int push_event(vcalendar* cal, vevent* ev);