diff --git a/libc3/buf.c b/libc3/buf.c
index 457669f..3b02fe6 100644
--- a/libc3/buf.c
+++ b/libc3/buf.c
@@ -826,6 +826,29 @@ sw buf_refill_compact (s_buf *buf)
return 0;
}
+s_str * buf_slice_to_str (const s_buf *buf, uw start, uw end,
+ s_str *dest)
+{
+ assert(buf);
+ assert(dest);
+ if (start > buf->wpos) {
+ err_puts("buf_slice_to_str: start > wpos");
+ assert(! "buf_slice_to_str: start > wpos");
+ return NULL;
+ }
+ if (end < start) {
+ err_puts("buf_slice_to_str: end < start");
+ assert(! "buf_slice_to_str: end < start");
+ return NULL;
+ }
+ if (end > buf->wpos) {
+ err_puts("buf_slice_to_str: end > wpos");
+ assert(! "buf_slice_to_str: end > wpos");
+ return NULL;
+ }
+ return str_init(dest, NULL, end - start, buf->ptr.ps8 + start);
+}
+
sw buf_str_to_hex (s_buf *buf, const s_str *src)
{
const u8 *b;
diff --git a/libc3/buf.h b/libc3/buf.h
index 71fb836..571efea 100644
--- a/libc3/buf.h
+++ b/libc3/buf.h
@@ -105,6 +105,8 @@ sw buf_xfer (s_buf *buf, s_buf *src, uw size);
sw buf_xfer_reverse(s_buf *src, s_buf *dest);
/* Observers. */
+s_str * buf_slice_to_str (const s_buf *buf, uw start, uw end,
+ s_str *dest);
s_str * buf_to_str (const s_buf *buf, s_str *dest);
#endif /* LIBC3_BUF_H */
diff --git a/libc3/buf_parse.c b/libc3/buf_parse.c
index 1b52b64..c95772c 100644
--- a/libc3/buf_parse.c
+++ b/libc3/buf_parse.c
@@ -2564,10 +2564,11 @@ sw buf_parse_str_eval (s_buf *buf, s_tag *dest)
{
character c;
uw end;
- bool eval = false;
s_str in;
s_buf in_buf = {0};
- s_str out;
+ s_list *list;
+ s_list **list_end;
+ s_buf out_buf;
sw r;
sw result;
s_buf_save save;
@@ -2578,20 +2579,34 @@ sw buf_parse_str_eval (s_buf *buf, s_tag *dest)
goto clean;
result = r;
buf_init_str(&in_buf, false, &in);
+ list = NULL;
+ list_end = &list;
start = 0;
while (1) {
- if (! eval) {
- end = in_buf.rpos;
- r = buf_read_1(&in_buf, "#{");
+ end = in_buf.rpos;
+ r = buf_read_1(&in_buf, "#{");
+ if (r < 0)
+ goto restore;
+ if (r > 0) {
+ *list_end = list_new(NULL);
+ (*list_end)->tag.type = TAG_STR;
+ buf_slice_to_str(&in_buf, start, end, &(*list_end)->tag.data.str);
+ list_end = &(*list_end)->next.data.list;
+ *list_end = list_new(NULL);
+ buf_parse_tag(&out_buf, &(*list_end)->tag);
+ list_end = &(*list_end)->next.data.list;
+ r = buf_ignore_spaces(&in_buf);
if (r < 0)
goto restore;
- if (r > 0) {
- buf_slice_to_str(&in_buf, start, end, &out);
- eval = true;
- }
+ r = buf_parse_comments(&in_buf);
+ if (r < 0)
+ goto restore;
+ r = buf_read_1(&in_buf, "}");
+ if (r <= 0)
+ goto restore;
+ start = in_buf.rpos;
}
r = buf_read_character_utf8(&in_buf, &c);
-
}
r = result;
goto clean;