diff options
author | Cyrill Gorcunov <gorcunov@gmail.com> | 2010-09-25 02:33:20 +0400 |
---|---|---|
committer | Cyrill Gorcunov <gorcunov@gmail.com> | 2010-09-30 22:28:53 +0400 |
commit | 8dcbbd7af0d6d07b455de0b6460dca6db6113553 (patch) | |
tree | 130dd1dbe64c8496bee0b7612a16755adcc7e966 | |
parent | 4402af0c5924aa779e06f0ada4998d4a61c4a0c7 (diff) | |
download | nasm-8dcbbd7af0d6d07b455de0b6460dca6db6113553.tar.gz |
BR30730640: Restore preprocessor token concatenation rules
During nasm-2.06 development we broke the rules for
concatenation of preprocessor tokens (d784a083a3f1).
The former candidates for concatenation were (in terms of RE)
expand_smacro
[(TOK_ID|TOK_PREPROC_ID)][(TOK_ID|TOK_PREPROC_ID|TOK_NUMBER)]
expand_mmac_params
[(TOK_ID|TOK_NUMBER|TOK_FLOAT)][(TOK_ID|TOK_NUMBER|TOK_FLOAT|TOK_OTHER)]
[ nb: review commits ec88c1beac00 , 20a94ad7fe41 and 984279b1dde9 if
you going to change this one ]
Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com>
-rw-r--r-- | preproc.c | 161 |
1 files changed, 73 insertions, 88 deletions
@@ -212,6 +212,8 @@ enum pp_token_type { TOK_MAX = INT_MAX /* Keep compiler from reducing the range */ }; +#define PP_CONCAT_MASK(x) (1 << (x)) + struct Token { Token *next; char *text; @@ -3637,7 +3639,8 @@ static int find_cc(Token * t) return i; } -static bool paste_tokens(Token **head, bool handle_paste_tokens) +static bool paste_tokens(Token **head, int mask_head, int mask_tail, + bool handle_paste_tokens) { Token **tail, *t, *tt; Token **paste_head; @@ -3658,51 +3661,6 @@ static bool paste_tokens(Token **head, bool handle_paste_tokens) tail = &t->next; } break; - case TOK_ID: - case TOK_PREPROC_ID: - case TOK_NUMBER: - case TOK_FLOAT: - { - size_t len = 0; - char *tmp, *p; - - while (tt && (tt->type == TOK_ID || tt->type == TOK_PREPROC_ID || - tt->type == TOK_NUMBER || tt->type == TOK_FLOAT || - tt->type == TOK_OTHER)) { - len += strlen(tt->text); - tt = tt->next; - } - - /* - * 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) { - tail = &t->next; - t = t->next; - } - t->next = tt; /* Attach the remaining token chain */ - - did_paste = true; - } - paste_head = tail; - tail = &t->next; - break; - } case TOK_PASTE: /* %+ */ if (handle_paste_tokens) { /* Zap %+ and whitespace tokens to the right */ @@ -3716,7 +3674,6 @@ static bool paste_tokens(Token **head, bool handle_paste_tokens) tt = t->next; while (tok_type_(tt, TOK_WHITESPACE)) tt = t->next = delete_Token(tt); - if (tt) { tmp = nasm_strcat(t->text, tt->text); delete_Token(t); @@ -3736,9 +3693,51 @@ static bool paste_tokens(Token **head, bool handle_paste_tokens) } /* else fall through */ default: - tail = &t->next; - if (!tok_type_(t->next, TOK_WHITESPACE)) + /* + * Concatenation of tokens might look nontrivial + * but in real it's pretty simple -- the caller + * prepares the masks of tokens to be concatenated + * and we simply find matched sequences and slip + * them together + */ + if (PP_CONCAT_MASK(t->type) & mask_head) { + size_t len = 0; + char *tmp, *p; + + while (tt && (PP_CONCAT_MASK(tt->type) & mask_tail)) { + len += strlen(tt->text); + tt = tt->next; + } + + /* + * 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) { + tail = &t->next; + t = t->next; + } + t->next = tt; /* Attach the remaining token chain */ + did_paste = true; + } paste_head = tail; + tail = &t->next; + } else { + tail = &t->next; + if (!tok_type_(t->next, TOK_WHITESPACE)) + paste_head = tail; + } break; } } @@ -3972,35 +3971,6 @@ static Token *expand_mmac_params(Token * tline) } delete_Token(t); changed = true; - } else if (tline->type == TOK_PREPROC_ID && - tline->text[0] == '%' && - tline->text[1] == '$' && - !tok_type_(tline->next, TOK_WHITESPACE) && - (tok_type_(tline->next, TOK_ID) || - tok_type_(tline->next, TOK_PREPROC_ID) || - tok_type_(tline->next, TOK_NUMBER) || - tok_type_(tline->next, TOK_OTHER) || - tok_type_(tline->next, TOK_FLOAT))) { - /* - * In a sake of backward compatibility we allow - * to expand local single macro that early before - * pasting token code have place - * - * NOTE: that new code MUST use %+ macro to obtain - * same result - */ - t = tline; - tline = tline->next; - tt = tokenize(t->text); - tt = expand_smacro(tt); - *tail = tt; - while (tt) { - tt->a.mac = NULL; - tail = &tt->next; - tt = tt->next; - } - delete_Token(t); - changed = true; } else { t = *tail = tline; tline = tline->next; @@ -4010,8 +3980,16 @@ static Token *expand_mmac_params(Token * tline) } *tail = NULL; - if (changed) - paste_tokens(&thead, false); + if (changed) { + int mask_head = PP_CONCAT_MASK(TOK_ID) | + PP_CONCAT_MASK(TOK_NUMBER) | + PP_CONCAT_MASK(TOK_FLOAT); + int mask_tail = PP_CONCAT_MASK(TOK_ID) | + PP_CONCAT_MASK(TOK_NUMBER) | + PP_CONCAT_MASK(TOK_FLOAT) | + PP_CONCAT_MASK(TOK_OTHER); + paste_tokens(&thead, mask_head, mask_tail, false); + } return thead; } @@ -4322,14 +4300,21 @@ again: * Also we look for %+ tokens and concatenate the tokens before and after * them (without white spaces in between). */ - if (expanded && paste_tokens(&thead, true)) { - /* - * If we concatenated something, *and* we had previously expanded - * an actual macro, scan the lines again for macros... - */ - tline = thead; - expanded = false; - goto again; + if (expanded) { + int mask_head = PP_CONCAT_MASK(TOK_ID) | + PP_CONCAT_MASK(TOK_PREPROC_ID); + int mask_tail = PP_CONCAT_MASK(TOK_ID) | + PP_CONCAT_MASK(TOK_PREPROC_ID) | + PP_CONCAT_MASK(TOK_NUMBER); + if (paste_tokens(&thead, mask_head, mask_tail, true)) { + /* + * If we concatenated something, *and* we had previously expanded + * an actual macro, scan the lines again for macros... + */ + tline = thead; + expanded = false; + goto again; + } } err: |