Sfoglia il codice sorgente

ncd: move NCDValue into NCDAst

ambrop7 13 anni fa
parent
commit
2dcfbced3b
7 ha cambiato i file con 1148 aggiunte e 1251 eliminazioni
  1. 3 8
      ncd/CMakeLists.txt
  2. 724 0
      ncd/NCDAst.c
  3. 419 1
      ncd/NCDAst.h
  4. 1 1
      ncd/NCDAst_maptree.h
  5. 1 1
      ncd/NCDValCompat.h
  6. 0 757
      ncd/NCDValue.c
  7. 0 483
      ncd/NCDValue.h

+ 3 - 8
ncd/CMakeLists.txt

@@ -26,10 +26,6 @@ add_library(ncdtokenizer
 )
 target_link_libraries(ncdtokenizer base)
 
-add_library(ncdvalue
-    NCDValue.c
-)
-
 add_library(ncdval
     NCDVal.c
 )
@@ -38,7 +34,7 @@ target_link_libraries(ncdval base)
 add_library(ncdvalcompat
     NCDValCompat.c
 )
-target_link_libraries(ncdvalcompat ncdvalue ncdval)
+target_link_libraries(ncdvalcompat ncdast ncdval)
 
 add_library(ncdvaluegenerator
     NCDValueGenerator.c
@@ -53,7 +49,6 @@ target_link_libraries(ncdvalueparser base ncdval ncdtokenizer ncdvalcons)
 add_library(ncdast
     NCDAst.c
 )
-target_link_libraries(ncdast ncdvalue)
 
 add_library(ncdconfigparser
     NCDConfigParser.c
@@ -68,7 +63,7 @@ target_link_libraries(ncdsugar ncdast)
 add_library(ncdrequest
     NCDRequestClient.c
 )
-target_link_libraries(ncdrequest base system ncdvalue ncdvaluegenerator ncdvalueparser)
+target_link_libraries(ncdrequest base system ncdvaluegenerator ncdvalueparser)
 
 add_library(ncdinterfacemonitor
     NCDInterfaceMonitor.c
@@ -160,7 +155,7 @@ add_executable(badvpn-ncd
     ${NCD_ADDITIONAL_SOURCES}
 )
 target_link_libraries(badvpn-ncd
-    system flow flowextra dhcpclient arpprobe ncdvalue ncdval ncdvalcompat ncdvaluegenerator
+    system flow flowextra dhcpclient arpprobe ncdval ncdvalcompat ncdvaluegenerator
     ncdvalueparser ncdconfigparser ncdsugar udevmonitor ncdinterfacemonitor ncdrequest
     badvpn_random
 )

+ 724 - 0
ncd/NCDAst.c

@@ -29,11 +29,735 @@
 
 #include <stdlib.h>
 #include <limits.h>
+#include <stdarg.h>
+#include <string.h>
 
 #include <misc/offset.h>
 
 #include "NCDAst.h"
 
+struct NCDValue__list_element {
+    LinkedList1Node list_node;
+    NCDValue v;
+};
+
+struct NCDValue__map_element {
+    NCDValue__MapTreeNode tree_node;
+    NCDValue key;
+    NCDValue val;
+};
+
+#include "NCDAst_maptree.h"
+#include <structure/SAvl_impl.h>
+
+static void value_assert (NCDValue *o)
+{
+    switch (o->type) {
+        case NCDVALUE_STRING:
+        case NCDVALUE_LIST:
+        case NCDVALUE_MAP:
+        case NCDVALUE_VAR:
+            return;
+        default:
+            ASSERT(0);
+    }
+}
+
+int NCDValue_InitCopy (NCDValue *o, NCDValue *v)
+{
+    value_assert(v);
+    
+    switch (v->type) {
+        case NCDVALUE_STRING: {
+            return NCDValue_InitStringBin(o, v->string, v->string_len);
+        } break;
+        
+        case NCDVALUE_LIST: {
+            NCDValue_InitList(o);
+            
+            for (LinkedList1Node *n = LinkedList1_GetFirst(&v->list); n; n = LinkedList1Node_Next(n)) {
+                struct NCDValue__list_element *e = UPPER_OBJECT(n, struct NCDValue__list_element, list_node);
+                
+                NCDValue tmp;
+                if (!NCDValue_InitCopy(&tmp, &e->v)) {
+                    goto fail;
+                }
+                
+                if (!NCDValue_ListAppend(o, tmp)) {
+                    NCDValue_Free(&tmp);
+                    goto fail;
+                }
+            }
+            
+            return 1;
+            
+        fail:
+            NCDValue_Free(o);
+            return 0;
+        } break;
+        
+        case NCDVALUE_MAP: {
+            NCDValue_InitMap(o);
+            
+            for (NCDValue *ekey = NCDValue_MapFirstKey(v); ekey; ekey = NCDValue_MapNextKey(v, ekey)) {
+                NCDValue *eval = NCDValue_MapKeyValue(v, ekey);
+                
+                NCDValue tmp_key;
+                NCDValue tmp_val;
+                if (!NCDValue_InitCopy(&tmp_key, ekey)) {
+                    goto mapfail;
+                }
+                if (!NCDValue_InitCopy(&tmp_val, eval)) {
+                    NCDValue_Free(&tmp_key);
+                    goto mapfail;
+                }
+                
+                if (!NCDValue_MapInsert(o, tmp_key, tmp_val)) {
+                    NCDValue_Free(&tmp_key);
+                    NCDValue_Free(&tmp_val);
+                    goto mapfail;
+                }
+            }
+            
+            return 1;
+            
+        mapfail:
+            NCDValue_Free(o);
+            return 0;
+        } break;
+        
+        case NCDVALUE_VAR: {
+            return NCDValue_InitVar(o, v->var_name);
+        } break;
+        
+        default:
+            ASSERT(0);
+    }
+    
+    return 0;
+}
+
+void NCDValue_Free (NCDValue *o)
+{
+    switch (o->type) {
+        case NCDVALUE_STRING: {
+            free(o->string);
+        } break;
+        
+        case NCDVALUE_LIST: {
+            LinkedList1Node *n;
+            while (n = LinkedList1_GetFirst(&o->list)) {
+                struct NCDValue__list_element *e = UPPER_OBJECT(n, struct NCDValue__list_element, list_node);
+                
+                NCDValue_Free(&e->v);
+                LinkedList1_Remove(&o->list, &e->list_node);
+                free(e);
+            }
+        } break;
+        
+        case NCDVALUE_MAP: {
+            struct NCDValue__map_element *e;
+            while (e = NCDValue__MapTree_GetFirst(&o->map_tree, 0)) {
+                NCDValue__MapTree_Remove(&o->map_tree, 0, e);
+                NCDValue_Free(&e->key);
+                NCDValue_Free(&e->val);
+                free(e);
+            }
+        } break;
+        
+        case NCDVALUE_VAR: {
+            free(o->var_name);
+        } break;
+        
+        default:
+            ASSERT(0);
+    }
+}
+
+int NCDValue_Type (NCDValue *o)
+{
+    value_assert(o);
+    
+    return o->type;
+}
+
+int NCDValue_IsString (NCDValue *o)
+{
+    value_assert(o);
+    
+    return o->type == NCDVALUE_STRING;
+}
+
+int NCDValue_IsStringNoNulls (NCDValue *o)
+{
+    return NCDValue_IsString(o) && NCDValue_StringHasNoNulls(o);
+}
+
+int NCDValue_InitString (NCDValue *o, const char *str)
+{
+    return NCDValue_InitStringBin(o, (const uint8_t *)str, strlen(str));
+}
+
+int NCDValue_InitStringBin (NCDValue *o, const uint8_t *str, size_t len)
+{
+    if (len == SIZE_MAX) {
+        return 0;
+    }
+    
+    if (!(o->string = malloc(len + 1))) {
+        return 0;
+    }
+    
+    memcpy(o->string, str, len);
+    o->string[len] = '\0';
+    o->string_len = len;
+    
+    o->type = NCDVALUE_STRING;
+    
+    return 1;
+}
+
+char * NCDValue_StringValue (NCDValue *o)
+{
+    ASSERT(o->type == NCDVALUE_STRING)
+    
+    return (char *)o->string;
+}
+
+size_t NCDValue_StringLength (NCDValue *o)
+{
+    ASSERT(o->type == NCDVALUE_STRING)
+    
+    return o->string_len;
+}
+
+int NCDValue_StringHasNoNulls (NCDValue *o)
+{
+    ASSERT(o->type == NCDVALUE_STRING)
+    
+    return strlen((char *)o->string) == o->string_len;
+}
+
+int NCDValue_StringHasNulls (NCDValue *o)
+{
+    ASSERT(o->type == NCDVALUE_STRING)
+    
+    return !NCDValue_StringHasNoNulls(o);
+}
+
+int NCDValue_StringEquals (NCDValue *o, const char *str)
+{
+    ASSERT(o->type == NCDVALUE_STRING)
+    
+    return NCDValue_StringHasNoNulls(o) && !strcmp((const char *)o->string, str);
+}
+
+int NCDValue_IsList (NCDValue *o)
+{
+    value_assert(o);
+    
+    return o->type == NCDVALUE_LIST;
+}
+
+void NCDValue_InitList (NCDValue *o)
+{
+    LinkedList1_Init(&o->list);
+    o->list_count = 0;
+    
+    o->type = NCDVALUE_LIST;
+}
+
+int NCDValue_ListAppend (NCDValue *o, NCDValue v)
+{
+    value_assert(o);
+    value_assert(&v);
+    ASSERT(o->type == NCDVALUE_LIST)
+    
+    if (o->list_count == SIZE_MAX) {
+        return 0;
+    }
+    
+    struct NCDValue__list_element *e = malloc(sizeof(*e));
+    if (!e) {
+        return 0;
+    }
+    
+    LinkedList1_Append(&o->list, &e->list_node);
+    o->list_count++;
+    e->v = v;
+    
+    return 1;
+}
+
+int NCDValue_ListPrepend (NCDValue *o, NCDValue v)
+{
+    value_assert(o);
+    value_assert(&v);
+    ASSERT(o->type == NCDVALUE_LIST)
+    
+    if (o->list_count == SIZE_MAX) {
+        return 0;
+    }
+    
+    struct NCDValue__list_element *e = malloc(sizeof(*e));
+    if (!e) {
+        return 0;
+    }
+    
+    LinkedList1_Prepend(&o->list, &e->list_node);
+    o->list_count++;
+    e->v = v;
+    
+    return 1;
+}
+
+int NCDValue_ListAppendList (NCDValue *o, NCDValue l)
+{
+    value_assert(o);
+    value_assert(&l);
+    ASSERT(o->type == NCDVALUE_LIST)
+    ASSERT(l.type == NCDVALUE_LIST)
+    
+    if (l.list_count > SIZE_MAX - o->list_count) {
+        return 0;
+    }
+    
+    LinkedList1Node *n;
+    while (n = LinkedList1_GetFirst(&l.list)) {
+        struct NCDValue__list_element *e = UPPER_OBJECT(n, struct NCDValue__list_element, list_node);
+        LinkedList1_Remove(&l.list, &e->list_node);
+        LinkedList1_Append(&o->list, &e->list_node);
+    }
+    
+    o->list_count += l.list_count;
+    
+    return 1;
+}
+
+size_t NCDValue_ListCount (NCDValue *o)
+{
+    value_assert(o);
+    ASSERT(o->type == NCDVALUE_LIST)
+    
+    return o->list_count;
+}
+
+NCDValue * NCDValue_ListFirst (NCDValue *o)
+{
+    value_assert(o);
+    ASSERT(o->type == NCDVALUE_LIST)
+    
+    LinkedList1Node *ln = LinkedList1_GetFirst(&o->list);
+    
+    if (!ln) {
+        return NULL;
+    }
+    
+    struct NCDValue__list_element *e = UPPER_OBJECT(ln, struct NCDValue__list_element, list_node);
+    
+    return &e->v;
+}
+
+NCDValue * NCDValue_ListNext (NCDValue *o, NCDValue *ev)
+{
+    value_assert(o);
+    ASSERT(o->type == NCDVALUE_LIST)
+    
+    struct NCDValue__list_element *cur_e = UPPER_OBJECT(ev, struct NCDValue__list_element, v);
+    LinkedList1Node *ln = LinkedList1Node_Next(&cur_e->list_node);
+    
+    if (!ln) {
+        return NULL;
+    }
+    
+    struct NCDValue__list_element *e = UPPER_OBJECT(ln, struct NCDValue__list_element, list_node);
+    
+    return &e->v;
+}
+
+int NCDValue_ListRead (NCDValue *o, int num, ...)
+{
+    value_assert(o);
+    ASSERT(o->type == NCDVALUE_LIST)
+    ASSERT(num >= 0)
+    
+    if (num != NCDValue_ListCount(o)) {
+        return 0;
+    }
+    
+    va_list ap;
+    va_start(ap, num);
+    
+    for (LinkedList1Node *n = LinkedList1_GetFirst(&o->list); n; n = LinkedList1Node_Next(n)) {
+        struct NCDValue__list_element *e = UPPER_OBJECT(n, struct NCDValue__list_element, list_node);
+        
+        NCDValue **dest = va_arg(ap, NCDValue **);
+        *dest = &e->v;
+    }
+    
+    va_end(ap);
+    
+    return 1;
+}
+
+int NCDValue_ListReadHead (NCDValue *o, int num, ...)
+{
+    value_assert(o);
+    ASSERT(o->type == NCDVALUE_LIST)
+    ASSERT(num >= 0)
+    
+    if (num > NCDValue_ListCount(o)) {
+        return 0;
+    }
+    
+    va_list ap;
+    va_start(ap, num);
+    
+    LinkedList1Node *n = LinkedList1_GetFirst(&o->list);
+    while (num > 0) {
+        ASSERT(n)
+        struct NCDValue__list_element *e = UPPER_OBJECT(n, struct NCDValue__list_element, list_node);
+        
+        NCDValue **dest = va_arg(ap, NCDValue **);
+        *dest = &e->v;
+        
+        n = LinkedList1Node_Next(n);
+        num--;
+    }
+    
+    va_end(ap);
+    
+    return 1;
+}
+
+NCDValue * NCDValue_ListGet (NCDValue *o, size_t pos)
+{
+    value_assert(o);
+    ASSERT(o->type == NCDVALUE_LIST)
+    ASSERT(pos < o->list_count)
+    
+    NCDValue *e = NCDValue_ListFirst(o);
+    while (e) {
+        if (pos == 0) {
+            break;
+        }
+        pos--;
+        e = NCDValue_ListNext(o, e);
+    }
+    ASSERT(e)
+    
+    return e;
+}
+
+NCDValue NCDValue_ListShift (NCDValue *o)
+{
+    value_assert(o);
+    ASSERT(o->type == NCDVALUE_LIST)
+    ASSERT(o->list_count > 0)
+    
+    struct NCDValue__list_element *e = UPPER_OBJECT(LinkedList1_GetFirst(&o->list), struct NCDValue__list_element, list_node);
+    
+    NCDValue v = e->v;
+    
+    LinkedList1_Remove(&o->list, &e->list_node);
+    o->list_count--;
+    free(e);
+    
+    return v;
+}
+
+NCDValue NCDValue_ListRemove (NCDValue *o, NCDValue *ev)
+{
+    value_assert(o);
+    ASSERT(o->type == NCDVALUE_LIST)
+    ASSERT(o->list_count > 0)
+    
+    struct NCDValue__list_element *e = UPPER_OBJECT(ev, struct NCDValue__list_element, v);
+    
+    NCDValue v = e->v;
+    
+    LinkedList1_Remove(&o->list, &e->list_node);
+    o->list_count--;
+    free(e);
+    
+    return v;
+}
+
+int NCDValue_IsMap (NCDValue *o)
+{
+    value_assert(o);
+    
+    return o->type == NCDVALUE_MAP;
+}
+
+void NCDValue_InitMap (NCDValue *o)
+{
+    o->type = NCDVALUE_MAP;
+    NCDValue__MapTree_Init(&o->map_tree);
+    o->map_count = 0;
+}
+
+size_t NCDValue_MapCount (NCDValue *o)
+{
+    value_assert(o);
+    ASSERT(o->type == NCDVALUE_MAP)
+    
+    return o->map_count;
+}
+
+NCDValue * NCDValue_MapFirstKey (NCDValue *o)
+{
+    value_assert(o);
+    ASSERT(o->type == NCDVALUE_MAP)
+    
+    struct NCDValue__map_element *e = NCDValue__MapTree_GetFirst(&o->map_tree, 0);
+    if (!e) {
+        return NULL;
+    }
+    
+    value_assert(&e->key);
+    value_assert(&e->val);
+    
+    return &e->key;
+}
+
+NCDValue * NCDValue_MapNextKey (NCDValue *o, NCDValue *ekey)
+{
+    value_assert(o);
+    ASSERT(o->type == NCDVALUE_MAP)
+    
+    struct NCDValue__map_element *e0 = UPPER_OBJECT(ekey, struct NCDValue__map_element, key);
+    value_assert(&e0->key);
+    value_assert(&e0->val);
+    
+    struct NCDValue__map_element *e = NCDValue__MapTree_GetNext(&o->map_tree, 0, e0);
+    if (!e) {
+        return NULL;
+    }
+    
+    value_assert(&e->key);
+    value_assert(&e->val);
+    
+    return &e->key;
+}
+
+NCDValue * NCDValue_MapKeyValue (NCDValue *o, NCDValue *ekey)
+{
+    value_assert(o);
+    ASSERT(o->type == NCDVALUE_MAP)
+    
+    struct NCDValue__map_element *e = UPPER_OBJECT(ekey, struct NCDValue__map_element, key);
+    value_assert(&e->key);
+    value_assert(&e->val);
+    
+    return &e->val;
+}
+
+NCDValue * NCDValue_MapFindKey (NCDValue *o, NCDValue *key)
+{
+    value_assert(o);
+    ASSERT(o->type == NCDVALUE_MAP)
+    value_assert(key);
+    
+    struct NCDValue__map_element *e = NCDValue__MapTree_LookupExact(&o->map_tree, 0, key);
+    if (!e) {
+        return NULL;
+    }
+    
+    value_assert(&e->key);
+    value_assert(&e->val);
+    ASSERT(!NCDValue_Compare(&e->key, key))
+    
+    return &e->key;
+}
+
+NCDValue * NCDValue_MapInsert (NCDValue *o, NCDValue key, NCDValue val)
+{
+    value_assert(o);
+    ASSERT(o->type == NCDVALUE_MAP)
+    value_assert(&key);
+    value_assert(&val);
+    ASSERT(!NCDValue_MapFindKey(o, &key))
+    
+    if (o->map_count == SIZE_MAX) {
+        return NULL;
+    }
+    
+    struct NCDValue__map_element *e = malloc(sizeof(*e));
+    if (!e) {
+        return NULL;
+    }
+    
+    e->key = key;
+    e->val = val;
+    int res = NCDValue__MapTree_Insert(&o->map_tree, 0, e, NULL);
+    ASSERT_EXECUTE(res)
+    
+    o->map_count++;
+    
+    return &e->key;
+}
+
+void NCDValue_MapRemove (NCDValue *o, NCDValue *ekey, NCDValue *out_key, NCDValue *out_val)
+{
+    value_assert(o);
+    ASSERT(o->type == NCDVALUE_MAP)
+    ASSERT(out_key)
+    ASSERT(out_val)
+    ASSERT(o->map_count > 0)
+    
+    struct NCDValue__map_element *e = UPPER_OBJECT(ekey, struct NCDValue__map_element, key);
+    value_assert(&e->key);
+    value_assert(&e->val);
+    
+    NCDValue__MapTree_Remove(&o->map_tree, 0, e);
+    
+    *out_key = e->key;
+    *out_val = e->val;
+    
+    o->map_count--;
+    
+    free(e);
+}
+
+NCDValue * NCDValue_MapFindValueByString (NCDValue *o, const char *key_str)
+{
+    value_assert(o);
+    ASSERT(o->type == NCDVALUE_MAP)
+    ASSERT(key_str)
+    
+    NCDValue key;
+    key.type = NCDVALUE_STRING;
+    key.string = (uint8_t *)key_str;
+    key.string_len = strlen(key_str);
+    
+    NCDValue *ekey = NCDValue_MapFindKey(o, &key);
+    if (!ekey) {
+        return NULL;
+    }
+    
+    return NCDValue_MapKeyValue(o, ekey);
+}
+
+int NCDValue_IsVar (NCDValue *o)
+{
+    value_assert(o);
+    
+    return o->type == NCDVALUE_VAR;
+}
+
+int NCDValue_InitVar (NCDValue *o, const char *var_name)
+{
+    ASSERT(var_name)
+    
+    if (!(o->var_name = strdup(var_name))) {
+        return 0;
+    }
+    
+    o->type = NCDVALUE_VAR;
+    
+    return 1;
+}
+
+const char * NCDValue_VarName (NCDValue *o)
+{
+    value_assert(o);
+    ASSERT(o->type == NCDVALUE_VAR)
+    
+    return o->var_name;
+}
+
+int NCDValue_Compare (NCDValue *o, NCDValue *v)
+{
+    value_assert(o);
+    value_assert(v);
+    
+    int cmp = (o->type > v->type) - (o->type < v->type);
+    if (cmp) {
+        return cmp;
+    }
+    
+    ASSERT(o->type == v->type)
+    
+    if (o->type == NCDVALUE_STRING) {
+        size_t min_len = o->string_len < v->string_len ? o->string_len : v->string_len;
+        
+        int cmp = memcmp(o->string, v->string, min_len);
+        if (cmp) {
+            return (cmp > 0) - (cmp < 0);
+        }
+        
+        return (o->string_len > v->string_len) - (o->string_len < v->string_len);
+    }
+    
+    if (o->type == NCDVALUE_LIST) {
+        NCDValue *x = NCDValue_ListFirst(o);
+        NCDValue *y = NCDValue_ListFirst(v);
+        
+        while (1) {
+            if (!x && y) {
+                return -1;
+            }
+            if (x && !y) {
+                return 1;
+            }
+            if (!x && !y) {
+                return 0;
+            }
+            
+            int res = NCDValue_Compare(x, y);
+            if (res) {
+                return res;
+            }
+            
+            x = NCDValue_ListNext(o, x);
+            y = NCDValue_ListNext(v, y);
+        }
+    }
+    
+    if (o->type == NCDVALUE_MAP) {
+        NCDValue *key1 = NCDValue_MapFirstKey(o);
+        NCDValue *key2 = NCDValue_MapFirstKey(v);
+        
+        while (1) {
+            if (!key1 && key2) {
+                return -1;
+            }
+            if (key1 && !key2) {
+                return 1;
+            }
+            if (!key1 && !key2) {
+                return 0;
+            }
+            
+            int res = NCDValue_Compare(key1, key2);
+            if (res) {
+                return res;
+            }
+            
+            NCDValue *val1 = NCDValue_MapKeyValue(o, key1);
+            NCDValue *val2 = NCDValue_MapKeyValue(v, key2);
+            
+            res = NCDValue_Compare(val1, val2);
+            if (res) {
+                return res;
+            }
+            
+            key1 = NCDValue_MapNextKey(o, key1);
+            key2 = NCDValue_MapNextKey(v, key2);
+        }
+    }
+    
+    if (o->type == NCDVALUE_VAR) {
+        int res = strcmp(o->var_name, v->var_name);
+        
+        return (res > 0) - (res < 0);
+    }
+    
+    ASSERT(0)
+    return 0;
+}
+
 void NCDProgram_Init (NCDProgram *o)
 {
     LinkedList1_Init(&o->processes_list);

+ 419 - 1
ncd/NCDAst.h

@@ -30,10 +30,14 @@
 #ifndef BADVPN_NCDAST_H
 #define BADVPN_NCDAST_H
 
+#include <stdint.h>
+#include <stddef.h>
+
 #include <misc/debug.h>
 #include <structure/LinkedList1.h>
-#include <ncd/NCDValue.h>
+#include <structure/SAvl.h>
 
+typedef struct NCDValue_s NCDValue;
 typedef struct NCDProgram_s NCDProgram;
 typedef struct NCDProcess_s NCDProcess;
 typedef struct NCDBlock_s NCDBlock;
@@ -41,6 +45,33 @@ typedef struct NCDStatement_s NCDStatement;
 typedef struct NCDIfBlock_s NCDIfBlock;
 typedef struct NCDIf_s NCDIf;
 
+struct NCDValue__map_element;
+typedef NCDValue *NCDValue__maptree_key;
+
+#include "NCDAst_maptree.h"
+#include <structure/SAvl_decl.h>
+
+struct NCDValue_s {
+    int type;
+    union {
+        struct {
+            uint8_t *string;
+            size_t string_len;
+        };
+        struct {
+            LinkedList1 list;
+            size_t list_count;
+        };
+        struct {
+            NCDValue__MapTree map_tree;
+            size_t map_count;
+        };
+        struct {
+            char *var_name;
+        };
+    };
+};
+
 struct NCDProgram_s {
     LinkedList1 processes_list;
     size_t num_processes;
@@ -107,10 +138,397 @@ struct IfBlockIf {
 
 //
 
+#define NCDVALUE_STRING 1
+#define NCDVALUE_LIST 2
+#define NCDVALUE_MAP 3
+#define NCDVALUE_VAR 4
+
 #define NCDSTATEMENT_REG 1
 #define NCDSTATEMENT_IF 2
 #define NCDSTATEMENT_FOREACH 3
 
+/**
+ * Initializes a value by copying an existing value.
+ * 
+ * @param o value structure to initialize
+ * @param v an existing value to copy
+ * @return 1 on success, 0 on failure
+ */
+int NCDValue_InitCopy (NCDValue *o, NCDValue *v) WARN_UNUSED;
+
+/**
+ * Frees a value.
+ * 
+ * @param o value to free
+ */
+void NCDValue_Free (NCDValue *o);
+
+/**
+ * Returns the type of a value.
+ * 
+ * @param o the value
+ * @return type of value; one of NCDVALUE_STRING, NCDVALUE_LIST and NCDVALUE_MAP.
+ */
+int NCDValue_Type (NCDValue *o);
+
+/**
+ * Checks if the value is a string value.
+ * 
+ * @param o the value
+ * @return 1 if string, 0 if not
+ */
+int NCDValue_IsString (NCDValue *o);
+
+/**
+ * Checks if the value is a string value and does not contain
+ * any null bytes.
+ * 
+ * @param o the value
+ * @return 1 if string with no nulls, 0 if not
+ */
+int NCDValue_IsStringNoNulls (NCDValue *o);
+
+/**
+ * Initializes a string value from a null-terminated string.
+ * This function can only be used to create string values which do
+ * not contain any null bytes. To create a string which may contain
+ * null bytes, use {@link NCDValue_InitStringBin}.
+ * 
+ * @param o value structure to initialize
+ * @param str null-terminated string
+ * @return 1 on success, 0 on failure
+ */
+int NCDValue_InitString (NCDValue *o, const char *str) WARN_UNUSED;
+
+/**
+ * Initializes a string value from a byte array.
+ * 
+ * @param o value structure to initialize
+ * @param str byte array
+ * @param len number of bytes in byte array
+ * @return 1 on success, 0 on failure
+ */
+int NCDValue_InitStringBin (NCDValue *o, const uint8_t *str, size_t len) WARN_UNUSED;
+
+/**
+ * Returns the pointer to the bytes of a string value. The string is always
+ * null-terminated (but it itself contain null bytes).
+ * 
+ * @param o string value
+ * @return pointer to null-terminated array of bytes
+ */
+char * NCDValue_StringValue (NCDValue *o);
+
+/**
+ * Returns the length of the string (excuding the internal null termination,
+ * but including any null bytes in the data).
+ * 
+ * @param o string value
+ * @return length of string
+ */
+size_t NCDValue_StringLength (NCDValue *o);
+
+/**
+ * Checks whether a string contains no null bytes in its data, i.e. strlen(str)==length.
+ * 
+ * @param o string value
+ * @return 1 if no null, 0 if nulls
+ */
+int NCDValue_StringHasNoNulls (NCDValue *o);
+
+/**
+ * Checks whether a string contains any null bytes in its data, i.e. strlen(str) < length.
+ * 
+ * @param o string value
+ * @return 1 if nulls, 0 if no nulls
+ */
+int NCDValue_StringHasNulls (NCDValue *o);
+
+/**
+ * Checks whether the string value is equal to the given null-terminated string.
+ * Note that this is not equivalent to strcmp()==0, because the string value may
+ * 
+ * @param o string value
+ * @param str null-terminated string to compare against
+ * @return 1 if equal, 0 if not
+ */
+int NCDValue_StringEquals (NCDValue *o, const char *str);
+
+/**
+ * Checks if the value is a list value.
+ * 
+ * @param o the value
+ * @return 1 if list, 0 if not
+ */
+int NCDValue_IsList (NCDValue *o);
+
+/**
+ * Initializes an empty list value.
+ * 
+ * @param o value structure to initialize
+ */
+void NCDValue_InitList (NCDValue *o);
+
+/**
+ * Appends a value to the end of a list.
+ * On success, the value that was passed for insertion must be assumed freed;
+ * on failure, it is unaffected.
+ * 
+ * @param o list value
+ * @param v value to append
+ * @return 1 on success, 0 on failure
+ */
+int NCDValue_ListAppend (NCDValue *o, NCDValue v) WARN_UNUSED;
+
+/**
+ * Prepends a value to the beginning of a list.
+ * On success, the value that was passed for insertion must be assumed freed;
+ * on failure, it is unaffected.
+ * 
+ * @param o list value
+ * @param v value to prepend
+ * @return 1 on success, 0 on failure
+ */
+int NCDValue_ListPrepend (NCDValue *o, NCDValue v) WARN_UNUSED;
+
+/**
+ * Appends values from a list to the end of a list.
+ * On success, the list value that was passed with elements for insertion must be
+ * assumed freed; on failure, it is unaffected.
+ * 
+ * @param o list value
+ * @param l list value whose elements to append
+ * @return 1 on success, 0 on failure
+ */
+int NCDValue_ListAppendList (NCDValue *o, NCDValue l) WARN_UNUSED;
+
+/**
+ * Returns the number of elements in a list.
+ * 
+ * @param o list value
+ * @return number of elements
+ */
+size_t NCDValue_ListCount (NCDValue *o);
+
+/**
+ * Returns a pointer to the first elements in a list, or NULL if there are no
+ * elements.
+ * 
+ * @param o list value
+ * @return pointer to first value, or NULL
+ */
+NCDValue * NCDValue_ListFirst (NCDValue *o);
+
+/**
+ * Given a pointer to an existing element in a list, returns a pointer to the
+ * element that follows it, or NULL if it is the last.
+ * Note that the element pointer must point to a value that is really in the list
+ * right now, and not just equal.
+ * 
+ * @param o list value
+ * @param ev pointer to an existing element in the list
+ * @return pointer to next value, or NULL
+ */
+NCDValue * NCDValue_ListNext (NCDValue *o, NCDValue *ev);
+
+/**
+ * Attempts to retrieve pointers to elements from a list.
+ * Pass exactly 'num' extra NCDValue ** arguments. If the list has exactly
+ * 'num' elements, this function succeeds, and returns pointers to them via the
+ * passed variable arguments; if not, it fails.
+ * 
+ * @param o list value
+ * @param num number of values to read. Must be >=0, and exactly that many
+ *            variable arguments of type NCDValue ** must follow, all non-NULL.
+ * @return 1 on succees, 0 on failure
+ */
+int NCDValue_ListRead (NCDValue *o, int num, ...) WARN_UNUSED;
+
+/**
+ * Like {@link NCDValue_ListRead}, but the list only needs to have >= 'num' values,
+ * instead of exactly 'num'.
+ */
+int NCDValue_ListReadHead (NCDValue *o, int num, ...) WARN_UNUSED;
+
+/**
+ * Returns a pointer to the element of the list at the given position.
+ * This performs a linear search from the beginning.
+ * 
+ * @param o list value
+ * @param pos index of element to retrieve; must be < length.
+ */
+NCDValue * NCDValue_ListGet (NCDValue *o, size_t pos);
+
+/**
+ * Removes the first element from a list and returns it.
+ * The caller takes ownership of the removed value and is responsible for freeing
+ * it.
+ * The list must have at least one element.
+ * 
+ * @param o list value
+ * @return value that was the first on the list
+ */
+NCDValue NCDValue_ListShift (NCDValue *o);
+
+/**
+ * Removes an element from a list and returns it.
+ * The caller takes ownership of the removed value and is responsible for freeing
+ * it; the passed element pointer becomes invalid.
+ * Note that the element pointer must point to a value that is really in the list
+ * right now, and not just equal.
+ * 
+ * @param o list value
+ * @param ev pointer to element of list to remove
+ * @return value that was just removed
+ */
+NCDValue NCDValue_ListRemove (NCDValue *o, NCDValue *ev);
+
+/**
+ * Checks if the value is a map value.
+ * 
+ * @param o the value
+ * @return 1 if map, 0 if not
+ */
+int NCDValue_IsMap (NCDValue *o);
+
+/**
+ * Initializes an empty map value.
+ * 
+ * @param o value structure to initialize
+ */
+void NCDValue_InitMap (NCDValue *o);
+
+/**
+ * Returns the number of entries in a map.
+ * 
+ * @param o map value
+ * @return number of entries
+ */
+size_t NCDValue_MapCount (NCDValue *o);
+
+/**
+ * Returns the pointer to the first key in the map, or NULL if
+ * the map is empty.
+ * The keys are ordered according to {@link NCDValue_Compare}.
+ * 
+ * @param o map value
+ * @return pointer to first key, or NULL
+ */
+NCDValue * NCDValue_MapFirstKey (NCDValue *o);
+
+/**
+ * Given a pointer to an existing key in a map, returns a pointer to the
+ * key that follows it, or NULL if this is the last key.
+ * Note that the key pointer must point to a value that is really a key in the map
+ * right now, and not just equal to some key.
+ * 
+ * @param o map value
+ * @param ekey pointer to an existing key in the map
+ * @return pointer to next key, or NULL
+ */
+NCDValue * NCDValue_MapNextKey (NCDValue *o, NCDValue *ekey);
+
+/**
+ * Given a pointer to an existing key in a map, returns a pointer to the
+ * value associated with it.
+ * Note that the key pointer must point to a value that is really a key in the
+ * map right now, and not just equal.
+ * 
+ * @param o map value
+ * @param ekey pointer to an existing key in the map
+ * @return pointer to the associated value
+ */
+NCDValue * NCDValue_MapKeyValue (NCDValue *o, NCDValue *ekey);
+
+/**
+ * Looks for a key in a map that is equal to the given key.
+ * 
+ * @param o map value
+ * @param key key to look for
+ * @return pointer to the key in the map, or NULL if not found
+ */
+NCDValue * NCDValue_MapFindKey (NCDValue *o, NCDValue *key);
+
+/**
+ * Inserts a (key, value) entry into the map.
+ * The map must not already contain a key equal to the provided key.
+ * On success, the key and value that were passed for insertion must be assumed freed;
+ * on failure, they are unaffected.
+ * 
+ * @param o map value
+ * @param key key to insert
+ * @param val value to insert
+ * @return pointer to the newly inserted key in the map, or NULL if insertion failed.
+ */
+NCDValue * NCDValue_MapInsert (NCDValue *o, NCDValue key, NCDValue val) WARN_UNUSED;
+
+/**
+ * Removes an entry from the map and returns the key and value that were just removed.
+ * The entry to remove is specified by a pointer to an existing key in the map.
+ * The caller takes ownership of the removed key and value value and is responsible for
+ * freeing them; the passed key pointer becomes invalid.
+ * Note that the key pointer must point to a value that is really a key in the map
+ * right now, and not just equal to some key.
+ * 
+ * @param o map value
+ * @param ekey pointer to an existing key in the map whose entry to remove
+ * @param out_key the key of the removed entry will be returned here; must not be NULL.
+ * @param out_val the value of the removed entry will be returned here; must not be NULL.
+ */
+void NCDValue_MapRemove (NCDValue *o, NCDValue *ekey, NCDValue *out_key, NCDValue *out_val);
+
+/**
+ * Looks for an entry in the map with a string key equal to the given null-terminated
+ * string.
+ * If such key exists, it returns a pointer to its associated value; if not, it returns
+ * NULL.
+ * NOTE: this returns a pointer to the value, not the key, unlike
+ *       {@link NCDValue_MapFindKey}.
+ * 
+ * @param o map value
+ * @param key_str null-terminated string specifying the key to look for
+ * @return pointer to value, or NULL if there is no such key
+ */
+NCDValue * NCDValue_MapFindValueByString (NCDValue *o, const char *key_str);
+
+/**
+ * Checks if the value is a variable value.
+ * 
+ * @param o the value
+ * @return 1 if variable, 0 if not
+ */
+int NCDValue_IsVar (NCDValue *o);
+
+/**
+ * Initializes a variable value.
+ * WARNING: variable values are only used internally by NCD as part of
+ * the AST, and must never be used as statement or template arguments
+ * during program execution.
+ * 
+ * @param o value structure to initialize
+ * @param var_name name of the variable
+ * @return 1 on success, 0 on failure
+ */
+int NCDValue_InitVar (NCDValue *o, const char *var_name) WARN_UNUSED;
+
+/**
+ * Returns the name of the variable.
+ * 
+ * @param o variable value
+ * @return variable name
+ */
+const char * NCDValue_VarName (NCDValue *o);
+
+/**
+ * Compares a value with another value.
+ * This function defines a total order on the set of all possible values.
+ * 
+ * @param o first value
+ * @param v second value
+ * @return -1 if 'o' is lesser than 'v', 0 if equal, 1 if greater
+ */
+int NCDValue_Compare (NCDValue *o, NCDValue *v);
+
 void NCDProgram_Init (NCDProgram *o);
 void NCDProgram_Free (NCDProgram *o);
 NCDProcess * NCDProgram_PrependProcess (NCDProgram *o, NCDProcess p) WARN_UNUSED;

+ 1 - 1
ncd/NCDValue_maptree.h → ncd/NCDAst_maptree.h

@@ -1,7 +1,7 @@
 #define SAVL_PARAM_NAME NCDValue__MapTree
 #define SAVL_PARAM_FEATURE_COUNTS 0
 #define SAVL_PARAM_FEATURE_NOKEYS 0
-#define SAVL_PARAM_TYPE_ENTRY struct NCDMapElement_s
+#define SAVL_PARAM_TYPE_ENTRY struct NCDValue__map_element
 #define SAVL_PARAM_TYPE_KEY NCDValue__maptree_key
 #define SAVL_PARAM_TYPE_ARG int
 #define SAVL_PARAM_FUN_COMPARE_ENTRIES(arg, entry1, entry2) NCDValue_Compare(&(entry1)->key, &(entry2)->key)

+ 1 - 1
ncd/NCDValCompat.h

@@ -31,7 +31,7 @@
 #define BADVPN_NCDVALCOMPAT_H
 
 #include <misc/debug.h>
-#include <ncd/NCDValue.h>
+#include <ncd/NCDAst.h>
 #include <ncd/NCDVal.h>
 
 /**

+ 0 - 757
ncd/NCDValue.c

@@ -1,757 +0,0 @@
-/**
- * @file NCDValue.c
- * @author Ambroz Bizjak <ambrop7@gmail.com>
- * 
- * @section LICENSE
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the author nor the
- *    names of its contributors may be used to endorse or promote products
- *    derived from this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <inttypes.h>
-
-#include <misc/debug.h>
-#include <misc/offset.h>
-
-#include <ncd/NCDValue.h>
-
-#include "NCDValue_maptree.h"
-#include <structure/SAvl_impl.h>
-
-static int ncdvalue_comparator (void *unused, void *vv1, void *vv2)
-{
-    NCDValue *v1 = vv1;
-    NCDValue *v2 = vv2;
-    
-    return NCDValue_Compare(v1, v2);
-}
-
-static void value_assert (NCDValue *o)
-{
-    switch (o->type) {
-        case NCDVALUE_STRING:
-        case NCDVALUE_LIST:
-        case NCDVALUE_MAP:
-        case NCDVALUE_VAR:
-            return;
-        default:
-            ASSERT(0);
-    }
-}
-
-int NCDValue_InitCopy (NCDValue *o, NCDValue *v)
-{
-    value_assert(v);
-    
-    switch (v->type) {
-        case NCDVALUE_STRING: {
-            return NCDValue_InitStringBin(o, v->string, v->string_len);
-        } break;
-        
-        case NCDVALUE_LIST: {
-            NCDValue_InitList(o);
-            
-            for (LinkedList1Node *n = LinkedList1_GetFirst(&v->list); n; n = LinkedList1Node_Next(n)) {
-                NCDListElement *e = UPPER_OBJECT(n, NCDListElement, list_node);
-                
-                NCDValue tmp;
-                if (!NCDValue_InitCopy(&tmp, &e->v)) {
-                    goto fail;
-                }
-                
-                if (!NCDValue_ListAppend(o, tmp)) {
-                    NCDValue_Free(&tmp);
-                    goto fail;
-                }
-            }
-            
-            return 1;
-            
-        fail:
-            NCDValue_Free(o);
-            return 0;
-        } break;
-        
-        case NCDVALUE_MAP: {
-            NCDValue_InitMap(o);
-            
-            for (NCDValue *ekey = NCDValue_MapFirstKey(v); ekey; ekey = NCDValue_MapNextKey(v, ekey)) {
-                NCDValue *eval = NCDValue_MapKeyValue(v, ekey);
-                
-                NCDValue tmp_key;
-                NCDValue tmp_val;
-                if (!NCDValue_InitCopy(&tmp_key, ekey)) {
-                    goto mapfail;
-                }
-                if (!NCDValue_InitCopy(&tmp_val, eval)) {
-                    NCDValue_Free(&tmp_key);
-                    goto mapfail;
-                }
-                
-                if (!NCDValue_MapInsert(o, tmp_key, tmp_val)) {
-                    NCDValue_Free(&tmp_key);
-                    NCDValue_Free(&tmp_val);
-                    goto mapfail;
-                }
-            }
-            
-            return 1;
-            
-        mapfail:
-            NCDValue_Free(o);
-            return 0;
-        } break;
-        
-        case NCDVALUE_VAR: {
-            return NCDValue_InitVar(o, v->var_name);
-        } break;
-        
-        default:
-            ASSERT(0);
-    }
-    
-    return 0;
-}
-
-void NCDValue_Free (NCDValue *o)
-{
-    switch (o->type) {
-        case NCDVALUE_STRING: {
-            free(o->string);
-        } break;
-        
-        case NCDVALUE_LIST: {
-            LinkedList1Node *n;
-            while (n = LinkedList1_GetFirst(&o->list)) {
-                NCDListElement *e = UPPER_OBJECT(n, NCDListElement, list_node);
-                
-                NCDValue_Free(&e->v);
-                LinkedList1_Remove(&o->list, &e->list_node);
-                free(e);
-            }
-        } break;
-        
-        case NCDVALUE_MAP: {
-            NCDMapElement *e;
-            while (e = NCDValue__MapTree_GetFirst(&o->map_tree, 0)) {
-                NCDValue__MapTree_Remove(&o->map_tree, 0, e);
-                NCDValue_Free(&e->key);
-                NCDValue_Free(&e->val);
-                free(e);
-            }
-        } break;
-        
-        case NCDVALUE_VAR: {
-            free(o->var_name);
-        } break;
-        
-        default:
-            ASSERT(0);
-    }
-}
-
-int NCDValue_Type (NCDValue *o)
-{
-    value_assert(o);
-    
-    return o->type;
-}
-
-int NCDValue_IsString (NCDValue *o)
-{
-    value_assert(o);
-    
-    return o->type == NCDVALUE_STRING;
-}
-
-int NCDValue_IsStringNoNulls (NCDValue *o)
-{
-    return NCDValue_IsString(o) && NCDValue_StringHasNoNulls(o);
-}
-
-int NCDValue_InitString (NCDValue *o, const char *str)
-{
-    return NCDValue_InitStringBin(o, (const uint8_t *)str, strlen(str));
-}
-
-int NCDValue_InitStringBin (NCDValue *o, const uint8_t *str, size_t len)
-{
-    if (len == SIZE_MAX) {
-        return 0;
-    }
-    
-    if (!(o->string = malloc(len + 1))) {
-        return 0;
-    }
-    
-    memcpy(o->string, str, len);
-    o->string[len] = '\0';
-    o->string_len = len;
-    
-    o->type = NCDVALUE_STRING;
-    
-    return 1;
-}
-
-char * NCDValue_StringValue (NCDValue *o)
-{
-    ASSERT(o->type == NCDVALUE_STRING)
-    
-    return (char *)o->string;
-}
-
-size_t NCDValue_StringLength (NCDValue *o)
-{
-    ASSERT(o->type == NCDVALUE_STRING)
-    
-    return o->string_len;
-}
-
-int NCDValue_StringHasNoNulls (NCDValue *o)
-{
-    ASSERT(o->type == NCDVALUE_STRING)
-    
-    return strlen((char *)o->string) == o->string_len;
-}
-
-int NCDValue_StringHasNulls (NCDValue *o)
-{
-    ASSERT(o->type == NCDVALUE_STRING)
-    
-    return !NCDValue_StringHasNoNulls(o);
-}
-
-int NCDValue_StringEquals (NCDValue *o, const char *str)
-{
-    ASSERT(o->type == NCDVALUE_STRING)
-    
-    return NCDValue_StringHasNoNulls(o) && !strcmp((const char *)o->string, str);
-}
-
-int NCDValue_IsList (NCDValue *o)
-{
-    value_assert(o);
-    
-    return o->type == NCDVALUE_LIST;
-}
-
-void NCDValue_InitList (NCDValue *o)
-{
-    LinkedList1_Init(&o->list);
-    o->list_count = 0;
-    
-    o->type = NCDVALUE_LIST;
-}
-
-int NCDValue_ListAppend (NCDValue *o, NCDValue v)
-{
-    value_assert(o);
-    value_assert(&v);
-    ASSERT(o->type == NCDVALUE_LIST)
-    
-    if (o->list_count == SIZE_MAX) {
-        return 0;
-    }
-    
-    NCDListElement *e = malloc(sizeof(*e));
-    if (!e) {
-        return 0;
-    }
-    
-    LinkedList1_Append(&o->list, &e->list_node);
-    o->list_count++;
-    e->v = v;
-    
-    return 1;
-}
-
-int NCDValue_ListPrepend (NCDValue *o, NCDValue v)
-{
-    value_assert(o);
-    value_assert(&v);
-    ASSERT(o->type == NCDVALUE_LIST)
-    
-    if (o->list_count == SIZE_MAX) {
-        return 0;
-    }
-    
-    NCDListElement *e = malloc(sizeof(*e));
-    if (!e) {
-        return 0;
-    }
-    
-    LinkedList1_Prepend(&o->list, &e->list_node);
-    o->list_count++;
-    e->v = v;
-    
-    return 1;
-}
-
-int NCDValue_ListAppendList (NCDValue *o, NCDValue l)
-{
-    value_assert(o);
-    value_assert(&l);
-    ASSERT(o->type == NCDVALUE_LIST)
-    ASSERT(l.type == NCDVALUE_LIST)
-    
-    if (l.list_count > SIZE_MAX - o->list_count) {
-        return 0;
-    }
-    
-    LinkedList1Node *n;
-    while (n = LinkedList1_GetFirst(&l.list)) {
-        NCDListElement *e = UPPER_OBJECT(n, NCDListElement, list_node);
-        LinkedList1_Remove(&l.list, &e->list_node);
-        LinkedList1_Append(&o->list, &e->list_node);
-    }
-    
-    o->list_count += l.list_count;
-    
-    return 1;
-}
-
-size_t NCDValue_ListCount (NCDValue *o)
-{
-    value_assert(o);
-    ASSERT(o->type == NCDVALUE_LIST)
-    
-    return o->list_count;
-}
-
-NCDValue * NCDValue_ListFirst (NCDValue *o)
-{
-    value_assert(o);
-    ASSERT(o->type == NCDVALUE_LIST)
-    
-    LinkedList1Node *ln = LinkedList1_GetFirst(&o->list);
-    
-    if (!ln) {
-        return NULL;
-    }
-    
-    NCDListElement *e = UPPER_OBJECT(ln, NCDListElement, list_node);
-    
-    return &e->v;
-}
-
-NCDValue * NCDValue_ListNext (NCDValue *o, NCDValue *ev)
-{
-    value_assert(o);
-    ASSERT(o->type == NCDVALUE_LIST)
-    
-    NCDListElement *cur_e = UPPER_OBJECT(ev, NCDListElement, v);
-    LinkedList1Node *ln = LinkedList1Node_Next(&cur_e->list_node);
-    
-    if (!ln) {
-        return NULL;
-    }
-    
-    NCDListElement *e = UPPER_OBJECT(ln, NCDListElement, list_node);
-    
-    return &e->v;
-}
-
-int NCDValue_ListRead (NCDValue *o, int num, ...)
-{
-    value_assert(o);
-    ASSERT(o->type == NCDVALUE_LIST)
-    ASSERT(num >= 0)
-    
-    if (num != NCDValue_ListCount(o)) {
-        return 0;
-    }
-    
-    va_list ap;
-    va_start(ap, num);
-    
-    for (LinkedList1Node *n = LinkedList1_GetFirst(&o->list); n; n = LinkedList1Node_Next(n)) {
-        NCDListElement *e = UPPER_OBJECT(n, NCDListElement, list_node);
-        
-        NCDValue **dest = va_arg(ap, NCDValue **);
-        *dest = &e->v;
-    }
-    
-    va_end(ap);
-    
-    return 1;
-}
-
-int NCDValue_ListReadHead (NCDValue *o, int num, ...)
-{
-    value_assert(o);
-    ASSERT(o->type == NCDVALUE_LIST)
-    ASSERT(num >= 0)
-    
-    if (num > NCDValue_ListCount(o)) {
-        return 0;
-    }
-    
-    va_list ap;
-    va_start(ap, num);
-    
-    LinkedList1Node *n = LinkedList1_GetFirst(&o->list);
-    while (num > 0) {
-        ASSERT(n)
-        NCDListElement *e = UPPER_OBJECT(n, NCDListElement, list_node);
-        
-        NCDValue **dest = va_arg(ap, NCDValue **);
-        *dest = &e->v;
-        
-        n = LinkedList1Node_Next(n);
-        num--;
-    }
-    
-    va_end(ap);
-    
-    return 1;
-}
-
-NCDValue * NCDValue_ListGet (NCDValue *o, size_t pos)
-{
-    value_assert(o);
-    ASSERT(o->type == NCDVALUE_LIST)
-    ASSERT(pos < o->list_count)
-    
-    NCDValue *e = NCDValue_ListFirst(o);
-    while (e) {
-        if (pos == 0) {
-            break;
-        }
-        pos--;
-        e = NCDValue_ListNext(o, e);
-    }
-    ASSERT(e)
-    
-    return e;
-}
-
-NCDValue NCDValue_ListShift (NCDValue *o)
-{
-    value_assert(o);
-    ASSERT(o->type == NCDVALUE_LIST)
-    ASSERT(o->list_count > 0)
-    
-    NCDListElement *e = UPPER_OBJECT(LinkedList1_GetFirst(&o->list), NCDListElement, list_node);
-    
-    NCDValue v = e->v;
-    
-    LinkedList1_Remove(&o->list, &e->list_node);
-    o->list_count--;
-    free(e);
-    
-    return v;
-}
-
-NCDValue NCDValue_ListRemove (NCDValue *o, NCDValue *ev)
-{
-    value_assert(o);
-    ASSERT(o->type == NCDVALUE_LIST)
-    ASSERT(o->list_count > 0)
-    
-    NCDListElement *e = UPPER_OBJECT(ev, NCDListElement, v);
-    
-    NCDValue v = e->v;
-    
-    LinkedList1_Remove(&o->list, &e->list_node);
-    o->list_count--;
-    free(e);
-    
-    return v;
-}
-
-int NCDValue_IsMap (NCDValue *o)
-{
-    value_assert(o);
-    
-    return o->type == NCDVALUE_MAP;
-}
-
-void NCDValue_InitMap (NCDValue *o)
-{
-    o->type = NCDVALUE_MAP;
-    NCDValue__MapTree_Init(&o->map_tree);
-    o->map_count = 0;
-}
-
-size_t NCDValue_MapCount (NCDValue *o)
-{
-    value_assert(o);
-    ASSERT(o->type == NCDVALUE_MAP)
-    
-    return o->map_count;
-}
-
-NCDValue * NCDValue_MapFirstKey (NCDValue *o)
-{
-    value_assert(o);
-    ASSERT(o->type == NCDVALUE_MAP)
-    
-    NCDMapElement *e = NCDValue__MapTree_GetFirst(&o->map_tree, 0);
-    if (!e) {
-        return NULL;
-    }
-    
-    value_assert(&e->key);
-    value_assert(&e->val);
-    
-    return &e->key;
-}
-
-NCDValue * NCDValue_MapNextKey (NCDValue *o, NCDValue *ekey)
-{
-    value_assert(o);
-    ASSERT(o->type == NCDVALUE_MAP)
-    
-    NCDMapElement *e0 = UPPER_OBJECT(ekey, NCDMapElement, key);
-    value_assert(&e0->key);
-    value_assert(&e0->val);
-    
-    NCDMapElement *e = NCDValue__MapTree_GetNext(&o->map_tree, 0, e0);
-    if (!e) {
-        return NULL;
-    }
-    
-    value_assert(&e->key);
-    value_assert(&e->val);
-    
-    return &e->key;
-}
-
-NCDValue * NCDValue_MapKeyValue (NCDValue *o, NCDValue *ekey)
-{
-    value_assert(o);
-    ASSERT(o->type == NCDVALUE_MAP)
-    
-    NCDMapElement *e = UPPER_OBJECT(ekey, NCDMapElement, key);
-    value_assert(&e->key);
-    value_assert(&e->val);
-    
-    return &e->val;
-}
-
-NCDValue * NCDValue_MapFindKey (NCDValue *o, NCDValue *key)
-{
-    value_assert(o);
-    ASSERT(o->type == NCDVALUE_MAP)
-    value_assert(key);
-    
-    NCDMapElement *e = NCDValue__MapTree_LookupExact(&o->map_tree, 0, key);
-    if (!e) {
-        return NULL;
-    }
-    
-    value_assert(&e->key);
-    value_assert(&e->val);
-    ASSERT(!NCDValue_Compare(&e->key, key))
-    
-    return &e->key;
-}
-
-NCDValue * NCDValue_MapInsert (NCDValue *o, NCDValue key, NCDValue val)
-{
-    value_assert(o);
-    ASSERT(o->type == NCDVALUE_MAP)
-    value_assert(&key);
-    value_assert(&val);
-    ASSERT(!NCDValue_MapFindKey(o, &key))
-    
-    if (o->map_count == SIZE_MAX) {
-        return NULL;
-    }
-    
-    NCDMapElement *e = malloc(sizeof(*e));
-    if (!e) {
-        return NULL;
-    }
-    
-    e->key = key;
-    e->val = val;
-    int res = NCDValue__MapTree_Insert(&o->map_tree, 0, e, NULL);
-    ASSERT_EXECUTE(res)
-    
-    o->map_count++;
-    
-    return &e->key;
-}
-
-void NCDValue_MapRemove (NCDValue *o, NCDValue *ekey, NCDValue *out_key, NCDValue *out_val)
-{
-    value_assert(o);
-    ASSERT(o->type == NCDVALUE_MAP)
-    ASSERT(out_key)
-    ASSERT(out_val)
-    ASSERT(o->map_count > 0)
-    
-    NCDMapElement *e = UPPER_OBJECT(ekey, NCDMapElement, key);
-    value_assert(&e->key);
-    value_assert(&e->val);
-    
-    NCDValue__MapTree_Remove(&o->map_tree, 0, e);
-    
-    *out_key = e->key;
-    *out_val = e->val;
-    
-    o->map_count--;
-    
-    free(e);
-}
-
-NCDValue * NCDValue_MapFindValueByString (NCDValue *o, const char *key_str)
-{
-    value_assert(o);
-    ASSERT(o->type == NCDVALUE_MAP)
-    ASSERT(key_str)
-    
-    NCDValue key;
-    key.type = NCDVALUE_STRING;
-    key.string = (uint8_t *)key_str;
-    key.string_len = strlen(key_str);
-    
-    NCDValue *ekey = NCDValue_MapFindKey(o, &key);
-    if (!ekey) {
-        return NULL;
-    }
-    
-    return NCDValue_MapKeyValue(o, ekey);
-}
-
-int NCDValue_IsVar (NCDValue *o)
-{
-    value_assert(o);
-    
-    return o->type == NCDVALUE_VAR;
-}
-
-int NCDValue_InitVar (NCDValue *o, const char *var_name)
-{
-    ASSERT(var_name)
-    
-    if (!(o->var_name = strdup(var_name))) {
-        return 0;
-    }
-    
-    o->type = NCDVALUE_VAR;
-    
-    return 1;
-}
-
-const char * NCDValue_VarName (NCDValue *o)
-{
-    value_assert(o);
-    ASSERT(o->type == NCDVALUE_VAR)
-    
-    return o->var_name;
-}
-
-int NCDValue_Compare (NCDValue *o, NCDValue *v)
-{
-    value_assert(o);
-    value_assert(v);
-    
-    int cmp = (o->type > v->type) - (o->type < v->type);
-    if (cmp) {
-        return cmp;
-    }
-    
-    ASSERT(o->type == v->type)
-    
-    if (o->type == NCDVALUE_STRING) {
-        size_t min_len = o->string_len < v->string_len ? o->string_len : v->string_len;
-        
-        int cmp = memcmp(o->string, v->string, min_len);
-        if (cmp) {
-            return (cmp > 0) - (cmp < 0);
-        }
-        
-        return (o->string_len > v->string_len) - (o->string_len < v->string_len);
-    }
-    
-    if (o->type == NCDVALUE_LIST) {
-        NCDValue *x = NCDValue_ListFirst(o);
-        NCDValue *y = NCDValue_ListFirst(v);
-        
-        while (1) {
-            if (!x && y) {
-                return -1;
-            }
-            if (x && !y) {
-                return 1;
-            }
-            if (!x && !y) {
-                return 0;
-            }
-            
-            int res = NCDValue_Compare(x, y);
-            if (res) {
-                return res;
-            }
-            
-            x = NCDValue_ListNext(o, x);
-            y = NCDValue_ListNext(v, y);
-        }
-    }
-    
-    if (o->type == NCDVALUE_MAP) {
-        NCDValue *key1 = NCDValue_MapFirstKey(o);
-        NCDValue *key2 = NCDValue_MapFirstKey(v);
-        
-        while (1) {
-            if (!key1 && key2) {
-                return -1;
-            }
-            if (key1 && !key2) {
-                return 1;
-            }
-            if (!key1 && !key2) {
-                return 0;
-            }
-            
-            int res = NCDValue_Compare(key1, key2);
-            if (res) {
-                return res;
-            }
-            
-            NCDValue *val1 = NCDValue_MapKeyValue(o, key1);
-            NCDValue *val2 = NCDValue_MapKeyValue(v, key2);
-            
-            res = NCDValue_Compare(val1, val2);
-            if (res) {
-                return res;
-            }
-            
-            key1 = NCDValue_MapNextKey(o, key1);
-            key2 = NCDValue_MapNextKey(v, key2);
-        }
-    }
-    
-    if (o->type == NCDVALUE_VAR) {
-        int res = strcmp(o->var_name, v->var_name);
-        
-        return (res > 0) - (res < 0);
-    }
-    
-    ASSERT(0)
-    return 0;
-}

+ 0 - 483
ncd/NCDValue.h

@@ -1,483 +0,0 @@
-/**
- * @file NCDValue.h
- * @author Ambroz Bizjak <ambrop7@gmail.com>
- * 
- * @section LICENSE
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the author nor the
- *    names of its contributors may be used to endorse or promote products
- *    derived from this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef BADVPN_NCD_NCDVALUE_H
-#define BADVPN_NCD_NCDVALUE_H
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <misc/debug.h>
-#include <structure/LinkedList1.h>
-#include <structure/SAvl.h>
-
-#define NCDVALUE_STRING 1
-#define NCDVALUE_LIST 2
-#define NCDVALUE_MAP 3
-#define NCDVALUE_VAR 4
-
-struct NCDValue_s;
-struct NCDMapElement_s;
-
-typedef struct NCDValue_s *NCDValue__maptree_key;
-
-#include "NCDValue_maptree.h"
-#include <structure/SAvl_decl.h>
-
-/**
- * Holds an NCD "value", which is used in the NCD programming when passing arguments to
- * statements, among other uses.
- * 
- * Each value is of one of the following three types:
- * - String (NCDVALUE_STRING); holds an array of arbitrary bytes, of any size.
- * - List (NCDVALUE_LIST); holds an ordered set of any number of values (by recursive
- *   definition).
- * - Map (NCDVALUE_MAP); holds a set of (key, value) pairs, where both 'key' and 'value'
- *   are values (by recursive definition), and 'key' is unique.
- * 
- * A valid NCDValue structure may be copied freely, which results in multiple valid NCDValue
- * structures holding the same value. When one of those is freed (or passed to a function
- * which proceeds to take ownership of the value), all the structures become invalid.
- * Similarly, if the value is modified via one structure, the others become invalid.
- */
-typedef struct NCDValue_s {
-    int type;
-    union {
-        struct {
-            uint8_t *string;
-            size_t string_len;
-        };
-        struct {
-            LinkedList1 list;
-            size_t list_count;
-        };
-        struct {
-            NCDValue__MapTree map_tree;
-            size_t map_count;
-        };
-        struct {
-            char *var_name;
-        };
-    };
-} NCDValue;
-
-typedef struct {
-    LinkedList1Node list_node;
-    NCDValue v;
-} NCDListElement;
-
-typedef struct NCDMapElement_s {
-    NCDValue__MapTreeNode tree_node;
-    NCDValue key;
-    NCDValue val;
-} NCDMapElement;
-
-/**
- * Initializes a value by copying an existing value.
- * 
- * @param o value structure to initialize
- * @param v an existing value to copy
- * @return 1 on success, 0 on failure
- */
-int NCDValue_InitCopy (NCDValue *o, NCDValue *v) WARN_UNUSED;
-
-/**
- * Frees a value.
- * 
- * @param o value to free
- */
-void NCDValue_Free (NCDValue *o);
-
-/**
- * Returns the type of a value.
- * 
- * @param o the value
- * @return type of value; one of NCDVALUE_STRING, NCDVALUE_LIST and NCDVALUE_MAP.
- */
-int NCDValue_Type (NCDValue *o);
-
-/**
- * Checks if the value is a string value.
- * 
- * @param o the value
- * @return 1 if string, 0 if not
- */
-int NCDValue_IsString (NCDValue *o);
-
-/**
- * Checks if the value is a string value and does not contain
- * any null bytes.
- * 
- * @param o the value
- * @return 1 if string with no nulls, 0 if not
- */
-int NCDValue_IsStringNoNulls (NCDValue *o);
-
-/**
- * Initializes a string value from a null-terminated string.
- * This function can only be used to create string values which do
- * not contain any null bytes. To create a string which may contain
- * null bytes, use {@link NCDValue_InitStringBin}.
- * 
- * @param o value structure to initialize
- * @param str null-terminated string
- * @return 1 on success, 0 on failure
- */
-int NCDValue_InitString (NCDValue *o, const char *str) WARN_UNUSED;
-
-/**
- * Initializes a string value from a byte array.
- * 
- * @param o value structure to initialize
- * @param str byte array
- * @param len number of bytes in byte array
- * @return 1 on success, 0 on failure
- */
-int NCDValue_InitStringBin (NCDValue *o, const uint8_t *str, size_t len) WARN_UNUSED;
-
-/**
- * Returns the pointer to the bytes of a string value. The string is always
- * null-terminated (but it itself contain null bytes).
- * 
- * @param o string value
- * @return pointer to null-terminated array of bytes
- */
-char * NCDValue_StringValue (NCDValue *o);
-
-/**
- * Returns the length of the string (excuding the internal null termination,
- * but including any null bytes in the data).
- * 
- * @param o string value
- * @return length of string
- */
-size_t NCDValue_StringLength (NCDValue *o);
-
-/**
- * Checks whether a string contains no null bytes in its data, i.e. strlen(str)==length.
- * 
- * @param o string value
- * @return 1 if no null, 0 if nulls
- */
-int NCDValue_StringHasNoNulls (NCDValue *o);
-
-/**
- * Checks whether a string contains any null bytes in its data, i.e. strlen(str) < length.
- * 
- * @param o string value
- * @return 1 if nulls, 0 if no nulls
- */
-int NCDValue_StringHasNulls (NCDValue *o);
-
-/**
- * Checks whether the string value is equal to the given null-terminated string.
- * Note that this is not equivalent to strcmp()==0, because the string value may
- * 
- * @param o string value
- * @param str null-terminated string to compare against
- * @return 1 if equal, 0 if not
- */
-int NCDValue_StringEquals (NCDValue *o, const char *str);
-
-/**
- * Checks if the value is a list value.
- * 
- * @param o the value
- * @return 1 if list, 0 if not
- */
-int NCDValue_IsList (NCDValue *o);
-
-/**
- * Initializes an empty list value.
- * 
- * @param o value structure to initialize
- */
-void NCDValue_InitList (NCDValue *o);
-
-/**
- * Appends a value to the end of a list.
- * On success, the value that was passed for insertion must be assumed freed;
- * on failure, it is unaffected.
- * 
- * @param o list value
- * @param v value to append
- * @return 1 on success, 0 on failure
- */
-int NCDValue_ListAppend (NCDValue *o, NCDValue v) WARN_UNUSED;
-
-/**
- * Prepends a value to the beginning of a list.
- * On success, the value that was passed for insertion must be assumed freed;
- * on failure, it is unaffected.
- * 
- * @param o list value
- * @param v value to prepend
- * @return 1 on success, 0 on failure
- */
-int NCDValue_ListPrepend (NCDValue *o, NCDValue v) WARN_UNUSED;
-
-/**
- * Appends values from a list to the end of a list.
- * On success, the list value that was passed with elements for insertion must be
- * assumed freed; on failure, it is unaffected.
- * 
- * @param o list value
- * @param l list value whose elements to append
- * @return 1 on success, 0 on failure
- */
-int NCDValue_ListAppendList (NCDValue *o, NCDValue l) WARN_UNUSED;
-
-/**
- * Returns the number of elements in a list.
- * 
- * @param o list value
- * @return number of elements
- */
-size_t NCDValue_ListCount (NCDValue *o);
-
-/**
- * Returns a pointer to the first elements in a list, or NULL if there are no
- * elements.
- * 
- * @param o list value
- * @return pointer to first value, or NULL
- */
-NCDValue * NCDValue_ListFirst (NCDValue *o);
-
-/**
- * Given a pointer to an existing element in a list, returns a pointer to the
- * element that follows it, or NULL if it is the last.
- * Note that the element pointer must point to a value that is really in the list
- * right now, and not just equal.
- * 
- * @param o list value
- * @param ev pointer to an existing element in the list
- * @return pointer to next value, or NULL
- */
-NCDValue * NCDValue_ListNext (NCDValue *o, NCDValue *ev);
-
-/**
- * Attempts to retrieve pointers to elements from a list.
- * Pass exactly 'num' extra NCDValue ** arguments. If the list has exactly
- * 'num' elements, this function succeeds, and returns pointers to them via the
- * passed variable arguments; if not, it fails.
- * 
- * @param o list value
- * @param num number of values to read. Must be >=0, and exactly that many
- *            variable arguments of type NCDValue ** must follow, all non-NULL.
- * @return 1 on succees, 0 on failure
- */
-int NCDValue_ListRead (NCDValue *o, int num, ...) WARN_UNUSED;
-
-/**
- * Like {@link NCDValue_ListRead}, but the list only needs to have >= 'num' values,
- * instead of exactly 'num'.
- */
-int NCDValue_ListReadHead (NCDValue *o, int num, ...) WARN_UNUSED;
-
-/**
- * Returns a pointer to the element of the list at the given position.
- * This performs a linear search from the beginning.
- * 
- * @param o list value
- * @param pos index of element to retrieve; must be < length.
- */
-NCDValue * NCDValue_ListGet (NCDValue *o, size_t pos);
-
-/**
- * Removes the first element from a list and returns it.
- * The caller takes ownership of the removed value and is responsible for freeing
- * it.
- * The list must have at least one element.
- * 
- * @param o list value
- * @return value that was the first on the list
- */
-NCDValue NCDValue_ListShift (NCDValue *o);
-
-/**
- * Removes an element from a list and returns it.
- * The caller takes ownership of the removed value and is responsible for freeing
- * it; the passed element pointer becomes invalid.
- * Note that the element pointer must point to a value that is really in the list
- * right now, and not just equal.
- * 
- * @param o list value
- * @param ev pointer to element of list to remove
- * @return value that was just removed
- */
-NCDValue NCDValue_ListRemove (NCDValue *o, NCDValue *ev);
-
-/**
- * Checks if the value is a map value.
- * 
- * @param o the value
- * @return 1 if map, 0 if not
- */
-int NCDValue_IsMap (NCDValue *o);
-
-/**
- * Initializes an empty map value.
- * 
- * @param o value structure to initialize
- */
-void NCDValue_InitMap (NCDValue *o);
-
-/**
- * Returns the number of entries in a map.
- * 
- * @param o map value
- * @return number of entries
- */
-size_t NCDValue_MapCount (NCDValue *o);
-
-/**
- * Returns the pointer to the first key in the map, or NULL if
- * the map is empty.
- * The keys are ordered according to {@link NCDValue_Compare}.
- * 
- * @param o map value
- * @return pointer to first key, or NULL
- */
-NCDValue * NCDValue_MapFirstKey (NCDValue *o);
-
-/**
- * Given a pointer to an existing key in a map, returns a pointer to the
- * key that follows it, or NULL if this is the last key.
- * Note that the key pointer must point to a value that is really a key in the map
- * right now, and not just equal to some key.
- * 
- * @param o map value
- * @param ekey pointer to an existing key in the map
- * @return pointer to next key, or NULL
- */
-NCDValue * NCDValue_MapNextKey (NCDValue *o, NCDValue *ekey);
-
-/**
- * Given a pointer to an existing key in a map, returns a pointer to the
- * value associated with it.
- * Note that the key pointer must point to a value that is really a key in the
- * map right now, and not just equal.
- * 
- * @param o map value
- * @param ekey pointer to an existing key in the map
- * @return pointer to the associated value
- */
-NCDValue * NCDValue_MapKeyValue (NCDValue *o, NCDValue *ekey);
-
-/**
- * Looks for a key in a map that is equal to the given key.
- * 
- * @param o map value
- * @param key key to look for
- * @return pointer to the key in the map, or NULL if not found
- */
-NCDValue * NCDValue_MapFindKey (NCDValue *o, NCDValue *key);
-
-/**
- * Inserts a (key, value) entry into the map.
- * The map must not already contain a key equal to the provided key.
- * On success, the key and value that were passed for insertion must be assumed freed;
- * on failure, they are unaffected.
- * 
- * @param o map value
- * @param key key to insert
- * @param val value to insert
- * @return pointer to the newly inserted key in the map, or NULL if insertion failed.
- */
-NCDValue * NCDValue_MapInsert (NCDValue *o, NCDValue key, NCDValue val) WARN_UNUSED;
-
-/**
- * Removes an entry from the map and returns the key and value that were just removed.
- * The entry to remove is specified by a pointer to an existing key in the map.
- * The caller takes ownership of the removed key and value value and is responsible for
- * freeing them; the passed key pointer becomes invalid.
- * Note that the key pointer must point to a value that is really a key in the map
- * right now, and not just equal to some key.
- * 
- * @param o map value
- * @param ekey pointer to an existing key in the map whose entry to remove
- * @param out_key the key of the removed entry will be returned here; must not be NULL.
- * @param out_val the value of the removed entry will be returned here; must not be NULL.
- */
-void NCDValue_MapRemove (NCDValue *o, NCDValue *ekey, NCDValue *out_key, NCDValue *out_val);
-
-/**
- * Looks for an entry in the map with a string key equal to the given null-terminated
- * string.
- * If such key exists, it returns a pointer to its associated value; if not, it returns
- * NULL.
- * NOTE: this returns a pointer to the value, not the key, unlike
- *       {@link NCDValue_MapFindKey}.
- * 
- * @param o map value
- * @param key_str null-terminated string specifying the key to look for
- * @return pointer to value, or NULL if there is no such key
- */
-NCDValue * NCDValue_MapFindValueByString (NCDValue *o, const char *key_str);
-
-/**
- * Checks if the value is a variable value.
- * 
- * @param o the value
- * @return 1 if variable, 0 if not
- */
-int NCDValue_IsVar (NCDValue *o);
-
-/**
- * Initializes a variable value.
- * WARNING: variable values are only used internally by NCD as part of
- * the AST, and must never be used as statement or template arguments
- * during program execution.
- * 
- * @param o value structure to initialize
- * @param var_name name of the variable
- * @return 1 on success, 0 on failure
- */
-int NCDValue_InitVar (NCDValue *o, const char *var_name) WARN_UNUSED;
-
-/**
- * Returns the name of the variable.
- * 
- * @param o variable value
- * @return variable name
- */
-const char * NCDValue_VarName (NCDValue *o);
-
-/**
- * Compares a value with another value.
- * This function defines a total order on the set of all possible values.
- * 
- * @param o first value
- * @param v second value
- * @return -1 if 'o' is lesser than 'v', 0 if equal, 1 if greater
- */
-int NCDValue_Compare (NCDValue *o, NCDValue *v);
-
-#endif