--- tinycc-rl-1.0.0/tcc.c +++ tinycc-rl-1.0.0/tcc.c @@ -3129,13 +3129,16 @@ tok_str_new(&str); last_tok = 0; + save_tf = 0; while(1) { TOK_GET(t, tf, macro_str, cval); + tf |= save_tf; - save_tf = tf; + save_tf = 0; if (!t) break; if (t == '#') { /* stringize */ + save_tf = tf; TOK_GET(t, tf, macro_str, cval); if (!t) break; @@ -3162,11 +3165,12 @@ } else { tok_str_add2(&str, t, save_tf, &cval); } + save_tf = 0; } else if (t >= TOK_IDENT) { s = sym_find2(args, t); if (s) { st = (int *)s->c; - st[1] = save_tf; + st[1] = save_tf = tf; /* if '##' is present before or after, no arg substitution */ if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) { /* special case for var arg macros : ## eats the @@ -3189,17 +3193,19 @@ } else { int t1; add_var: + save_tf = 0; for(;;) { TOK_GET(t1, tf, st, cval); if (!t1) break; - tok_str_add2(&str, t1, save_tf, &cval); + tok_str_add2(&str, t1, tf, &cval); } } } else { /* NOTE: the stream cannot be read when macro substituing an argument */ - macro_subst(&str, nested_list, st, NULL); + if (macro_subst(&str, nested_list, st, NULL) > 0) + save_tf = 0; } } else { tok_str_add(&str, t, tf); @@ -3221,8 +3227,8 @@ /* do macro substitution of current token with macro 's' and add result to (tok_str,tok_len). 'nested_list' is the list of all - macros we got inside to avoid recursing. Return non zero if no + macros we got inside to avoid recursing. Return -1 if no - substitution needs to be done */ + substitution needs to be done, else the number of added tokens. */ static int macro_subst_tok(TokenString *tok_str, Sym **nested_list, Sym *s, struct macro_level **can_read_stream) { @@ -3267,6 +3273,7 @@ cval.cstr = &cstr; tok_str_add2(tok_str, t1, tok_flags, &cval); cstr_free(&cstr); + return 1; } else { mstr = (int *)s->c; mstr[1] = tok_flags; @@ -3360,15 +3367,15 @@ mstr_allocated = 1; } sym_push2(nested_list, s->v, 0, 0); - macro_subst(tok_str, nested_list, mstr, can_read_stream); + t = macro_subst(tok_str, nested_list, mstr, can_read_stream); /* pop nested defined symbol */ sa1 = *nested_list; *nested_list = sa1->prev; sym_free(sa1); if (mstr_allocated) tok_str_free(mstr); + return t; } - return 0; } /* handle the '##' operator. Return NULL if no '##' seen. Otherwise @@ -3512,14 +3519,14 @@ /* do macro substitution of macro_str and add result to (tok_str,tok_len). 'nested_list' is the list of all macros we got - inside to avoid recursing. */ + inside to avoid recursing. Return the number of added tokens. */ -static void macro_subst(TokenString *tok_str, Sym **nested_list, +static int macro_subst(TokenString *tok_str, Sym **nested_list, - const int *macro_str, struct macro_level ** can_read_stream) + const int *macro_str, struct macro_level ** can_read_stream) { Sym *s; int *macro_str1; const int *ptr; - int t, tf, ret; + int t, tf, save_tf, len, ret; CValue cval; struct macro_level ml; @@ -3528,12 +3535,18 @@ macro_str1 = macro_twosharps(ptr); if (macro_str1) ptr = macro_str1; + + save_tf = 0; + len = 0; while (1) { /* NOTE: ptr == NULL can only happen if tokens are read from file stream due to a macro function call */ if (ptr == NULL) break; TOK_GET(t, tf, ptr, cval); + tf |= save_tf; + save_tf = 0; + if (t == 0) break; s = define_find(t); @@ -3552,15 +3565,21 @@ macro_ptr = ml.p; if (can_read_stream && *can_read_stream == &ml) *can_read_stream = ml.prev; - if (ret != 0) + if (ret < 0) goto no_subst; + if (ret == 0) + save_tf = tf; + if (ret > 0) + len += ret; } else { no_subst: tok_str_add2(tok_str, t, tf, &cval); + len += 1; } } if (macro_str1) tok_str_free(macro_str1); + return len; } @@ -3584,7 +3603,7 @@ tok_str_new(&str); nested_list = NULL; ml = NULL; - if (macro_subst_tok(&str, &nested_list, s, &ml) == 0) { + if (macro_subst_tok(&str, &nested_list, s, &ml) >= 0) { /* substitution done, NOTE: maybe empty */ tok_str_add(&str, 0, 0); macro_ptr = str.str; @@ -8483,7 +8502,7 @@ tok_str_new(&str); nested_list = NULL; ml = NULL; - if (macro_subst_tok(&str, &nested_list, top, &ml) == 0) { + if (macro_subst_tok(&str, &nested_list, top, &ml) >= 0) { int t, tf, *stri; CValue cval; preprocess_out("#define "); --- tinycc-rl-1.0.0/tcc.h +++ tinycc-rl-1.0.0/tcc.h @@ -707,8 +707,8 @@ int *p; }; -static void macro_subst(TokenString *tok_str, Sym **nested_list, +static int macro_subst(TokenString *tok_str, Sym **nested_list, - const int *macro_str, struct macro_level **can_read_stream); + const int *macro_str, struct macro_level **can_read_stream); void gen_op(int op); void force_charshort_cast(int t); static void gen_cast(CType *type);