preproc: Handle curly braces in multi-line macro parameters

Multi-line macro uses curly braces for enclosing a parameter
containing comma(s). Passing curly braces as a part of a parameter
which is already enclosed with braces confuses the macro expander.

The number of braces in a group parameter is counted and any brace
in the outmost enclosing braces is treated as a part of parameter.
	e.g.) mmacro {1,2,3}, {4,{5,6}}
	      mmacro gets 2 parameters of '1,2,3' and '4,{5,6}'

Signed-off-by: Jin Kyu Song <jin.kyu.song@intel.com>
This commit is contained in:
Jin Kyu Song 2013-11-27 20:52:16 -08:00
parent 28f95668e0
commit 5eac14bb0e

View File

@ -1632,19 +1632,24 @@ static void count_mmac_params(Token * t, int *nparam, Token *** params)
*params = nasm_realloc(*params, sizeof(**params) * paramsize); *params = nasm_realloc(*params, sizeof(**params) * paramsize);
} }
skip_white_(t); skip_white_(t);
brace = false; brace = 0;
if (tok_is_(t, "{")) if (tok_is_(t, "{"))
brace = true; brace++;
(*params)[(*nparam)++] = t; (*params)[(*nparam)++] = t;
while (tok_isnt_(t, brace ? "}" : ",")) if (brace) {
t = t->next; while (brace && (t = t->next) != NULL) {
if (t) { /* got a comma/brace */ if (tok_is_(t, "{"))
t = t->next; brace++;
if (brace) { else if (tok_is_(t, "}"))
brace--;
}
if (t) {
/* /*
* Now we've found the closing brace, look further * Now we've found the closing brace, look further
* for the comma. * for the comma.
*/ */
t = t->next;
skip_white_(t); skip_white_(t);
if (tok_isnt_(t, ",")) { if (tok_isnt_(t, ",")) {
error(ERR_NONFATAL, error(ERR_NONFATAL,
@ -1652,9 +1657,13 @@ static void count_mmac_params(Token * t, int *nparam, Token *** params)
while (tok_isnt_(t, ",")) while (tok_isnt_(t, ","))
t = t->next; t = t->next;
} }
if (t)
t = t->next; /* eat the comma */
} }
} else {
while (tok_isnt_(t, ","))
t = t->next;
}
if (t) { /* got a comma/brace */
t = t->next; /* eat the comma */
} }
} }
} }
@ -4640,13 +4649,13 @@ static int expand_mmacro(Token * tline)
paramlen = nparam ? nasm_malloc(nparam * sizeof(*paramlen)) : NULL; paramlen = nparam ? nasm_malloc(nparam * sizeof(*paramlen)) : NULL;
for (i = 0; params[i]; i++) { for (i = 0; params[i]; i++) {
int brace = false; int brace = 0;
int comma = (!m->plus || i < nparam - 1); int comma = (!m->plus || i < nparam - 1);
t = params[i]; t = params[i];
skip_white_(t); skip_white_(t);
if (tok_is_(t, "{")) if (tok_is_(t, "{"))
t = t->next, brace = true, comma = false; t = t->next, brace++, comma = false;
params[i] = t; params[i] = t;
paramlen[i] = 0; paramlen[i] = 0;
while (t) { while (t) {
@ -4655,11 +4664,18 @@ static int expand_mmacro(Token * tline)
if (comma && t->type == TOK_WHITESPACE if (comma && t->type == TOK_WHITESPACE
&& tok_is_(t->next, ",")) && tok_is_(t->next, ","))
break; /* ... or a space then a comma */ break; /* ... or a space then a comma */
if (brace && t->type == TOK_OTHER && !strcmp(t->text, "}")) if (brace && t->type == TOK_OTHER) {
break; /* ... or a brace */ if (t->text[0] == '{')
brace++; /* ... or a nested opening brace */
else if (t->text[0] == '}')
if (!--brace)
break; /* ... or a brace */
}
t = t->next; t = t->next;
paramlen[i]++; paramlen[i]++;
} }
if (brace)
error(ERR_NONFATAL, "macro params should be enclosed in braces");
} }
/* /*