summaryrefslogtreecommitdiff
path: root/asm/preproc.c
diff options
context:
space:
mode:
Diffstat (limited to 'asm/preproc.c')
-rw-r--r--asm/preproc.c95
1 files changed, 30 insertions, 65 deletions
diff --git a/asm/preproc.c b/asm/preproc.c
index 0a6e2451..eee4d8a9 100644
--- a/asm/preproc.c
+++ b/asm/preproc.c
@@ -345,7 +345,8 @@ static inline bool tok_text_match(const struct Token *a, const struct Token *b)
return a->len == b->len && !memcmp(tok_text(a), tok_text(b), a->len);
}
-static inline bool tok_match(const struct Token *a, const struct Token *b)
+static inline unused bool
+tok_match(const struct Token *a, const struct Token *b)
{
return a->type == b->type && tok_text_match(a, b);
}
@@ -763,7 +764,8 @@ static const char *unquote_token_cstr(Token *t)
* TOK_STRING tokens.
*/
static Token *quote_any_token(Token *t);
-static inline Token *quote_token(Token *t)
+static inline unused
+Token *quote_token(Token *t)
{
if (likely(!tok_is(t, TOK_INTERNAL_STRING)))
return t;
@@ -4886,17 +4888,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
@@ -4914,56 +4914,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;
}
/*
@@ -5014,16 +4986,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;
}
@@ -5999,7 +5964,7 @@ static MMacro *is_mmacro(Token * tline, int *nparamp, Token ***paramsp)
*! The legacy behavior is quite strange and highly context-dependent,
*! and can be disabled with:
*!-
- *! \c %pragma preproc sane_empty_expansion true
+ *! \c %pragma preproc sane_empty_expansion true
*!-
*! It is highly recommended to use this option in new code.
*/