/* Lex a number to NUMBER starting at BUFFER->CUR - 1. */ static void lex_number (cpp_reader *pfile, cpp_string *number) { const uchar *cur; const uchar *base; uchar *dest; base = pfile->buffer->cur - 1; do { cur = pfile->buffer->cur; /* N.B. ISIDNUM does not include $. */ while (ISIDNUM (*cur) || *cur == '.' || VALID_SIGN (*cur, cur[-1])) cur++; pfile->buffer->cur = cur; } while (forms_identifier_p (pfile, false)); number->len = cur - base; dest = _cpp_unaligned_alloc (pfile, number->len + 1); memcpy (dest, base, number->len); dest[number->len] = '\0'; number->text = dest; }
int name_needs_quotes (const char *name) { int c; while ((c = *name++) != '\0') if (! ISIDNUM (c) && c != '.' && c != '$') return 1; return 0; }
/* Lex an identifier starting at BUFFER->CUR - 1. */ static cpp_hashnode * lex_identifier (cpp_reader *pfile, const uchar *base) { cpp_hashnode *result; const uchar *cur; do { cur = pfile->buffer->cur; /* N.B. ISIDNUM does not include $. */ while (ISIDNUM (*cur)) cur++; pfile->buffer->cur = cur; } while (forms_identifier_p (pfile, false)); result = (cpp_hashnode *) ht_lookup (pfile->hash_table, base, cur - base, HT_ALLOC); /* Rarely, identifiers require diagnostics when lexed. */ if (__builtin_expect ((result->flags & NODE_DIAGNOSTIC) && !pfile->state.skipping, 0)) { /* It is allowed to poison the same identifier twice. */ if ((result->flags & NODE_POISONED) && !pfile->state.poisoned_ok) cpp_error (pfile, CPP_DL_ERROR, "attempt to use poisoned \"%s\"", NODE_NAME (result)); /* Constraint 6.10.3.5: __VA_ARGS__ should only appear in the replacement list of a variadic macro. */ if (result == pfile->spec_nodes.n__VA_ARGS__ && !pfile->state.va_args_ok) cpp_error (pfile, CPP_DL_PEDWARN, "__VA_ARGS__ can only appear in the expansion" " of a C99 variadic macro"); } return result; }
static int cp_already_canonical (const char *string) { /* Identifier start character [a-zA-Z_]. */ if (!ISIDST (string[0])) return 0; /* These are the only two identifiers which canonicalize to other than themselves or an error: unsigned -> unsigned int and signed -> int. */ if (string[0] == 'u' && strcmp (&string[1], "nsigned") == 0) return 0; else if (string[0] == 's' && strcmp (&string[1], "igned") == 0) return 0; /* Identifier character [a-zA-Z0-9_]. */ while (ISIDNUM (string[1])) string++; if (string[1] == '\0') return 1; else return 0; }
int yylex (void) { char *s; unichar *us; rc_uint_type length; int ch; /* Make sure that rclex_tok is initialized. */ if (! rclex_tok) rclex_tok_add_char (-1); do { do { /* Clear token. */ rclex_tok_pos = 0; rclex_tok[0] = 0; if ((ch = rclex_readch ()) == -1) return -1; if (ch == '\n') ++rc_lineno; } while (ch <= 0x20); switch (ch) { case '#': while ((ch = rclex_peekch ()) != -1 && ch != '\n') rclex_readch (); cpp_line (); ch = IGNORED_TOKEN; break; case '{': ch = IGNORE_CPP (BEG); break; case '}': ch = IGNORE_CPP (END); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': yylval.i.val = read_digit (ch); yylval.i.dword = 0; switch (rclex_peekch ()) { case 'l': case 'L': rclex_readch (); yylval.i.dword = 1; break; } ch = IGNORE_CPP (NUMBER); break; case '"': rclex_string (); ch = IGNORE_CPP ((! rcdata_mode ? QUOTEDSTRING : SIZEDSTRING)); if (ch == IGNORED_TOKEN) break; s = handle_quotes (&length); if (! rcdata_mode) yylval.s = s; else { yylval.ss.length = length; yylval.ss.s = s; } break; case 'L': case 'l': if (rclex_peekch () == '"') { rclex_readch (); rclex_string (); ch = IGNORE_CPP ((! rcdata_mode ? QUOTEDUNISTRING : SIZEDUNISTRING)); if (ch == IGNORED_TOKEN) break; us = handle_uniquotes (&length); if (! rcdata_mode) yylval.uni = us; else { yylval.suni.length = length; yylval.suni.s = us; } break; } /* Fall through. */ default: if (ISIDST (ch) || ch=='$') { while ((ch = rclex_peekch ()) != -1 && (ISIDNUM (ch) || ch == '$' || ch == '.' || ch == ':' || ch == '\\' || ch == '/' || ch == '_' || ch == '-') ) rclex_readch (); ch = IGNORE_CPP (rclex_translatekeyword (rclex_tok)); if (ch == STRING) { s = get_string (strlen (rclex_tok) + 1); strcpy (s, rclex_tok); yylval.s = s; } else if (ch == BLOCK) { const char *hs = NULL; switch (yylex ()) { case STRING: case QUOTEDSTRING: hs = yylval.s; break; case SIZEDSTRING: hs = yylval.s = yylval.ss.s; break; } if (! hs) { rcparse_warning ("BLOCK expects a string as argument."); ch = IGNORED_TOKEN; } else if (! strcmp (hs, "StringFileInfo")) ch = BLOCKSTRINGFILEINFO; else if (! strcmp (hs, "VarFileInfo")) ch = BLOCKVARFILEINFO; } break; } ch = IGNORE_CPP (ch); break; } } while (ch == IGNORED_TOKEN); return ch; }