basic support for builtins
[m6w6/ext-psi] / src / types / cpp_exp.c
index ee7a30b255fef8bfa27cccb76e584455e778c003..bfff0d197d443a8a2a6c721b6bd4868b5524f1b3 100644 (file)
@@ -32,7 +32,7 @@
 
 struct psi_cpp_exp *psi_cpp_exp_init(token_t type, void *data)
 {
-       struct psi_cpp_exp *exp = calloc(1, sizeof(*exp));
+       struct psi_cpp_exp *exp = pecalloc(1, sizeof(*exp), 1);
 
        switch ((exp->type = type)) {
        case PSI_T_WARNING:
@@ -54,6 +54,7 @@ struct psi_cpp_exp *psi_cpp_exp_init(token_t type, void *data)
                break;
        case PSI_T_ENDIF:
        case PSI_T_ELSE:
+       case PSI_T_PRAGMA_ONCE:
                break;
        default:
                assert(0);
@@ -72,18 +73,13 @@ void psi_cpp_exp_free(struct psi_cpp_exp **exp_ptr)
                switch (exp->type) {
                case PSI_T_WARNING:
                case PSI_T_ERROR:
-                       if (!exp->data.tok) {
-                               break;
-                       }
-                       /* no break */
                case PSI_T_UNDEF:
                case PSI_T_IFDEF:
                case PSI_T_IFNDEF:
                case PSI_T_IMPORT:
                case PSI_T_INCLUDE:
                case PSI_T_INCLUDE_NEXT:
-                       free(exp->data.tok);
-                       exp->data.tok = NULL;
+                       psi_token_free(&exp->data.tok);
                        break;
                case PSI_T_DEFINE:
                        psi_cpp_macro_decl_free(&exp->data.decl);
@@ -94,21 +90,20 @@ void psi_cpp_exp_free(struct psi_cpp_exp **exp_ptr)
                        break;
                case PSI_T_ENDIF:
                case PSI_T_ELSE:
+               case PSI_T_PRAGMA_ONCE:
                        break;
                default:
                        assert(0);
                        break;
                }
-               if (exp->token) {
-                       free(exp->token);
-               }
+               psi_token_free(&exp->token);
                free(exp);
        }
 }
 
 void psi_cpp_exp_dump(int fd, struct psi_cpp_exp *exp)
 {
-       dprintf(fd, "#%s ", exp->token->text);
+       dprintf(fd, "#%s ", exp->token->text->val);
        switch (exp->type) {
        case PSI_T_WARNING:
        case PSI_T_ERROR:
@@ -119,10 +114,16 @@ void psi_cpp_exp_dump(int fd, struct psi_cpp_exp *exp)
        case PSI_T_UNDEF:
        case PSI_T_IFDEF:
        case PSI_T_IFNDEF:
+               dprintf(fd, "%s", exp->data.tok->text->val);
+               break;
        case PSI_T_IMPORT:
        case PSI_T_INCLUDE:
        case PSI_T_INCLUDE_NEXT:
-               dprintf(fd, "%s", exp->data.tok->text);
+               if (exp->data.tok->type == PSI_T_CPP_HEADER) {
+                       dprintf(fd, "<%s>", exp->data.tok->text->val);
+               } else {
+                       dprintf(fd, "\"%s\"", exp->data.tok->text->val);
+               }
                break;
        case PSI_T_DEFINE:
                psi_cpp_macro_decl_dump(fd, exp->data.decl);
@@ -133,6 +134,7 @@ void psi_cpp_exp_dump(int fd, struct psi_cpp_exp *exp)
                break;
        case PSI_T_ENDIF:
        case PSI_T_ELSE:
+       case PSI_T_PRAGMA_ONCE:
                break;
        default:
                assert(0);
@@ -179,23 +181,24 @@ static inline void psi_cpp_level_unmask(struct psi_cpp *cpp)
 void psi_cpp_exp_exec(struct psi_cpp_exp *exp, struct psi_cpp *cpp, struct psi_data *D)
 {
        PSI_DEBUG_PRINT(D, "PSI: CPP EVAL < %s (level=%u, skip=%u)\n",
-                       exp->token->text, cpp->level, cpp->skip);
+                       exp->token->text->val, cpp->level, cpp->skip);
 
 #if PSI_CPP_DEBUG
-       psi_cpp_exp_dump(2, exp);
+       PSI_DEBUG_PRINT(cpp->parser, "PSI: CPP exec -> ");
+       PSI_DEBUG_DUMP(cpp->parser, psi_cpp_exp_dump, exp);
 #endif
 
        switch (exp->type) {
        case PSI_T_ERROR:
                if (!cpp->skip) {
                        D->error(D, exp->token, PSI_ERROR, "%s",
-                                       exp->data.tok ? exp->data.tok->text : "");
+                                       exp->data.tok ? exp->data.tok->text->val : "");
                }
                break;
        case PSI_T_WARNING:
                if (!cpp->skip) {
                        D->error(D, exp->token, PSI_WARNING, "%s",
-                                       exp->data.tok ? exp->data.tok->text : "");
+                                       exp->data.tok ? exp->data.tok->text->val : "");
                }
                break;
        case PSI_T_UNDEF:
@@ -293,23 +296,38 @@ void psi_cpp_exp_exec(struct psi_cpp_exp *exp, struct psi_cpp *cpp, struct psi_d
                break;
        case PSI_T_INCLUDE:
                if (!cpp->skip) {
-                       if (!psi_cpp_include(cpp, exp->data.tok->text, PSI_CPP_INCLUDE)) {
-                               D->error(D, exp->token, PSI_WARNING, "Failed to include %s", exp->data.tok->text);
+                       if (!psi_cpp_include(cpp, exp->data.tok, PSI_CPP_INCLUDE)) {
+                               D->error(D, exp->token, PSI_WARNING, "Failed to include %s: %s",
+                                               exp->data.tok->text->val, strerror(errno));
                        }
                }
                break;
        case PSI_T_INCLUDE_NEXT:
                if (!cpp->skip) {
-                       if (!psi_cpp_include(cpp, exp->data.tok->text, PSI_CPP_INCLUDE_NEXT)) {
-                               D->error(D, exp->token, PSI_WARNING, "Failed to include %s", exp->data.tok->text);
+                       if (!psi_cpp_include(cpp, exp->data.tok, PSI_CPP_INCLUDE_NEXT)) {
+                               D->error(D, exp->token, PSI_WARNING, "Failed to include next %s: %s",
+                                               exp->data.tok->text->val, strerror(errno));
                        }
                }
                break;
+       case PSI_T_IMPORT:
+               if (!cpp->skip) {
+                       if (!psi_cpp_include(cpp, exp->data.tok, PSI_CPP_INCLUDE_ONCE)) {
+                               D->error(D, exp->token, PSI_WARNING, "Failed to include once %s: %s",
+                                               exp->data.tok->text->val, strerror(errno));
+                       }
+               }
+               break;
+       case PSI_T_PRAGMA_ONCE:
+               if (!cpp->skip) {
+                       zend_hash_add_empty_element(&cpp->once, exp->token->file);
+               }
+               break;
        default:
                assert(0);
                break;
        }
 
        PSI_DEBUG_PRINT(D, "PSI: CPP EVAL > %s (level=%u, skip=%u)\n",
-                       exp->token->text, cpp->level, cpp->skip);
+                       exp->token->text->val, cpp->level, cpp->skip);
 }