mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2025-01-18 14:21:36 +00:00
## concatenation, -Wpreprocessor warning about redefining macros, #undef
This commit is contained in:
parent
d237ff1736
commit
990450bfe0
3 changed files with 84 additions and 1 deletions
83
ftepp.c
83
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;
|
||||
|
|
1
main.c
1
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);
|
||||
|
||||
|
|
1
opts.def
1
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 */
|
||||
|
|
Loading…
Reference in a new issue