aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHugo Hörnquist <hugo@lysator.liu.se>2019-02-03 23:35:27 +0100
committerHugo Hörnquist <hugo@lysator.liu.se>2019-02-03 23:35:27 +0100
commit82c63a1f2422c3f4b1599bcb889e3ed1fc4f6ed0 (patch)
treec433dbc1621492794c6d9993f4939aa68c20940b
parentLoads of memmory fixes, among other. (diff)
downloadcalp-82c63a1f2422c3f4b1599bcb889e3ed1fc4f6ed0.tar.gz
calp-82c63a1f2422c3f4b1599bcb889e3ed1fc4f6ed0.tar.xz
Add linked list generic type.
-rw-r--r--linked_list.h38
-rw-r--r--linked_list.inc.h61
-rw-r--r--macro.h2
-rw-r--r--main.c6
-rw-r--r--parse.c24
-rw-r--r--scheme.scm.c10
-rw-r--r--strbuf.c4
-rw-r--r--strbuf.h2
-rw-r--r--vcal.c18
-rw-r--r--vcal.h8
10 files changed, 151 insertions, 22 deletions
diff --git a/linked_list.h b/linked_list.h
new file mode 100644
index 00000000..666524be
--- /dev/null
+++ b/linked_list.h
@@ -0,0 +1,38 @@
+#ifndef LINKED_LIST_H
+#define LINKED_LIST_H
+
+#include "macro.h"
+
+#define LLIST(T) TP(llist__, T)
+#define LINK(T) TP(llist_link__, T)
+
+#define LLIST_INIT(T) CONSTRUCTOR_GEN(llist, T, 0);
+#define LLIST_FREE(T) TP(llist_free__, T)
+#define LLIST_CONS(T) TP(llist_cons__, T)
+
+#endif /* LINKED_LIST_H */
+#ifdef TYPE
+
+typedef struct LINK(TYPE) {
+ struct LINK(TYPE)* before;
+ struct LINK(TYPE)* after;
+ TYPE* value;
+} LINK(TYPE);
+
+typedef struct {
+ LINK(TYPE)* head;
+ LINK(TYPE)* tail;
+ LINK(TYPE)* cur;
+ int length;
+} LLIST(TYPE);
+
+int CONSTRUCTOR_DECL ( LLIST(TYPE) );
+int LLIST_FREE(TYPE) ( LLIST(TYPE)* );
+
+int CONSTRUCTOR_DECL ( LINK(TYPE) );
+
+int LLIST_CONS(TYPE) ( LLIST(TYPE)* lst, TYPE* val);
+
+int DEEP_COPY(LLIST(TYPE)) ( LLIST(TYPE)* dest, LLIST(TYPE)* src );
+
+#endif /* TYPE */
diff --git a/linked_list.inc.h b/linked_list.inc.h
new file mode 100644
index 00000000..260eaf0d
--- /dev/null
+++ b/linked_list.inc.h
@@ -0,0 +1,61 @@
+#ifndef TYPE
+#error "Set TYPE before including this file"
+#else
+
+int CONSTRUCTOR_DECL ( LLIST(TYPE) ) {
+ this->length = 0;
+ this->head = NULL;
+ this->tail = NULL;
+ this->cur = NULL;
+ return 0;
+}
+
+int LLIST_FREE(TYPE) (LLIST(TYPE)* this ) {
+ LINK(TYPE) *node, *next;
+ node = this->head;
+ while (node != NULL) {
+ next = node->after;
+ FFREE(TYPE, node->value);
+ free(node);
+ node = next;
+ }
+ this->length = 0;
+ return 0;
+}
+
+int CONSTRUCTOR_DECL ( LINK(TYPE) ) {
+ this->before = NULL;
+ this->after = NULL;
+ this->value = NULL;
+ return 0;
+}
+
+int LLIST_CONS(TYPE) ( LLIST(TYPE)* lst, TYPE* val) {
+ NEW(LINK(TYPE), l);
+ l->after = lst->head;
+ if (l->after != NULL) {
+ l->after->before = l;
+ }
+ lst->head = l;
+ l->value = val;
+ ++lst->length;
+
+ lst->cur = l;
+
+ return 0;
+}
+
+int DEEP_COPY(LLIST(TYPE)) ( LLIST(TYPE)* dest, LLIST(TYPE)* src ) {
+ LINK(TYPE)* n = src->head;
+
+ while (n != NULL) {
+ NEW(TYPE, cpy);
+ DEEP_COPY(TYPE)(cpy, n->value);
+ LLIST_CONS(TYPE) ( dest, cpy );
+ n = n->after;
+ }
+
+ return 0;
+}
+
+#endif /* TYPE */
diff --git a/macro.h b/macro.h
index ce2bfd21..8a0a725b 100644
--- a/macro.h
+++ b/macro.h
@@ -72,4 +72,6 @@
/* Declare destructor */
#define FREE_DECL(T) TP(T, __free) (T* this)
+#define DEEP_COPY(T) TP(deep_copy__, T)
+
#endif /* MACRO_H */
diff --git a/main.c b/main.c
index 6783c3e3..f1298431 100644
--- a/main.c
+++ b/main.c
@@ -42,7 +42,8 @@ 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")->val.mem);
+ get_property(cal.events[i], "SUMMARY")->vals.head->value->mem);
}
} else if (strcmp(args.argv[0], "-g") == 0) {
if (arg_shift(&args) == 0) {
@@ -63,7 +64,8 @@ int main (int argc, char* argv[argc]) {
for (int i = 0; i < cline_ptr; i++) {
if (clines[i] != NULL) {
- printf("clines[%i] : [%s] := [%s]\n", i, clines[i]->key.mem, clines[i]->val.mem);
+ // printf("clines[%i] : [%s] := [%s]\n", i, clines[i]->key.mem, clines[i]->val.mem);
+ printf("clines[%i] : [%s] := [%s]\n", i, clines[i]->key.mem, clines[i]->vals.head->value->mem);
}
}
diff --git a/parse.c b/parse.c
index 82a60671..890c37c3 100644
--- a/parse.c
+++ b/parse.c
@@ -65,11 +65,11 @@ int parse_file(char* fname, FILE* f, vcalendar* cal) {
/* At TRUE end of line */
if (str.ptr + 1 > vallen) {
vallen = str.ptr + 1;
- strbuf_realloc(&cline.val, vallen);
+ strbuf_realloc(cline.vals.cur->value, vallen);
}
- strbuf_copy(&cline.val, &str);
- strbuf_cap(&cline.val);
+ strbuf_copy(cline.vals.cur->value, &str);
+ strbuf_cap(cline.vals.cur->value);
++line;
@@ -116,10 +116,10 @@ int parse_file(char* fname, FILE* f, vcalendar* cal) {
*/
if (str.ptr + 1 > vallen) {
vallen = str.ptr + 1;
- strbuf_realloc(&cline.val, vallen);
+ strbuf_realloc(cline.vals.cur->value, vallen);
}
- strbuf_copy(&cline.val, &str);
- strbuf_cap(&cline.val);
+ strbuf_copy(cline.vals.cur->value, &str);
+ strbuf_cap(cline.vals.cur->value);
handle_kv(cal, ev, &cline, line, &ctx);
}
FREE(strbuf)(&str);
@@ -143,14 +143,14 @@ int handle_kv(
switch (ctx->scope) {
case s_skip:
- if (strbuf_c(&cline->key, "END") && strbuf_cmp(&cline->val, ctx->skip_to)) {
+ 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;
case s_none:
- if (! (strbuf_c(&cline->key, "BEGIN") && strbuf_c(&cline->val, "VCALENDAR"))) {
+ if (! (strbuf_c(&cline->key, "BEGIN") && strbuf_c(cline->vals.cur->value, "VCALENDAR"))) {
ERR("Invalid start of calendar", line);
return -1;
}
@@ -159,17 +159,17 @@ int handle_kv(
case s_calendar:
if (strbuf_c(&cline->key, "BEGIN")) {
- if (strbuf_c(&cline->val, "VEVENT")) {
+ if (strbuf_c(cline->vals.cur->value, "VEVENT")) {
ctx->scope = s_event;
return ctx->scope;
break;
} else {
// ERR("Unsupported start", line);
ctx->scope = s_skip;
- strbuf_copy(ctx->skip_to, &cline->val);
+ strbuf_copy(ctx->skip_to, cline->vals.cur->value);
}
} else if (strbuf_c(&cline->key, "END")) {
- if (strbuf_c(&cline->val, "VCALENDAR")) {
+ if (strbuf_c(cline->vals.cur->value, "VCALENDAR")) {
ctx->scope = s_none;
break;
}
@@ -182,7 +182,7 @@ int handle_kv(
return -5;
}
if (strbuf_c(&cline->key, "END")) {
- if (strbuf_c(&cline->val, "VEVENT")) {
+ if (strbuf_c(cline->vals.cur->value, "VEVENT")) {
push_event(cal, ev);
ctx->scope = s_calendar;
return ctx->scope;
diff --git a/scheme.scm.c b/scheme.scm.c
index 84e4f40c..e62610ff 100644
--- a/scheme.scm.c
+++ b/scheme.scm.c
@@ -49,7 +49,15 @@ SCM_DEFINE (calendar_get_attr, "calendar-get-attr", 3, 0, 0,
if (c == NULL) return SCM_BOOL_F;
- return scm_from_strbuf(&c->val);
+ LINK(strbuf)* cur = c->vals.head;
+ SCM llist = NULL;
+ while (cur != NULL) {
+ llist = scm_cons (scm_from_strbuf(cur->value), llist);
+ cur = cur->after;
+ }
+
+ // // return scm_from_strbuf(&c->val);
+ return llist;
}
SCM_DEFINE (calendar_size, "calendar-size", 1, 0, 0,
diff --git a/strbuf.c b/strbuf.c
index 0dbaa0c7..e2b8d689 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -122,6 +122,10 @@ int strbuf_init_copy(strbuf* dest, strbuf* src) {
return 0;
}
+int DEEP_COPY(strbuf)(strbuf* dest, strbuf* src) {
+ return strbuf_init_copy(dest, src);
+}
+
char* strbuf_end(strbuf* s) {
return &s->mem[s->len];
}
diff --git a/strbuf.h b/strbuf.h
index b5cd085f..19987dc3 100644
--- a/strbuf.h
+++ b/strbuf.h
@@ -48,6 +48,8 @@ int strbuf_copy(strbuf* dest, strbuf* src);
int strbuf_cmp(strbuf* a, strbuf* b);
int strbuf_c(strbuf* a, char* b);
+int DEEP_COPY(strbuf)(strbuf*, strbuf*);
+
/*
* Append char to end of strbuf, determined by s->len.
*/
diff --git a/vcal.c b/vcal.c
index 7464c72b..0371a35b 100644
--- a/vcal.c
+++ b/vcal.c
@@ -7,6 +7,10 @@
#include "trie.inc.h"
#undef TYPE
+#define TYPE strbuf
+#include "linked_list.inc.h"
+#undef TYPE
+
content_line** clines;
int cline_ptr;
@@ -34,7 +38,8 @@ int add_content_line (vevent* ev, content_line* c) {
int CONSTRUCTOR_DECL(content_line) {
clines[cline_ptr++] = this;
CONSTRUCT(strbuf, &this->key);
- CONSTRUCT(strbuf, &this->val);
+ // CONSTRUCT(strbuf, &this->val);
+ CONSTRUCT( LLIST(strbuf), &this->vals );
// TODO remaining fields
return 0;
}
@@ -42,7 +47,10 @@ int CONSTRUCTOR_DECL(content_line) {
int CONSTRUCTOR_DECL(content_line, int keylen, int vallen) {
clines[cline_ptr++] = this;
CONSTRUCT(strbuf, &this->key, keylen);
- CONSTRUCT(strbuf, &this->val, vallen);
+ // CONSTRUCT(strbuf, &this->val, vallen);
+ CONSTRUCT( LLIST(strbuf), &this->vals );
+ NEW(strbuf, s, vallen);
+ LLIST_CONS(strbuf)(&this->vals, s);
// TODO remaining fields
return 0;
}
@@ -50,14 +58,16 @@ int CONSTRUCTOR_DECL(content_line, int keylen, int vallen) {
int content_line_copy (content_line* dest, content_line* src) {
strbuf_init_copy(&dest->key, &src->key);
- strbuf_init_copy(&dest->val, &src->val);
+ // strbuf_init_copy(&dest->val, &src->val);
+ DEEP_COPY(LLIST(strbuf))(&dest->vals, &src->vals);
// TODO remaining fields
return 0;
}
int FREE_DECL(content_line) {
FREE(strbuf)(&this->key);
- FREE(strbuf)(&this->val);
+ // FREE(strbuf)(&this->val);
+ LLIST_FREE(strbuf)(&this->vals);
for (int i = 0; i < cline_ptr; i++) {
if (clines[i] == this) {
clines[i] = NULL;
diff --git a/vcal.h b/vcal.h
index 350871b7..91eed471 100644
--- a/vcal.h
+++ b/vcal.h
@@ -5,6 +5,10 @@
#include "strbuf.h"
+#define TYPE strbuf
+#include "linked_list.h"
+#undef TYPE
+
typedef struct {
strbuf key;
strbuf value;
@@ -15,9 +19,7 @@ typedef struct {
typedef struct {
strbuf key;
- strbuf val;
- strbuf* aux_values;
- int value_count;
+ LLIST(strbuf) vals;
parameter* params;
int param_count;