diff --git a/libc3/call.c b/libc3/call.c
index 6835db1..9ee76c4 100644
--- a/libc3/call.c
+++ b/libc3/call.c
@@ -39,7 +39,7 @@ s_call * call_copy (const s_call *src, s_call *dest)
assert(src);
assert(dest);
ident_copy(&src->ident, &dest->ident);
- list_copy(src->arguments, &dest->arguments);
+ list_copy((const s_list **) &src->arguments, &dest->arguments);
dest->cfn = src->cfn;
dest->fn = src->fn;
return dest;
diff --git a/libc3/cfn.c b/libc3/cfn.c
index dceb46d..f507ea2 100644
--- a/libc3/cfn.c
+++ b/libc3/cfn.c
@@ -111,7 +111,7 @@ s_cfn * cfn_copy (const s_cfn *cfn, s_cfn *dest)
assert(dest);
dest->name = cfn->name;
dest->arg_result = cfn->arg_result;
- list_copy(cfn->arg_types, &dest->arg_types);
+ list_copy((const s_list **) &cfn->arg_types, &dest->arg_types);
dest->arity = cfn->arity;
dest->cif = cfn->cif;
if (cfn->arity) {
diff --git a/libc3/fn_clause.c b/libc3/fn_clause.c
index 7de9208..5378f7f 100644
--- a/libc3/fn_clause.c
+++ b/libc3/fn_clause.c
@@ -33,8 +33,8 @@ s_fn_clause * fn_clause_copy (const s_fn_clause *src, s_fn_clause **dest)
while (src) {
*tail = fn_clause_new(NULL);
(*tail)->arity = src->arity;
- list_copy(src->pattern, &(*tail)->pattern);
- list_copy(src->algo, &(*tail)->algo);
+ list_copy((const s_list **) &src->pattern, &(*tail)->pattern);
+ list_copy((const s_list **) &src->algo, &(*tail)->algo);
src = src->next_clause;
tail = &(*tail)->next_clause;
}
diff --git a/libc3/list.c b/libc3/list.c
index 1f6aa84..e98b2c9 100644
--- a/libc3/list.c
+++ b/libc3/list.c
@@ -35,12 +35,19 @@ s_list * list_1 (const char *p)
return list;
}
-void list_clean (s_list *list)
+void list_clean (s_list **list)
{
- if (list) {
- tag_clean(&list->tag);
- if (list->next.type != TAG_LIST)
- tag_clean(&list->next);
+ s_list *l;
+ s_list *next;
+ assert(list);
+ l = *list;
+ while (l) {
+ tag_clean(&l->tag);
+ next = list_next(l);
+ if (l->next.type != TAG_LIST)
+ tag_clean(&l->next);
+ free(l);
+ l = next;
}
}
@@ -48,7 +55,7 @@ s_list ** list_cast (const s_tag *tag, s_list **list)
{
assert(tag);
if (tag->type == TAG_LIST) {
- list_copy(tag->data.list, list);
+ list_copy((const s_list **) &tag->data.list, list);
return list;
}
return NULL;
@@ -57,13 +64,14 @@ s_list ** list_cast (const s_tag *tag, s_list **list)
/* FIXME: does not work on circular lists */
s_list ** list_copy (const s_list **src, s_list **dest)
{
- s_list **i = dest;
+ s_list **i;
s_list *next;
const s_list *s;
assert(src);
assert(dest);
- s = *src;
+ i = dest;
*i = NULL;
+ s = *src;
while (s) {
*i = list_new(NULL, NULL);
tag_copy(&s->tag, &(*i)->tag);
@@ -84,7 +92,10 @@ s_list * list_delete (s_list *list)
s_list *next = NULL;
if (list) {
next = list_next(list);
- list_clean(list);
+ tag_clean(&list->tag);
+ next = list_next(list);
+ if (list->next.type != TAG_LIST)
+ tag_clean(&list->next);
free(list);
}
return next;
diff --git a/libc3/list.h b/libc3/list.h
index e7a9ae3..0a3d8e1 100644
--- a/libc3/list.h
+++ b/libc3/list.h
@@ -26,7 +26,7 @@
/* Stack allocation compatible functions, do not use */
s_list * list_init (s_list *list, const s_tag *tag, s_list *next);
-void list_clean (s_list *list);
+void list_clean (s_list **list);
/* Constructors, call list_delete after use */
s_list * list_1 (const s8 *p);
@@ -37,7 +37,7 @@ s_list * list_delete (s_list *list);
void list_delete_all (s_list *list);
/* Observers */
-s_list * list_copy (const s_list *src, s_list **dest);
+s_list ** list_copy (const s_list **src, s_list **dest);
sw list_length (const s_list *list);
s_list * list_next (const s_list *list);
s_array * list_to_array (s_list *list, const s_sym *type,
diff --git a/libc3/tag.c b/libc3/tag.c
index 2951ec5..27fa1f5 100644
--- a/libc3/tag.c
+++ b/libc3/tag.c
@@ -1429,7 +1429,7 @@ s_tag * tag_copy (const s_tag *src, s_tag *dest)
integer_copy(&src->data.integer, &dest->data.integer);
break;
case TAG_LIST:
- list_copy(src->data.list, &dest->data.list);
+ list_copy((const s_list **) &src->data.list, &dest->data.list);
break;
case TAG_QUOTE:
quote_copy(&src->data.quote, &dest->data.quote);