Merge branch 'slimconfigure'
[m6w6/ext-psi] / src / cpp.c
index 8075cf6b6ea646a21eddb32ba86a321953870ab6..5ab649247d17a4a2f468d7411a825e2c9333541c 100644 (file)
--- a/src/cpp.c
+++ b/src/cpp.c
@@ -25,6 +25,8 @@
 
 #include "php_psi_stdinc.h"
 
 
 #include "php_psi_stdinc.h"
 
+#include <libgen.h>
+
 #include "cpp.h"
 #include "parser.h"
 
 #include "cpp.h"
 #include "parser.h"
 
@@ -65,6 +67,7 @@ bool psi_cpp_load_defaults(struct psi_cpp *cpp)
        return false;
 }
 
        return false;
 }
 
+#if PSI_CPP_DEBUG
 static int dump_def(zval *p)
 {
        struct psi_cpp_macro_decl *decl = Z_PTR_P(p);
 static int dump_def(zval *p)
 {
        struct psi_cpp_macro_decl *decl = Z_PTR_P(p);
@@ -76,17 +79,18 @@ static int dump_def(zval *p)
        }
        return ZEND_HASH_APPLY_KEEP;
 }
        }
        return ZEND_HASH_APPLY_KEEP;
 }
+#endif
 
 void psi_cpp_free(struct psi_cpp **cpp_ptr)
 {
        if (*cpp_ptr) {
                struct psi_cpp *cpp = *cpp_ptr;
 
 
 void psi_cpp_free(struct psi_cpp **cpp_ptr)
 {
        if (*cpp_ptr) {
                struct psi_cpp *cpp = *cpp_ptr;
 
+#if PSI_CPP_DEBUG
+               fprintf(stderr, "PSI: CPP decls:\n");
+               zend_hash_apply(&cpp->defs, dump_def);
+#endif
                *cpp_ptr = NULL;
                *cpp_ptr = NULL;
-               if (cpp->parser->flags & PSI_DEBUG) {
-                       fprintf(stderr, "PSI: CPP decls:\n");
-                       zend_hash_apply(&cpp->defs, dump_def);
-               }
                zend_hash_destroy(&cpp->defs);
                zend_hash_destroy(&cpp->once);
                free(cpp);
                zend_hash_destroy(&cpp->defs);
                zend_hash_destroy(&cpp->once);
                free(cpp);
@@ -371,6 +375,15 @@ void psi_cpp_define(struct psi_cpp *cpp, struct psi_cpp_macro_decl *decl)
                cpp->parser->error(PSI_DATA(cpp->parser), old->token, PSI_WARNING,
                                "'%s' previously defined", old->token->text);
        }
                cpp->parser->error(PSI_DATA(cpp->parser), old->token, PSI_WARNING,
                                "'%s' previously defined", old->token->text);
        }
+#if PSI_CPP_DEBUG
+       if (decl->exp) {
+               fprintf(stderr, "MACRO: num_exp: ", decl->token->text);
+       } else if (decl->tokens) {
+               fprintf(stderr, "MACRO: decl   : ", decl->token->text);
+       }
+       psi_cpp_macro_decl_dump(2, decl);
+       fprintf(stderr, "\n");
+#endif
        zend_hash_str_update_ptr(&cpp->defs, decl->token->text, decl->token->size, decl);
 }
 
        zend_hash_str_update_ptr(&cpp->defs, decl->token->text, decl->token->size, decl);
 }
 
@@ -381,10 +394,13 @@ bool psi_cpp_undef(struct psi_cpp *cpp, struct psi_token *tok)
 
 bool psi_cpp_if(struct psi_cpp *cpp, struct psi_cpp_exp *exp)
 {
 
 bool psi_cpp_if(struct psi_cpp *cpp, struct psi_cpp_exp *exp)
 {
-       if (!psi_num_exp_validate(PSI_DATA(cpp->parser), exp->data.num, NULL, NULL, NULL, NULL, NULL)) {
+       struct psi_validate_scope scope = {0};
+
+       scope.defs = &cpp->defs;
+       if (!psi_num_exp_validate(PSI_DATA(cpp->parser), exp->data.num, &scope)) {
                return false;
        }
                return false;
        }
-       if (!psi_long_num_exp(exp->data.num, NULL, &cpp->defs)) {
+       if (!psi_num_exp_get_long(exp->data.num, NULL, &cpp->defs)) {
                return false;
        }
        return true;
                return false;
        }
        return true;
@@ -427,24 +443,49 @@ static inline bool try_include(struct psi_cpp *cpp, const char *path, bool *pars
        return false;
 }
 
        return false;
 }
 
-bool psi_cpp_include(struct psi_cpp *cpp, const char *file, unsigned flags)
+static inline void include_path(const struct psi_token *file, char **path)
+{
+       if (*file->text == '/') {
+               *path = file->text;
+       } else {
+               char *dir;
+               size_t len;
+
+               strncpy(*path, file->file, PATH_MAX);
+
+               dir = dirname(*path);
+               len = strlen(dir);
+
+               assert(len + file->size + 1 < PATH_MAX);
+
+               memmove(*path, dir, len);
+               (*path)[len] = '/';
+               memcpy(&(*path)[len + 1], file->text, file->size + 1);
+       }
+}
+
+bool psi_cpp_include(struct psi_cpp *cpp, const struct psi_token *file, unsigned flags)
 {
        bool parsed = false;
 {
        bool parsed = false;
-       int f_len = strlen(file);
+       int f_len = strlen(file->text);
 
 
-       if (!(flags & PSI_CPP_INCLUDE_NEXT) || *file == '/') {
+       if (!(flags & PSI_CPP_INCLUDE_NEXT) || *file->text == '/') {
                /* first try as is, full or relative path */
                /* first try as is, full or relative path */
-               if ((flags & PSI_CPP_INCLUDE_ONCE) && zend_hash_str_exists(&cpp->once, file, f_len)) {
+               char temp[PATH_MAX], *path = temp;
+
+               include_path(file, &path);
+
+               if ((flags & PSI_CPP_INCLUDE_ONCE) && zend_hash_str_exists(&cpp->once, path, f_len)) {
                        return true;
                }
                        return true;
                }
-               if (try_include(cpp, file, &parsed)) {
+               if (try_include(cpp, path, &parsed)) {
                        /* found */
                        return parsed;
                }
        }
 
        /* look through search paths */
                        /* found */
                        return parsed;
                }
        }
 
        /* look through search paths */
-       if (*file != '/') {
+       if (*file->text != '/') {
                char path[PATH_MAX];
                const char *sep;
                int p_len;
                char path[PATH_MAX];
                const char *sep;
                int p_len;
@@ -468,7 +509,7 @@ bool psi_cpp_include(struct psi_cpp *cpp, const char *file, unsigned flags)
                        sep = strchr(cpp->search, ':');
                        d_len = sep ? sep - cpp->search : strlen(cpp->search);
 
                        sep = strchr(cpp->search, ':');
                        d_len = sep ? sep - cpp->search : strlen(cpp->search);
 
-                       if (PATH_MAX > (p_len = snprintf(path, PATH_MAX, "%.*s/%.*s", d_len, cpp->search, f_len, file))) {
+                       if (PATH_MAX > (p_len = snprintf(path, PATH_MAX, "%.*s/%.*s", d_len, cpp->search, f_len, file->text))) {
                                if ((flags & PSI_CPP_INCLUDE_ONCE) && zend_hash_str_exists(&cpp->once, path, p_len)) {
                                        return true;
                                }
                                if ((flags & PSI_CPP_INCLUDE_ONCE) && zend_hash_str_exists(&cpp->once, path, p_len)) {
                                        return true;
                                }