- return type;
-
-#else
- int c;
- char *p;
- int wide_flag = 0;
- int objc_flag = 0;
- int charconst = 0;
-
- *value = NULL_TREE;
-
- retry:
- c = getch ();
-
- /* Effectively do c = skip_white_space (c)
- but do it faster in the usual cases. */
- while (1)
- switch (c)
- {
- case ' ':
- case '\t':
- case '\f':
- case '\v':
- c = getch ();
- break;
-
- case '\n':
- c = skip_white_space (c);
- default:
- goto found_nonwhite;
- }
- found_nonwhite:
-
- lineno = lex_lineno;
-
- switch (c)
- {
- case EOF:
- return CPP_EOF;
-
- case 'L':
- /* Capital L may start a wide-string or wide-character constant. */
- {
- register int c1 = getch();
- if (c1 == '\'')
- {
- wide_flag = 1;
- goto char_constant;
- }
- if (c1 == '"')
- {
- wide_flag = 1;
- goto string_constant;
- }
- put_back (c1);
- }
- goto letter;
-
- case '@':
- if (!doing_objc_thang)
- goto straychar;
- else
- {
- /* '@' may start a constant string object. */
- register int c1 = getch ();
- if (c1 == '"')
- {
- objc_flag = 1;
- goto string_constant;
- }
- put_back (c1);
- /* Fall through to treat '@' as the start of an identifier. */
- }
-
- case 'A': case 'B': case 'C': case 'D': case 'E':
- case 'F': case 'G': case 'H': case 'I': case 'J':
- case 'K': case 'M': case 'N': case 'O':
- case 'P': case 'Q': case 'R': case 'S': case 'T':
- case 'U': case 'V': case 'W': case 'X': case 'Y':
- case 'Z':
- case 'a': case 'b': case 'c': case 'd': case 'e':
- case 'f': case 'g': case 'h': case 'i': case 'j':
- case 'k': case 'l': case 'm': case 'n': case 'o':
- case 'p': case 'q': case 'r': case 's': case 't':
- case 'u': case 'v': case 'w': case 'x': case 'y':
- case 'z':
- case '_':
- case '$':
- letter:
- p = token_buffer;
- while (ISALNUM (c) || c == '_' || c == '$' || c == '@')
- {
- /* Make sure this char really belongs in an identifier. */
- if (c == '$')
- {
- if (! dollars_in_ident)
- error ("'$' in identifier");
- else if (pedantic)
- pedwarn ("'$' in identifier");
- }
-
- if (p >= token_buffer + maxtoken)
- p = extend_token_buffer (p);
-
- *p++ = c;
- c = getch();
- }
-
- put_back (c);
-
- if (p >= token_buffer + maxtoken)
- p = extend_token_buffer (p);
- *p = 0;
-
- *value = get_identifier (token_buffer);
- return CPP_NAME;
-
- case '.':
- {
- /* It's hard to preserve tokenization on '.' because
- it could be a symbol by itself, or it could be the
- start of a floating point number and cpp won't tell us. */
- int c1 = getch ();
- if (c1 == '.')
- {
- int c2 = getch ();
- if (c2 == '.')
- return CPP_ELLIPSIS;
-
- put_back (c2);
- error ("parse error at '..'");
- }
- else if (c1 == '*' && c_language == clk_cplusplus)
- return CPP_DOT_STAR;
-
- put_back (c1);
- if (ISDIGIT (c1))
- goto number;
- }
- return CPP_DOT;
-
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- number:
- p = token_buffer;
- /* Scan the next preprocessing number. All C numeric constants
- are preprocessing numbers, but not all preprocessing numbers
- are valid numeric constants. Preprocessing numbers fit the
- regular expression \.?[0-9]([0-9a-zA-Z_.]|[eEpP][+-])*
- See C99 section 6.4.8. */
- for (;;)
- {
- if (p >= token_buffer + maxtoken)
- p = extend_token_buffer (p);
-
- *p++ = c;
- c = getch();
-
- if (c == '+' || c == '-')
- {
- int d = p[-1];
- if (d == 'e' || d == 'E' || d == 'p' || d == 'P')
- continue;
- }
- if (ISALNUM (c) || c == '_' || c == '.')
- continue;
- break;
- }
- put_back (c);
-
- *value = lex_number (token_buffer, p - token_buffer);
- return CPP_NUMBER;
-
- case '\'':
- char_constant:
- charconst = 1;
-
- case '"':
- string_constant:
- {
- int delimiter = charconst ? '\'' : '"';
-#ifdef MULTIBYTE_CHARS
- int longest_char = local_mb_cur_max ();
- (void) local_mbtowc (NULL_PTR, NULL_PTR, 0);
-#endif
- c = getch ();
- p = token_buffer + 1;
-
- while (c != delimiter && c != EOF)
- {
- if (p + 2 > token_buffer + maxtoken)
- p = extend_token_buffer (p);
-
- /* ignore_escape_flag is set for reading the filename in #line. */
- if (!ignore_escape_flag && c == '\\')
- {
- *p++ = c;
- *p++ = getch (); /* escaped character */
- c = getch ();
- continue;
- }
- else
- {
-#ifdef MULTIBYTE_CHARS
- int i;
- int char_len = -1;
- for (i = 0; i < longest_char; ++i)
- {
- if (p + i >= token_buffer + maxtoken)
- p = extend_token_buffer (p);
- p[i] = c;
-
- char_len = local_mblen (p, i + 1);
- if (char_len != -1)
- break;
- c = getch ();
- }
- if (char_len == -1)
- {
- /* Replace all except the first byte. */
- put_back (c);
- for (--i; i > 0; --i)
- put_back (p[i]);
- char_len = 1;
- }
- /* mbtowc sometimes needs an extra char before accepting */
- else if (char_len <= i)
- put_back (c);
-
- p += char_len;
-#else
- *p++ = c;
-#endif
- c = getch ();
- }
- }
- }
-
- if (charconst)
- {
- *value = lex_charconst (token_buffer + 1, p - (token_buffer + 1),
- wide_flag);
- return wide_flag ? CPP_WCHAR : CPP_CHAR;
- }
- else
- {
- *value = lex_string (token_buffer + 1, p - (token_buffer + 1),
- wide_flag);
- return wide_flag ? CPP_WSTRING : objc_flag ? CPP_OSTRING : CPP_STRING;
- }
-
- case '+':
- case '-':
- case '&':
- case '|':
- case ':':
- case '<':
- case '>':
- case '*':
- case '/':
- case '%':
- case '^':
- case '!':
- case '=':
- {
- int c1;
- enum cpp_ttype type = CPP_EOF;
-
- switch (c)
- {
- case '+': type = CPP_PLUS; break;
- case '-': type = CPP_MINUS; break;
- case '&': type = CPP_AND; break;
- case '|': type = CPP_OR; break;
- case ':': type = CPP_COLON; break;
- case '<': type = CPP_LESS; break;
- case '>': type = CPP_GREATER; break;
- case '*': type = CPP_MULT; break;
- case '/': type = CPP_DIV; break;
- case '%': type = CPP_MOD; break;
- case '^': type = CPP_XOR; break;
- case '!': type = CPP_NOT; break;
- case '=': type = CPP_EQ; break;
- }
-
- c1 = getch ();
-
- if (c1 == '=' && type < CPP_LAST_EQ)
- return type + (CPP_EQ_EQ - CPP_EQ);
- else if (c == c1)
- switch (c)
- {
- case '+': return CPP_PLUS_PLUS;
- case '-': return CPP_MINUS_MINUS;
- case '&': return CPP_AND_AND;
- case '|': return CPP_OR_OR;
- case ':':
- if (c_language == clk_cplusplus)
- return CPP_SCOPE;
- break;
-
- case '<': type = CPP_LSHIFT; goto do_triad;
- case '>': type = CPP_RSHIFT; goto do_triad;
- }
- else
- switch (c)
- {
- case '-':
- if (c1 == '>')
- {
- if (c_language == clk_cplusplus)
- {
- c1 = getch ();
- if (c1 == '*')
- return CPP_DEREF_STAR;
- put_back (c1);
- }
- return CPP_DEREF;
- }
- break;
-
- case '>':
- if (c1 == '?' && c_language == clk_cplusplus)
- { type = CPP_MAX; goto do_triad; }
- break;
-
- case '<':
- if (c1 == ':' && flag_digraphs)
- return CPP_OPEN_SQUARE;
- if (c1 == '%' && flag_digraphs)
- { indent_level++; return CPP_OPEN_BRACE; }
- if (c1 == '?' && c_language == clk_cplusplus)
- { type = CPP_MIN; goto do_triad; }
- break;
-
- case ':':
- if (c1 == '>' && flag_digraphs)
- return CPP_CLOSE_SQUARE;
- break;
- case '%':
- if (c1 == '>' && flag_digraphs)
- { indent_level--; return CPP_CLOSE_BRACE; }
- break;
- }
-
- put_back (c1);
- return type;
-
- do_triad:
- c1 = getch ();
- if (c1 == '=')
- type += (CPP_EQ_EQ - CPP_EQ);
- else
- put_back (c1);
- return type;
- }
-
- case '~': return CPP_COMPL;
- case '?': return CPP_QUERY;
- case ',': return CPP_COMMA;
- case '(': return CPP_OPEN_PAREN;
- case ')': return CPP_CLOSE_PAREN;
- case '[': return CPP_OPEN_SQUARE;
- case ']': return CPP_CLOSE_SQUARE;
- case '{': indent_level++; return CPP_OPEN_BRACE;
- case '}': indent_level--; return CPP_CLOSE_BRACE;
- case ';': return CPP_SEMICOLON;
-
- straychar:
- default:
- if (ISGRAPH (c))
- error ("stray '%c' in program", c);
- else
- error ("stray '\\%#o' in program", c);
- goto retry;
- }
- /* NOTREACHED */
-#endif