diff options
author | H. Peter Anvin <hpa@zytor.com> | 2008-10-19 16:24:53 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2008-10-19 16:24:53 -0700 |
commit | c0ab1cd15a8008d820ebbeedb04c53bc84afd995 (patch) | |
tree | 9d4a6d48f52ff49e8b2912801ebe4114d7238445 | |
parent | 992fe7591dca84b0ec5c779dad2f17b46b8ddd84 (diff) | |
download | nasm-c0ab1cd15a8008d820ebbeedb04c53bc84afd995.tar.gz |
preproc: fix list iteration in the case of expand_indirect()
Linked lists where an element may be deleted or substituted during
processing can be subtle to deal with. Fix the iteration conditions
in this particular case.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r-- | preproc.c | 71 |
1 files changed, 37 insertions, 34 deletions
@@ -3901,7 +3901,8 @@ static Token *expand_id(Token * tline) } /* - * Expand indirect tokens, %[...]. + * Expand indirect tokens, %[...]. Just like expand_smacro(), + * the input is considered destroyed. */ static Token *expand_indirect(Token * tline, int level) { @@ -3914,42 +3915,44 @@ static Token *expand_indirect(Token * tline, int level) error(ERR_NONFATAL, "interminable indirect expansion"); } else { thead = NULL; - for (tp = &tline; (t = *tp); thead = t, tp = &t->next) { - if (t->type != TOK_INDIRECT) - continue; - it = tokenize(t->text); - it = expand_indirect(it, level+1); - it = expand_smacro(it); - while (it) { - skip = false; - switch (thead ? thead->type : TOK_NONE) { - case TOK_WHITESPACE: - skip = (it->type == TOK_WHITESPACE); - break; - - case TOK_ID: - case TOK_NUMBER: - if (it->type == thead->type || it->type == TOK_NUMBER) { - char *tmp = nasm_strcat(thead->text, it->text); - thead->text = tmp; - skip = true; + tp = &tline; + while ((t = *tp)) { + if (t->type != TOK_INDIRECT) { + thead = t; + tp = &t->next; + } else { + it = tokenize(t->text); + it = expand_indirect(it, level+1); + it = expand_smacro(it); + while (it) { + skip = false; + switch (thead ? thead->type : TOK_NONE) { + case TOK_WHITESPACE: + skip = (it->type == TOK_WHITESPACE); + break; + case TOK_ID: + case TOK_NUMBER: + if (it->type == thead->type || it->type == TOK_NUMBER) { + char *tmp = nasm_strcat(thead->text, it->text); + nasm_free(thead->text); + thead->text = tmp; + skip = true; + } + break; + default: + break; + } + if (skip) { + it = delete_Token(it); + } else { + *tp = thead = it; + tp = &it->next; + it = it->next; } - break; - - default: - break; - } - - if (skip) { - it = delete_Token(it); - } else { - *tp = thead = it; - tp = &it->next; - it = it->next; } + *tp = thead = t->next; + t = delete_Token(t); } - *tp = t->next; - delete_Token(t); } } return tline; |