Commit c2b1f4af1a5108074824a13eab0fe4f9ad316efb

Thomas de Grivel 2023-04-15T17:25:24

wip buf_inspect_str

diff --git a/libc3/buf_inspect.c b/libc3/buf_inspect.c
index d5ca671..2a0264c 100644
--- a/libc3/buf_inspect.c
+++ b/libc3/buf_inspect.c
@@ -1028,18 +1028,24 @@ sw buf_inspect_str_byte (s_buf *buf, const u8 *byte)
   sw r;
   sw result = 0;
   s_buf_save save;
-  if ((r = buf_write_u8(buf, '\\')) < 0)
-    return r;
+  buf_save_init(buf, &save);
+  if ((r = buf_write_u8(buf, '\\')) <= 0) {
+    if (! r)
+      r = -1;
+    goto clean;
+  }
   result += r;
-  if ((r = buf_write_u8(buf, 'x')) < 0)
+  if ((r = buf_write_u8(buf, 'x')) <= 0)
     goto restore;
   result += r;
-  if ((r = buf_u8_to_hex(buf, *byte)) < 0)
+  if ((r = buf_u8_to_hex(buf, *byte)) <= 0)
     goto restore;
   result += r;
   r = result;
   goto clean;
  restore:
+  if (! r)
+    r = -1;
   buf_save_restore_wpos(buf, &save);
  clean:
   buf_save_clean(buf, &save);
@@ -1140,69 +1146,82 @@ sw buf_inspect_str_reserved (s_buf *buf, const s_str *str)
   s_str s;
   s_buf_save save;
   buf_save_init(buf, &save);
-  if ((r = buf_write_u8(buf, '"')) < 0)
-    return r;
+  if ((r = buf_write_u8(buf, '"')) <= 0) {
+    if (! r)
+      r = -1;
+    goto clean;
+  }
   result += r;
   str_init_str(&s, str);
   while (r) {
     if ((r = str_read_character_utf8(&s, &c)) < 0)
       goto restore;
     if (r) {
-      if ((r = buf_inspect_str_character(buf, &c)) < 0)
+      if ((r = buf_inspect_str_character(buf, &c)) <= 0)
         goto restore;
       result += r;
     }
     else if ((r = str_read_u8(&s, &byte)) < 0)
       goto restore;
     else if (r) {
-      if ((r = buf_inspect_str_byte(buf, &byte)) < 0)
+      if ((r = buf_inspect_str_byte(buf, &byte)) <= 0)
         goto restore;
       result += r;
     }
   }
-  if ((r = buf_write_u8(buf, '"')) < 0)
+  if ((r = buf_write_u8(buf, '"')) <= 0)
     goto restore;
   result += r;
   r = result;
   goto clean;
  restore:
+  if (! r)
+    r = -1;
   buf_save_restore_wpos(buf, &save);
  clean:
   buf_save_clean(buf, &save);
   return r;
 }
 
-/* XXX keep in sync with buf_inspect_str_reserved */
+/* keep in sync with buf_inspect_str_reserved */
 sw buf_inspect_str_reserved_size (const s_str *str)
 {
-  u8 b;
+  u8 byte;
   character c;
-  const sw quote_size = 1;
   sw r;
+  sw result = 0;
   s_str s;
-  sw size;
-  size = 2 * quote_size;
+  result += sizeof('"');
   str_init_str(&s, str);
-  while (1) {
-    if ((r = str_read_character_utf8(&s, &c)) > 0)
-      size += buf_inspect_str_character_size(&c);
-    else if (r && (r = str_read_u8(&s, &b)) == 1)
-      size += buf_inspect_str_byte_size;
-    else if (r < 0)
-      return -1;
-    else if (r == 0)
-      break;
+  r = 1;
+  while (r) {
+    if ((r = str_read_character_utf8(&s, &c)) < 0)
+      return r;
+    if (r) {
+      if ((r = buf_inspect_str_character_size(&c)) <= 0)
+        goto ko;
+      result += r;
+    }
+    else if ((r = str_read_u8(&s, &byte)) < 0)
+      return r;
+    else if (r)
+      result += buf_inspect_str_byte_size;
   }
-  return size;
+  result += sizeof('"');
+  return result;
+ ko:
+  if (! r)
+    r = -1;
+  return r;
 }
 
-sw buf_inspect_str_size (const s_str *x)
+sw buf_inspect_str_size (const s_str *str)
 {
   const sw quote_size = 1;
   sw size;
-  if (str_has_reserved_characters(x))
-    return buf_inspect_str_reserved_size(x);
-  size = x->size + 2 * quote_size;
+  if (str_has_reserved_characters(str))
+    return buf_inspect_str_reserved_size(str);
+  size = str->size + 2 * quote_size;
   return size;
 }
 
diff --git a/libc3/str.c b/libc3/str.c
index e3061ff..01075aa 100644
--- a/libc3/str.c
+++ b/libc3/str.c
@@ -185,9 +185,7 @@ s_str * str_init_str (s_str *str, const s_str *src)
 {
   assert(str);
   assert(src);
-  str->free = src->free;
-  str->size = src->size;
-  str->ptr = src->ptr;
+  *str = *src;
   return str;
 }
 
diff --git a/test/buf_inspect_test.c b/test/buf_inspect_test.c
index 5cbdb5d..44f32e9 100644
--- a/test/buf_inspect_test.c
+++ b/test/buf_inspect_test.c
@@ -274,6 +274,11 @@ TEST_CASE(buf_inspect_str)
   BUF_INSPECT_TEST_STR("\t", "\"\\t\"");
   BUF_INSPECT_TEST_STR("\v", "\"\\v\"");
   BUF_INSPECT_TEST_STR("\"", "\"\\\"\"");
+  BUF_INSPECT_TEST_STR("\x00", "\"\\x00\"");
+  BUF_INSPECT_TEST_STR("\x01", "\"\\x01\"");
+  BUF_INSPECT_TEST_STR("\x02", "\"\\x02\"");
+  BUF_INSPECT_TEST_STR("\xff", "\"\\xFF\"");
+  BUF_INSPECT_TEST_STR("\xFF", "\"\\xFF\"");
   BUF_INSPECT_TEST_STR(".", "\".\"");
   BUF_INSPECT_TEST_STR("..", "\"..\"");
   BUF_INSPECT_TEST_STR("...", "\"...\"");
diff --git a/test/str_test.c b/test/str_test.c
index 418bbc9..59d6d20 100644
--- a/test/str_test.c
+++ b/test/str_test.c
@@ -28,21 +28,26 @@
     test_context(NULL);                                                \
   } while (0)
 
-#define STR_TEST_INSPECT_1(test, result)                               \
+#define STR_TEST_INSPECT_1(test, expected)                               \
   do {                                                                 \
+    s_str result;                                                      \
     s_str str;                                                         \
     str_init_1(&str, NULL, (test));                                    \
-    STR_TEST_INSPECT(&str, (result));                                  \
+    test_context("str_inspect(" # test ") -> " # expected);            \
+    TEST_EQ(str_inspect(&str, &result), &result);                      \
+    TEST_STRNCMP(result.ptr.p, (expected), result.size);               \
+    str_clean(&result);                                                \
+    test_context(NULL);                                                \
   } while (0)
 
-#define STR_TEST_TO_HEX(test, result)                                  \
+#define STR_TEST_TO_HEX(test, expected)                                  \
   do {                                                                 \
     s_str str;                                                         \
     s_str *test_;                                                      \
-    test_context("str_to_hex(" # test ") -> " # result);               \
+    test_context("str_to_hex(" # test ") -> " # expected);               \
     test_ = (test);                                                    \
     TEST_EQ(str_to_hex(test_, &str), &str);                            \
-    TEST_STRNCMP(str.ptr.p, (result), str.size);                       \
+    TEST_STRNCMP(str.ptr.p, (expected), str.size);                       \
     str_clean(&str);                                                   \
     str_delete(test_);                                                 \
     test_context(NULL);                                                \