flush
[m6w6/ext-psi] / src / context.c
index 7670462cd255e8769f0d01caa7ffa3ae803d8729..a051697ff7715f72b34cdb271e46ce0950f83c42 100644 (file)
@@ -3,14 +3,44 @@
 #include <fnmatch.h>
 #include <errno.h>
 
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
 #include "php.h"
 #include "php_scandir.h"
 #include "context.h"
 #include "parser.h"
 #include "validator.h"
 
+#define psi_predef_count(s) (sizeof(psi_predef_ ##s## s)/sizeof(psi_predef ##s))
+typedef struct psi_predef_type {
+       token_t type_tag;
+       const char *type_name;
+       const char *alias;
+} psi_predef_type;
+#define psi_predef_type_count() psi_predef_count(type)
+static const psi_predef_types[] = {
+       PHP_PSI_TYPES
+};
+
+typedef struct psi_predef_const {
+       token_t type_tag;
+       const char *type_name;
+       const char *name;
+       const char *val_text;
+       token_t val_type_tag;
+} psi_predef_const;
+#define psi_predef_const_count() psi_predef_count(const)
+static const psi_predef_consts[] = {
+       PHP_PSI_CONSTS
+};
+
 PSI_Context *PSI_ContextInit(PSI_Context *C, PSI_ContextOps *ops, PSI_ContextErrorFunc error)
 {
+       size_t i;
+       PSI_Data data;
+
        if (!C) {
                C = malloc(sizeof(*C));
        }
@@ -20,6 +50,22 @@ PSI_Context *PSI_ContextInit(PSI_Context *C, PSI_ContextOps *ops, PSI_ContextErr
        C->ops = ops;
        ops->init(C);
 
+       memset(&data, 0, sizeof(data));
+       for (i = 0; i < psi_predef_type_count(); ++i) {
+               psi_predef_type *pre = &psi_predef_types[i];
+               decl_type *type = init_decl_type(pre->type_tag, pre->type_name);
+               decl_typedef *def = init_decl_typedef(pre->alias, type);
+
+               data.defs = add_decl_typedef(data.defs, def);
+       }
+       for (i = 0; i < psi_predef_const_count(); ++i) {
+               psi_predef_const *pre = psi_predef_const[i];
+               impl_def_val *val = init_impl_def_val(pre->val_type_tag, pre->val_text);
+               const_type *type = init_const_type(pre->type_tag, pre->type_name);
+               constant *constant = init_constant(type, pre->name, val);
+
+               data.consts = add_constant(data.consts, constant);
+       }
        return C;
 }
 
@@ -41,7 +87,6 @@ void PSI_ContextBuild(PSI_Context *C, const char *path)
 
        if (n < 0) {
                return;
-               C->error(PSI_WARNING, "Failed to scan PSI directory '%s'", path);
        } else for (i = 0; i < n; ++i) {
                char psi[MAXPATHLEN];
                PSI_Parser P;
@@ -71,33 +116,6 @@ void PSI_ContextBuild(PSI_Context *C, const char *path)
                if (PSI_ValidatorValidate(&V)) {
                        zend_function_entry *closures;
 
-                       if (V.consts) {
-                               zend_constant zc;
-
-                               zc.flags = CONST_PERSISTENT|CONST_CS;
-                               zc.module_number = EG(current_module)->module_number;
-
-                               for (i = 0; i < V.consts->count; ++i) {
-                                       constant *c = V.consts->list[i];
-
-                                       zc.name = zend_string_init(c->name + (c->name[0] == '\\'), strlen(c->name) - (c->name[0] == '\\'), 1);
-                                       ZVAL_NEW_STR(&zc.value, zend_string_init(c->val->text, strlen(c->val->text), 1));
-
-                                       switch (c->type->type) {
-                                       case PSI_T_BOOL:
-                                               convert_to_boolean(&zc.value);
-                                               break;
-                                       case PSI_T_INT:
-                                               convert_to_long(&zc.value);
-                                               break;
-                                       case PSI_T_FLOAT:
-                                               convert_to_double(&zc.value);
-                                               break;
-                                       }
-                                       zend_register_constant(&zc);
-                               }
-                       }
-
                        closures = PSI_ContextCompile(C, (PSI_Data *) &V);
                        if (closures && SUCCESS != zend_register_functions(NULL, closures, NULL, MODULE_PERSISTENT)) {
                                C->error(PSI_WARNING, "Failed to register functions!");
@@ -116,9 +134,36 @@ void PSI_ContextBuild(PSI_Context *C, const char *path)
 
 zend_function_entry *PSI_ContextCompile(PSI_Context *C, PSI_Data *D)
 {
-       size_t count = C->count++;
+       size_t i, count = C->count++;
        zend_function_entry *zfe;
 
+       if (D->consts) {
+               zend_constant zc;
+
+               zc.flags = CONST_PERSISTENT|CONST_CS;
+               zc.module_number = EG(current_module)->module_number;
+
+               for (i = 0; i < D->consts->count; ++i) {
+                       constant *c = D->consts->list[i];
+
+                       zc.name = zend_string_init(c->name + (c->name[0] == '\\'), strlen(c->name) - (c->name[0] == '\\'), 1);
+                       ZVAL_NEW_STR(&zc.value, zend_string_init(c->val->text, strlen(c->val->text), 1));
+
+                       switch (c->type->type) {
+                       case PSI_T_BOOL:
+                               convert_to_boolean(&zc.value);
+                               break;
+                       case PSI_T_INT:
+                               convert_to_long(&zc.value);
+                               break;
+                       case PSI_T_FLOAT:
+                               convert_to_double(&zc.value);
+                               break;
+                       }
+                       zend_register_constant(&zc);
+               }
+       }
+
        C->data = realloc(C->data, C->count * sizeof(*C->data));
        PSI_DataExchange(&C->data[count], D);
 
@@ -139,7 +184,6 @@ void PSI_ContextDtor(PSI_Context *C)
        for (i = 0; i < C->count; ++i) {
                PSI_DataDtor(&C->data[i]);
                if (C->closures[i]){
-                       free(C->closures[i]->arg_info);
                        free(C->closures[i]);
                }
        }
@@ -157,4 +201,3 @@ void PSI_ContextFree(PSI_Context **C)
                *C = NULL;
        }
 }
-