Unified · Split
| @@ -463,6 +463,7 @@ struct TCCState { · 462 unmodified lines | ||
| 463 | 463 | #define TOK_ARROW 0xcb |
| 464 | 464 | #define TOK_DOTS 0xcc /* three dots */ |
| 465 | 465 | #define TOK_SHR 0xcd /* unsigned shift right */ |
| 466 | +#define TOK_PPNUM 0xce /* preprocessor number */ | |
| 466 | 467 | |
| 467 | 468 | #define TOK_SHL 0x01 /* shift left */ |
| 468 | 469 | #define TOK_SAR 0x02 /* signed shift right */ |
| @@ -1029,10 +1030,10 @@ static inline int isoct(int c) · 560 unmodified lines | ||
| 1029 | 1030 | |
| 1030 | 1031 | static inline int toup(int c) |
| 1031 | 1032 | { |
| 1032 | − if (ch >= 'a' && ch <= 'z') | |
| 1033 | − return ch - 'a' + 'A'; | |
| 1033 | + if (c >= 'a' && c <= 'z') | |
| 1034 | + return c - 'a' + 'A'; | |
| 1034 | 1035 | else |
| 1035 | − return ch; | |
| 1036 | + return c; | |
| 1036 | 1037 | } |
| 1037 | 1038 | |
| 1038 | 1039 | static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap) |
| @@ -1081,7 +1082,8 @@ void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap) · 42 unmodified lines | ||
| 1081 | 1082 | } else { |
| 1082 | 1083 | s1->error_func(s1->error_opaque, buf); |
| 1083 | 1084 | } |
| 1084 | − s1->nb_errors++; | |
| 1085 | + if (!is_warning) | |
| 1086 | + s1->nb_errors++; | |
| 1085 | 1087 | } |
| 1086 | 1088 | |
| 1087 | 1089 | #ifdef LIBTCC |
| @@ -1314,6 +1316,12 @@ char *get_tok_str(int v, CValue *cv) · 226 unmodified lines | ||
| 1314 | 1316 | cstr_ccat(&cstr_buf, '\''); |
| 1315 | 1317 | cstr_ccat(&cstr_buf, '\0'); |
| 1316 | 1318 | break; |
| 1319 | + case TOK_PPNUM: | |
| 1320 | + cstr = cv->cstr; | |
| 1321 | + len = cstr->size - 1; | |
| 1322 | + for(i=0;i<len;i++) | |
| 1323 | + add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]); | |
| 1324 | + break; | |
| 1317 | 1325 | case TOK_STR: |
| 1318 | 1326 | case TOK_LSTR: |
| 1319 | 1327 | cstr = cv->cstr; |
| @@ -1724,6 +1732,7 @@ static inline int tok_ext_size(int t) · 404 unmodified lines | ||
| 1724 | 1732 | case TOK_LSTR: |
| 1725 | 1733 | case TOK_CFLOAT: |
| 1726 | 1734 | case TOK_LINENUM: |
| 1735 | + case TOK_PPNUM: | |
| 1727 | 1736 | return 1; |
| 1728 | 1737 | case TOK_CDOUBLE: |
| 1729 | 1738 | case TOK_CLLONG: |
| @@ -1756,7 +1765,7 @@ static void tok_str_free(int *str) · 26 unmodified lines | ||
| 1756 | 1765 | t = *p++; |
| 1757 | 1766 | if (t == 0) |
| 1758 | 1767 | break; |
| 1759 | − if (t == TOK_STR || t == TOK_LSTR) { | |
| 1768 | + if (t == TOK_STR || t == TOK_LSTR || t == TOK_PPNUM) { | |
| 1760 | 1769 | /* XXX: use a macro to be portable on 64 bit ? */ |
| 1761 | 1770 | cstr = (CString *)(*p++); |
| 1762 | 1771 | cstr_free(cstr); |
| @@ -1791,7 +1800,7 @@ static void tok_str_add2(TokenString *s, int t, CValue *cv) · 28 unmodified lines | ||
| 1791 | 1800 | CValue cv1; |
| 1792 | 1801 | |
| 1793 | 1802 | tok_str_add(s, t); |
| 1794 | − if (t == TOK_STR || t == TOK_LSTR) { | |
| 1803 | + if (t == TOK_STR || t == TOK_LSTR || t == TOK_PPNUM) { | |
| 1795 | 1804 | /* special case: need to duplicate string */ |
| 1796 | 1805 | cstr1 = cv->cstr; |
| 1797 | 1806 | cstr = tcc_malloc(sizeof(CString)); |
| @@ -2325,42 +2334,32 @@ void bn_zero(unsigned int *bn) · 527 unmodified lines | ||
| 2325 | 2334 | } |
| 2326 | 2335 | } |
| 2327 | 2336 | |
| 2328 | −void parse_number(void) | |
| 2337 | +/* parse number in null terminated string 'p' and return it in the | |
| 2338 | + current token */ | |
| 2339 | +void parse_number(const char *p) | |
| 2329 | 2340 | { |
| 2330 | − int b, t, shift, frac_bits, s, exp_val; | |
| 2341 | + int b, t, shift, frac_bits, s, exp_val, ch; | |
| 2331 | 2342 | char *q; |
| 2332 | 2343 | unsigned int bn[BN_SIZE]; |
| 2333 | 2344 | double d; |
| 2334 | 2345 | |
| 2335 | 2346 | /* number */ |
| 2336 | 2347 | q = token_buf; |
| 2348 | + ch = *p++; | |
| 2337 | 2349 | t = ch; |
| 2338 | − cinp(); | |
| 2350 | + ch = *p++; | |
| 2339 | 2351 | *q++ = t; |
| 2340 | 2352 | b = 10; |
| 2341 | 2353 | if (t == '.') { |
| 2342 | − /* special dot handling */ | |
| 2343 | − if (ch >= '0' && ch <= '9') { | |
| 2344 | − goto float_frac_parse; | |
| 2345 | − } else if (ch == '.') { | |
| 2346 | − cinp(); | |
| 2347 | − if (ch != '.') | |
| 2348 | − expect("'.'"); | |
| 2349 | − cinp(); | |
| 2350 | − tok = TOK_DOTS; | |
| 2351 | − } else { | |
| 2352 | − /* dots */ | |
| 2353 | − tok = t; | |
| 2354 | − } | |
| 2355 | − return; | |
| 2354 | + goto float_frac_parse; | |
| 2356 | 2355 | } else if (t == '0') { |
| 2357 | 2356 | if (ch == 'x' || ch == 'X') { |
| 2358 | 2357 | q--; |
| 2359 | − cinp(); | |
| 2358 | + ch = *p++; | |
| 2360 | 2359 | b = 16; |
| 2361 | 2360 | } else if (tcc_ext && (ch == 'b' || ch == 'B')) { |
| 2362 | 2361 | q--; |
| 2363 | − cinp(); | |
| 2362 | + ch = *p++; | |
| 2364 | 2363 | b = 2; |
| 2365 | 2364 | } |
| 2366 | 2365 | } |
| @@ -2382,7 +2381,7 @@ void parse_number(void) · 15 unmodified lines | ||
| 2382 | 2381 | error("number too long"); |
| 2383 | 2382 | } |
| 2384 | 2383 | *q++ = ch; |
| 2385 | − cinp(); | |
| 2384 | + ch = *p++; | |
| 2386 | 2385 | } |
| 2387 | 2386 | if (ch == '.' || |
| 2388 | 2387 | ((ch == 'e' || ch == 'E') && b == 10) || |
| @@ -2415,7 +2414,7 @@ void parse_number(void) · 26 unmodified lines | ||
| 2415 | 2414 | } |
| 2416 | 2415 | frac_bits = 0; |
| 2417 | 2416 | if (ch == '.') { |
| 2418 | − cinp(); | |
| 2417 | + ch = *p++; | |
| 2419 | 2418 | while (1) { |
| 2420 | 2419 | t = ch; |
| 2421 | 2420 | if (t >= 'a' && t <= 'f') { |
| @@ -2431,25 +2430,25 @@ void parse_number(void) · 9 unmodified lines | ||
| 2431 | 2430 | error("invalid digit"); |
| 2432 | 2431 | bn_lshift(bn, shift, t); |
| 2433 | 2432 | frac_bits += shift; |
| 2434 | − cinp(); | |
| 2433 | + ch = *p++; | |
| 2435 | 2434 | } |
| 2436 | 2435 | } |
| 2437 | 2436 | if (ch != 'p' && ch != 'P') |
| 2438 | 2437 | error("exponent expected"); |
| 2439 | − cinp(); | |
| 2438 | + ch = *p++; | |
| 2440 | 2439 | s = 1; |
| 2441 | 2440 | exp_val = 0; |
| 2442 | 2441 | if (ch == '+') { |
| 2443 | − cinp(); | |
| 2442 | + ch = *p++; | |
| 2444 | 2443 | } else if (ch == '-') { |
| 2445 | 2444 | s = -1; |
| 2446 | − cinp(); | |
| 2445 | + ch = *p++; | |
| 2447 | 2446 | } |
| 2448 | 2447 | if (ch < '0' || ch > '9') |
| 2449 | 2448 | error("exponent digits expected"); |
| 2450 | 2449 | while (ch >= '0' && ch <= '9') { |
| 2451 | 2450 | exp_val = exp_val * 10 + ch - '0'; |
| 2452 | − cinp(); | |
| 2451 | + ch = *p++; | |
| 2453 | 2452 | } |
| 2454 | 2453 | exp_val = exp_val * s; |
| 2455 | 2454 | |
| @@ -2459,12 +2458,12 @@ void parse_number(void) · 3 unmodified lines | ||
| 2459 | 2458 | d = ldexp(d, exp_val - frac_bits); |
| 2460 | 2459 | t = toup(ch); |
| 2461 | 2460 | if (t == 'F') { |
| 2462 | − cinp(); | |
| 2461 | + ch = *p++; | |
| 2463 | 2462 | tok = TOK_CFLOAT; |
| 2464 | 2463 | /* float : should handle overflow */ |
| 2465 | 2464 | tokc.f = (float)d; |
| 2466 | 2465 | } else if (t == 'L') { |
| 2467 | − cinp(); | |
| 2466 | + ch = *p++; | |
| 2468 | 2467 | tok = TOK_CLDOUBLE; |
| 2469 | 2468 | /* XXX: not large enough */ |
| 2470 | 2469 | tokc.ld = (long double)d; |
| @@ -2478,25 +2477,25 @@ void parse_number(void) · 7 unmodified lines | ||
| 2478 | 2477 | if (q >= token_buf + STRING_MAX_SIZE) |
| 2479 | 2478 | goto num_too_long; |
| 2480 | 2479 | *q++ = ch; |
| 2481 | − cinp(); | |
| 2480 | + ch = *p++; | |
| 2482 | 2481 | float_frac_parse: |
| 2483 | 2482 | while (ch >= '0' && ch <= '9') { |
| 2484 | 2483 | if (q >= token_buf + STRING_MAX_SIZE) |
| 2485 | 2484 | goto num_too_long; |
| 2486 | 2485 | *q++ = ch; |
| 2487 | − cinp(); | |
| 2486 | + ch = *p++; | |
| 2488 | 2487 | } |
| 2489 | 2488 | } |
| 2490 | 2489 | if (ch == 'e' || ch == 'E') { |
| 2491 | 2490 | if (q >= token_buf + STRING_MAX_SIZE) |
| 2492 | 2491 | goto num_too_long; |
| 2493 | 2492 | *q++ = ch; |
| 2494 | − cinp(); | |
| 2493 | + ch = *p++; | |
| 2495 | 2494 | if (ch == '-' || ch == '+') { |
| 2496 | 2495 | if (q >= token_buf + STRING_MAX_SIZE) |
| 2497 | 2496 | goto num_too_long; |
| 2498 | 2497 | *q++ = ch; |
| 2499 | − cinp(); | |
| 2498 | + ch = *p++; | |
| 2500 | 2499 | } |
| 2501 | 2500 | if (ch < '0' || ch > '9') |
| 2502 | 2501 | error("exponent digits expected"); |
| @@ -2504,18 +2503,18 @@ void parse_number(void) · 1 unmodified line | ||
| 2504 | 2503 | if (q >= token_buf + STRING_MAX_SIZE) |
| 2505 | 2504 | goto num_too_long; |
| 2506 | 2505 | *q++ = ch; |
| 2507 | − cinp(); | |
| 2506 | + ch = *p++; | |
| 2508 | 2507 | } |
| 2509 | 2508 | } |
| 2510 | 2509 | *q = '\0'; |
| 2511 | 2510 | t = toup(ch); |
| 2512 | 2511 | errno = 0; |
| 2513 | 2512 | if (t == 'F') { |
| 2514 | − cinp(); | |
| 2513 | + ch = *p++; | |
| 2515 | 2514 | tok = TOK_CFLOAT; |
| 2516 | 2515 | tokc.f = strtof(token_buf, NULL); |
| 2517 | 2516 | } else if (t == 'L') { |
| 2518 | − cinp(); | |
| 2517 | + ch = *p++; | |
| 2519 | 2518 | tok = TOK_CLDOUBLE; |
| 2520 | 2519 | tokc.ld = strtold(token_buf, NULL); |
| 2521 | 2520 | } else { |
| @@ -2525,7 +2524,7 @@ void parse_number(void) · 3 unmodified lines | ||
| 2525 | 2524 | } |
| 2526 | 2525 | } else { |
| 2527 | 2526 | unsigned long long n, n1; |
| 2528 | − int lcount; | |
| 2527 | + int lcount, ucount; | |
| 2529 | 2528 | |
| 2530 | 2529 | /* integer number */ |
| 2531 | 2530 | *q = '\0'; |
| @@ -2552,6 +2551,7 @@ void parse_number(void) · 20 unmodified lines | ||
| 2552 | 2551 | n1 = n; |
| 2553 | 2552 | n = n * b + t; |
| 2554 | 2553 | /* detect overflow */ |
| 2554 | + /* XXX: this test is not reliable */ | |
| 2555 | 2555 | if (n < n1) |
| 2556 | 2556 | error("integer constant overflow"); |
| 2557 | 2557 | } |
| @@ -2568,11 +2568,12 @@ void parse_number(void) · 10 unmodified lines | ||
| 2568 | 2568 | tok = TOK_CINT; |
| 2569 | 2569 | } |
| 2570 | 2570 | lcount = 0; |
| 2571 | + ucount = 0; | |
| 2571 | 2572 | for(;;) { |
| 2572 | 2573 | t = toup(ch); |
| 2573 | 2574 | if (t == 'L') { |
| 2574 | 2575 | if (lcount >= 2) |
| 2575 | − error("three 'l' in integer constant"); | |
| 2576 | + error("three 'l's in integer constant"); | |
| 2576 | 2577 | lcount++; |
| 2577 | 2578 | if (lcount == 2) { |
| 2578 | 2579 | if (tok == TOK_CINT) |
| @@ -2580,13 +2581,16 @@ void parse_number(void) · 1 unmodified line | ||
| 2580 | 2581 | else if (tok == TOK_CUINT) |
| 2581 | 2582 | tok = TOK_CULLONG; |
| 2582 | 2583 | } |
| 2583 | − cinp(); | |
| 2584 | + ch = *p++; | |
| 2584 | 2585 | } else if (t == 'U') { |
| 2586 | + if (ucount >= 1) | |
| 2587 | + error("two 'u's in integer constant"); | |
| 2588 | + ucount++; | |
| 2585 | 2589 | if (tok == TOK_CINT) |
| 2586 | 2590 | tok = TOK_CUINT; |
| 2587 | 2591 | else if (tok == TOK_CLLONG) |
| 2588 | 2592 | tok = TOK_CULLONG; |
| 2589 | − cinp(); | |
| 2593 | + ch = *p++; | |
| 2590 | 2594 | } else { |
| 2591 | 2595 | break; |
| 2592 | 2596 | } |
| @@ -2598,7 +2602,6 @@ void parse_number(void) · 5 unmodified lines | ||
| 2598 | 2602 | } |
| 2599 | 2603 | } |
| 2600 | 2604 | |
| 2601 | − | |
| 2602 | 2605 | /* return next token without macro substitution */ |
| 2603 | 2606 | static inline void next_nomacro1(void) |
| 2604 | 2607 | { |
| @@ -2649,8 +2652,42 @@ static inline void next_nomacro1(void) · 44 unmodified lines | ||
| 2649 | 2652 | *q = '\0'; |
| 2650 | 2653 | ts = tok_alloc(token_buf, q - token_buf); |
| 2651 | 2654 | tok = ts->tok; |
| 2652 | − } else if (isnum(ch) || ch == '.') { | |
| 2653 | − parse_number(); | |
| 2655 | + } else if (isnum(ch)) { | |
| 2656 | + int t; | |
| 2657 | + cstr_reset(&tokcstr); | |
| 2658 | + /* after the first digit, accept digits, alpha, '.' or sign if | |
| 2659 | + prefixed by 'eEpP' */ | |
| 2660 | + parse_num: | |
| 2661 | + for(;;) { | |
| 2662 | + t = ch; | |
| 2663 | + cstr_ccat(&tokcstr, ch); | |
| 2664 | + cinp(); | |
| 2665 | + if (!(isnum(ch) || isid(ch) || ch == '.' || | |
| 2666 | + ((ch == '+' || ch == '-') && | |
| 2667 | + (t == 'e' || t == 'E' || t == 'p' || t == 'P')))) | |
| 2668 | + break; | |
| 2669 | + } | |
| 2670 | + /* We add a trailing '\0' to ease parsing */ | |
| 2671 | + cstr_ccat(&tokcstr, '\0'); | |
| 2672 | + tokc.cstr = &tokcstr; | |
| 2673 | + tok = TOK_PPNUM; | |
| 2674 | + } else if (ch == '.') { | |
| 2675 | + /* special dot handling because it can also start a number */ | |
| 2676 | + cinp(); | |
| 2677 | + if (isnum(ch)) { | |
| 2678 | + cstr_reset(&tokcstr); | |
| 2679 | + cstr_ccat(&tokcstr, '.'); | |
| 2680 | + goto parse_num; | |
| 2681 | + } | |
| 2682 | + if (ch == '.') { | |
| 2683 | + cinp(); | |
| 2684 | + if (ch != '.') | |
| 2685 | + expect("'.'"); | |
| 2686 | + cinp(); | |
| 2687 | + tok = TOK_DOTS; | |
| 2688 | + } else { | |
| 2689 | + tok = '.'; | |
| 2690 | + } | |
| 2654 | 2691 | } else if (ch == '\'') { |
| 2655 | 2692 | tok = TOK_CCHAR; |
| 2656 | 2693 | char_const: |
| @@ -2824,13 +2861,6 @@ int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args) · 167 unmodified lines | ||
| 2824 | 2861 | return str.str; |
| 2825 | 2862 | } |
| 2826 | 2863 | |
| 2827 | −/* not inline to save space */ | |
| 2828 | −static int is_tok_num(int t) | |
| 2829 | −{ | |
| 2830 | − return (t == TOK_CINT || t == TOK_CUINT || | |
| 2831 | − t == TOK_CLLONG || t == TOK_CULLONG); | |
| 2832 | −} | |
| 2833 | − | |
| 2834 | 2864 | /* handle the '##' operator */ |
| 2835 | 2865 | static int *macro_twosharps(void) |
| 2836 | 2866 | { |
| @@ -2840,7 +2870,9 @@ static int *macro_twosharps(void) · 3 unmodified lines | ||
| 2840 | 2870 | const char *p1, *p2; |
| 2841 | 2871 | CValue cval; |
| 2842 | 2872 | TokenString macro_str1; |
| 2843 | − | |
| 2873 | + CString cstr; | |
| 2874 | + | |
| 2875 | + cstr_new(&cstr); | |
| 2844 | 2876 | tok_str_new(¯o_str1); |
| 2845 | 2877 | tok = 0; |
| 2846 | 2878 | while (1) { |
| @@ -2853,49 +2885,86 @@ static int *macro_twosharps(void) · 6 unmodified lines | ||
| 2853 | 2885 | t = *macro_ptr; |
| 2854 | 2886 | if (t) { |
| 2855 | 2887 | t = tok_get(¯o_ptr, &cval); |
| 2856 | − /* XXX: not exact, but cannot do more without | |
| 2857 | − modifying the whole preprocessing architecture ! */ | |
| 2858 | − /* XXX: handle arbitrary size */ | |
| 2888 | + | |
| 2889 | + /* We concatenate the two tokens if we have an | |
| 2890 | + identifier or a preprocessing number */ | |
| 2891 | + cstr_reset(&cstr); | |
| 2859 | 2892 | p1 = get_tok_str(tok, &tokc); |
| 2860 | − pstrcpy(token_buf, sizeof(token_buf), p1); | |
| 2893 | + cstr_cat(&cstr, p1); | |
| 2861 | 2894 | p2 = get_tok_str(t, &cval); |
| 2862 | − if (tok >= TOK_IDENT && | |
| 2863 | − (t >= TOK_IDENT || is_tok_num(t))) { | |
| 2864 | − pstrcat(token_buf, sizeof(token_buf), p2); | |
| 2865 | − ts = tok_alloc(token_buf, strlen(token_buf)); | |
| 2866 | − tok = ts->tok; /* modify current token */ | |
| 2867 | − } else if (is_tok_num(tok) && is_tok_num(t)) { | |
| 2868 | − unsigned long long n; | |
| 2869 | − do_num: | |
| 2870 | − pstrcat(token_buf, sizeof(token_buf), p2); | |
| 2871 | − n = strtoull(token_buf, NULL, 10); | |
| 2872 | − if ((n & 0xffffffff00000000LL) != 0) { | |
| 2873 | − if ((n >> 63) != 0) | |
| 2874 | − tok = TOK_CULLONG; | |
| 2875 | − else | |
| 2876 | − tok = TOK_CLLONG; | |
| 2877 | − } else if (n > 0x7fffffff) { | |
| 2878 | − tok = TOK_CUINT; | |
| 2895 | + cstr_cat(&cstr, p2); | |
| 2896 | + cstr_ccat(&cstr, '\0'); | |
| 2897 | + | |
| 2898 | + if ((tok >= TOK_IDENT || tok == TOK_PPNUM) && | |
| 2899 | + (t >= TOK_IDENT || t == TOK_PPNUM)) { | |
| 2900 | + if (tok == TOK_PPNUM) { | |
| 2901 | + /* if number, then create a number token */ | |
| 2902 | + /* NOTE: no need to allocate because | |
| 2903 | + tok_str_add2() does it */ | |
| 2904 | + tokc.cstr = &cstr; | |
| 2879 | 2905 | } else { |
| 2880 | − tok = TOK_CINT; | |
| 2906 | + /* if identifier, we must do a test to | |
| 2907 | + validate we have a correct identifier */ | |
| 2908 | + if (t == TOK_PPNUM) { | |
| 2909 | + const char *p; | |
| 2910 | + int c; | |
| 2911 | + | |
| 2912 | + p = p2; | |
| 2913 | + for(;;) { | |
| 2914 | + c = *p; | |
| 2915 | + if (c == '\0') | |
| 2916 | + break; | |
| 2917 | + p++; | |
| 2918 | + if (!isnum(c) && !isid(c)) | |
| 2919 | + goto error_pasting; | |
| 2920 | + } | |
| 2921 | + } | |
| 2922 | + ts = tok_alloc(cstr.data, strlen(cstr.data)); | |
| 2923 | + tok = ts->tok; /* modify current token */ | |
| 2881 | 2924 | } |
| 2882 | − if (tok == TOK_CINT || tok == TOK_CUINT) | |
| 2883 | − tokc.ui = n; | |
| 2884 | − else | |
| 2885 | − tokc.ull = n; | |
| 2886 | − } else if (is_tok_num(tok) && t >= TOK_IDENT) { | |
| 2887 | − /* incorrect, but suffisant for '1LL' case */ | |
| 2888 | − goto do_num; | |
| 2889 | 2925 | } else { |
| 2890 | − warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", token_buf, p2); | |
| 2891 | − /* cannot merge tokens: skip '##' */ | |
| 2892 | − macro_ptr = macro_ptr1; | |
| 2893 | − break; | |
| 2926 | + const char *str = cstr.data; | |
| 2927 | + const unsigned char *q; | |
| 2928 | + | |
| 2929 | + /* we look for a valid token */ | |
| 2930 | + /* XXX: do more extensive checks */ | |
| 2931 | + if (!strcmp(str, ">>=")) { | |
| 2932 | + tok = TOK_A_SAR; | |
| 2933 | + } else if (!strcmp(str, "<<=")) { | |
| 2934 | + tok = TOK_A_SHL; | |
| 2935 | + } else if (strlen(str) == 2) { | |
| 2936 | + /* search in two bytes table */ | |
| 2937 | + q = tok_two_chars; | |
| 2938 | + for(;;) { | |
| 2939 | + if (!*q) | |
| 2940 | + goto error_pasting; | |
| 2941 | + if (q[0] == str[0] && q[1] == str[1]) | |
| 2942 | + break; | |
| 2943 | + q += 3; | |
| 2944 | + } | |
| 2945 | + tok = q[2]; | |
| 2946 | + } else { | |
| 2947 | + error_pasting: | |
| 2948 | + /* NOTE: because get_tok_str use a static buffer, | |
| 2949 | + we must save it */ | |
| 2950 | + cstr_reset(&cstr); | |
| 2951 | + p1 = get_tok_str(tok, &tokc); | |
| 2952 | + cstr_cat(&cstr, p1); | |
| 2953 | + cstr_ccat(&cstr, '\0'); | |
| 2954 | + p2 = get_tok_str(t, &cval); | |
| 2955 | + warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr.data, p2); | |
| 2956 | + /* cannot merge tokens: just add them separately */ | |
| 2957 | + tok_str_add2(¯o_str1, tok, &tokc); | |
| 2958 | + /* XXX: free associated memory ? */ | |
| 2959 | + tok = t; | |
| 2960 | + tokc = cval; | |
| 2961 | + } | |
| 2894 | 2962 | } |
| 2895 | 2963 | } |
| 2896 | 2964 | } |
| 2897 | 2965 | tok_str_add2(¯o_str1, tok, &tokc); |
| 2898 | 2966 | } |
| 2967 | + cstr_free(&cstr); | |
| 2899 | 2968 | tok_str_add(¯o_str1, 0); |
| 2900 | 2969 | return macro_str1.str; |
| 2901 | 2970 | } |
| @@ -3100,6 +3169,11 @@ void next(void) · 198 unmodified lines | ||
| 3100 | 3169 | goto redo; |
| 3101 | 3170 | } |
| 3102 | 3171 | } |
| 3172 | + | |
| 3173 | + /* convert preprocessor tokens into C tokens */ | |
| 3174 | + if (tok == TOK_PPNUM) { | |
| 3175 | + parse_number((char *)tokc.cstr->data); | |
| 3176 | + } | |
| 3103 | 3177 | } |
| 3104 | 3178 | #if defined(DEBUG) |
| 3105 | 3179 | printf("token = %s\n", get_tok_str(tok, &tokc)); |