From 67c637236a18e7ae3f3086487a88274a89608d10 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Sun, 26 Oct 2008 23:49:00 -0700 Subject: [PATCH] preproc: merge expand_mmac_params() and expand_indirect() These two really need to be done together, in order for constructs such as %[%1] to work properly. Furthermore, fix a token-pasting bug in expand_mmac_params(). Signed-off-by: H. Peter Anvin --- preproc.c | 131 ++++++++++++++------------------------------------------------ 1 file changed, 30 insertions(+), 101 deletions(-) diff --git a/preproc.c b/preproc.c index ea86dcb5..350b293c 100644 --- a/preproc.c +++ b/preproc.c @@ -397,7 +397,6 @@ static Blocks blocks = { NULL, NULL }; static Token *expand_mmac_params(Token * tline); static Token *expand_smacro(Token * tline); static Token *expand_id(Token * tline); -static Token *expand_indirect(Token * tline, int level); static Context *get_ctx(const char *name, bool all_contexts); static void make_tok_num(Token * tok, int64_t val); static void error(int severity, const char *fmt, ...); @@ -2465,13 +2464,10 @@ static int do_directive(Token * tline) * called expand_mmac_params(); however, if we're * processing an %elif we must have been in a * non-emitting mode, which would have inhibited - * the normal invocation of expand_indirect() and - * expand_mmac_params(). Therefore, we have to do it - * explicitly here. + * the normal invocation of expand_mmac_params(). + * Therefore, we have to do it explicitly here. */ - t = expand_indirect(tline->next,0); - t = expand_mmac_params(t); - j = if_condition(expand_mmac_params(t), i); + j = if_condition(expand_mmac_params(tline->next), i); tline->next = NULL; /* it got freed */ istk->conds->state = j < 0 ? COND_NEVER : j ? COND_IF_TRUE : COND_IF_FALSE; @@ -3324,7 +3320,8 @@ static int find_cc(Token * t) /* * Expand MMacro-local things: parameter references (%0, %n, %+n, - * %-n) and MMacro-local identifiers (%%foo). + * %-n) and MMacro-local identifiers (%%foo) as well as + * macro indirection (%[...]). */ static Token *expand_mmac_params(Token * tline) { @@ -3393,8 +3390,7 @@ static Token *expand_mmac_params(Token * tline) conditions[cc]); text = NULL; } else - text = - nasm_strdup(conditions[inverse_ccs[cc]]); + text = nasm_strdup(conditions[inverse_ccs[cc]]); } break; case '+': @@ -3447,6 +3443,19 @@ static Token *expand_mmac_params(Token * tline) t->a.mac = NULL; } continue; + } else if (tline->type == TOK_INDIRECT) { + t = tline; + tline = tline->next; + tt = tokenize(t->text); + tt = expand_mmac_params(tt); + tt = expand_smacro(tt); + *tail = tt; + while (tt) { + tt->a.mac = NULL; /* Necessary? */ + tail = &tt->next; + tt = tt->next; + } + delete_Token(t); } else { t = *tail = tline; tline = tline->next; @@ -3455,13 +3464,17 @@ static Token *expand_mmac_params(Token * tline) } } *tail = NULL; + + /* Now handle token pasting... */ t = thead; - for (; t && (tt = t->next) != NULL; t = t->next) + while (t && (tt = t->next)) { switch (t->type) { case TOK_WHITESPACE: if (tt->type == TOK_WHITESPACE) { t->next = delete_Token(tt); - } + } else { + t = tt; + } break; case TOK_ID: case TOK_NUMBER: @@ -3470,12 +3483,15 @@ static Token *expand_mmac_params(Token * tline) nasm_free(t->text); t->text = tmp; t->next = delete_Token(tt); - } + } else { + t = tt; + } break; default: + t = tt; break; } - + } return thead; } @@ -3902,92 +3918,6 @@ static Token *expand_id(Token * tline) } /* - * Expand indirect tokens, %[...]. Just like expand_smacro(), - * the input is considered destroyed. - * - * XXX: fix duplicated code in this function and in expand_mmac_params() - */ -static Token *expand_indirect(Token * tline, int level) -{ - const int max_indirect_level = 1000; - Token *t, *thead, **tp; - Token *it; - bool skip; - - if (level >= max_indirect_level) { - error(ERR_NONFATAL, "interminable indirect expansion"); - } else { - thead = NULL; - tp = &tline; - while ((t = *tp)) { - if (t->type != TOK_INDIRECT) { - thead = t; - tp = &t->next; - } else { - it = tokenize(t->text); - it = expand_indirect(it, level+1); - it = expand_smacro(it); - while (it) { - skip = false; - switch (thead ? thead->type : TOK_NONE) { - case TOK_WHITESPACE: - skip = (it->type == TOK_WHITESPACE); - break; - case TOK_ID: - case TOK_NUMBER: - if (it->type == thead->type || it->type == TOK_NUMBER) { - char *tmp = nasm_strcat(thead->text, it->text); - nasm_free(thead->text); - thead->text = tmp; - skip = true; - } - break; - default: - break; - } - if (skip) { - it = delete_Token(it); - } else { - *tp = thead = it; - tp = &it->next; - it = it->next; - } - } - - skip = false; - it = t->next; - if (it) { - switch (thead ? thead->type : TOK_NONE) { - case TOK_WHITESPACE: - skip = (it->type == TOK_WHITESPACE); - break; - case TOK_ID: - case TOK_NUMBER: - if (it->type == thead->type || it->type == TOK_NUMBER) { - char *tmp = nasm_strcat(thead->text, it->text); - nasm_free(thead->text); - thead->text = tmp; - skip = true; - } - break; - default: - break; - } - } - if (skip) { - *tp = thead = it->next; - t = delete_Token(t); - } else { - *tp = thead = it; - } - t = delete_Token(t); - } - } - } - return tline; -} - -/* * Determine whether the given line constitutes a multi-line macro * call, and return the MMacro structure called if so. Doesn't have * to check for an initial label - that's taken care of in @@ -4530,7 +4460,6 @@ static char *pp_getline(void) */ if (!defining && !(istk->conds && !emitting(istk->conds->state)) && !(istk->mstk && !istk->mstk->in_progress)) { - tline = expand_indirect(tline,0); tline = expand_mmac_params(tline); } -- 2.11.4.GIT