diff --git a/libc3/buf_inspect.c b/libc3/buf_inspect.c
index 5367830..1b90457 100644
--- a/libc3/buf_inspect.c
+++ b/libc3/buf_inspect.c
@@ -176,53 +176,110 @@
DEF_BUF_INSPECT_U_BASE(bits, hexadecimal) \
DEF_BUF_INSPECT_U_BASE(bits, octal)
-sw buf_inspect_array (s_buf *buf, const s_array *a)
+sw buf_inspect_array_data (s_buf *buf, const s_array *array);
+sw buf_inspect_array_type (s_buf *buf, const s_array *array);
+
+sw buf_inspect_array_data (s_buf *buf, const s_array *array);
+sw buf_inspect_array_data_rec (s_buf *buf, const s_array *array,
+ uw dimension, uw *address,
+ f_buf_inspect inspect, u8 **data);
+sw buf_inspect_tag_type (s_buf *buf, e_tag_type type);
+
+sw buf_inspect_array_data (s_buf *buf, const s_array *array)
{
uw *address;
- uw i = 0;
+ u8 *data;
f_buf_inspect inspect;
sw r;
- sw result = 0;
- assert(a);
assert(buf);
- if (a->type == TAG_ARRAY) {
- assert(! "buf_inspect_array: array of array");
- errx(1, "buf_inspect_array: array of array");
- return -1;
- }
- inspect = tag_type_to_buf_inspect(a->type);
- if (! (address = calloc(a->dimension, sizeof(uw)))) {
- err(1, "buf_inspect_array: calloc");
- return -1;
- }
- while (i < a->dimension) {
- if (i < a->dimension - 1) {
- if (! address[i]) {
- if ((r = buf_write_1(buf, "{")) < 0)
- return r;
- result += r;
- }
+ assert(array);
+ address = calloc(array->dimension, sizeof(uw));
+ inspect = tag_type_to_buf_inspect(array->type);
+ data = array->data;
+ r = buf_inspect_array_data_rec(buf, array, 0, address,
+ inspect, &data);
+ return r;
+}
+
+sw buf_inspect_array_data_rec (s_buf *buf, const s_array *array,
+ uw dimension, uw *address,
+ f_buf_inspect inspect, u8 **data)
+{
+ sw r;
+ sw result = 0;
+ if ((r = buf_write_1(buf, "{")) <= 0)
+ goto clean;
+ result += r;
+ address[dimension] = 0;
+ while (1) {
+ if (dimension == array->dimension - 1) {
+ if ((r = inspect(buf, *data)) <= 0)
+ goto clean;
+ result += r;
+ *data += array->dimensions[dimension].item_size;
}
- if (i == a->dimension - 1) {
- if ((r = inspect(buf, array_data(a, address))) < 0)
- return r;
+ else {
+ if ((r = buf_inspect_array_data_rec(buf, array, dimension + 1,
+ address, inspect, data)) <= 0)
+ goto clean;
result += r;
}
- if (i == a->dimension - 1) {
- while (address[i] == a->dimensions[i].count) {
- if ((r = buf_write_1(buf, "}")) < 0)
- return r;
- result += r;
- if (! i)
- return result;
- i--;
- }
+ address[dimension]++;
+ if (address[dimension] == array->dimensions[dimension].count)
break;
- }
- address[i]++;
- i++;
+ if ((r = buf_write_1(buf, ", ")) <= 0)
+ goto clean;
+ result += r;
}
- return result;
+ if ((r = buf_write_1(buf, "}")) <= 0)
+ goto clean;
+ result += r;
+ r = result;
+ clean:
+ return r;
+}
+
+sw buf_inspect_array_type (s_buf *buf, const s_array *array)
+{
+ sw r;
+ sw result = 0;
+ assert(buf);
+ assert(array);
+ if ((r = buf_write_1(buf, "(")) <= 0)
+ goto clean;
+ result += r;
+ if ((r = buf_inspect_tag_type(buf, array->type)) <= 0)
+ goto clean;
+ result += r;
+ if ((r = buf_write_1(buf, ")")) <= 0)
+ goto clean;
+ result += r;
+ r = result;
+ clean:
+ return r;
+}
+
+sw buf_inspect_array (s_buf *buf, const s_array *array)
+{
+ sw r;
+ sw result = 0;
+ assert(buf);
+ assert(array);
+ if ((r = buf_inspect_array_type(buf, array)) <= 0)
+ goto clean;
+ result += r;
+ if ((r = buf_write_1(buf, " ")) < 0)
+ goto clean;
+ result += r;
+ if ((r = buf_inspect_array_data(buf, array)) < 0) {
+ warnx("buf_inspect_array: buf_inspect_array_data");
+ goto clean;
+ }
+ result += r;
+ r = result;
+ clean:
+ return r;
+
}
sw buf_inspect_array_size (const s_array *a)
@@ -1415,6 +1472,69 @@ sw buf_inspect_tag_size (const s_tag *tag)
return -1;
}
+sw buf_inspect_tag_type (s_buf *buf, e_tag_type type)
+{
+ switch(type) {
+ case TAG_VOID:
+ return buf_write_1(buf, "void");
+ case TAG_ARRAY:
+ return buf_write_1(buf, "array");
+ case TAG_BOOL:
+ return buf_write_1(buf, "bool");
+ case TAG_CALL:
+ case TAG_CALL_FN:
+ case TAG_CALL_MACRO:
+ return buf_write_1(buf, "call");
+ case TAG_CFN:
+ return buf_write_1(buf, "cfn");
+ case TAG_CHARACTER:
+ return buf_write_1(buf, "character");
+ case TAG_F32:
+ return buf_write_1(buf, "f32");
+ case TAG_F64:
+ return buf_write_1(buf, "f64");
+ case TAG_FN:
+ return buf_write_1(buf, "fn");
+ case TAG_IDENT:
+ return buf_write_1(buf, "ident");
+ case TAG_INTEGER:
+ return buf_write_1(buf, "integer");
+ case TAG_LIST:
+ return buf_write_1(buf, "list");
+ case TAG_PTAG:
+ return buf_write_1(buf, "ptag");
+ case TAG_QUOTE:
+ return buf_write_1(buf, "quote");
+ case TAG_S8:
+ return buf_write_1(buf, "s8");
+ case TAG_S16:
+ return buf_write_1(buf, "s16");
+ case TAG_S32:
+ return buf_write_1(buf, "s32");
+ case TAG_S64:
+ return buf_write_1(buf, "s64");
+ case TAG_STR:
+ return buf_write_1(buf, "str");
+ case TAG_SYM:
+ return buf_write_1(buf, "sym");
+ case TAG_TUPLE:
+ return buf_write_1(buf, "tuple");
+ case TAG_U8:
+ return buf_write_1(buf, "u8");
+ case TAG_U16:
+ return buf_write_1(buf, "u16");
+ case TAG_U32:
+ return buf_write_1(buf, "u32");
+ case TAG_U64:
+ return buf_write_1(buf, "u64");
+ case TAG_VAR:
+ return buf_write_1(buf, "var");
+ }
+ assert(! "buf_inspect_tag_type: unknown tag type");
+ errx(1, "buf_inspect_tag_type: unknown tag type");
+ return -1;
+}
+
sw buf_inspect_tuple (s_buf *buf, const s_tuple *tuple)
{
u64 i = 0;
diff --git a/test/buf_inspect_test.c b/test/buf_inspect_test.c
index b2e6e11..7b1031e 100644
--- a/test/buf_inspect_test.c
+++ b/test/buf_inspect_test.c
@@ -15,6 +15,25 @@
#include "../libc3/c3.h"
#include "test.h"
+#define BUF_INSPECT_TEST_ARRAY(test, expected) \
+ do { \
+ s8 b[1024]; \
+ s_buf buf_test; \
+ s_buf buf_result; \
+ s_array tmp; \
+ test_context("buf_inspect_array(" # test ") -> " # expected); \
+ buf_init_1(&buf_test, (test)); \
+ buf_parse_array(&buf_test, &tmp); \
+ buf_clean(&buf_test); \
+ buf_init(&buf_result, false, sizeof(b), b); \
+ /* TEST_EQ(buf_inspect_array_size(&tmp), strlen(expected)); */ \
+ TEST_EQ(buf_inspect_array(&buf_result, &tmp), strlen(expected)); \
+ array_clean(&tmp); \
+ TEST_EQ(buf_result.wpos, strlen(expected)); \
+ TEST_STRNCMP(buf_result.ptr.ps8, (expected), buf_result.wpos); \
+ buf_clean(&buf_result); \
+ } while (0)
+
#define BUF_INSPECT_TEST_BOOL(test, expected) \
do { \
s8 b[16]; \
@@ -159,6 +178,7 @@
} while (0)
void buf_inspect_test ();
+TEST_CASE_PROTOTYPE(buf_inspect_array);
TEST_CASE_PROTOTYPE(buf_inspect_bool);
TEST_CASE_PROTOTYPE(buf_inspect_character);
TEST_CASE_PROTOTYPE(buf_inspect_f32);
@@ -171,6 +191,7 @@ TEST_CASE_PROTOTYPE(buf_inspect_tag);
void buf_inspect_test ()
{
+ TEST_CASE_RUN(buf_inspect_array);
TEST_CASE_RUN(buf_inspect_bool);
TEST_CASE_RUN(buf_inspect_str_character);
TEST_CASE_RUN(buf_inspect_character);
@@ -182,6 +203,14 @@ void buf_inspect_test ()
TEST_CASE_RUN(buf_inspect_tag);
}
+TEST_CASE(buf_inspect_array)
+{
+ BUF_INSPECT_TEST_ARRAY("(u8){0}", "(u8) {0}");
+ BUF_INSPECT_TEST_ARRAY("(u8){{0, 1}, {2, 3}}",
+ "(u8) {{0, 1}, {2, 3}}");
+}
+TEST_CASE_END(buf_inspect_array)
+
TEST_CASE(buf_inspect_bool)
{
BUF_INSPECT_TEST_BOOL(true, "true");
diff --git a/test/buf_parse_test.c b/test/buf_parse_test.c
index 7558caa..00457e7 100644
--- a/test/buf_parse_test.c
+++ b/test/buf_parse_test.c
@@ -24,7 +24,6 @@
s_array dest; \
test_context("buf_parse_array(" # test ")"); \
buf_init_1(&buf, (test)); \
- printf("%s\n", # test); \
TEST_EQ(buf_parse_array(&buf, &dest), strlen(test)); \
TEST_EQ(buf.rpos, strlen(test)); \
buf_clean(&buf); \