From: Wolfgang (Blub) Bumiller Date: Fri, 16 Nov 2012 21:54:59 +0000 (+0100) Subject: ## concatenation, -Wpreprocessor warning about redefining macros, #undef X-Git-Tag: 0.1.9~404^2~30 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=990450bfe02839007bf2364d918df5168e4b37a7;p=xonotic%2Fgmqcc.git ## concatenation, -Wpreprocessor warning about redefining macros, #undef --- diff --git a/ftepp.c b/ftepp.c index ba8829d..1a2ff21 100644 --- a/ftepp.c +++ b/ftepp.c @@ -91,6 +91,25 @@ static void ftepp_error(ftepp_t *ftepp, const char *fmt, ...) va_end(ap); } +static bool GMQCC_WARN ftepp_warn(ftepp_t *ftepp, int warntype, const char *fmt, ...) +{ + va_list ap; + int lvl = LVL_WARNING; + + if (!OPTS_WARN(warntype)) + return false; + + if (opts_werror) { + lvl = LVL_ERROR; + ftepp->errors++; + } + + va_start(ap, fmt); + con_vprintmsg(lvl, ftepp->lex->tok.ctx.file, ftepp->lex->tok.ctx.line, "error", fmt, ap); + va_end(ap); + return opts_werror; +} + static pptoken *pptoken_make(ftepp_t *ftepp) { pptoken *token = (pptoken*)mem_a(sizeof(pptoken)); @@ -187,6 +206,17 @@ static ppmacro* ftepp_macro_find(ftepp_t *ftepp, const char *name) return NULL; } +static void ftepp_macro_delete(ftepp_t *ftepp, const char *name) +{ + size_t i; + for (i = 0; i < vec_size(ftepp->macros); ++i) { + if (!strcmp(name, ftepp->macros[i]->name)) { + vec_remove(ftepp->macros, i, 1); + return; + } + } +} + static inline int ftepp_next(ftepp_t *ftepp) { return (ftepp->token = lex_do(ftepp->lex)); @@ -281,6 +311,12 @@ static bool ftepp_define(ftepp_t *ftepp) case TOKEN_IDENT: case TOKEN_TYPENAME: case TOKEN_KEYWORD: + macro = ftepp_macro_find(ftepp, ftepp_tokval(ftepp)); + if (macro) { + if (ftepp_warn(ftepp, WARN_PREPROCESSOR, "redefining `%s`", ftepp_tokval(ftepp))) + return false; + ftepp_macro_delete(ftepp, ftepp_tokval(ftepp)); + } macro = ppmacro_new(ftepp_ctx(ftepp), ftepp_tokval(ftepp)); break; default: @@ -435,6 +471,14 @@ static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *param } } break; + case '#': + if (o + 1 < vec_size(macro->output) && macro->output[o+1]->token == '#') { + /* raw concatenation */ + ++o; + break; + } + ftepp_out(ftepp, "#", false); + break; case TOKEN_EOL: ftepp_out(ftepp, "\n", false); break; @@ -704,14 +748,48 @@ static bool ftepp_ifdef(ftepp_t *ftepp, ppcondition *cond) (void)ftepp_next(ftepp); if (!ftepp_skipspace(ftepp)) return false; - if (ftepp->token != TOKEN_EOL) { + /* relaxing this condition + if (ftepp->token != TOKEN_EOL && ftepp->token != TOKEN_EOF) { ftepp_error(ftepp, "stray tokens after #ifdef"); return false; } + */ cond->on = !!macro; return true; } +/** + * undef is also simple + */ +static bool ftepp_undef(ftepp_t *ftepp) +{ + (void)ftepp_next(ftepp); + if (!ftepp_skipspace(ftepp)) + return false; + + switch (ftepp->token) { + case TOKEN_IDENT: + case TOKEN_TYPENAME: + case TOKEN_KEYWORD: + ftepp_macro_delete(ftepp, ftepp_tokval(ftepp)); + break; + default: + ftepp_error(ftepp, "expected macro name"); + return false; + } + + (void)ftepp_next(ftepp); + if (!ftepp_skipspace(ftepp)) + return false; + /* relaxing this condition + if (ftepp->token != TOKEN_EOL && ftepp->token != TOKEN_EOF) { + ftepp_error(ftepp, "stray tokens after #ifdef"); + return false; + } + */ + return true; +} + /* Basic structure handlers */ static bool ftepp_else_allowed(ftepp_t *ftepp) { @@ -743,6 +821,9 @@ static bool ftepp_hash(ftepp_t *ftepp) if (!strcmp(ftepp_tokval(ftepp), "define")) { return ftepp_define(ftepp); } + else if (!strcmp(ftepp_tokval(ftepp), "undef")) { + return ftepp_undef(ftepp); + } else if (!strcmp(ftepp_tokval(ftepp), "ifdef")) { if (!ftepp_ifdef(ftepp, &cond)) return false; diff --git a/main.c b/main.c index ba4cba0..1c11b27 100644 --- a/main.c +++ b/main.c @@ -435,6 +435,7 @@ int main(int argc, char **argv) { options_set(opts_warn, WARN_EFFECTLESS_STATEMENT, true); options_set(opts_warn, WARN_END_SYS_FIELDS, true); options_set(opts_warn, WARN_ASSIGN_FUNCTION_TYPES, true); + options_set(opts_warn, WARN_PREPROCESSOR, true); options_set(opts_flags, ADJUST_VECTOR_FIELDS, true); diff --git a/opts.def b/opts.def index e628f43..1c362d3 100644 --- a/opts.def +++ b/opts.def @@ -52,6 +52,7 @@ GMQCC_DEFINE_FLAG(EFFECTLESS_STATEMENT) GMQCC_DEFINE_FLAG(END_SYS_FIELDS) GMQCC_DEFINE_FLAG(ASSIGN_FUNCTION_TYPES) + GMQCC_DEFINE_FLAG(PREPROCESSOR) #endif /* some cleanup so we don't have to */