From 1f3d3957c4aa4d403b07245fe4f0a49ac8fefcc4 Mon Sep 17 00:00:00 2001 From: Michael Matz Date: Sun, 9 Jul 2017 04:53:24 +0200 Subject: [PATCH] tccpp: Cleanup With last change the can_read_stream flag is unneeded, so tidy this a bit. --- tccpp.c | 237 ++++++++++++++++++++++++++++++---------------------------------- 1 file changed, 111 insertions(+), 126 deletions(-) diff --git a/tccpp.c b/tccpp.c index 7eb45012..ced5cc62 100644 --- a/tccpp.c +++ b/tccpp.c @@ -2901,8 +2901,7 @@ ST_FUNC void next_nomacro(void) static void macro_subst( TokenString *tok_str, Sym **nested_list, - const int *macro_str, - int can_read_stream + const int *macro_str ); /* substitute arguments in replacement lists in macro_str by the values in @@ -2992,9 +2991,7 @@ static int *macro_arg_subst(Sym **nested_list, const int *macro_str, Sym *args) } } else { add_var: - /* NOTE: the stream cannot be read when macro - substituting an argument */ - macro_subst(&str, nested_list, st, 0); + macro_subst(&str, nested_list, st); } if (str.len == l0) /* expanded to empty string */ tok_str_add(&str, TOK_PLCHLDR); @@ -3016,9 +3013,102 @@ static char const ab_month_name[12][4] = "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; +static int paste_tokens(int t1, CValue *v1, int t2, CValue *v2) +{ + CString cstr; + int n, ret = 1; + + cstr_new(&cstr); + if (t1 != TOK_PLCHLDR) + cstr_cat(&cstr, get_tok_str(t1, v1), -1); + n = cstr.size; + if (t2 != TOK_PLCHLDR) + cstr_cat(&cstr, get_tok_str(t2, v2), -1); + cstr_ccat(&cstr, '\0'); + + tcc_open_bf(tcc_state, ":paste:", cstr.size); + memcpy(file->buffer, cstr.data, cstr.size); + for (;;) { + next_nomacro1(); + if (0 == *file->buf_ptr) + break; + if (is_space(tok)) + continue; + tcc_warning("pasting \"%.*s\" and \"%s\" does not give a valid" + " preprocessing token", n, cstr.data, (char*)cstr.data + n); + ret = 0; + break; + } + tcc_close(); + //printf("paste <%s>\n", (char*)cstr.data); + cstr_free(&cstr); + return ret; +} + +/* handle the '##' operator. Return NULL if no '##' seen. Otherwise + return the resulting string (which must be freed). */ +static inline int *macro_twosharps(const int *ptr0) +{ + int t; + CValue cval; + TokenString macro_str1; + int start_of_nosubsts = -1; + const int *ptr; + + /* we search the first '##' */ + for (ptr = ptr0;;) { + TOK_GET(&t, &ptr, &cval); + if (t == TOK_PPJOIN) + break; + if (t == 0) + return NULL; + } + + tok_str_new(¯o_str1); + + //tok_print(" $$$", ptr0); + for (ptr = ptr0;;) { + TOK_GET(&t, &ptr, &cval); + if (t == 0) + break; + if (t == TOK_PPJOIN) + continue; + while (*ptr == TOK_PPJOIN) { + int t1; CValue cv1; + /* given 'a##b', remove nosubsts preceding 'a' */ + if (start_of_nosubsts >= 0) + macro_str1.len = start_of_nosubsts; + /* given 'a##b', remove nosubsts preceding 'b' */ + while ((t1 = *++ptr) == TOK_NOSUBST) + ; + if (t1 && t1 != TOK_PPJOIN) { + TOK_GET(&t1, &ptr, &cv1); + if (t != TOK_PLCHLDR || t1 != TOK_PLCHLDR) { + if (paste_tokens(t, &cval, t1, &cv1)) { + t = tok, cval = tokc; + } else { + tok_str_add2(¯o_str1, t, &cval); + t = t1, cval = cv1; + } + } + } + } + if (t == TOK_NOSUBST) { + if (start_of_nosubsts < 0) + start_of_nosubsts = macro_str1.len; + } else { + start_of_nosubsts = -1; + } + tok_str_add2(¯o_str1, t, &cval); + } + tok_str_add(¯o_str1, 0); + //tok_print(" ###", macro_str1.str); + return macro_str1.str; +} + /* peek or read [ws_str == NULL] next token from function macro call, walking up macro levels up to the file if necessary */ -static int next_argstream(Sym **nested_list, int can_read_stream, TokenString *ws_str) +static int next_argstream(Sym **nested_list, TokenString *ws_str) { int t; const int *p; @@ -3081,8 +3171,7 @@ static int next_argstream(Sym **nested_list, int can_read_stream, TokenString *w static int macro_subst_tok( TokenString *tok_str, Sym **nested_list, - Sym *s, - int can_read_stream) + Sym *s) { Sym *args, *sa, *sa1; int parlevel, *mstr, t, t1, spc; @@ -3127,6 +3216,7 @@ static int macro_subst_tok( cstr_free(&cstr); } else { int saved_parse_flags = parse_flags; + int *joined_str = NULL; mstr = s->d; if (s->type.t == MACRO_FUNC) { @@ -3139,7 +3229,7 @@ static int macro_subst_tok( | PARSE_FLAG_ACCEPT_STRAYS; /* get next token from argument stream */ - t = next_argstream(nested_list, can_read_stream, &ws_str); + t = next_argstream(nested_list, &ws_str); if (t != '(') { /* not a macro substitution after all, restore the * macro token plus all whitespace we've read. @@ -3167,7 +3257,7 @@ static int macro_subst_tok( /* NOTE: empty args are allowed, except if no args */ for(;;) { do { - next_argstream(nested_list, can_read_stream, NULL); + next_argstream(nested_list, NULL); } while (is_space(tok) || TOK_LINEFEED == tok); empty_arg: /* handle '()' case */ @@ -3192,7 +3282,7 @@ static int macro_subst_tok( tok = ' '; if (!check_space(tok, &spc)) tok_str_add2(&str, tok, &tokc); - next_argstream(nested_list, can_read_stream, NULL); + next_argstream(nested_list, NULL); } if (parlevel) expect(")"); @@ -3233,140 +3323,38 @@ static int macro_subst_tok( sym_push2(nested_list, s->v, 0, 0); parse_flags = saved_parse_flags; - macro_subst(tok_str, nested_list, mstr, can_read_stream | 2); + joined_str = macro_twosharps(mstr); + macro_subst(tok_str, nested_list, joined_str ? joined_str : mstr); /* pop nested defined symbol */ sa1 = *nested_list; *nested_list = sa1->prev; sym_free(sa1); + if (joined_str) + tok_str_free_str(joined_str); if (mstr != s->d) tok_str_free_str(mstr); } return 0; } -static int paste_tokens(int t1, CValue *v1, int t2, CValue *v2) -{ - CString cstr; - int n, ret = 1; - - cstr_new(&cstr); - if (t1 != TOK_PLCHLDR) - cstr_cat(&cstr, get_tok_str(t1, v1), -1); - n = cstr.size; - if (t2 != TOK_PLCHLDR) - cstr_cat(&cstr, get_tok_str(t2, v2), -1); - cstr_ccat(&cstr, '\0'); - - tcc_open_bf(tcc_state, ":paste:", cstr.size); - memcpy(file->buffer, cstr.data, cstr.size); - for (;;) { - next_nomacro1(); - if (0 == *file->buf_ptr) - break; - if (is_space(tok)) - continue; - tcc_warning("pasting \"%.*s\" and \"%s\" does not give a valid" - " preprocessing token", n, cstr.data, (char*)cstr.data + n); - ret = 0; - break; - } - tcc_close(); - //printf("paste <%s>\n", (char*)cstr.data); - cstr_free(&cstr); - return ret; -} - -/* handle the '##' operator. Return NULL if no '##' seen. Otherwise - return the resulting string (which must be freed). */ -static inline int *macro_twosharps(const int *ptr0) -{ - int t; - CValue cval; - TokenString macro_str1; - int start_of_nosubsts = -1; - const int *ptr; - - /* we search the first '##' */ - for (ptr = ptr0;;) { - TOK_GET(&t, &ptr, &cval); - if (t == TOK_PPJOIN) - break; - if (t == 0) - return NULL; - } - - tok_str_new(¯o_str1); - - //tok_print(" $$$", ptr0); - for (ptr = ptr0;;) { - TOK_GET(&t, &ptr, &cval); - if (t == 0) - break; - if (t == TOK_PPJOIN) - continue; - while (*ptr == TOK_PPJOIN) { - int t1; CValue cv1; - /* given 'a##b', remove nosubsts preceding 'a' */ - if (start_of_nosubsts >= 0) - macro_str1.len = start_of_nosubsts; - /* given 'a##b', remove nosubsts preceding 'b' */ - while ((t1 = *++ptr) == TOK_NOSUBST) - ; - if (t1 && t1 != TOK_PPJOIN) { - TOK_GET(&t1, &ptr, &cv1); - if (t != TOK_PLCHLDR || t1 != TOK_PLCHLDR) { - if (paste_tokens(t, &cval, t1, &cv1)) { - t = tok, cval = tokc; - } else { - tok_str_add2(¯o_str1, t, &cval); - t = t1, cval = cv1; - } - } - } - } - if (t == TOK_NOSUBST) { - if (start_of_nosubsts < 0) - start_of_nosubsts = macro_str1.len; - } else { - start_of_nosubsts = -1; - } - tok_str_add2(¯o_str1, t, &cval); - } - tok_str_add(¯o_str1, 0); - //tok_print(" ###", macro_str1.str); - return macro_str1.str; -} - /* 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. */ static void macro_subst( TokenString *tok_str, Sym **nested_list, - const int *macro_str, - int can_read_stream + const int *macro_str ) { Sym *s; - const int *ptr; int t, spc, nosubst; CValue cval; - int *macro_str1 = NULL; - /* first scan for '##' operator handling */ - ptr = macro_str; spc = nosubst = 0; - /* first scan for '##' operator handling */ - if (can_read_stream) { - macro_str1 = macro_twosharps(ptr); - if (macro_str1) - ptr = macro_str1; - } - while (1) { - TOK_GET(&t, &ptr, &cval); + TOK_GET(&t, ¯o_str, &cval); if (t <= 0) break; @@ -3384,18 +3372,18 @@ static void macro_subst( { TokenString str; - str.str = (int*)ptr; + str.str = (int*)macro_str; begin_macro(&str, 2); tok = t; - macro_subst_tok(tok_str, nested_list, s, can_read_stream); + macro_subst_tok(tok_str, nested_list, s); if (str.alloc == 3) { /* already finished by reading function macro arguments */ break; } - ptr = macro_ptr; + macro_str = macro_ptr; end_macro (); } @@ -3416,9 +3404,6 @@ no_subst: nosubst = 1; } } - if (macro_str1) - tok_str_free_str(macro_str1); - } /* return next token with macro substitution */ @@ -3446,7 +3431,7 @@ ST_FUNC void next(void) if (s) { Sym *nested_list = NULL; tokstr_buf.len = 0; - macro_subst_tok(&tokstr_buf, &nested_list, s, 1); + macro_subst_tok(&tokstr_buf, &nested_list, s); tok_str_add(&tokstr_buf, 0); begin_macro(&tokstr_buf, 2); goto redo; -- 2.11.4.GIT