Insert a space when it is required to prevent mistokenisation of the output, and also in a few cases where it is not strictly required, imitating GCC's behaviour.
Unified · Split
| @@ -31,7 +31,6 @@ Bugs: · 30 unmodified lines | |||
| 31 | - make libtcc fully reentrant (except for the compilation stage itself). | 31 | - make libtcc fully reentrant (except for the compilation stage itself). |
| 32 | - struct/union/enum definitions in nested scopes (see also Debian bug #770657) | 32 | - struct/union/enum definitions in nested scopes (see also Debian bug #770657) |
| 33 | - __STDC_IEC_559__: float f(void) { static float x = 0.0 / 0.0; return x; } | 33 | - __STDC_IEC_559__: float f(void) { static float x = 0.0 / 0.0; return x; } |
| 34 | - preprocessor: #define Y(x) Z(x) {newline} #define X Y {newline} X(X(1)) | ||
| 35 | 34 | ||
| 36 | Portability: | 35 | Portability: |
| 37 | 36 | ||
| @@ -94,7 +93,6 @@ Not critical: · 56 unmodified lines | |||
| 94 | - handle void (__attribute__() *ptr)() | 93 | - handle void (__attribute__() *ptr)() |
| 95 | - VLAs are implemented in a way that is not compatible with signals: | 94 | - VLAs are implemented in a way that is not compatible with signals: |
| 96 | http://lists.gnu.org/archive/html/tinycc-devel/2015-11/msg00018.html | 95 | http://lists.gnu.org/archive/html/tinycc-devel/2015-11/msg00018.html |
| 97 | - output with -E should include spaces: #define n 0xe {newline} n+1 | ||
| 98 | 96 | ||
| 99 | Fixed (probably): | 97 | Fixed (probably): |
| 100 | 98 | ||
| @@ -3644,12 +3644,61 @@ static void pp_debug_builtins(TCCState *s1) · 3643 unmodified lines | |||
| 3644 | define_print(s1, v); | 3644 | define_print(s1, v); |
| 3645 | } | 3645 | } |
| 3646 | 3646 | ||
| 3647 | static int need_space(int prev_tok, int tok, const char *tokstr) | ||
| 3648 | { | ||
| 3649 | const char *sp_chars = ""; | ||
| 3650 | if ((prev_tok >= TOK_IDENT || prev_tok == TOK_PPNUM) && | ||
| 3651 | (tok >= TOK_IDENT || tok == TOK_PPNUM)) | ||
| 3652 | return 1; | ||
| 3653 | switch (prev_tok) { | ||
| 3654 | case '+': | ||
| 3655 | sp_chars = "+="; | ||
| 3656 | break; | ||
| 3657 | case '-': | ||
| 3658 | sp_chars = "-=>"; | ||
| 3659 | break; | ||
| 3660 | case '*': | ||
| 3661 | case '/': | ||
| 3662 | case '%': | ||
| 3663 | case '^': | ||
| 3664 | case '=': | ||
| 3665 | case '!': | ||
| 3666 | case TOK_A_SHL: | ||
| 3667 | case TOK_A_SAR: | ||
| 3668 | sp_chars = "="; | ||
| 3669 | break; | ||
| 3670 | case '&': | ||
| 3671 | sp_chars = "&="; | ||
| 3672 | break; | ||
| 3673 | case '|': | ||
| 3674 | sp_chars = "|="; | ||
| 3675 | break; | ||
| 3676 | case '<': | ||
| 3677 | sp_chars = "<="; | ||
| 3678 | break; | ||
| 3679 | case '>': | ||
| 3680 | sp_chars = ">="; | ||
| 3681 | break; | ||
| 3682 | case '.': | ||
| 3683 | sp_chars = "."; | ||
| 3684 | break; | ||
| 3685 | case '#': | ||
| 3686 | sp_chars = "#"; | ||
| 3687 | break; | ||
| 3688 | case TOK_PPNUM: | ||
| 3689 | sp_chars = "+-"; | ||
| 3690 | break; | ||
| 3691 | } | ||
| 3692 | return !!strchr(sp_chars, tokstr[0]); | ||
| 3693 | } | ||
| 3694 | |||
| 3647 | /* Preprocess the current file */ | 3695 | /* Preprocess the current file */ |
| 3648 | ST_FUNC int tcc_preprocess(TCCState *s1) | 3696 | ST_FUNC int tcc_preprocess(TCCState *s1) |
| 3649 | { | 3697 | { |
| 3650 | BufferedFile **iptr; | 3698 | BufferedFile **iptr; |
| 3651 | int token_seen, spcs, level; | 3699 | int token_seen, spcs, level; |
| 3652 | Sym *define_start; | 3700 | Sym *define_start; |
| 3701 | const char *tokstr; | ||
| 3653 | 3702 | ||
| 3654 | preprocess_init(s1); | 3703 | preprocess_init(s1); |
| 3655 | ch = file->buf_ptr[0]; | 3704 | ch = file->buf_ptr[0]; |
| @@ -3707,9 +3756,12 @@ ST_FUNC int tcc_preprocess(TCCState *s1) · 51 unmodified lines | |||
| 3707 | ++file->line_ref; | 3756 | ++file->line_ref; |
| 3708 | } | 3757 | } |
| 3709 | 3758 | ||
| 3759 | tokstr = get_tok_str(tok, &tokc); | ||
| 3760 | if (!spcs && need_space(token_seen, tok, tokstr)) | ||
| 3761 | ++spcs; | ||
| 3710 | while (spcs) | 3762 | while (spcs) |
| 3711 | fputs(" ", s1->ppfp), --spcs; | 3763 | fputs(" ", s1->ppfp), --spcs; |
| 3712 | fputs(get_tok_str(tok, &tokc), s1->ppfp); | 3764 | fputs(tokstr, s1->ppfp); |
| 3713 | 3765 | ||
| 3714 | token_seen = tok; | 3766 | token_seen = tok; |
| 3715 | } | 3767 | } |
| @@ -19,3 +19,8 @@ return A + B; · 18 unmodified lines | |||
| 19 | #define B1 C1+2 | 19 | #define B1 C1+2 |
| 20 | #define C1 A1+3 | 20 | #define C1 A1+3 |
| 21 | return A1 + B1; | 21 | return A1 + B1; |
| 22 | |||
| 23 | #define i() x | ||
| 24 | #define n() 1 | ||
| 25 | i()i()n()n()i() | ||
| 26 | i()+i()-n()+n()- | ||
| @@ -1,6 +1,26 @@ | |||
| 1 | |||
| 2 | |||
| 1 | Z(1) | 3 | Z(1) |
| 2 | Z(Z(1)) | 4 | Z(Z(1)) |
| 3 | Z(Z(Z(Z(Z(1))))) | 5 | Z(Z(Z(Z(Z(1))))) |
| 6 | |||
| 7 | |||
| 8 | |||
| 4 | return A + B; | 9 | return A + B; |
| 10 | |||
| 11 | |||
| 12 | |||
| 13 | |||
| 14 | |||
| 15 | |||
| 5 | return A+1 + B+1; | 16 | return A+1 + B+1; |
| 17 | |||
| 18 | |||
| 19 | |||
| 20 | |||
| 6 | return A1+3 +2 +1 + B1+1 +3 +2; | 21 | return A1+3 +2 +1 + B1+1 +3 +2; |
| 22 | |||
| 23 | |||
| 24 | |||
| 25 | x x 1 1 x | ||
| 26 | x+x-1 +1 - | ||