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);