Commit f7e6e6eac209974d9a358492af50466e104a17ff

Thomas de Grivel 2025-04-08T19:33:52

Tag.from_str parser

diff --git a/lib/kc3/0.1/tag.kc3 b/lib/kc3/0.1/tag.kc3
index 5b3ed51..055e03e 100644
--- a/lib/kc3/0.1/tag.kc3
+++ b/lib/kc3/0.1/tag.kc3
@@ -2,6 +2,8 @@ defmodule Tag do
 
   def cast = cfn Tag "tag_init_cast" (Result, Sym, Tag)
 
+  def from_str = cfn Tag "tag_init_from_str" (Result, Str)
+
   def type = cfn S32 "kc3_tag_type" (Tag)
 
 end
diff --git a/libkc3/tag.c b/libkc3/tag.c
index 8e1da56..92710d8 100644
--- a/libkc3/tag.c
+++ b/libkc3/tag.c
@@ -374,17 +374,17 @@ s_tag * tag_init_1 (s_tag *tag, const char *p)
   if (! p)
     return tag;
   len = strlen(p);
-  buf_init(&buf, false, len, (char *) p); // buf is read-only
+  buf_init_const(&buf, len, p);
   buf.wpos = len;
   r = buf_parse_tag(&buf, tag);
   if (r < 0 || (uw) r != len) {
-    err_write_1("invalid tag: \"");
+    err_write_1("tag_init_1: invalid tag: \"");
     err_write_1(p);
     err_write_1("\", ");
     err_inspect_uw(&len);
     err_write_1(" != ");
     err_inspect_sw(&r);
-    assert(! "invalid tag");
+    assert(! "tag_init_1: invalid tag");
     return NULL;
   }
   return tag;
@@ -669,6 +669,30 @@ s_tag * tag_init_copy (s_tag *tag, s_tag *src)
   return NULL;
 }
 
+s_tag * tag_init_from_str (s_tag *tag, s_str *str)
+{
+  s_buf buf;
+  sw r;
+  assert(tag);
+  tag_init_void(tag);
+  if (! str->size)
+    return tag;
+  buf_init_const(&buf, str->size, str->ptr.pchar);
+  buf.wpos = str->size;
+  r = buf_parse_tag(&buf, tag);
+  if (r < 0 || (uw) r != str->size) {
+    err_write_1("tag_init_str: invalid tag: ");
+    err_inspect_str(str);
+    err_write_1(", ");
+    err_inspect_u32_decimal(&str->size);
+    err_write_1(" != ");
+    err_inspect_sw(&r);
+    assert(! "tag_init_str: invalid tag");
+    return NULL;
+  }
+  return tag;
+}
+
 s_tag * tag_init_var (s_tag *tag, const s_sym *type)
 {
   s_tag tmp = {0};
diff --git a/libkc3/tag.h b/libkc3/tag.h
index eef49d3..b383fd5 100644
--- a/libkc3/tag.h
+++ b/libkc3/tag.h
@@ -36,6 +36,7 @@ s_tag * tag_init_1 (s_tag *tag, const char *p);
 s_tag * tag_init_call_cast (s_tag *tag, const s_sym *type);
 s_tag * tag_init_facts_cast (s_tag *tag, const s_sym * const *type,
                              s_tag *src);
+s_tag * tag_init_from_str (s_tag *tag, s_str *str);
 
 /* Heap-allocation functions, call tag_delete after use. */
 void    tag_delete (s_tag *tag);