Commit 89c7603743d57c5e75238c159971a12fff6dc4f7

Thomas de Grivel 2023-04-03T15:03:42

wip array

diff --git a/libc3/buf_parse.c b/libc3/buf_parse.c
index 664aefa..2eca055 100644
--- a/libc3/buf_parse.c
+++ b/libc3/buf_parse.c
@@ -1438,23 +1438,50 @@ sw buf_parse_quote (s_buf *buf, s_quote *dest)
   return r;
 }
 
-sw buf_parse_s (s_buf *buf, void *s, u8 size, const s_str *base)
+sw buf_parse_s (s_buf *buf, void *s, u8 size)
+{
+  e_bool negative = false;
+  sw r;
+  sw result = 0;
+  s_buf_save save;
+  buf_save_init(buf, &save);
+  if ((r = buf_read_1(buf, "-")) < 0)
+    goto clean;
+  result += r;
+  if (r > 0)
+    negative = true;
+  if ((r = buf_read_1(buf, "0x")) < 0)
+    goto restore;
+  result += r;
+  if (r > 0) {
+    if ((r = buf_parse_s_hex(buf, s, size, negative)) <= 0)
+      goto restore;
+    result += r;
+    goto ok;
+  }
+ ok:
+  r = result;
+  goto clean;
+ restore:
+  buf_save_restore_rpos(buf, &save);
+ clean:
+  buf_save_clean(buf, &save);
+  return r;
+}
+
+sw buf_parse_s_base (s_buf *buf, void *s, u8 size, const s_str *base,
+                     bool negative)
 {
   character c;
   sw i;
   sw r;
   sw result = 0;
   s_buf_save save;
-  e_bool negative = false;
   s64 tmp = 0;
   assert(buf);
   assert(s);
   assert(size);
   buf_save_init(buf, &save);
-  if ((r = buf_read_1(buf, "-")) < 0)
-    goto clean;
-  if (r > 0)
-    negative = true;
   while ((r = buf_parse_character_from_str(buf, base, &c)) > 0) {
     i = str_character_index(base, c);
     if (tmp > (((1 << 64) - 1) + base->size - 1) / base->size) {
@@ -1462,8 +1489,10 @@ sw buf_parse_s (s_buf *buf, void *s, u8 size, const s_str *base)
       goto restore;
     }
     tmp *= base->size;
-    if (tmp > (1 << 64) - 1 - i)
+    if (tmp > (1 << 64) - 1 - i) {
+      warnx("buf_parse_s: integer overflow");
       goto restore;
+    }
     tmp += i;
   }
   if (negative)
@@ -1476,6 +1505,43 @@ sw buf_parse_s (s_buf *buf, void *s, u8 size, const s_str *base)
   return r;
 }
 
+sw buf_parse_u_base (s_buf *buf, void *s, u8 size, const s_str *base)
+{
+  character c;
+  sw i;
+  sw r;
+  sw result = 0;
+  s_buf_save save;
+  s64 tmp = 0;
+  assert(buf);
+  assert(s);
+  assert(size);
+  buf_save_init(buf, &save);
+  while ((r = buf_parse_character_from_str(buf, base, &c)) > 0) {
+    i = str_character_index(base, c);
+    if (tmp > (((1 << 65) - 1) + base->size - 1) / base->size) {
+      warnx("buf_parse_u: integer overflow");
+      goto restore;
+    }
+    tmp *= base->size;
+    if (tmp > (1 << 65) - 1 - i) {
+      warnx("buf_parse_u: integer overflow");
+      goto restore;
+    }
+    tmp += i;
+  }
+  memcpy(s, &tmp + 8 - size, size);
+ restore:
+  buf_save_restore_rpos(buf, &save);
+ clean:
+  buf_save_clean(buf, &save);
+  return r;
+}
+
+sw buf_parse_s8 (s_buf *buf, s8 *dest)
+{
+  return buf_parse_s(buf, dest, 1, "
+
 sw buf_parse_str (s_buf *buf, s_str *dest)
 {
   u8 b;