--- tinycc-rl-1.0.0/Makefile +++ tinycc-rl-1.0.0/Makefile @@ -62,10 +62,10 @@ $(CC) $(CFLAGS) -I. -Iinclude -o $@ $< test.ref: tcctest.ref - ./tcctest.ref > $@ + ./tcctest.ref > $@ || ( rm $@ ; false ) test.out: tcc libtcc1.a tests/tcctest.c - $(TCC) -run tests/tcctest.c > $@ + $(TCC) -run tests/tcctest.c > $@ || ( rm $@ ; false ) run: tcc tests/tcctest.c $(TCC) -run tests/tcctest.c --- tinycc-rl-1.0.0/tcc.c +++ tinycc-rl-1.0.0/tcc.c @@ -55,7 +55,7 @@ static CValue tokc; static CString tokcstr; /* current parsed string, if any */ /* additional informations about token */ -static int tok_flags; +static int tok_flags, next_tok_flags; static int *macro_ptr, *macro_ptr_allocated; static int *unget_saved_macro_ptr; @@ -1515,19 +1515,20 @@ return str; } -static void tok_str_add(TokenString *s, int t) +static void tok_str_add(TokenString *s, int t, int tf) { int len, *str; len = s->len; str = s->str; - if (len >= s->allocated_len) + if (len+1 >= s->allocated_len) str = tok_str_realloc(s); str[len++] = t; + str[len++] = tf; s->len = len; } -static void tok_str_add2(TokenString *s, int t, CValue *cv) +static void tok_str_add2(TokenString *s, int t, int tf, CValue *cv) { int len, *str; @@ -1538,6 +1539,7 @@ if (len + TOK_MAX_SIZE > s->allocated_len) str = tok_str_realloc(s); str[len++] = t; + str[len++] = tf; switch(t) { case TOK_CINT: case TOK_CUINT: @@ -1600,9 +1602,9 @@ if (file->line_num != s->last_line_num) { s->last_line_num = file->line_num; cval.i = s->last_line_num; - tok_str_add2(s, TOK_LINENUM, &cval); + tok_str_add2(s, TOK_LINENUM, 0, &cval); } - tok_str_add2(s, tok, &tokc); + tok_str_add2(s, tok, tok_flags, &tokc); } #if LDOUBLE_SIZE == 12 @@ -1621,9 +1623,10 @@ /* get a token from an integer array and increment pointer accordingly. we code it as a macro to avoid pointer aliasing. */ -#define TOK_GET(t, p, cv) \ +#define TOK_GET(t, tf, p, cv) \ { \ t = *p++; \ + tf = *p++; \ switch(t) { \ case TOK_CINT: \ case TOK_CUINT: \ @@ -1792,8 +1795,8 @@ } tok_str_add_tok(&str); } - tok_str_add(&str, -1); /* simulate end of file */ + tok_str_add(&str, -1, 0); /* simulate end of file */ - tok_str_add(&str, 0); + tok_str_add(&str, 0, 0); /* now evaluate C constant expression */ macro_ptr = str.str; next(); @@ -1806,11 +1809,11 @@ #if defined(PARSE_DEBUG) || defined(PP_DEBUG) static void tok_print(int *str) { - int t; + int t, tf; CValue cval; while (1) { - TOK_GET(t, str, cval); + TOK_GET(t, tf, str, cval); if (!t) break; printf(" %s", get_tok_str(t, &cval)); @@ -1866,10 +1869,10 @@ next_nomacro(); /* EOF testing necessary for '-D' handling */ while (tok != TOK_LINEFEED && tok != TOK_EOF) { - tok_str_add2(&str, tok, &tokc); + tok_str_add2(&str, tok, tok_flags, &tokc); next_nomacro(); } - tok_str_add(&str, 0); + tok_str_add(&str, 0, 0); #ifdef PP_DEBUG printf("define %s %d: ", get_tok_str(v, NULL), t); tok_print(str.str); @@ -2133,7 +2136,7 @@ if (do_debug) { put_stabs(file->filename, N_BINCL, 0, 0, 0); } - tok_flags |= TOK_FLAG_BOF | TOK_FLAG_BOL; + next_tok_flags |= TOK_FLAG_BOW | TOK_FLAG_BOF | TOK_FLAG_BOL; ch = file->buf_ptr[0]; if (tcc_preprocess) @@ -2207,7 +2210,7 @@ file->ifndef_macro = 0; while (tok != TOK_LINEFEED) next_nomacro(); - tok_flags |= TOK_FLAG_ENDIF; + next_tok_flags |= TOK_FLAG_ENDIF; goto the_end; } break; @@ -2689,6 +2692,7 @@ case '\v': case '\r': p++; + next_tok_flags |= TOK_FLAG_BOW; goto redo_no_start; case '\\': @@ -2722,7 +2726,7 @@ /* test if previous '#endif' was after a #ifdef at start of file */ - if (tok_flags & TOK_FLAG_ENDIF) { + if (next_tok_flags & TOK_FLAG_ENDIF) { #ifdef INC_DEBUG printf("#endif %s\n", get_tok_str(file->ifndef_macro_saved, NULL)); #endif @@ -2751,7 +2755,7 @@ tok = TOK_LINEFEED; } else { file->line_num++; - tok_flags |= TOK_FLAG_BOL; + next_tok_flags |= TOK_FLAG_BOW | TOK_FLAG_BOL; p++; goto redo_no_start; } @@ -2760,10 +2764,10 @@ case '#': /* XXX: simplify */ PEEKC(c, p); - if ((tok_flags & TOK_FLAG_BOL) && + if ((next_tok_flags & TOK_FLAG_BOL) && (parse_flags & PARSE_FLAG_PREPROCESS)) { file->buf_ptr = p; - preprocess(tok_flags & TOK_FLAG_BOF); + preprocess(next_tok_flags & TOK_FLAG_BOF); p = file->buf_ptr; goto redo_no_start; } else { @@ -3052,9 +3056,11 @@ PEEKC(c, p); if (c == '*') { p = parse_comment(p); + next_tok_flags |= TOK_FLAG_BOW; goto redo_no_start; } else if (c == '/') { p = parse_line_comment(p); + next_tok_flags |= TOK_FLAG_BOW; goto redo_no_start; } else if (c == '=') { p++; @@ -3086,7 +3092,8 @@ break; } file->buf_ptr = p; + tok_flags = next_tok_flags; - tok_flags = 0; + next_tok_flags = 0; #if defined(PARSE_DEBUG) printf("token = %s\n", get_tok_str(tok, &tokc)); #endif @@ -3100,7 +3107,7 @@ redo: tok = *macro_ptr; if (tok) { - TOK_GET(tok, macro_ptr, tokc); + TOK_GET(tok, tok_flags, macro_ptr, tokc); if (tok == TOK_LINENUM) { file->line_num = tokc.i; goto redo; @@ -3114,7 +3121,7 @@ /* substitute args in macro_str and return allocated string */ static int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args) { - int *st, last_tok, t, notfirst; + int *st, last_tok, t, tf, save_tf, notfirst; Sym *s; CValue cval; TokenString str; @@ -3123,12 +3130,13 @@ tok_str_new(&str); last_tok = 0; while(1) { - TOK_GET(t, macro_str, cval); + TOK_GET(t, tf, macro_str, cval); + save_tf = tf; if (!t) break; if (t == '#') { /* stringize */ - TOK_GET(t, macro_str, cval); + TOK_GET(t, tf, macro_str, cval); if (!t) break; s = sym_find2(args, t); @@ -3137,9 +3145,9 @@ st = (int *)s->c; notfirst = 0; while (*st) { - if (notfirst) - cstr_ccat(&cstr, ' '); - TOK_GET(t, st, cval); + TOK_GET(t, tf, st, cval); + if (notfirst && tf & TOK_FLAG_BOW) + cstr_ccat(&cstr, ' '); cstr_cat(&cstr, get_tok_str(t, &cval)); notfirst = 1; } @@ -3149,15 +3157,16 @@ #endif /* add string */ cval.cstr = &cstr; - tok_str_add2(&str, TOK_STR, &cval); + tok_str_add2(&str, TOK_STR, save_tf, &cval); cstr_free(&cstr); } else { - tok_str_add2(&str, t, &cval); + tok_str_add2(&str, t, save_tf, &cval); } } else if (t >= TOK_IDENT) { s = sym_find2(args, t); if (s) { st = (int *)s->c; + st[1] = save_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 @@ -3167,23 +3176,24 @@ problems */ if (gnu_ext && s->type.t && last_tok == TOK_TWOSHARPS && - str.len >= 2 && str.str[str.len - 2] == ',') { + str.len >= 4 && str.str[str.len - 4] == ',') { if (*st == 0) { /* suppress ',' '##' */ - str.len -= 2; + str.len -= 4; + next_tok_flags = tok_flags; } else { /* suppress '##' and add variable */ - str.len--; + str.len -= 2; goto add_var; } } else { int t1; add_var: for(;;) { - TOK_GET(t1, st, cval); + TOK_GET(t1, tf, st, cval); if (!t1) break; - tok_str_add2(&str, t1, &cval); + tok_str_add2(&str, t1, save_tf, &cval); } } } else { @@ -3192,14 +3202,14 @@ macro_subst(&str, nested_list, st, NULL); } } else { - tok_str_add(&str, t); + tok_str_add(&str, t, tf); } } else { - tok_str_add2(&str, t, &cval); + tok_str_add2(&str, t, tf, &cval); } last_tok = t; } - tok_str_add(&str, 0); + tok_str_add(&str, 0, 0); return str.str; } @@ -3255,10 +3265,11 @@ cstr_cat(&cstr, cstrval); cstr_ccat(&cstr, '\0'); cval.cstr = &cstr; - tok_str_add2(tok_str, t1, &cval); + tok_str_add2(tok_str, t1, tok_flags, &cval); cstr_free(&cstr); } else { mstr = (int *)s->c; + mstr[1] = tok_flags; mstr_allocated = 0; if (s->type.t == MACRO_FUNC) { /* NOTE: we do not use next_nomacro to avoid eating the @@ -3313,10 +3324,10 @@ parlevel++; else if (tok == ')') parlevel--; - tok_str_add2(&str, tok, &tokc); + tok_str_add2(&str, tok, tok_flags, &tokc); next_nomacro(); } - tok_str_add(&str, 0); + tok_str_add(&str, 0, 0); sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, (int)str.str); sa = sa->next; if (tok == ')') { @@ -3366,7 +3377,7 @@ { TokenSym *ts; const int *macro_ptr1, *start_macro_ptr, *ptr, *saved_macro_ptr; - int t; + int t, tf; const char *p1, *p2; CValue cval; TokenString macro_str1; @@ -3376,7 +3387,7 @@ /* we search the first '##' */ for(;;) { macro_ptr1 = macro_str; - TOK_GET(t, macro_str, cval); + TOK_GET(t, tf, macro_str, cval); /* nothing more to do if end of string */ if (t == 0) return NULL; @@ -3388,23 +3399,24 @@ cstr_new(&cstr); tok_str_new(¯o_str1); tok = t; + tok_flags = tf; tokc = cval; /* add all tokens seen so far */ for(ptr = start_macro_ptr; ptr < macro_ptr1;) { - TOK_GET(t, ptr, cval); + TOK_GET(t, tf, ptr, cval); - tok_str_add2(¯o_str1, t, &cval); + tok_str_add2(¯o_str1, t, tf, &cval); } saved_macro_ptr = macro_ptr; /* XXX: get rid of the use of macro_ptr here */ macro_ptr = (int *)macro_str; for(;;) { while (*macro_ptr == TOK_TWOSHARPS) { - macro_ptr++; + macro_ptr+=2; macro_ptr1 = macro_ptr; t = *macro_ptr; if (t) { - TOK_GET(t, macro_ptr, cval); + TOK_GET(t, tf, macro_ptr, cval); /* We concatenate the two tokens if we have an identifier or a preprocessing number */ cstr_reset(&cstr); @@ -3478,7 +3490,7 @@ p2 = get_tok_str(t, &cval); warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr.data, p2); /* cannot merge tokens: just add them separately */ - tok_str_add2(¯o_str1, tok, &tokc); + tok_str_add2(¯o_str1, tok, tok_flags, &tokc); /* XXX: free associated memory ? */ tok = t; tokc = cval; @@ -3486,14 +3498,14 @@ } } } - tok_str_add2(¯o_str1, tok, &tokc); + tok_str_add2(¯o_str1, tok, tok_flags, &tokc); next_nomacro(); if (tok == 0) break; } macro_ptr = (int *)saved_macro_ptr; cstr_free(&cstr); - tok_str_add(¯o_str1, 0); + tok_str_add(¯o_str1, 0, 0); return macro_str1.str; } @@ -3507,7 +3519,7 @@ Sym *s; int *macro_str1; const int *ptr; - int t, ret; + int t, tf, ret; CValue cval; struct macro_level ml; @@ -3521,7 +3533,7 @@ file stream due to a macro function call */ if (ptr == NULL) break; - TOK_GET(t, ptr, cval); + TOK_GET(t, tf, ptr, cval); if (t == 0) break; s = define_find(t); @@ -3534,6 +3546,7 @@ ml.prev = *can_read_stream, *can_read_stream = &ml; macro_ptr = (int *)ptr; tok = t; + tok_flags = tf; ret = macro_subst_tok(tok_str, nested_list, s, can_read_stream); ptr = (int *)macro_ptr; macro_ptr = ml.p; @@ -3543,7 +3556,7 @@ goto no_subst; } else { no_subst: - tok_str_add2(tok_str, t, &cval); + tok_str_add2(tok_str, t, tf, &cval); } } if (macro_str1) @@ -3573,7 +3586,7 @@ ml = NULL; if (macro_subst_tok(&str, &nested_list, s, &ml) == 0) { /* substitution done, NOTE: maybe empty */ - tok_str_add(&str, 0); + tok_str_add(&str, 0, 0); macro_ptr = str.str; macro_ptr_allocated = str.str; goto redo; @@ -7946,8 +7959,8 @@ next(); } } - tok_str_add(&init_str, -1); + tok_str_add(&init_str, -1, 0); - tok_str_add(&init_str, 0); + tok_str_add(&init_str, 0, 0); /* compute size */ save_parse_state(&saved_parse_state); @@ -8374,8 +8387,8 @@ break; } } - tok_str_add(&func_str, -1); + tok_str_add(&func_str, -1, 0); - tok_str_add(&func_str, 0); + tok_str_add(&func_str, 0, 0); sym->r = (int)func_str.str; } else { /* compute text section */ @@ -8471,16 +8484,16 @@ nested_list = NULL; ml = NULL; if (macro_subst_tok(&str, &nested_list, top, &ml) == 0) { - int t, *stri; + int t, tf, *stri; CValue cval; preprocess_out("#define "); preprocess_out(get_tok_str(tok,NULL)); - tok_str_add(&str, 0); + tok_str_add(&str, 0, 0); stri=str.str; for (;;) { - TOK_GET(t, stri, cval); + TOK_GET(t, tf, stri, cval); if (!t) break; preprocess_out(" "); preprocess_out(get_tok_str(t, &cval)); @@ -8569,7 +8582,7 @@ s1->error_set_jmp_enabled = 1; ch = file->buf_ptr[0]; - tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; + next_tok_flags = TOK_FLAG_BOW | TOK_FLAG_BOL | TOK_FLAG_BOF; parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM; if (tcc_preprocess) { --- tinycc-rl-1.0.0/tcc.h +++ tinycc-rl-1.0.0/tcc.h @@ -121,7 +121,7 @@ #define TOK_HASH_SIZE 8192 /* must be a power of two */ #define TOK_ALLOC_INCR 512 /* must be a power of two */ -#define TOK_MAX_SIZE 4 /* token max size in int unit when stored in string */ +#define TOK_MAX_SIZE 5 /* token max size in int unit when stored in string */ /* token symbol management */ typedef struct TokenSym { @@ -310,9 +310,10 @@ #define CACHED_INCLUDES_HASH_SIZE 512 /* additional information about token */ +#define TOK_FLAG_BOW 0x0001 /* beginning of word before */ -#define TOK_FLAG_BOL 0x0001 /* beginning of line before */ +#define TOK_FLAG_BOL 0x0002 /* beginning of line before */ -#define TOK_FLAG_BOF 0x0002 /* beginning of file before */ +#define TOK_FLAG_BOF 0x0004 /* beginning of file before */ -#define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */ +#define TOK_FLAG_ENDIF 0x0008 /* a endif was found matching starting #ifdef */ #define PARSE_FLAG_PREPROCESS 0x0001 /* activate preprocessing */ #define PARSE_FLAG_TOK_NUM 0x0002 /* return numbers instead of TOK_PPNUM */ --- tinycc-rl-1.0.0/tccasm.c +++ tinycc-rl-1.0.0/tccasm.c @@ -618,7 +618,7 @@ /* XXX: undefine C labels */ ch = file->buf_ptr[0]; - tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; + next_tok_flags = TOK_FLAG_BOW | TOK_FLAG_BOL | TOK_FLAG_BOF; parse_flags = PARSE_FLAG_ASM_COMMENTS; if (do_preprocess) parse_flags |= PARSE_FLAG_PREPROCESS;