X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=blobdiff_plain;f=ftepp.c;h=1c80d9ed6f27287e71ddcd10b976da81f08cf6e8;hp=c574f03bb99d518191a243a8155e60f41a9e7c76;hb=a7b45ea14dd05ac141f7f220568fa4757ff98a03;hpb=f1650c42d950400b41be53af2da1ad9867642df4 diff --git a/ftepp.c b/ftepp.c index c574f03..1c80d9e 100644 --- a/ftepp.c +++ b/ftepp.c @@ -1,26 +1,3 @@ -/* - * Copyright (C) 2012, 2013, 2014 - * Wolfgang Bumiller - * Dale Weiler - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is furnished to do - * so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ #include #include #include @@ -251,13 +228,7 @@ static pptoken *pptoken_make(ftepp_t *ftepp) { pptoken *token = (pptoken*)mem_a(sizeof(pptoken)); token->token = ftepp->token; -#if 0 - if (token->token == TOKEN_WHITE) - token->value = util_strdup(" "); - else -#else - token->value = util_strdup(ftepp_tokval(ftepp)); -#endif + token->value = util_strdup(ftepp_tokval(ftepp)); memcpy(&token->constval, &ftepp->lex->tok.constval, sizeof(token->constval)); return token; } @@ -703,9 +674,9 @@ static void ftepp_stringify_token(ftepp_t *ftepp, pptoken *token) ++ch; } break; - case TOKEN_WHITE: + /*case TOKEN_WHITE: ftepp_out(ftepp, " ", false); - break; + break;*/ case TOKEN_EOL: ftepp_out(ftepp, "\\n", false); break; @@ -734,6 +705,7 @@ static void ftepp_recursion_footer(ftepp_t *ftepp) ftepp_out(ftepp, "\n#pragma pop(line)\n", false); } +static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *params, bool resetline); static void ftepp_param_out(ftepp_t *ftepp, macroparam *param) { size_t i; @@ -742,8 +714,13 @@ static void ftepp_param_out(ftepp_t *ftepp, macroparam *param) out = param->tokens[i]; if (out->token == TOKEN_EOL) ftepp_out(ftepp, "\n", false); - else - ftepp_out(ftepp, out->value, false); + else { + ppmacro *find = ftepp_macro_find(ftepp, out->value); + if (OPTS_FLAG(FTEPP_INDIRECT_EXPANSION) && find && !find->has_params) + ftepp_macro_expand(ftepp, find, NULL, false); + else + ftepp_out(ftepp, out->value, false); + } } } @@ -837,7 +814,7 @@ static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *param macro_params_find(macro, macro->output[o+1]->value, &pi)) { ++o; - + ftepp_stringify(ftepp, ¶ms[pi]); break; } @@ -849,10 +826,11 @@ static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *param break; default: buffer = out->value; - if (vec_size(macro->output) > o + 1 && macro->output[o+1]->token == '#') + #define buffer_stripable(X) ((X) == ' ' || (X) == '\t') + if (vec_size(macro->output) > o + 1 && macro->output[o+1]->token == '#' && buffer_stripable(*buffer)) buffer++; if (strip) { - while (util_isspace(*buffer)) buffer++; + while (buffer_stripable(*buffer)) buffer++; strip = false; } ftepp_out(ftepp, buffer, false); @@ -1316,7 +1294,7 @@ static void unescape(const char *str, char *out) { static char *ftepp_include_find_path(const char *file, const char *pathfile) { - fs_file_t *fp; + FILE *fp; char *filename = NULL; const char *last_slash; size_t len; @@ -1336,9 +1314,9 @@ static char *ftepp_include_find_path(const char *file, const char *pathfile) memcpy(vec_add(filename, len+1), file, len); vec_last(filename) = 0; - fp = fs_file_open(filename, "rb"); + fp = fopen(filename, "rb"); if (fp) { - fs_file_close(fp); + fclose(fp); return filename; } vec_free(filename); @@ -1454,6 +1432,7 @@ static bool ftepp_include(ftepp_t *ftepp) lex_ctx_t ctx; char lineno[128]; char *filename; + char *parsename = NULL; char *old_includename; (void)ftepp_next(ftepp); @@ -1461,28 +1440,56 @@ static bool ftepp_include(ftepp_t *ftepp) return false; if (ftepp->token != TOKEN_STRINGCONST) { - ftepp_error(ftepp, "expected filename to include"); - return false; + ppmacro *macro = ftepp_macro_find(ftepp, ftepp_tokval(ftepp)); + if (macro) { + char *backup = ftepp->output_string; + ftepp->output_string = NULL; + if (ftepp_macro_expand(ftepp, macro, NULL, true)) { + parsename = util_strdup(ftepp->output_string); + vec_free(ftepp->output_string); + ftepp->output_string = backup; + } else { + ftepp->output_string = backup; + ftepp_error(ftepp, "expected filename to include"); + return false; + } + } else if (OPTS_FLAG(FTEPP_PREDEFS)) { + /* Well it could be a predefine like __LINE__ */ + char *(*predef)(ftepp_t*) = ftepp_predef(ftepp_tokval(ftepp)); + if (predef) { + parsename = predef(ftepp); + } else { + ftepp_error(ftepp, "expected filename to include"); + return false; + } + } } if (!ftepp->output_on) { - ftepp_next(ftepp); + (void)ftepp_next(ftepp); return true; } - ctx = ftepp_ctx(ftepp); - - unescape(ftepp_tokval(ftepp), ftepp_tokval(ftepp)); + if (parsename) + unescape(parsename, parsename); + else { + char *tokval = ftepp_tokval(ftepp); + unescape(tokval, tokval); + parsename = util_strdup(tokval); + } + ctx = ftepp_ctx(ftepp); ftepp_out(ftepp, "\n#pragma file(", false); - ftepp_out(ftepp, ftepp_tokval(ftepp), false); + ftepp_out(ftepp, parsename, false); ftepp_out(ftepp, ")\n#pragma line(1)\n", false); - filename = ftepp_include_find(ftepp, ftepp_tokval(ftepp)); + filename = ftepp_include_find(ftepp, parsename); if (!filename) { - ftepp_error(ftepp, "failed to open include file `%s`", ftepp_tokval(ftepp)); + ftepp_error(ftepp, "failed to open include file `%s`", parsename); + mem_d(parsename); return false; } + mem_d(parsename); inlex = lex_open(filename); if (!inlex) { ftepp_error(ftepp, "open failed on include file `%s`", filename); @@ -1718,10 +1725,6 @@ static bool ftepp_preprocess(ftepp_t *ftepp) { if (ftepp->token >= TOKEN_EOF) break; -#if 0 - newline = true; -#endif - switch (ftepp->token) { case TOKEN_KEYWORD: case TOKEN_IDENT: