cleanup
[m6w6/ext-psi] / src / context.c
index 18e76e4db451b06fdde9f37537a6a1b09608451b..987fb9abc0a45a660ba8353d25047a8e75c6feb4 100644 (file)
@@ -235,19 +235,19 @@ static inline int validate_decl_func(PSI_Data *data, void *dl, decl *decl, decl_
 #ifndef RTLD_NEXT
 # define RTLD_NEXT ((void *) -1l)
 #endif
-       decl->dlptr = dlsym(dl ?: RTLD_NEXT, func->var->name);
-       if (!decl->dlptr) {
+       decl->call.sym = dlsym(dl ?: RTLD_NEXT, func->var->name);
+       if (!decl->call.sym) {
                size_t i;
 
                for (i = 0; i < psi_predef_func_count(); ++i) {
                        psi_predef_func *pre = &psi_predef_funcs[i];
 
                        if (!strcmp(func->var->name, pre->name)) {
-                               decl->dlptr = pre->func;
+                               decl->call.sym = pre->func;
                                break;
                        }
                }
-               if (!decl->dlptr) {
+               if (!decl->call.sym) {
                        data->error(PSI_WARNING, "Failed to locate symbol '%s': %s",
                                func->var->name, dlerror());
                }
@@ -368,10 +368,13 @@ static inline int validate_impl_ret_stmt(PSI_Data *data, impl *impl) {
                                impl->func->name);
                return 0;
        }
+
        if (!validate_set_value(data, ret->set, ret->decl)) {
                return 0;
        }
 
+       impl->decl->impl = impl;
+
        return 1;
 }
 static inline int validate_impl_let_stmts(PSI_Data *data, impl *impl) {
@@ -576,7 +579,13 @@ PSI_Context *PSI_ContextInit(PSI_Context *C, PSI_ContextOps *ops, PSI_ContextErr
 
        C->error = error;
        C->ops = ops;
-       ops->init(C);
+
+       if (ops->init) {
+               ops->init(C);
+       }
+
+       ZEND_ASSERT(ops->call != NULL);
+       ZEND_ASSERT(ops->compile != NULL);
 
        /* build up predefs in a temporary PSI_Data for validation */
        memset(&T, 0, sizeof(T));
@@ -728,47 +737,62 @@ static int psi_select_dirent(const struct dirent *entry)
        return 0 == fnmatch("*.psi", entry->d_name, FNM_CASEFOLD);
 }
 
-void PSI_ContextBuild(PSI_Context *C, const char *path)
+void PSI_ContextBuild(PSI_Context *C, const char *paths)
 {
        int i, n;
+       char *sep = NULL, *cpy = strdup(paths), *ptr = cpy;
        struct dirent **entries = NULL;
 
-       n = php_scandir(path, &entries, psi_select_dirent, alphasort);
 
-       if (n < 0) {
-               return;
-       } else for (i = 0; i < n; ++i) {
-               char psi[MAXPATHLEN];
-               PSI_Parser P;
+       do {
+               sep = strchr(ptr, ':');
+
+               if (sep) {
+                       *sep = 0;
+               }
+
+               n = php_scandir(ptr, &entries, psi_select_dirent, alphasort);
+
+               if (n > 0) {
+                       for (i = 0; i < n; ++i) {
+                               char psi[MAXPATHLEN];
+                               PSI_Parser P;
+
+                               if (MAXPATHLEN <= slprintf(psi, MAXPATHLEN, "%s/%s", ptr, entries[i]->d_name)) {
+                                       C->error(PSI_WARNING, "Path to PSI file too long: %s/%s",
+                                               ptr, entries[i]->d_name);
+                               }
+                               if (!PSI_ParserInit(&P, psi, C->error, 0)) {
+                                       C->error(PSI_WARNING, "Failed to init PSI parser (%s): %s",
+                                               psi, strerror(errno));
+                                       continue;
+                               }
 
-               if (MAXPATHLEN <= slprintf(psi, MAXPATHLEN, "%s/%s", path, entries[i]->d_name)) {
-                       C->error(PSI_WARNING, "Path to PSI file too long: %s/%s",
-                               path, entries[i]->d_name);
+                               while (-1 != PSI_ParserScan(&P)) {
+                                       PSI_ParserParse(&P, PSI_TokenAlloc(&P));
+                               };
+                               PSI_ParserParse(&P, NULL);
+                               PSI_ContextValidate(C, &P);
+                               PSI_ParserDtor(&P);
+                       }
                }
-               if (!PSI_ParserInit(&P, psi, C->error, 0)) {
-                       C->error(PSI_WARNING, "Failed to init PSI parser (%s): %s",
-                               psi, strerror(errno));
-                       continue;
+
+               if (entries) {
+                       for (i = 0; i < n; ++i) {
+                               free(entries[i]);
+                       }
+                       free(entries);
                }
 
-               while (-1 != PSI_ParserScan(&P)) {
-                       PSI_ParserParse(&P, PSI_TokenAlloc(&P));
-               };
-               PSI_ParserParse(&P, NULL);
-               PSI_ContextValidate(C, &P);
-               PSI_ParserDtor(&P);
-       }
+               ptr = sep + 1;
+       } while (sep);
+
 
        if (PSI_ContextCompile(C) && SUCCESS != zend_register_functions(NULL, C->closures, NULL, MODULE_PERSISTENT)) {
                C->error(PSI_WARNING, "Failed to register functions!");
        }
 
-       if (entries) {
-               for (i = 0; i < n; ++i) {
-                       free(entries[i]);
-               }
-               free(entries);
-       }
+       free(cpy);
 
 }
 
@@ -803,29 +827,34 @@ zend_function_entry *PSI_ContextCompile(PSI_Context *C)
                }
        }
 
-
        return C->closures = C->ops->compile(C);
 }
 
 
-void PSI_ContextCall(PSI_Context *C, impl_val *ret_val, decl *decl, impl_val **args)
+void PSI_ContextCall(PSI_Context *C, impl_val *ret_val, decl *decl)
 {
-       C->ops->call(C, ret_val, decl, args);
+       C->ops->call(C, ret_val, decl);
 }
 
 void PSI_ContextDtor(PSI_Context *C)
 {
        size_t i;
+       zend_function_entry *zfe;
 
-       C->ops->dtor(C);
+       if (C->ops->dtor) {
+               C->ops->dtor(C);
+       }
 
        free_decl_libs(&C->psi.libs);
 
        for (i = 0; i < C->count; ++i) {
                PSI_DataDtor(&C->data[i]);
        }
-
        free(C->data);
+
+       for (zfe = C->closures; zfe->fname; ++zfe) {
+               free((void *) zfe->arg_info);
+       }
        free(C->closures);
 
        if (C->consts) {