Commit 7336628ffaeafbb4a098d81d4b436ffb4f63f107

Thomas de Grivel 2023-07-14T11:24:20

wip

diff --git a/libc3/buf_parse.c b/libc3/buf_parse.c
index 49dfa01..df0801c 100644
--- a/libc3/buf_parse.c
+++ b/libc3/buf_parse.c
@@ -24,6 +24,43 @@ sw buf_parse_array_dimensions_rec (s_buf *buf, s_array *dest,
                                    uw dimension, uw *address,
                                    f_buf_parse parse, void *data);
 sw buf_parse_cfn_arg_types (s_buf *buf, s_list **dest);
+sw buf_peek_array_dimension_count (s_buf *buf, s_array *dest);
+
+sw buf_parse_array (s_buf *buf, s_array *dest)
+{
+  sw r;
+  sw result = 0;
+  s_buf_save save;
+  s_array tmp;
+  assert(buf);
+  assert(dest);
+  buf_save_init(buf, &save);
+  tmp = *dest;
+  if ((r = buf_parse_array_type(buf, &tmp)) <= 0)
+    goto clean;
+  result += r;
+  if ((r = buf_peek_array_dimension_count(buf, &tmp)) <= 0) {
+    warnx("buf_parse_array: buf_peek_array_dimension_count");
+    goto restore;
+  }
+  if ((r = buf_peek_array_dimensions(buf, &tmp)) <= 0) {
+    warnx("buf_parse_array: buf_peek_array_dimensions");
+    goto restore;
+  }
+  if ((r = buf_parse_array_data(buf, &tmp)) < 0) {
+    warnx("buf_parse_array: buf_peek_array_data");
+    goto restore;
+  }
+  result += r;
+  *dest = tmp;
+  r = result;
+  goto clean;
+ restore:
+  buf_save_restore_rpos(buf, &save);
+ clean:
+  buf_save_clean(buf, &save);
+  return r;
+}
 
 sw buf_parse_array_data (s_buf *buf, s_array *dest)
 {
@@ -183,14 +220,16 @@ sw buf_parse_array_dimensions (s_buf *buf, s_array *dest)
   parse = tag_type_to_buf_parse(tmp.type);
   data = calloc(1, size);
   tmp.dimensions[tmp.dimension - 1].item_size = size;
-  if ((r = buf_parse_array_dimensions_rec(buf, dest,
-                                          tmp.dimension - 1,
-                                          address, parse, data)) <= 0)
+  if ((r = buf_parse_array_dimensions_rec(buf, dest, 0,
+                                          address, parse, data)) <= 0) {
+    warnx("buf_parse_array_dimensions: buf_parse_array_dimensions_rec");
     goto clean;
-  r = result;
+  }
   *dest = tmp;
- clean:
+  r = result;
+  goto clean;
   buf_save_restore_rpos(buf, &save);
+ clean:
   buf_save_clean(buf, &save);
   return r;
 }
@@ -208,33 +247,59 @@ sw buf_parse_array_dimensions_rec (s_buf *buf, s_array *dest,
   assert(address);
   tmp = *dest;
   buf_save_init(buf, &save);
- start:
   if (dimension == dest->dimension - 1) {
-    if ((r = parse(buf, data)) < 0)
+    if ((r = parse(buf, data)) < 0) {
+      warnx("buf_parse_array_dimensions_rec: parse");
       goto clean;
+    }
     result += r;
     goto ok;
   }
-  if ((r = buf_read_1(buf, "[")) < 0)
-    goto clean;
-  if (r) {
+  else {
+    if ((r = buf_read_1(buf, "{")) <= 0) {
+      warnx("buf_parse_array_dimensions_rec: {");
+      goto clean;
+    }
+    result += r;
+    if ((r = buf_ignore_spaces(buf)) < 0) {
+      warnx("buf_parse_array_dimensions_rec: 1");
+      goto restore;
+    }
     result += r;
     dimension++;
     address[dimension] = 0;
-    if ((r = buf_parse_array_dimensions_rec(buf, &tmp, dimension,
-                                            address, parse,
-                                            data)) <= 0)
-      goto clean;
-    result += r;
-    goto ok;
-  }
-  if (! dimension)
-    goto ok;
-  if ((r = buf_read_1(buf, "]")) < 0)
-    goto clean;
-  if (r) {
+    while (1) {
+      if ((r = buf_parse_array_dimensions_rec(buf, &tmp, dimension,
+                                              address, parse,
+                                              data)) <= 0) {
+        warnx("buf_parse_array_dimensions_rec: buf_parse_array_dimensions_rec");
+        goto restore;
+      }
+      address[dimension]++;
+      result += r;
+      if ((r = buf_ignore_spaces(buf)) < 0) {
+        warnx("buf_parse_array_dimensions_rec: 2");
+        goto restore;
+      }
+      result += r;
+      if ((r = buf_read_1(buf, ",")) < 0) {
+        warnx("buf_parse_array_dimensions_rec: 3");
+        goto restore;
+      }
+      result += r;
+      if (! r)
+        break;
+      if ((r = buf_ignore_spaces(buf)) < 0) {
+        warnx("buf_parse_array_dimensions_rec: 4");
+        goto restore;
+      }
+      result += r;
+    }
+    if ((r = buf_read_1(buf, "}")) <= 0) {
+      warnx("buf_parse_array_dimensions_rec: }");
+      goto restore;
+    }
     result += r;
-    dimension--;
     if (! tmp.dimensions[dimension].count) {
       tmp.dimensions[dimension].count = address[dimension];
       tmp.dimensions[dimension].item_size = tmp.dimensions[dimension + 1].count * tmp.dimensions[dimension + 1].item_size;
@@ -242,21 +307,22 @@ sw buf_parse_array_dimensions_rec (s_buf *buf, s_array *dest,
     else if (tmp.dimensions[dimension].count != address[dimension]) {
       assert(! "buf_parse_array_dimensions_rec: dimension mismatch");
       errx(1, "buf_parse_array_dimensions_rec: dimension mismatch"
-             ": %lu", dimension);
+           ": %lu", dimension);
       r = -1;
-      goto clean;
+      goto restore;
+    }
+    if ((r = buf_ignore_spaces(buf)) < 0) {
+      warnx("buf_parse_array_dimensions_rec: 5");
+      goto restore;
     }
+    result += r;
     goto ok;
   }
-  if ((r = buf_read_1(buf, ",")) <= 0)
-    goto clean;
-  result += r;
-  address[dimension]++;
-  if (dimension)
-    goto start;
  ok:
   r = result;
   goto clean;
+ restore:
+  buf_save_restore_rpos(buf, &save);
  clean:
   buf_save_clean(buf, &save);
   return r;
@@ -298,35 +364,6 @@ sw buf_parse_array_type (s_buf *buf, s_array *dest)
   return r;
 }
 
-sw buf_parse_array (s_buf *buf, s_array *dest)
-{
-  sw r;
-  sw result = 0;
-  s_buf_save save;
-  s_array tmp;
-  assert(buf);
-  assert(dest);
-  buf_save_init(buf, &save);
-  tmp = *dest;
-  if ((r = buf_parse_array_type(buf, &tmp)) <= 0)
-    goto clean;
-  result += r;
-  if ((r = buf_parse_array_dimension_count(buf, &tmp)) <= 0)
-    goto restore;
-  if ((r = buf_peek_array_dimensions(buf, &tmp)) < 0)
-    goto restore;
-  if ((r = buf_parse_array_data(buf, &tmp)) < 0)
-    goto restore;
-  *dest = tmp;
-  r = result;
-  goto clean;
- restore:
-  buf_save_restore_rpos(buf, &save);
- clean:
-  buf_save_clean(buf, &save);
-  return r;
-}
-
 sw buf_parse_bool (s_buf *buf, bool *p)
 {
   character c;
@@ -2428,6 +2465,17 @@ sw buf_parse_f64 (s_buf *buf, f64 *dest) {
   return r;
 }
 
+sw buf_peek_array_dimension_count (s_buf *buf, s_array *dest)
+{
+  sw r;
+  s_buf_save save;
+  buf_save_init(buf, &save);
+  r = buf_parse_array_dimension_count(buf, dest);
+  buf_save_restore_rpos(buf, &save);
+  buf_save_clean(buf, &save);
+  return r;
+}
+
 sw buf_peek_array_dimensions (s_buf *buf, s_array *dest)
 {
   sw r;
@@ -2435,5 +2483,6 @@ sw buf_peek_array_dimensions (s_buf *buf, s_array *dest)
   buf_save_init(buf, &save);
   r = buf_parse_array_dimensions(buf, dest);
   buf_save_restore_rpos(buf, &save);
+  buf_save_clean(buf, &save);
   return r;
 }
diff --git a/libc3/facts.c b/libc3/facts.c
index 6624d02..0800dfe 100644
--- a/libc3/facts.c
+++ b/libc3/facts.c
@@ -366,7 +366,7 @@ void facts_lock_unlock_r (s_facts *facts)
 {
   assert(facts);
   if (pthread_rwlock_unlock(&facts->rwlock))
-    err(1, "facts_lock_unlock_r: pthread_rwlock_unlock");
+    errx(1, "facts_lock_unlock_r: pthread_rwlock_unlock");
 }
 
 void facts_lock_unlock_w (s_facts *facts)
@@ -375,7 +375,7 @@ void facts_lock_unlock_w (s_facts *facts)
   facts->rwlock_count--;
   if (! facts->rwlock_count) {
     if (pthread_rwlock_unlock(&facts->rwlock))
-      err(1, "facts_lock_unlock_w: pthread_rwlock_unlock");
+      errx(1, "facts_lock_unlock_w: pthread_rwlock_unlock");
     facts->rwlock_thread = 0;
   }
 }
diff --git a/test/ic3/array.in b/test/ic3/array.in
index a4437d5..b02d0bb 100644
--- a/test/ic3/array.in
+++ b/test/ic3/array.in
@@ -1,6 +1,6 @@
-(u8) [0, 1]
-(u8) [[0, 1], [2, 3]]
-(u8) [[[0, 1],
-       [2, 3]],
-      [[4, 5],
-       [6, 7]]]
+(u8) {0, 1}
+(u8) {{0, 1}, {2, 3}}
+(u8) {{{0, 1},
+       {2, 3}},
+      {{4, 5},
+       {6, 7}}}