preprocessor oprtion -C (keep comments)
This is done by impression of the pcc -C option. Usual execution path and speed are not changed.
This commit is contained in:
parent
16cbca281f
commit
c6dc756d4e
5 changed files with 195 additions and 48 deletions
20
libtcc.c
20
libtcc.c
|
@ -1604,6 +1604,21 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type)
|
||||||
{
|
{
|
||||||
s->output_type = 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) {
|
if (!s->nostdinc) {
|
||||||
/* default include paths */
|
/* default include paths */
|
||||||
/* -isystem paths have already been handled */
|
/* -isystem paths have already been handled */
|
||||||
|
@ -1946,6 +1961,7 @@ enum {
|
||||||
TCC_OPTION_b,
|
TCC_OPTION_b,
|
||||||
TCC_OPTION_g,
|
TCC_OPTION_g,
|
||||||
TCC_OPTION_c,
|
TCC_OPTION_c,
|
||||||
|
TCC_OPTION_C,
|
||||||
TCC_OPTION_dumpversion,
|
TCC_OPTION_dumpversion,
|
||||||
TCC_OPTION_d,
|
TCC_OPTION_d,
|
||||||
TCC_OPTION_float_abi,
|
TCC_OPTION_float_abi,
|
||||||
|
@ -2003,6 +2019,7 @@ static const TCCOption tcc_options[] = {
|
||||||
#endif
|
#endif
|
||||||
{ "g", TCC_OPTION_g, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
|
{ "g", TCC_OPTION_g, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
|
||||||
{ "c", TCC_OPTION_c, 0 },
|
{ "c", TCC_OPTION_c, 0 },
|
||||||
|
{ "C", TCC_OPTION_C, 0 },
|
||||||
{ "dumpversion", TCC_OPTION_dumpversion, 0},
|
{ "dumpversion", TCC_OPTION_dumpversion, 0},
|
||||||
{ "d", TCC_OPTION_d, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
|
{ "d", TCC_OPTION_d, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
|
||||||
#ifdef TCC_TARGET_ARM
|
#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);
|
tcc_warning("-c: some compiler action already specified (%d)", s->output_type);
|
||||||
s->output_type = TCC_OUTPUT_OBJ;
|
s->output_type = TCC_OUTPUT_OBJ;
|
||||||
break;
|
break;
|
||||||
|
case TCC_OPTION_C:
|
||||||
|
s->option_C = 1;
|
||||||
|
break;
|
||||||
case TCC_OPTION_d:
|
case TCC_OPTION_d:
|
||||||
if (*optarg == 'D' || *optarg == 'M')
|
if (*optarg == 'D' || *optarg == 'M')
|
||||||
s->dflag = *optarg;
|
s->dflag = *optarg;
|
||||||
|
|
18
tcc.c
18
tcc.c
|
@ -98,8 +98,9 @@ static void help(void)
|
||||||
" -Dsym[=val] define 'sym' with value 'val'\n"
|
" -Dsym[=val] define 'sym' with value 'val'\n"
|
||||||
" -Usym undefine 'sym'\n"
|
" -Usym undefine 'sym'\n"
|
||||||
" -E preprocess only\n"
|
" -E preprocess only\n"
|
||||||
" -P[1] no/alternative output of #line directives with -E\n"
|
" -P[1] no/alternative output of #line directives\n"
|
||||||
" -d{D|M} dump defines (only with -E)\n"
|
" -d{D|M} dump defines\n"
|
||||||
|
" -C keep comments\n"
|
||||||
"Linker options:\n"
|
"Linker options:\n"
|
||||||
" -Ldir add library path 'dir'\n"
|
" -Ldir add library path 'dir'\n"
|
||||||
" -llib link with dynamic or static library 'lib'\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);
|
tcc_set_output_type(s, s->output_type);
|
||||||
|
|
||||||
/* compile or add each files or library */
|
/* compile or add each files or library */
|
||||||
|
|
3
tcc.h
3
tcc.h
|
@ -812,6 +812,7 @@ struct TCCState {
|
||||||
char *option_m; /* only -m32/-m64 handled */
|
char *option_m; /* only -m32/-m64 handled */
|
||||||
int print_search_dirs; /* option */
|
int print_search_dirs; /* option */
|
||||||
int option_r; /* option -r */
|
int option_r; /* option -r */
|
||||||
|
int option_C; /* option -C, keep comments when -E */
|
||||||
int do_bench; /* option -bench */
|
int do_bench; /* option -bench */
|
||||||
int gen_deps; /* option -MD */
|
int gen_deps; /* option -MD */
|
||||||
char *deps_outfile; /* option -MF */
|
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
|
#ifndef TCC_TARGET_PE
|
||||||
ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level);
|
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 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_FUNC void minp(void);
|
||||||
ST_INLN void inp(void);
|
ST_INLN void inp(void);
|
||||||
ST_FUNC int handle_eob(void);
|
ST_FUNC int handle_eob(void);
|
||||||
|
|
2
tccelf.c
2
tccelf.c
|
@ -3282,7 +3282,7 @@ static int ld_next(TCCState *s1, char *name, int name_size)
|
||||||
case '/':
|
case '/':
|
||||||
minp();
|
minp();
|
||||||
if (ch == '*') {
|
if (ch == '*') {
|
||||||
file->buf_ptr = parse_comment(file->buf_ptr);
|
file->buf_ptr = parse_comment(file->buf_ptr,0);
|
||||||
ch = file->buf_ptr[0];
|
ch = file->buf_ptr[0];
|
||||||
goto redo;
|
goto redo;
|
||||||
} else {
|
} else {
|
||||||
|
|
200
tccpp.c
200
tccpp.c
|
@ -524,13 +524,163 @@ ST_FUNC void minp(void)
|
||||||
handle_stray();
|
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 */
|
/* 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;
|
int c;
|
||||||
|
|
||||||
p++;
|
p++;
|
||||||
|
if (tcc_state->option_C && !skip)
|
||||||
|
return parse_print_line_comment(p);
|
||||||
for(;;) {
|
for(;;) {
|
||||||
c = *p;
|
c = *p;
|
||||||
redo:
|
redo:
|
||||||
|
@ -563,11 +713,13 @@ static uint8_t *parse_line_comment(uint8_t *p)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* C comments */
|
/* C comments */
|
||||||
ST_FUNC uint8_t *parse_comment(uint8_t *p)
|
ST_FUNC uint8_t *parse_comment(uint8_t *p, int skip)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
p++;
|
p++;
|
||||||
|
if (tcc_state->option_C && !skip)
|
||||||
|
return parse_print_comment(p);
|
||||||
for(;;) {
|
for(;;) {
|
||||||
/* fast skip loop */
|
/* fast skip loop */
|
||||||
for(;;) {
|
for(;;) {
|
||||||
|
@ -774,9 +926,9 @@ redo_start:
|
||||||
minp();
|
minp();
|
||||||
p = file->buf_ptr;
|
p = file->buf_ptr;
|
||||||
if (ch == '*') {
|
if (ch == '*') {
|
||||||
p = parse_comment(p);
|
p = parse_comment(p,1);
|
||||||
} else if (ch == '/') {
|
} else if (ch == '/') {
|
||||||
p = parse_line_comment(p);
|
p = parse_line_comment(p,1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '#':
|
case '#':
|
||||||
|
@ -797,9 +949,9 @@ redo_start:
|
||||||
else if (tok == TOK_LINEFEED)
|
else if (tok == TOK_LINEFEED)
|
||||||
goto redo_start;
|
goto redo_start;
|
||||||
else if (parse_flags & PARSE_FLAG_ASM_FILE)
|
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)
|
} else if (parse_flags & PARSE_FLAG_ASM_FILE)
|
||||||
p = parse_line_comment(p);
|
p = parse_line_comment(p,0);
|
||||||
break;
|
break;
|
||||||
_default:
|
_default:
|
||||||
default:
|
default:
|
||||||
|
@ -1072,24 +1224,6 @@ static int macro_is_equal(const int *a, const int *b)
|
||||||
return !(*a || *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)
|
static void tok_print(const char *msg, const int *str)
|
||||||
{
|
{
|
||||||
FILE *pr = tcc_state->dffp;
|
FILE *pr = tcc_state->dffp;
|
||||||
|
@ -1848,7 +1982,7 @@ _line_num:
|
||||||
goto ignore;
|
goto ignore;
|
||||||
tcc_warning("Ignoring unknown preprocessing directive #%s", get_tok_str(tok, &tokc));
|
tcc_warning("Ignoring unknown preprocessing directive #%s", get_tok_str(tok, &tokc));
|
||||||
ignore:
|
ignore:
|
||||||
file->buf_ptr = parse_line_comment(file->buf_ptr);
|
file->buf_ptr = parse_line_comment(file->buf_ptr,0);
|
||||||
goto the_end;
|
goto the_end;
|
||||||
}
|
}
|
||||||
/* ignore other preprocess commands or #! for C scripts */
|
/* ignore other preprocess commands or #! for C scripts */
|
||||||
|
@ -2444,7 +2578,7 @@ maybe_newline:
|
||||||
tok = TOK_TWOSHARPS;
|
tok = TOK_TWOSHARPS;
|
||||||
} else {
|
} else {
|
||||||
if (parse_flags & PARSE_FLAG_ASM_FILE) {
|
if (parse_flags & PARSE_FLAG_ASM_FILE) {
|
||||||
p = parse_line_comment(p - 1);
|
p = parse_line_comment(p - 1,0);
|
||||||
goto redo_no_start;
|
goto redo_no_start;
|
||||||
} else {
|
} else {
|
||||||
tok = '#';
|
tok = '#';
|
||||||
|
@ -2711,13 +2845,17 @@ maybe_newline:
|
||||||
case '/':
|
case '/':
|
||||||
PEEKC(c, p);
|
PEEKC(c, p);
|
||||||
if (c == '*') {
|
if (c == '*') {
|
||||||
p = parse_comment(p);
|
p = parse_comment(p,0);
|
||||||
/* comments replaced by a blank */
|
/* comments replaced by a blank */
|
||||||
tok = ' ';
|
tok = ' ';
|
||||||
|
if (tcc_state->option_C)
|
||||||
|
goto redo_no_start;
|
||||||
goto keep_tok_flags;
|
goto keep_tok_flags;
|
||||||
} else if (c == '/') {
|
} else if (c == '/') {
|
||||||
p = parse_line_comment(p);
|
p = parse_line_comment(p,0);
|
||||||
tok = ' ';
|
tok = ' ';
|
||||||
|
if (tcc_state->option_C)
|
||||||
|
goto redo_no_start;
|
||||||
goto keep_tok_flags;
|
goto keep_tok_flags;
|
||||||
} else if (c == '=') {
|
} else if (c == '=') {
|
||||||
p++;
|
p++;
|
||||||
|
@ -2939,10 +3077,10 @@ static int next_argstream(Sym **nested_list, int can_read_stream, TokenString *w
|
||||||
uint8_t *p = file->buf_ptr;
|
uint8_t *p = file->buf_ptr;
|
||||||
PEEKC(c, p);
|
PEEKC(c, p);
|
||||||
if (c == '*') {
|
if (c == '*') {
|
||||||
p = parse_comment(p);
|
p = parse_comment(p,0);
|
||||||
file->buf_ptr = p - 1;
|
file->buf_ptr = p - 1;
|
||||||
} else if (c == '/') {
|
} else if (c == '/') {
|
||||||
p = parse_line_comment(p);
|
p = parse_line_comment(p,0);
|
||||||
file->buf_ptr = p - 1;
|
file->buf_ptr = p - 1;
|
||||||
} else
|
} else
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue