mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-04-19 07:51:08 +00:00
[qfcc] Improve handling of spaces in macro definitions
Avoids space tokens on either side of ## and after #
This commit is contained in:
parent
5590ea5b75
commit
45e61544bb
3 changed files with 48 additions and 8 deletions
|
@ -69,9 +69,10 @@ typedef struct rua_tok_s {
|
|||
};
|
||||
} rua_tok_t;
|
||||
|
||||
rua_macro_t *rua_start_macro (const char *name, void *scanner);
|
||||
rua_macro_t *rua_start_macro (const char *name, bool params, void *scanner);
|
||||
rua_macro_t *rua_macro_param (rua_macro_t *macro, rua_tok_t *token,
|
||||
void *scanner);
|
||||
rua_macro_t *rua_end_params (rua_macro_t *macro, void *scanner);
|
||||
rua_macro_t *rua_macro_append (rua_macro_t *macro, rua_tok_t *token,
|
||||
void *scanner);
|
||||
void rua_macro_finish (rua_macro_t *macro, void *scanner);
|
||||
|
|
|
@ -151,10 +151,10 @@ directive_list
|
|||
directive
|
||||
: INCLUDE expand string extra_warn
|
||||
| EMBED expand string extra_ignore
|
||||
| DEFINE ID <macro> { $$ = rua_start_macro ($2, scanner); }
|
||||
| DEFINE ID <macro> { $$ = rua_start_macro ($2, false, scanner); }
|
||||
body { rua_macro_finish ($body, scanner); }
|
||||
| DEFINE IDp <macro> { $$ = rua_start_macro ($2, scanner); }
|
||||
params ')' <macro> { $$ = $3; }
|
||||
| DEFINE IDp <macro> { $$ = rua_start_macro ($2, true, scanner); }
|
||||
params ')' <macro> { $$ = rua_end_params ($3, scanner); }
|
||||
body { rua_macro_finish ($body, scanner); }
|
||||
| UNDEF ID extra_warn { rua_undefine ($2, scanner); }
|
||||
| ERROR text { error (0, "%s", $text->str); dstring_delete ($text); }
|
||||
|
|
|
@ -98,6 +98,7 @@ typedef struct rua_extra_s {
|
|||
int start_state;
|
||||
bool preprocessor;
|
||||
bool recording;
|
||||
bool params;
|
||||
qc_yypstate *qc_state;
|
||||
pre_yypstate *pre_state;
|
||||
rua_cond_stack_t cond_stack;
|
||||
|
@ -1086,13 +1087,13 @@ preproc_token (rua_extra_t *extra, int token, rua_tok_t *tok, yyscan_t *scanner)
|
|||
case rua_char:
|
||||
break;
|
||||
case rua_space:
|
||||
if (!extra->recording) {
|
||||
if (!extra->recording || extra->params) {
|
||||
token = -rua_ignore;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (extra->recording) {
|
||||
if (-token != rua_ignore && extra->recording) {
|
||||
tok->token = token;
|
||||
if (token != PRE_EOD && token != ',' && token != ')') {
|
||||
token = PRE_TOKEN;
|
||||
|
@ -1202,9 +1203,10 @@ qc_yyparse (FILE *in)
|
|||
}
|
||||
|
||||
rua_macro_t *
|
||||
rua_start_macro (const char *name, void *scanner)
|
||||
rua_start_macro (const char *name, bool params, void *scanner)
|
||||
{
|
||||
auto extra = qc_yyget_extra (scanner);
|
||||
extra->params = params;
|
||||
extra->recording = true;
|
||||
|
||||
int len = strlen (name);
|
||||
|
@ -1226,10 +1228,34 @@ rua_start_macro (const char *name, void *scanner)
|
|||
return macro;
|
||||
}
|
||||
|
||||
rua_macro_t *
|
||||
rua_end_params (rua_macro_t *macro, void *scanner)
|
||||
{
|
||||
auto extra = qc_yyget_extra (scanner);
|
||||
extra->params = false;
|
||||
return macro;
|
||||
}
|
||||
|
||||
rua_macro_t *
|
||||
rua_macro_append (rua_macro_t *macro, rua_tok_t *token, void *scanner)
|
||||
{
|
||||
rua_expr_t *expr = malloc (sizeof (*expr));
|
||||
if (token->token == -rua_space) {
|
||||
if (!macro->tokens) {
|
||||
// ignore leading space
|
||||
return macro;
|
||||
}
|
||||
auto t = (rua_expr_t *) macro->tail;
|
||||
if (t->token == '#' || t->token == PRE_CONCAT) {
|
||||
// ignore space after '#' and '##'
|
||||
return macro;
|
||||
}
|
||||
}
|
||||
rua_expr_t *expr = (rua_expr_t *) macro->tail;
|
||||
if (token->token != PRE_CONCAT
|
||||
|| !macro->tokens
|
||||
|| expr->token != -rua_space) {
|
||||
expr = malloc (sizeof (*expr));
|
||||
}
|
||||
*expr = (rua_expr_t) {
|
||||
.location = token->location,
|
||||
.textlen = token->textlen,
|
||||
|
@ -1244,6 +1270,10 @@ rua_macro_append (rua_macro_t *macro, rua_tok_t *token, void *scanner)
|
|||
rua_macro_t *
|
||||
rua_macro_param (rua_macro_t *macro, rua_tok_t *token, void *scanner)
|
||||
{
|
||||
if (token->token == -rua_space) {
|
||||
// ignore spaces
|
||||
return macro;
|
||||
}
|
||||
if (token->token != PRE_ID) {
|
||||
error (0, "expected parameter name, found \"%s\"", token->text);
|
||||
return macro;
|
||||
|
@ -1261,6 +1291,15 @@ void
|
|||
rua_macro_finish (rua_macro_t *macro, void *scanner)
|
||||
{
|
||||
if (macro->tokens) {
|
||||
while (((rua_expr_t *) macro->tail)->token == -rua_space) {
|
||||
// space is never added as the first token, so it's guaranteed
|
||||
// there is always at least two tokens
|
||||
rua_expr_t *t;
|
||||
for (t = macro->tokens; t->next->next; t = t->next) continue;
|
||||
free (t->next);
|
||||
t->next = 0;
|
||||
macro->tail = &t->next;
|
||||
}
|
||||
if (macro->tokens->token == PRE_CONCAT
|
||||
|| ((rua_expr_t *) macro->tail)->token == PRE_CONCAT) {
|
||||
error (0, "'##' cannot appear at either end of a macro expansion");
|
||||
|
|
Loading…
Reference in a new issue