X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-psi;a=blobdiff_plain;f=src%2Fcpp.c;h=1300d57e9513e5b5a43410386ce5733df2bf47d8;hp=8075cf6b6ea646a21eddb32ba86a321953870ab6;hb=2559f07a178b681dc240e20153ff5abdff54cb34;hpb=7fb50f31e25b1cc307ef59fb9cbfe71e4c2283c5 diff --git a/src/cpp.c b/src/cpp.c index 8075cf6..1300d57 100644 --- a/src/cpp.c +++ b/src/cpp.c @@ -25,6 +25,8 @@ #include "php_psi_stdinc.h" +#include + #include "cpp.h" #include "parser.h" @@ -58,35 +60,37 @@ bool psi_cpp_load_defaults(struct psi_cpp *cpp) if ((predef = psi_parser_open_string(cpp->parser, psi_cpp_predef, sizeof(psi_cpp_predef) - 1))) { bool parsed = psi_parser_parse(cpp->parser, predef); - free(predef); + psi_parser_input_free(&predef); return parsed; } return false; } +#if PSI_CPP_DEBUG static int dump_def(zval *p) { struct psi_cpp_macro_decl *decl = Z_PTR_P(p); if (decl) { - dprintf(2, "#define "); + fflush(stderr); + dprintf(2, "PSI: CPP decl -> #define "); psi_cpp_macro_decl_dump(2, decl); dprintf(2, "\n"); } return ZEND_HASH_APPLY_KEEP; } +#endif void psi_cpp_free(struct psi_cpp **cpp_ptr) { if (*cpp_ptr) { struct psi_cpp *cpp = *cpp_ptr; +#if PSI_CPP_DEBUG + zend_hash_apply(&cpp->defs, dump_def); +#endif *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); @@ -113,8 +117,8 @@ static bool psi_cpp_stage1(struct psi_cpp *cpp) /* line continuations */ if (token->type == PSI_T_EOL) { if (esc) { - psi_cpp_tokiter_del_range(cpp, psi_cpp_tokiter_index(cpp) - 1, 2, true); - psi_cpp_tokiter_prev(cpp); + psi_cpp_tokiter_del_prev(cpp, true); + psi_cpp_tokiter_del_cur(cpp, true); esc = false; continue; } @@ -168,8 +172,9 @@ static bool psi_cpp_stage1(struct psi_cpp *cpp) struct psi_token *no_ws = psi_token_copy(token); no_ws->type = PSI_T_NO_WHITESPACE; - no_ws->text[0] = '\xA0'; - psi_cpp_tokiter_ins_cur(cpp, no_ws); + zend_string_release(no_ws->text); + no_ws->text = zend_string_init_interned("\xA0", 1, 1); + psi_cpp_tokiter_add(cpp, no_ws); continue; } } @@ -180,6 +185,7 @@ static bool psi_cpp_stage1(struct psi_cpp *cpp) } ws = false; + psi_cpp_tokiter_add_cur(cpp); psi_cpp_tokiter_next(cpp); } @@ -261,7 +267,6 @@ static bool psi_cpp_stage2(struct psi_cpp *cpp) } if (cpp->skip) { - /* FIXME: del_range */ if (!do_cpp) { #if PSI_CPP_DEBUG fprintf(stderr, "PSI: CPP skip "); @@ -312,6 +317,7 @@ static bool psi_cpp_stage2(struct psi_cpp *cpp) continue; } + psi_cpp_tokiter_add_cur(cpp); psi_cpp_tokiter_next(cpp); } @@ -325,14 +331,24 @@ bool psi_cpp_process(struct psi_cpp *cpp, struct psi_plist **tokens) bool parsed = false; struct psi_cpp temp = *cpp; - cpp->tokens = *tokens; + cpp->tokens.iter = *tokens; + cpp->tokens.next = NULL; + if (psi_cpp_stage1(cpp) && psi_cpp_stage2(cpp)) { parsed = true; } - *tokens = cpp->tokens; - if (temp.tokens) { - cpp->tokens = temp.tokens; + if (cpp->tokens.next) { + free(cpp->tokens.iter); + cpp->tokens.iter = cpp->tokens.next; + cpp->tokens.next = NULL; + } + + *tokens = cpp->tokens.iter; + + if (temp.tokens.iter) { + cpp->tokens.iter = temp.tokens.iter; + cpp->tokens.next = temp.tokens.next; cpp->index = temp.index; } @@ -344,7 +360,7 @@ bool psi_cpp_defined(struct psi_cpp *cpp, struct psi_token *tok) bool defined; if (tok->type == PSI_T_NAME) { - defined = zend_hash_str_exists(&cpp->defs, tok->text, tok->size); + defined = zend_hash_exists(&cpp->defs, tok->text); } else { defined = false; } @@ -352,8 +368,8 @@ bool psi_cpp_defined(struct psi_cpp *cpp, struct psi_token *tok) #if PSI_CPP_DEBUG fprintf(stderr, "PSI: CPP defined -> %s ", defined ? "true" : "false"); if (defined) { - struct psi_cpp_macro_decl *macro = zend_hash_str_find_ptr(&cpp->defs, tok->text, tok->size); - fprintf(stderr, " @ %s:%u ", macro->token->file, macro->token->line); + struct psi_cpp_macro_decl *macro = zend_hash_find_ptr(&cpp->defs, tok->text); + fprintf(stderr, " @ %s:%u ", macro->token->file->val, macro->token->line); } psi_token_dump(2, tok); #endif @@ -363,28 +379,40 @@ bool psi_cpp_defined(struct psi_cpp *cpp, struct psi_token *tok) void psi_cpp_define(struct psi_cpp *cpp, struct psi_cpp_macro_decl *decl) { - struct psi_cpp_macro_decl *old = zend_hash_str_find_ptr(&cpp->defs, decl->token->text, decl->token->size); + struct psi_cpp_macro_decl *old = zend_hash_find_ptr(&cpp->defs, decl->token->text); if (old && !psi_cpp_macro_decl_equal(old, decl)) { cpp->parser->error(PSI_DATA(cpp->parser), decl->token, PSI_WARNING, - "'%s' redefined", decl->token->text); + "'%s' redefined", decl->token->text->val); cpp->parser->error(PSI_DATA(cpp->parser), old->token, PSI_WARNING, - "'%s' previously defined", old->token->text); + "'%s' previously defined", old->token->text->val); + } +#if PSI_CPP_DEBUG + if (decl->exp) { + fprintf(stderr, "PSI: CPP MACRO num_exp -> %s ", decl->token->text->val); + } else { + fprintf(stderr, "PSI: CPP MACRO decl -> %s ", decl->token->text->val); } - zend_hash_str_update_ptr(&cpp->defs, decl->token->text, decl->token->size, decl); + psi_cpp_macro_decl_dump(2, decl); + fprintf(stderr, "\n"); +#endif + zend_hash_update_ptr(&cpp->defs, decl->token->text, decl); } bool psi_cpp_undef(struct psi_cpp *cpp, struct psi_token *tok) { - return SUCCESS == zend_hash_str_del(&cpp->defs, tok->text, tok->size); + return SUCCESS == zend_hash_del(&cpp->defs, tok->text); } 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; } - 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; @@ -410,16 +438,13 @@ static inline bool try_include(struct psi_cpp *cpp, const char *path, bool *pars size_t num_tokens = psi_plist_count(tokens); ++cpp->expanded; - psi_cpp_tokiter_ins_range(cpp, cpp->index, - num_tokens, psi_plist_eles(tokens)); - /* skip already processed tokens */ - cpp->index += num_tokens; + psi_cpp_tokiter_add_range(cpp, num_tokens, psi_plist_eles(tokens)); free(tokens); } else { psi_plist_free(tokens); } } - free(include); + psi_parser_input_free(&include); zend_hash_str_add_empty_element(&cpp->once, path, strlen(path)); return true; @@ -427,24 +452,48 @@ static inline bool try_include(struct psi_cpp *cpp, const char *path, bool *pars 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->val[0] == '/') { + *path = file->text->val; + } else { + char *dir; + size_t len; + + strncpy(*path, file->file->val, PATH_MAX); + + dir = dirname(*path); + len = strlen(dir); + + assert(len + file->text->len + 1 < PATH_MAX); + + memmove(*path, dir, len); + (*path)[len] = '/'; + memcpy(&(*path)[len + 1], file->text->val, file->text->len + 1); + } +} + +bool psi_cpp_include(struct psi_cpp *cpp, const struct psi_token *file, unsigned flags) { bool parsed = false; - int f_len = strlen(file); - if (!(flags & PSI_CPP_INCLUDE_NEXT) || *file == '/') { + if (file->type == PSI_T_QUOTED_STRING && (!(flags & PSI_CPP_INCLUDE_NEXT) || file->text->val[0] == '/')) { /* 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, strlen(path))) { return true; } - if (try_include(cpp, file, &parsed)) { + if (try_include(cpp, path, &parsed)) { /* found */ return parsed; } } /* look through search paths */ - if (*file != '/') { + if (file->text->val[0] != '/') { char path[PATH_MAX]; const char *sep; int p_len; @@ -458,7 +507,7 @@ bool psi_cpp_include(struct psi_cpp *cpp, const char *file, unsigned flags) } } - if (!(flags & PSI_CPP_INCLUDE_NEXT) || !cpp->search) { + if (!(flags & PSI_CPP_INCLUDE_NEXT)) { cpp->search = PSI_G(search_path); } @@ -468,7 +517,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); - 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, (int) file->text->len, file->text->val))) { if ((flags & PSI_CPP_INCLUDE_ONCE) && zend_hash_str_exists(&cpp->once, path, p_len)) { return true; }