diff options
| author | grischka <grischka> | 2016-05-05 14:12:53 +0200 |
|---|---|---|
| committer | grischka <grischka> | 2016-05-05 14:12:53 +0200 |
| commit | fe845cf53da206bb28f6b49a0878b0118b4f242b (patch) | |
| tree | 27caab94c1fdd03dd8b551d637cd74e917c0f5ae /tccpp.c | |
| parent | caebbc3ee1071ace94003cdf645f749d2b0a9eed (diff) | |
| download | tinycc-fe845cf53da206bb28f6b49a0878b0118b4f242b.tar.gz tinycc-fe845cf53da206bb28f6b49a0878b0118b4f242b.tar.bz2 | |
tccpp: cleanup options -dD -dM, remove -C
The lexer is for reading files, not for writing.
Also :
- macro_is_equal(): avoid crash if redefining __FILE__
Diffstat (limited to 'tccpp.c')
| -rw-r--r-- | tccpp.c | 382 |
1 files changed, 180 insertions, 202 deletions
@@ -49,6 +49,9 @@ static char token_buf[STRING_MAX_SIZE + 1]; static CString cstr_buf; static TokenString tokstr_buf; static unsigned char isidnum_table[256 - CH_EOF]; +static int pp_debug_tok, pp_debug_symv; +static void tok_print(const char *msg, const int *str); + /* isidnum_table flags: */ #define IS_SPC 1 #define IS_ID 2 @@ -129,6 +132,21 @@ ST_FUNC void end_macro(void) } } +ST_FUNC char *trimfront(char *p) +{ + while (*p && (unsigned char)*p <= ' ') + ++p; + return p; +} + +ST_FUNC char *trimback(char *a, char *e) +{ + while (e > a && (unsigned char)e[-1] <= ' ') + --e; + *e = 0;; + return a; +} + /* ------------------------------------------------------------------------- */ /* Custom allocator for tiny objects */ @@ -675,80 +693,12 @@ ST_FUNC void minp(void) handle_stray(); } -static void pp_line(TCCState *s1, BufferedFile *f, int level) -{ - if (s1->ppfp) { - int d = f->line_num - f->line_ref; - if (s1->Pflag == LINE_MACRO_OUTPUT_FORMAT_NONE - || (level == 0 && f->line_ref && d < 8)) { - while (d > 0) - fputs("\n", s1->ppfp), --d; - } else if (s1->Pflag == LINE_MACRO_OUTPUT_FORMAT_STD) { - fprintf(s1->ppfp, "#line %d \"%s\"\n", f->line_num, f->filename); - } else { - fprintf(s1->ppfp, "# %d \"%s\"%s\n", f->line_num, f->filename, - level > 0 ? " 1" : level < 0 ? " 2" : ""); - } - } - f->line_ref = f->line_num; -} - -static uint8_t *parse_print_comment(uint8_t *p, int is_line_comment) -{ - int c, star_count; - FILE *ppfp = tcc_state->ppfp; - - if ((file->line_num - file->line_ref) > 0) { - fputc('\n', ppfp); - file->line_ref++; - pp_line(tcc_state, file, 0); - } - if (is_line_comment) - fputs("//", ppfp); else - fputs("/*", ppfp); - - star_count = 0; - for(;;) { - c = *p; - if (c == '\\') { - file->buf_ptr = p; - c = handle_eob(); - p = file->buf_ptr; - } - if (c == CH_EOF) { - if (is_line_comment) break; - tcc_error("unexpected end of file in comment"); - } - if (c == '*') - star_count++; - else { - if ((c == '/') && star_count && !is_line_comment) - break; - star_count = 0; - if (c == '\n') { - if (is_line_comment) break; - file->line_num++; - } - } - fputc(c, ppfp); - p++; - } - if (!is_line_comment) { - fputc('/', ppfp); - p++; - file->line_ref = file->line_num; - } - return p; -} - /* single line C++ comments */ -static uint8_t *parse_line_comment(uint8_t *p, int skip) +static uint8_t *parse_line_comment(uint8_t *p) { int c; p++; - if (tcc_state->option_C && !skip) - return parse_print_comment(p, 1); for(;;) { c = *p; redo: @@ -781,13 +731,11 @@ static uint8_t *parse_line_comment(uint8_t *p, int skip) } /* C comments */ -ST_FUNC uint8_t *parse_comment(uint8_t *p, int skip) +ST_FUNC uint8_t *parse_comment(uint8_t *p) { int c; p++; - if (tcc_state->option_C && !skip) - return parse_print_comment(p, 0); for(;;) { /* fast skip loop */ for(;;) { @@ -994,9 +942,9 @@ redo_start: minp(); p = file->buf_ptr; if (ch == '*') { - p = parse_comment(p,1); + p = parse_comment(p); } else if (ch == '/') { - p = parse_line_comment(p,1); + p = parse_line_comment(p); } break; case '#': @@ -1017,9 +965,9 @@ redo_start: else if (tok == TOK_LINEFEED) goto redo_start; else if (parse_flags & PARSE_FLAG_ASM_FILE) - p = parse_line_comment(p,0); + p = parse_line_comment(p); } else if (parse_flags & PARSE_FLAG_ASM_FILE) - p = parse_line_comment(p,0); + p = parse_line_comment(p); break; _default: default: @@ -1287,6 +1235,10 @@ static int macro_is_equal(const int *a, const int *b) { CValue cv; int t; + + if (!a || !b) + return 1; + while (*a && *b) { /* first time preallocate static cstr_buf, next time only reset position to start */ cstr_reset(&cstr_buf); @@ -1299,106 +1251,25 @@ static int macro_is_equal(const int *a, const int *b) return !(*a || *b); } -static void tok_print(const char *msg, const int *str) -{ - FILE *pr = tcc_state->dffp; - int t; - CValue cval; - - fprintf(pr, "%s ", msg); - while (str) { - TOK_GET(&t, &str, &cval); - if (!t) - break; - fprintf(pr,"%s", get_tok_str(t, &cval)); - } - fprintf(pr, "\n"); -} - -static int define_print_prepared(Sym *s) -{ - if (!s || !tcc_state->dffp || tcc_state->dflag == 0) - return 0; - - if (s->v < TOK_IDENT || s->v >= tok_ident) - return 0; - - if (file && tcc_state->dflag == 'D') { - file->line_num--; - pp_line(tcc_state, file, 0); - file->line_ref = ++file->line_num; - } - return 1; -} - -static void define_print(int v) -{ - FILE *pr = tcc_state->dffp; - Sym *s, *a; - - s = define_find(v); - if (define_print_prepared(s) == 0) - return; - - fprintf(pr, "// #define %s", get_tok_str(v, NULL)); - if (s->type.t == MACRO_FUNC) { - a = s->next; - fprintf(pr,"("); - if (a) - for (;;) { - fprintf(pr,"%s", get_tok_str(a->v & ~SYM_FIELD, NULL)); - if (!(a = a->next)) - break; - fprintf(pr,","); - } - fprintf(pr,")"); - } - tok_print("", s->d); -} - -static void undef_print(int v) -{ - FILE *pr = tcc_state->dffp; - Sym *s; - - s = define_find(v); - if (define_print_prepared(s) == 0) - return; - - fprintf(pr, "// #undef %s\n", get_tok_str(s->v, NULL)); -} - -ST_FUNC void print_defines(void) -{ - Sym *top = define_stack; - while (top) { - define_print(top->v); - top = top->prev; - } -} - /* defines handling */ ST_INLN void define_push(int v, int macro_type, TokenString *str, Sym *first_arg) { - Sym *s; - - if (str) { - s = define_find(v); - if (s && !macro_is_equal(s->d, str->str)) - tcc_warning("%s redefined", get_tok_str(v, NULL)); - } + Sym *s, *o; + o = define_find(v); s = sym_push2(&define_stack, v, macro_type, 0); s->d = str ? tok_str_dup(str) : NULL; s->next = first_arg; table_ident[v - TOK_IDENT]->sym_define = s; + + if (o && !macro_is_equal(o->d, s->d)) + tcc_warning("%s redefined", get_tok_str(v, NULL)); } /* undefined a define symbol. Its name is just set to zero */ ST_FUNC void define_undef(Sym *s) { int v = s->v; - undef_print(v); if (v >= TOK_IDENT && v < tok_ident) table_ident[v - TOK_IDENT]->sym_define = NULL; } @@ -1602,7 +1473,6 @@ ST_FUNC void parse_define(void) bad_twosharp: tcc_error("'##' cannot appear at either end of macro"); define_push(v, t, &tokstr_buf, first); - define_print(v); } static inline int hash_cached_include(const char *filename) @@ -1688,6 +1558,7 @@ static void pragma_parse(TCCState *s1) table_ident[v - TOK_IDENT]->sym_define = s->d ? s : NULL; else tcc_warning("unbalanced #pragma pop_macro"); + pp_debug_tok = t, pp_debug_symv = v; } else if (tok == TOK_once) { char buf1[sizeof(file->filename) + sizeof(ONCE_PREFIX)]; @@ -1788,11 +1659,15 @@ ST_FUNC void preprocess(int is_bof) redo: switch(tok) { case TOK_DEFINE: + pp_debug_tok = tok; next_nomacro(); + pp_debug_symv = tok; parse_define(); break; case TOK_UNDEF: + pp_debug_tok = tok; next_nomacro(); + pp_debug_symv = tok; s = define_find(tok); /* undefine symbol by putting an invalid name */ if (s) @@ -2059,7 +1934,7 @@ _line_num: goto ignore; tcc_warning("Ignoring unknown preprocessing directive #%s", get_tok_str(tok, &tokc)); ignore: - file->buf_ptr = parse_line_comment(file->buf_ptr,0); + file->buf_ptr = parse_line_comment(file->buf_ptr); goto the_end; } /* ignore other preprocess commands or #! for C scripts */ @@ -2655,7 +2530,7 @@ maybe_newline: tok = TOK_TWOSHARPS; } else { if (parse_flags & PARSE_FLAG_ASM_FILE) { - p = parse_line_comment(p - 1,0); + p = parse_line_comment(p - 1); goto redo_no_start; } else { tok = '#'; @@ -2918,17 +2793,13 @@ maybe_newline: case '/': PEEKC(c, p); if (c == '*') { - p = parse_comment(p,0); + p = parse_comment(p); /* comments replaced by a blank */ tok = ' '; - if (tcc_state->option_C) - goto redo_no_start; goto keep_tok_flags; } else if (c == '/') { - p = parse_line_comment(p,0); + p = parse_line_comment(p); tok = ' '; - if (tcc_state->option_C) - goto redo_no_start; goto keep_tok_flags; } else if (c == '=') { p++; @@ -3150,10 +3021,10 @@ static int next_argstream(Sym **nested_list, int can_read_stream, TokenString *w uint8_t *p = file->buf_ptr; PEEKC(c, p); if (c == '*') { - p = parse_comment(p,0); + p = parse_comment(p); file->buf_ptr = p - 1; } else if (c == '/') { - p = parse_line_comment(p,0); + p = parse_line_comment(p); file->buf_ptr = p - 1; } else break; @@ -3570,8 +3441,6 @@ ST_INLN void unget_tok(int last_tok) tok = last_tok; } -/* better than nothing, but needs extension to handle '-E' option - correctly too */ ST_FUNC void preprocess_init(TCCState *s1) { s1->include_stack_ptr = s1->include_stack; @@ -3585,8 +3454,7 @@ ST_FUNC void preprocess_init(TCCState *s1) s1->pack_stack_ptr = s1->pack_stack; isidnum_table['$' - CH_EOF] = - tcc_state->dollars_in_identifiers ? IS_ID : 0; - + s1->dollars_in_identifiers ? IS_ID : 0; isidnum_table['.' - CH_EOF] = (parse_flags & PARSE_FLAG_ASM_FILE) ? IS_ID : 0; } @@ -3665,11 +3533,122 @@ ST_FUNC void preprocess_delete(void) cstr_alloc = NULL; } +/* ------------------------------------------------------------------------- */ +/* tcc -E [-P[1]] [-dD} support */ + +static void tok_print(const char *msg, const int *str) +{ + FILE *fp; + int t; + CValue cval; + + fp = tcc_state->ppfp; + if (!fp || !tcc_state->dflag) + fp = stdout; + + fprintf(fp, "%s ", msg); + while (str) { + TOK_GET(&t, &str, &cval); + if (!t) + break; + fprintf(fp,"%s", get_tok_str(t, &cval)); + } + fprintf(fp, "\n"); +} + +static void pp_line(TCCState *s1, BufferedFile *f, int level) +{ + int d = f->line_num - f->line_ref; + + if (s1->dflag & 4) + return; + + if (s1->Pflag == LINE_MACRO_OUTPUT_FORMAT_NONE) { + if (level == 0 && f->line_ref && d) { + d = 1; + goto simple; + } + } else if (level == 0 && f->line_ref && d < 8) { +simple: + while (d > 0) + fputs("\n", s1->ppfp), --d; + } else if (s1->Pflag == LINE_MACRO_OUTPUT_FORMAT_STD) { + fprintf(s1->ppfp, "#line %d \"%s\"\n", f->line_num, f->filename); + } else { + fprintf(s1->ppfp, "# %d \"%s\"%s\n", f->line_num, f->filename, + level > 0 ? " 1" : level < 0 ? " 2" : ""); + } + f->line_ref = f->line_num; +} + +static void define_print(TCCState *s1, int v) +{ + FILE *fp; + Sym *s; + + s = define_find(v); + if (NULL == s || NULL == s->d) + return; + + fp = s1->ppfp; + fprintf(fp, "#define %s", get_tok_str(v, NULL)); + if (s->type.t == MACRO_FUNC) { + Sym *a = s->next; + fprintf(fp,"("); + if (a) + for (;;) { + fprintf(fp,"%s", get_tok_str(a->v & ~SYM_FIELD, NULL)); + if (!(a = a->next)) + break; + fprintf(fp,","); + } + fprintf(fp,")"); + } + tok_print("", s->d); +} + +static void pp_debug_defines(TCCState *s1) +{ + int v, t; + const char *vs; + FILE *fp; + + t = pp_debug_tok; + if (t == 0) + return; + + file->line_num--; + pp_line(s1, file, 0); + file->line_ref = ++file->line_num; + + fp = s1->ppfp; + v = pp_debug_symv; + vs = get_tok_str(v, NULL); + if (t == TOK_DEFINE) { + define_print(s1, v); + } else if (t == TOK_UNDEF) { + fprintf(fp, "#undef %s\n", vs); + } else if (t == TOK_push_macro) { + fprintf(fp, "#pragma push_macro(\"%s\")\n", vs); + } else if (t == TOK_pop_macro) { + fprintf(fp, "#pragma pop_macro(\"%s\")\n", vs); + } + pp_debug_tok = 0; +} + +static void pp_debug_builtins(TCCState *s1) +{ + int v; + for (v = TOK_IDENT; v < tok_ident; ++v) + define_print(s1, v); +} + /* Preprocess the current file */ ST_FUNC int tcc_preprocess(TCCState *s1) { BufferedFile **iptr; int token_seen, spcs, level; + Sym *define_start; preprocess_init(s1); ch = file->buf_ptr[0]; @@ -3680,12 +3659,19 @@ ST_FUNC int tcc_preprocess(TCCState *s1) | PARSE_FLAG_SPACES | PARSE_FLAG_ACCEPT_STRAYS ; + define_start = define_stack; #ifdef PP_BENCH + /* for PP benchmarks */ do next(); while (tok != TOK_EOF); return 0; #endif - token_seen = spcs = 0; + if (s1->dflag & 1) { + pp_debug_builtins(s1); + s1->dflag &= ~1; + } + + token_seen = TOK_LINEFEED, spcs = 0; pp_line(s1, file, 0); for (;;) { @@ -3700,7 +3686,13 @@ ST_FUNC int tcc_preprocess(TCCState *s1) pp_line(s1, file, level); } - if (0 == token_seen) { + if (s1->dflag) { + pp_debug_defines(s1); + if (s1->dflag & 4) + continue; + } + + if (token_seen == TOK_LINEFEED) { if (tok == ' ') { ++spcs; continue; @@ -3710,33 +3702,19 @@ ST_FUNC int tcc_preprocess(TCCState *s1) continue; } pp_line(s1, file, 0); - while (s1->ppfp && spcs > 0) - fputs(" ", s1->ppfp), --spcs; - spcs = 0; - token_seen = 1; - } else if (tok == TOK_LINEFEED) { ++file->line_ref; - token_seen = 0; } - if (s1->ppfp) - fputs(get_tok_str(tok, &tokc), s1->ppfp); - } - return 0; -} + while (spcs) + fputs(" ", s1->ppfp), --spcs; + fputs(get_tok_str(tok, &tokc), s1->ppfp); -ST_FUNC char *trimfront(char *p) -{ - while (*p && (unsigned char)*p <= ' ') - ++p; - return p; + token_seen = tok; + } + /* reset define stack, but keep -D and built-ins */ + free_defines(define_start); + return 0; } -ST_FUNC char *trimback(char *a, char *e) -{ - while (e > a && (unsigned char)e[-1] <= ' ') - --e; - *e = 0;; - return a; -} +/* ------------------------------------------------------------------------- */ |
