From 50cdccf3efaa13dd11d1533b73fb34e0429d5cd6 Mon Sep 17 00:00:00 2001 From: seyko Date: Tue, 3 Mar 2015 14:19:14 +0300 Subject: [PATCH] Added a gcc preprocessor options -P, -P1 tcc -E -P do not output a #line directive, a gcc compatible option tcc -E -P1 don't follow a gcc preprocessor style and do output a standard #line directive. In such case we don't lose a location info when we going to compile a resulting file wtith a compiler not understanding a gnu style line info. --- libtcc.c | 5 +++++ tcc.c | 2 ++ tcc.h | 5 +++++ tccpp.c | 44 ++++++++++++++++++++++++++++++++++---------- 4 files changed, 46 insertions(+), 10 deletions(-) diff --git a/libtcc.c b/libtcc.c index c68221e..3581ffb 100644 --- a/libtcc.c +++ b/libtcc.c @@ -1647,6 +1647,7 @@ enum { TCC_OPTION_I, TCC_OPTION_D, TCC_OPTION_U, + TCC_OPTION_P, TCC_OPTION_L, TCC_OPTION_B, TCC_OPTION_l, @@ -1695,6 +1696,7 @@ static const TCCOption tcc_options[] = { { "I", TCC_OPTION_I, TCC_OPTION_HAS_ARG }, { "D", TCC_OPTION_D, TCC_OPTION_HAS_ARG }, { "U", TCC_OPTION_U, TCC_OPTION_HAS_ARG }, + { "P", TCC_OPTION_P, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, { "L", TCC_OPTION_L, TCC_OPTION_HAS_ARG }, { "B", TCC_OPTION_B, TCC_OPTION_HAS_ARG }, { "l", TCC_OPTION_l, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, @@ -1930,6 +1932,9 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv) tcc_warning("-E: some compiler action already specified (%d)", s->output_type); s->output_type = TCC_OUTPUT_PREPROCESS; break; + case TCC_OPTION_P: + s->Pflag = atoi(optarg) + 1; + break; case TCC_OPTION_MD: s->gen_deps = 1; break; diff --git a/tcc.c b/tcc.c index 52afca7..7b19114 100644 --- a/tcc.c +++ b/tcc.c @@ -45,6 +45,8 @@ static void help(void) " -Idir add include path 'dir'\n" " -Dsym[=val] define 'sym' with value 'val'\n" " -Usym undefine 'sym'\n" + " -P do not output a #line directive\n" + " -P1 use a #line directive in output instead of the gcc style\n" "Linker options:\n" " -Ldir add library path 'dir'\n" " -llib link with dynamic or static library 'lib'\n" diff --git a/tcc.h b/tcc.h index e77a3fb..f268aed 100644 --- a/tcc.h +++ b/tcc.h @@ -656,6 +656,11 @@ struct TCCState { /* output file for preprocessing (-E) */ FILE *ppfp; + enum { + LINE_MACRO_OUTPUT_FORMAT_GCC, + LINE_MACRO_OUTPUT_FORMAT_NONE, + LINE_MACRO_OUTPUT_FORMAT_STD, + } Pflag; /* for -MD/-MF: collected dependencies for this compilation */ char **target_deps; diff --git a/tccpp.c b/tccpp.c index ab70ba2..18f3063 100644 --- a/tccpp.c +++ b/tccpp.c @@ -3133,6 +3133,26 @@ ST_FUNC void preprocess_new(void) } } +static void line_macro_output(BufferedFile *f, const char *s, TCCState *s1) +{ + switch (s1->Pflag) { + case LINE_MACRO_OUTPUT_FORMAT_STD: + /* "tcc -E -P1" case */ + fprintf(s1->ppfp, "# line %d \"%s\"\n", f->line_num, f->filename); + break; + + case LINE_MACRO_OUTPUT_FORMAT_NONE: + /* "tcc -E -P" case: don't output a line directive */ + break; + + case LINE_MACRO_OUTPUT_FORMAT_GCC: + default: + /* "tcc -E" case: a gcc standard by default */ + fprintf(s1->ppfp, "# %d \"%s\"%s\n", f->line_num, f->filename, s); + break; + } +} + /* Preprocess the current file */ ST_FUNC int tcc_preprocess(TCCState *s1) { @@ -3158,6 +3178,8 @@ ST_FUNC int tcc_preprocess(TCCState *s1) if (tok == TOK_EOF) { break; } else if (file != file_ref) { + if (file_ref) + line_macro_output(file_ref, "", s1); goto print_line; } else if (tok == TOK_LINEFEED) { if (!token_seen) @@ -3166,18 +3188,20 @@ ST_FUNC int tcc_preprocess(TCCState *s1) token_seen = 0; } else if (!token_seen) { d = file->line_num - file->line_ref; - if (file != file_ref || d < 0 || d >= 8) { + if (file != file_ref || d >= 8) { print_line: - iptr_new = s1->include_stack_ptr; - s = iptr_new > iptr ? " 1" - : iptr_new < iptr ? " 2" - : iptr_new > s1->include_stack ? " 3" - : "" - ; - iptr = iptr_new; - fprintf(s1->ppfp, "# %d \"%s\"%s\n", file->line_num, file->filename, s); + s = ""; + if (tcc_state->Pflag == LINE_MACRO_OUTPUT_FORMAT_GCC) { + iptr_new = s1->include_stack_ptr; + s = iptr_new > iptr ? " 1" + : iptr_new < iptr ? " 2" + : iptr_new > s1->include_stack ? " 3" + : "" + ; + } + line_macro_output(file, s, s1); } else { - while (d) + while (d > 0) fputs("\n", s1->ppfp), --d; } file->line_ref = (file_ref = file)->line_num;