Commit 93111ebdf74c4616e077dd8714cd83c8876534dc

Thomas de Grivel 2023-01-30T11:32:35

fix memleak

diff --git a/libc3/buf_parse.c b/libc3/buf_parse.c
index 0c071bf..36042b0 100644
--- a/libc3/buf_parse.c
+++ b/libc3/buf_parse.c
@@ -339,7 +339,7 @@ sw buf_parse_digit_dec (s_buf *buf, u8 *dest)
   return r;
 }
 
-sw buf_parse_fact (s_buf *buf, s_fact *dest)
+sw buf_parse_fact (s_buf *buf, s_fact_w *dest)
 {
   s_tag *object = NULL;
   s_tag *predicate = NULL;
diff --git a/libc3/buf_parse.h b/libc3/buf_parse.h
index 17e6713..814fa39 100644
--- a/libc3/buf_parse.h
+++ b/libc3/buf_parse.h
@@ -39,7 +39,7 @@ sw buf_parse_digit_oct (s_buf *buf, u8 *dest);
 sw buf_parse_digit_dec (s_buf *buf, u8 *dest);
 sw buf_parse_f32 (s_buf *buf, f32 *dest);
 sw buf_parse_f64 (s_buf *buf, f64 *dest);
-sw buf_parse_fact (s_buf *buf, s_fact *dest);
+sw buf_parse_fact (s_buf *buf, s_fact_w *dest);
 sw buf_parse_fn (s_buf *buf, s_fn *dest);
 sw buf_parse_fn_algo (s_buf *buf, s_list **dest);
 sw buf_parse_fn_args (s_buf *buf, s_arg **dest);
diff --git a/libc3/fact.c b/libc3/fact.c
index de3dce6..cb9214f 100644
--- a/libc3/fact.c
+++ b/libc3/fact.c
@@ -64,3 +64,18 @@ s_str * fact_inspect (const s_fact *fact, s_str *dest)
   }
   return buf_to_str(&buf, dest);
 }
+
+s_fact * fact_r (const s_fact_w *fact)
+{
+  return (s_fact *) fact;
+}
+
+void fact_w_clean (s_fact_w *fact)
+{
+  tag_delete(fact->subject);
+  fact->subject = NULL;
+  tag_delete(fact->predicate);
+  fact->predicate = NULL;
+  tag_delete(fact->object);
+  fact->object = NULL;
+}
diff --git a/libc3/fact.h b/libc3/fact.h
index 95a736c..61a506b 100644
--- a/libc3/fact.h
+++ b/libc3/fact.h
@@ -25,5 +25,9 @@ s_fact * fact_init (s_fact *fact, const s_tag *subject,
 s_fact * fact_copy (const s_fact *src, s_fact *dest);
 uw       fact_hash_uw (const s_fact *x);
 s_str *  fact_inspect (const s_fact *fact, s_str *dest);
+s_fact * fact_r (const s_fact_w *fact);
+
+/* Modifiers */
+void fact_w_clean (s_fact_w *fact);
 
 #endif /* FACT_H */
diff --git a/libc3/facts.c b/libc3/facts.c
index fd7e1fa..832ef50 100644
--- a/libc3/facts.c
+++ b/libc3/facts.c
@@ -208,7 +208,8 @@ s_facts * facts_init (s_facts *facts)
 sw facts_load (s_facts *facts, s_buf *buf)
 {
   u64 count;
-  s_fact fact;
+  s_fact_w fact;
+  s_fact *factp = fact_r(&fact);
   t_hash hash;
   u64 hash_u64;
   u64 hash_u64_buf;
@@ -234,8 +235,9 @@ sw facts_load (s_facts *facts, s_buf *buf)
     if ((r = buf_parse_fact(buf, &fact)) <= 0)
       goto ko_fact;
     result += r;
-    hash_update_fact(&hash, &fact);
-    facts_add_fact(facts, &fact);
+    hash_update_fact(&hash, factp);
+    facts_add_fact(facts, factp);
+    fact_w_clean(&fact);
     if ((r = buf_read_1(buf, "\n")) <= 0) {
       r = -1;
       goto ko_fact;
@@ -419,7 +421,8 @@ sw facts_open_file_create (s_facts *facts, const s8 *path)
 
 sw facts_open_log (s_facts *facts, s_buf *buf)
 {
-  s_fact fact;
+  s_fact_w fact;
+  s_fact *factp = fact_r(&fact);
   sw r;
   sw result = 0;
   assert(facts);
@@ -432,7 +435,7 @@ sw facts_open_log (s_facts *facts, s_buf *buf)
       if ((r = buf_parse_fact(buf, &fact)) <= 0)
         break;
       result += r;
-      facts_add_fact(facts, &fact);
+      facts_add_fact(facts, factp);
       goto ok;
     }
     if ((r = buf_read_1(buf, "remove ")) <= 0)
@@ -441,8 +444,9 @@ sw facts_open_log (s_facts *facts, s_buf *buf)
     if ((r = buf_parse_fact(buf, &fact)) <= 0)
       break;
     result += r;
-    facts_remove_fact(facts, &fact);
+    facts_remove_fact(facts, factp);
   ok:
+    fact_w_clean(&fact);
     if ((r = buf_read_1(buf, "\n")) <= 0)
       break;
     result += r;
diff --git a/libc3/types.h b/libc3/types.h
index 6b911ce..e2e0c48 100644
--- a/libc3/types.h
+++ b/libc3/types.h
@@ -89,6 +89,7 @@ typedef struct call                    s_call;
 typedef struct env                     s_env;
 typedef struct error_handler           s_error_handler;
 typedef struct fact                    s_fact;
+typedef struct fact_w                  s_fact_w;
 typedef struct facts                   s_facts;
 typedef struct facts_cursor            s_facts_cursor;
 typedef struct facts_spec_cursor       s_facts_spec_cursor;
@@ -142,6 +143,13 @@ struct fact {
   uw id; /* XXX random without collision */
 };
 
+struct fact_w {
+  s_tag *subject;
+  s_tag *predicate;
+  s_tag *object;
+  uw id; /* XXX random without collision */
+};
+
 struct frame {
   s_binding *bindings;
   s_frame *next;