diff options
author | H. Peter Anvin <hpa@zytor.com> | 2009-04-07 21:59:24 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2009-04-07 21:59:24 -0700 |
commit | 9bb46df4b716c5d8c483e66d39d2edb3ceb161f0 (patch) | |
tree | 3692eb5836c0b99b78954aec41c9811d754cc22d /preproc.c | |
parent | 1582d52863ee6f857c1c76e2abe9a413f278e648 (diff) | |
download | nasm-9bb46df4b716c5d8c483e66d39d2edb3ceb161f0.tar.gz nasm-9bb46df4b716c5d8c483e66d39d2edb3ceb161f0.tar.bz2 nasm-9bb46df4b716c5d8c483e66d39d2edb3ceb161f0.zip |
Handle weird cases of token pasting
Especially when token pasting involves floating-point numbers, we can
have some really strange effects from token pasting: for example,
pasting the two tokens "xyzzy" and "1e+10" ends up with *three*
tokens: "xyzzy1e" "+" "10". The easiest way to deal with this is to
explicitly combine the string and then run tokenize() on it.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'preproc.c')
-rw-r--r-- | preproc.c | 53 |
1 files changed, 40 insertions, 13 deletions
@@ -159,7 +159,7 @@ enum pp_token_type { TOK_NUMBER, TOK_FLOAT, TOK_SMAC_END, TOK_OTHER, TOK_INTERNAL_STRING, TOK_PREPROC_Q, TOK_PREPROC_QQ, - TOK_INDIRECT, /* %[...] */ + TOK_INDIRECT, /* %[...] */ TOK_SMAC_PARAM, /* MUST BE LAST IN THE LIST!!! */ TOK_MAX = INT_MAX /* Keep compiler from reducing the range */ }; @@ -3467,29 +3467,56 @@ static Token *expand_mmac_params(Token * tline) *tail = NULL; /* Now handle token pasting... */ - t = thead; - while (t && (tt = t->next)) { + tail = &thead; + while ((t = *tail) && (tt = t->next)) { switch (t->type) { case TOK_WHITESPACE: if (tt->type == TOK_WHITESPACE) { t->next = delete_Token(tt); } else { - t = tt; + tail = &t->next; } break; case TOK_ID: case TOK_NUMBER: - if (tt->type == t->type || tt->type == TOK_NUMBER) { - char *tmp = nasm_strcat(t->text, tt->text); - nasm_free(t->text); - t->text = tmp; - t->next = delete_Token(tt); - } else { - t = tt; + case TOK_FLOAT: + { + size_t len = 0; + char *tmp, *p; + + while (tt && + (tt->type == TOK_ID || tt->type == TOK_NUMBER || + tt->type == TOK_FLOAT)) { + len += strlen(tt->text); + tt = tt->next; } - break; + + /* Now tt points to the first token after the potential + paste area... */ + if (tt != t->next) { + /* We have at least two tokens... */ + len += strlen(t->text); + p = tmp = nasm_malloc(len+1); + + while (t != tt) { + strcpy(p, t->text); + p = strchr(p, '\0'); + t = delete_Token(t); + } + + t = *tail = tokenize(tmp); + nasm_free(tmp); + + while (t->next) + t = t->next; + + t->next = tt; /* Attach the remaining token chain */ + } + tail = &t->next; + break; + } default: - t = tt; + tail = &t->next; break; } } |