diff -urN tcc-0.9.23/tcc.c tcc-0.9.23-lepton/tcc.c --- tcc-0.9.23/tcc.c 2005-06-27 23:05:42.000000000 +0800 +++ tcc-0.9.23-lepton/tcc.c 2005-06-27 23:28:43.000000000 +0800 @@ -222,6 +222,13 @@ unsigned char dllexport; } AttributeDef; +struct inc_item { + char *inc_name; + struct inc_item * next; +}; + +static struct inc_item * inc_item_chain=NULL, * inc_item_head=NULL, * inc_item_tail=NULL; + #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */ #define SYM_FIELD 0x20000000 /* struct/union field symbol space */ #define SYM_FIRST_ANOM 0x10000000 /* first anonymous sym */ @@ -828,6 +835,8 @@ #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */ static int tcc_add_file_internal(TCCState *s, const char *filename, int flags); +static void tcc_add_include(TCCState *s, const char *filename); + /* tcccoff.c */ int tcc_output_coff(TCCState *s1, FILE *f); @@ -3535,8 +3544,15 @@ /* pop include stack */ tcc_close(file); s1->include_stack_ptr--; - file = *s1->include_stack_ptr; - p = file->buf_ptr; + if(inc_item_chain){ + tcc_add_include(s1, inc_item_chain->inc_name); + inc_item_chain=inc_item_chain->next; + p = file->buf_ptr; + } + else { + file = *s1->include_stack_ptr; + p = file->buf_ptr; + } goto redo_no_start; } } @@ -9212,6 +9228,11 @@ ch = file->buf_ptr[0]; tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM; + if(inc_item_head){ + inc_item_chain=inc_item_head; + tcc_add_include(s1, inc_item_chain->inc_name); + inc_item_chain=inc_item_chain->next; + } next(); decl(VT_CONST); if (tok != TOK_EOF) @@ -9309,6 +9330,72 @@ define_undef(s); } +static void tcc_add_include(TCCState *s1, const char *buf) +{ + static CachedInclude *e; + int size, n, i; + char *p, buf1[1024]; + BufferedFile *f; + e = search_cached_include(s1, '\"', buf); + if (e && define_find(e->ifndef_macro)) { + /* no need to parse the include because the 'ifndef macro' + is defined */ +#ifdef INC_DEBUG + printf("%s: skipping %s\n", file->filename, buf); +#endif + } else { + /* first search in current dir if "header.h" */ + size = 0; + p = strrchr(file->filename, '/'); + if (p) + size = p + 1 - file->filename; + if (size > sizeof(buf1) - 1) + size = sizeof(buf1) - 1; + memcpy(buf1, file->filename, size); + buf1[size] = '\0'; + pstrcat(buf1, sizeof(buf1), buf); + f = tcc_open(s1, buf1); + if (f) + goto found; + } + if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE) + error("#include recursion too deep"); + /* now search in all the include paths */ + n = s1->nb_include_paths + s1->nb_sysinclude_paths; + for(i = 0; i < n; i++) { + const char *path; + if (i < s1->nb_include_paths) + path = s1->include_paths[i]; + else + path = s1->sysinclude_paths[i - s1->nb_include_paths]; + pstrcpy(buf1, sizeof(buf1), path); + pstrcat(buf1, sizeof(buf1), "/"); + pstrcat(buf1, sizeof(buf1), buf); + f = tcc_open(s1, buf1); + if (f) + goto found; + } + error("include file '%s' not found", buf); + f = NULL; + found: +#ifdef INC_DEBUG + printf("%s: including %s\n", file->filename, buf1); +#endif + f->inc_type = '\"'; + pstrcpy(f->inc_filename, sizeof(f->inc_filename), buf); + /* push current file in stack */ + /* XXX: fix current line init */ + *s1->include_stack_ptr++ = file; + file = f; + /* add include file debug info */ + if (do_debug) { + put_stabs(file->filename, N_BINCL, 0, 0, 0); + } + tok_flags |= TOK_FLAG_BOF | TOK_FLAG_BOL; + ch = file->buf_ptr[0]; + return; +} + #ifdef CONFIG_TCC_ASM #ifdef TCC_TARGET_I386 @@ -10212,6 +10299,7 @@ " -Idir add include path 'dir'\n" " -Dsym[=val] define 'sym' with value 'val'\n" " -Usym undefine 'sym'\n" + " -include includefile set include filename\n" "Linker options:\n" " -Ldir add library path 'dir'\n" " -llib link with dynamic or static library 'lib'\n" @@ -10267,6 +10355,7 @@ TCC_OPTION_v, TCC_OPTION_w, TCC_OPTION_pipe, + TCC_OPTION_include }; static const TCCOption tcc_options[] = { @@ -10302,6 +10391,7 @@ { "v", TCC_OPTION_v, 0 }, { "w", TCC_OPTION_w, 0 }, { "pipe", TCC_OPTION_pipe, 0}, + { "include", TCC_OPTION_include, TCC_OPTION_HAS_ARG }, { NULL }, }; @@ -10332,6 +10422,38 @@ return argc; } +int tcc_add_inc_item_chain(const char *name) +{ + struct inc_item *tmp; + tmp=tcc_malloc(sizeof(struct inc_item)); + if(NULL==tmp) + return -1; + tmp->inc_name=tcc_strdup(name); + if(!tmp->inc_name){ + tcc_free(tmp); + return -1; + } + tmp->next=NULL; + if(NULL==inc_item_head) + inc_item_head=inc_item_tail=tmp; + else{ + inc_item_tail->next=tmp; + inc_item_tail=tmp; + } + return 0; +} + +void tcc_free_inc_item_chain() +{ + struct inc_item *tmp=inc_item_head, *next; + while(tmp){ + next=tmp->next; + tcc_free(tmp->inc_name); + tcc_free(tmp); + tmp=next; + } +} + static char **files; static int nb_files, nb_libraries; static int multiple_files; @@ -10461,6 +10583,10 @@ multiple_files = 1; outfile = optarg; break; + case TCC_OPTION_include: + if(tcc_add_inc_item_chain(optarg)<0) + error("too many include files in command line.\n"); + break; case TCC_OPTION_r: /* generate a .o merging several output files */ reloc_output = 1; @@ -10651,6 +10777,7 @@ /* free all files */ tcc_free(files); + tcc_free_inc_item_chain(); if (do_bench) { double total_time;