Commit 61285d608c0874904cede879c0c1f93fc9819985

Thomas de Grivel 2024-01-26T11:05:44

wip buf_parse_str_eval

diff --git a/.ic3_history b/.ic3_history
index 0dd1a2f..6f893a1 100644
--- a/.ic3_history
+++ b/.ic3_history
@@ -1,12 +1,3 @@
-2.66666666666666666666f
-1.0
-1.0f
-2.0
-2.123
-1.1
-1.1f
-type(1.1)
-type(1.1f)
 type(11/10)
 type(1)
 type(1 + 1)
@@ -97,3 +88,12 @@ getenv("USER")
 hello = fn (name) { "Hello, " + name + " !" }
 hello("Patrice")
 hello("Thomas")
+"Hello, " + "Tiyon" + " !"
+hello = fn (name) { "Hello, " + name + " !" }
+hello("Tiyon")
+hello("Patrice")
+"Hello, #{name} !"
+hello("Tiyon")
+hello = fn (name) { "Hello, " + name + " !" }
+hello("Tiyon")
+hello("Baptiste")
diff --git a/libc3/buf.c b/libc3/buf.c
index 8adeaf3..457669f 100644
--- a/libc3/buf.c
+++ b/libc3/buf.c
@@ -10,7 +10,7 @@
  * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
  * THIS SOFTWARE.
  */
-#include <assert.h>
+#include "assert.h"
 #include <err.h>
 #include <stdlib.h>
 #include <string.h>
@@ -181,43 +181,42 @@ sw buf_ignore_spaces_but_newline (s_buf *buf)
 
 s_buf * buf_init (s_buf *buf, bool p_free, uw size, char *p)
 {
+  s_buf tmp = {0};
   assert(buf);
   assert(p);
-  buf->column = 0;
-  buf->flush = NULL;
-  buf->free = p_free;
-  buf->line = -1;
-  buf->ptr.pchar = p;
-  buf->refill = NULL;
-  buf->rpos = 0;
-  buf->save = NULL;
-  buf->size = size;
-  buf->user_ptr = NULL;
-  buf->wpos = 0;
+  tmp.free = p_free;
+  tmp.line = -1;
+  tmp.ptr.pchar = p;
+  tmp.size = size;
+  *buf = tmp;
   return buf;
 }
 
 s_buf * buf_init_1 (s_buf *buf, bool p_free, char *p)
 {
   uw len;
+  s_buf tmp = {0};
   assert(buf);
   assert(p);
   len = strlen(p);
-  buf_init(buf, p_free, len, p);
-  buf->wpos = len;
+  buf_init(&tmp, p_free, len, p);
+  tmp.wpos = len;
+  *buf = tmp;
   return buf;
 }
 
 s_buf * buf_init_1_copy (s_buf *buf, const char *p)
 {
   uw size;
+  s_buf tmp = {0};
   assert(buf);
   assert(p);
   size = strlen(p);
-  if (! buf_init_alloc(buf, size))
+  if (! buf_init_alloc(&tmp, size))
     return NULL;
-  memcpy(buf->ptr.p, p, size);
-  buf->wpos = size;
+  memcpy(tmp.ptr.p, p, size);
+  tmp.wpos = size;
+  *buf = tmp;
   return buf;
 }
 
@@ -228,36 +227,46 @@ s_buf * buf_init_alloc (s_buf *buf, uw size)
   if (! size)
     return buf_init(buf, false, 0, NULL);
   p = calloc(size + 1, 1);
-  if (!p)
-    err(1, "out of memory");
+  if (! p) {
+    err_puts("buf_init_alloc: failed to allocate memory");
+    assert(! "buf_init_alloc: failed to allocate memory");
+    return NULL;
+  }
   return buf_init(buf, true, size, p);
 }
 
 s_buf * buf_init_str (s_buf *buf, bool p_free, s_str *p)
 {
+  s_buf tmp = {0};
   assert(buf);
   assert(p);
-  buf_init(buf, p_free, p->size, (char *) p->ptr.pchar);
-  buf->wpos = p->size;
+  buf_init(&tmp, p_free, p->size, (char *) p->ptr.pchar);
+  tmp.wpos = p->size;
+  *buf = tmp;
   return buf;
 }
 
 s_buf * buf_init_str_copy (s_buf *buf, const s_str *str)
 {
+  s_buf tmp = {0};
   assert(buf);
   assert(str);
-  buf_init_alloc(buf, str->size);
-  memcpy(buf->ptr.p, str->ptr.p, str->size);
-  buf->wpos = str->size;
+  buf_init_alloc(&tmp, str->size);
+  memcpy(tmp.ptr.p, str->ptr.p, str->size);
+  tmp.wpos = str->size;
+  *buf = tmp;
   return buf;
 }
 
 s_buf * buf_new (bool p_free, uw size, char *p)
 {
   s_buf *buf;
-  buf = malloc(sizeof(s_buf));
-  if (! buf)
-    err(1, "out of memory");
+  buf = calloc(1, sizeof(s_buf));
+  if (! buf) {
+    err_puts("buf_new: failed to allocate memory");
+    assert(! "buf_new: failed to allocate memory");
+    return NULL;
+  }
   buf_init(buf, p_free, size, p);
   return buf;
 }
@@ -265,10 +274,16 @@ s_buf * buf_new (bool p_free, uw size, char *p)
 s_buf * buf_new_alloc (uw size)
 {
   s_buf *buf;
-  buf = malloc(sizeof(s_buf));
-  if (! buf)
-    err(1, "out of memory");
-  buf_init_alloc(buf, size);
+  buf = calloc(1, sizeof(s_buf));
+  if (! buf) {
+    err_puts("buf_new_alloc: failed to allocate memory");
+    assert(! "buf_new_alloc: failed to allocate memory");
+    return NULL;
+  }
+  if (! buf_init_alloc(buf, size)) {
+    free(buf);
+    return NULL;
+  }
   return buf;
 }
 
diff --git a/libc3/buf_parse.c b/libc3/buf_parse.c
index 6417ec5..1b52b64 100644
--- a/libc3/buf_parse.c
+++ b/libc3/buf_parse.c
@@ -2560,6 +2560,48 @@ sw buf_parse_str_character_unicode (s_buf *buf, character *dest)
   return r;
 }
 
+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;
+  sw r;
+  sw result;
+  s_buf_save save;
+  uw start;
+  buf_save_init(buf, &save);
+  r = buf_parse_str(buf, &in);
+  if (r <= 0)
+    goto clean;
+  result = r;
+  buf_init_str(&in_buf, false, &in);
+  start = 0;
+  while (1) {
+    if (! eval) {
+      end = in_buf.rpos;
+      r = buf_read_1(&in_buf, "#{");
+      if (r < 0)
+        goto restore;
+      if (r > 0) {
+        buf_slice_to_str(&in_buf, start, end, &out);
+        eval = true;
+      }
+    }
+    r = buf_read_character_utf8(&in_buf, &c);
+    
+  }
+  r = result;
+  goto clean;
+ restore:
+  buf_save_restore_rpos(buf, &save);
+ clean:
+  buf_save_clean(buf, &save);
+  return r;
+}
+
 sw buf_parse_str_u8 (s_buf *buf, u8 *dest)
 {
   u8 digit[3];
diff --git a/libc3/str.c b/libc3/str.c
index 90f1750..f8e77b3 100644
--- a/libc3/str.c
+++ b/libc3/str.c
@@ -167,8 +167,10 @@ s_str * str_init_cat (s_str *str, const s_str *a, const s_str *b)
     return NULL;
   }
   tmp.ptr.p = tmp.free.p;
-  memcpy(tmp.free.ps8, a->ptr.p, a->size);
-  memcpy(tmp.free.ps8 + a->size, b->ptr.p, b->size);
+  if (a->size)
+    memcpy(tmp.free.ps8, a->ptr.p, a->size);
+  if (b->size)
+    memcpy(tmp.free.ps8 + a->size, b->ptr.p, b->size);
   *str = tmp;
   return str;
 }