Sorry about that. This should definitely fix Sergey's issue.
Unified · Split
| @@ -2890,7 +2890,7 @@ static int macro_subst_tok(TokenString *tok_str, · 2889 unmodified lines | |||
| 2890 | p = macro_ptr; | 2890 | p = macro_ptr; |
| 2891 | while (is_space(t = *p) || TOK_LINEFEED == t) { | 2891 | while (is_space(t = *p) || TOK_LINEFEED == t) { |
| 2892 | if (saved_parse_flags & PARSE_FLAG_SPACES) | 2892 | if (saved_parse_flags & PARSE_FLAG_SPACES) |
| 2893 | tok_str_add(&ws_str, t); | 2893 | tok_str_add(&ws_str, t); |
| 2894 | ++p; | 2894 | ++p; |
| 2895 | } | 2895 | } |
| 2896 | if (t == 0 && can_read_stream) { | 2896 | if (t == 0 && can_read_stream) { |
| @@ -2927,7 +2927,8 @@ static int macro_subst_tok(TokenString *tok_str, · 30 unmodified lines | |||
| 2927 | break; | 2927 | break; |
| 2928 | ch = ' '; | 2928 | ch = ' '; |
| 2929 | } | 2929 | } |
| 2930 | tok_str_add(&ws_str, ch); | 2930 | if (saved_parse_flags & PARSE_FLAG_SPACES) |
| 2931 | tok_str_add(&ws_str, ch); | ||
| 2931 | cinp(); | 2932 | cinp(); |
| 2932 | } | 2933 | } |
| 2933 | t = ch; | 2934 | t = ch; |
| @@ -2995,8 +2996,30 @@ static int macro_subst_tok(TokenString *tok_str, · 61 unmodified lines | |||
| 2995 | else | 2996 | else |
| 2996 | break; | 2997 | break; |
| 2997 | } | 2998 | } |
| 2998 | if (tok != ',') | 2999 | /* |
| 2999 | expect(","); | 3000 | * #define f(a) f(a) |
| 3001 | * #define h f(r | ||
| 3002 | * h 5) | ||
| 3003 | */ | ||
| 3004 | if (tok != ',') { | ||
| 3005 | /* Argh! Not a macro invocation after all, at this | ||
| 3006 | * point, so put everything back onto mstr that's | ||
| 3007 | * been skipped since we saw the '(' )*/ | ||
| 3008 | tok_str_new(&str); | ||
| 3009 | tok_str_add(&str, mtok); | ||
| 3010 | tok_str_add(&str, '('); | ||
| 3011 | for (sa = s->next; sa; sa = sa->next) { | ||
| 3012 | int *p = sa->d; | ||
| 3013 | while (p && *p) { | ||
| 3014 | tok_str_add(&str, *p); | ||
| 3015 | p++; | ||
| 3016 | } | ||
| 3017 | mstr = str.str; | ||
| 3018 | /* leak memory */; | ||
| 3019 | mstr_allocated = 0; | ||
| 3020 | goto free_memory; | ||
| 3021 | } | ||
| 3022 | } | ||
| 3000 | next_nomacro(); | 3023 | next_nomacro(); |
| 3001 | } | 3024 | } |
| 3002 | if (sa) { | 3025 | if (sa) { |
| @@ -3006,6 +3029,7 @@ static int macro_subst_tok(TokenString *tok_str, · 3 unmodified lines | |||
| 3006 | 3029 | ||
| 3007 | /* now subst each arg */ | 3030 | /* now subst each arg */ |
| 3008 | mstr = macro_arg_subst(nested_list, mstr, args); | 3031 | mstr = macro_arg_subst(nested_list, mstr, args); |
| 3032 | free_memory: | ||
| 3009 | /* free memory */ | 3033 | /* free memory */ |
| 3010 | sa = args; | 3034 | sa = args; |
| 3011 | while (sa) { | 3035 | while (sa) { |
| @@ -3057,8 +3081,6 @@ static inline int *macro_twosharps(const int *macro_str) · 45 unmodified lines | |||
| 3057 | TOK_GET(&tok, &ptr, &tokc); | 3081 | TOK_GET(&tok, &ptr, &tokc); |
| 3058 | if (tok == 0) | 3082 | if (tok == 0) |
| 3059 | break; | 3083 | break; |
| 3060 | if (tok == TOK_TWOSHARPS) | ||
| 3061 | continue; | ||
| 3062 | if (tok == TOK_NOSUBST && start_of_nosubsts < 0) | 3084 | if (tok == TOK_NOSUBST && start_of_nosubsts < 0) |
| 3063 | start_of_nosubsts = macro_str1.len; | 3085 | start_of_nosubsts = macro_str1.len; |
| 3064 | while (*ptr == TOK_TWOSHARPS) { | 3086 | while (*ptr == TOK_TWOSHARPS) { |
| @@ -3078,13 +3100,15 @@ static inline int *macro_twosharps(const int *macro_str) · 13 unmodified lines | |||
| 3078 | if (tok != TOK_PLCHLDR) | 3100 | if (tok != TOK_PLCHLDR) |
| 3079 | cstr_cat(&cstr, get_tok_str(tok, &tokc)); | 3101 | cstr_cat(&cstr, get_tok_str(tok, &tokc)); |
| 3080 | n = cstr.size; | 3102 | n = cstr.size; |
| 3081 | if (t != TOK_PLCHLDR || tok == TOK_PLCHLDR) | 3103 | if (t != TOK_PLCHLDR) |
| 3082 | cstr_cat(&cstr, get_tok_str(t, &cval)); | 3104 | cstr_cat(&cstr, get_tok_str(t, &cval)); |
| 3083 | cstr_ccat(&cstr, '\0'); | 3105 | cstr_ccat(&cstr, '\0'); |
| 3084 | 3106 | ||
| 3085 | tcc_open_bf(tcc_state, ":paste:", cstr.size); | 3107 | tcc_open_bf(tcc_state, ":paste:", cstr.size); |
| 3086 | memcpy(file->buffer, cstr.data, cstr.size); | 3108 | memcpy(file->buffer, cstr.data, cstr.size); |
| 3087 | for (;;) { | 3109 | for (;;) { |
| 3110 | if (0 == *file->buf_ptr) | ||
| 3111 | break; | ||
| 3088 | next_nomacro1(); | 3112 | next_nomacro1(); |
| 3089 | if (0 == *file->buf_ptr) | 3113 | if (0 == *file->buf_ptr) |
| 3090 | break; | 3114 | break; |
| @@ -3095,13 +3119,22 @@ static inline int *macro_twosharps(const int *macro_str) · 4 unmodified lines | |||
| 3095 | tcc_close(); | 3119 | tcc_close(); |
| 3096 | cstr_free(&cstr); | 3120 | cstr_free(&cstr); |
| 3097 | } | 3121 | } |
| 3122 | if (tok == TOK_TWOSHARPS) { | ||
| 3123 | /* two sharps twosharped together tokenize to two | ||
| 3124 | * sharp tokens, not a twosharp token. */ | ||
| 3125 | /* That's fun to say, but is it actually true? GCC | ||
| 3126 | * stringifies #define a # ## # ## # to "## #" (and a | ||
| 3127 | * warning), while we produce "###" (no warning) */ | ||
| 3128 | tok_str_add(¯o_str1, '#'); | ||
| 3129 | tok = '#'; | ||
| 3130 | } | ||
| 3098 | } | 3131 | } |
| 3099 | if (tok != TOK_NOSUBST) { | 3132 | if (tok != TOK_NOSUBST) { |
| 3100 | tok_str_add2(¯o_str1, tok, &tokc); | 3133 | tok_str_add2(¯o_str1, tok, &tokc); |
| 3101 | tok = ' '; | 3134 | tok = ' '; |
| 3102 | start_of_nosubsts = -1; | 3135 | start_of_nosubsts = -1; |
| 3103 | } | 3136 | } else |
| 3104 | tok_str_add2(¯o_str1, tok, &tokc); | 3137 | tok_str_add2(¯o_str1, tok, &tokc); |
| 3105 | } | 3138 | } |
| 3106 | tok_str_add(¯o_str1, 0); | 3139 | tok_str_add(¯o_str1, 0); |
| 3107 | return macro_str1.str; | 3140 | return macro_str1.str; |
| @@ -3120,7 +3153,6 @@ static void macro_subst(TokenString *tok_str, Sym **nested_list, · 12 unmodified lines | |||
| 3120 | int t, spc; | 3153 | int t, spc; |
| 3121 | CValue cval; | 3154 | CValue cval; |
| 3122 | struct macro_level ml; | 3155 | struct macro_level ml; |
| 3123 | int force_blank; | ||
| 3124 | int gnucomma_index = -1; | 3156 | int gnucomma_index = -1; |
| 3125 | 3157 | ||
| 3126 | /* first scan for '##' operator handling */ | 3158 | /* first scan for '##' operator handling */ |
| @@ -3130,7 +3162,6 @@ static void macro_subst(TokenString *tok_str, Sym **nested_list, · 3 unmodified lines | |||
| 3130 | if (macro_str1) | 3162 | if (macro_str1) |
| 3131 | ptr = macro_str1; | 3163 | ptr = macro_str1; |
| 3132 | spc = 0; | 3164 | spc = 0; |
| 3133 | force_blank = 0; | ||
| 3134 | 3165 | ||
| 3135 | while (1) { | 3166 | while (1) { |
| 3136 | /* NOTE: ptr == NULL can only happen if tokens are read from | 3167 | /* NOTE: ptr == NULL can only happen if tokens are read from |
| @@ -3176,18 +3207,11 @@ static void macro_subst(TokenString *tok_str, Sym **nested_list, · 39 unmodified lines | |||
| 3176 | macro_ptr = ml.p; | 3207 | macro_ptr = ml.p; |
| 3177 | if (can_read_stream && *can_read_stream == &ml) | 3208 | if (can_read_stream && *can_read_stream == &ml) |
| 3178 | *can_read_stream = ml.prev; | 3209 | *can_read_stream = ml.prev; |
| 3179 | if (parse_flags & PARSE_FLAG_SPACES) | ||
| 3180 | force_blank = 1; | ||
| 3181 | if (old_len == tok_str->len) | 3210 | if (old_len == tok_str->len) |
| 3182 | tok_str_add(tok_str, TOK_PLCHLDR); | 3211 | tok_str_add(tok_str, TOK_PLCHLDR); |
| 3183 | } else { | 3212 | } else { |
| 3184 | no_subst: | 3213 | no_subst: |
| 3185 | if (force_blank) { | 3214 | if (!check_space(t, &spc)) |
| 3186 | tok_str_add(tok_str, ' '); | ||
| 3187 | spc = 1; | ||
| 3188 | force_blank = 0; | ||
| 3189 | } | ||
| 3190 | if (!check_space(t, &spc)) | ||
| 3191 | tok_str_add2(tok_str, t, &cval); | 3215 | tok_str_add2(tok_str, t, &cval); |
| 3192 | } | 3216 | } |
| 3193 | if (gnucomma_index != -1) { | 3217 | if (gnucomma_index != -1) { |