changeset 43:0efbcd20df2c

value: Implement yvalue_destroy
author Lewin Bormann <lbo@spheniscida.de>
date Wed, 21 Aug 2019 21:59:11 +0200
parents 9bead1335e42
children 6183b0c133bf
files .clang CMakeLists.txt src/.clang src/value.c src/value.h src/value_test.c
diffstat 6 files changed, 39 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/.clang	Wed Aug 21 13:09:17 2019 +0200
+++ b/.clang	Wed Aug 21 21:59:11 2019 +0200
@@ -1,1 +1,1 @@
-flags = -I. -Ibuild/
+flags = -I. -I./build
--- a/CMakeLists.txt	Wed Aug 21 13:09:17 2019 +0200
+++ b/CMakeLists.txt	Wed Aug 21 21:59:11 2019 +0200
@@ -6,6 +6,8 @@
 
 ADD_COMPILE_OPTIONS(-std=c11 -D_XOPEN_SOURCE=500 -D__ISOC99_SOURCE)
 
+# SET(CMAKE_EXPORT_COMPILE_COMMANDS ON)
+
 if (CMAKE_BUILD_TYPE STREQUAL "Release")
 ADD_COMPILE_OPTIONS(-O3)
 else ()
--- a/src/.clang	Wed Aug 21 13:09:17 2019 +0200
+++ b/src/.clang	Wed Aug 21 21:59:11 2019 +0200
@@ -1,1 +1,1 @@
-flags = -I.. -I../build/
+flags = -I.. -I../build
--- a/src/value.c	Wed Aug 21 13:09:17 2019 +0200
+++ b/src/value.c	Wed Aug 21 21:59:11 2019 +0200
@@ -42,6 +42,16 @@
     YVEC_INIT(&yvalue_table, YVALUE_INITIAL_VALUES, yvalue_t);
 }
 
+void yvalue_destroy(yvalue_t* val) {
+    switch (val->typ) {
+        case YVALUE_EXPR:
+            yexpr_destroy(&val->value.expr);
+            break;
+        default:
+            return;
+    }
+}
+
 yvalue_id_t yvalue_resolve_symbol(ystr_t* sym) {
     if (ystr_len(sym) == 0) return YVALUE_INVALID_ID;
     yvalue_init_tables();
--- a/src/value.h	Wed Aug 21 13:09:17 2019 +0200
+++ b/src/value.h	Wed Aug 21 21:59:11 2019 +0200
@@ -36,6 +36,9 @@
 /**
  * @brief A value with a name, stored in the global value table to be referenced
  * by name or ID. To be used as pointer (not value).
+ *
+ * Expressions or functions assigned to a yvalue_t are owned by it; do not
+ * destroy them. Use `yvalue_destroy()` instead.
  */
 typedef struct {
     union {
@@ -45,27 +48,34 @@
     enum YVALUE_TYPE typ;
 } yvalue_t;
 
+
 /**
- * @brief Resolve a symbol to an ID.
+ * @brief Free all memory used by a value.
+ */
+void yvalue_destroy(yvalue_t* val);
+
+/**
+ * @brief Resolve a symbol to an ID. Caller retains ownership of `sym`.
  */
 yvalue_id_t yvalue_resolve_symbol(ystr_t* sym);
 
 /**
  * @brief Resolve a symbol to an ID or create a new ID if one doesn't exist
- * already. Also allocates a place in the value table.
+ * already. Also allocates a place in the value table. Caller retains ownership
+ * of `sym`.
  */
 yvalue_id_t yvalue_resolve_or_create_symbol(ystr_t* sym);
 
 /**
  * @brief Translate a symbol in `ref` to an ID, or create a new ID. `ref` is
- * updated to be an ID ref.
+ * updated to be an ID ref. Caller retains ownership of `ref`.
  */
 bool yvalue_resolve_or_create_ref(yref_t* ref);
 
 /**
  * @brief Set a value referenced by `ref`. If a new value should be created, use
  * the special ref value `YVALUE_INSERT`. The value pointed to by val may not be
- * destroyed afterwards (the variable itself can be deallocated though)
+ * destroyed afterwards (the variable itself can be deallocated though).
  */
 yref_t yvalue_set(yref_t ref, yvalue_t* val);
 
--- a/src/value_test.c	Wed Aug 21 13:09:17 2019 +0200
+++ b/src/value_test.c	Wed Aug 21 21:59:11 2019 +0200
@@ -2,9 +2,6 @@
 
 #include <assert.h>
 
-#include <src/base/str.h>
-#include <src/expr.h>
-
 void test_value_create_resolve(void) {
     ystr_t sym;
     ystr_init(&sym, "vcr_symbol");
@@ -18,7 +15,7 @@
 
 void test_ref_create_resolve(void) {
     ystr_t symbol = ystr_new("rcr_symbol");
-    ystr_t symbol2;
+    ystr_t symbol2 = ystr_new(NULL);
     ystr_copy(&symbol, &symbol2);
     yref_t ref = yref_new_str(&symbol);  // symbol is now owned by ref.
 
@@ -26,6 +23,9 @@
     assert(YVALUE_INVALID_ID != yvalue_resolve_symbol(&symbol2));
     assert(YREF_ID == ref.typ);
     assert(ref.ref.id == yvalue_resolve_symbol(&symbol2));
+
+    ystr_destroy(&symbol2);
+    yref_destroy(&ref);
 }
 
 void test_value_set(void) {
@@ -65,6 +65,13 @@
     yref_t ref_invalid = yref_new_c("invalid_entry");
     assert(NULL == yvalue_get(ref_invalid));
     assert(NULL != yvalue_get(ref3));
+
+    yvalue_destroy(&val);
+    yref_destroy(&ref);
+    yref_destroy(&ref2);
+    yref_destroy(&ref2b);
+    yref_destroy(&ref3);
+    yref_destroy(&ref_invalid);
 }
 
 int main(int argc, char** argv) {