X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=blobdiff_plain;f=ftepp.c;h=d2c01df501d2a1b301d076b06226c3d2043ce5fd;hp=943411eef09c7f5707a2936ae2d5c676448bb360;hb=refs%2Ftags%2Fxonotic-v0.8.1;hpb=ab2a4f1318814843a7a59779468eb677cf31b344 diff --git a/ftepp.c b/ftepp.c index 943411e..d2c01df 100644 --- a/ftepp.c +++ b/ftepp.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012, 2013 + * Copyright (C) 2012, 2013, 2014, 2015 * Wolfgang Bumiller * Dale Weiler * @@ -498,10 +498,29 @@ static bool ftepp_define_body(ftepp_t *ftepp, ppmacro *macro) return true; } +static const char *ftepp_math_constants[][2] = { + { "M_E", "2.7182818284590452354" }, /* e */ + { "M_LOG2E", "1.4426950408889634074" }, /* log_2 e */ + { "M_LOG10E", "0.43429448190325182765" }, /* log_10 e */ + { "M_LN2", "0.69314718055994530942" }, /* log_e 2 */ + { "M_LN10", "2.30258509299404568402" }, /* log_e 10 */ + { "M_PI", "3.14159265358979323846" }, /* pi */ + { "M_PI_2", "1.57079632679489661923" }, /* pi/2 */ + { "M_PI_4", "0.78539816339744830962" }, /* pi/4 */ + { "M_1_PI", "0.31830988618379067154" }, /* 1/pi */ + { "M_2_PI", "0.63661977236758134308" }, /* 2/pi */ + { "M_2_SQRTPI", "1.12837916709551257390" }, /* 2/sqrt(pi) */ + { "M_SQRT2", "1.41421356237309504880" }, /* sqrt(2) */ + { "M_SQRT1_2", "0.70710678118654752440" }, /* 1/sqrt(2) */ + { "M_TAU", "6.28318530717958647692" } /* pi*2 */ +}; + static bool ftepp_define(ftepp_t *ftepp) { ppmacro *macro = NULL; size_t l = ftepp_ctx(ftepp).line; + size_t i; + bool mathconstant = false; (void)ftepp_next(ftepp); if (!ftepp_skipspace(ftepp)) @@ -511,7 +530,25 @@ static bool ftepp_define(ftepp_t *ftepp) case TOKEN_IDENT: case TOKEN_TYPENAME: case TOKEN_KEYWORD: + if (OPTS_FLAG(FTEPP_MATHDEFS)) { + for (i = 0; i < GMQCC_ARRAY_COUNT(ftepp_math_constants); i++) { + if (!strcmp(ftepp_math_constants[i][0], ftepp_tokval(ftepp))) { + mathconstant = true; + break; + } + } + } + macro = ftepp_macro_find(ftepp, ftepp_tokval(ftepp)); + + if (OPTS_FLAG(FTEPP_MATHDEFS)) { + /* user defined ones take precedence */ + if (macro && mathconstant) { + ftepp_macro_delete(ftepp, ftepp_tokval(ftepp)); + macro = NULL; + } + } + if (macro && ftepp->output_on) { if (ftepp_warn(ftepp, WARN_CPP, "redefining `%s`", ftepp_tokval(ftepp))) return false; @@ -666,9 +703,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; @@ -697,6 +734,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; @@ -705,8 +743,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); + } } } @@ -726,6 +769,7 @@ static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *param lex_file *inlex; bool old_inmacro; + bool strip = false; int nextok; @@ -790,6 +834,7 @@ static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *param if (nextok == '#') { /* raw concatenation */ ++o; + strip = true; break; } if ( (nextok == TOKEN_IDENT || @@ -798,6 +843,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; } @@ -808,7 +854,15 @@ static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *param ftepp_out(ftepp, "\n", false); break; default: - ftepp_out(ftepp, out->value, false); + buffer = out->value; + #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 (buffer_stripable(*buffer)) buffer++; + strip = false; + } + ftepp_out(ftepp, buffer, false); break; } } @@ -1407,6 +1461,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); @@ -1414,28 +1469,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); @@ -1811,23 +1894,6 @@ void ftepp_add_macro(ftepp_t *ftepp, const char *name, const char *value) { vec_free (create); } -static const char *ftepp_math_constants[][2] = { - { "M_E", "2.7182818284590452354" }, /* e */ - { "M_LOG2E", "1.4426950408889634074" }, /* log_2 e */ - { "M_LOG10E", "0.43429448190325182765" }, /* log_10 e */ - { "M_LN2", "0.69314718055994530942" }, /* log_e 2 */ - { "M_LN10", "2.30258509299404568402" }, /* log_e 10 */ - { "M_PI", "3.14159265358979323846" }, /* pi */ - { "M_PI_2", "1.57079632679489661923" }, /* pi/2 */ - { "M_PI_4", "0.78539816339744830962" }, /* pi/4 */ - { "M_1_PI", "0.31830988618379067154" }, /* 1/pi */ - { "M_2_PI", "0.63661977236758134308" }, /* 2/pi */ - { "M_2_SQRTPI", "1.12837916709551257390" }, /* 2/sqrt(pi) */ - { "M_SQRT2", "1.41421356237309504880" }, /* sqrt(2) */ - { "M_SQRT1_2", "0.70710678118654752440" }, /* 1/sqrt(2) */ - { "M_TAU", "6.28318530717958647692" } /* pi*2 */ -}; - ftepp_t *ftepp_create() { ftepp_t *ftepp; @@ -1883,9 +1949,12 @@ ftepp_t *ftepp_create() */ ftepp_add_macro(ftepp, "__NULL__", "nil"); - /* add all the math constants */ - for (i = 0; i < GMQCC_ARRAY_COUNT(ftepp_math_constants); i++) - ftepp_add_macro(ftepp, ftepp_math_constants[i][0], ftepp_math_constants[i][1]); + /* add all the math constants if they can be */ + if (OPTS_FLAG(FTEPP_MATHDEFS)) { + for (i = 0; i < GMQCC_ARRAY_COUNT(ftepp_math_constants); i++) + if (!ftepp_macro_find(ftepp, ftepp_math_constants[i][0])) + ftepp_add_macro(ftepp, ftepp_math_constants[i][0], ftepp_math_constants[i][1]); + } return ftepp; }