Przeglądaj źródła

ncd: add interface for providing special variables/objects in template processes

ambrop7 14 lat temu
rodzic
commit
f2aea39226
3 zmienionych plików z 119 dodań i 0 usunięć
  1. 48 0
      ncd/NCDModule.c
  2. 54 0
      ncd/NCDModule.h
  3. 17 0
      ncd/ncd.c

+ 48 - 0
ncd/NCDModule.c

@@ -423,6 +423,10 @@ int NCDModuleProcess_Init (NCDModuleProcess *o, NCDModuleInst *n, const char *te
     o->user = user;
     o->handler_event = handler_event;
     
+    // set no special functions
+    o->func_getspecialvar = NULL;
+    o->func_getspecialobj = NULL;
+    
     // init event job
     BPending_Init(&o->event_job, BReactor_PendingGroup(n->reactor), (BPending_handler)process_event_job_handler, o);
     
@@ -459,6 +463,14 @@ void NCDModuleProcess_Free (NCDModuleProcess *o)
     BPending_Free(&o->event_job);
 }
 
+void NCDModuleProcess_SetSpecialFuncs (NCDModuleProcess *o, NCDModuleProcess_func_getspecialvar func_getspecialvar, NCDModuleProcess_func_getspecialobj func_getspecialobj)
+{
+    DebugObject_Access(&o->d_obj);
+    
+    o->func_getspecialvar = func_getspecialvar;
+    o->func_getspecialobj = func_getspecialobj;
+}
+
 void NCDModuleProcess_Continue (NCDModuleProcess *o)
 {
     DebugObject_Access(&o->d_obj);
@@ -566,3 +578,39 @@ void NCDModuleProcess_Interp_Terminated (NCDModuleProcess *o)
     BPending_Set(&o->event_job);
     o->state = PROCESS_STATE_TERMINATED_PENDING;
 }
+
+int NCDModuleProcess_Interp_GetSpecialVar (NCDModuleProcess *o, const char *name, NCDValue *out)
+{
+    DebugObject_Access(&o->d_obj);
+    ASSERT(o->state == PROCESS_STATE_DOWN || o->state == PROCESS_STATE_UP_PENDING ||
+           o->state == PROCESS_STATE_DOWN_CONTINUE_PENDING || o->state == PROCESS_STATE_UP ||
+           o->state == PROCESS_STATE_DOWN_PENDING || o->state == PROCESS_STATE_DOWN_WAITING ||
+           o->state == PROCESS_STATE_TERMINATING)
+    ASSERT(name)
+    ASSERT(out)
+    
+    if (!o->func_getspecialvar) {
+        return 0;
+    }
+    
+    int res = o->func_getspecialvar(o->user, name, out);
+    ASSERT(res == 0 || res == 1)
+    
+    return res;
+}
+
+NCDModuleInst * NCDModuleProcess_Interp_GetSpecialObj (NCDModuleProcess *o, const char *name)
+{
+    DebugObject_Access(&o->d_obj);
+    ASSERT(o->state == PROCESS_STATE_DOWN || o->state == PROCESS_STATE_UP_PENDING ||
+           o->state == PROCESS_STATE_DOWN_CONTINUE_PENDING || o->state == PROCESS_STATE_UP ||
+           o->state == PROCESS_STATE_DOWN_PENDING || o->state == PROCESS_STATE_DOWN_WAITING ||
+           o->state == PROCESS_STATE_TERMINATING)
+    ASSERT(name)
+    
+    if (!o->func_getspecialobj) {
+        return NULL;
+    }
+    
+    return o->func_getspecialobj(o->user, name);
+}

+ 54 - 0
ncd/NCDModule.h

@@ -144,6 +144,29 @@ typedef int (*NCDModuleInst_func_initprocess) (void *user, struct NCDModuleProce
  */
 typedef void (*NCDModuleProcess_handler_event) (void *user, int event);
 
+/**
+ * Function called when the interpreter wants to resolve a special
+ * variable in the process.
+ * This function must have no side effects.
+ * 
+ * @param user as in {@link NCDModuleProcess_Init}
+ * @param name name of the variable
+ * @param out on success, should initialize the value here
+ * @return 1 on success, 0 on failure
+ */
+typedef int (*NCDModuleProcess_func_getspecialvar) (void *user, const char *name, NCDValue *out);
+
+/**
+ * Function called when the interpreter wants to resolve a special
+ * object in the process.
+ * This function must have no side effects.
+ * 
+ * @param user as in {@link NCDModuleProcess_Init}
+ * @param name name of the object
+ * @return object, or NULL on failure
+ */
+typedef struct NCDModuleInst_s * (*NCDModuleProcess_func_getspecialobj) (void *user, const char *name);
+
 #define NCDMODULEPROCESS_INTERP_EVENT_CONTINUE 1
 #define NCDMODULEPROCESS_INTERP_EVENT_TERMINATE 2
 
@@ -239,6 +262,8 @@ typedef struct NCDModuleProcess_s {
     NCDModuleInst *n;
     void *user;
     NCDModuleProcess_handler_event handler_event;
+    NCDModuleProcess_func_getspecialvar func_getspecialvar;
+    NCDModuleProcess_func_getspecialobj func_getspecialobj;
     BPending event_job;
     int state;
     void *interp_user;
@@ -436,6 +461,16 @@ int NCDModuleProcess_Init (NCDModuleProcess *o, NCDModuleInst *n, const char *te
  */
 void NCDModuleProcess_Free (NCDModuleProcess *o);
 
+/**
+ * Sets callback functions for providing special variables and objects within
+ * the process.
+ * 
+ * @param o the process
+ * @param func_getspecialvar function for resolving special variables, or NULL
+ * @param func_getspecialobj function for resolving special objects, or NULL
+ */
+void NCDModuleProcess_SetSpecialFuncs (NCDModuleProcess *o, NCDModuleProcess_func_getspecialvar func_getspecialvar, NCDModuleProcess_func_getspecialobj func_getspecialobj);
+
 /**
  * Continues the process after the process went down.
  * The process must be in waiting state.
@@ -527,6 +562,25 @@ void NCDModuleProcess_Interp_Down (NCDModuleProcess *o);
  */
 void NCDModuleProcess_Interp_Terminated (NCDModuleProcess *o);
 
+/**
+ * Resolves a special process variable for the process backend.
+ * 
+ * @param o process backend handle
+ * @param name name of the variable
+ * @param out the value will be initialized here if successful
+ * @return 1 on success, 0 on failure
+ */
+int NCDModuleProcess_Interp_GetSpecialVar (NCDModuleProcess *o, const char *name, NCDValue *out) WARN_UNUSED;
+
+/**
+ * Resolves a special process object for the process backend.
+ * 
+ * @param o process backend handle
+ * @param name name of the object
+ * @return object, or NULL on failure
+ */
+NCDModuleInst * NCDModuleProcess_Interp_GetSpecialObj (NCDModuleProcess *o, const char *name) WARN_UNUSED;
+
 /**
  * Function called before any instance of any backend in a module
  * group is created;

+ 17 - 0
ncd/ncd.c

@@ -1241,6 +1241,13 @@ int process_resolve_variable (struct process *p, size_t pos, const char *varname
             return 1;
         }
         
+        // handle special variables
+        if (p->module_process) {
+            if (NCDModuleProcess_Interp_GetSpecialVar(p->module_process, varname, out)) {
+                return 1;
+            }
+        }
+        
         process_log(p, BLOG_ERROR, "unknown statement name in variable: %s", varname);
         return 0;
     }
@@ -1271,6 +1278,16 @@ struct process_statement * process_resolve_object (struct process *p, size_t pos
     }
     
     if (!rps) {
+        // handle special objects
+        if (p->module_process) {
+            NCDModuleInst *inst = NCDModuleProcess_Interp_GetSpecialObj(p->module_process, objname);
+            if (inst) {
+                struct process_statement *res_ps = UPPER_OBJECT(inst, struct process_statement, inst);
+                ASSERT(res_ps->state == SSTATE_ADULT)
+                return res_ps;
+            }
+        }
+        
         process_log(p, BLOG_ERROR, "unknown statement name in object: %s", objname);
         return NULL;
     }