[nasm:nasm-2.15.xx] preproc: fix %{:} macro operand ranges

nasm-bot for H. Peter Anvin (Intel) hpa at zytor.com
Tue Jun 30 17:03:12 PDT 2020


Commit-ID:  e99a946390e561804bf624a1e67f25ae34b13dfd
Gitweb:     http://repo.or.cz/w/nasm.git?a=commitdiff;h=e99a946390e561804bf624a1e67f25ae34b13dfd
Author:     H. Peter Anvin (Intel) <hpa at zytor.com>
AuthorDate: Tue, 30 Jun 2020 11:51:41 -0700
Committer:  H. Peter Anvin (Intel) <hpa at zytor.com>
CommitDate: Tue, 30 Jun 2020 11:51:41 -0700

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 at gmail.com>
Reported-by: Jasper Lievisse Adriaanse <r+nasm at jasper.la>
Reported-by: Jason Hood <jadoxa at yahoo.com.au>
Signed-off-by: H. Peter Anvin (Intel) <hpa at zytor.com>


---
 asm/preproc.c     |  87 ++++++++++-----------------------
 test/emptyarg.asm | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 164 insertions(+), 63 deletions(-)

diff --git a/asm/preproc.c b/asm/preproc.c
index 14ca17d3..2165fa12 100644
--- a/asm/preproc.c
+++ b/asm/preproc.c
@@ -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;
-
-    pos = strchr(tok_text(tline), ':');
-    nasm_assert(pos);
+    Token *t;
+    const char *arg = tok_text(tline) + 1;
+    int fst, lst, incr, n;
+    int parsed;
 
-    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;
 
-    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;
-            }
-        }
+    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;
     }
 
-    *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;
             }
 
diff --git a/test/emptyarg.asm b/test/emptyarg.asm
deleted file mode 120000
index 0627dfae..00000000
--- a/test/emptyarg.asm
+++ /dev/null
@@ -1 +0,0 @@
-../../nasm-2.14.xx/test/emptyarg.asm
\ No newline at end of file
diff --git a/test/emptyarg.asm b/test/emptyarg.asm
new file mode 100644
index 00000000..f164fe41
--- /dev/null
+++ b/test/emptyarg.asm
@@ -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


More information about the Nasm-commits mailing list