aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbellard <bellard>2006-10-16 19:44:00 +0000
committerbellard <bellard>2006-10-16 19:44:00 +0000
commit200b58dad81f4c871e6796695577076fa90ee0ed (patch)
tree78417dc726c565822091fa3112faeb9cd88bcb36
parent6ca0299e5b7b9d59a56c6d1674ee61b2bc84c608 (diff)
downloadtinycc-200b58dad81f4c871e6796695577076fa90ee0ed.tar.gz
tinycc-200b58dad81f4c871e6796695577076fa90ee0ed.tar.bz2
initial implementation of -E option
-rw-r--r--libtcc.h1
-rw-r--r--tcc.c95
2 files changed, 85 insertions, 11 deletions
diff --git a/libtcc.h b/libtcc.h
index db77000..6cacd73 100644
--- a/libtcc.h
+++ b/libtcc.h
@@ -60,6 +60,7 @@ int tcc_compile_string(TCCState *s, const char *buf);
#define TCC_OUTPUT_EXE 1 /* executable file */
#define TCC_OUTPUT_DLL 2 /* dynamic library */
#define TCC_OUTPUT_OBJ 3 /* object file */
+#define TCC_OUTPUT_PREPROCESS 4 /* preprocessed file (used internally) */
int tcc_set_output_type(TCCState *s, int output_type);
#define TCC_OUTPUT_FORMAT_ELF 0 /* default output format: ELF */
diff --git a/tcc.c b/tcc.c
index 76c19a5..7596adf 100644
--- a/tcc.c
+++ b/tcc.c
@@ -504,6 +504,9 @@ struct TCCState {
/* pack stack */
int pack_stack[PACK_STACK_SIZE];
int *pack_stack_ptr;
+
+ /* output file for preprocessing */
+ FILE *outfile;
};
/* The current value can be: */
@@ -839,6 +842,7 @@ static int tcc_add_dll(TCCState *s, const char *filename, int flags);
#define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
#define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
+#define AFF_PREPROCESS 0x0004 /* preprocess file */
static int tcc_add_file_internal(TCCState *s, const char *filename, int flags);
/* tcccoff.c */
@@ -1675,6 +1679,8 @@ char *get_tok_str(int v, CValue *cv)
case TOK_GT:
v = '>';
goto addv;
+ case TOK_DOTS:
+ return strcpy(p, "...");
case TOK_A_SHL:
return strcpy(p, "<<=");
case TOK_A_SAR:
@@ -9279,6 +9285,47 @@ static int tcc_compile(TCCState *s1)
return s1->nb_errors != 0 ? -1 : 0;
}
+/* Preprocess the current file */
+/* XXX: add line and file infos, add options to preserve spaces */
+static int tcc_preprocess(TCCState *s1)
+{
+ Sym *define_start;
+ int last_is_space;
+
+ preprocess_init(s1);
+
+ define_start = define_stack;
+
+ ch = file->buf_ptr[0];
+ tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
+ parse_flags = PARSE_FLAG_ASM_COMMENTS | PARSE_FLAG_PREPROCESS |
+ PARSE_FLAG_LINEFEED;
+ last_is_space = 1;
+ next();
+ for(;;) {
+ if (tok == TOK_EOF)
+ break;
+ if (!last_is_space) {
+ fputc(' ', s1->outfile);
+ }
+ fputs(get_tok_str(tok, &tokc), s1->outfile);
+ if (tok == TOK_LINEFEED) {
+ last_is_space = 1;
+ /* XXX: suppress that hack */
+ parse_flags &= ~PARSE_FLAG_LINEFEED;
+ next();
+ parse_flags |= PARSE_FLAG_LINEFEED;
+ } else {
+ last_is_space = 0;
+ next();
+ }
+ }
+
+ free_defines(define_start);
+
+ return 0;
+}
+
#ifdef LIBTCC
int tcc_compile_string(TCCState *s, const char *str)
{
@@ -9944,7 +9991,9 @@ static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
goto fail1;
}
- if (!ext || !strcmp(ext, "c")) {
+ if (flags & AFF_PREPROCESS) {
+ ret = tcc_preprocess(s1);
+ } else if (!ext || !strcmp(ext, "c")) {
/* C file assumed */
ret = tcc_compile(s1);
} else
@@ -10264,7 +10313,7 @@ static int64_t getclock_us(void)
void help(void)
{
- printf("tcc version " TCC_VERSION " - Tiny C Compiler - Copyright (C) 2001-2005 Fabrice Bellard\n"
+ printf("tcc version " TCC_VERSION " - Tiny C Compiler - Copyright (C) 2001-2006 Fabrice Bellard\n"
"usage: tcc [-v] [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
" [-Wwarn] [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n"
" [infile1 infile2...] [-run infile args...]\n"
@@ -10280,6 +10329,7 @@ void help(void)
" -Wwarning set or reset (with 'no-' prefix) 'warning' (see man page)\n"
" -w disable all warnings\n"
"Preprocessor options:\n"
+ " -E preprocess only\n"
" -Idir add include path 'dir'\n"
" -Dsym[=val] define 'sym' with value 'val'\n"
" -Usym undefine 'sym'\n"
@@ -10338,6 +10388,7 @@ enum {
TCC_OPTION_v,
TCC_OPTION_w,
TCC_OPTION_pipe,
+ TCC_OPTION_E,
};
static const TCCOption tcc_options[] = {
@@ -10373,6 +10424,7 @@ static const TCCOption tcc_options[] = {
{ "v", TCC_OPTION_v, 0 },
{ "w", TCC_OPTION_w, 0 },
{ "pipe", TCC_OPTION_pipe, 0},
+ { "E", TCC_OPTION_E, 0},
{ NULL },
};
@@ -10601,6 +10653,9 @@ int parse_args(TCCState *s, int argc, char **argv)
}
}
break;
+ case TCC_OPTION_E:
+ output_type = TCC_OUTPUT_PREPROCESS;
+ break;
default:
if (s->warn_unsupported) {
unsupported_option:
@@ -10657,7 +10712,7 @@ int main(int argc, char **argv)
printf("install: %s/\n", tcc_lib_path);
return 0;
}
-
+
nb_objfiles = nb_files - nb_libraries;
/* if outfile provided without other options, we output an
@@ -10674,7 +10729,16 @@ int main(int argc, char **argv)
error("cannot specify libraries with -c");
}
- if (output_type != TCC_OUTPUT_MEMORY) {
+
+ if (output_type == TCC_OUTPUT_PREPROCESS) {
+ if (!outfile) {
+ s->outfile = stdout;
+ } else {
+ s->outfile = fopen(outfile, "wb");
+ if (!s->outfile)
+ error("could not open '%s", outfile);
+ }
+ } else if (output_type != TCC_OUTPUT_MEMORY) {
if (!outfile) {
/* compute default outfile name */
pstrcpy(objfilename, sizeof(objfilename) - 1,
@@ -10709,13 +10773,18 @@ int main(int argc, char **argv)
const char *filename;
filename = files[i];
- if (filename[0] == '-') {
- if (tcc_add_library(s, filename + 2) < 0)
- error("cannot find %s", filename);
+ if (output_type == TCC_OUTPUT_PREPROCESS) {
+ tcc_add_file_internal(s, filename,
+ AFF_PRINT_ERROR | AFF_PREPROCESS);
} else {
- if (tcc_add_file(s, filename) < 0) {
- ret = 1;
- goto the_end;
+ if (filename[0] == '-') {
+ if (tcc_add_library(s, filename + 2) < 0)
+ error("cannot find %s", filename);
+ } else {
+ if (tcc_add_file(s, filename) < 0) {
+ ret = 1;
+ goto the_end;
+ }
}
}
}
@@ -10736,7 +10805,11 @@ int main(int argc, char **argv)
total_bytes / total_time / 1000000.0);
}
- if (s->output_type == TCC_OUTPUT_MEMORY) {
+ if (s->output_type == TCC_OUTPUT_PREPROCESS) {
+ if (outfile)
+ fclose(s->outfile);
+ ret = 0;
+ } else if (s->output_type == TCC_OUTPUT_MEMORY) {
ret = tcc_run(s, argc - optind, argv + optind);
} else
#ifdef TCC_TARGET_PE