aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHugo Hörnquist <hugo@lysator.liu.se>2019-02-04 00:36:57 +0100
committerHugo Hörnquist <hugo@lysator.liu.se>2019-02-04 00:36:57 +0100
commit2c2bdb8b66e386e14b5cc1a35abfbf242dcf2018 (patch)
tree7f640c7845bd26823b8d6108b4f554bf5b6c9d97
parentAdd linked list generic type. (diff)
downloadcalp-2c2bdb8b66e386e14b5cc1a35abfbf242dcf2018.tar.gz
calp-2c2bdb8b66e386e14b5cc1a35abfbf242dcf2018.tar.xz
Work on propper memmory management for linked lists.
-rw-r--r--linked_list.h7
-rw-r--r--linked_list.inc.h72
-rw-r--r--macro.h2
-rw-r--r--main.c2
-rw-r--r--strbuf.c5
-rw-r--r--trie.inc.h6
-rw-r--r--vcal.c17
-rw-r--r--vcal.h10
8 files changed, 97 insertions, 24 deletions
diff --git a/linked_list.h b/linked_list.h
index 666524be..a76c3443 100644
--- a/linked_list.h
+++ b/linked_list.h
@@ -6,8 +6,6 @@
#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 */
@@ -27,12 +25,15 @@ typedef struct {
} LLIST(TYPE);
int CONSTRUCTOR_DECL ( LLIST(TYPE) );
-int LLIST_FREE(TYPE) ( LLIST(TYPE)* );
+int FREE_DECL( LLIST(TYPE) );
int CONSTRUCTOR_DECL ( LINK(TYPE) );
+int CONSTRUCTOR_DECL ( LINK(TYPE), TYPE* val );
int LLIST_CONS(TYPE) ( LLIST(TYPE)* lst, TYPE* val);
int DEEP_COPY(LLIST(TYPE)) ( LLIST(TYPE)* dest, LLIST(TYPE)* src );
+int APPEND(LLIST(TYPE)) ( LLIST(TYPE)* dest, LLIST(TYPE)* new );
+
#endif /* TYPE */
diff --git a/linked_list.inc.h b/linked_list.inc.h
index 260eaf0d..a878d075 100644
--- a/linked_list.inc.h
+++ b/linked_list.inc.h
@@ -4,21 +4,29 @@
int CONSTRUCTOR_DECL ( LLIST(TYPE) ) {
this->length = 0;
- this->head = NULL;
- this->tail = NULL;
- this->cur = NULL;
+ NEW(LINK(TYPE), head);
+ NEW(LINK(TYPE), tail);
+ this->head = head;
+ this->tail = tail;
+ head->after = tail;
+ tail->before = head;
+ this->cur = head;
return 0;
}
-int LLIST_FREE(TYPE) (LLIST(TYPE)* this ) {
+int FREE_DECL( LLIST(TYPE) ) {
LINK(TYPE) *node, *next;
- node = this->head;
- while (node != NULL) {
+ node = this->head->after;
+ while (node->after != NULL) {
next = node->after;
- FFREE(TYPE, node->value);
- free(node);
+ if (node->value != NULL) {
+ FFREE(TYPE, node->value);
+ }
+ // free(node);
node = next;
}
+ free (this->head);
+ free (this->tail);
this->length = 0;
return 0;
}
@@ -30,25 +38,32 @@ int CONSTRUCTOR_DECL ( LINK(TYPE) ) {
return 0;
}
+int CONSTRUCTOR_DECL ( LINK(TYPE), TYPE* val ) {
+ this->before = NULL;
+ this->after = NULL;
+ this->value = val;
+ 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;
+ NEW(LINK(TYPE), l, val);
+
+ l->after = lst->head->after;
+ lst->head->after = l;
+ l->after->before = l;
+ l->before = lst->head;
++lst->length;
+ // TODO do I want to change that?
lst->cur = l;
return 0;
}
int DEEP_COPY(LLIST(TYPE)) ( LLIST(TYPE)* dest, LLIST(TYPE)* src ) {
- LINK(TYPE)* n = src->head;
+ LINK(TYPE)* n = src->head->after;
- while (n != NULL) {
+ while (n->after != NULL) {
NEW(TYPE, cpy);
DEEP_COPY(TYPE)(cpy, n->value);
LLIST_CONS(TYPE) ( dest, cpy );
@@ -58,4 +73,27 @@ int DEEP_COPY(LLIST(TYPE)) ( LLIST(TYPE)* dest, LLIST(TYPE)* src ) {
return 0;
}
+/*
+ * TODO
+ * this or cons links wrong, creating infinite loops.
+ */
+int APPEND(LLIST(TYPE)) ( LLIST(TYPE)* dest, LLIST(TYPE)* new ) {
+
+ dest->tail->before->after = new->head->after;
+ new->head->after->before = dest->tail->before;
+ LINK(TYPE)* old_tail = dest->tail;
+ dest->tail = new->tail;
+ dest->length += new->length;
+
+ // free(old_tail);
+ // free(new->head);
+
+ /*
+ * TODO `new` can now be handled as an empty husk.
+ * Somehow it needs to be collected
+ */
+
+ return 0;
+}
+
#endif /* TYPE */
diff --git a/macro.h b/macro.h
index 8a0a725b..a62d12d1 100644
--- a/macro.h
+++ b/macro.h
@@ -73,5 +73,7 @@
#define FREE_DECL(T) TP(T, __free) (T* this)
#define DEEP_COPY(T) TP(deep_copy__, T)
+#define RESOLVE(T) TP(resolve__, T)
+#define APPEND(T) TP(append__, T)
#endif /* MACRO_H */
diff --git a/main.c b/main.c
index f1298431..1d1b20ed 100644
--- a/main.c
+++ b/main.c
@@ -43,7 +43,7 @@ int main (int argc, char* argv[argc]) {
i + 1,
filename,
// get_property(cal.events[i], "SUMMARY")->val.mem);
- get_property(cal.events[i], "SUMMARY")->vals.head->value->mem);
+ get_property(cal.events[i], "SUMMARY")->vals.cur->value->mem);
}
} else if (strcmp(args.argv[0], "-g") == 0) {
if (arg_shift(&args) == 0) {
diff --git a/strbuf.c b/strbuf.c
index e2b8d689..e4dfb803 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -114,6 +114,11 @@ int strbuf_init_copy(strbuf* dest, strbuf* src) {
ERR("Dest already allocated");
return 1;
}
+
+ if (src == NULL) {
+ ERR("Attempting to copy NULL strbuf");
+ return 2;
+ }
#endif
CONSTRUCT(strbuf, dest, src->len + 1);
diff --git a/trie.inc.h b/trie.inc.h
index b839a7e8..61dc3701 100644
--- a/trie.inc.h
+++ b/trie.inc.h
@@ -46,7 +46,8 @@ int TRIE_PUT(TYPE) ( TRIE(TYPE)* trie, char* key, TYPE* val ) {
last->child = t;
last = t;
}
- last->value = val;
+ RESOLVE(TYPE)(&last->value, val);
+ // last->value = val;
return 0;
} else if (cur->c == subkey[0]) {
/* This node belongs to the key,
@@ -56,7 +57,8 @@ int TRIE_PUT(TYPE) ( TRIE(TYPE)* trie, char* key, TYPE* val ) {
subkey++;
} else if (subkey[0] == '\0') {
/* Key finished */
- last->value = val;
+ // last->value = val;
+ RESOLVE(TYPE)(&last->value, val);
return 0;
} else if (cur->next != NULL) {
/* This node was not part of the set, but it's sibling might */
diff --git a/vcal.c b/vcal.c
index 0371a35b..73158aeb 100644
--- a/vcal.c
+++ b/vcal.c
@@ -26,6 +26,20 @@ int CONSTRUCTOR_DECL(vevent, char* filename) {
return 0;
}
+int RESOLVE(content_line)
+ (content_line** dest, content_line* new) {
+ if (*dest == NULL) *dest = new;
+
+ if (strbuf_cmp(&(*dest)->key, &new->key) != 0) {
+ ERR("Can't resolve between these two types");
+ return 1;
+ }
+
+ // printf("len = %i\n", dest->vals.length);
+ APPEND(LLIST(strbuf))(&(*dest)->vals, &new->vals);
+ return 0;
+}
+
content_line* get_property (vevent* ev, char* key) {
return TRIE_GET(content_line)(&ev->clines, key);
}
@@ -67,7 +81,8 @@ int content_line_copy (content_line* dest, content_line* src) {
int FREE_DECL(content_line) {
FREE(strbuf)(&this->key);
// FREE(strbuf)(&this->val);
- LLIST_FREE(strbuf)(&this->vals);
+ // LLIST_FREE(strbuf)(&this->vals);
+ FREE(LLIST(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 91eed471..a5144992 100644
--- a/vcal.h
+++ b/vcal.h
@@ -28,6 +28,9 @@ typedef struct {
int CONSTRUCTOR_DECL(content_line);
int CONSTRUCTOR_DECL(content_line, int keylen, int vallen);
+int RESOLVE(content_line)
+ (content_line** orig, content_line* new);
+
#define TYPE content_line
// #include "hash.h"
#include "trie.h"
@@ -65,6 +68,13 @@ int free_vcalendar (vcalendar* cal);
*/
int push_event(vcalendar* cal, vevent* ev);
+/*
+ * NOTE
+ * these create a very basic garbage collector. It shouldn't be used,
+ * but is useful for finding lost memmory during debugging.
+ * TODO
+ * remove it.
+ */
extern content_line** clines;
extern int cline_ptr;