diff --git a/Makefile b/Makefile
index a3b4e51..657c68b 100644
--- a/Makefile
+++ b/Makefile
@@ -151,11 +151,17 @@ gdb_ikc3:
${MAKE} -C ikc3 gdb_ikc3
gdb_test:
- ${MAKE} debug
+ ${MAKE} -C libtommath debug
+ ${MAKE} -C ucd2c
+ ${MAKE} -C libkc3 debug
${MAKE} -C test gdb_test
gdb_test_ekc3:
- ${MAKE} debug
+ ${MAKE} -C libtommath debug
+ ${MAKE} -C ucd2c
+ ${MAKE} -C libkc3 debug
+ ${MAKE} -C ikc3 debug
+ ${MAKE} -C kc3s debug
${MAKE} -C test gdb_test_ekc3
gdb_test_http:
@@ -166,6 +172,13 @@ gdb_test_http:
${MAKE} -C kc3s debug
${MAKE} -C test gdb_test_http
+gdb_test_ikc3:
+ ${MAKE} -C libtommath debug
+ ${MAKE} -C ucd2c
+ ${MAKE} -C libkc3 debug
+ ${MAKE} -C ikc3 debug
+ ${MAKE} -C test gdb_test_ikc3
+
gen:
${MAKE} -C libkc3 gen
diff --git a/libkc3/data.c b/libkc3/data.c
index 047746d..3723996 100644
--- a/libkc3/data.c
+++ b/libkc3/data.c
@@ -187,6 +187,8 @@ bool data_clean (const s_sym *type, void *data)
s_struct s = {0};
const s_struct_type *st;
assert(type);
+ if (! data)
+ return true;
if (type == &g_sym_Array ||
sym_is_array_type(type)) {
array_clean(data);
diff --git a/libkc3/env.c b/libkc3/env.c
index 532ea0c..d06cb58 100644
--- a/libkc3/env.c
+++ b/libkc3/env.c
@@ -1875,11 +1875,12 @@ s_tag * env_ident_get (s_env *env, const s_ident *ident, s_tag *dest)
&tag_ident, &tag_symbol_value, &tag_var,
NULL, NULL }))
return NULL;
- if (! facts_with_cursor_next(&cursor, &fact) ||
- ! fact) {
+ if (! facts_with_cursor_next(&cursor, &fact)) {
facts_with_cursor_clean(&cursor);
return NULL;
}
+ if (! fact)
+ return NULL;
if (! tag_init_copy(&tmp, &tag_var)) {
facts_with_cursor_clean(&cursor);
return NULL;
diff --git a/libkc3/list_init.c b/libkc3/list_init.c
index a30eace..735d784 100644
--- a/libkc3/list_init.c
+++ b/libkc3/list_init.c
@@ -413,12 +413,13 @@ s_list * list_init_struct (s_list *list, const s_sym *module,
}
s_list * list_init_struct_with_data (s_list *list, const s_sym *module,
- void *data, s_list *next)
+ void *data, bool free_data,
+ s_list *next)
{
s_list tmp;
assert(list);
list_init(&tmp, next);
- if (! tag_init_struct_with_data(&tmp.tag, module, data))
+ if (! tag_init_struct_with_data(&tmp.tag, module, data, free_data))
return NULL;
*list = tmp;
return list;
@@ -1016,13 +1017,14 @@ s_list * list_new_struct (const s_sym *module, s_list *next)
}
s_list * list_new_struct_with_data (const s_sym *module, void *data,
- s_list *next)
+ bool free_data, s_list *next)
{
s_list *list;
list = list_new(next);
if (! list)
return NULL;
- if (! tag_init_struct_with_data(&list->tag, module, data)) {
+ if (! tag_init_struct_with_data(&list->tag, module, data,
+ free_data)) {
free(list);
return NULL;
}
diff --git a/libkc3/list_init.h b/libkc3/list_init.h
index c92e33f..0ab1122 100644
--- a/libkc3/list_init.h
+++ b/libkc3/list_init.h
@@ -64,7 +64,8 @@ s_list * list_init_str_empty (s_list *list, s_list *next);
s_list * list_init_struct (s_list *list, const s_sym *module,
s_list *next);
s_list * list_init_struct_with_data (s_list *list, const s_sym *module,
- void *data, s_list *next);
+ void *data, bool free_data,
+ s_list *next);
s_list * list_init_struct_type (s_list *list, const s_sym *module,
const s_list *spec, s_list *next);
s_list * list_init_struct_type_update_clean (s_list *list,
@@ -128,7 +129,7 @@ s_list * list_new_str_cat (const s_str *a, const s_str *b,
s_list * list_new_str_empty (s_list *next);
s_list * list_new_struct (const s_sym *module, s_list *next);
s_list * list_new_struct_with_data (const s_sym *module, void *data,
- s_list *next);
+ bool free_data, s_list *next);
s_list * list_new_struct_type (const s_sym *module, const s_list *spec,
s_list *next);
s_list * list_new_struct_type_update_clean (const s_struct_type *st,
@@ -187,7 +188,7 @@ s_list * list_str_cat (s_list *list, const s_str *a, const s_str *b);
s_list * list_str_empty (s_list *list);
s_list * list_struct (s_list *list, const s_sym *module);
s_list * list_struct_with_data (s_list *list, const s_sym *module,
- void *data);
+ void *data, bool free_data);
s_list * list_struct_type (s_list *list, const s_sym *module,
const s_list *spec);
s_list * list_struct_type_update_clean (s_list *list,
diff --git a/libkc3/struct.c b/libkc3/struct.c
index 935dedd..873247e 100644
--- a/libkc3/struct.c
+++ b/libkc3/struct.c
@@ -49,9 +49,14 @@ s_struct * struct_allocate (s_struct *s)
s_struct tmp;
assert(s);
assert(s->type);
- assert(! s->data);
+ if (s->data) {
+ err_puts("struct_allocate: data != NULL");
+ assert(! "struct_allocate: data != NULL");
+ return NULL;
+ }
tmp = *s;
tmp.data = alloc(tmp.type->size);
+ tmp.free_data = true;
if (! tmp.data)
return NULL;
*s = tmp;
@@ -75,7 +80,8 @@ void struct_clean (s_struct *s)
i++;
}
}
- free(s->data);
+ if (s->free_data)
+ free(s->data);
}
if (s->tag) {
i = 0;
@@ -293,7 +299,7 @@ s_struct * struct_init_from_lists (s_struct *s, const s_sym *module,
}
s_struct * struct_init_with_data (s_struct *s, const s_sym *module,
- void *data)
+ void *data, bool free_data)
{
s_struct tmp = {0};
assert(s);
@@ -307,6 +313,7 @@ s_struct * struct_init_with_data (s_struct *s, const s_sym *module,
return NULL;
}
tmp.data = data;
+ tmp.free_data = free_data;
*s = tmp;
return s;
}
diff --git a/libkc3/struct.h b/libkc3/struct.h
index 57a5982..29da30f 100644
--- a/libkc3/struct.h
+++ b/libkc3/struct.h
@@ -31,7 +31,7 @@ s_struct * struct_init_from_lists (s_struct *s, const s_sym *module,
const s_list *keys,
const s_list *values);
s_struct * struct_init_with_data (s_struct *s, const s_sym *module,
- void *data);
+ void *data, bool free_data);
/* Heap-allocation functions, call struct_delete after use. */
void struct_delete (s_struct *s);
diff --git a/libkc3/tag.c b/libkc3/tag.c
index 94440d6..33416cd 100644
--- a/libkc3/tag.c
+++ b/libkc3/tag.c
@@ -893,6 +893,7 @@ bool tag_to_const_pointer (const s_tag *tag, const s_sym *type,
}
if (type == tag->data.struct_.type->module) {
*dest = tag->data.struct_.data;
+ assert(*dest);
return true;
}
err_write_1("tag_to_const_pointer: cannot cast ");
@@ -1145,6 +1146,7 @@ bool tag_to_ffi_pointer (s_tag *tag, const s_sym *type, void **dest)
}
if (type == tag->data.struct_.type->module) {
*dest = tag->data.struct_.data;
+ assert(*dest);
return true;
}
goto invalid_cast;
diff --git a/libkc3/tag_init.c b/libkc3/tag_init.c
index ac9c835..0b4dbd9 100644
--- a/libkc3/tag_init.c
+++ b/libkc3/tag_init.c
@@ -405,12 +405,13 @@ s_tag * tag_init_struct (s_tag *tag, const s_sym *module)
}
s_tag * tag_init_struct_with_data (s_tag *tag, const s_sym *module,
- void *data)
+ void *data, bool free_data)
{
s_tag tmp = {0};
assert(tag);
tmp.type = TAG_STRUCT;
- if (! struct_init_with_data(&tmp.data.struct_, module, data))
+ if (! struct_init_with_data(&tmp.data.struct_, module, data,
+ free_data))
return NULL;
*tag = tmp;
return tag;
@@ -1005,14 +1006,16 @@ s_tag * tag_new_struct (const s_sym *module)
return tag;
}
-s_tag * tag_new_struct_with_data (const s_sym *module, void *data)
+s_tag * tag_new_struct_with_data (const s_sym *module, void *data,
+ bool free_data)
{
s_tag *tag;
tag = alloc(sizeof(s_tag));
if (! tag)
return NULL;
tag->type = TAG_STRUCT;
- if (! struct_init_with_data(&tag->data.struct_, module, data)) {
+ if (! struct_init_with_data(&tag->data.struct_, module, data,
+ free_data)) {
free(tag);
return NULL;
}
@@ -1590,13 +1593,14 @@ s_tag * tag_struct (s_tag *tag, const s_sym *module)
}
s_tag * tag_struct_with_data (s_tag *tag, const s_sym *module,
- void *data)
+ void *data, bool free_data)
{
s_tag tmp = {0};
assert(tag);
tag_clean(tag);
tmp.type = TAG_STRUCT;
- if (! struct_init_with_data(&tmp.data.struct_, module, data))
+ if (! struct_init_with_data(&tmp.data.struct_, module, data,
+ free_data))
return NULL;
*tag = tmp;
return tag;
diff --git a/libkc3/tag_init.h b/libkc3/tag_init.h
index f1b8605..6453eab 100644
--- a/libkc3/tag_init.h
+++ b/libkc3/tag_init.h
@@ -53,7 +53,7 @@ s_tag * tag_init_str_cat (s_tag *tag, const s_str *a, const s_str *b);
s_tag * tag_init_str_empty (s_tag *tag);
s_tag * tag_init_struct (s_tag *tag, const s_sym *module);
s_tag * tag_init_struct_with_data (s_tag *tag, const s_sym *module,
- void *data);
+ void *data, bool free_data);
s_tag * tag_init_struct_type (s_tag *tag, const s_sym *module,
const s_list *spec);
s_tag * tag_init_struct_type_update_clean (s_tag *tag,
@@ -110,7 +110,8 @@ s_tag * tag_new_str_1 (char *p_free, const char *p);
s_tag * tag_new_str_cat (const s_str *a, const s_str *b);
s_tag * tag_new_str_empty (void);
s_tag * tag_new_struct (const s_sym *module);
-s_tag * tag_new_struct_with_data (const s_sym *module, void *data);
+s_tag * tag_new_struct_with_data (const s_sym *module, void *data,
+ bool free_data);
s_tag * tag_new_struct_type (const s_sym *module, const s_list *spec);
s_tag * tag_new_struct_type_update_clean (const s_struct_type *st,
const s_cfn *clean);
@@ -166,7 +167,7 @@ s_tag * tag_str_cat (s_tag *tag, const s_str *a, const s_str *b);
s_tag * tag_str_empty (s_tag *tag);
s_tag * tag_struct (s_tag *tag, const s_sym *module);
s_tag * tag_struct_with_data (s_tag *tag, const s_sym *module,
- void *data);
+ void *data, bool free_data);
s_tag * tag_struct_type (s_tag *tag, const s_sym *module,
const s_list *spec);
s_tag * tag_struct_type_update_clean (s_tag *tag,
diff --git a/libkc3/tag_init.rb b/libkc3/tag_init.rb
index 72a7cde..245839b 100644
--- a/libkc3/tag_init.rb
+++ b/libkc3/tag_init.rb
@@ -376,7 +376,8 @@ class TagInitList
[Arg.new("const s_sym *", "module")]),
TagInit.new("struct", "with_data", "TAG_STRUCT", :init_mode_init,
[Arg.new("const s_sym *", "module"),
- Arg.new("void *", "data")]),
+ Arg.new("void *", "data"),
+ Arg.new("bool", "free_data")]),
TagInit.new("struct_type", "TAG_STRUCT_TYPE", :init_mode_init,
[Arg.new("const s_sym *", "module"),
Arg.new("const s_list *", "spec")]),
diff --git a/libkc3/types.h b/libkc3/types.h
index 5c617c4..8c96778 100644
--- a/libkc3/types.h
+++ b/libkc3/types.h
@@ -301,6 +301,7 @@ struct quote {
struct struct_ {
void *data;
+ bool free_data;
s_tag *tag;
const s_struct_type *type;
};
diff --git a/libkc3_window/sdl2/demo/earth.c b/libkc3_window/sdl2/demo/earth.c
index 28e241d..45952dc 100644
--- a/libkc3_window/sdl2/demo/earth.c
+++ b/libkc3_window/sdl2/demo/earth.c
@@ -56,7 +56,7 @@ bool earth_load (s_sequence *seq)
tag_init_f64( map->value + 1, 0.01);
tag_init_sym( map->key + 2, sym_1("sphere"));
tag_init_struct_with_data(map->value + 2, sym_1("GL.Sphere"),
- sphere);
+ sphere, false);
return true;
}
diff --git a/test/Makefile b/test/Makefile
index bdb861d..bc10586 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -80,6 +80,9 @@ gdb_test_ekc3:
gdb_test_http:
cd http && gdb ../../ikc3/.libs/ikc3_debug
+gdb_test_ikc3:
+ cd ikc3 && gdb ../../ikc3/.libs/ikc3_debug
+
lldb_test: debug
if [ -f libkc3_test_debug.core ]; then lldb .libs/libkc3_test_debug libkc3_test_debug.core; else lldb .libs/libkc3_test_debug; fi
diff --git a/test/ikc3/buf.kc3 b/test/ikc3/buf.kc3
new file mode 100644
index 0000000..f0268c5
--- /dev/null
+++ b/test/ikc3/buf.kc3
@@ -0,0 +1,2 @@
+quote %Buf{}
+%Buf{}
diff --git a/test/ikc3/buf.out.expected b/test/ikc3/buf.out.expected
new file mode 100644
index 0000000..aea9558
--- /dev/null
+++ b/test/ikc3/buf.out.expected
@@ -0,0 +1,2 @@
+%Buf{}
+%Buf{column: 0, flush: (Ptr) 0x0, free: false, line: 0, ptr: (Ptr) 0x0, refill: (Ptr) 0x0, rpos: 0, save: (Ptr) 0x0, seek: (Ptr) 0x0, size: 0, user_ptr: (Ptr) 0x0, wpos: 0}
diff --git a/test/ikc3/buf.ret.expected b/test/ikc3/buf.ret.expected
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/test/ikc3/buf.ret.expected
@@ -0,0 +1 @@
+0
diff --git a/test/ikc3/buf_rw.kc3 b/test/ikc3/buf_rw.kc3
new file mode 100644
index 0000000..77248ef
--- /dev/null
+++ b/test/ikc3/buf_rw.kc3
@@ -0,0 +1,2 @@
+quote %BufRW{}
+%BufRW{}
diff --git a/test/ikc3/buf_rw.out.expected b/test/ikc3/buf_rw.out.expected
new file mode 100644
index 0000000..9404390
--- /dev/null
+++ b/test/ikc3/buf_rw.out.expected
@@ -0,0 +1,2 @@
+%BufRW{}
+%BufRW{r: %Buf{column: 0, flush: (Ptr) 0x0, free: false, line: 0, ptr: (Ptr) 0x0, refill: (Ptr) 0x0, rpos: 0, save: (Ptr) 0x0, seek: (Ptr) 0x0, size: 0, user_ptr: (Ptr) 0x0, wpos: 0}, w: %Buf{column: 0, flush: (Ptr) 0x0, free: false, line: 0, ptr: (Ptr) 0x0, refill: (Ptr) 0x0, rpos: 0, save: (Ptr) 0x0, seek: (Ptr) 0x0, size: 0, user_ptr: (Ptr) 0x0, wpos: 0}}
diff --git a/test/ikc3/buf_rw.ret.expected b/test/ikc3/buf_rw.ret.expected
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/test/ikc3/buf_rw.ret.expected
@@ -0,0 +1 @@
+0