preproc: fix %{:} macro operand ranges
Fix the handling of %{:} macro operands. Use the same code for expanding the subarguments as for normal arguments. This (hopefully) resolves the following bug reports: BR 3392611, BR 3392686, BR 3392688 Reported-by: <coconutfaistoslimeregistry@gmail.com> Reported-by: Jasper Lievisse Adriaanse <r+nasm@jasper.la> Reported-by: Jason Hood <jadoxa@yahoo.com.au> Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
This commit is contained in:
parent
5c85b7f87b
commit
e99a946390
2 changed files with 165 additions and 64 deletions
|
@ -4835,17 +4835,15 @@ static int mmac_rotate(const MMacro *mac, unsigned int n)
|
|||
/*
|
||||
* expands to a list of tokens from %{x:y}
|
||||
*/
|
||||
static Token *expand_mmac_params_range(MMacro *mac, Token *tline, Token ***last)
|
||||
void expand_mmac_params_range(MMacro *mac, Token *tline, Token ***tail)
|
||||
{
|
||||
Token *t = tline, **tt, *tm, *head;
|
||||
char *pos;
|
||||
int fst, lst, j, i;
|
||||
Token *t;
|
||||
const char *arg = tok_text(tline) + 1;
|
||||
int fst, lst, incr, n;
|
||||
int parsed;
|
||||
|
||||
pos = strchr(tok_text(tline), ':');
|
||||
nasm_assert(pos);
|
||||
|
||||
lst = atoi(pos + 1);
|
||||
fst = atoi(tok_text(tline) + 1);
|
||||
parsed = sscanf(arg, "%d:%d", &fst, &lst);
|
||||
nasm_assert(parsed == 2);
|
||||
|
||||
/*
|
||||
* only macros params are accounted so
|
||||
|
@ -4863,56 +4861,28 @@ static Token *expand_mmac_params_range(MMacro *mac, Token *tline, Token ***last)
|
|||
fst = fst < 0 ? fst + (int)mac->nparam + 1: fst;
|
||||
lst = lst < 0 ? lst + (int)mac->nparam + 1: lst;
|
||||
|
||||
/* count from zero */
|
||||
fst--, lst--;
|
||||
|
||||
/*
|
||||
* It will be at least one token. Note we
|
||||
* need to scan params until separator, otherwise
|
||||
* only first token will be passed.
|
||||
* It will be at least one parameter, as we can loop
|
||||
* in either direction.
|
||||
*/
|
||||
j = (fst + mac->rotate) % mac->nparam;
|
||||
tm = mac->params[j+1];
|
||||
if (!tm)
|
||||
goto err;
|
||||
head = dup_Token(NULL, tm);
|
||||
tt = &head->next, tm = tm->next;
|
||||
while (tok_isnt(tm, ',')) {
|
||||
t = dup_Token(NULL, tm);
|
||||
*tt = t, tt = &t->next, tm = tm->next;
|
||||
incr = (fst < lst) ? 1 : -1;
|
||||
|
||||
while (true) {
|
||||
n = mmac_rotate(mac, fst);
|
||||
dup_tlistn(mac->params[n], mac->paramlen[n], tail);
|
||||
if (fst == lst)
|
||||
break;
|
||||
t = make_tok_char(NULL, ',');
|
||||
**tail = t;
|
||||
*tail = &t->next;
|
||||
fst += incr;
|
||||
}
|
||||
|
||||
if (fst < lst) {
|
||||
for (i = fst + 1; i <= lst; i++) {
|
||||
t = make_tok_char(NULL, ',');
|
||||
*tt = t, tt = &t->next;
|
||||
j = (i + mac->rotate) % mac->nparam;
|
||||
tm = mac->params[j+1];
|
||||
while (tok_isnt(tm, ',')) {
|
||||
t = dup_Token(NULL, tm);
|
||||
*tt = t, tt = &t->next, tm = tm->next;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = fst - 1; i >= lst; i--) {
|
||||
t = make_tok_char(NULL, ',');
|
||||
*tt = t, tt = &t->next;
|
||||
j = (i + mac->rotate) % mac->nparam;
|
||||
tm = mac->params[j+1];
|
||||
while (!tok_isnt(tm, ',')) {
|
||||
t = dup_Token(NULL, tm);
|
||||
*tt = t, tt = &t->next, tm = tm->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*last = tt;
|
||||
return head;
|
||||
return;
|
||||
|
||||
err:
|
||||
nasm_nonfatal("`%%{%s}': macro parameters out of range",
|
||||
tok_text(tline) + 1);
|
||||
return NULL;
|
||||
nasm_nonfatal("`%%{%s}': macro parameters out of range", arg);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -4963,16 +4933,9 @@ static Token *expand_mmac_params(Token * tline)
|
|||
}
|
||||
|
||||
if (strchr(text, ':')) {
|
||||
/*
|
||||
* seems we have a parameters range here
|
||||
*/
|
||||
Token *head, **last;
|
||||
head = expand_mmac_params_range(mac, t, &last);
|
||||
if (head) {
|
||||
*tail = head;
|
||||
*last = tline;
|
||||
text = NULL;
|
||||
}
|
||||
/* It is a range */
|
||||
expand_mmac_params_range(mac, t, &tail);
|
||||
text = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
../../nasm-2.14.xx/test/emptyarg.asm
|
139
test/emptyarg.asm
Normal file
139
test/emptyarg.asm
Normal file
|
@ -0,0 +1,139 @@
|
|||
%define EMPTY
|
||||
|
||||
%macro bar 1
|
||||
db "bar", __LINE__, %0, %1
|
||||
%endmacro
|
||||
|
||||
%macro baz 2
|
||||
db "baz", __LINE__, %0, %1, %2
|
||||
%endmacro
|
||||
|
||||
%macro nothing 0
|
||||
db "nothing", __LINE__, %0
|
||||
%endmacro
|
||||
|
||||
%macro xyzzy 1-2
|
||||
db "xyzzy", __LINE__, %0, %1, %2, %3
|
||||
%endmacro
|
||||
|
||||
%macro vararg 0-*
|
||||
db "vararg", __LINE__, %0
|
||||
%assign %%i 1
|
||||
%rep %0
|
||||
db "vararg arg ", %%i, %1
|
||||
%rotate 1
|
||||
%assign %%i %%i + 1
|
||||
%endrep
|
||||
%endmacro
|
||||
|
||||
%macro defargs 1-5 def2, def3, def4, def5
|
||||
db "defargs", __LINE__, %0, %1, %2, %3, %4, %5
|
||||
%endmacro
|
||||
|
||||
%macro ivar 1
|
||||
vararg %1
|
||||
%endmacro
|
||||
|
||||
%macro foo 1-2
|
||||
db "foo", __LINE__, %0, %1, %2
|
||||
bar %2
|
||||
bar {%2}
|
||||
bar %2,
|
||||
bar {%2},
|
||||
baz %1,%2
|
||||
baz {%1},{%2}
|
||||
nothing %1
|
||||
nothing %2
|
||||
xyzzy "meep",%1,%2,
|
||||
xyzzy "meep","meep",%1,%2
|
||||
xyzzy "alpha","bravo",
|
||||
xyzzy "with","empty",EMPTY
|
||||
%endmacro
|
||||
|
||||
%macro prange1 2-3
|
||||
db %{1:2}, 0%3
|
||||
%endmacro
|
||||
|
||||
%macro prange2 1-3 'two', 'three'
|
||||
db %{1:3}
|
||||
%endmacro
|
||||
|
||||
db 4,
|
||||
nothing
|
||||
nothing 1
|
||||
nothing ; foo
|
||||
nothing EMPTY
|
||||
|
||||
flup: foo 1,2
|
||||
foo 3
|
||||
bar
|
||||
bar EMPTY
|
||||
foo 6,
|
||||
foo 6, ; With space/comment
|
||||
foo 6,EMPTY
|
||||
baz 8,EMPTY
|
||||
foo 6,{}
|
||||
foo ,5
|
||||
|
||||
xyzzy 13,14,15,
|
||||
xyzzy 13,14,15,EMPTY
|
||||
xyzzy 20,21
|
||||
xyzzy 22,23,
|
||||
xyzzy 24,25,EMPTY
|
||||
xyzzy 26,27,,
|
||||
xyzzy 28,29,EMPTY,EMPTY
|
||||
|
||||
vararg
|
||||
vararg EMPTY
|
||||
vararg ,
|
||||
vararg 10
|
||||
vararg 11,
|
||||
vararg 12,EMPTY
|
||||
vararg 13,14,15,
|
||||
vararg 13,14,15,EMPTY
|
||||
vararg 20,21
|
||||
vararg 22,23,
|
||||
vararg 24,25,EMPTY
|
||||
vararg 26,27,,
|
||||
vararg 28,29,EMPTY,EMPTY
|
||||
|
||||
ivar {}
|
||||
ivar {EMPTY}
|
||||
ivar EMPTY
|
||||
ivar ,
|
||||
ivar {,}
|
||||
ivar {60}
|
||||
ivar {61,}
|
||||
ivar {62,EMPTY}
|
||||
ivar {63,64,65,}
|
||||
ivar {63,64,65,EMPTY}
|
||||
ivar {70,71}
|
||||
ivar {72,73,}
|
||||
ivar {74,75,EMPTY}
|
||||
ivar {76,77,,}
|
||||
ivar {78,79,EMPTY,EMPTY}
|
||||
|
||||
defargs EMPTY
|
||||
defargs 91
|
||||
defargs 91,92
|
||||
defargs 91,92,93
|
||||
defargs 91,92,93,94
|
||||
defargs 91,92,93,94,95
|
||||
defargs ,
|
||||
defargs 91,
|
||||
defargs 91,92,
|
||||
defargs 91,92,93,
|
||||
defargs 91,92,93,94,
|
||||
defargs 91,92,93,94,95,
|
||||
|
||||
prange1 101
|
||||
prange1 101, 102
|
||||
prange1 101, 102, 103
|
||||
prange2 121
|
||||
prange2 121, 122
|
||||
prange2 121, 122, 123
|
||||
prange2 {121}
|
||||
prange2 {121,121}
|
||||
prange2 {121},{122}
|
||||
prange2 {121},122,{123}
|
||||
prange2 121,{122,122},123
|
Loading…
Reference in a new issue