X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=blobdiff_plain;f=ftepp.c;h=e3e91e7ccdc72d887b409135cdca49d283dff64e;hp=838d0de38d37f9198fbe3fa2e795340e83c09394;hb=ba207cc04caa361d775055cd614ef73cae300872;hpb=2d96b2a3ecb3610493c261c297da8a0ed429cd15 diff --git a/ftepp.c b/ftepp.c index 838d0de..e3e91e7 100644 --- a/ftepp.c +++ b/ftepp.c @@ -68,6 +68,7 @@ typedef struct { char *itemname; char *includename; + bool in_macro; } ftepp_t; /* @@ -634,17 +635,21 @@ static void ftepp_param_out(ftepp_t *ftepp, macroparam *param) } static bool ftepp_preprocess(ftepp_t *ftepp); -static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *params) +static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *params, bool resetline) { char *old_string = ftepp->output_string; + char *inner_string; lex_file *old_lexer = ftepp->lex; size_t vararg_start = vec_size(macro->params); bool retval = true; + bool has_newlines; size_t varargs; size_t o, pi; lex_file *inlex; + bool old_inmacro; + int nextok; if (vararg_start < vec_size(params)) @@ -663,6 +668,7 @@ static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *param case TOKEN_VA_ARGS: if (!macro->variadic) { ftepp_error(ftepp, "internal preprocessor error: TOKEN_VA_ARGS in non-variadic macro"); + vec_free(old_string); return false; } if (!varargs) @@ -722,22 +728,47 @@ static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *param retval = false; goto cleanup; } - ftepp->output_string = old_string; - inlex->line = ftepp->lex->line; + + inlex->line = ftepp->lex->line; inlex->sline = ftepp->lex->sline; - ftepp->lex = inlex; - ftepp_recursion_header(ftepp); + ftepp->lex = inlex; + + old_inmacro = ftepp->in_macro; + ftepp->in_macro = true; + ftepp->output_string = NULL; if (!ftepp_preprocess(ftepp)) { + ftepp->in_macro = old_inmacro; vec_free(ftepp->lex->open_string); - old_string = ftepp->output_string; + vec_free(ftepp->output_string); lex_close(ftepp->lex); retval = false; goto cleanup; } + ftepp->in_macro = old_inmacro; vec_free(ftepp->lex->open_string); - ftepp_recursion_footer(ftepp); - old_string = ftepp->output_string; + lex_close(ftepp->lex); + + inner_string = ftepp->output_string; + ftepp->output_string = old_string; + has_newlines = (strchr(inner_string, '\n') != NULL); + + if (has_newlines && !old_inmacro) + ftepp_recursion_header(ftepp); + + vec_append(ftepp->output_string, vec_size(inner_string), inner_string); + vec_free(inner_string); + + if (has_newlines && !old_inmacro) + ftepp_recursion_footer(ftepp); + + if (resetline && !ftepp->in_macro) { + char lineno[128]; + sprintf(lineno, "\n#pragma line(%lu)\n", (unsigned long)(old_lexer->sline)); + ftepp_out(ftepp, lineno, false); + } + + old_string = ftepp->output_string; cleanup: ftepp->lex = old_lexer; ftepp->output_string = old_string; @@ -749,9 +780,10 @@ static bool ftepp_macro_call(ftepp_t *ftepp, ppmacro *macro) size_t o; macroparam *params = NULL; bool retval = true; + size_t paramline; if (!macro->has_params) { - if (!ftepp_macro_expand(ftepp, macro, NULL)) + if (!ftepp_macro_expand(ftepp, macro, NULL, false)) return false; ftepp_next(ftepp); return true; @@ -767,6 +799,7 @@ static bool ftepp_macro_call(ftepp_t *ftepp, ppmacro *macro) } ftepp_next(ftepp); + paramline = ftepp->lex->sline; if (!ftepp_macro_call_params(ftepp, ¶ms)) return false; @@ -781,7 +814,7 @@ static bool ftepp_macro_call(ftepp_t *ftepp, ppmacro *macro) goto cleanup; } - if (!ftepp_macro_expand(ftepp, macro, params)) + if (!ftepp_macro_expand(ftepp, macro, params, (paramline != ftepp->lex->sline))) retval = false; ftepp_next(ftepp); @@ -1539,7 +1572,7 @@ static bool ftepp_preprocess(ftepp_t *ftepp) break; case TOKEN_WHITE: /* same as default but don't set newline=false */ - ftepp_out(ftepp, ftepp_tokval(ftepp), false); + ftepp_out(ftepp, ftepp_tokval(ftepp), true); ftepp_next(ftepp); break; default: @@ -1652,6 +1685,10 @@ bool ftepp_init() ftepp_add_define(NULL, "__STD_GMQCC__"); sprintf(major, "\"%d\"", GMQCC_VERSION_MAJOR); sprintf(minor, "\"%d\"", GMQCC_VERSION_MINOR); + } else if (opts.standard == COMPILER_QCCX) { + ftepp_add_define(NULL, "__STD_QCCX__"); + sprintf(major, "\"%d\"", GMQCC_VERSION_MAJOR); + sprintf(minor, "\"%d\"", GMQCC_VERSION_MINOR); } else if (opts.standard == COMPILER_QCC) { ftepp_add_define(NULL, "__STD_QCC__"); /* 1.0 */