diff options
Diffstat (limited to 'stdscan.c')
-rw-r--r-- | stdscan.c | 110 |
1 files changed, 46 insertions, 64 deletions
@@ -53,8 +53,6 @@ static char *stdscan_bufptr = NULL; static char **stdscan_tempstorage = NULL; static int stdscan_tempsize = 0, stdscan_templen = 0; -static int brace = 0; /* nested brace counter */ -static bool brace_opened = false; /* if brace is just opened */ #define STDSCAN_TEMP_DELTA 256 void stdscan_set(char *str) @@ -110,7 +108,6 @@ static char *stdscan_copy(char *p, int len) /* * a token is enclosed with braces. proper token type will be assigned * accordingly with the token flag. - * a closing brace is treated as an ending character of corresponding token. */ static int stdscan_handle_brace(struct tokenval *tv) { @@ -126,18 +123,6 @@ static int stdscan_handle_brace(struct tokenval *tv) } } - stdscan_bufptr = nasm_skip_spaces(stdscan_bufptr); - - if (stdscan_bufptr[0] == '}') { - stdscan_bufptr ++; /* skip the closing brace */ - brace --; - } else if (stdscan_bufptr[0] != ',') { - /* treat {foo,bar} as {foo}{bar} - * by regarding ',' as a mere separator between decorators - */ - nasm_error(ERR_NONFATAL, "closing brace expected"); - tv->t_type = TOKEN_INVALID; - } return tv->t_type; } @@ -148,23 +133,16 @@ int stdscan(void *private_data, struct tokenval *tv) (void)private_data; /* Don't warn that this parameter is unused */ stdscan_bufptr = nasm_skip_spaces(stdscan_bufptr); - if (!*stdscan_bufptr) { - /* nested brace shouldn't affect following lines */ - brace = 0; + if (!*stdscan_bufptr) return tv->t_type = TOKEN_EOS; - } /* we have a token; either an id, a number or a char */ if (isidstart(*stdscan_bufptr) || - (*stdscan_bufptr == '$' && isidstart(stdscan_bufptr[1])) || - (brace && isidchar(*stdscan_bufptr))) { /* because of {1to8} */ + (*stdscan_bufptr == '$' && isidstart(stdscan_bufptr[1]))) { /* now we've got an identifier */ bool is_sym = false; int token_type; - /* opening brace is followed by any letter */ - brace_opened = false; - if (*stdscan_bufptr == '$') { is_sym = true; stdscan_bufptr++; @@ -172,8 +150,7 @@ int stdscan(void *private_data, struct tokenval *tv) r = stdscan_bufptr++; /* read the entire buffer to advance the buffer pointer but... */ - /* {rn-sae}, {rd-sae}, {ru-sae}, {rz-sae} contain '-' in tokens. */ - while (isidchar(*stdscan_bufptr) || (brace && *stdscan_bufptr == '-')) + while (isidchar(*stdscan_bufptr)) stdscan_bufptr++; /* ... copy only up to IDLEN_MAX-1 characters */ @@ -190,16 +167,11 @@ int stdscan(void *private_data, struct tokenval *tv) * is it actually a register or instruction name, or what? */ token_type = nasm_token_hash(ourcopy, tv); - if (likely(!brace)) { - if (likely(!(tv->t_flag & TFLAG_BRC))) { - /* most of the tokens fall into this case */ - return token_type; - } else { - return tv->t_type = TOKEN_ID; - } + if (likely(!(tv->t_flag & TFLAG_BRC))) { + /* most of the tokens fall into this case */ + return token_type; } else { - /* handle tokens inside braces */ - return stdscan_handle_brace(tv); + return tv->t_type = TOKEN_ID; } } else if (*stdscan_bufptr == '$' && !isnumchar(stdscan_bufptr[1])) { /* @@ -285,6 +257,45 @@ int stdscan(void *private_data, struct tokenval *tv) return tv->t_type = TOKEN_ERRSTR; stdscan_bufptr++; /* Skip final quote */ return tv->t_type = TOKEN_STR; + } else if (*stdscan_bufptr == '{') { + /* now we've got a decorator */ + int token_len; + + stdscan_bufptr = nasm_skip_spaces(stdscan_bufptr); + + r = ++stdscan_bufptr; + /* + * read the entire buffer to advance the buffer pointer + * {rn-sae}, {rd-sae}, {ru-sae}, {rz-sae} contain '-' in tokens. + */ + while (isbrcchar(*stdscan_bufptr)) + stdscan_bufptr++; + + token_len = stdscan_bufptr - r; + + /* ... copy only up to DECOLEN_MAX-1 characters */ + tv->t_charptr = stdscan_copy(r, token_len < DECOLEN_MAX ? + token_len : DECOLEN_MAX - 1); + + stdscan_bufptr = nasm_skip_spaces(stdscan_bufptr); + /* if brace is not closed properly or token is too long */ + if ((*stdscan_bufptr != '}') || (token_len > MAX_KEYWORD)) { + nasm_error(ERR_NONFATAL, + "invalid decorator token inside braces"); + return tv->t_type = TOKEN_INVALID; + } + + stdscan_bufptr++; /* skip closing brace */ + + for (s = tv->t_charptr, r = ourcopy; *s; s++) + *r++ = nasm_tolower(*s); + *r = '\0'; + + /* right, so we have a decorator sitting in temp storage. */ + nasm_token_hash(ourcopy, tv); + + /* handle tokens inside braces */ + return stdscan_handle_brace(tv); } else if (*stdscan_bufptr == ';') { /* a comment has happened - stay */ return tv->t_type = TOKEN_EOS; @@ -324,35 +335,6 @@ int stdscan(void *private_data, struct tokenval *tv) } else if (stdscan_bufptr[0] == '|' && stdscan_bufptr[1] == '|') { stdscan_bufptr += 2; return tv->t_type = TOKEN_DBL_OR; - } else if (stdscan_bufptr[0] == '{') { - stdscan_bufptr ++; /* skip the opening brace */ - brace ++; /* in case of nested braces */ - brace_opened = true; /* brace is just opened */ - return stdscan(private_data, tv); - } else if (stdscan_bufptr[0] == ',' && brace) { - /* - * a comma inside braces should be treated just as a separator. - * this is almost same as an opening brace except increasing counter. - */ - stdscan_bufptr ++; - brace_opened = true; /* brace is just opened */ - return stdscan(private_data, tv); - } else if (stdscan_bufptr[0] == '}') { - stdscan_bufptr ++; /* skip the closing brace */ - if (brace) { - /* unhandled nested closing brace */ - brace --; - /* if brace is closed without any content in it */ - if (brace_opened) { - brace_opened = false; - nasm_error(ERR_NONFATAL, "nothing inside braces"); - } - return stdscan(private_data, tv); - } else { - /* redundant closing brace */ - return tv->t_type = TOKEN_INVALID; - } - return stdscan(private_data, tv); } else /* just an ordinary char */ return tv->t_type = (uint8_t)(*stdscan_bufptr++); } |