浏览代码

ncd: get some more stuff working nicely with string id's

ambrop7 13 年之前
父节点
当前提交
8d37e18d31

+ 7 - 12
ncd/NCDModule.c

@@ -33,10 +33,8 @@
 #include <inttypes.h>
 #include <limits.h>
 
-#include <misc/string_begins_with.h>
-#include <misc/parse_number.h>
-
 #include <ncd/NCDModule.h>
+#include <ncd/static_strings.h>
 
 #define STATE_DEAD 3
 #define STATE_DOWN_CLEAN 4
@@ -489,18 +487,15 @@ int NCDModuleProcess_Interp_GetSpecialObj (NCDModuleProcess *o, NCD_string_id_t
     process_assert_interp(o);
     ASSERT(out_object)
     
-    const char *name_str = NCDStringIndex_Value(o->iparams->string_index, name);
-    
     if (!NCDVal_IsInvalid(o->args)) {
-        if (!strcmp(name_str, "_args")) {
+        if (name == NCD_STRING_ARGS) {
             *out_object = NCDObject_Build(NULL, o, (NCDObject_func_getvar)process_args_object_func_getvar, NULL);
             return 1;
         }
         
-        size_t len;
-        uintmax_t n;
-        if ((len = string_begins_with(name_str, "_arg")) && parse_unsigned_integer(name_str + len, &n) && n < NCDVal_ListCount(o->args) && n < UINTPTR_MAX) {
-            *out_object = NCDObject_Build2(NULL, o, (void *)((uintptr_t)(n + 1)), (NCDObject_func_getvar2)process_arg_object_func_getvar2, NULL);
+        if (name >= NCD_STRING_ARG0 && name <= NCD_STRING_ARG19) {
+            int num = name - NCD_STRING_ARG0;
+            *out_object = NCDObject_Build2(NULL, o, (void *)((uintptr_t)(num + 1)), (NCDObject_func_getvar2)process_arg_object_func_getvar2, NULL);
             return 1;
         }
     }
@@ -521,7 +516,7 @@ static int process_args_object_func_getvar (NCDModuleProcess *o, NCD_string_id_t
     process_assert_interp(o);
     ASSERT(!NCDVal_IsInvalid(o->args))
     
-    if (name != NCD_EMPTY_STRING_ID) {
+    if (name != NCD_STRING_EMPTY) {
         return 0;
     }
     
@@ -538,7 +533,7 @@ static int process_arg_object_func_getvar2 (NCDModuleProcess *o, void *n_ptr, NC
     process_assert_interp(o);
     ASSERT(!NCDVal_IsInvalid(o->args))
     
-    if (name != NCD_EMPTY_STRING_ID) {
+    if (name != NCD_STRING_EMPTY) {
         return 0;
     }
     

+ 4 - 2
ncd/NCDObject.c

@@ -29,6 +29,8 @@
 
 #include <stddef.h>
 
+#include <ncd/static_strings.h>
+
 #include "NCDObject.h"
 
 NCDObject NCDObject_Build (const char *type, void *user, NCDObject_func_getvar func_getvar, NCDObject_func_getobj func_getobj)
@@ -99,7 +101,7 @@ int NCDObject_GetVar (NCDObject *o, NCD_string_id_t name, NCDValMem *mem, NCDVal
 static NCDObject dig_into_object (NCDObject object)
 {
     NCDObject obj2;
-    while (NCDObject_GetObj(&object, NCD_EMPTY_STRING_ID, &obj2)) {
+    while (NCDObject_GetObj(&object, NCD_STRING_EMPTY, &obj2)) {
         object = obj2;
     }
     
@@ -155,5 +157,5 @@ int NCDObject_ResolveVarExprCompact (NCDObject *o, const NCD_string_id_t *names,
         num_names--;
     }
     
-    return NCDObject_GetVar(&object, NCD_EMPTY_STRING_ID, mem, out_value);
+    return NCDObject_GetVar(&object, NCD_STRING_EMPTY, mem, out_value);
 }

+ 34 - 2
ncd/NCDStringIndex.c

@@ -32,6 +32,7 @@
 
 #include <misc/hashfun.h>
 #include <misc/strdup.h>
+#include <misc/array_length.h>
 #include <base/BLog.h>
 
 #include "NCDStringIndex.h"
@@ -48,6 +49,32 @@
 
 #include <generated/blog_channel_ncd.h>
 
+// NOTE: keep synchronized with static_strings.h
+static const char *static_strings[] = {
+    "",
+    "_args",
+    "_arg0",
+    "_arg1",
+    "_arg2",
+    "_arg3",
+    "_arg4",
+    "_arg5",
+    "_arg6",
+    "_arg7",
+    "_arg8",
+    "_arg9",
+    "_arg10",
+    "_arg11",
+    "_arg12",
+    "_arg13",
+    "_arg14",
+    "_arg15",
+    "_arg16",
+    "_arg17",
+    "_arg18",
+    "_arg19"
+};
+
 static NCD_string_id_t do_get (NCDStringIndex *o, const char *str, size_t str_len)
 {
     ASSERT(str)
@@ -99,14 +126,19 @@ int NCDStringIndex_Init (NCDStringIndex *o)
         goto fail1;
     }
     
-    if (do_get(o, "", 0) < 0) {
-        goto fail2;
+    for (size_t i = 0; i < B_ARRAY_LENGTH(static_strings); i++) {
+        if (do_get(o, static_strings[i], strlen(static_strings[i])) < 0) {
+            goto fail2;
+        }
     }
     
     DebugObject_Init(&o->d_obj);
     return 1;
     
 fail2:
+    for (NCD_string_id_t i = 0; i < o->entries_size; i++) {
+        free(o->entries[i].str);
+    }
     NCDStringIndex__Hash_Free(&o->hash);
 fail1:
     Array_Free(o);

+ 0 - 2
ncd/NCDStringIndex.h

@@ -55,8 +55,6 @@ typedef struct NCDStringIndex__entry *NCDStringIndex_hash_arg;
 #include "NCDStringIndex_hash.h"
 #include <structure/CHash_decl.h>
 
-#define NCD_EMPTY_STRING_ID ((NCD_string_id_t)0)
-
 typedef struct {
     struct NCDStringIndex__entry *entries;
     NCD_string_id_t entries_capacity;

+ 2 - 2
ncd/modules/alias.c

@@ -44,7 +44,7 @@
 #include <misc/debug.h>
 #include <misc/balloc.h>
 #include <ncd/NCDModule.h>
-#include <ncd/make_name_indices.h>
+#include <ncd/static_strings.h>
 
 #include <generated/blog_channel_ncd_alias.h>
 
@@ -194,7 +194,7 @@ static int func_getobj (void *vo, NCD_string_id_t name, NCDObject *out_object)
         return 0;
     }
     
-    if (name == NCD_EMPTY_STRING_ID) {
+    if (name == NCD_STRING_EMPTY) {
         *out_object = obj2;
         return 1;
     }

+ 11 - 6
ncd/modules/call.c

@@ -99,6 +99,12 @@ static void instance_free (struct instance *o);
 static int caller_obj_func_getobj (struct instance *o, NCD_string_id_t name, NCDObject *out_object);
 static int ref_obj_func_getobj (struct instance *o, NCD_string_id_t name, NCDObject *out_object);
 
+enum {STRING_CALLER, STRING_REF};
+
+static struct NCD_string_request strings[] = {
+    {"_caller"}, {"_ref"}, {NULL}
+};
+
 static void process_handler_event (struct instance *o, int event)
 {
     switch (event) {
@@ -135,15 +141,13 @@ static void process_handler_event (struct instance *o, int event)
 }
 
 static int process_func_getspecialobj (struct instance *o, NCD_string_id_t name, NCDObject *out_object)
-{     
-    const char *name_str = NCDStringIndex_Value(o->i->params->iparams->string_index, name);
-    
-    if (!strcmp(name_str, "_caller")) {
+{
+    if (name == strings[STRING_CALLER].id) {
         *out_object = NCDObject_Build(NULL, o, NULL, (NCDObject_func_getobj)caller_obj_func_getobj);
         return 1;
     }
     
-    if (!strcmp(name_str, "_ref")) {
+    if (name == strings[STRING_REF].id) {
         *out_object = NCDObject_Build(NULL, o, NULL, (NCDObject_func_getobj)ref_obj_func_getobj);
         return 1;
     }
@@ -347,5 +351,6 @@ static const struct NCDModule modules[] = {
 };
 
 const struct NCDModuleGroup ncdmodule_call = {
-    .modules = modules
+    .modules = modules,
+    .strings = strings
 };

+ 9 - 4
ncd/modules/call2.c

@@ -67,6 +67,12 @@ static int caller_obj_func_getobj (struct instance *o, NCD_string_id_t name, NCD
 static void func_new_templ (void *vo, NCDModuleInst *i, const char *template_name, NCDValRef args, int embed);
 static void instance_free (struct instance *o);
 
+enum {STRING_CALLER};
+
+static struct NCD_string_request strings[] = {
+    {"_caller"}, {NULL}
+};
+
 static void process_handler_event (struct instance *o, int event)
 {
     switch (event) {
@@ -108,9 +114,7 @@ static int process_func_getspecialobj (struct instance *o, NCD_string_id_t name,
         return NCDModuleInst_Backend_GetObj(o->i, name, out_object);
     }
     
-    const char *name_str = NCDStringIndex_Value(o->i->params->iparams->string_index, name);
-    
-    if (!strcmp(name_str, "_caller")) {
+    if (name == strings[STRING_CALLER].id) {
         *out_object = NCDObject_Build(NULL, o, NULL, (NCDObject_func_getobj)caller_obj_func_getobj);
         return 1;
     }
@@ -477,5 +481,6 @@ static const struct NCDModule modules[] = {
 };
 
 const struct NCDModuleGroup ncdmodule_call2 = {
-    .modules = modules
+    .modules = modules,
+    .strings = strings
 };

+ 46 - 28
ncd/modules/foreach.c

@@ -73,6 +73,7 @@
 #include <misc/debug.h>
 #include <system/BReactor.h>
 #include <ncd/NCDModule.h>
+#include <ncd/static_strings.h>
 
 #include <generated/blog_channel_ncd_foreach.h>
 
@@ -95,8 +96,8 @@ struct instance {
     NCDModuleInst *i;
     const char *template_name;
     NCDValRef args;
-    const char *name1;
-    const char *name2;
+    NCD_string_id_t name1;
+    NCD_string_id_t name2;
     BTimer timer;
     struct element *elems;
     int type;
@@ -135,6 +136,12 @@ static int element_map_key_object_func_getvar (struct element *e, NCD_string_id_
 static int element_map_val_object_func_getvar (struct element *e, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out);
 static void instance_free (struct instance *o);
 
+enum {STRING_CALLER, STRING_INDEX, STRING_ELEM, STRING_KEY, STRING_VAL};
+
+static struct NCD_string_request strings[] = {
+    {"_caller"}, {"_index"}, {"_elem"}, {"_key"}, {"_val"}, {NULL}
+};
+
 static void assert_state (struct instance *o)
 {
     ASSERT(o->num_elems >= 0)
@@ -353,33 +360,31 @@ static int element_process_func_getspecialobj (struct element *e, NCD_string_id_
     struct instance *o = e->inst;
     ASSERT(e->state != ESTATE_FORGOTTEN)
     
-    const char *name_str = NCDStringIndex_Value(o->i->params->iparams->string_index, name);
-    
     switch (o->type) {
         case NCDVAL_LIST: {
-            const char *index_name = (o->name2 ? o->name1 : NULL);
-            const char *elem_name = (o->name2 ? o->name2 : o->name1);
+            NCD_string_id_t index_name = (o->name2 >= 0 ? o->name1 : -1);
+            NCD_string_id_t elem_name = (o->name2 >= 0 ? o->name2 : o->name1);
             
-            if (index_name && !strcmp(name_str, index_name)) {
+            if (index_name >= 0 && name == index_name) {
                 *out_object = NCDObject_Build(NULL, e, (NCDObject_func_getvar)element_list_index_object_func_getvar, NULL);
                 return 1;
             }
             
-            if (!strcmp(name_str, elem_name)) {
+            if (name == elem_name) {
                 *out_object = NCDObject_Build(NULL, e, (NCDObject_func_getvar)element_list_elem_object_func_getvar, NULL);
                 return 1;
             }
         } break;
         case NCDVAL_MAP: {
-            const char *key_name = o->name1;
-            const char *val_name = o->name2;
+            NCD_string_id_t key_name = o->name1;
+            NCD_string_id_t val_name = o->name2;
             
-            if (!strcmp(name_str, key_name)) {
+            if (name == key_name) {
                 *out_object = NCDObject_Build(NULL, e, (NCDObject_func_getvar)element_map_key_object_func_getvar, NULL);
                 return 1;
             }
             
-            if (val_name && !strcmp(name_str, val_name)) {
+            if (val_name >= 0 && name == val_name) {
                 *out_object = NCDObject_Build(NULL, e, (NCDObject_func_getvar)element_map_val_object_func_getvar, NULL);
                 return 1;
             }
@@ -390,7 +395,7 @@ static int element_process_func_getspecialobj (struct element *e, NCD_string_id_
         return NCDModuleInst_Backend_GetObj(o->i, name, out_object);
     }
     
-    if (!strcmp(name_str, "_caller")) {
+    if (name == strings[STRING_CALLER].id) {
         *out_object = NCDObject_Build(NULL, e, NULL, (NCDObject_func_getobj)element_caller_object_func_getobj);
         return 1;
     }
@@ -413,7 +418,7 @@ static int element_list_index_object_func_getvar (struct element *e, NCD_string_
     ASSERT(e->state != ESTATE_FORGOTTEN)
     ASSERT(o->type == NCDVAL_LIST)
     
-    if (name != NCD_EMPTY_STRING_ID) {
+    if (name != NCD_STRING_EMPTY) {
         return 0;
     }
     
@@ -433,7 +438,7 @@ static int element_list_elem_object_func_getvar (struct element *e, NCD_string_i
     ASSERT(e->state != ESTATE_FORGOTTEN)
     ASSERT(o->type == NCDVAL_LIST)
     
-    if (name != NCD_EMPTY_STRING_ID) {
+    if (name != NCD_STRING_EMPTY) {
         return 0;
     }
     
@@ -450,7 +455,7 @@ static int element_map_key_object_func_getvar (struct element *e, NCD_string_id_
     ASSERT(e->state != ESTATE_FORGOTTEN)
     ASSERT(o->type == NCDVAL_MAP)
     
-    if (name != NCD_EMPTY_STRING_ID) {
+    if (name != NCD_STRING_EMPTY) {
         return 0;
     }
     
@@ -467,7 +472,7 @@ static int element_map_val_object_func_getvar (struct element *e, NCD_string_id_
     ASSERT(e->state != ESTATE_FORGOTTEN)
     ASSERT(o->type == NCDVAL_MAP)
     
-    if (name != NCD_EMPTY_STRING_ID) {
+    if (name != NCD_STRING_EMPTY) {
         return 0;
     }
     
@@ -478,12 +483,12 @@ static int element_map_val_object_func_getvar (struct element *e, NCD_string_id_
     return 1;
 }
 
-static void func_new_common (void *vo, NCDModuleInst *i, NCDValRef collection, const char *template_name, NCDValRef args, const char *name1, const char *name2)
+static void func_new_common (void *vo, NCDModuleInst *i, NCDValRef collection, const char *template_name, NCDValRef args, NCD_string_id_t name1, NCD_string_id_t name2)
 {
     ASSERT(!NCDVal_IsInvalid(collection))
     ASSERT(template_name)
     ASSERT(NCDVal_IsInvalid(args) || NCDVal_IsList(args))
-    ASSERT(name1)
+    ASSERT(name1 >= 0)
     
     struct instance *o = vo;
     o->i = i;
@@ -582,17 +587,17 @@ static void func_new_foreach (void *vo, NCDModuleInst *i, const struct NCDModule
     }
     
     const char *template_name = NCDVal_StringValue(arg_template);
-    const char *name1;
-    const char *name2;
+    NCD_string_id_t name1;
+    NCD_string_id_t name2;
     
     switch (NCDVal_Type(arg_collection)) {
         case NCDVAL_LIST: {
-            name1 = "_index";
-            name2 = "_elem";
+            name1 = strings[STRING_INDEX].id;
+            name2 = strings[STRING_ELEM].id;
         } break;
         case NCDVAL_MAP: {
-            name1 = "_key";
-            name2 = "_val";
+            name1 = strings[STRING_KEY].id;
+            name2 = strings[STRING_VAL].id;
         } break;
         default:
             ModuleLog(i, BLOG_ERROR, "invalid collection type");
@@ -624,8 +629,20 @@ static void func_new_foreach_emb (void *vo, NCDModuleInst *i, const struct NCDMo
     }
     
     const char *template_name = NCDVal_StringValue(arg_template);
-    const char *name1 = NCDVal_StringValue(arg_name1);
-    const char *name2 = (NCDVal_IsInvalid(arg_name2) ? NULL : NCDVal_StringValue(arg_name2));
+    const char *name1_str = NCDVal_StringValue(arg_name1);
+    const char *name2_str = (NCDVal_IsInvalid(arg_name2) ? NULL : NCDVal_StringValue(arg_name2));
+    
+    NCD_string_id_t name1 = NCDStringIndex_Get(i->params->iparams->string_index, name1_str);
+    if (name1 < 0) {
+        ModuleLog(i, BLOG_ERROR, "NCDStringIndex_Get failed");
+        goto fail0;
+    }
+    
+    NCD_string_id_t name2 = -1;
+    if (name2_str && (name2 = NCDStringIndex_Get(i->params->iparams->string_index, name2_str)) < 0) {
+        ModuleLog(i, BLOG_ERROR, "NCDStringIndex_Get failed");
+        goto fail0;
+    }
     
     func_new_common(vo, i, arg_collection, template_name, NCDVal_NewInvalid(), name1, name2);
     return;
@@ -699,5 +716,6 @@ static const struct NCDModule modules[] = {
 };
 
 const struct NCDModuleGroup ncdmodule_foreach = {
-    .modules = modules
+    .modules = modules,
+    .strings = strings
 };

+ 9 - 4
ncd/modules/imperative.c

@@ -85,6 +85,12 @@ static int process_caller_object_func_getobj (struct instance *o, NCD_string_id_
 static void deinit_timer_handler (struct instance *o);
 static void instance_free (struct instance *o);
 
+enum {STRING_CALLER};
+
+static struct NCD_string_request strings[] = {
+    {"_caller"}, {NULL}
+};
+
 static int start_process (struct instance *o, const char *templ, NCDValRef args, NCDModuleProcess_handler_event handler)
 {
     ASSERT(NCDVal_IsList(args))
@@ -196,9 +202,7 @@ static int process_func_getspecialobj (struct instance *o, NCD_string_id_t name,
 {
     ASSERT(o->state != STATE_UP)
     
-    const char *name_str = NCDStringIndex_Value(o->i->params->iparams->string_index, name);
-    
-    if (!strcmp(name_str, "_caller")) {
+    if (name == strings[STRING_CALLER].id) {
         *out_object = NCDObject_Build(NULL, o, NULL, (NCDObject_func_getobj)process_caller_object_func_getobj);
         return 1;
     }
@@ -315,5 +319,6 @@ static const struct NCDModule modules[] = {
 };
 
 const struct NCDModuleGroup ncdmodule_imperative = {
-    .modules = modules
+    .modules = modules,
+    .strings = strings
 };

+ 9 - 4
ncd/modules/process_manager.c

@@ -100,6 +100,12 @@ static void process_try (struct process *p);
 static int process_set_params (struct process *p, const char *template_name, NCDValMem mem, NCDValSafeRef args);
 static void instance_free (struct instance *o);
 
+enum {STRING_CALLER};
+
+static struct NCD_string_request strings[] = {
+    {"_caller"}, {NULL}
+};
+
 struct process * find_process (struct instance *o, const char *name)
 {
     LinkedList1Node *n = LinkedList1_GetFirst(&o->processes_list);
@@ -266,9 +272,7 @@ int process_module_process_func_getspecialobj (struct process *p, NCD_string_id_
 {
     ASSERT(p->have_module_process)
     
-    const char *name_str = NCDStringIndex_Value(p->manager->i->params->iparams->string_index, name);
-    
-    if (!strcmp(name_str, "_caller")) {
+    if (name == strings[STRING_CALLER].id) {
         *out_object = NCDObject_Build(NULL, p, NULL, (NCDObject_func_getobj)process_module_process_caller_obj_func_getobj);
         return 1;
     }
@@ -584,5 +588,6 @@ static const struct NCDModule modules[] = {
 };
 
 const struct NCDModuleGroup ncdmodule_process_manager = {
-    .modules = modules
+    .modules = modules,
+    .strings = strings
 };

+ 3 - 2
ncd/modules/ref.c

@@ -49,6 +49,7 @@
 #include <misc/offset.h>
 #include <structure/LinkedList0.h>
 #include <ncd/NCDModule.h>
+#include <ncd/static_strings.h>
 
 #include <generated/blog_channel_ncd_ref.h>
 
@@ -110,7 +111,7 @@ static int refhere_func_getobj (void *vo, NCD_string_id_t objname, NCDObject *ou
     
     // We don't redirect methods, and there will never be an object
     // with empty name. Fail here so we don't report non-errors.
-    if (objname == NCD_EMPTY_STRING_ID) {
+    if (objname == NCD_STRING_EMPTY) {
         return 0;
     }
     
@@ -178,7 +179,7 @@ static int ref_func_getobj (void *vo, NCD_string_id_t objname, NCDObject *out_ob
     
     // We don't redirect methods, and there will never be an object
     // with empty name. Fail here so we don't report non-errors.
-    if (objname == NCD_EMPTY_STRING_ID) {
+    if (objname == NCD_STRING_EMPTY) {
         return 0;
     }
     

+ 9 - 4
ncd/modules/spawn.c

@@ -93,6 +93,12 @@ static void continue_working (struct instance *o);
 static void continue_terminating (struct instance *o);
 static void instance_free (struct instance *o);
 
+enum {STRING_CALLER};
+
+static struct NCD_string_request strings[] = {
+    {"_caller"}, {NULL}
+};
+
 static void assert_dirty_state (struct instance *o)
 {
     ASSERT(!LinkedList0_IsEmpty(&o->dirty_list) == (o->state == STATE_WAITING || o->state == STATE_WAITING_TERMINATING))
@@ -151,9 +157,7 @@ static void process_handler_event (struct instance *o, int event)
 
 static int process_func_getspecialobj (struct instance *o, NCD_string_id_t name, NCDObject *out_object)
 {
-    const char *name_str = NCDStringIndex_Value(o->i->params->iparams->string_index, name);
-    
-    if (!strcmp(name_str, "_caller")) {
+    if (name == strings[STRING_CALLER].id) {
         *out_object = NCDObject_Build(NULL, o, NULL, (NCDObject_func_getobj)caller_obj_func_getobj);
         return 1;
     }
@@ -404,5 +408,6 @@ static const struct NCDModule modules[] = {
 };
 
 const struct NCDModuleGroup ncdmodule_spawn = {
-    .modules = modules
+    .modules = modules,
+    .strings = strings
 };

+ 11 - 8
ncd/modules/sys_request_client.c

@@ -163,6 +163,12 @@ static int get_connect_addr (struct instance *o, NCDValRef connect_addr_arg, str
 static void instance_free (struct instance *o, int with_error);
 static void request_instance_free (struct request_instance *o, int with_error);
 
+enum {STRING_CALLER, STRING_REPLY, STRING_DATA};
+
+static struct NCD_string_request strings[] = {
+    {"_caller"}, {"_reply"}, {"data"}, {NULL}
+};
+
 static void client_handler_error (struct instance *o)
 {
     ModuleLog(o->i, BLOG_ERROR, "client error");
@@ -316,14 +322,12 @@ static int request_process_func_getspecialobj (struct request_instance *o, NCD_s
 {
     ASSERT(o->pstate != RPSTATE_NONE)
     
-    const char *name_str = NCDStringIndex_Value(o->i->params->iparams->string_index, name);
-    
-    if (!strcmp(name_str, "_caller")) {
+    if (name == strings[STRING_CALLER].id) {
         *out_object = NCDObject_Build(NULL, o, NULL, (NCDObject_func_getobj)request_process_caller_obj_func_getobj);
         return 1;
     }
     
-    if (!o->process_is_finished && !strcmp(name_str, "_reply")) {
+    if (!o->process_is_finished && name == strings[STRING_REPLY].id) {
         *out_object = NCDObject_Build(NULL, o, (NCDObject_func_getvar)request_process_reply_obj_func_getvar, NULL);
         return 1;
     }
@@ -343,9 +347,7 @@ static int request_process_reply_obj_func_getvar (struct request_instance *o, NC
     ASSERT(o->pstate != RPSTATE_NONE)
     ASSERT(!o->process_is_finished)
     
-    const char *name_str = NCDStringIndex_Value(o->i->params->iparams->string_index, name);
-    
-    if (!strcmp(name_str, "data")) {
+    if (name == strings[STRING_DATA].id) {
         *out = NCDVal_NewCopy(mem, o->process_reply_data);
         if (NCDVal_IsInvalid(*out)) {
             ModuleLog(o->i, BLOG_ERROR, "NCDVal_NewCopy failed");
@@ -702,5 +704,6 @@ static const struct NCDModule modules[] = {
 };
 
 const struct NCDModuleGroup ncdmodule_sys_request_client = {
-    .modules = modules
+    .modules = modules,
+    .strings = strings
 };

+ 12 - 9
ncd/modules/sys_request_server.c

@@ -171,6 +171,12 @@ static void reply_send_qflow_if_handler_done (struct reply *r);
 static int init_listen (struct instance *o, NCDValRef listen_addr_arg);
 static void instance_free (struct instance *o);
 
+enum {STRING_REQUEST, STRING_DATA, STRING_CLIENT_ADDR_TYPE, STRING_CLIENT_ADDR};
+
+static struct NCD_string_request strings[] = {
+    {"_request"}, {"data"}, {"client_addr_type"}, {"client_addr"}, {NULL}
+};
+
 static void listener_handler (struct instance *o)
 {
     ASSERT(!o->dying)
@@ -474,9 +480,7 @@ static void request_process_handler_event (struct request *r, int event)
 
 static int request_process_func_getspecialobj (struct request *r, NCD_string_id_t name, NCDObject *out_object)
 {
-    const char *name_str = NCDStringIndex_Value(r->con->inst->i->params->iparams->string_index, name);
-    
-    if (!strcmp(name_str, "_request")) {
+    if (name == strings[STRING_REQUEST].id) {
         *out_object = NCDObject_Build("sys.request_server.request", r, (NCDObject_func_getvar)request_process_request_obj_func_getvar, NULL);
         return 1;
     }
@@ -488,9 +492,7 @@ static int request_process_request_obj_func_getvar (struct request *r, NCD_strin
 {
     struct instance *o = r->con->inst;
     
-    const char *name_str = NCDStringIndex_Value(o->i->params->iparams->string_index, name);
-    
-    if (!strcmp(name_str, "data")) {
+    if (name == strings[STRING_DATA].id) {
         *out = NCDVal_NewCopy(mem, r->request_data);
         if (NCDVal_IsInvalid(*out)) {
             ModuleLog(o->i, BLOG_ERROR, "NCDVal_NewCopy failed");
@@ -498,7 +500,7 @@ static int request_process_request_obj_func_getvar (struct request *r, NCD_strin
         return 1;
     }
     
-    if (!strcmp(name_str, "client_addr_type")) {
+    if (name == strings[STRING_CLIENT_ADDR_TYPE].id) {
         const char *str = "none";
         switch (r->con->addr.type) {
             case BADDR_TYPE_IPV4:
@@ -516,7 +518,7 @@ static int request_process_request_obj_func_getvar (struct request *r, NCD_strin
         return 1;
     }
     
-    if (!strcmp(name_str, "client_addr")) {
+    if (name == strings[STRING_CLIENT_ADDR].id) {
         char str[BIPADDR_MAX_PRINT_LEN] = "none";
         
         switch (r->con->addr.type) {
@@ -889,5 +891,6 @@ static const struct NCDModule modules[] = {
 };
 
 const struct NCDModuleGroup ncdmodule_sys_request_server = {
-    .modules = modules
+    .modules = modules,
+    .strings = strings
 };

+ 10 - 5
ncd/modules/try.c

@@ -83,6 +83,12 @@ static int process_caller_object_func_getobj (struct instance *o, NCD_string_id_
 static void start_terminating (struct instance *o);
 static void instance_free (struct instance *o);
 
+enum {STRING_CALLER, STRING_TRY};
+
+static struct NCD_string_request strings[] = {
+    {"_caller"}, {"_try"}, {NULL}
+};
+
 static void process_handler_event (struct instance *o, int event)
 {
     switch (event) {
@@ -125,14 +131,12 @@ static int process_func_getspecialobj (struct instance *o, NCD_string_id_t name,
 {
     ASSERT(o->state == STATE_INIT || o->state == STATE_DEINIT)
     
-    const char *name_str = NCDStringIndex_Value(o->i->params->iparams->string_index, name);
-    
-    if (!strcmp(name_str, "_caller")) {
+    if (name == strings[STRING_CALLER].id) {
         *out_object = NCDObject_Build(NULL, o, NULL, (NCDObject_func_getobj)process_caller_object_func_getobj);
         return 1;
     }
     
-    if (!strcmp(name_str, "_try")) {
+    if (name == strings[STRING_TRY].id) {
         *out_object = NCDObject_Build("try.try", o, NULL, NULL);
         return 1;
     }
@@ -293,5 +297,6 @@ static const struct NCDModule modules[] = {
 };
 
 const struct NCDModuleGroup ncdmodule_try = {
-    .modules = modules
+    .modules = modules,
+    .strings = strings
 };

+ 59 - 0
ncd/static_strings.h

@@ -0,0 +1,59 @@
+/**
+ * @file static_strings.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_STATIC_STRINGS_H
+#define BADVPN_STATIC_STRINGS_H
+
+// NOTE: keep synchronized with NCDStringIndex.c
+enum {
+    NCD_STRING_EMPTY,
+    NCD_STRING_ARGS,
+    NCD_STRING_ARG0,
+    NCD_STRING_ARG1,
+    NCD_STRING_ARG2,
+    NCD_STRING_ARG3,
+    NCD_STRING_ARG4,
+    NCD_STRING_ARG5,
+    NCD_STRING_ARG6,
+    NCD_STRING_ARG7,
+    NCD_STRING_ARG8,
+    NCD_STRING_ARG9,
+    NCD_STRING_ARG10,
+    NCD_STRING_ARG11,
+    NCD_STRING_ARG12,
+    NCD_STRING_ARG13,
+    NCD_STRING_ARG14,
+    NCD_STRING_ARG15,
+    NCD_STRING_ARG16,
+    NCD_STRING_ARG17,
+    NCD_STRING_ARG18,
+    NCD_STRING_ARG19
+};
+
+#endif