aboutsummaryrefslogtreecommitdiffstats
path: root/lcc/src/lex.c
diff options
context:
space:
mode:
authorzakk <zakk@edf5b092-35ff-0310-97b2-ce42778d08ea>2005-08-26 17:39:27 +0000
committerzakk <zakk@edf5b092-35ff-0310-97b2-ce42778d08ea>2005-08-26 17:39:27 +0000
commit6bf20c78f5b69d40bcc4931df93d29198435ab67 (patch)
treee3eda937a05d7db42de725b7013bd0344b987f34 /lcc/src/lex.c
parent872d4d7f55af706737ffb361bb76ad13e7496770 (diff)
downloadioquake3-aero-6bf20c78f5b69d40bcc4931df93d29198435ab67.tar.gz
ioquake3-aero-6bf20c78f5b69d40bcc4931df93d29198435ab67.zip
newlines fixed
git-svn-id: svn://svn.icculus.org/quake3/trunk@6 edf5b092-35ff-0310-97b2-ce42778d08ea
Diffstat (limited to 'lcc/src/lex.c')
-rwxr-xr-xlcc/src/lex.c1844
1 files changed, 922 insertions, 922 deletions
diff --git a/lcc/src/lex.c b/lcc/src/lex.c
index 09c50f3..6643172 100755
--- a/lcc/src/lex.c
+++ b/lcc/src/lex.c
@@ -1,922 +1,922 @@
-#include "c.h"
-#include <float.h>
-#include <errno.h>
-
-
-#define MAXTOKEN 32
-
-enum { BLANK=01, NEWLINE=02, LETTER=04,
- DIGIT=010, HEX=020, OTHER=040 };
-
-static unsigned char map[256] = { /* 000 nul */ 0,
- /* 001 soh */ 0,
- /* 002 stx */ 0,
- /* 003 etx */ 0,
- /* 004 eot */ 0,
- /* 005 enq */ 0,
- /* 006 ack */ 0,
- /* 007 bel */ 0,
- /* 010 bs */ 0,
- /* 011 ht */ BLANK,
- /* 012 nl */ NEWLINE,
- /* 013 vt */ BLANK,
- /* 014 ff */ BLANK,
- /* 015 cr */ 0,
- /* 016 so */ 0,
- /* 017 si */ 0,
- /* 020 dle */ 0,
- /* 021 dc1 */ 0,
- /* 022 dc2 */ 0,
- /* 023 dc3 */ 0,
- /* 024 dc4 */ 0,
- /* 025 nak */ 0,
- /* 026 syn */ 0,
- /* 027 etb */ 0,
- /* 030 can */ 0,
- /* 031 em */ 0,
- /* 032 sub */ 0,
- /* 033 esc */ 0,
- /* 034 fs */ 0,
- /* 035 gs */ 0,
- /* 036 rs */ 0,
- /* 037 us */ 0,
- /* 040 sp */ BLANK,
- /* 041 ! */ OTHER,
- /* 042 " */ OTHER,
- /* 043 # */ OTHER,
- /* 044 $ */ 0,
- /* 045 % */ OTHER,
- /* 046 & */ OTHER,
- /* 047 ' */ OTHER,
- /* 050 ( */ OTHER,
- /* 051 ) */ OTHER,
- /* 052 * */ OTHER,
- /* 053 + */ OTHER,
- /* 054 , */ OTHER,
- /* 055 - */ OTHER,
- /* 056 . */ OTHER,
- /* 057 / */ OTHER,
- /* 060 0 */ DIGIT,
- /* 061 1 */ DIGIT,
- /* 062 2 */ DIGIT,
- /* 063 3 */ DIGIT,
- /* 064 4 */ DIGIT,
- /* 065 5 */ DIGIT,
- /* 066 6 */ DIGIT,
- /* 067 7 */ DIGIT,
- /* 070 8 */ DIGIT,
- /* 071 9 */ DIGIT,
- /* 072 : */ OTHER,
- /* 073 ; */ OTHER,
- /* 074 < */ OTHER,
- /* 075 = */ OTHER,
- /* 076 > */ OTHER,
- /* 077 ? */ OTHER,
- /* 100 @ */ 0,
- /* 101 A */ LETTER|HEX,
- /* 102 B */ LETTER|HEX,
- /* 103 C */ LETTER|HEX,
- /* 104 D */ LETTER|HEX,
- /* 105 E */ LETTER|HEX,
- /* 106 F */ LETTER|HEX,
- /* 107 G */ LETTER,
- /* 110 H */ LETTER,
- /* 111 I */ LETTER,
- /* 112 J */ LETTER,
- /* 113 K */ LETTER,
- /* 114 L */ LETTER,
- /* 115 M */ LETTER,
- /* 116 N */ LETTER,
- /* 117 O */ LETTER,
- /* 120 P */ LETTER,
- /* 121 Q */ LETTER,
- /* 122 R */ LETTER,
- /* 123 S */ LETTER,
- /* 124 T */ LETTER,
- /* 125 U */ LETTER,
- /* 126 V */ LETTER,
- /* 127 W */ LETTER,
- /* 130 X */ LETTER,
- /* 131 Y */ LETTER,
- /* 132 Z */ LETTER,
- /* 133 [ */ OTHER,
- /* 134 \ */ OTHER,
- /* 135 ] */ OTHER,
- /* 136 ^ */ OTHER,
- /* 137 _ */ LETTER,
- /* 140 ` */ 0,
- /* 141 a */ LETTER|HEX,
- /* 142 b */ LETTER|HEX,
- /* 143 c */ LETTER|HEX,
- /* 144 d */ LETTER|HEX,
- /* 145 e */ LETTER|HEX,
- /* 146 f */ LETTER|HEX,
- /* 147 g */ LETTER,
- /* 150 h */ LETTER,
- /* 151 i */ LETTER,
- /* 152 j */ LETTER,
- /* 153 k */ LETTER,
- /* 154 l */ LETTER,
- /* 155 m */ LETTER,
- /* 156 n */ LETTER,
- /* 157 o */ LETTER,
- /* 160 p */ LETTER,
- /* 161 q */ LETTER,
- /* 162 r */ LETTER,
- /* 163 s */ LETTER,
- /* 164 t */ LETTER,
- /* 165 u */ LETTER,
- /* 166 v */ LETTER,
- /* 167 w */ LETTER,
- /* 170 x */ LETTER,
- /* 171 y */ LETTER,
- /* 172 z */ LETTER,
- /* 173 { */ OTHER,
- /* 174 | */ OTHER,
- /* 175 } */ OTHER,
- /* 176 ~ */ OTHER, };
-static struct symbol tval;
-static char cbuf[BUFSIZE+1];
-static unsigned int wcbuf[BUFSIZE+1];
-
-Coordinate src; /* current source coordinate */
-int t;
-char *token; /* current token */
-Symbol tsym; /* symbol table entry for current token */
-
-static void *cput(int c, void *cl);
-static void *wcput(int c, void *cl);
-static void *scon(int q, void *put(int c, void *cl), void *cl);
-static int backslash(int q);
-static Symbol fcon(void);
-static Symbol icon(unsigned long, int, int);
-static void ppnumber(char *);
-
-int gettok(void) {
- for (;;) {
- register unsigned char *rcp = cp;
- while (map[*rcp]&BLANK)
- rcp++;
- if (limit - rcp < MAXTOKEN) {
- cp = rcp;
- fillbuf();
- rcp = cp;
- }
- src.file = file;
- src.x = (char *)rcp - line;
- src.y = lineno;
- cp = rcp + 1;
- switch (*rcp++) {
- case '/': if (*rcp == '*') {
- int c = 0;
- for (rcp++; *rcp != '/' || c != '*'; )
- if (map[*rcp]&NEWLINE) {
- if (rcp < limit)
- c = *rcp;
- cp = rcp + 1;
- nextline();
- rcp = cp;
- if (rcp == limit)
- break;
- } else
- c = *rcp++;
- if (rcp < limit)
- rcp++;
- else
- error("unclosed comment\n");
- cp = rcp;
- continue;
- }
- return '/';
- case '<':
- if (*rcp == '=') return cp++, LEQ;
- if (*rcp == '<') return cp++, LSHIFT;
- return '<';
- case '>':
- if (*rcp == '=') return cp++, GEQ;
- if (*rcp == '>') return cp++, RSHIFT;
- return '>';
- case '-':
- if (*rcp == '>') return cp++, DEREF;
- if (*rcp == '-') return cp++, DECR;
- return '-';
- case '=': return *rcp == '=' ? cp++, EQL : '=';
- case '!': return *rcp == '=' ? cp++, NEQ : '!';
- case '|': return *rcp == '|' ? cp++, OROR : '|';
- case '&': return *rcp == '&' ? cp++, ANDAND : '&';
- case '+': return *rcp == '+' ? cp++, INCR : '+';
- case ';': case ',': case ':':
- case '*': case '~': case '%': case '^': case '?':
- case '[': case ']': case '{': case '}': case '(': case ')':
- return rcp[-1];
- case '\n': case '\v': case '\r': case '\f':
- nextline();
- if (cp == limit) {
- tsym = NULL;
- return EOI;
- }
- continue;
-
- case 'i':
- if (rcp[0] == 'f'
- && !(map[rcp[1]]&(DIGIT|LETTER))) {
- cp = rcp + 1;
- return IF;
- }
- if (rcp[0] == 'n'
- && rcp[1] == 't'
- && !(map[rcp[2]]&(DIGIT|LETTER))) {
- cp = rcp + 2;
- tsym = inttype->u.sym;
- return INT;
- }
- goto id;
- case 'h': case 'j': case 'k': case 'm': case 'n': case 'o':
- case 'p': case 'q': 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 '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':
- id:
- if (limit - rcp < MAXLINE) {
- cp = rcp - 1;
- fillbuf();
- rcp = ++cp;
- }
- assert(cp == rcp);
- token = (char *)rcp - 1;
- while (map[*rcp]&(DIGIT|LETTER))
- rcp++;
- token = stringn(token, (char *)rcp - token);
- tsym = lookup(token, identifiers);
- cp = rcp;
- return ID;
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9': {
- unsigned long n = 0;
- if (limit - rcp < MAXLINE) {
- cp = rcp - 1;
- fillbuf();
- rcp = ++cp;
- }
- assert(cp == rcp);
- token = (char *)rcp - 1;
- if (*token == '0' && (*rcp == 'x' || *rcp == 'X')) {
- int d, overflow = 0;
- while (*++rcp) {
- if (map[*rcp]&DIGIT)
- d = *rcp - '0';
- else if (*rcp >= 'a' && *rcp <= 'f')
- d = *rcp - 'a' + 10;
- else if (*rcp >= 'A' && *rcp <= 'F')
- d = *rcp - 'A' + 10;
- else
- break;
- if (n&~(~0UL >> 4))
- overflow = 1;
- else
- n = (n<<4) + d;
- }
- if ((char *)rcp - token <= 2)
- error("invalid hexadecimal constant `%S'\n", token, (char *)rcp-token);
- cp = rcp;
- tsym = icon(n, overflow, 16);
- } else if (*token == '0') {
- int err = 0, overflow = 0;
- for ( ; map[*rcp]&DIGIT; rcp++) {
- if (*rcp == '8' || *rcp == '9')
- err = 1;
- if (n&~(~0UL >> 3))
- overflow = 1;
- else
- n = (n<<3) + (*rcp - '0');
- }
- if (*rcp == '.' || *rcp == 'e' || *rcp == 'E') {
- cp = rcp;
- tsym = fcon();
- return FCON;
- }
- cp = rcp;
- tsym = icon(n, overflow, 8);
- if (err)
- error("invalid octal constant `%S'\n", token, (char*)cp-token);
- } else {
- int overflow = 0;
- for (n = *token - '0'; map[*rcp]&DIGIT; ) {
- int d = *rcp++ - '0';
- if (n > (ULONG_MAX - d)/10)
- overflow = 1;
- else
- n = 10*n + d;
- }
- if (*rcp == '.' || *rcp == 'e' || *rcp == 'E') {
- cp = rcp;
- tsym = fcon();
- return FCON;
- }
- cp = rcp;
- tsym = icon(n, overflow, 10);
- }
- return ICON;
- }
- case '.':
- if (rcp[0] == '.' && rcp[1] == '.') {
- cp += 2;
- return ELLIPSIS;
- }
- if ((map[*rcp]&DIGIT) == 0)
- return '.';
- if (limit - rcp < MAXLINE) {
- cp = rcp - 1;
- fillbuf();
- rcp = ++cp;
- }
- assert(cp == rcp);
- cp = rcp - 1;
- token = (char *)cp;
- tsym = fcon();
- return FCON;
- case 'L':
- if (*rcp == '\'') {
- unsigned int *s = scon(*cp, wcput, wcbuf);
- if (s - wcbuf > 2)
- warning("excess characters in wide-character literal ignored\n");
- tval.type = widechar;
- tval.u.c.v.u = wcbuf[0];
- tsym = &tval;
- return ICON;
- } else if (*rcp == '"') {
- unsigned int *s = scon(*cp, wcput, wcbuf);
- tval.type = array(widechar, s - wcbuf, 0);
- tval.u.c.v.p = wcbuf;
- tsym = &tval;
- return SCON;
- } else
- goto id;
- case '\'': {
- char *s = scon(*--cp, cput, cbuf);
- if (s - cbuf > 2)
- warning("excess characters in multibyte character literal ignored\n");
- tval.type = inttype;
- if (chartype->op == INT)
- tval.u.c.v.i = extend(cbuf[0], chartype);
- else
- tval.u.c.v.i = cbuf[0]&0xFF;
- tsym = &tval;
- return ICON;
- }
- case '"': {
- char *s = scon(*--cp, cput, cbuf);
- tval.type = array(chartype, s - cbuf, 0);
- tval.u.c.v.p = cbuf;
- tsym = &tval;
- return SCON;
- }
- case 'a':
- if (rcp[0] == 'u'
- && rcp[1] == 't'
- && rcp[2] == 'o'
- && !(map[rcp[3]]&(DIGIT|LETTER))) {
- cp = rcp + 3;
- return AUTO;
- }
- goto id;
- case 'b':
- if (rcp[0] == 'r'
- && rcp[1] == 'e'
- && rcp[2] == 'a'
- && rcp[3] == 'k'
- && !(map[rcp[4]]&(DIGIT|LETTER))) {
- cp = rcp + 4;
- return BREAK;
- }
- goto id;
- case 'c':
- if (rcp[0] == 'a'
- && rcp[1] == 's'
- && rcp[2] == 'e'
- && !(map[rcp[3]]&(DIGIT|LETTER))) {
- cp = rcp + 3;
- return CASE;
- }
- if (rcp[0] == 'h'
- && rcp[1] == 'a'
- && rcp[2] == 'r'
- && !(map[rcp[3]]&(DIGIT|LETTER))) {
- cp = rcp + 3;
- tsym = chartype->u.sym;
- return CHAR;
- }
- if (rcp[0] == 'o'
- && rcp[1] == 'n'
- && rcp[2] == 's'
- && rcp[3] == 't'
- && !(map[rcp[4]]&(DIGIT|LETTER))) {
- cp = rcp + 4;
- return CONST;
- }
- if (rcp[0] == 'o'
- && rcp[1] == 'n'
- && rcp[2] == 't'
- && rcp[3] == 'i'
- && rcp[4] == 'n'
- && rcp[5] == 'u'
- && rcp[6] == 'e'
- && !(map[rcp[7]]&(DIGIT|LETTER))) {
- cp = rcp + 7;
- return CONTINUE;
- }
- goto id;
- case 'd':
- if (rcp[0] == 'e'
- && rcp[1] == 'f'
- && rcp[2] == 'a'
- && rcp[3] == 'u'
- && rcp[4] == 'l'
- && rcp[5] == 't'
- && !(map[rcp[6]]&(DIGIT|LETTER))) {
- cp = rcp + 6;
- return DEFAULT;
- }
- if (rcp[0] == 'o'
- && rcp[1] == 'u'
- && rcp[2] == 'b'
- && rcp[3] == 'l'
- && rcp[4] == 'e'
- && !(map[rcp[5]]&(DIGIT|LETTER))) {
- cp = rcp + 5;
- tsym = doubletype->u.sym;
- return DOUBLE;
- }
- if (rcp[0] == 'o'
- && !(map[rcp[1]]&(DIGIT|LETTER))) {
- cp = rcp + 1;
- return DO;
- }
- goto id;
- case 'e':
- if (rcp[0] == 'l'
- && rcp[1] == 's'
- && rcp[2] == 'e'
- && !(map[rcp[3]]&(DIGIT|LETTER))) {
- cp = rcp + 3;
- return ELSE;
- }
- if (rcp[0] == 'n'
- && rcp[1] == 'u'
- && rcp[2] == 'm'
- && !(map[rcp[3]]&(DIGIT|LETTER))) {
- cp = rcp + 3;
- return ENUM;
- }
- if (rcp[0] == 'x'
- && rcp[1] == 't'
- && rcp[2] == 'e'
- && rcp[3] == 'r'
- && rcp[4] == 'n'
- && !(map[rcp[5]]&(DIGIT|LETTER))) {
- cp = rcp + 5;
- return EXTERN;
- }
- goto id;
- case 'f':
- if (rcp[0] == 'l'
- && rcp[1] == 'o'
- && rcp[2] == 'a'
- && rcp[3] == 't'
- && !(map[rcp[4]]&(DIGIT|LETTER))) {
- cp = rcp + 4;
- tsym = floattype->u.sym;
- return FLOAT;
- }
- if (rcp[0] == 'o'
- && rcp[1] == 'r'
- && !(map[rcp[2]]&(DIGIT|LETTER))) {
- cp = rcp + 2;
- return FOR;
- }
- goto id;
- case 'g':
- if (rcp[0] == 'o'
- && rcp[1] == 't'
- && rcp[2] == 'o'
- && !(map[rcp[3]]&(DIGIT|LETTER))) {
- cp = rcp + 3;
- return GOTO;
- }
- goto id;
- case 'l':
- if (rcp[0] == 'o'
- && rcp[1] == 'n'
- && rcp[2] == 'g'
- && !(map[rcp[3]]&(DIGIT|LETTER))) {
- cp = rcp + 3;
- return LONG;
- }
- goto id;
- case 'r':
- if (rcp[0] == 'e'
- && rcp[1] == 'g'
- && rcp[2] == 'i'
- && rcp[3] == 's'
- && rcp[4] == 't'
- && rcp[5] == 'e'
- && rcp[6] == 'r'
- && !(map[rcp[7]]&(DIGIT|LETTER))) {
- cp = rcp + 7;
- return REGISTER;
- }
- if (rcp[0] == 'e'
- && rcp[1] == 't'
- && rcp[2] == 'u'
- && rcp[3] == 'r'
- && rcp[4] == 'n'
- && !(map[rcp[5]]&(DIGIT|LETTER))) {
- cp = rcp + 5;
- return RETURN;
- }
- goto id;
- case 's':
- if (rcp[0] == 'h'
- && rcp[1] == 'o'
- && rcp[2] == 'r'
- && rcp[3] == 't'
- && !(map[rcp[4]]&(DIGIT|LETTER))) {
- cp = rcp + 4;
- return SHORT;
- }
- if (rcp[0] == 'i'
- && rcp[1] == 'g'
- && rcp[2] == 'n'
- && rcp[3] == 'e'
- && rcp[4] == 'd'
- && !(map[rcp[5]]&(DIGIT|LETTER))) {
- cp = rcp + 5;
- return SIGNED;
- }
- if (rcp[0] == 'i'
- && rcp[1] == 'z'
- && rcp[2] == 'e'
- && rcp[3] == 'o'
- && rcp[4] == 'f'
- && !(map[rcp[5]]&(DIGIT|LETTER))) {
- cp = rcp + 5;
- return SIZEOF;
- }
- if (rcp[0] == 't'
- && rcp[1] == 'a'
- && rcp[2] == 't'
- && rcp[3] == 'i'
- && rcp[4] == 'c'
- && !(map[rcp[5]]&(DIGIT|LETTER))) {
- cp = rcp + 5;
- return STATIC;
- }
- if (rcp[0] == 't'
- && rcp[1] == 'r'
- && rcp[2] == 'u'
- && rcp[3] == 'c'
- && rcp[4] == 't'
- && !(map[rcp[5]]&(DIGIT|LETTER))) {
- cp = rcp + 5;
- return STRUCT;
- }
- if (rcp[0] == 'w'
- && rcp[1] == 'i'
- && rcp[2] == 't'
- && rcp[3] == 'c'
- && rcp[4] == 'h'
- && !(map[rcp[5]]&(DIGIT|LETTER))) {
- cp = rcp + 5;
- return SWITCH;
- }
- goto id;
- case 't':
- if (rcp[0] == 'y'
- && rcp[1] == 'p'
- && rcp[2] == 'e'
- && rcp[3] == 'd'
- && rcp[4] == 'e'
- && rcp[5] == 'f'
- && !(map[rcp[6]]&(DIGIT|LETTER))) {
- cp = rcp + 6;
- return TYPEDEF;
- }
- goto id;
- case 'u':
- if (rcp[0] == 'n'
- && rcp[1] == 'i'
- && rcp[2] == 'o'
- && rcp[3] == 'n'
- && !(map[rcp[4]]&(DIGIT|LETTER))) {
- cp = rcp + 4;
- return UNION;
- }
- if (rcp[0] == 'n'
- && rcp[1] == 's'
- && rcp[2] == 'i'
- && rcp[3] == 'g'
- && rcp[4] == 'n'
- && rcp[5] == 'e'
- && rcp[6] == 'd'
- && !(map[rcp[7]]&(DIGIT|LETTER))) {
- cp = rcp + 7;
- return UNSIGNED;
- }
- goto id;
- case 'v':
- if (rcp[0] == 'o'
- && rcp[1] == 'i'
- && rcp[2] == 'd'
- && !(map[rcp[3]]&(DIGIT|LETTER))) {
- cp = rcp + 3;
- tsym = voidtype->u.sym;
- return VOID;
- }
- if (rcp[0] == 'o'
- && rcp[1] == 'l'
- && rcp[2] == 'a'
- && rcp[3] == 't'
- && rcp[4] == 'i'
- && rcp[5] == 'l'
- && rcp[6] == 'e'
- && !(map[rcp[7]]&(DIGIT|LETTER))) {
- cp = rcp + 7;
- return VOLATILE;
- }
- goto id;
- case 'w':
- if (rcp[0] == 'h'
- && rcp[1] == 'i'
- && rcp[2] == 'l'
- && rcp[3] == 'e'
- && !(map[rcp[4]]&(DIGIT|LETTER))) {
- cp = rcp + 4;
- return WHILE;
- }
- goto id;
- case '_':
- if (rcp[0] == '_'
- && rcp[1] == 't'
- && rcp[2] == 'y'
- && rcp[3] == 'p'
- && rcp[4] == 'e'
- && rcp[5] == 'c'
- && rcp[6] == 'o'
- && rcp[7] == 'd'
- && rcp[8] == 'e'
- && !(map[rcp[9]]&(DIGIT|LETTER))) {
- cp = rcp + 9;
- return TYPECODE;
- }
- if (rcp[0] == '_'
- && rcp[1] == 'f'
- && rcp[2] == 'i'
- && rcp[3] == 'r'
- && rcp[4] == 's'
- && rcp[5] == 't'
- && rcp[6] == 'a'
- && rcp[7] == 'r'
- && rcp[8] == 'g'
- && !(map[rcp[9]]&(DIGIT|LETTER))) {
- cp = rcp + 9;
- return FIRSTARG;
- }
- goto id;
- default:
- if ((map[cp[-1]]&BLANK) == 0)
- if (cp[-1] < ' ' || cp[-1] >= 0177)
- error("illegal character `\\0%o'\n", cp[-1]);
- else
- error("illegal character `%c'\n", cp[-1]);
- }
- }
-}
-static Symbol icon(unsigned long n, int overflow, int base) {
- if ((*cp=='u'||*cp=='U') && (cp[1]=='l'||cp[1]=='L')
- || (*cp=='l'||*cp=='L') && (cp[1]=='u'||cp[1]=='U')) {
- tval.type = unsignedlong;
- cp += 2;
- } else if (*cp == 'u' || *cp == 'U') {
- if (overflow || n > unsignedtype->u.sym->u.limits.max.i)
- tval.type = unsignedlong;
- else
- tval.type = unsignedtype;
- cp += 1;
- } else if (*cp == 'l' || *cp == 'L') {
- if (overflow || n > longtype->u.sym->u.limits.max.i)
- tval.type = unsignedlong;
- else
- tval.type = longtype;
- cp += 1;
- } else if (overflow || n > longtype->u.sym->u.limits.max.i)
- tval.type = unsignedlong;
- else if (n > inttype->u.sym->u.limits.max.i)
- tval.type = longtype;
- else if (base != 10 && n > inttype->u.sym->u.limits.max.i)
- tval.type = unsignedtype;
- else
- tval.type = inttype;
- switch (tval.type->op) {
- case INT:
- if (overflow || n > tval.type->u.sym->u.limits.max.i) {
- warning("overflow in constant `%S'\n", token,
- (char*)cp - token);
- tval.u.c.v.i = tval.type->u.sym->u.limits.max.i;
- } else
- tval.u.c.v.i = n;
- break;
- case UNSIGNED:
- if (overflow || n > tval.type->u.sym->u.limits.max.u) {
- warning("overflow in constant `%S'\n", token,
- (char*)cp - token);
- tval.u.c.v.u = tval.type->u.sym->u.limits.max.u;
- } else
- tval.u.c.v.u = n;
- break;
- default: assert(0);
- }
- ppnumber("integer");
- return &tval;
-}
-static void ppnumber(char *which) {
- unsigned char *rcp = cp--;
-
- for ( ; (map[*cp]&(DIGIT|LETTER)) || *cp == '.'; cp++)
- if ((cp[0] == 'E' || cp[0] == 'e')
- && (cp[1] == '-' || cp[1] == '+'))
- cp++;
- if (cp > rcp)
- error("`%S' is a preprocessing number but an invalid %s constant\n", token,
-
- (char*)cp-token, which);
-}
-static Symbol fcon(void) {
- if (*cp == '.')
- do
- cp++;
- while (map[*cp]&DIGIT);
- if (*cp == 'e' || *cp == 'E') {
- if (*++cp == '-' || *cp == '+')
- cp++;
- if (map[*cp]&DIGIT)
- do
- cp++;
- while (map[*cp]&DIGIT);
- else
- error("invalid floating constant `%S'\n", token,
- (char*)cp - token);
- }
-
- errno = 0;
- tval.u.c.v.d = strtod(token, NULL);
- if (errno == ERANGE)
- warning("overflow in floating constant `%S'\n", token,
- (char*)cp - token);
- if (*cp == 'f' || *cp == 'F') {
- ++cp;
- if (tval.u.c.v.d > floattype->u.sym->u.limits.max.d)
- warning("overflow in floating constant `%S'\n", token,
- (char*)cp - token);
- tval.type = floattype;
- } else if (*cp == 'l' || *cp == 'L') {
- cp++;
- tval.type = longdouble;
- } else {
- if (tval.u.c.v.d > doubletype->u.sym->u.limits.max.d)
- warning("overflow in floating constant `%S'\n", token,
- (char*)cp - token);
- tval.type = doubletype;
- }
- ppnumber("floating");
- return &tval;
-}
-
-static void *cput(int c, void *cl) {
- char *s = cl;
-
- if (c < 0 || c > 255)
- warning("overflow in escape sequence with resulting value `%d'\n", c);
- *s++ = c;
- return s;
-}
-
-static void *wcput(int c, void *cl) {
- unsigned int *s = cl;
-
- *s++ = c;
- return s;
-}
-
-static void *scon(int q, void *put(int c, void *cl), void *cl) {
- int n = 0, nbad = 0;
-
- do {
- cp++;
- while (*cp != q) {
- int c;
- if (map[*cp]&NEWLINE) {
- if (cp < limit)
- break;
- cp++;
- nextline();
- if (cp == limit)
- break;
- continue;
- }
- c = *cp++;
- if (c == '\\') {
- if (map[*cp]&NEWLINE) {
- if (cp < limit)
- break;
- cp++;
- nextline();
- }
- if (limit - cp < MAXTOKEN)
- fillbuf();
- c = backslash(q);
- } else if (c < 0 || c > 255 || map[c] == 0)
- nbad++;
- if (n++ < BUFSIZE)
- cl = put(c, cl);
- }
- if (*cp == q)
- cp++;
- else
- error("missing %c\n", q);
- } while (q == '"' && getchr() == '"');
- cl = put(0, cl);
- if (n >= BUFSIZE)
- error("%s literal too long\n", q == '"' ? "string" : "character");
- if (Aflag >= 2 && q == '"' && n > 509)
- warning("more than 509 characters in a string literal\n");
- if (Aflag >= 2 && nbad > 0)
- warning("%s literal contains non-portable characters\n",
- q == '"' ? "string" : "character");
- return cl;
-}
-int getchr(void) {
- for (;;) {
- while (map[*cp]&BLANK)
- cp++;
- if (!(map[*cp]&NEWLINE))
- return *cp;
- cp++;
- nextline();
- if (cp == limit)
- return EOI;
- }
-}
-static int backslash(int q) {
- unsigned int c;
-
- switch (*cp++) {
- case 'a': return 7;
- case 'b': return '\b';
- case 'f': return '\f';
- case 'n': return '\n';
- case 'r': return '\r';
- case 't': return '\t';
- case 'v': return '\v';
- case '\'': case '"': case '\\': case '\?': break;
- case 'x': {
- int overflow = 0;
- if ((map[*cp]&(DIGIT|HEX)) == 0) {
- if (*cp < ' ' || *cp == 0177)
- error("ill-formed hexadecimal escape sequence\n");
- else
- error("ill-formed hexadecimal escape sequence `\\x%c'\n", *cp);
- if (*cp != q)
- cp++;
- return 0;
- }
- for (c = 0; map[*cp]&(DIGIT|HEX); cp++) {
- if (c >> (8*widechar->size - 4))
- overflow = 1;
- if (map[*cp]&DIGIT)
- c = (c<<4) + *cp - '0';
- else
- c = (c<<4) + (*cp&~040) - 'A' + 10;
- }
- if (overflow)
- warning("overflow in hexadecimal escape sequence\n");
- return c&ones(8*widechar->size);
- }
- case '0': case '1': case '2': case '3':
- case '4': case '5': case '6': case '7':
- c = *(cp-1) - '0';
- if (*cp >= '0' && *cp <= '7') {
- c = (c<<3) + *cp++ - '0';
- if (*cp >= '0' && *cp <= '7')
- c = (c<<3) + *cp++ - '0';
- }
- return c;
- default:
- if (cp[-1] < ' ' || cp[-1] >= 0177)
- warning("unrecognized character escape sequence\n");
- else
- warning("unrecognized character escape sequence `\\%c'\n", cp[-1]);
- }
- return cp[-1];
-}
+#include "c.h"
+#include <float.h>
+#include <errno.h>
+
+
+#define MAXTOKEN 32
+
+enum { BLANK=01, NEWLINE=02, LETTER=04,
+ DIGIT=010, HEX=020, OTHER=040 };
+
+static unsigned char map[256] = { /* 000 nul */ 0,
+ /* 001 soh */ 0,
+ /* 002 stx */ 0,
+ /* 003 etx */ 0,
+ /* 004 eot */ 0,
+ /* 005 enq */ 0,
+ /* 006 ack */ 0,
+ /* 007 bel */ 0,
+ /* 010 bs */ 0,
+ /* 011 ht */ BLANK,
+ /* 012 nl */ NEWLINE,
+ /* 013 vt */ BLANK,
+ /* 014 ff */ BLANK,
+ /* 015 cr */ 0,
+ /* 016 so */ 0,
+ /* 017 si */ 0,
+ /* 020 dle */ 0,
+ /* 021 dc1 */ 0,
+ /* 022 dc2 */ 0,
+ /* 023 dc3 */ 0,
+ /* 024 dc4 */ 0,
+ /* 025 nak */ 0,
+ /* 026 syn */ 0,
+ /* 027 etb */ 0,
+ /* 030 can */ 0,
+ /* 031 em */ 0,
+ /* 032 sub */ 0,
+ /* 033 esc */ 0,
+ /* 034 fs */ 0,
+ /* 035 gs */ 0,
+ /* 036 rs */ 0,
+ /* 037 us */ 0,
+ /* 040 sp */ BLANK,
+ /* 041 ! */ OTHER,
+ /* 042 " */ OTHER,
+ /* 043 # */ OTHER,
+ /* 044 $ */ 0,
+ /* 045 % */ OTHER,
+ /* 046 & */ OTHER,
+ /* 047 ' */ OTHER,
+ /* 050 ( */ OTHER,
+ /* 051 ) */ OTHER,
+ /* 052 * */ OTHER,
+ /* 053 + */ OTHER,
+ /* 054 , */ OTHER,
+ /* 055 - */ OTHER,
+ /* 056 . */ OTHER,
+ /* 057 / */ OTHER,
+ /* 060 0 */ DIGIT,
+ /* 061 1 */ DIGIT,
+ /* 062 2 */ DIGIT,
+ /* 063 3 */ DIGIT,
+ /* 064 4 */ DIGIT,
+ /* 065 5 */ DIGIT,
+ /* 066 6 */ DIGIT,
+ /* 067 7 */ DIGIT,
+ /* 070 8 */ DIGIT,
+ /* 071 9 */ DIGIT,
+ /* 072 : */ OTHER,
+ /* 073 ; */ OTHER,
+ /* 074 < */ OTHER,
+ /* 075 = */ OTHER,
+ /* 076 > */ OTHER,
+ /* 077 ? */ OTHER,
+ /* 100 @ */ 0,
+ /* 101 A */ LETTER|HEX,
+ /* 102 B */ LETTER|HEX,
+ /* 103 C */ LETTER|HEX,
+ /* 104 D */ LETTER|HEX,
+ /* 105 E */ LETTER|HEX,
+ /* 106 F */ LETTER|HEX,
+ /* 107 G */ LETTER,
+ /* 110 H */ LETTER,
+ /* 111 I */ LETTER,
+ /* 112 J */ LETTER,
+ /* 113 K */ LETTER,
+ /* 114 L */ LETTER,
+ /* 115 M */ LETTER,
+ /* 116 N */ LETTER,
+ /* 117 O */ LETTER,
+ /* 120 P */ LETTER,
+ /* 121 Q */ LETTER,
+ /* 122 R */ LETTER,
+ /* 123 S */ LETTER,
+ /* 124 T */ LETTER,
+ /* 125 U */ LETTER,
+ /* 126 V */ LETTER,
+ /* 127 W */ LETTER,
+ /* 130 X */ LETTER,
+ /* 131 Y */ LETTER,
+ /* 132 Z */ LETTER,
+ /* 133 [ */ OTHER,
+ /* 134 \ */ OTHER,
+ /* 135 ] */ OTHER,
+ /* 136 ^ */ OTHER,
+ /* 137 _ */ LETTER,
+ /* 140 ` */ 0,
+ /* 141 a */ LETTER|HEX,
+ /* 142 b */ LETTER|HEX,
+ /* 143 c */ LETTER|HEX,
+ /* 144 d */ LETTER|HEX,
+ /* 145 e */ LETTER|HEX,
+ /* 146 f */ LETTER|HEX,
+ /* 147 g */ LETTER,
+ /* 150 h */ LETTER,
+ /* 151 i */ LETTER,
+ /* 152 j */ LETTER,
+ /* 153 k */ LETTER,
+ /* 154 l */ LETTER,
+ /* 155 m */ LETTER,
+ /* 156 n */ LETTER,
+ /* 157 o */ LETTER,
+ /* 160 p */ LETTER,
+ /* 161 q */ LETTER,
+ /* 162 r */ LETTER,
+ /* 163 s */ LETTER,
+ /* 164 t */ LETTER,
+ /* 165 u */ LETTER,
+ /* 166 v */ LETTER,
+ /* 167 w */ LETTER,
+ /* 170 x */ LETTER,
+ /* 171 y */ LETTER,
+ /* 172 z */ LETTER,
+ /* 173 { */ OTHER,
+ /* 174 | */ OTHER,
+ /* 175 } */ OTHER,
+ /* 176 ~ */ OTHER, };
+static struct symbol tval;
+static char cbuf[BUFSIZE+1];
+static unsigned int wcbuf[BUFSIZE+1];
+
+Coordinate src; /* current source coordinate */
+int t;
+char *token; /* current token */
+Symbol tsym; /* symbol table entry for current token */
+
+static void *cput(int c, void *cl);
+static void *wcput(int c, void *cl);
+static void *scon(int q, void *put(int c, void *cl), void *cl);
+static int backslash(int q);
+static Symbol fcon(void);
+static Symbol icon(unsigned long, int, int);
+static void ppnumber(char *);
+
+int gettok(void) {
+ for (;;) {
+ register unsigned char *rcp = cp;
+ while (map[*rcp]&BLANK)
+ rcp++;
+ if (limit - rcp < MAXTOKEN) {
+ cp = rcp;
+ fillbuf();
+ rcp = cp;
+ }
+ src.file = file;
+ src.x = (char *)rcp - line;
+ src.y = lineno;
+ cp = rcp + 1;
+ switch (*rcp++) {
+ case '/': if (*rcp == '*') {
+ int c = 0;
+ for (rcp++; *rcp != '/' || c != '*'; )
+ if (map[*rcp]&NEWLINE) {
+ if (rcp < limit)
+ c = *rcp;
+ cp = rcp + 1;
+ nextline();
+ rcp = cp;
+ if (rcp == limit)
+ break;
+ } else
+ c = *rcp++;
+ if (rcp < limit)
+ rcp++;
+ else
+ error("unclosed comment\n");
+ cp = rcp;
+ continue;
+ }
+ return '/';
+ case '<':
+ if (*rcp == '=') return cp++, LEQ;
+ if (*rcp == '<') return cp++, LSHIFT;
+ return '<';
+ case '>':
+ if (*rcp == '=') return cp++, GEQ;
+ if (*rcp == '>') return cp++, RSHIFT;
+ return '>';
+ case '-':
+ if (*rcp == '>') return cp++, DEREF;
+ if (*rcp == '-') return cp++, DECR;
+ return '-';
+ case '=': return *rcp == '=' ? cp++, EQL : '=';
+ case '!': return *rcp == '=' ? cp++, NEQ : '!';
+ case '|': return *rcp == '|' ? cp++, OROR : '|';
+ case '&': return *rcp == '&' ? cp++, ANDAND : '&';
+ case '+': return *rcp == '+' ? cp++, INCR : '+';
+ case ';': case ',': case ':':
+ case '*': case '~': case '%': case '^': case '?':
+ case '[': case ']': case '{': case '}': case '(': case ')':
+ return rcp[-1];
+ case '\n': case '\v': case '\r': case '\f':
+ nextline();
+ if (cp == limit) {
+ tsym = NULL;
+ return EOI;
+ }
+ continue;
+
+ case 'i':
+ if (rcp[0] == 'f'
+ && !(map[rcp[1]]&(DIGIT|LETTER))) {
+ cp = rcp + 1;
+ return IF;
+ }
+ if (rcp[0] == 'n'
+ && rcp[1] == 't'
+ && !(map[rcp[2]]&(DIGIT|LETTER))) {
+ cp = rcp + 2;
+ tsym = inttype->u.sym;
+ return INT;
+ }
+ goto id;
+ case 'h': case 'j': case 'k': case 'm': case 'n': case 'o':
+ case 'p': case 'q': 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 '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':
+ id:
+ if (limit - rcp < MAXLINE) {
+ cp = rcp - 1;
+ fillbuf();
+ rcp = ++cp;
+ }
+ assert(cp == rcp);
+ token = (char *)rcp - 1;
+ while (map[*rcp]&(DIGIT|LETTER))
+ rcp++;
+ token = stringn(token, (char *)rcp - token);
+ tsym = lookup(token, identifiers);
+ cp = rcp;
+ return ID;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9': {
+ unsigned long n = 0;
+ if (limit - rcp < MAXLINE) {
+ cp = rcp - 1;
+ fillbuf();
+ rcp = ++cp;
+ }
+ assert(cp == rcp);
+ token = (char *)rcp - 1;
+ if (*token == '0' && (*rcp == 'x' || *rcp == 'X')) {
+ int d, overflow = 0;
+ while (*++rcp) {
+ if (map[*rcp]&DIGIT)
+ d = *rcp - '0';
+ else if (*rcp >= 'a' && *rcp <= 'f')
+ d = *rcp - 'a' + 10;
+ else if (*rcp >= 'A' && *rcp <= 'F')
+ d = *rcp - 'A' + 10;
+ else
+ break;
+ if (n&~(~0UL >> 4))
+ overflow = 1;
+ else
+ n = (n<<4) + d;
+ }
+ if ((char *)rcp - token <= 2)
+ error("invalid hexadecimal constant `%S'\n", token, (char *)rcp-token);
+ cp = rcp;
+ tsym = icon(n, overflow, 16);
+ } else if (*token == '0') {
+ int err = 0, overflow = 0;
+ for ( ; map[*rcp]&DIGIT; rcp++) {
+ if (*rcp == '8' || *rcp == '9')
+ err = 1;
+ if (n&~(~0UL >> 3))
+ overflow = 1;
+ else
+ n = (n<<3) + (*rcp - '0');
+ }
+ if (*rcp == '.' || *rcp == 'e' || *rcp == 'E') {
+ cp = rcp;
+ tsym = fcon();
+ return FCON;
+ }
+ cp = rcp;
+ tsym = icon(n, overflow, 8);
+ if (err)
+ error("invalid octal constant `%S'\n", token, (char*)cp-token);
+ } else {
+ int overflow = 0;
+ for (n = *token - '0'; map[*rcp]&DIGIT; ) {
+ int d = *rcp++ - '0';
+ if (n > (ULONG_MAX - d)/10)
+ overflow = 1;
+ else
+ n = 10*n + d;
+ }
+ if (*rcp == '.' || *rcp == 'e' || *rcp == 'E') {
+ cp = rcp;
+ tsym = fcon();
+ return FCON;
+ }
+ cp = rcp;
+ tsym = icon(n, overflow, 10);
+ }
+ return ICON;
+ }
+ case '.':
+ if (rcp[0] == '.' && rcp[1] == '.') {
+ cp += 2;
+ return ELLIPSIS;
+ }
+ if ((map[*rcp]&DIGIT) == 0)
+ return '.';
+ if (limit - rcp < MAXLINE) {
+ cp = rcp - 1;
+ fillbuf();
+ rcp = ++cp;
+ }
+ assert(cp == rcp);
+ cp = rcp - 1;
+ token = (char *)cp;
+ tsym = fcon();
+ return FCON;
+ case 'L':
+ if (*rcp == '\'') {
+ unsigned int *s = scon(*cp, wcput, wcbuf);
+ if (s - wcbuf > 2)
+ warning("excess characters in wide-character literal ignored\n");
+ tval.type = widechar;
+ tval.u.c.v.u = wcbuf[0];
+ tsym = &tval;
+ return ICON;
+ } else if (*rcp == '"') {
+ unsigned int *s = scon(*cp, wcput, wcbuf);
+ tval.type = array(widechar, s - wcbuf, 0);
+ tval.u.c.v.p = wcbuf;
+ tsym = &tval;
+ return SCON;
+ } else
+ goto id;
+ case '\'': {
+ char *s = scon(*--cp, cput, cbuf);
+ if (s - cbuf > 2)
+ warning("excess characters in multibyte character literal ignored\n");
+ tval.type = inttype;
+ if (chartype->op == INT)
+ tval.u.c.v.i = extend(cbuf[0], chartype);
+ else
+ tval.u.c.v.i = cbuf[0]&0xFF;
+ tsym = &tval;
+ return ICON;
+ }
+ case '"': {
+ char *s = scon(*--cp, cput, cbuf);
+ tval.type = array(chartype, s - cbuf, 0);
+ tval.u.c.v.p = cbuf;
+ tsym = &tval;
+ return SCON;
+ }
+ case 'a':
+ if (rcp[0] == 'u'
+ && rcp[1] == 't'
+ && rcp[2] == 'o'
+ && !(map[rcp[3]]&(DIGIT|LETTER))) {
+ cp = rcp + 3;
+ return AUTO;
+ }
+ goto id;
+ case 'b':
+ if (rcp[0] == 'r'
+ && rcp[1] == 'e'
+ && rcp[2] == 'a'
+ && rcp[3] == 'k'
+ && !(map[rcp[4]]&(DIGIT|LETTER))) {
+ cp = rcp + 4;
+ return BREAK;
+ }
+ goto id;
+ case 'c':
+ if (rcp[0] == 'a'
+ && rcp[1] == 's'
+ && rcp[2] == 'e'
+ && !(map[rcp[3]]&(DIGIT|LETTER))) {
+ cp = rcp + 3;
+ return CASE;
+ }
+ if (rcp[0] == 'h'
+ && rcp[1] == 'a'
+ && rcp[2] == 'r'
+ && !(map[rcp[3]]&(DIGIT|LETTER))) {
+ cp = rcp + 3;
+ tsym = chartype->u.sym;
+ return CHAR;
+ }
+ if (rcp[0] == 'o'
+ && rcp[1] == 'n'
+ && rcp[2] == 's'
+ && rcp[3] == 't'
+ && !(map[rcp[4]]&(DIGIT|LETTER))) {
+ cp = rcp + 4;
+ return CONST;
+ }
+ if (rcp[0] == 'o'
+ && rcp[1] == 'n'
+ && rcp[2] == 't'
+ && rcp[3] == 'i'
+ && rcp[4] == 'n'
+ && rcp[5] == 'u'
+ && rcp[6] == 'e'
+ && !(map[rcp[7]]&(DIGIT|LETTER))) {
+ cp = rcp + 7;
+ return CONTINUE;
+ }
+ goto id;
+ case 'd':
+ if (rcp[0] == 'e'
+ && rcp[1] == 'f'
+ && rcp[2] == 'a'
+ && rcp[3] == 'u'
+ && rcp[4] == 'l'
+ && rcp[5] == 't'
+ && !(map[rcp[6]]&(DIGIT|LETTER))) {
+ cp = rcp + 6;
+ return DEFAULT;
+ }
+ if (rcp[0] == 'o'
+ && rcp[1] == 'u'
+ && rcp[2] == 'b'
+ && rcp[3] == 'l'
+ && rcp[4] == 'e'
+ && !(map[rcp[5]]&(DIGIT|LETTER))) {
+ cp = rcp + 5;
+ tsym = doubletype->u.sym;
+ return DOUBLE;
+ }
+ if (rcp[0] == 'o'
+ && !(map[rcp[1]]&(DIGIT|LETTER))) {
+ cp = rcp + 1;
+ return DO;
+ }
+ goto id;
+ case 'e':
+ if (rcp[0] == 'l'
+ && rcp[1] == 's'
+ && rcp[2] == 'e'
+ && !(map[rcp[3]]&(DIGIT|LETTER))) {
+ cp = rcp + 3;
+ return ELSE;
+ }
+ if (rcp[0] == 'n'
+ && rcp[1] == 'u'
+ && rcp[2] == 'm'
+ && !(map[rcp[3]]&(DIGIT|LETTER))) {
+ cp = rcp + 3;
+ return ENUM;
+ }
+ if (rcp[0] == 'x'
+ && rcp[1] == 't'
+ && rcp[2] == 'e'
+ && rcp[3] == 'r'
+ && rcp[4] == 'n'
+ && !(map[rcp[5]]&(DIGIT|LETTER))) {
+ cp = rcp + 5;
+ return EXTERN;
+ }
+ goto id;
+ case 'f':
+ if (rcp[0] == 'l'
+ && rcp[1] == 'o'
+ && rcp[2] == 'a'
+ && rcp[3] == 't'
+ && !(map[rcp[4]]&(DIGIT|LETTER))) {
+ cp = rcp + 4;
+ tsym = floattype->u.sym;
+ return FLOAT;
+ }
+ if (rcp[0] == 'o'
+ && rcp[1] == 'r'
+ && !(map[rcp[2]]&(DIGIT|LETTER))) {
+ cp = rcp + 2;
+ return FOR;
+ }
+ goto id;
+ case 'g':
+ if (rcp[0] == 'o'
+ && rcp[1] == 't'
+ && rcp[2] == 'o'
+ && !(map[rcp[3]]&(DIGIT|LETTER))) {
+ cp = rcp + 3;
+ return GOTO;
+ }
+ goto id;
+ case 'l':
+ if (rcp[0] == 'o'
+ && rcp[1] == 'n'
+ && rcp[2] == 'g'
+ && !(map[rcp[3]]&(DIGIT|LETTER))) {
+ cp = rcp + 3;
+ return LONG;
+ }
+ goto id;
+ case 'r':
+ if (rcp[0] == 'e'
+ && rcp[1] == 'g'
+ && rcp[2] == 'i'
+ && rcp[3] == 's'
+ && rcp[4] == 't'
+ && rcp[5] == 'e'
+ && rcp[6] == 'r'
+ && !(map[rcp[7]]&(DIGIT|LETTER))) {
+ cp = rcp + 7;
+ return REGISTER;
+ }
+ if (rcp[0] == 'e'
+ && rcp[1] == 't'
+ && rcp[2] == 'u'
+ && rcp[3] == 'r'
+ && rcp[4] == 'n'
+ && !(map[rcp[5]]&(DIGIT|LETTER))) {
+ cp = rcp + 5;
+ return RETURN;
+ }
+ goto id;
+ case 's':
+ if (rcp[0] == 'h'
+ && rcp[1] == 'o'
+ && rcp[2] == 'r'
+ && rcp[3] == 't'
+ && !(map[rcp[4]]&(DIGIT|LETTER))) {
+ cp = rcp + 4;
+ return SHORT;
+ }
+ if (rcp[0] == 'i'
+ && rcp[1] == 'g'
+ && rcp[2] == 'n'
+ && rcp[3] == 'e'
+ && rcp[4] == 'd'
+ && !(map[rcp[5]]&(DIGIT|LETTER))) {
+ cp = rcp + 5;
+ return SIGNED;
+ }
+ if (rcp[0] == 'i'
+ && rcp[1] == 'z'
+ && rcp[2] == 'e'
+ && rcp[3] == 'o'
+ && rcp[4] == 'f'
+ && !(map[rcp[5]]&(DIGIT|LETTER))) {
+ cp = rcp + 5;
+ return SIZEOF;
+ }
+ if (rcp[0] == 't'
+ && rcp[1] == 'a'
+ && rcp[2] == 't'
+ && rcp[3] == 'i'
+ && rcp[4] == 'c'
+ && !(map[rcp[5]]&(DIGIT|LETTER))) {
+ cp = rcp + 5;
+ return STATIC;
+ }
+ if (rcp[0] == 't'
+ && rcp[1] == 'r'
+ && rcp[2] == 'u'
+ && rcp[3] == 'c'
+ && rcp[4] == 't'
+ && !(map[rcp[5]]&(DIGIT|LETTER))) {
+ cp = rcp + 5;
+ return STRUCT;
+ }
+ if (rcp[0] == 'w'
+ && rcp[1] == 'i'
+ && rcp[2] == 't'
+ && rcp[3] == 'c'
+ && rcp[4] == 'h'
+ && !(map[rcp[5]]&(DIGIT|LETTER))) {
+ cp = rcp + 5;
+ return SWITCH;
+ }
+ goto id;
+ case 't':
+ if (rcp[0] == 'y'
+ && rcp[1] == 'p'
+ && rcp[2] == 'e'
+ && rcp[3] == 'd'
+ && rcp[4] == 'e'
+ && rcp[5] == 'f'
+ && !(map[rcp[6]]&(DIGIT|LETTER))) {
+ cp = rcp + 6;
+ return TYPEDEF;
+ }
+ goto id;
+ case 'u':
+ if (rcp[0] == 'n'
+ && rcp[1] == 'i'
+ && rcp[2] == 'o'
+ && rcp[3] == 'n'
+ && !(map[rcp[4]]&(DIGIT|LETTER))) {
+ cp = rcp + 4;
+ return UNION;
+ }
+ if (rcp[0] == 'n'
+ && rcp[1] == 's'
+ && rcp[2] == 'i'
+ && rcp[3] == 'g'
+ && rcp[4] == 'n'
+ && rcp[5] == 'e'
+ && rcp[6] == 'd'
+ && !(map[rcp[7]]&(DIGIT|LETTER))) {
+ cp = rcp + 7;
+ return UNSIGNED;
+ }
+ goto id;
+ case 'v':
+ if (rcp[0] == 'o'
+ && rcp[1] == 'i'
+ && rcp[2] == 'd'
+ && !(map[rcp[3]]&(DIGIT|LETTER))) {
+ cp = rcp + 3;
+ tsym = voidtype->u.sym;
+ return VOID;
+ }
+ if (rcp[0] == 'o'
+ && rcp[1] == 'l'
+ && rcp[2] == 'a'
+ && rcp[3] == 't'
+ && rcp[4] == 'i'
+ && rcp[5] == 'l'
+ && rcp[6] == 'e'
+ && !(map[rcp[7]]&(DIGIT|LETTER))) {
+ cp = rcp + 7;
+ return VOLATILE;
+ }
+ goto id;
+ case 'w':
+ if (rcp[0] == 'h'
+ && rcp[1] == 'i'
+ && rcp[2] == 'l'
+ && rcp[3] == 'e'
+ && !(map[rcp[4]]&(DIGIT|LETTER))) {
+ cp = rcp + 4;
+ return WHILE;
+ }
+ goto id;
+ case '_':
+ if (rcp[0] == '_'
+ && rcp[1] == 't'
+ && rcp[2] == 'y'
+ && rcp[3] == 'p'
+ && rcp[4] == 'e'
+ && rcp[5] == 'c'
+ && rcp[6] == 'o'
+ && rcp[7] == 'd'
+ && rcp[8] == 'e'
+ && !(map[rcp[9]]&(DIGIT|LETTER))) {
+ cp = rcp + 9;
+ return TYPECODE;
+ }
+ if (rcp[0] == '_'
+ && rcp[1] == 'f'
+ && rcp[2] == 'i'
+ && rcp[3] == 'r'
+ && rcp[4] == 's'
+ && rcp[5] == 't'
+ && rcp[6] == 'a'
+ && rcp[7] == 'r'
+ && rcp[8] == 'g'
+ && !(map[rcp[9]]&(DIGIT|LETTER))) {
+ cp = rcp + 9;
+ return FIRSTARG;
+ }
+ goto id;
+ default:
+ if ((map[cp[-1]]&BLANK) == 0)
+ if (cp[-1] < ' ' || cp[-1] >= 0177)
+ error("illegal character `\\0%o'\n", cp[-1]);
+ else
+ error("illegal character `%c'\n", cp[-1]);
+ }
+ }
+}
+static Symbol icon(unsigned long n, int overflow, int base) {
+ if ((*cp=='u'||*cp=='U') && (cp[1]=='l'||cp[1]=='L')
+ || (*cp=='l'||*cp=='L') && (cp[1]=='u'||cp[1]=='U')) {
+ tval.type = unsignedlong;
+ cp += 2;
+ } else if (*cp == 'u' || *cp == 'U') {
+ if (overflow || n > unsignedtype->u.sym->u.limits.max.i)
+ tval.type = unsignedlong;
+ else
+ tval.type = unsignedtype;
+ cp += 1;
+ } else if (*cp == 'l' || *cp == 'L') {
+ if (overflow || n > longtype->u.sym->u.limits.max.i)
+ tval.type = unsignedlong;
+ else
+ tval.type = longtype;
+ cp += 1;
+ } else if (overflow || n > longtype->u.sym->u.limits.max.i)
+ tval.type = unsignedlong;
+ else if (n > inttype->u.sym->u.limits.max.i)
+ tval.type = longtype;
+ else if (base != 10 && n > inttype->u.sym->u.limits.max.i)
+ tval.type = unsignedtype;
+ else
+ tval.type = inttype;
+ switch (tval.type->op) {
+ case INT:
+ if (overflow || n > tval.type->u.sym->u.limits.max.i) {
+ warning("overflow in constant `%S'\n", token,
+ (char*)cp - token);
+ tval.u.c.v.i = tval.type->u.sym->u.limits.max.i;
+ } else
+ tval.u.c.v.i = n;
+ break;
+ case UNSIGNED:
+ if (overflow || n > tval.type->u.sym->u.limits.max.u) {
+ warning("overflow in constant `%S'\n", token,
+ (char*)cp - token);
+ tval.u.c.v.u = tval.type->u.sym->u.limits.max.u;
+ } else
+ tval.u.c.v.u = n;
+ break;
+ default: assert(0);
+ }
+ ppnumber("integer");
+ return &tval;
+}
+static void ppnumber(char *which) {
+ unsigned char *rcp = cp--;
+
+ for ( ; (map[*cp]&(DIGIT|LETTER)) || *cp == '.'; cp++)
+ if ((cp[0] == 'E' || cp[0] == 'e')
+ && (cp[1] == '-' || cp[1] == '+'))
+ cp++;
+ if (cp > rcp)
+ error("`%S' is a preprocessing number but an invalid %s constant\n", token,
+
+ (char*)cp-token, which);
+}
+static Symbol fcon(void) {
+ if (*cp == '.')
+ do
+ cp++;
+ while (map[*cp]&DIGIT);
+ if (*cp == 'e' || *cp == 'E') {
+ if (*++cp == '-' || *cp == '+')
+ cp++;
+ if (map[*cp]&DIGIT)
+ do
+ cp++;
+ while (map[*cp]&DIGIT);
+ else
+ error("invalid floating constant `%S'\n", token,
+ (char*)cp - token);
+ }
+
+ errno = 0;
+ tval.u.c.v.d = strtod(token, NULL);
+ if (errno == ERANGE)
+ warning("overflow in floating constant `%S'\n", token,
+ (char*)cp - token);
+ if (*cp == 'f' || *cp == 'F') {
+ ++cp;
+ if (tval.u.c.v.d > floattype->u.sym->u.limits.max.d)
+ warning("overflow in floating constant `%S'\n", token,
+ (char*)cp - token);
+ tval.type = floattype;
+ } else if (*cp == 'l' || *cp == 'L') {
+ cp++;
+ tval.type = longdouble;
+ } else {
+ if (tval.u.c.v.d > doubletype->u.sym->u.limits.max.d)
+ warning("overflow in floating constant `%S'\n", token,
+ (char*)cp - token);
+ tval.type = doubletype;
+ }
+ ppnumber("floating");
+ return &tval;
+}
+
+static void *cput(int c, void *cl) {
+ char *s = cl;
+
+ if (c < 0 || c > 255)
+ warning("overflow in escape sequence with resulting value `%d'\n", c);
+ *s++ = c;
+ return s;
+}
+
+static void *wcput(int c, void *cl) {
+ unsigned int *s = cl;
+
+ *s++ = c;
+ return s;
+}
+
+static void *scon(int q, void *put(int c, void *cl), void *cl) {
+ int n = 0, nbad = 0;
+
+ do {
+ cp++;
+ while (*cp != q) {
+ int c;
+ if (map[*cp]&NEWLINE) {
+ if (cp < limit)
+ break;
+ cp++;
+ nextline();
+ if (cp == limit)
+ break;
+ continue;
+ }
+ c = *cp++;
+ if (c == '\\') {
+ if (map[*cp]&NEWLINE) {
+ if (cp < limit)
+ break;
+ cp++;
+ nextline();
+ }
+ if (limit - cp < MAXTOKEN)
+ fillbuf();
+ c = backslash(q);
+ } else if (c < 0 || c > 255 || map[c] == 0)
+ nbad++;
+ if (n++ < BUFSIZE)
+ cl = put(c, cl);
+ }
+ if (*cp == q)
+ cp++;
+ else
+ error("missing %c\n", q);
+ } while (q == '"' && getchr() == '"');
+ cl = put(0, cl);
+ if (n >= BUFSIZE)
+ error("%s literal too long\n", q == '"' ? "string" : "character");
+ if (Aflag >= 2 && q == '"' && n > 509)
+ warning("more than 509 characters in a string literal\n");
+ if (Aflag >= 2 && nbad > 0)
+ warning("%s literal contains non-portable characters\n",
+ q == '"' ? "string" : "character");
+ return cl;
+}
+int getchr(void) {
+ for (;;) {
+ while (map[*cp]&BLANK)
+ cp++;
+ if (!(map[*cp]&NEWLINE))
+ return *cp;
+ cp++;
+ nextline();
+ if (cp == limit)
+ return EOI;
+ }
+}
+static int backslash(int q) {
+ unsigned int c;
+
+ switch (*cp++) {
+ case 'a': return 7;
+ case 'b': return '\b';
+ case 'f': return '\f';
+ case 'n': return '\n';
+ case 'r': return '\r';
+ case 't': return '\t';
+ case 'v': return '\v';
+ case '\'': case '"': case '\\': case '\?': break;
+ case 'x': {
+ int overflow = 0;
+ if ((map[*cp]&(DIGIT|HEX)) == 0) {
+ if (*cp < ' ' || *cp == 0177)
+ error("ill-formed hexadecimal escape sequence\n");
+ else
+ error("ill-formed hexadecimal escape sequence `\\x%c'\n", *cp);
+ if (*cp != q)
+ cp++;
+ return 0;
+ }
+ for (c = 0; map[*cp]&(DIGIT|HEX); cp++) {
+ if (c >> (8*widechar->size - 4))
+ overflow = 1;
+ if (map[*cp]&DIGIT)
+ c = (c<<4) + *cp - '0';
+ else
+ c = (c<<4) + (*cp&~040) - 'A' + 10;
+ }
+ if (overflow)
+ warning("overflow in hexadecimal escape sequence\n");
+ return c&ones(8*widechar->size);
+ }
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ c = *(cp-1) - '0';
+ if (*cp >= '0' && *cp <= '7') {
+ c = (c<<3) + *cp++ - '0';
+ if (*cp >= '0' && *cp <= '7')
+ c = (c<<3) + *cp++ - '0';
+ }
+ return c;
+ default:
+ if (cp[-1] < ' ' || cp[-1] >= 0177)
+ warning("unrecognized character escape sequence\n");
+ else
+ warning("unrecognized character escape sequence `\\%c'\n", cp[-1]);
+ }
+ return cp[-1];
+}