Commit 551e8f69f557d221391665c7adb93415787d1527

Thomas de Grivel 2024-06-30T00:24:16

work on error handling for structs and struct_type, and fix bug in env_struct_type_exists

diff --git a/libc3/buf_parse.c b/libc3/buf_parse.c
index dd82df2..5f0beba 100644
--- a/libc3/buf_parse.c
+++ b/libc3/buf_parse.c
@@ -3154,9 +3154,10 @@ sw buf_parse_struct (s_buf *buf, s_struct *dest)
   if (r > 0) {
     result += r;
     if (! struct_init(&tmp, module)) {
-      err_write_1("buf_parse_struct: struct_init ");
+      err_write_1("buf_parse_struct: struct_init(");
       err_inspect_sym(&module);
-      err_puts(".");
+      err_puts(")");
+      assert(! "buf_parse_struct: struct init");
       r = -2;
       goto clean;
     }
diff --git a/libc3/data.c b/libc3/data.c
index 75b3383..c237816 100644
--- a/libc3/data.c
+++ b/libc3/data.c
@@ -82,7 +82,8 @@ sw data_buf_inspect (const s_sym *type, s_buf *buf, const void *data)
     return buf_inspect_var(buf, data);
   if (type == &g_sym_Void)
     return buf_inspect_void(buf, data);
-  st = struct_type_find(type);
+  if (! struct_type_find(type, &st))
+    return -1;
   if (st) {
     s_struct s = {0};
     s.type = st;
@@ -167,7 +168,8 @@ sw data_buf_inspect_size (const s_sym *type, const void *data)
     return buf_inspect_var_size(data);
   if (type == &g_sym_Void)
     return buf_inspect_void_size(data);
-  st = struct_type_find(type);
+  if (! struct_type_find(type, &st))
+    return -1;
   if (st) {
     s.type = st;
     s.data = (void *) data;
@@ -302,7 +304,8 @@ bool data_clean (const s_sym *type, void *data)
   if (type == &g_sym_Void) {
     return true;
   }
-  st = struct_type_find(type);
+  if (! struct_type_find(type, &st))
+    return false;
   if (st) {
     s.type = st;
     s.data = data;
@@ -388,7 +391,8 @@ bool data_compare (const s_sym *type, const void *a, const void *b)
     return compare_ptr(a, b);
   if (type == &g_sym_Void)
     return 0;
-  st = struct_type_find(type);
+  if (! struct_type_find(type, &st))
+    return COMPARE_ERROR;
   if (st) {
     sa.type = st;
     sa.data = (void *) a;
@@ -400,7 +404,7 @@ bool data_compare (const s_sym *type, const void *a, const void *b)
   err_inspect_sym(&type);
   err_write_1("\n");
   assert(! "data_compare: unknown type");
-  return false;
+  return COMPARE_ERROR;
 }
 
 bool data_hash_update (const s_sym *type, t_hash *hash, const void *data)
@@ -474,7 +478,8 @@ bool data_hash_update (const s_sym *type, t_hash *hash, const void *data)
     return hash_update_var(hash, data);
   if (type == &g_sym_Void)
     return hash_update_void(hash, data);
-  st = struct_type_find(type);
+  if (! struct_type_find(type, &st))
+    return false;
   if (st) {
     s.type = st;
     s.data = (void *) data;
@@ -566,7 +571,8 @@ void * data_init_cast (void *data, const s_sym * const *type,
   /*
   if (sym_is_array_type(t)) {
   */
-  st = struct_type_find(t);
+  if (! struct_type_find(t, &st))
+    return NULL;
   if (st) {
     s.type = st;
     s.data = data;
@@ -651,7 +657,8 @@ void * data_init_copy (const s_sym *type, void *data, const void *src)
     return var_init_copy(data, src);
   if (type == &g_sym_Void)
     return data;
-  st = struct_type_find(type);
+  if (! struct_type_find(type, &st))
+    return NULL;
   if (st) {
     t.type = s.type = st;
     s.data = data;
diff --git a/libc3/env.c b/libc3/env.c
index e07c93c..42525cc 100644
--- a/libc3/env.c
+++ b/libc3/env.c
@@ -2209,8 +2209,6 @@ bool env_module_maybe_reload (s_env *env, const s_sym *module)
   bool r = false;
   s_tag tag_load_time = {0};
   s_tag tag_mtime;
-  if (! env_module_load_time(env, module, &tag_load_time))
-    return env_module_load(env, module);
   if (module_path(module, &env->module_path, C3_EXT, &path)) {
     if (file_access(&path, &g_sym_r))
       r = true;
@@ -2223,12 +2221,10 @@ bool env_module_maybe_reload (s_env *env, const s_sym *module)
     else
       str_clean(&path);
   }
-  if (! r) {
-    err_write_1("env_module_maybe_reload: module not found: ");
-    err_inspect_sym(&module);
-    err_write_1("\n");
-    return false;
-  }
+  if (! r)
+    return true;
+  if (! env_module_load_time(env, module, &tag_load_time))
+    return env_module_load(env, module);
   if (! file_mtime(&path, &tag_mtime)) {
     str_clean(&path);
     return false;
@@ -2563,36 +2559,33 @@ bool * env_struct_type_exists (s_env *env, const s_sym *module,
 {
   s_facts_cursor cursor;
   const s_fact *fact;
-  s_tag tag_defstruct;
+  s_tag tag_struct_type;
   s_tag tag_module;
   s_tag tag_var;
   assert(env);
   assert(module);
   assert(dest);
   tag_init_sym(&tag_module, module);
-  tag_init_sym(&tag_defstruct, &g_sym_defstruct);
+  tag_init_sym(&tag_struct_type, &g_sym_struct_type);
   tag_init_var(&tag_var, &g_sym_Tag);
   if (! env_module_maybe_reload(env, module))
     return NULL;
   if (! facts_with_tags(&env->facts, &cursor, &tag_module,
-                        &tag_defstruct, &tag_var))
+                        &tag_struct_type, &tag_var))
     return NULL;
   if (! facts_cursor_next(&cursor, &fact))
     return NULL;
-  if (! fact) {
-    facts_save_file(&env->facts, "env_struct_type_exists.facts");
-  }
   *dest = fact ? true : false;
   facts_cursor_clean(&cursor);
   return dest;
 }
 
-const s_struct_type * env_struct_type_find (s_env *env,
-                                            const s_sym *module)
+const s_struct_type ** env_struct_type_find (s_env *env,
+                                             const s_sym *module,
+                                             const s_struct_type **dest)
 {
   s_facts_with_cursor cursor;
   const s_fact *found;
-  const s_struct_type *result;
   s_tag tag_struct_type;
   s_tag tag_module;
   s_tag tag_var;
@@ -2602,8 +2595,12 @@ const s_struct_type * env_struct_type_find (s_env *env,
   tag_init_sym(&tag_module, module);
   tag_init_sym(&tag_struct_type, &g_sym_struct_type);
   tag_init_var(&tag_var, &g_sym_Tag);
-  if (! env_module_maybe_reload(env, module))
+  if (! env_module_maybe_reload(env, module)) {
+    err_write_1("env_struct_type_find: env_module_maybe_reload(");
+    err_inspect_sym(&module);
+    err_puts(")");
     return NULL;
+  }
   if (! facts_with(&env->facts, &cursor, (t_facts_spec) {
                    &tag_module, &tag_struct_type, &tag_var,
                    NULL, NULL }))
@@ -2612,7 +2609,8 @@ const s_struct_type * env_struct_type_find (s_env *env,
     return NULL;
   if (! found) {
     facts_with_cursor_clean(&cursor);
-    return NULL;
+    *dest = NULL;
+    return dest;
   }
   if (found->object->type != TAG_STRUCT_TYPE) {
     tag_type(found->object, &type);
@@ -2624,9 +2622,9 @@ const s_struct_type * env_struct_type_find (s_env *env,
     assert(! "env_struct_type_find: invalid struct_type");
     return NULL;
   }
-  result = &found->object->data.struct_type;
+  *dest = &found->object->data.struct_type;
   facts_with_cursor_clean(&cursor);
-  return result;
+  return dest;
 }
 
 f_clean env_struct_type_get_clean (s_env *env, const s_sym *module)
diff --git a/libc3/env.h b/libc3/env.h
index bc76226..84eebf4 100644
--- a/libc3/env.h
+++ b/libc3/env.h
@@ -198,8 +198,9 @@ u8            env_special_operator_arity (s_env *env,
                                           const s_ident *ident);
 bool *        env_struct_type_exists (s_env *env, const s_sym *module,
                                       bool *dest);
-const s_struct_type *
-              env_struct_type_find (s_env *env, const s_sym *module);
+const s_struct_type **
+              env_struct_type_find (s_env *env, const s_sym *module,
+                                    const s_struct_type **dest);
 f_clean       env_struct_type_get_clean (s_env *env,
                                          const s_sym *module);
 s_list **     env_struct_type_get_spec (s_env *env, const s_sym *module,
diff --git a/libc3/struct.c b/libc3/struct.c
index 62dfb9b..832d254 100644
--- a/libc3/struct.c
+++ b/libc3/struct.c
@@ -122,7 +122,12 @@ s_struct * struct_init (s_struct *s, const s_sym *module)
   s_struct tmp = {0};
   assert(s);
   assert(module);
-  tmp.type = struct_type_find(module);
+  if (! struct_type_find(module, &tmp.type)) {
+    err_write_1("struct_init: struct_type_find(");
+    err_inspect_sym(&module);
+    err_puts(")");
+    return NULL;
+  }
   if (! tmp.type) {
     err_write_1("struct_init: struct_type not found: ");
     err_inspect_sym(&module);
@@ -263,9 +268,14 @@ s_struct * struct_init_with_data (s_struct *s, const s_sym *module,
   s_struct tmp = {0};
   assert(s);
   assert(module);
-  tmp.type = struct_type_find(module);
-  if (! tmp.type)
+  if (! struct_type_find(module, &tmp.type))
+    return NULL;
+  if (! tmp.type) {
+    err_write_1("struct_init_with_data: struct_type not found: ");
+    err_inspect_sym(&module);
+    err_write_1("\n");
     return NULL;
+  }
   tmp.free_data = free_data;
   tmp.data = data;
   *s = tmp;
diff --git a/libc3/struct_type.c b/libc3/struct_type.c
index 9de6ad1..9377aed 100644
--- a/libc3/struct_type.c
+++ b/libc3/struct_type.c
@@ -42,9 +42,10 @@ bool * struct_type_exists (const s_sym *module, bool *dest)
   return env_struct_type_exists(&g_c3_env, module, dest);
 }
 
-const s_struct_type * struct_type_find (const s_sym *module)
+const s_struct_type ** struct_type_find (const s_sym *module,
+                                         const s_struct_type **dest)
 {
-  return env_struct_type_find(&g_c3_env, module);
+  return env_struct_type_find(&g_c3_env, module, dest);
 }
 
 s_struct_type * struct_type_init (s_struct_type *st,
diff --git a/libc3/struct_type.h b/libc3/struct_type.h
index 351e7dc..0930e40 100644
--- a/libc3/struct_type.h
+++ b/libc3/struct_type.h
@@ -41,9 +41,10 @@ s_struct_type * struct_type_new (const s_sym *module,
                                  const s_list *spec);
 
 /* Observers. */
-bool *                struct_type_exists (const s_sym *module,
-                                          bool *dest);
-const s_struct_type * struct_type_find (const s_sym *module);
-uw                    struct_type_padding (uw offset, uw size);
+bool *                 struct_type_exists (const s_sym *module,
+                                           bool *dest);
+const s_struct_type ** struct_type_find (const s_sym *module,
+                                         const s_struct_type **dest);
+uw                     struct_type_padding (uw offset, uw size);
 
 #endif /* LIBC3_STRUCT_TYPE_H */
diff --git a/libc3/sym.c b/libc3/sym.c
index 92b2862..3b284b9 100644
--- a/libc3/sym.c
+++ b/libc3/sym.c
@@ -626,7 +626,8 @@ bool sym_must_clean (const s_sym *sym, bool *must_clean)
     *must_clean = false;
     return true;
   }
-  st = struct_type_find(sym);
+  if (! struct_type_find(sym, &st))
+    return false;
   if (st) {
     *must_clean = st->must_clean;
     return true;
@@ -1156,7 +1157,8 @@ bool sym_type_size (const s_sym *type, uw *dest)
     *dest = 0;
     return true;
   }
-  st = struct_type_find(type);
+  if (! struct_type_find(type, &st))
+    return false;
   if (st) {
     *dest = st->size;
     return true;