Commit c494666d83dce212099d35b2797000a12c942a65

Thomas de Grivel 2022-12-22T03:13:21

facts_dump

diff --git a/libc3/env.c b/libc3/env.c
index ce72f3c..ba90437 100644
--- a/libc3/env.c
+++ b/libc3/env.c
@@ -49,7 +49,7 @@ void env_error_tag (s_env *env, const s_tag *tag)
 {
   s_error_handler *error_handler;
   assert(env);
-  assert(str);
+  assert(tag);
   error_handler = env->error_handler;
   if (error_handler) {
     tag_copy(tag, &error_handler->tag);
@@ -240,7 +240,7 @@ s_tag * env_unwind_protect (s_env *env, s_tag *protected, s_list *cleanup,
   s_tag tmp;
   s_unwind_protect unwind_protect;
   assert(env);
-  assert(protect);
+  assert(protected);
   if (setjmp(unwind_protect.buf)) {
     env_pop_unwind_protect(env);
     env_eval_progn(env, cleanup, &tmp);
diff --git a/libc3/facts.c b/libc3/facts.c
index e9392f2..2d3d1ca 100644
--- a/libc3/facts.c
+++ b/libc3/facts.c
@@ -76,35 +76,46 @@ void facts_delete (s_facts *facts)
   free(facts);
 }
 
-sw facts_dump (const s_facts *facts, const s8 *path)
+sw facts_dump (const s_facts *facts, s_buf *buf)
 {
-  s_buf buf;
   s_facts_cursor cursor;
   s_fact *fact;
-  FILE *fp;
   s_tag predicate;
   s_tag object;
   sw r;
   sw result = 0;
   s_tag subject;
   assert(facts);
-  assert(path);
-  BUF_INIT_ALLOCA(&buf, 1024);
-  fp = fopen(path, "w");
-  buf_file_open_w(&buf, fp);
+  assert(buf);
   tag_init_var(&subject);
   tag_init_var(&predicate);
   tag_init_var(&object);
   facts_with_0(facts, &cursor, &subject, &predicate, &object);
   while ((fact = facts_cursor_next(&cursor))) {
-    if ((r = facts_log_add(&buf, fact)) < 0)
-      goto clean;
+    if ((r = facts_log_add(buf, fact)) < 0)
+      return r;
     result += r;
   }
- clean:
+  return result;
+}
+
+sw facts_dump_file (const s_facts *facts, const s8 *path)
+{
+  s_buf buf;
+  FILE *fp;
+  sw r;
+  assert(facts);
+  assert(path);
+  BUF_INIT_ALLOCA(&buf, 1024);
+  if (! (fp = fopen(path, "wb"))) {
+    warn("fopen: %s", path);
+    return -1;
+  }
+  buf_file_open_w(&buf, fp);
+  r = facts_dump(facts, &buf);
   buf_file_close(&buf);
   fclose(fp);
-  return result;
+  return r;
 }
 
 s_fact * facts_find_fact (const s_facts *facts, const s_fact *fact)
@@ -151,40 +162,48 @@ s_facts * facts_init (s_facts *facts, s_buf *log)
   return facts;
 }
 
-/* XXX nested databases should be used with care */
-sw facts_load (s_facts *facts, const s8 *path)
+sw facts_load (s_facts *facts, s_buf *buf)
 {
-  s_buf buf;
   s_fact fact;
-  FILE *fp;
   sw r;
   sw result = 0;
   assert(facts);
-  assert(path);
-  BUF_INIT_ALLOCA(&buf, 1024);
-  fp = fopen(path, "r");
-  buf_file_open_r(&buf, fp);
+  assert(buf);
   while (1) {
-    if ((r = buf_read_1(&buf, "add ")) < 0)
+    if ((r = buf_read_1(buf, "add ")) < 0)
       break;
     result += r;
     if (r) {
-      if ((r = buf_parse_fact(&buf, &fact)) <= 0)
+      if ((r = buf_parse_fact(buf, &fact)) <= 0)
         break;
       result += r;
       facts_add_fact(facts, &fact);
       goto ok;
     }
-    if ((r = buf_read_1(&buf, "remove ")) <= 0)
+    if ((r = buf_read_1(buf, "remove ")) <= 0)
       break;
     result += r;
-    if ((r = buf_parse_fact(&buf, &fact)) <= 0)
+    if ((r = buf_parse_fact(buf, &fact)) <= 0)
       break;
     result += r;
     facts_remove_fact(facts, &fact);
   ok:
-    buf_read_1(&buf, "\n");
+    buf_read_1(buf, "\n");
   }
+  return result;
+}
+
+sw facts_load_file (s_facts *facts, const s8 *path)
+{
+  s_buf buf;
+  FILE *fp;
+  sw result;
+  assert(facts);
+  assert(path);
+  BUF_INIT_ALLOCA(&buf, 1024);
+  fp = fopen(path, "r");
+  buf_file_open_r(&buf, fp);
+  result = facts_load(facts, &buf);
   buf_file_close(&buf);
   fclose(fp);
   return result;
diff --git a/libc3/facts.h b/libc3/facts.h
index 6b07af7..2b6bf25 100644
--- a/libc3/facts.h
+++ b/libc3/facts.h
@@ -31,16 +31,21 @@ s_fact * facts_add_fact (s_facts *facts, const s_fact *fact);
 s_fact * facts_add_tags (s_facts *facts, const s_tag *subject,
                          const s_tag *predicate,
                          const s_tag *object);
-sw       facts_load (s_facts *facts, const s8 *path);
+void     facts_close (s_facts *facts);
+sw       facts_load (s_facts *facts, s_buf *buf);
+sw       facts_load_file (s_facts *facts, const s8 *path);
+sw       facts_open (s_facts *facts, const s8 *path);
 s_tag *  facts_ref_tag (s_facts *facts, const s_tag *tag);
 e_bool   facts_remove_fact (s_facts *facts, const s_fact *fact);
 e_bool   facts_unref_tag (s_facts *facts, const s_tag *tag);
 
 /* Observers */
-sw       facts_dump (const s_facts *facts, const s8 *path);
+sw       facts_dump (const s_facts *facts, s_buf *buf);
+sw       facts_dump_file (const s_facts *facts, const s8 *path);
 s_fact * facts_find_fact (const s_facts *facts, const s_fact *fact);
 s_tag *  facts_find_tag (const s_facts *facts, const s_tag *tag);
 sw       facts_log_add (s_buf *log, const s_fact *fact);
 sw       facts_log_remove (s_buf *log, const s_fact *fact);
+sw       facts_save (s_facts *facts, const s8 *path);
 
 #endif /* FACTS_H */
diff --git a/test/facts_test.c b/test/facts_test.c
index 118fa63..9bd589b 100644
--- a/test/facts_test.c
+++ b/test/facts_test.c
@@ -20,7 +20,7 @@
 
 void facts_test ();
 void facts_test_add ();
-void facts_test_dump ();
+void facts_test_dump_file ();
 void facts_test_find ();
 void facts_test_init_clean ();
 void facts_test_load ();
@@ -38,7 +38,7 @@ void facts_test ()
   facts_test_find();
   facts_test_log_add();
   facts_test_log_remove();
-  facts_test_dump();
+  facts_test_dump_file();
 }
 
 void facts_test_add ()
@@ -94,7 +94,7 @@ void facts_test_add ()
   facts_clean(&facts);
 }
 
-void facts_test_dump ()
+void facts_test_dump_file ()
 {
   uw i = 0;
   s8 *p[24] = {
@@ -131,11 +131,11 @@ void facts_test_dump ()
     facts_add_fact(&facts, fact + i);
     i++;
   }
-  facts_dump(&facts, "facts_test_dump.facts");
-  test_file_compare("facts_test_dump.facts",
-                    "facts_test_dump.facts.expected");
+  facts_dump_file(&facts, "facts_test_dump_file.facts");
+  test_file_compare("facts_test_dump_file.facts",
+                    "facts_test_dump_file.facts.expected");
   if (g_test_last_ok)
-    unlink("facts_test_dump.facts");
+    unlink("facts_test_dump_file.facts");
   i = 0;
   while (p[i]) {
     fact_test_clean_1(fact + i);
diff --git a/test/facts_test_dump.facts.expected b/test/facts_test_dump.facts.expected
deleted file mode 100644
index bebffb3..0000000
--- a/test/facts_test_dump.facts.expected
+++ /dev/null
@@ -1,23 +0,0 @@
-add {a, a, a}
-add {-18446744073709551616, -18446744073709551616, -18446744073709551616}
-add {18446744073709551616, 18446744073709551616, 18446744073709551616}
-add {-4294967296, -4294967296, -4294967296}
-add {-65536, -65536, -65536}
-add {-256, -256, -256}
-add {-10, -10, -10}
-add {-1, -1, -1}
-add {0, 0, 0}
-add {1, 1, 1}
-add {10, 10, 10}
-add {256, 256, 256}
-add {65536, 65536, 65536}
-add {4294967296, 4294967296, 4294967296}
-add {[], [], []}
-add {[[], []], [[], []], [[], []]}
-add {"a", "a", "a"}
-add {A, A, A}
-add {:a, :a, :a}
-add {{a, b}, {a, b}, {a, b}}
-add {{:a, :b}, {:a, :b}, {:a, :b}}
-add {{{a, b}, {c, d}}, {{a, b}, {c, d}}, {{a, b}, {c, d}}}
-add {{{:a, :b}, {:c, :d}}, {{:a, :b}, {:c, :d}}, {{:a, :b}, {:c, :d}}}
diff --git a/test/facts_test_dump_file.facts.expected b/test/facts_test_dump_file.facts.expected
new file mode 100644
index 0000000..bebffb3
--- /dev/null
+++ b/test/facts_test_dump_file.facts.expected
@@ -0,0 +1,23 @@
+add {a, a, a}
+add {-18446744073709551616, -18446744073709551616, -18446744073709551616}
+add {18446744073709551616, 18446744073709551616, 18446744073709551616}
+add {-4294967296, -4294967296, -4294967296}
+add {-65536, -65536, -65536}
+add {-256, -256, -256}
+add {-10, -10, -10}
+add {-1, -1, -1}
+add {0, 0, 0}
+add {1, 1, 1}
+add {10, 10, 10}
+add {256, 256, 256}
+add {65536, 65536, 65536}
+add {4294967296, 4294967296, 4294967296}
+add {[], [], []}
+add {[[], []], [[], []], [[], []]}
+add {"a", "a", "a"}
+add {A, A, A}
+add {:a, :a, :a}
+add {{a, b}, {a, b}, {a, b}}
+add {{:a, :b}, {:a, :b}, {:a, :b}}
+add {{{a, b}, {c, d}}, {{a, b}, {c, d}}, {{a, b}, {c, d}}}
+add {{{:a, :b}, {:c, :d}}, {{:a, :b}, {:c, :d}}, {{:a, :b}, {:c, :d}}}
diff --git a/test/test.c b/test/test.c
index 8bb4142..46f079e 100644
--- a/test/test.c
+++ b/test/test.c
@@ -67,6 +67,7 @@ int test_file_compare (const char *path_a, const char *path_b)
          path_a, path_b, lineno,
          TEST_COLOR_RESET);
   test_ko();
+  return 1;
  ok:
   test_ok();
   return 0;