| @@ -2565,7 +2565,8 @@ ST_FUNC void next_nomacro(void) · 2564 unmodified lines |
| 2565 | 2565 | } while (is_space(tok)); |
| 2566 | 2566 | } |
| 2567 | 2567 | |
| 2568 | | −/* substitute args in macro_str and return allocated string */ |
| 2568 | +/* substitute arguments in replacement lists in macro_str by the values in |
| 2569 | + args (field d) and return allocated string */ |
| 2569 | 2570 | static int *macro_arg_subst(Sym **nested_list, const int *macro_str, Sym *args) |
| 2570 | 2571 | { |
| 2571 | 2572 | int last_tok, t, spc; |
| @@ -2622,7 +2623,7 @@ static int *macro_arg_subst(Sym **nested_list, const int *macro_str, Sym *args) · 50 unmodified lines |
| 2622 | 2623 | if (gnu_ext && s->type.t && |
| 2623 | 2624 | last_tok == TOK_TWOSHARPS && |
| 2624 | 2625 | str.len >= 2 && str.str[str.len - 2] == ',') { |
| 2625 | | − if (*st == 0) { |
| 2626 | + if (*st == TOK_PLCHLDR) { |
| 2626 | 2627 | /* suppress ',' '##' */ |
| 2627 | 2628 | str.len -= 2; |
| 2628 | 2629 | } else { |
| @@ -2793,6 +2794,8 @@ static int macro_subst_tok(TokenString *tok_str, · 164 unmodified lines |
| 2793 | 2794 | tok_str_add2(&str, tok, &tokc); |
| 2794 | 2795 | next_nomacro_spc(); |
| 2795 | 2796 | } |
| 2797 | + if (!str.len) |
| 2798 | + tok_str_add(&str, TOK_PLCHLDR); |
| 2796 | 2799 | str.len -= spc; |
| 2797 | 2800 | tok_str_add(&str, 0); |
| 2798 | 2801 | sa1 = sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, 0); |
| @@ -2885,9 +2888,11 @@ static inline int *macro_twosharps(const int *macro_str) · 86 unmodified lines |
| 2885 | 2888 | TOK_GET(&t, &ptr, &cval); |
| 2886 | 2889 | /* We concatenate the two tokens */ |
| 2887 | 2890 | cstr_new(&cstr); |
| 2888 | | − cstr_cat(&cstr, get_tok_str(tok, &tokc)); |
| 2891 | + if (tok != TOK_PLCHLDR) |
| 2892 | + cstr_cat(&cstr, get_tok_str(tok, &tokc)); |
| 2889 | 2893 | n = cstr.size; |
| 2890 | | − cstr_cat(&cstr, get_tok_str(t, &cval)); |
| 2894 | + if (t != TOK_PLCHLDR || tok == TOK_PLCHLDR) |
| 2895 | + cstr_cat(&cstr, get_tok_str(t, &cval)); |
| 2891 | 2896 | cstr_ccat(&cstr, '\0'); |
| 2892 | 2897 | |
| 2893 | 2898 | tcc_open_bf(tcc_state, ":paste:", cstr.size); |
| @@ -2904,8 +2909,35 @@ static inline int *macro_twosharps(const int *macro_str) · 10 unmodified lines |
| 2904 | 2909 | cstr_free(&cstr); |
| 2905 | 2910 | } |
| 2906 | 2911 | } |
| 2907 | | − if (tok != TOK_NOSUBST) |
| 2912 | + if (tok != TOK_NOSUBST) { |
| 2913 | + const int *oldptr; |
| 2914 | + CValue cval; |
| 2915 | + |
| 2916 | + /* Check if a space need to be added after ## concatenation in |
| 2917 | + order to avoid misinterpreting the newly formed token |
| 2918 | + followed by the next token as being a single token (see |
| 2919 | + macro_concat test) */ |
| 2920 | + cstr_new(&cstr); |
| 2921 | + cstr_cat(&cstr, get_tok_str(tok, &tokc)); |
| 2922 | + oldptr = ptr; |
| 2923 | + TOK_GET(&t, &ptr, &cval); |
| 2924 | + ptr = oldptr; |
| 2925 | + cstr_cat(&cstr, get_tok_str(t, &cval)); |
| 2926 | + cstr_ccat(&cstr, '\0'); |
| 2927 | + t = tok; |
| 2928 | + cval = tokc; |
| 2929 | + tcc_open_bf(tcc_state, ":paste:", cstr.size); |
| 2930 | + memcpy(file->buffer, cstr.data, cstr.size); |
| 2931 | + next_nomacro1(); |
| 2932 | + if (!*file->buf_ptr) { |
| 2933 | + tok_str_add2(¯o_str1, t, &cval); |
| 2934 | + tok = ' '; |
| 2935 | + } |
| 2936 | + tcc_close(); |
| 2937 | + cstr_free(&cstr); |
| 2938 | + |
| 2908 | 2939 | start_of_nosubsts = -1; |
| 2940 | + } |
| 2909 | 2941 | tok_str_add2(¯o_str1, tok, &tokc); |
| 2910 | 2942 | } |
| 2911 | 2943 | tok_str_add(¯o_str1, 0); |