aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorseyko <seyko2@gmail.com>2015-03-03 14:19:14 +0300
committerseyko <seyko2@gmail.com>2015-03-03 14:19:14 +0300
commit50cdccf3efaa13dd11d1533b73fb34e0429d5cd6 (patch)
tree0239fe1588a10cc4d70c80a2e2aba9f1ca185f4a
parent40418f87c7da9d3358363769fb13c558b43f2847 (diff)
downloadtinycc-50cdccf3efaa13dd11d1533b73fb34e0429d5cd6.tar.gz
tinycc-50cdccf3efaa13dd11d1533b73fb34e0429d5cd6.tar.bz2
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.
-rw-r--r--libtcc.c5
-rw-r--r--tcc.c2
-rw-r--r--tcc.h5
-rw-r--r--tccpp.c44
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;