- }
-
- /* single-character tokens */
- switch (ch)
- {
- case '(':
- if (!lex_tokench(lex, ch) ||
- !lex_endtoken(lex))
- {
- return (lex->tok->ttype = TOKEN_FATAL);
- }
- if (lex->flags.noops)
- return (lex->tok->ttype = ch);
- else
- return (lex->tok->ttype = TOKEN_OPERATOR);
- case ')':
- case ';':
- case '{':
- case '}':
- case '[':
- case ']':
-
- case '#':
- if (!lex_tokench(lex, ch) ||
- !lex_endtoken(lex))
- {
- return (lex->tok->ttype = TOKEN_FATAL);
- }
- return (lex->tok->ttype = ch);
- default:
- break;
- }
-
- if (lex->flags.noops)
- {
- /* Detect characters early which are normally
- * operators OR PART of an operator.
- */
- switch (ch)
- {
- case '+':
- case '-':
- case '*':
- case '/':
- case '<':
- case '>':
- case '=':
- case '&':
- case '|':
- case '^':
- case '~':
- case ',':
- case '.':
- case '!':
- if (!lex_tokench(lex, ch) ||
- !lex_endtoken(lex))
- {
- return (lex->tok->ttype = TOKEN_FATAL);
- }
- return (lex->tok->ttype = ch);
- default:
- break;
- }
- }
-
- if (ch == ',' || ch == '.') {
- if (!lex_tokench(lex, ch) ||
- !lex_endtoken(lex))
- {
- return (lex->tok->ttype = TOKEN_FATAL);
- }
- return (lex->tok->ttype = TOKEN_OPERATOR);
- }
-
- if (ch == '+' || ch == '-' || /* ++, --, +=, -= and -> as well! */
- ch == '>' || ch == '<' || /* <<, >>, <=, >= */
- ch == '=' || ch == '!' || /* ==, != */
- ch == '&' || ch == '|') /* &&, ||, &=, |= */
- {
- if (!lex_tokench(lex, ch))
- return (lex->tok->ttype = TOKEN_FATAL);
-
- nextch = lex_getch(lex);
- if (nextch == ch || nextch == '=') {
- if (!lex_tokench(lex, nextch))
- return (lex->tok->ttype = TOKEN_FATAL);
- } else if (ch == '-' && nextch == '>') {
- if (!lex_tokench(lex, nextch))
- return (lex->tok->ttype = TOKEN_FATAL);
- } else
- lex_ungetch(lex, nextch);
-
- if (!lex_endtoken(lex))
- return (lex->tok->ttype = TOKEN_FATAL);
- return (lex->tok->ttype = TOKEN_OPERATOR);
- }
+ }
+
+ /* single-character tokens */
+ switch (ch)
+ {
+ case '[':
+ nextch = lex_getch(lex);
+ if (nextch == '[') {
+ lex_tokench(lex, ch);
+ lex_tokench(lex, nextch);
+ lex_endtoken(lex);
+ return (lex->tok.ttype = TOKEN_ATTRIBUTE_OPEN);
+ }
+ lex_ungetch(lex, nextch);
+ /* FALL THROUGH */
+ case '(':
+ case ':':
+ case '?':
+ lex_tokench(lex, ch);
+ lex_endtoken(lex);
+ if (lex->flags.noops)
+ return (lex->tok.ttype = ch);
+ else
+ return (lex->tok.ttype = TOKEN_OPERATOR);
+
+ case ']':
+ if (lex->flags.noops) {
+ nextch = lex_getch(lex);
+ if (nextch == ']') {
+ lex_tokench(lex, ch);
+ lex_tokench(lex, nextch);
+ lex_endtoken(lex);
+ return (lex->tok.ttype = TOKEN_ATTRIBUTE_CLOSE);
+ }
+ lex_ungetch(lex, nextch);
+ }
+ /* FALL THROUGH */
+ case ')':
+ case ';':
+ case '{':
+ case '}':
+
+ case '#':
+ lex_tokench(lex, ch);
+ lex_endtoken(lex);
+ return (lex->tok.ttype = ch);
+ default:
+ break;
+ }
+
+ if (ch == '.') {
+ nextch = lex_getch(lex);
+ /* digits starting with a dot */
+ if (isdigit(nextch)) {
+ lex_ungetch(lex, nextch);
+ lex->tok.ttype = lex_finish_digit(lex, ch);
+ lex_endtoken(lex);
+ return lex->tok.ttype;
+ }
+ lex_ungetch(lex, nextch);
+ }
+
+ if (lex->flags.noops)
+ {
+ /* Detect characters early which are normally
+ * operators OR PART of an operator.
+ */
+ switch (ch)
+ {
+ /*
+ case '+':
+ case '-':
+ */
+ case '*':
+ case '/':
+ case '<':
+ case '>':
+ case '=':
+ case '&':
+ case '|':
+ case '^':
+ case '~':
+ case ',':
+ case '!':
+ lex_tokench(lex, ch);
+ lex_endtoken(lex);
+ return (lex->tok.ttype = ch);
+ default:
+ break;
+ }
+ }
+
+ if (ch == '.')
+ {
+ lex_tokench(lex, ch);
+ /* peak ahead once */
+ nextch = lex_getch(lex);
+ if (nextch != '.') {
+ lex_ungetch(lex, nextch);
+ lex_endtoken(lex);
+ if (lex->flags.noops)
+ return (lex->tok.ttype = ch);
+ else
+ return (lex->tok.ttype = TOKEN_OPERATOR);
+ }
+ /* peak ahead again */
+ nextch = lex_getch(lex);
+ if (nextch != '.') {
+ lex_ungetch(lex, nextch);
+ lex_ungetch(lex, '.');
+ lex_endtoken(lex);
+ if (lex->flags.noops)
+ return (lex->tok.ttype = ch);
+ else
+ return (lex->tok.ttype = TOKEN_OPERATOR);
+ }
+ /* fill the token to be "..." */
+ lex_tokench(lex, ch);
+ lex_tokench(lex, ch);
+ lex_endtoken(lex);
+ return (lex->tok.ttype = TOKEN_DOTS);
+ }
+
+ if (ch == ',' || ch == '.') {
+ lex_tokench(lex, ch);
+ lex_endtoken(lex);
+ return (lex->tok.ttype = TOKEN_OPERATOR);
+ }
+
+ if (ch == '+' || ch == '-' || /* ++, --, +=, -= and -> as well! */
+ ch == '>' || ch == '<' || /* <<, >>, <=, >= */
+ ch == '=' || ch == '!' || /* <=>, ==, != */
+ ch == '&' || ch == '|' || /* &&, ||, &=, |= */
+ ch == '~' /* ~=, ~ */
+ ) {
+ lex_tokench(lex, ch);
+
+ nextch = lex_getch(lex);
+ if ((nextch == '=' && ch != '<') || (nextch == ch && ch != '!')) {
+ lex_tokench(lex, nextch);
+ } else if (ch == '<' && nextch == '=') {
+ lex_tokench(lex, nextch);
+ if ((thirdch = lex_getch(lex)) == '>')
+ lex_tokench(lex, thirdch);
+ else
+ lex_ungetch(lex, thirdch);
+
+ } else if (ch == '-' && nextch == '>') {
+ lex_tokench(lex, nextch);
+ } else if (ch == '&' && nextch == '~') {
+ thirdch = lex_getch(lex);
+ if (thirdch != '=') {
+ lex_ungetch(lex, thirdch);
+ lex_ungetch(lex, nextch);
+ }
+ else {
+ lex_tokench(lex, nextch);
+ lex_tokench(lex, thirdch);
+ }
+ }
+ else if (lex->flags.preprocessing &&
+ ch == '-' && isdigit(nextch))
+ {
+ lex->tok.ttype = lex_finish_digit(lex, nextch);
+ if (lex->tok.ttype == TOKEN_INTCONST)
+ lex->tok.constval.i = -lex->tok.constval.i;
+ else
+ lex->tok.constval.f = -lex->tok.constval.f;
+ lex_endtoken(lex);
+ return lex->tok.ttype;
+ } else {
+ lex_ungetch(lex, nextch);
+ }
+
+ lex_endtoken(lex);
+ return (lex->tok.ttype = TOKEN_OPERATOR);
+ }