diff --git a/libc3/buf_inspect.c b/libc3/buf_inspect.c
index 9841e39..1e4b2bb 100644
--- a/libc3/buf_inspect.c
+++ b/libc3/buf_inspect.c
@@ -21,13 +21,36 @@ 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_array_data_size (const s_array *array);
-sw buf_inspect_array_data_size_rec (s_buf *buf, const s_array *array,
- uw dimension, uw *address,
- f_buf_inspect inspect, u8 **data);
+sw buf_inspect_array_data_size_rec (const s_array *array,
+ uw dimension, uw *address,
+ f_buf_inspect_size inspect,
+ u8 **data);
sw buf_inspect_array_type (s_buf *buf, const s_array *array);
sw buf_inspect_array_type_size (const s_array *array);
sw buf_inspect_tag_type (s_buf *buf, e_tag_type type);
+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_data (s_buf *buf, const s_array *array)
{
uw *address;
@@ -41,6 +64,7 @@ sw buf_inspect_array_data (s_buf *buf, const s_array *array)
data = array->data;
r = buf_inspect_array_data_rec(buf, array, 0, address,
inspect, &data);
+ free(address);
return r;
}
@@ -82,54 +106,113 @@ sw buf_inspect_array_data_rec (s_buf *buf, const s_array *array,
return r;
}
-sw buf_inspect_array_type (s_buf *buf, const s_array *array)
+sw buf_inspect_array_data_size (const s_array *array)
+{
+ uw *address;
+ u8 *data;
+ f_buf_inspect_size inspect;
+ sw r;
+ assert(array);
+ address = calloc(array->dimension, sizeof(uw));
+ inspect = tag_type_to_buf_inspect_size(array->type);
+ data = array->data;
+ r = buf_inspect_array_data_size_rec(array, 0, address,
+ inspect, &data);
+ free(address);
+ return r;
+}
+
+sw buf_inspect_array_data_size_rec (const s_array *array,
+ uw dimension, uw *address,
+ f_buf_inspect_size inspect, u8 **data)
+{
+ sw r;
+ sw result = 0;
+ r = strlen("{");
+ result += r;
+ address[dimension] = 0;
+ while (1) {
+ if (dimension == array->dimension - 1) {
+ if ((r = inspect(*data)) <= 0)
+ goto clean;
+ result += r;
+ *data += array->dimensions[dimension].item_size;
+ }
+ else {
+ if ((r = buf_inspect_array_data_size_rec(array, dimension + 1,
+ address, inspect,
+ data)) <= 0)
+ goto clean;
+ result += r;
+ }
+ address[dimension]++;
+ if (address[dimension] == array->dimensions[dimension].count)
+ break;
+ r = strlen(", ");
+ result += r;
+ }
+ r = strlen("}");
+ result += r;
+ r = result;
+ clean:
+ return r;
+}
+
+sw buf_inspect_array_size (const s_array *array)
{
sw r;
sw result = 0;
- assert(buf);
assert(array);
- if ((r = buf_write_1(buf, "(")) <= 0)
+ if ((r = buf_inspect_array_type_size(array)) <= 0)
goto clean;
result += r;
- if ((r = buf_inspect_tag_type(buf, array->type)) <= 0)
- goto clean;
+ r = strlen(" ");
result += r;
- if ((r = buf_write_1(buf, ")")) <= 0)
+ if ((r = buf_inspect_array_data_size(array)) <= 0) {
+ warnx("buf_inspect_array_size: buf_inspect_array_data");
goto clean;
+ }
result += r;
r = result;
clean:
return r;
}
-sw buf_inspect_array (s_buf *buf, const s_array *array)
+sw buf_inspect_array_type (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)
+ if ((r = buf_write_1(buf, "(")) <= 0)
goto clean;
result += r;
- if ((r = buf_write_1(buf, " ")) < 0)
+ if ((r = buf_inspect_tag_type(buf, array->type)) <= 0)
goto clean;
result += r;
- if ((r = buf_inspect_array_data(buf, array)) < 0) {
- warnx("buf_inspect_array: buf_inspect_array_data");
+ if ((r = buf_write_1(buf, ")")) <= 0)
goto clean;
- }
result += r;
r = result;
clean:
return r;
-
}
-sw buf_inspect_array_size (const s_array *a)
+sw buf_inspect_array_type_size (const s_array *array)
{
- assert(a);
- (void) a;
- return -1;
+ sw r;
+ sw result = 0;
+ assert(array);
+ r = strlen("(");
+ result += r;
+ if ((r = buf_inspect_tag_type_size(array->type)) <= 0)
+ goto clean;
+ result += r;
+ r = strlen(")");
+ result += r;
+ r = result;
+ clean:
+ return r;
}
sw buf_inspect_bool (s_buf *buf, const bool *b)
@@ -1372,6 +1455,69 @@ sw buf_inspect_tag_type (s_buf *buf, e_tag_type type)
return -1;
}
+sw buf_inspect_tag_type_size (e_tag_type type)
+{
+ switch(type) {
+ case TAG_VOID:
+ return strlen("void");
+ case TAG_ARRAY:
+ return strlen("array");
+ case TAG_BOOL:
+ return strlen("bool");
+ case TAG_CALL:
+ case TAG_CALL_FN:
+ case TAG_CALL_MACRO:
+ return strlen("call");
+ case TAG_CFN:
+ return strlen("cfn");
+ case TAG_CHARACTER:
+ return strlen("character");
+ case TAG_F32:
+ return strlen("f32");
+ case TAG_F64:
+ return strlen("f64");
+ case TAG_FN:
+ return strlen("fn");
+ case TAG_IDENT:
+ return strlen("ident");
+ case TAG_INTEGER:
+ return strlen("integer");
+ case TAG_LIST:
+ return strlen("list");
+ case TAG_PTAG:
+ return strlen("ptag");
+ case TAG_QUOTE:
+ return strlen("quote");
+ case TAG_S8:
+ return strlen("s8");
+ case TAG_S16:
+ return strlen("s16");
+ case TAG_S32:
+ return strlen("s32");
+ case TAG_S64:
+ return strlen("s64");
+ case TAG_STR:
+ return strlen("str");
+ case TAG_SYM:
+ return strlen("sym");
+ case TAG_TUPLE:
+ return strlen("tuple");
+ case TAG_U8:
+ return strlen("u8");
+ case TAG_U16:
+ return strlen("u16");
+ case TAG_U32:
+ return strlen("u32");
+ case TAG_U64:
+ return strlen("u64");
+ case TAG_VAR:
+ return strlen("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/libc3/buf_inspect.h b/libc3/buf_inspect.h
index 612eef3..de5ee62 100644
--- a/libc3/buf_inspect.h
+++ b/libc3/buf_inspect.h
@@ -110,6 +110,8 @@ sw buf_inspect_sym_reserved_size (const s_sym *sym);
sw buf_inspect_sym_size (const s_sym *sym);
sw buf_inspect_tag (s_buf *buf, const s_tag *tag);
sw buf_inspect_tag_size (const s_tag *tag);
+sw buf_inspect_tag_type (s_buf *buf, e_tag_type type);
+sw buf_inspect_tag_type_size (e_tag_type type);
sw buf_inspect_tuple (s_buf *buf, const s_tuple *tuple);
sw buf_inspect_tuple_size (const s_tuple *tuple);
BUF_INSPECT_U_PROTOTYPES(8);
diff --git a/libc3/tag.c b/libc3/tag.c
index 0f84662..33ff5ac 100644
--- a/libc3/tag.c
+++ b/libc3/tag.c
@@ -2147,6 +2147,68 @@ f_buf_inspect tag_type_to_buf_inspect (e_tag_type type)
return NULL;
}
+f_buf_inspect_size tag_type_to_buf_inspect_size (e_tag_type type)
+{
+ switch (type) {
+ case TAG_VOID:
+ return (f_buf_inspect_size) buf_inspect_void_size;
+ case TAG_ARRAY:
+ case TAG_BOOL:
+ return (f_buf_inspect_size) buf_inspect_bool_size;
+ case TAG_CALL:
+ case TAG_CALL_FN:
+ case TAG_CALL_MACRO:
+ return (f_buf_inspect_size) buf_inspect_call_size;
+ case TAG_CFN:
+ return (f_buf_inspect_size) buf_inspect_cfn_size;
+ case TAG_CHARACTER:
+ return (f_buf_inspect_size) buf_inspect_character_size;
+ case TAG_F32:
+ return (f_buf_inspect_size) buf_inspect_f32_size;
+ case TAG_F64:
+ return (f_buf_inspect_size) buf_inspect_f64_size;
+ case TAG_FN:
+ return (f_buf_inspect_size) buf_inspect_fn_size;
+ case TAG_IDENT:
+ return (f_buf_inspect_size) buf_inspect_ident_size;
+ case TAG_INTEGER:
+ return (f_buf_inspect_size) buf_inspect_integer_size;
+ case TAG_S64:
+ return (f_buf_inspect_size) buf_inspect_s64_size;
+ case TAG_S32:
+ return (f_buf_inspect_size) buf_inspect_s32_size;
+ case TAG_S16:
+ return (f_buf_inspect_size) buf_inspect_s16_size;
+ case TAG_S8:
+ return (f_buf_inspect_size) buf_inspect_s8_size;
+ case TAG_U8:
+ return (f_buf_inspect_size) buf_inspect_u8_size;
+ case TAG_U16:
+ return (f_buf_inspect_size) buf_inspect_u16_size;
+ case TAG_U32:
+ return (f_buf_inspect_size) buf_inspect_u32_size;
+ case TAG_U64:
+ return (f_buf_inspect_size) buf_inspect_u64_size;
+ case TAG_LIST:
+ return (f_buf_inspect_size) buf_inspect_list_size;
+ case TAG_PTAG:
+ return (f_buf_inspect_size) buf_inspect_ptag_size;
+ case TAG_QUOTE:
+ return (f_buf_inspect_size) buf_inspect_quote_size;
+ case TAG_STR:
+ return (f_buf_inspect_size) buf_inspect_str_size;
+ case TAG_SYM:
+ return (f_buf_inspect_size) buf_inspect_sym_size;
+ case TAG_TUPLE:
+ return (f_buf_inspect_size) buf_inspect_tuple_size;
+ case TAG_VAR:
+ return (f_buf_inspect_size) buf_inspect_var_size;
+ }
+ assert(! "tag_type_to_buf_inspect_size: unknown tag type");
+ errx(1, "tag_type_to_buf_inspect_size: unknown tag type");
+ return NULL;
+}
+
f_buf_parse tag_type_to_buf_parse (e_tag_type type)
{
switch (type) {
diff --git a/libc3/tag.h b/libc3/tag.h
index e69f99a..140459d 100644
--- a/libc3/tag.h
+++ b/libc3/tag.h
@@ -89,22 +89,23 @@ s_tag * tag_new_var ();
void tag_delete (s_tag *tag);
/* Observers */
-u64 tag_hash_u64 (const s_tag *tag);
-uw tag_hash_uw (const s_tag *tag);
-s_str * tag_inspect (const s_tag *tag, s_str *dest);
-e_bool tag_is_bound_var (const s_tag *tag);
-e_bool tag_is_number (const s_tag *tag);
-e_bool tag_is_unbound_var (const s_tag *tag);
-s8 tag_number_compare (const s_tag *a, const s_tag *b);
-sw tag_size (const s_tag *tag);
-void * tag_to_ffi_pointer (s_tag *tag, const s_sym *type);
-ffi_type tag_to_ffi_type(const s_tag *tag);
-void * tag_to_pointer (s_tag *tag, e_tag_type type);
-sw tag_type_size (e_tag_type type);
-f_buf_inspect tag_type_to_buf_inspect (e_tag_type type);
-f_buf_parse tag_type_to_buf_parse (e_tag_type type);
-s8 * tag_type_to_string (e_tag_type type);
-const s_sym * tag_type_to_sym (e_tag_type tag_type);
+u64 tag_hash_u64 (const s_tag *tag);
+uw tag_hash_uw (const s_tag *tag);
+s_str * tag_inspect (const s_tag *tag, s_str *dest);
+e_bool tag_is_bound_var (const s_tag *tag);
+e_bool tag_is_number (const s_tag *tag);
+e_bool tag_is_unbound_var (const s_tag *tag);
+s8 tag_number_compare (const s_tag *a, const s_tag *b);
+sw tag_size (const s_tag *tag);
+void * tag_to_ffi_pointer (s_tag *tag, const s_sym *type);
+ffi_type tag_to_ffi_type(const s_tag *tag);
+void * tag_to_pointer (s_tag *tag, e_tag_type type);
+sw tag_type_size (e_tag_type type);
+f_buf_inspect tag_type_to_buf_inspect (e_tag_type type);
+f_buf_inspect_size tag_type_to_buf_inspect_size (e_tag_type type);
+f_buf_parse tag_type_to_buf_parse (e_tag_type type);
+s8 * tag_type_to_string (e_tag_type type);
+const s_sym * tag_type_to_sym (e_tag_type tag_type);
/* Modifiers */
s_tag * tag_1 (s_tag *tag, const s8 *p);
diff --git a/libc3/types.h b/libc3/types.h
index 3e8cc4a..67dae59 100644
--- a/libc3/types.h
+++ b/libc3/types.h
@@ -506,5 +506,6 @@ struct facts_with_cursor {
/* Functions */
typedef sw (* f_buf_inspect) (s_buf *buf, const void *x);
+typedef sw (* f_buf_inspect_size) (const void *x);
#endif /* TYPES_H */
diff --git a/test/buf_inspect_test.c b/test/buf_inspect_test.c
index 9ff0098..35bb106 100644
--- a/test/buf_inspect_test.c
+++ b/test/buf_inspect_test.c
@@ -28,9 +28,9 @@
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); \
+ array_clean(&tmp); \
buf_clean(&buf_result); \
} while (0)