aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libtcc.c20
-rw-r--r--tcc.c18
-rw-r--r--tcc.h3
-rw-r--r--tccelf.c2
-rw-r--r--tccpp.c200
5 files changed, 195 insertions, 48 deletions
diff --git a/libtcc.c b/libtcc.c
index 678ba23..d587179 100644
--- a/libtcc.c
+++ b/libtcc.c
@@ -1604,6 +1604,21 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type)
{
s->output_type = output_type;
+ if (s->output_type == TCC_OUTPUT_PREPROCESS) {
+ if (!s->outfile) {
+ s->ppfp = stdout;
+ } else {
+ s->ppfp = fopen(s->outfile, "w");
+ if (!s->ppfp)
+ tcc_error("could not write '%s'", s->outfile);
+ }
+ s->dffp = s->ppfp;
+ if (s->dflag == 'M')
+ s->ppfp = NULL;
+ }
+ if (s->option_C && !s->ppfp)
+ s->option_C = 0;
+
if (!s->nostdinc) {
/* default include paths */
/* -isystem paths have already been handled */
@@ -1946,6 +1961,7 @@ enum {
TCC_OPTION_b,
TCC_OPTION_g,
TCC_OPTION_c,
+ TCC_OPTION_C,
TCC_OPTION_dumpversion,
TCC_OPTION_d,
TCC_OPTION_float_abi,
@@ -2003,6 +2019,7 @@ static const TCCOption tcc_options[] = {
#endif
{ "g", TCC_OPTION_g, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
{ "c", TCC_OPTION_c, 0 },
+ { "C", TCC_OPTION_C, 0 },
{ "dumpversion", TCC_OPTION_dumpversion, 0},
{ "d", TCC_OPTION_d, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
#ifdef TCC_TARGET_ARM
@@ -2191,6 +2208,9 @@ ST_FUNC int tcc_parse_args1(TCCState *s, int argc, char **argv)
tcc_warning("-c: some compiler action already specified (%d)", s->output_type);
s->output_type = TCC_OUTPUT_OBJ;
break;
+ case TCC_OPTION_C:
+ s->option_C = 1;
+ break;
case TCC_OPTION_d:
if (*optarg == 'D' || *optarg == 'M')
s->dflag = *optarg;
diff --git a/tcc.c b/tcc.c
index 722bd4c..e79e1fb 100644
--- a/tcc.c
+++ b/tcc.c
@@ -98,8 +98,9 @@ static void help(void)
" -Dsym[=val] define 'sym' with value 'val'\n"
" -Usym undefine 'sym'\n"
" -E preprocess only\n"
- " -P[1] no/alternative output of #line directives with -E\n"
- " -d{D|M} dump defines (only with -E)\n"
+ " -P[1] no/alternative output of #line directives\n"
+ " -d{D|M} dump defines\n"
+ " -C keep comments\n"
"Linker options:\n"
" -Ldir add library path 'dir'\n"
" -llib link with dynamic or static library 'lib'\n"
@@ -294,19 +295,6 @@ int main(int argc, char **argv)
}
}
- if (s->output_type == TCC_OUTPUT_PREPROCESS) {
- if (!s->outfile) {
- s->ppfp = stdout;
- } else {
- s->ppfp = fopen(s->outfile, "w");
- if (!s->ppfp)
- tcc_error("could not write '%s'", s->outfile);
- }
- s->dffp = s->ppfp;
- if (s->dflag == 'M')
- s->ppfp = NULL;
- }
-
tcc_set_output_type(s, s->output_type);
/* compile or add each files or library */
diff --git a/tcc.h b/tcc.h
index dd4ecd5..208af44 100644
--- a/tcc.h
+++ b/tcc.h
@@ -812,6 +812,7 @@ struct TCCState {
char *option_m; /* only -m32/-m64 handled */
int print_search_dirs; /* option */
int option_r; /* option -r */
+ int option_C; /* option -C, keep comments when -E */
int do_bench; /* option -bench */
int gen_deps; /* option -MD */
char *deps_outfile; /* option -MF */
@@ -1406,7 +1407,7 @@ ST_FUNC void *tcc_get_symbol_err(TCCState *s, const char *name);
#ifndef TCC_TARGET_PE
ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level);
ST_FUNC int tcc_load_ldscript(TCCState *s1);
-ST_FUNC uint8_t *parse_comment(uint8_t *p);
+ST_FUNC uint8_t *parse_comment(uint8_t *p, int skip);
ST_FUNC void minp(void);
ST_INLN void inp(void);
ST_FUNC int handle_eob(void);
diff --git a/tccelf.c b/tccelf.c
index 196dd65..a09e36a 100644
--- a/tccelf.c
+++ b/tccelf.c
@@ -3282,7 +3282,7 @@ static int ld_next(TCCState *s1, char *name, int name_size)
case '/':
minp();
if (ch == '*') {
- file->buf_ptr = parse_comment(file->buf_ptr);
+ file->buf_ptr = parse_comment(file->buf_ptr,0);
ch = file->buf_ptr[0];
goto redo;
} else {
diff --git a/tccpp.c b/tccpp.c
index cb220ab..765a569 100644
--- a/tccpp.c
+++ b/tccpp.c
@@ -524,13 +524,163 @@ 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_line_comment(uint8_t *p)
+{
+ int c;
+
+ if ((file->line_num - file->line_ref) > 0) {
+ fputc('\n', tcc_state->ppfp);
+ file->line_ref++;
+ pp_line(tcc_state, file, 0);
+ }
+ fputs("// ", tcc_state->ppfp);
+
+ for(;;) {
+ c = *p;
+ redo:
+ if (c == '\n' || c == CH_EOF)
+ break;
+ fputc(c, tcc_state->ppfp);
+ if (c == '\\') {
+ file->buf_ptr = p;
+ c = handle_eob();
+ p = file->buf_ptr;
+ if (c == '\\') {
+ PEEKC_EOB(c, p);
+ if (c == '\n') {
+ file->line_num++;
+ PEEKC_EOB(c, p);
+ } else if (c == '\r') {
+ PEEKC_EOB(c, p);
+ if (c == '\n') {
+ file->line_num++;
+ PEEKC_EOB(c, p);
+ }
+ }
+ } else {
+ goto redo;
+ }
+ } else {
+ p++;
+ }
+ }
+ return p;
+}
+
+
+static uint8_t *parse_print_comment(uint8_t *p)
+{
+ int c;
+
+ if ((file->line_num - file->line_ref) > 0) {
+ fputc('\n', tcc_state->ppfp);
+ file->line_ref++;
+ pp_line(tcc_state, file, 0);
+ }
+ fputs("/*", tcc_state->ppfp);
+
+ for(;;) {
+ /* fast skip loop */
+ for(;;) {
+ c = *p;
+ if (c == '\n' || c == '*' || c == '\\')
+ break;
+ fputc(c, tcc_state->ppfp);
+ p++;
+ }
+ /* now we can handle all the cases */
+ if (c == '\n') {
+ fputc(c, tcc_state->ppfp);
+ file->line_num++;
+ p++;
+ } else if (c == '*') {
+ fputc(c, tcc_state->ppfp);
+ p++;
+ for(;;) {
+ c = *p;
+ if (c == '*') {
+ fputc(c, tcc_state->ppfp);
+ p++;
+ } else if (c == '/') {
+ fputc(c, tcc_state->ppfp);
+ goto end_of_comment;
+ } else if (c == '\\') {
+ file->buf_ptr = p;
+ c = handle_eob();
+ p = file->buf_ptr;
+ if (c == CH_EOF)
+ tcc_error("unexpected end of file in comment");
+ if (c == '\\') {
+ /* skip '\[\r]\n', otherwise just skip the stray */
+ while (c == '\\') {
+ fputc(c, tcc_state->ppfp);
+ PEEKC_EOB(c, p);
+ if (c == '\n') {
+ fputc(c, tcc_state->ppfp);
+ file->line_num++;
+ PEEKC_EOB(c, p);
+ } else if (c == '\r') {
+ PEEKC_EOB(c, p);
+ if (c == '\n') {
+ fputc(c, tcc_state->ppfp);
+ file->line_num++;
+ PEEKC_EOB(c, p);
+ }
+ } else {
+ goto after_star;
+ }
+ }
+ }
+ } else {
+ break;
+ }
+ }
+ after_star: ;
+ } else {
+ /* stray, eob or eof */
+ file->buf_ptr = p;
+ c = handle_eob();
+ p = file->buf_ptr;
+ if (c == CH_EOF)
+ tcc_error("unexpected end of file in comment");
+ if (c == '\\') {
+ fputc(c, tcc_state->ppfp);
+ p++;
+ }
+ }
+ }
+ end_of_comment:
+ p++;
+ file->line_ref = file->line_num;
+ return p;
+}
/* single line C++ comments */
-static uint8_t *parse_line_comment(uint8_t *p)
+static uint8_t *parse_line_comment(uint8_t *p, int skip)
{
int c;
p++;
+ if (tcc_state->option_C && !skip)
+ return parse_print_line_comment(p);
for(;;) {
c = *p;
redo:
@@ -563,11 +713,13 @@ static uint8_t *parse_line_comment(uint8_t *p)
}
/* C comments */
-ST_FUNC uint8_t *parse_comment(uint8_t *p)
+ST_FUNC uint8_t *parse_comment(uint8_t *p, int skip)
{
int c;
-
+
p++;
+ if (tcc_state->option_C && !skip)
+ return parse_print_comment(p);
for(;;) {
/* fast skip loop */
for(;;) {
@@ -774,9 +926,9 @@ redo_start:
minp();
p = file->buf_ptr;
if (ch == '*') {
- p = parse_comment(p);
+ p = parse_comment(p,1);
} else if (ch == '/') {
- p = parse_line_comment(p);
+ p = parse_line_comment(p,1);
}
break;
case '#':
@@ -797,9 +949,9 @@ redo_start:
else if (tok == TOK_LINEFEED)
goto redo_start;
else if (parse_flags & PARSE_FLAG_ASM_FILE)
- p = parse_line_comment(p);
+ p = parse_line_comment(p,0);
} else if (parse_flags & PARSE_FLAG_ASM_FILE)
- p = parse_line_comment(p);
+ p = parse_line_comment(p,0);
break;
_default:
default:
@@ -1072,24 +1224,6 @@ static int macro_is_equal(const int *a, const int *b)
return !(*a || *b);
}
-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 void tok_print(const char *msg, const int *str)
{
FILE *pr = tcc_state->dffp;
@@ -1848,7 +1982,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);
+ file->buf_ptr = parse_line_comment(file->buf_ptr,0);
goto the_end;
}
/* ignore other preprocess commands or #! for C scripts */
@@ -2444,7 +2578,7 @@ maybe_newline:
tok = TOK_TWOSHARPS;
} else {
if (parse_flags & PARSE_FLAG_ASM_FILE) {
- p = parse_line_comment(p - 1);
+ p = parse_line_comment(p - 1,0);
goto redo_no_start;
} else {
tok = '#';
@@ -2711,13 +2845,17 @@ maybe_newline:
case '/':
PEEKC(c, p);
if (c == '*') {
- p = parse_comment(p);
+ p = parse_comment(p,0);
/* 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);
+ p = parse_line_comment(p,0);
tok = ' ';
+ if (tcc_state->option_C)
+ goto redo_no_start;
goto keep_tok_flags;
} else if (c == '=') {
p++;
@@ -2939,10 +3077,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);
+ p = parse_comment(p,0);
file->buf_ptr = p - 1;
} else if (c == '/') {
- p = parse_line_comment(p);
+ p = parse_line_comment(p,0);
file->buf_ptr = p - 1;
} else
break;