diff --git a/libc3/buf_inspect.c b/libc3/buf_inspect.c
index 540475a..e5a7ec5 100644
--- a/libc3/buf_inspect.c
+++ b/libc3/buf_inspect.c
@@ -194,6 +194,33 @@ sw buf_inspect_fact_size (const s_fact *fact)
return result;
}
+sw buf_inspect_fact_spec (s_buf *buf, p_facts_spec spec)
+{
+ sw r;
+ sw result = 0;
+ if (spec) {
+ if ((r = buf_write_1(buf, "{")) < 0)
+ return r;
+ result += r;
+ if ((r = buf_inspect_tag(buf, spec[0])) < 0)
+ return r;
+ result += r;
+ while (spec[0] || spec[1]) {
+ spec++;
+ if ((r = buf_write_1(buf, ", ")) < 0)
+ return r;
+ result += r;
+ if ((r = buf_inspect_tag(buf, spec[0])) < 0)
+ return r;
+ result += r;
+ }
+ if ((r = buf_write_1(buf, "}")) < 0)
+ return r;
+ result += r;
+ }
+ return result;
+}
+
sw buf_inspect_ident (s_buf *buf, const s_ident *ident)
{
sw r;
@@ -754,7 +781,8 @@ sw buf_inspect_sym_reserved_size (const s_sym *x)
sw buf_inspect_tag (s_buf *buf, const s_tag *tag)
{
- assert(tag);
+ if (! tag)
+ return buf_write_1(buf, "NULL");
switch(tag->type.type) {
case TAG_VOID: return 0;
case TAG_BOOL: return buf_inspect_bool(buf, tag->data.bool);
@@ -779,7 +807,7 @@ sw buf_inspect_tag (s_buf *buf, const s_tag *tag)
case TAG_U16: return buf_inspect_u16(buf, tag->data.u16);
case TAG_U32: return buf_inspect_u32(buf, tag->data.u32);
case TAG_U64: return buf_inspect_u64(buf, tag->data.u64);
- case TAG_VAR: break;
+ case TAG_VAR: return buf_inspect_var(buf, tag->data.var);
}
assert(! "unknown tag type");
return -1;
@@ -1007,13 +1035,30 @@ sw buf_inspect_u64 (s_buf *buf, u64 x)
return size;
}
-sw buf_inspect_u64_size (u64 x)
+sw buf_inspect_u64_hex (s_buf *buf, u64 i)
+{
+ const s8 basis[] = "0123456789ABCDEF";
+ uw shift = 64;
+ while (shift) {
+ shift -= 4;
+ buf_write_s8(buf, basis[(i >> shift) & 0xF]);
+ }
+ return 16;
+}
+
+sw buf_inspect_u64_hex_size (u64 i)
+{
+ (void) i;
+ return 16;
+}
+
+sw buf_inspect_u64_size (u64 i)
{
sw size = 0;
- if (x == 0)
+ if (i == 0)
return 1;
- while (x > 0) {
- x /= 10;
+ while (i > 0) {
+ i /= 10;
size++;
}
return size;
@@ -1021,21 +1066,35 @@ sw buf_inspect_u64_size (u64 x)
sw buf_inspect_uw_hex (s_buf *buf, uw i)
{
- const s8 map[] = "0123456789ABCDEF";
- u8 s = (sizeof(uw) - 1) / 4;
- uw w = 0xF << s;
- sw r;
- while (0xF < w) {
- if ((r = buf_write_u8(buf, map[(i & w) >> s])) < 0)
- return r;
- s -= 4;
- w >>= 4;
- }
- return sizeof(uw) / 4;
+ if (sizeof(uw) == 8)
+ return buf_inspect_u64_hex(buf, i);
+ if (sizeof(uw) == 4)
+ return buf_inspect_u32_hex(buf, i);
+ assert(! "unknown word size");
+ return -1;
}
-sw buf_inspect_uw_hex_size (uw x)
+sw buf_inspect_uw_hex_size (uw i)
{
- (void) x;
+ (void) i;
return sizeof(uw) / 4;
}
+
+sw buf_inspect_var (s_buf *buf, const s_tag *var)
+{
+ sw r;
+ sw result = 0;
+ if ((r = buf_write_1(buf, "var(0x")) < 0)
+ return r;
+ result += r;
+ if ((r = buf_inspect_uw_hex(buf, (uw) var)) < 0)
+ return r;
+ result += r;
+ if ((r = buf_write_1(buf, ") = ")) < 0)
+ return r;
+ result += r;
+ if ((r = buf_inspect_tag(buf, var)) < 0)
+ return r;
+ result += r;
+ return result;
+}
diff --git a/libc3/buf_inspect.h b/libc3/buf_inspect.h
index 9b4c029..7f19b8d 100644
--- a/libc3/buf_inspect.h
+++ b/libc3/buf_inspect.h
@@ -26,17 +26,18 @@ extern const sw buf_inspect_str_byte_size;
sw buf_inspect_bool (s_buf *buf, e_bool b);
sw buf_inspect_bool_size (e_bool b);
+sw buf_inspect_call (s_buf *buf, const s_call *funcall);
+sw buf_inspect_call_args (s_buf *buf, const s_list *args);
+sw buf_inspect_call_size (const s_call *funcall);
sw buf_inspect_character (s_buf *buf, character c);
sw buf_inspect_character_size (character c);
sw buf_inspect_f32 (s_buf *buf, f32 x);
sw buf_inspect_f32_size (f32 x);
sw buf_inspect_f64 (s_buf *buf, f64 x);
sw buf_inspect_f64_size (f64 x);
-sw buf_inspect_call (s_buf *buf, const s_call *funcall);
-sw buf_inspect_call_args (s_buf *buf, const s_list *args);
-sw buf_inspect_call_size (const s_call *funcall);
sw buf_inspect_fact (s_buf *buf, const s_fact *fact);
sw buf_inspect_fact_size (const s_fact *fact);
+sw buf_inspect_fact_spec (s_buf *buf, p_facts_spec spec);
sw buf_inspect_ident (s_buf *buf, const s_ident *ident);
sw buf_inspect_ident_size (const s_ident *ident);
sw buf_inspect_integer (s_buf *buf, const s_integer *x);
@@ -71,9 +72,14 @@ sw buf_inspect_u16 (s_buf *buf, u16 i);
sw buf_inspect_u16_size (u16 i);
sw buf_inspect_u32 (s_buf *buf, u32 i);
sw buf_inspect_u32_size (u32 i);
+sw buf_inspect_u32_hex (s_buf *buf, u32 i);
+sw buf_inspect_u32_hex_size (u32 i);
+sw buf_inspect_u64_hex (s_buf *buf, u64 i);
+sw buf_inspect_u64_hex_size (u64 i);
sw buf_inspect_u64 (s_buf *buf, u64 i);
sw buf_inspect_u64_size (u64 i);
sw buf_inspect_uw_hex (s_buf *buf, uw i);
sw buf_inspect_uw_hex_size (uw i);
+sw buf_inspect_var (s_buf *buf, const s_tag *var);
#endif /* BUF_INSPECT_H */
diff --git a/libc3/c3.c b/libc3/c3.c
index c56c941..1cae9e7 100644
--- a/libc3/c3.c
+++ b/libc3/c3.c
@@ -34,9 +34,17 @@ s_module * c3_init (s_module *c3, s_facts *facts)
void libc3_init ()
{
+#ifdef DEBUG
+ buf_init_alloc(&g_debug_buf, 1024);
+ buf_file_open_w(&g_debug_buf, stderr);
+#endif
}
void libc3_shutdown ()
{
sym_delete_all();
+#ifdef DEBUG
+ buf_file_close(&g_debug_buf);
+ buf_clean(&g_debug_buf);
+#endif
}
diff --git a/libc3/c3.h b/libc3/c3.h
index bc8abc3..b437fbf 100644
--- a/libc3/c3.h
+++ b/libc3/c3.h
@@ -21,6 +21,7 @@
#include "buf_parse.h"
#include "call.h"
#include "character.h"
+#include "debug.h"
#include "env.h"
#include "eval.h"
#include "f32.h"
diff --git a/libc3/configure b/libc3/configure
index 81adc3a..84e61b0 100755
--- a/libc3/configure
+++ b/libc3/configure
@@ -41,7 +41,7 @@ LDFLAGS="${LDFLAGS:=}"
LIBS="${LIBS:=-lm -lffi}"
# Common config for all targets
-CFLAGS="$CFLAGS -W -Wall -Werror -std=c99 -pedantic"
+CFLAGS="$CFLAGS -W -Wall -Werror -Wno-empty-translation-unit -std=c99 -pedantic"
config_asan
config_libbsd
config_libcrypto
diff --git a/libc3/debug.c b/libc3/debug.c
new file mode 100644
index 0000000..040d424
--- /dev/null
+++ b/libc3/debug.c
@@ -0,0 +1,20 @@
+/* c3
+ * Copyright 2022 kmx.io <contact@kmx.io>
+ *
+ * Permission is hereby granted to use this software granted
+ * the above copyright notice and this permission paragraph
+ * are included in all copies and substantial portions of this
+ * software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
+ * PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
+ * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+#ifdef DEBUG
+
+#include "debug.h"
+
+s_buf g_debug_buf = {0};
+
+#endif /* DEBUG */
diff --git a/libc3/debug.h b/libc3/debug.h
new file mode 100644
index 0000000..8ef5bcc
--- /dev/null
+++ b/libc3/debug.h
@@ -0,0 +1,27 @@
+/* c3
+ * Copyright 2022 kmx.io <contact@kmx.io>
+ *
+ * Permission is hereby granted to use this software granted
+ * the above copyright notice and this permission paragraph
+ * are included in all copies and substantial portions of this
+ * software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
+ * PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
+ * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+#ifdef DEBUG
+
+#ifndef DEBUG_H
+#define DEBUG_H
+
+#include "buf.h"
+#include "buf_inspect.h"
+#include "types.h"
+
+extern s_buf g_debug_buf;
+
+#endif /* DEBUG_H */
+
+#endif /* DEBUG */
diff --git a/libc3/fact.c b/libc3/fact.c
index 05c1d7c..a09c4b8 100644
--- a/libc3/fact.c
+++ b/libc3/fact.c
@@ -29,9 +29,11 @@ s8 fact_compare (const s_fact *a, const s_fact *b)
return -1;
if (!b)
return 1;
- (void) ((r = tag_compare(a->subject, b->subject)) ||
- (r = tag_compare(a->predicate, b->predicate)) ||
- (r = tag_compare(a->object, b->object)));
+ if ((r = tag_compare(a->subject, b->subject)))
+ return r;
+ if ((r = tag_compare(a->predicate, b->predicate)))
+ return r;
+ r = tag_compare(a->object, b->object);
return r;
}
@@ -72,9 +74,11 @@ s8 fact_compare_pos (const s_fact *a, const s_fact *b)
return -1;
if (!b)
return 1;
- (void) ((r = tag_compare(a->predicate, b->predicate)) ||
- (r = tag_compare(a->object, b->object)) ||
- (r = tag_compare(a->subject, b->subject)));
+ if ((r = tag_compare(a->predicate, b->predicate)))
+ return r;
+ if ((r = tag_compare(a->object, b->object)))
+ return r;
+ r = tag_compare(a->subject, b->subject);
return r;
}
@@ -87,9 +91,11 @@ s8 fact_compare_osp (const s_fact *a, const s_fact *b)
return -1;
if (!b)
return 1;
- (void) ((r = tag_compare(a->object, b->object)) ||
- (r = tag_compare(a->subject, b->subject)) ||
- (r = tag_compare(a->predicate, b->predicate)));
+ if ((r = tag_compare(a->object, b->object)))
+ return r;
+ if ((r = tag_compare(a->subject, b->subject)))
+ return r;
+ r = tag_compare(a->predicate, b->predicate);
return r;
}
diff --git a/libc3/facts_cursor.c b/libc3/facts_cursor.c
index 43bd0ad..e671c13 100644
--- a/libc3/facts_cursor.c
+++ b/libc3/facts_cursor.c
@@ -20,35 +20,35 @@
#include "tag.h"
s_facts_cursor * facts_cursor_init (s_facts_cursor *cursor,
- s_skiplist__fact *tree,
+ s_skiplist__fact *index,
s_fact *start,
s_fact *end)
{
s_skiplist_node__fact *pred;
assert(cursor);
- assert(tree);
- pred = skiplist_pred__fact(tree, start);
+ assert(index);
+ pred = skiplist_pred__fact(index, start);
assert(pred);
- cursor->tree = tree;
+ cursor->index = index;
cursor->node = SKIPLIST_NODE_NEXT__fact(pred, 0);
skiplist_node_delete__fact(pred);
if (start)
cursor->start = *start;
else {
- cursor->start.subject =
- cursor->start.predicate =
- cursor->start.object = TAG_FIRST;
+ cursor->start.subject = TAG_FIRST;
+ cursor->start.predicate = TAG_FIRST;
+ cursor->start.object = TAG_FIRST;
}
if (end)
cursor->end = *end;
else {
- cursor->end.subject =
- cursor->end.predicate =
- cursor->end.object = TAG_LAST;
+ cursor->end.subject = TAG_LAST;
+ cursor->end.predicate = TAG_LAST;
+ cursor->end.object = TAG_LAST;
}
- cursor->var_subject = NULL;
+ cursor->var_subject = NULL;
cursor->var_predicate = NULL;
- cursor->var_object = NULL;
+ cursor->var_object = NULL;
return cursor;
}
@@ -58,7 +58,7 @@ s_fact * facts_cursor_next (s_facts_cursor *cursor)
if (cursor->node) {
cursor->node = SKIPLIST_NODE_NEXT__fact(cursor->node, 0);
if (cursor->node &&
- cursor->tree->compare(&cursor->end, cursor->node->fact) < 0)
+ cursor->index->compare(&cursor->end, cursor->node->fact) < 0)
cursor->node = NULL;
}
if (cursor->node) {
diff --git a/libc3/facts_with.c b/libc3/facts_with.c
index 04a6d1a..7d64d8c 100644
--- a/libc3/facts_with.c
+++ b/libc3/facts_with.c
@@ -18,6 +18,31 @@
#include "facts_with.h"
#include "tag.h"
+s_facts_with_cursor * facts_with (const s_facts *facts,
+ s_facts_with_cursor *cursor,
+ p_facts_spec spec)
+{
+ uw facts_count;
+ assert(facts);
+ assert(cursor);
+ assert(spec);
+ facts_count = facts_spec_count_facts(spec);
+ cursor->facts = facts;
+ cursor->facts_count = facts_count;
+ if (facts_count > 0) {
+ cursor->levels = calloc(facts_count,
+ sizeof(s_facts_with_cursor_level));
+ cursor->spec = facts_spec_new_expand(spec);
+ /* facts_spec_sort(cursor->spec); */
+ }
+ else {
+ cursor->levels = NULL;
+ cursor->spec = NULL;
+ }
+ cursor->level = 0;
+ return cursor;
+}
+
s_facts_cursor * facts_with_0 (const s_facts *facts,
s_facts_cursor *cursor,
s_tag *var_subject,
@@ -57,9 +82,12 @@ s_facts_cursor * facts_with_1_2 (const s_facts *facts,
end.subject = var_subject ? TAG_LAST : subject;
end.predicate = var_predicate ? TAG_LAST : predicate;
end.object = var_object ? TAG_LAST : object;
- tree = (! var_subject && var_object) ? facts->index_spo :
- ! var_predicate ? facts->index_pos :
- facts->index_osp;
+ if (! var_subject && var_object)
+ tree = facts->index_spo;
+ else if (! var_predicate)
+ tree = facts->index_pos;
+ else
+ tree = facts->index_osp;
facts_cursor_init(cursor, tree, &start, &end);
cursor->var_subject = var_subject;
cursor->var_predicate = var_predicate;
@@ -113,28 +141,3 @@ s_facts_cursor * facts_with_tags (const s_facts *facts,
return facts_with_1_2(facts, cursor, subject, predicate, object,
var_subject, var_predicate, var_object);
}
-
-s_facts_with_cursor * facts_with (const s_facts *facts,
- s_facts_with_cursor *cursor,
- p_facts_spec spec)
-{
- uw facts_count;
- assert(facts);
- assert(cursor);
- assert(spec);
- facts_count = facts_spec_count_facts(spec);
- cursor->facts = facts;
- cursor->facts_count = facts_count;
- if (facts_count > 0) {
- cursor->l = calloc(facts_count,
- sizeof(s_facts_with_cursor_level));
- cursor->spec = facts_spec_new_expand(spec);
- facts_spec_sort(cursor->spec);
- }
- else {
- cursor->l = NULL;
- cursor->spec = NULL;
- }
- cursor->level = 0;
- return cursor;
-}
diff --git a/libc3/facts_with_cursor.c b/libc3/facts_with_cursor.c
index 31741d0..ed58d35 100644
--- a/libc3/facts_with_cursor.c
+++ b/libc3/facts_with_cursor.c
@@ -13,6 +13,7 @@
*/
#include <assert.h>
#include <stdlib.h>
+#include "debug.h"
#include "facts_cursor.h"
#include "facts_spec.h"
#include "facts_with.h"
@@ -20,8 +21,13 @@
void facts_with_cursor_clean (s_facts_with_cursor *cursor)
{
+ uw i = 0;
assert(cursor);
- free(cursor->l);
+ while (i < cursor->facts_count) {
+ free(cursor->levels[i].spec);
+ i++;
+ }
+ free(cursor->levels);
free(cursor->spec);
}
@@ -34,30 +40,61 @@ s_fact * facts_with_cursor_next (s_facts_with_cursor *cursor)
if (! cursor->facts_count)
return NULL;
if (cursor->level == cursor->facts_count) {
- level = cursor->l + (cursor->facts_count - 1);
+ level = &cursor->levels[cursor->facts_count - 1];
+#ifdef DEBUG
+ buf_write_1(&g_debug_buf, "[debug] cursor->level=");
+ buf_inspect_u64(&g_debug_buf, cursor->level);
+ buf_write_1(&g_debug_buf, " level->spec=");
+ buf_inspect_fact_spec(&g_debug_buf, level->spec);
+ buf_write_1(&g_debug_buf, " ");
+ buf_inspect_fact(&g_debug_buf, level->fact);
+#endif
level->fact = facts_cursor_next(&level->cursor);
+#ifdef DEBUG
+ buf_write_1(&g_debug_buf, " -> ");
+ buf_inspect_fact(&g_debug_buf, level->fact);
+ buf_write_1(&g_debug_buf, "\n");
+ buf_flush(&g_debug_buf);
+#endif
if (level->fact)
return level->fact;
free(level->spec);
level->spec = NULL;
cursor->level--;
- if (!cursor->level) {
+ if (! cursor->level) {
cursor->facts_count = 0;
return NULL;
}
cursor->level--;
}
while (cursor->level < cursor->facts_count) {
- level = cursor->l + cursor->level;
+ level = &cursor->levels[cursor->level];
if (! level->spec) {
- parent_spec = cursor->level ?
- cursor->l[cursor->level - 1].spec + 4 :
- cursor->spec;
+ if (cursor->level)
+ parent_spec = cursor->levels[cursor->level - 1].spec + 4;
+ else
+ parent_spec = cursor->spec;
level->spec = facts_spec_new_expand(parent_spec);
- facts_with_tags(cursor->facts, &level->cursor, level->spec[0],
- level->spec[1], level->spec[2]);
+ facts_with_tags(cursor->facts, &level->cursor,
+ level->spec[0], level->spec[1],
+ level->spec[2]);
}
- level->fact = fact = facts_cursor_next(&level->cursor);
+#ifdef DEBUG
+ buf_write_1(&g_debug_buf, "[debug] cursor->level=");
+ buf_inspect_u64(&g_debug_buf, cursor->level);
+ buf_write_1(&g_debug_buf, " level->spec=");
+ buf_inspect_fact_spec(&g_debug_buf, level->spec);
+ buf_write_1(&g_debug_buf, " ");
+ buf_inspect_fact(&g_debug_buf, level->fact);
+#endif
+ fact = facts_cursor_next(&level->cursor);
+ level->fact = fact;
+#ifdef DEBUG
+ buf_write_1(&g_debug_buf, " -> ");
+ buf_inspect_fact(&g_debug_buf, level->fact);
+ buf_write_1(&g_debug_buf, "\n");
+ buf_flush(&g_debug_buf);
+#endif
if (fact) {
cursor->level++;
continue;
diff --git a/libc3/tag.c b/libc3/tag.c
index b408ff1..f355317 100644
--- a/libc3/tag.c
+++ b/libc3/tag.c
@@ -957,41 +957,6 @@ s_tag * tag_sym_1 (s_tag *tag, const s8 *p)
return tag_init_sym_1(tag, p);
}
-s_tag * tag_u8 (s_tag *tag, u8 x)
-{
- assert(tag);
- tag_clean(tag);
- return tag_init_u8(tag, x);
-}
-
-s_tag * tag_u16 (s_tag *tag, u16 x)
-{
- assert(tag);
- tag_clean(tag);
- return tag_init_u16(tag, x);
-}
-
-s_tag * tag_u32 (s_tag *tag, u32 x)
-{
- assert(tag);
- tag_clean(tag);
- return tag_init_u32(tag, x);
-}
-
-s_tag * tag_u64 (s_tag *tag, u64 x)
-{
- assert(tag);
- tag_clean(tag);
- return tag_init_u64(tag, x);
-}
-
-s_tag * tag_void (s_tag *tag)
-{
- assert(tag);
- tag_clean(tag);
- return tag_init_void(tag);
-}
-
ffi_type tag_to_ffi_type(const s_tag *tag)
{
switch (tag->type.type) {
@@ -1025,6 +990,49 @@ ffi_type tag_to_ffi_type(const s_tag *tag)
return ffi_type_schar;
default: ;
}
- assert(! "tag_to_ffi_type: not a good type");
+ assert(! "tag_to_ffi_type: unknown type");
+ errx(1, "tag_to_ffi_type: unknown type");
return ffi_type_void;
}
+
+s_tag * tag_u8 (s_tag *tag, u8 x)
+{
+ assert(tag);
+ tag_clean(tag);
+ return tag_init_u8(tag, x);
+}
+
+s_tag * tag_u16 (s_tag *tag, u16 x)
+{
+ assert(tag);
+ tag_clean(tag);
+ return tag_init_u16(tag, x);
+}
+
+s_tag * tag_u32 (s_tag *tag, u32 x)
+{
+ assert(tag);
+ tag_clean(tag);
+ return tag_init_u32(tag, x);
+}
+
+s_tag * tag_u64 (s_tag *tag, u64 x)
+{
+ assert(tag);
+ tag_clean(tag);
+ return tag_init_u64(tag, x);
+}
+
+s_tag * tag_var (s_tag *tag)
+{
+ assert(tag);
+ tag_clean(tag);
+ return tag_init_var(tag);
+}
+
+s_tag * tag_void (s_tag *tag)
+{
+ assert(tag);
+ tag_clean(tag);
+ return tag_init_void(tag);
+}
diff --git a/libc3/tag.h b/libc3/tag.h
index f998c1d..026e7b0 100644
--- a/libc3/tag.h
+++ b/libc3/tag.h
@@ -132,6 +132,7 @@ s_tag * tag_u16 (s_tag *tag, u16 i);
s_tag * tag_u32 (s_tag *tag, u32 i);
s_tag * tag_u64 (s_tag *tag, u64 i);
s_tag * tag_u8 (s_tag *tag, u8 i);
+s_tag * tag_var (s_tag *tag);
s_tag * tag_void (s_tag *tag);
ffi_type tag_to_ffi_type(const s_tag *tag);
diff --git a/libc3/types.h b/libc3/types.h
index d2010a3..54ac241 100644
--- a/libc3/types.h
+++ b/libc3/types.h
@@ -271,7 +271,7 @@ typedef struct facts {
} s_facts;
typedef struct facts_cursor {
- s_skiplist__fact *tree;
+ s_skiplist__fact *index;
s_skiplist_node__fact *node;
s_fact start;
s_fact end;
@@ -298,7 +298,7 @@ typedef struct facts_with_cursor {
const s_facts *facts;
s_list *bindings;
size_t facts_count;
- s_facts_with_cursor_level *l;
+ s_facts_with_cursor_level *levels;
size_t level;
p_facts_spec spec;
} s_facts_with_cursor;
diff --git a/test/facts_with_test.c b/test/facts_with_test.c
index e0f2ca6..e292ec6 100644
--- a/test/facts_with_test.c
+++ b/test/facts_with_test.c
@@ -113,16 +113,29 @@ void facts_with_test_ ()
TAG_TEST_EQ(predicate.data.var, tag + 1);
TAG_TEST_EQ(object.data.var, tag + 2);
TEST_ASSERT(facts_with_cursor_next(&cursor));
+ TAG_TEST_EQ(subject.data.var, tag);
+ TAG_TEST_EQ(predicate.data.var, tag + 1);
+ TAG_TEST_EQ(object.data.var, tag + 3);
+ TEST_ASSERT(facts_with_cursor_next(&cursor));
TAG_TEST_EQ(subject.data.var, tag + 5);
TAG_TEST_EQ(predicate.data.var, tag + 1);
TAG_TEST_EQ(object.data.var, tag + 2);
+ TEST_ASSERT(! facts_with_cursor_next(&cursor));
+ TEST_ASSERT(! facts_with_cursor_next(&cursor));
+ facts_with_cursor_clean(&cursor);
+ facts_with(&facts, &cursor, (s_tag *[]) { tag, tag + 1, tag + 2,
+ tag + 1, tag + 3,
+ NULL,
+ tag + 5, tag + 1, tag + 2,
+ NULL, NULL });
TEST_ASSERT(facts_with_cursor_next(&cursor));
- TAG_TEST_EQ(subject.data.var, tag);
+ if (! g_test_last_ok)
+ return;
+ TAG_TEST_EQ(subject.data.var, tag + 5);
TAG_TEST_EQ(predicate.data.var, tag + 1);
- TAG_TEST_EQ(object.data.var, tag + 3);
+ TAG_TEST_EQ(object.data.var, tag + 2);
TEST_ASSERT(! facts_with_cursor_next(&cursor));
TEST_ASSERT(! facts_with_cursor_next(&cursor));
- facts_with_cursor_clean(&cursor);
facts_with(&facts, &cursor, (s_tag *[]) { tag + 3, tag, tag + 1,
tag, tag + 2,
NULL,