00001 #include "c.h"
00002 #include <float.h>
00003 #include <errno.h>
00004
00005
00006 #define MAXTOKEN 32
00007
00008 enum { BLANK=01, NEWLINE=02, LETTER=04,
00009 DIGIT=010, HEX=020, OTHER=040 };
00010
00011 static unsigned char map[256] = { 0,
00012 0,
00013 0,
00014 0,
00015 0,
00016 0,
00017 0,
00018 0,
00019 0,
00020 BLANK,
00021 NEWLINE,
00022 BLANK,
00023 BLANK,
00024 0,
00025 0,
00026 0,
00027 0,
00028 0,
00029 0,
00030 0,
00031 0,
00032 0,
00033 0,
00034 0,
00035 0,
00036 0,
00037 0,
00038 0,
00039 0,
00040 0,
00041 0,
00042 0,
00043 BLANK,
00044 OTHER,
00045 OTHER,
00046 OTHER,
00047 0,
00048 OTHER,
00049 OTHER,
00050 OTHER,
00051 OTHER,
00052 OTHER,
00053 OTHER,
00054 OTHER,
00055 OTHER,
00056 OTHER,
00057 OTHER,
00058 OTHER,
00059 DIGIT,
00060 DIGIT,
00061 DIGIT,
00062 DIGIT,
00063 DIGIT,
00064 DIGIT,
00065 DIGIT,
00066 DIGIT,
00067 DIGIT,
00068 DIGIT,
00069 OTHER,
00070 OTHER,
00071 OTHER,
00072 OTHER,
00073 OTHER,
00074 OTHER,
00075 0,
00076 LETTER|HEX,
00077 LETTER|HEX,
00078 LETTER|HEX,
00079 LETTER|HEX,
00080 LETTER|HEX,
00081 LETTER|HEX,
00082 LETTER,
00083 LETTER,
00084 LETTER,
00085 LETTER,
00086 LETTER,
00087 LETTER,
00088 LETTER,
00089 LETTER,
00090 LETTER,
00091 LETTER,
00092 LETTER,
00093 LETTER,
00094 LETTER,
00095 LETTER,
00096 LETTER,
00097 LETTER,
00098 LETTER,
00099 LETTER,
00100 LETTER,
00101 LETTER,
00102 OTHER,
00103 OTHER,
00104 OTHER,
00105 OTHER,
00106 LETTER,
00107 0,
00108 LETTER|HEX,
00109 LETTER|HEX,
00110 LETTER|HEX,
00111 LETTER|HEX,
00112 LETTER|HEX,
00113 LETTER|HEX,
00114 LETTER,
00115 LETTER,
00116 LETTER,
00117 LETTER,
00118 LETTER,
00119 LETTER,
00120 LETTER,
00121 LETTER,
00122 LETTER,
00123 LETTER,
00124 LETTER,
00125 LETTER,
00126 LETTER,
00127 LETTER,
00128 LETTER,
00129 LETTER,
00130 LETTER,
00131 LETTER,
00132 LETTER,
00133 LETTER,
00134 OTHER,
00135 OTHER,
00136 OTHER,
00137 OTHER, };
00138 static struct symbol tval;
00139 static char cbuf[BUFSIZE+1];
00140 static unsigned int wcbuf[BUFSIZE+1];
00141
00142 Coordinate src;
00143 int t;
00144 char *token;
00145 Symbol tsym;
00146
00147 static void *cput(int c, void *cl);
00148 static void *wcput(int c, void *cl);
00149 static void *scon(int q, void *put(int c, void *cl), void *cl);
00150 static int backslash(int q);
00151 static Symbol fcon(void);
00152 static Symbol icon(unsigned long, int, int);
00153 static void ppnumber(char *);
00154
00155 int gettok(void) {
00156 for (;;) {
00157 register unsigned char *rcp = cp;
00158 while (map[*rcp]&BLANK)
00159 rcp++;
00160 if (limit - rcp < MAXTOKEN) {
00161 cp = rcp;
00162 fillbuf();
00163 rcp = cp;
00164 }
00165 src.file = file;
00166 src.x = (char *)rcp - line;
00167 src.y = lineno;
00168 cp = rcp + 1;
00169 switch (*rcp++) {
00170 case '/': if (*rcp == '*') {
00171 int c = 0;
00172 for (rcp++; *rcp != '/' || c != '*'; )
00173 if (map[*rcp]&NEWLINE) {
00174 if (rcp < limit)
00175 c = *rcp;
00176 cp = rcp + 1;
00177 nextline();
00178 rcp = cp;
00179 if (rcp == limit)
00180 break;
00181 } else
00182 c = *rcp++;
00183 if (rcp < limit)
00184 rcp++;
00185 else
00186 error("unclosed comment\n");
00187 cp = rcp;
00188 continue;
00189 }
00190 return '/';
00191 case '<':
00192 if (*rcp == '=') return cp++, LEQ;
00193 if (*rcp == '<') return cp++, LSHIFT;
00194 return '<';
00195 case '>':
00196 if (*rcp == '=') return cp++, GEQ;
00197 if (*rcp == '>') return cp++, RSHIFT;
00198 return '>';
00199 case '-':
00200 if (*rcp == '>') return cp++, DEREF;
00201 if (*rcp == '-') return cp++, DECR;
00202 return '-';
00203 case '=': return *rcp == '=' ? cp++, EQL : '=';
00204 case '!': return *rcp == '=' ? cp++, NEQ : '!';
00205 case '|': return *rcp == '|' ? cp++, OROR : '|';
00206 case '&': return *rcp == '&' ? cp++, ANDAND : '&';
00207 case '+': return *rcp == '+' ? cp++, INCR : '+';
00208 case ';': case ',': case ':':
00209 case '*': case '~': case '%': case '^': case '?':
00210 case '[': case ']': case '{': case '}': case '(': case ')':
00211 return rcp[-1];
00212 case '\n': case '\v': case '\r': case '\f':
00213 nextline();
00214 if (cp == limit) {
00215 tsym = NULL;
00216 return EOI;
00217 }
00218 continue;
00219
00220 case 'i':
00221 if (rcp[0] == 'f'
00222 && !(map[rcp[1]]&(DIGIT|LETTER))) {
00223 cp = rcp + 1;
00224 return IF;
00225 }
00226 if (rcp[0] == 'n'
00227 && rcp[1] == 't'
00228 && !(map[rcp[2]]&(DIGIT|LETTER))) {
00229 cp = rcp + 2;
00230 tsym = inttype->u.sym;
00231 return INT;
00232 }
00233 goto id;
00234 case 'h': case 'j': case 'k': case 'm': case 'n': case 'o':
00235 case 'p': case 'q': case 'x': case 'y': case 'z':
00236 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
00237 case 'G': case 'H': case 'I': case 'J': case 'K':
00238 case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
00239 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
00240 case 'Y': case 'Z':
00241 id:
00242 if (limit - rcp < MAXLINE) {
00243 cp = rcp - 1;
00244 fillbuf();
00245 rcp = ++cp;
00246 }
00247 assert(cp == rcp);
00248 token = (char *)rcp - 1;
00249 while (map[*rcp]&(DIGIT|LETTER))
00250 rcp++;
00251 token = stringn(token, (char *)rcp - token);
00252 tsym = lookup(token, identifiers);
00253 cp = rcp;
00254 return ID;
00255 case '0': case '1': case '2': case '3': case '4':
00256 case '5': case '6': case '7': case '8': case '9': {
00257 unsigned long n = 0;
00258 if (limit - rcp < MAXLINE) {
00259 cp = rcp - 1;
00260 fillbuf();
00261 rcp = ++cp;
00262 }
00263 assert(cp == rcp);
00264 token = (char *)rcp - 1;
00265 if (*token == '0' && (*rcp == 'x' || *rcp == 'X')) {
00266 int d, overflow = 0;
00267 while (*++rcp) {
00268 if (map[*rcp]&DIGIT)
00269 d = *rcp - '0';
00270 else if (*rcp >= 'a' && *rcp <= 'f')
00271 d = *rcp - 'a' + 10;
00272 else if (*rcp >= 'A' && *rcp <= 'F')
00273 d = *rcp - 'A' + 10;
00274 else
00275 break;
00276 if (n&~(~0UL >> 4))
00277 overflow = 1;
00278 else
00279 n = (n<<4) + d;
00280 }
00281 if ((char *)rcp - token <= 2)
00282 error("invalid hexadecimal constant `%S'\n", token, (char *)rcp-token);
00283 cp = rcp;
00284 tsym = icon(n, overflow, 16);
00285 } else if (*token == '0') {
00286 int err = 0, overflow = 0;
00287 for ( ; map[*rcp]&DIGIT; rcp++) {
00288 if (*rcp == '8' || *rcp == '9')
00289 err = 1;
00290 if (n&~(~0UL >> 3))
00291 overflow = 1;
00292 else
00293 n = (n<<3) + (*rcp - '0');
00294 }
00295 if (*rcp == '.' || *rcp == 'e' || *rcp == 'E') {
00296 cp = rcp;
00297 tsym = fcon();
00298 return FCON;
00299 }
00300 cp = rcp;
00301 tsym = icon(n, overflow, 8);
00302 if (err)
00303 error("invalid octal constant `%S'\n", token, (char*)cp-token);
00304 } else {
00305 int overflow = 0;
00306 for (n = *token - '0'; map[*rcp]&DIGIT; ) {
00307 int d = *rcp++ - '0';
00308 if (n > (ULONG_MAX - d)/10)
00309 overflow = 1;
00310 else
00311 n = 10*n + d;
00312 }
00313 if (*rcp == '.' || *rcp == 'e' || *rcp == 'E') {
00314 cp = rcp;
00315 tsym = fcon();
00316 return FCON;
00317 }
00318 cp = rcp;
00319 tsym = icon(n, overflow, 10);
00320 }
00321 return ICON;
00322 }
00323 case '.':
00324 if (rcp[0] == '.' && rcp[1] == '.') {
00325 cp += 2;
00326 return ELLIPSIS;
00327 }
00328 if ((map[*rcp]&DIGIT) == 0)
00329 return '.';
00330 if (limit - rcp < MAXLINE) {
00331 cp = rcp - 1;
00332 fillbuf();
00333 rcp = ++cp;
00334 }
00335 assert(cp == rcp);
00336 cp = rcp - 1;
00337 token = (char *)cp;
00338 tsym = fcon();
00339 return FCON;
00340 case 'L':
00341 if (*rcp == '\'') {
00342 unsigned int *s = scon(*cp, wcput, wcbuf);
00343 if (s - wcbuf > 2)
00344 warning("excess characters in wide-character literal ignored\n");
00345 tval.type = widechar;
00346 tval.u.c.v.u = wcbuf[0];
00347 tsym = &tval;
00348 return ICON;
00349 } else if (*rcp == '"') {
00350 unsigned int *s = scon(*cp, wcput, wcbuf);
00351 tval.type = array(widechar, s - wcbuf, 0);
00352 tval.u.c.v.p = wcbuf;
00353 tsym = &tval;
00354 return SCON;
00355 } else
00356 goto id;
00357 case '\'': {
00358 char *s = scon(*--cp, cput, cbuf);
00359 if (s - cbuf > 2)
00360 warning("excess characters in multibyte character literal ignored\n");
00361 tval.type = inttype;
00362 if (chartype->op == INT)
00363 tval.u.c.v.i = extend(cbuf[0], chartype);
00364 else
00365 tval.u.c.v.i = cbuf[0]&0xFF;
00366 tsym = &tval;
00367 return ICON;
00368 }
00369 case '"': {
00370 char *s = scon(*--cp, cput, cbuf);
00371 tval.type = array(chartype, s - cbuf, 0);
00372 tval.u.c.v.p = cbuf;
00373 tsym = &tval;
00374 return SCON;
00375 }
00376 case 'a':
00377 if (rcp[0] == 'u'
00378 && rcp[1] == 't'
00379 && rcp[2] == 'o'
00380 && !(map[rcp[3]]&(DIGIT|LETTER))) {
00381 cp = rcp + 3;
00382 return AUTO;
00383 }
00384 goto id;
00385 case 'b':
00386 if (rcp[0] == 'r'
00387 && rcp[1] == 'e'
00388 && rcp[2] == 'a'
00389 && rcp[3] == 'k'
00390 && !(map[rcp[4]]&(DIGIT|LETTER))) {
00391 cp = rcp + 4;
00392 return BREAK;
00393 }
00394 goto id;
00395 case 'c':
00396 if (rcp[0] == 'a'
00397 && rcp[1] == 's'
00398 && rcp[2] == 'e'
00399 && !(map[rcp[3]]&(DIGIT|LETTER))) {
00400 cp = rcp + 3;
00401 return CASE;
00402 }
00403 if (rcp[0] == 'h'
00404 && rcp[1] == 'a'
00405 && rcp[2] == 'r'
00406 && !(map[rcp[3]]&(DIGIT|LETTER))) {
00407 cp = rcp + 3;
00408 tsym = chartype->u.sym;
00409 return CHAR;
00410 }
00411 if (rcp[0] == 'o'
00412 && rcp[1] == 'n'
00413 && rcp[2] == 's'
00414 && rcp[3] == 't'
00415 && !(map[rcp[4]]&(DIGIT|LETTER))) {
00416 cp = rcp + 4;
00417 return CONST;
00418 }
00419 if (rcp[0] == 'o'
00420 && rcp[1] == 'n'
00421 && rcp[2] == 't'
00422 && rcp[3] == 'i'
00423 && rcp[4] == 'n'
00424 && rcp[5] == 'u'
00425 && rcp[6] == 'e'
00426 && !(map[rcp[7]]&(DIGIT|LETTER))) {
00427 cp = rcp + 7;
00428 return CONTINUE;
00429 }
00430 goto id;
00431 case 'd':
00432 if (rcp[0] == 'e'
00433 && rcp[1] == 'f'
00434 && rcp[2] == 'a'
00435 && rcp[3] == 'u'
00436 && rcp[4] == 'l'
00437 && rcp[5] == 't'
00438 && !(map[rcp[6]]&(DIGIT|LETTER))) {
00439 cp = rcp + 6;
00440 return DEFAULT;
00441 }
00442 if (rcp[0] == 'o'
00443 && rcp[1] == 'u'
00444 && rcp[2] == 'b'
00445 && rcp[3] == 'l'
00446 && rcp[4] == 'e'
00447 && !(map[rcp[5]]&(DIGIT|LETTER))) {
00448 cp = rcp + 5;
00449 tsym = doubletype->u.sym;
00450 return DOUBLE;
00451 }
00452 if (rcp[0] == 'o'
00453 && !(map[rcp[1]]&(DIGIT|LETTER))) {
00454 cp = rcp + 1;
00455 return DO;
00456 }
00457 goto id;
00458 case 'e':
00459 if (rcp[0] == 'l'
00460 && rcp[1] == 's'
00461 && rcp[2] == 'e'
00462 && !(map[rcp[3]]&(DIGIT|LETTER))) {
00463 cp = rcp + 3;
00464 return ELSE;
00465 }
00466 if (rcp[0] == 'n'
00467 && rcp[1] == 'u'
00468 && rcp[2] == 'm'
00469 && !(map[rcp[3]]&(DIGIT|LETTER))) {
00470 cp = rcp + 3;
00471 return ENUM;
00472 }
00473 if (rcp[0] == 'x'
00474 && rcp[1] == 't'
00475 && rcp[2] == 'e'
00476 && rcp[3] == 'r'
00477 && rcp[4] == 'n'
00478 && !(map[rcp[5]]&(DIGIT|LETTER))) {
00479 cp = rcp + 5;
00480 return EXTERN;
00481 }
00482 goto id;
00483 case 'f':
00484 if (rcp[0] == 'l'
00485 && rcp[1] == 'o'
00486 && rcp[2] == 'a'
00487 && rcp[3] == 't'
00488 && !(map[rcp[4]]&(DIGIT|LETTER))) {
00489 cp = rcp + 4;
00490 tsym = floattype->u.sym;
00491 return FLOAT;
00492 }
00493 if (rcp[0] == 'o'
00494 && rcp[1] == 'r'
00495 && !(map[rcp[2]]&(DIGIT|LETTER))) {
00496 cp = rcp + 2;
00497 return FOR;
00498 }
00499 goto id;
00500 case 'g':
00501 if (rcp[0] == 'o'
00502 && rcp[1] == 't'
00503 && rcp[2] == 'o'
00504 && !(map[rcp[3]]&(DIGIT|LETTER))) {
00505 cp = rcp + 3;
00506 return GOTO;
00507 }
00508 goto id;
00509 case 'l':
00510 if (rcp[0] == 'o'
00511 && rcp[1] == 'n'
00512 && rcp[2] == 'g'
00513 && !(map[rcp[3]]&(DIGIT|LETTER))) {
00514 cp = rcp + 3;
00515 return LONG;
00516 }
00517 goto id;
00518 case 'r':
00519 if (rcp[0] == 'e'
00520 && rcp[1] == 'g'
00521 && rcp[2] == 'i'
00522 && rcp[3] == 's'
00523 && rcp[4] == 't'
00524 && rcp[5] == 'e'
00525 && rcp[6] == 'r'
00526 && !(map[rcp[7]]&(DIGIT|LETTER))) {
00527 cp = rcp + 7;
00528 return REGISTER;
00529 }
00530 if (rcp[0] == 'e'
00531 && rcp[1] == 't'
00532 && rcp[2] == 'u'
00533 && rcp[3] == 'r'
00534 && rcp[4] == 'n'
00535 && !(map[rcp[5]]&(DIGIT|LETTER))) {
00536 cp = rcp + 5;
00537 return RETURN;
00538 }
00539 goto id;
00540 case 's':
00541 if (rcp[0] == 'h'
00542 && rcp[1] == 'o'
00543 && rcp[2] == 'r'
00544 && rcp[3] == 't'
00545 && !(map[rcp[4]]&(DIGIT|LETTER))) {
00546 cp = rcp + 4;
00547 return SHORT;
00548 }
00549 if (rcp[0] == 'i'
00550 && rcp[1] == 'g'
00551 && rcp[2] == 'n'
00552 && rcp[3] == 'e'
00553 && rcp[4] == 'd'
00554 && !(map[rcp[5]]&(DIGIT|LETTER))) {
00555 cp = rcp + 5;
00556 return SIGNED;
00557 }
00558 if (rcp[0] == 'i'
00559 && rcp[1] == 'z'
00560 && rcp[2] == 'e'
00561 && rcp[3] == 'o'
00562 && rcp[4] == 'f'
00563 && !(map[rcp[5]]&(DIGIT|LETTER))) {
00564 cp = rcp + 5;
00565 return SIZEOF;
00566 }
00567 if (rcp[0] == 't'
00568 && rcp[1] == 'a'
00569 && rcp[2] == 't'
00570 && rcp[3] == 'i'
00571 && rcp[4] == 'c'
00572 && !(map[rcp[5]]&(DIGIT|LETTER))) {
00573 cp = rcp + 5;
00574 return STATIC;
00575 }
00576 if (rcp[0] == 't'
00577 && rcp[1] == 'r'
00578 && rcp[2] == 'u'
00579 && rcp[3] == 'c'
00580 && rcp[4] == 't'
00581 && !(map[rcp[5]]&(DIGIT|LETTER))) {
00582 cp = rcp + 5;
00583 return STRUCT;
00584 }
00585 if (rcp[0] == 'w'
00586 && rcp[1] == 'i'
00587 && rcp[2] == 't'
00588 && rcp[3] == 'c'
00589 && rcp[4] == 'h'
00590 && !(map[rcp[5]]&(DIGIT|LETTER))) {
00591 cp = rcp + 5;
00592 return SWITCH;
00593 }
00594 goto id;
00595 case 't':
00596 if (rcp[0] == 'y'
00597 && rcp[1] == 'p'
00598 && rcp[2] == 'e'
00599 && rcp[3] == 'd'
00600 && rcp[4] == 'e'
00601 && rcp[5] == 'f'
00602 && !(map[rcp[6]]&(DIGIT|LETTER))) {
00603 cp = rcp + 6;
00604 return TYPEDEF;
00605 }
00606 goto id;
00607 case 'u':
00608 if (rcp[0] == 'n'
00609 && rcp[1] == 'i'
00610 && rcp[2] == 'o'
00611 && rcp[3] == 'n'
00612 && !(map[rcp[4]]&(DIGIT|LETTER))) {
00613 cp = rcp + 4;
00614 return UNION;
00615 }
00616 if (rcp[0] == 'n'
00617 && rcp[1] == 's'
00618 && rcp[2] == 'i'
00619 && rcp[3] == 'g'
00620 && rcp[4] == 'n'
00621 && rcp[5] == 'e'
00622 && rcp[6] == 'd'
00623 && !(map[rcp[7]]&(DIGIT|LETTER))) {
00624 cp = rcp + 7;
00625 return UNSIGNED;
00626 }
00627 goto id;
00628 case 'v':
00629 if (rcp[0] == 'o'
00630 && rcp[1] == 'i'
00631 && rcp[2] == 'd'
00632 && !(map[rcp[3]]&(DIGIT|LETTER))) {
00633 cp = rcp + 3;
00634 tsym = voidtype->u.sym;
00635 return VOID;
00636 }
00637 if (rcp[0] == 'o'
00638 && rcp[1] == 'l'
00639 && rcp[2] == 'a'
00640 && rcp[3] == 't'
00641 && rcp[4] == 'i'
00642 && rcp[5] == 'l'
00643 && rcp[6] == 'e'
00644 && !(map[rcp[7]]&(DIGIT|LETTER))) {
00645 cp = rcp + 7;
00646 return VOLATILE;
00647 }
00648 goto id;
00649 case 'w':
00650 if (rcp[0] == 'h'
00651 && rcp[1] == 'i'
00652 && rcp[2] == 'l'
00653 && rcp[3] == 'e'
00654 && !(map[rcp[4]]&(DIGIT|LETTER))) {
00655 cp = rcp + 4;
00656 return WHILE;
00657 }
00658 goto id;
00659 case '_':
00660 if (rcp[0] == '_'
00661 && rcp[1] == 't'
00662 && rcp[2] == 'y'
00663 && rcp[3] == 'p'
00664 && rcp[4] == 'e'
00665 && rcp[5] == 'c'
00666 && rcp[6] == 'o'
00667 && rcp[7] == 'd'
00668 && rcp[8] == 'e'
00669 && !(map[rcp[9]]&(DIGIT|LETTER))) {
00670 cp = rcp + 9;
00671 return TYPECODE;
00672 }
00673 if (rcp[0] == '_'
00674 && rcp[1] == 'f'
00675 && rcp[2] == 'i'
00676 && rcp[3] == 'r'
00677 && rcp[4] == 's'
00678 && rcp[5] == 't'
00679 && rcp[6] == 'a'
00680 && rcp[7] == 'r'
00681 && rcp[8] == 'g'
00682 && !(map[rcp[9]]&(DIGIT|LETTER))) {
00683 cp = rcp + 9;
00684 return FIRSTARG;
00685 }
00686 goto id;
00687 default:
00688 if ((map[cp[-1]]&BLANK) == 0)
00689 if (cp[-1] < ' ' || cp[-1] >= 0177)
00690 error("illegal character `\\0%o'\n", cp[-1]);
00691 else
00692 error("illegal character `%c'\n", cp[-1]);
00693 }
00694 }
00695 }
00696 static Symbol icon(unsigned long n, int overflow, int base) {
00697 if ((*cp=='u'||*cp=='U') && (cp[1]=='l'||cp[1]=='L')
00698 || (*cp=='l'||*cp=='L') && (cp[1]=='u'||cp[1]=='U')) {
00699 tval.type = unsignedlong;
00700 cp += 2;
00701 } else if (*cp == 'u' || *cp == 'U') {
00702 if (overflow || n > unsignedtype->u.sym->u.limits.max.i)
00703 tval.type = unsignedlong;
00704 else
00705 tval.type = unsignedtype;
00706 cp += 1;
00707 } else if (*cp == 'l' || *cp == 'L') {
00708 if (overflow || n > longtype->u.sym->u.limits.max.i)
00709 tval.type = unsignedlong;
00710 else
00711 tval.type = longtype;
00712 cp += 1;
00713 } else if (overflow || n > longtype->u.sym->u.limits.max.i)
00714 tval.type = unsignedlong;
00715 else if (n > inttype->u.sym->u.limits.max.i)
00716 tval.type = longtype;
00717 else if (base != 10 && n > inttype->u.sym->u.limits.max.i)
00718 tval.type = unsignedtype;
00719 else
00720 tval.type = inttype;
00721 switch (tval.type->op) {
00722 case INT:
00723 if (overflow || n > tval.type->u.sym->u.limits.max.i) {
00724 warning("overflow in constant `%S'\n", token,
00725 (char*)cp - token);
00726 tval.u.c.v.i = tval.type->u.sym->u.limits.max.i;
00727 } else
00728 tval.u.c.v.i = n;
00729 break;
00730 case UNSIGNED:
00731 if (overflow || n > tval.type->u.sym->u.limits.max.u) {
00732 warning("overflow in constant `%S'\n", token,
00733 (char*)cp - token);
00734 tval.u.c.v.u = tval.type->u.sym->u.limits.max.u;
00735 } else
00736 tval.u.c.v.u = n;
00737 break;
00738 default: assert(0);
00739 }
00740 ppnumber("integer");
00741 return &tval;
00742 }
00743 static void ppnumber(char *which) {
00744 unsigned char *rcp = cp--;
00745
00746 for ( ; (map[*cp]&(DIGIT|LETTER)) || *cp == '.'; cp++)
00747 if ((cp[0] == 'E' || cp[0] == 'e')
00748 && (cp[1] == '-' || cp[1] == '+'))
00749 cp++;
00750 if (cp > rcp)
00751 error("`%S' is a preprocessing number but an invalid %s constant\n", token,
00752
00753 (char*)cp-token, which);
00754 }
00755 static Symbol fcon(void) {
00756 if (*cp == '.')
00757 do
00758 cp++;
00759 while (map[*cp]&DIGIT);
00760 if (*cp == 'e' || *cp == 'E') {
00761 if (*++cp == '-' || *cp == '+')
00762 cp++;
00763 if (map[*cp]&DIGIT)
00764 do
00765 cp++;
00766 while (map[*cp]&DIGIT);
00767 else
00768 error("invalid floating constant `%S'\n", token,
00769 (char*)cp - token);
00770 }
00771
00772 errno = 0;
00773 tval.u.c.v.d = strtod(token, NULL);
00774 if (errno == ERANGE)
00775 warning("overflow in floating constant `%S'\n", token,
00776 (char*)cp - token);
00777 if (*cp == 'f' || *cp == 'F') {
00778 ++cp;
00779 if (tval.u.c.v.d > floattype->u.sym->u.limits.max.d)
00780 warning("overflow in floating constant `%S'\n", token,
00781 (char*)cp - token);
00782 tval.type = floattype;
00783 } else if (*cp == 'l' || *cp == 'L') {
00784 cp++;
00785 tval.type = longdouble;
00786 } else {
00787 if (tval.u.c.v.d > doubletype->u.sym->u.limits.max.d)
00788 warning("overflow in floating constant `%S'\n", token,
00789 (char*)cp - token);
00790 tval.type = doubletype;
00791 }
00792 ppnumber("floating");
00793 return &tval;
00794 }
00795
00796 static void *cput(int c, void *cl) {
00797 char *s = cl;
00798
00799 if (c < 0 || c > 255)
00800 warning("overflow in escape sequence with resulting value `%d'\n", c);
00801 *s++ = c;
00802 return s;
00803 }
00804
00805 static void *wcput(int c, void *cl) {
00806 unsigned int *s = cl;
00807
00808 *s++ = c;
00809 return s;
00810 }
00811
00812 static void *scon(int q, void *put(int c, void *cl), void *cl) {
00813 int n = 0, nbad = 0;
00814
00815 do {
00816 cp++;
00817 while (*cp != q) {
00818 int c;
00819 if (map[*cp]&NEWLINE) {
00820 if (cp < limit)
00821 break;
00822 cp++;
00823 nextline();
00824 if (cp == limit)
00825 break;
00826 continue;
00827 }
00828 c = *cp++;
00829 if (c == '\\') {
00830 if (map[*cp]&NEWLINE) {
00831 if (cp < limit)
00832 break;
00833 cp++;
00834 nextline();
00835 }
00836 if (limit - cp < MAXTOKEN)
00837 fillbuf();
00838 c = backslash(q);
00839 } else if (c < 0 || c > 255 || map[c] == 0)
00840 nbad++;
00841 if (n++ < BUFSIZE)
00842 cl = put(c, cl);
00843 }
00844 if (*cp == q)
00845 cp++;
00846 else
00847 error("missing %c\n", q);
00848 } while (q == '"' && getchr() == '"');
00849 cl = put(0, cl);
00850 if (n >= BUFSIZE)
00851 error("%s literal too long\n", q == '"' ? "string" : "character");
00852 if (Aflag >= 2 && q == '"' && n > 509)
00853 warning("more than 509 characters in a string literal\n");
00854 if (Aflag >= 2 && nbad > 0)
00855 warning("%s literal contains non-portable characters\n",
00856 q == '"' ? "string" : "character");
00857 return cl;
00858 }
00859 int getchr(void) {
00860 for (;;) {
00861 while (map[*cp]&BLANK)
00862 cp++;
00863 if (!(map[*cp]&NEWLINE))
00864 return *cp;
00865 cp++;
00866 nextline();
00867 if (cp == limit)
00868 return EOI;
00869 }
00870 }
00871 static int backslash(int q) {
00872 unsigned int c;
00873
00874 switch (*cp++) {
00875 case 'a': return 7;
00876 case 'b': return '\b';
00877 case 'f': return '\f';
00878 case 'n': return '\n';
00879 case 'r': return '\r';
00880 case 't': return '\t';
00881 case 'v': return '\v';
00882 case '\'': case '"': case '\\': case '\?': break;
00883 case 'x': {
00884 int overflow = 0;
00885 if ((map[*cp]&(DIGIT|HEX)) == 0) {
00886 if (*cp < ' ' || *cp == 0177)
00887 error("ill-formed hexadecimal escape sequence\n");
00888 else
00889 error("ill-formed hexadecimal escape sequence `\\x%c'\n", *cp);
00890 if (*cp != q)
00891 cp++;
00892 return 0;
00893 }
00894 for (c = 0; map[*cp]&(DIGIT|HEX); cp++) {
00895 if (c >> (8*widechar->size - 4))
00896 overflow = 1;
00897 if (map[*cp]&DIGIT)
00898 c = (c<<4) + *cp - '0';
00899 else
00900 c = (c<<4) + (*cp&~040) - 'A' + 10;
00901 }
00902 if (overflow)
00903 warning("overflow in hexadecimal escape sequence\n");
00904 return c&ones(8*widechar->size);
00905 }
00906 case '0': case '1': case '2': case '3':
00907 case '4': case '5': case '6': case '7':
00908 c = *(cp-1) - '0';
00909 if (*cp >= '0' && *cp <= '7') {
00910 c = (c<<3) + *cp++ - '0';
00911 if (*cp >= '0' && *cp <= '7')
00912 c = (c<<3) + *cp++ - '0';
00913 }
00914 return c;
00915 default:
00916 if (cp[-1] < ' ' || cp[-1] >= 0177)
00917 warning("unrecognized character escape sequence\n");
00918 else
00919 warning("unrecognized character escape sequence `\\%c'\n", cp[-1]);
00920 }
00921 return cp[-1];
00922 }