diff --git a/libtcc.c b/libtcc.c index bf13724..c00a909 100644 --- a/libtcc.c +++ b/libtcc.c @@ -508,8 +508,9 @@ static void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap) if (!s1->error_func) { /* default case: stderr */ - if (s1->ppfp) /* print a newline during tcc -E */ - fprintf(s1->ppfp, "\n"), fflush(s1->ppfp); + if (s1->output_type == TCC_OUTPUT_PREPROCESS && s1->ppfp == stdout) + /* print a newline during tcc -E */ + printf("\n"), fflush(stdout); fflush(stdout); /* flush -v output */ fprintf(stderr, "%s\n", buf); fflush(stderr); /* print error/warning now (win32) */ @@ -587,6 +588,7 @@ ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen) bf->fd = -1; bf->prev = file; file = bf; + tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; } ST_FUNC void tcc_close(void) @@ -622,36 +624,36 @@ ST_FUNC int tcc_open(TCCState *s1, const char *filename) return fd; } -/* compile the C file opened in 'file'. Return non zero if errors. */ +/* compile the file opened in 'file'. Return non zero if errors. */ static int tcc_compile(TCCState *s1) { Sym *define_start; + int filetype, is_asm; define_start = define_stack; + filetype = s1->filetype; + is_asm = filetype == AFF_TYPE_ASM || filetype == AFF_TYPE_ASMPP; + if (setjmp(s1->error_jmp_buf) == 0) { s1->nb_errors = 0; s1->error_set_jmp_enabled = 1; - preprocess_start(s1); - tccgen_start(s1); -#ifdef INC_DEBUG - printf("%s: **** new file\n", file->filename); + preprocess_start(s1, is_asm); + if (s1->output_type == TCC_OUTPUT_PREPROCESS) { + tcc_preprocess(s1); + } else if (is_asm) { +#ifdef CONFIG_TCC_ASM + tcc_assemble(s1, filetype == AFF_TYPE_ASMPP); +#else + tcc_error_noabort("asm not supported"); #endif - ch = file->buf_ptr[0]; - tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; - parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | PARSE_FLAG_TOK_STR; - next(); - decl(VT_CONST); - if (tok != TOK_EOF) - expect("declaration"); - /* free defines here already on behalf of of M.M.'s possibly existing - experimental preprocessor implementation. The normal call below - is still there to free after error-longjmp */ - free_defines(define_start); - tccgen_end(s1); + } else { + tccgen_compile(s1); + } } s1->error_set_jmp_enabled = 0; + preprocess_end(s1); free_inline_functions(s1); /* reset define stack, but keep -D and built-ins */ free_defines(define_start); @@ -689,10 +691,8 @@ LIBTCCAPI void tcc_define_symbol(TCCState *s1, const char *sym, const char *valu memcpy(file->buffer + len1 + 1, value, len2); /* parse with define parser */ - ch = file->buf_ptr[0]; next_nomacro(); parse_define(); - tcc_close(); } @@ -713,6 +713,8 @@ static void tcc_cleanup(void) { if (NULL == tcc_state) return; + while (file) + tcc_close(); tccpp_delete(tcc_state); tcc_state = NULL; /* free sym_pools */ @@ -993,26 +995,7 @@ LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname) ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) { - int ret, filetype; - - filetype = flags & 0x0F; - if (filetype == 0) { - /* use a file extension to detect a filetype */ - const char *ext = tcc_fileextension(filename); - if (ext[0]) { - ext++; - if (!strcmp(ext, "S")) - filetype = AFF_TYPE_ASMPP; - else if (!strcmp(ext, "s")) - filetype = AFF_TYPE_ASM; - else if (!PATHCMP(ext, "c") || !PATHCMP(ext, "i")) - filetype = AFF_TYPE_C; - else - filetype = AFF_TYPE_BIN; - } else { - filetype = AFF_TYPE_C; - } - } + int ret; /* open the file */ ret = tcc_open(s1, filename); @@ -1026,26 +1009,7 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) dynarray_add(&s1->target_deps, &s1->nb_target_deps, tcc_strdup(filename)); - parse_flags = 0; - /* if .S file, define __ASSEMBLER__ like gcc does */ - if (filetype == AFF_TYPE_ASM || filetype == AFF_TYPE_ASMPP) { - tcc_define_symbol(s1, "__ASSEMBLER__", NULL); - parse_flags = PARSE_FLAG_ASM_FILE; - } - - if (flags & AFF_PREPROCESS) { - ret = tcc_preprocess(s1); - } else if (filetype == AFF_TYPE_C) { - ret = tcc_compile(s1); -#ifdef CONFIG_TCC_ASM - } else if (filetype == AFF_TYPE_ASMPP) { - /* non preprocessed assembler */ - ret = tcc_assemble(s1, 1); - } else if (filetype == AFF_TYPE_ASM) { - /* preprocessed assembler */ - ret = tcc_assemble(s1, 0); -#endif - } else { + if (flags & AFF_TYPE_BIN) { ElfW(Ehdr) ehdr; int fd, obj_type; @@ -1098,6 +1062,8 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) tcc_error_noabort("unrecognized file type"); break; } + } else { + ret = tcc_compile(s1); } tcc_close(); return ret; @@ -1105,10 +1071,27 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename) { - if (s->output_type == TCC_OUTPUT_PREPROCESS) - return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR | AFF_PREPROCESS | s->filetype); - else - return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR | s->filetype); + int filetype = s->filetype; + int flags = AFF_PRINT_ERROR; + if (filetype == 0) { + /* use a file extension to detect a filetype */ + const char *ext = tcc_fileextension(filename); + if (ext[0]) { + ext++; + if (!strcmp(ext, "S")) + filetype = AFF_TYPE_ASMPP; + else if (!strcmp(ext, "s")) + filetype = AFF_TYPE_ASM; + else if (!PATHCMP(ext, "c") || !PATHCMP(ext, "i")) + filetype = AFF_TYPE_C; + else + flags |= AFF_TYPE_BIN; + } else { + filetype = AFF_TYPE_C; + } + s->filetype = filetype; + } + return tcc_add_file_internal(s, filename, flags); } LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname) @@ -1799,8 +1782,8 @@ reparse: s->dflag = 3; else if (*optarg == 'M') s->dflag = 7; - else if (*optarg == 'T') - s->do_test = argc; + else if (*optarg == 't') + s->dflag = 16; else if (isnum(*optarg)) g_debug = atoi(optarg); else diff --git a/tcc.c b/tcc.c index 769501f..bef02e7 100644 --- a/tcc.c +++ b/tcc.c @@ -91,6 +91,7 @@ static const char help2[] = " -static link to static libraries (not recommended)\n" " -dumpversion print version\n" " -print-search-dirs print search paths\n" + " -dt with -run/-E: auto-define 'test_...' macros\n" "Ignored options:\n" " --param -pedantic -pipe -s -std -traditional\n" "-W... warnings:\n" @@ -244,18 +245,21 @@ static unsigned getclock_ms(void) #endif } -int main(int argc, char **argv) +int main(int argc0, char **argv0) { TCCState *s; - int ret, opt, n = 0; + int ret, opt, n = 0, t = 0; unsigned start_time = 0; const char *first_file; + int argc; char **argv; + FILE *ppfp = stdout; redo: + argc = argc0, argv = argv0; s = tcc_new(); opt = tcc_parse_args(s, &argc, &argv, 1); - if (n == 0) { + if ((n | t) == 0) { if (opt == OPT_HELP) return printf(help), 1; if (opt == OPT_HELP2) @@ -282,17 +286,11 @@ redo: n = s->nb_files; if (n == 0) tcc_error("no input files\n"); -#ifdef TCC_IS_NATIVE - if (s->do_test) - tcc_tool_test(s, argc, argv); /* maybe never returns */ -#endif if (s->output_type == TCC_OUTPUT_PREPROCESS) { - if (!s->outfile) { - s->ppfp = stdout; - } else { - s->ppfp = fopen(s->outfile, "w"); - if (!s->ppfp) + if (s->outfile) { + ppfp = fopen(s->outfile, "w"); + if (!ppfp) tcc_error("could not write '%s'", s->outfile); } } else if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r) { @@ -313,6 +311,11 @@ redo: if (s->output_type == 0) s->output_type = TCC_OUTPUT_EXE; tcc_set_output_type(s, s->output_type); + s->ppfp = ppfp; + + if ((s->output_type == TCC_OUTPUT_MEMORY + || s->output_type == TCC_OUTPUT_PREPROCESS) && (s->dflag & 16)) + s->dflag |= t ? 32 : 0, s->run_test = ++t, n = s->nb_files; /* compile or add each files or library */ for (first_file = NULL, ret = 0;;) { @@ -338,8 +341,7 @@ redo: } if (s->output_type == TCC_OUTPUT_PREPROCESS) { - if (s->outfile) - fclose(s->ppfp); + ; } else if (0 == ret) { if (s->output_type == TCC_OUTPUT_MEMORY) { #ifdef TCC_IS_NATIVE @@ -355,10 +357,18 @@ redo: } } - if (s->do_bench && ret == 0 && n == 0) + if (t) + ret = 0; + if (s->run_test) + t = 0; + if (s->do_bench && (n | t | ret) == 0) tcc_print_stats(s, getclock_ms() - start_time); tcc_delete(s); if (ret == 0 && n) goto redo; /* compile more files with -c */ + if (t) + goto redo; /* run more tests with -dt -run */ + if (ppfp && ppfp != stdout) + fclose(ppfp); return ret; } diff --git a/tcc.h b/tcc.h index 4113028..4b272f5 100644 --- a/tcc.h +++ b/tcc.h @@ -556,15 +556,6 @@ typedef struct BufferedFile { #define CH_EOB '\\' /* end of buffer or '\0' char in file */ #define CH_EOF (-1) /* end of file */ -/* parsing state (used to save parser state to reparse part of the - source several times) */ -typedef struct ParseState { - const int *macro_ptr; - int line_num; - int tok; - CValue tokc; -} ParseState; - /* used to record tokens */ typedef struct TokenString { int *str; @@ -572,6 +563,7 @@ typedef struct TokenString { int lastlen; int allocated_len; int last_line_num; + int save_line_num; /* used to chain token-strings with begin/end_macro() */ struct TokenString *prev; const int *prev_ptr; @@ -675,6 +667,7 @@ struct TCCState { #ifdef TCC_TARGET_ARM enum float_abi float_abi; /* float ABI of the generated code*/ #endif + int run_test; /* nth test to run with -dt -run */ addr_t text_addr; /* address of text section */ int has_text_addr; @@ -813,7 +806,6 @@ struct TCCState { int option_pthread; /* -pthread option */ int argc; char **argv; - int do_test; }; struct filespec { @@ -1145,14 +1137,13 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) /* flags: */ #define AFF_PRINT_ERROR 0x10 /* print error if file not found */ #define AFF_REFERENCED_DLL 0x20 /* load a referenced dll from another dll */ -#define AFF_PREPROCESS 0x40 /* preprocess file */ -/* combined with: */ +#define AFF_TYPE_BIN 0x40 /* file to add is binary */ +/* s->filetype: */ #define AFF_TYPE_NONE 0 #define AFF_TYPE_C 1 #define AFF_TYPE_ASM 2 #define AFF_TYPE_ASMPP 3 -#define AFF_TYPE_BIN 4 -#define AFF_TYPE_LIB 5 +#define AFF_TYPE_LIB 4 /* values from tcc_object_type(...) */ #define AFF_BINTYPE_REL 1 #define AFF_BINTYPE_DYN 2 @@ -1220,9 +1211,7 @@ ST_FUNC TokenSym *tok_alloc(const char *str, int len); ST_FUNC const char *get_tok_str(int v, CValue *cv); ST_FUNC void begin_macro(TokenString *str, int alloc); ST_FUNC void end_macro(void); -ST_FUNC void set_idnum(int c, int val); -ST_FUNC void save_parse_state(ParseState *s); -ST_FUNC void restore_parse_state(ParseState *s); +ST_FUNC int set_idnum(int c, int val); ST_INLN void tok_str_new(TokenString *s); ST_FUNC TokenString *tok_str_alloc(void); ST_FUNC void tok_str_free(TokenString *s); @@ -1241,7 +1230,8 @@ ST_FUNC void preprocess(int is_bof); ST_FUNC void next_nomacro(void); ST_FUNC void next(void); ST_INLN void unget_tok(int last_tok); -ST_FUNC void preprocess_start(TCCState *s1); +ST_FUNC void preprocess_start(TCCState *s1, int is_asm); +ST_FUNC void preprocess_end(TCCState *s1); ST_FUNC void tccpp_new(TCCState *s); ST_FUNC void tccpp_delete(TCCState *s); ST_FUNC int tcc_preprocess(TCCState *s1); @@ -1298,9 +1288,7 @@ ST_FUNC void tcc_debug_funcstart(TCCState *s1, Sym *sym); ST_FUNC void tcc_debug_funcend(TCCState *s1, int size); ST_FUNC void tcc_debug_line(TCCState *s1); -ST_FUNC void tccgen_start(TCCState *s1); -ST_FUNC void tccgen_end(TCCState *s1); - +ST_FUNC int tccgen_compile(TCCState *s1); ST_FUNC void free_inline_functions(TCCState *s); ST_FUNC void check_vstack(void); @@ -1342,7 +1330,6 @@ ST_FUNC void expr_prod(void); ST_FUNC void expr_sum(void); ST_FUNC void gexpr(void); ST_FUNC int expr_const(void); -ST_FUNC void decl(int l); #if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_C67 ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size); #endif diff --git a/tccasm.c b/tccasm.c index 59264ce..1e20dc6 100644 --- a/tccasm.c +++ b/tccasm.c @@ -628,20 +628,16 @@ static void asm_parse_directive(TCCState *s1, int global) { int repeat; TokenString *init_str; - ParseState saved_parse_state = {0}; next(); repeat = asm_int_expr(s1); init_str = tok_str_alloc(); - next(); - while ((tok != TOK_ASMDIR_endr) && (tok != CH_EOF)) { + while (next(), tok != TOK_ASMDIR_endr) { + if (tok == CH_EOF) + tcc_error("we at end of file, .endr not found"); tok_str_add_tok(init_str); - next(); } - if (tok == CH_EOF) tcc_error("we at end of file, .endr not found"); - next(); tok_str_add(init_str, -1); tok_str_add(init_str, 0); - save_parse_state(&saved_parse_state); begin_macro(init_str, 1); while (repeat-- > 0) { tcc_assemble_internal(s1, (parse_flags & PARSE_FLAG_PREPROCESS), @@ -649,7 +645,7 @@ static void asm_parse_directive(TCCState *s1, int global) macro_ptr = init_str->str; } end_macro(); - restore_parse_state(&saved_parse_state); + next(); break; } case TOK_ASMDIR_org: @@ -917,13 +913,10 @@ static void asm_parse_directive(TCCState *s1, int global) static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global) { int opcode; + int saved_parse_flags = parse_flags; /* XXX: undefine C labels */ - - ch = file->buf_ptr[0]; - tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; parse_flags = PARSE_FLAG_ASM_FILE | PARSE_FLAG_TOK_STR; - set_idnum('.', IS_ID); if (do_preprocess) parse_flags |= PARSE_FLAG_PREPROCESS; for(;;) { @@ -990,30 +983,22 @@ static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global) } asm_free_labels(s1); + parse_flags = saved_parse_flags; return 0; } /* Assemble the current file */ ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess) { - Sym *define_start; int ret; - - define_start = define_stack; - preprocess_start(s1); tcc_debug_start(s1); - /* default section is text */ cur_text_section = text_section; ind = cur_text_section->data_offset; nocode_wanted = 0; - ret = tcc_assemble_internal(s1, do_preprocess, 1); - cur_text_section->data_offset = ind; - tcc_debug_end(s1); - free_defines(define_start); return ret; } @@ -1025,21 +1010,16 @@ ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess) end */ static void tcc_assemble_inline(TCCState *s1, char *str, int len, int global) { - int saved_parse_flags; - const int *saved_macro_ptr; - - saved_parse_flags = parse_flags; - saved_macro_ptr = macro_ptr; + const int *saved_macro_ptr = macro_ptr; + int dotid = set_idnum('.', IS_ID); tcc_open_bf(s1, ":asm:", len); memcpy(file->buffer, str, len); - macro_ptr = NULL; tcc_assemble_internal(s1, 0, global); tcc_close(); - parse_flags = saved_parse_flags; - set_idnum('.', (parse_flags & PARSE_FLAG_ASM_FILE) ? IS_ID : 0); + set_idnum('.', dotid); macro_ptr = saved_macro_ptr; } diff --git a/tccgen.c b/tccgen.c index acba740..d53c6b7 100644 --- a/tccgen.c +++ b/tccgen.c @@ -84,6 +84,7 @@ static void init_putv(CType *type, Section *sec, unsigned long c); static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only); static void block(int *bsym, int *csym, int is_expr); static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope); +static void decl(int l); static int decl0(int l, int is_for_loop_init, Sym *); static void expr_eq(void); static void vla_runtime_type_size(CType *type, int *a); @@ -91,9 +92,9 @@ static void vla_sp_restore(void); static void vla_sp_restore_root(void); static int is_compatible_unqualified_types(CType *type1, CType *type2); static inline int64_t expr_const64(void); -ST_FUNC void vpush64(int ty, unsigned long long v); -ST_FUNC void vpush(CType *type); -ST_FUNC int gvtst(int inv, int t); +static void vpush64(int ty, unsigned long long v); +static void vpush(CType *type); +static int gvtst(int inv, int t); static void gen_inline_functions(TCCState *s); static void skip_or_save_block(TokenString **str); static void gv_dup(void); @@ -225,7 +226,7 @@ ST_FUNC void tcc_debug_funcend(TCCState *s1, int size) } /* ------------------------------------------------------------------------- */ -ST_FUNC void tccgen_start(TCCState *s1) +ST_FUNC int tccgen_compile(TCCState *s1) { cur_text_section = NULL; funcname = ""; @@ -253,14 +254,22 @@ ST_FUNC void tccgen_start(TCCState *s1) #ifdef TCC_TARGET_ARM arm_init(s1); #endif -} -ST_FUNC void tccgen_end(TCCState *s1) -{ +#ifdef INC_DEBUG + printf("%s: **** new file\n", file->filename); +#endif + + parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | PARSE_FLAG_TOK_STR; + next(); + decl(VT_CONST); + if (tok != TOK_EOF) + expect("declaration"); + gen_inline_functions(s1); check_vstack(); /* end of translation unit info */ tcc_debug_end(s1); + return 0; } /* ------------------------------------------------------------------------- */ @@ -4441,15 +4450,11 @@ static void gfunc_param_typed(Sym *func, Sym *arg) } } -/* parse an expression and return its type without any side effect. - If UNRY we parse an unary expression, otherwise a full one. */ -static void expr_type(CType *type, int unry) +/* parse an expression and return its type without any side effect. */ +static void expr_type(CType *type, void (*expr_fn)(void)) { nocode_wanted++; - if (unry) - unary(); - else - gexpr(); + expr_fn(); *type = vtop->type; vpop(); nocode_wanted--; @@ -4466,7 +4471,7 @@ static void parse_expr_type(CType *type) if (parse_btype(type, &ad)) { type_decl(type, &ad, &n, TYPE_ABSTRACT); } else { - expr_type(type, 0); + expr_type(type, gexpr); } skip(')'); } @@ -4694,7 +4699,7 @@ ST_FUNC void unary(void) t = tok; next(); in_sizeof++; - expr_type(&type, 1); // Perform a in_sizeof = 0; + expr_type(&type, unary); /* Perform a in_sizeof = 0; */ s = vtop[1].sym; /* hack: accessing previous vtop */ size = type_size(&type, &align); if (s && s->a.aligned) @@ -4896,70 +4901,60 @@ ST_FUNC void unary(void) CType controlling_type; int has_default = 0; int has_match = 0; - CType cur_type; - AttributeDef ad_tmp; int learn = 0; TokenString *str = NULL; - ParseState saved_parse_state; next(); skip('('); - expr_type(&controlling_type, 1); - if (controlling_type.t & VT_ARRAY) - controlling_type.t = VT_PTR; - controlling_type.t &= ~VT_CONSTANT; - controlling_type.t &= ~VT_VOLATILE; + expr_type(&controlling_type, expr_eq); + controlling_type.t &= ~(VT_CONSTANT|VT_VOLATILE|VT_ARRAY); for (;;) { learn = 0; skip(','); if (tok == TOK_DEFAULT) { if (has_default) tcc_error("too many 'default'"); - if (!has_match) { - has_default = 1; + has_default = 1; + if (!has_match) learn = 1; - } next(); } else { + AttributeDef ad_tmp; int itmp; - + CType cur_type; parse_btype(&cur_type, &ad_tmp); type_decl(&cur_type, &ad_tmp, &itmp, TYPE_ABSTRACT); if (compare_types(&controlling_type, &cur_type, 0)) { if (has_match) { // tcc_error("type match twice"); } - if (str) - tok_str_free(str); has_match = 1; learn = 1; } } skip(':'); if (learn) { + if (str) + tok_str_free(str); skip_or_save_block(&str); } else { skip_or_save_block(NULL); } - if (tok == ',') - continue; - else if (tok == ')') + if (tok == ')') break; } - if (!has_match && !has_default) { - char buf[256]; - - type_to_str(buf, 256, &controlling_type, NULL); - tcc_error("_Generic selector of type '%s' is not compatible with any assosiation", - buf); + if (!str) { + char buf[60]; + type_to_str(buf, sizeof buf, &controlling_type, NULL); + tcc_error("type '%s' does not match any association", buf); } - skip(')'); - save_parse_state(&saved_parse_state); begin_macro(str, 1); next(); expr_eq(); + if (tok != TOK_EOF) + expect(","); end_macro(); - restore_parse_state(&saved_parse_state); + next(); break; } // special qnan , snan and infinity values @@ -5599,7 +5594,9 @@ ST_FUNC void gexpr(void) static void expr_const1(void) { const_wanted++; + nocode_wanted++; expr_cond(); + nocode_wanted--; const_wanted--; } @@ -6721,8 +6718,8 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope) { int size, align, addr; - ParseState saved_parse_state = {0}; TokenString *init_str = NULL; + Section *sec; Sym *flexible_array; Sym *sym = NULL; @@ -6768,10 +6765,9 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, } else { skip_or_save_block(&init_str); } - - /* compute size */ - save_parse_state(&saved_parse_state); + unget_tok(0); + /* compute size */ begin_macro(init_str, 1); next(); decl_initializer(type, NULL, 0, 1, 1); @@ -6959,7 +6955,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, /* restore parse state if needed */ if (init_str) { end_macro(); - restore_parse_state(&saved_parse_state); + next(); } nocode_wanted = saved_nocode_wanted; @@ -7328,7 +7324,7 @@ found: return 0; } -ST_FUNC void decl(int l) +static void decl(int l) { decl0(l, 0, NULL); } diff --git a/tccpp.c b/tccpp.c index 0e46510..8d003d7 100644 --- a/tccpp.c +++ b/tccpp.c @@ -820,9 +820,11 @@ ST_FUNC uint8_t *parse_comment(uint8_t *p) return p; } -ST_FUNC void set_idnum(int c, int val) +ST_FUNC int set_idnum(int c, int val) { + int prev = isidnum_table[c - CH_EOF]; isidnum_table[c - CH_EOF] = val; + return prev; } #define cinp minp @@ -999,30 +1001,6 @@ _default: file->buf_ptr = p; } -/* ParseState handling */ - -/* XXX: currently, no include file info is stored. Thus, we cannot display - accurate messages if the function or data definition spans multiple - files */ - -/* save current parse state in 's' */ -ST_FUNC void save_parse_state(ParseState *s) -{ - s->line_num = file->line_num; - s->macro_ptr = macro_ptr; - s->tok = tok; - s->tokc = tokc; -} - -/* restore parse state from 's' */ -ST_FUNC void restore_parse_state(ParseState *s) -{ - file->line_num = s->line_num; - macro_ptr = s->macro_ptr; - tok = s->tok; - tokc = s->tokc; -} - #if 0 /* return the number of additional 'ints' necessary to store the token */ @@ -1124,6 +1102,7 @@ ST_FUNC void begin_macro(TokenString *str, int alloc) str->alloc = alloc; str->prev = macro_stack; str->prev_ptr = macro_ptr; + str->save_line_num = file->line_num; macro_ptr = str->str; macro_stack = str; } @@ -1133,6 +1112,7 @@ ST_FUNC void end_macro(void) TokenString *str = macro_stack; macro_stack = str->prev; macro_ptr = str->prev_ptr; + file->line_num = str->save_line_num; if (str->alloc == 2) { str->alloc = 3; /* just mark as finished */ } else { @@ -1402,6 +1382,21 @@ ST_FUNC void label_pop(Sym **ptop, Sym *slast, int keep) *ptop = slast; } +/* fake the nth "#if defined test_..." for tcc -dt -run */ +static void maybe_run_test(TCCState *s, int *c) +{ + const char *p; + if (s->include_stack_ptr != s->include_stack) + return; + p = get_tok_str(tok, NULL); + if (0 != memcmp(p, "test_", 5)) + return; + if (0 != --s->run_test) + return; + fprintf(s->ppfp, "\n[%s]\n" + !(s->dflag & 32), p), fflush(s->ppfp); + *c = 1; +} + /* eval an expression for #if/#elif */ static int expr_preprocess(void) { @@ -1420,6 +1415,8 @@ static int expr_preprocess(void) if (tok < TOK_IDENT) expect("identifier"); c = define_find(tok) != 0; + if (tcc_state->run_test) + maybe_run_test(tcc_state, &c); if (t == '(') { next_nomacro(); if (tok != ')') @@ -1467,7 +1464,7 @@ ST_FUNC void parse_define(void) /* '(' must be just after macro definition for MACRO_FUNC */ next_nomacro_spc(); if (tok == '(') { - set_idnum('.', 0); + int dotid = set_idnum('.', 0); next_nomacro(); ps = &first; if (tok != ')') for (;;) { @@ -1495,6 +1492,7 @@ ST_FUNC void parse_define(void) } next_nomacro_spc(); t = MACRO_FUNC; + set_idnum('.', dotid); } tokstr_buf.len = 0; @@ -1505,7 +1503,6 @@ ST_FUNC void parse_define(void) ID character in asm mode). But '#' should be retained instead of regarded as line comment leader, so still don't set ASM_FILE in parse_flags. */ - set_idnum('.', (saved_parse_flags & PARSE_FLAG_ASM_FILE) ? IS_ID : 0); while (tok != TOK_LINEFEED && tok != TOK_EOF) { /* remove spaces around ## and after '#' */ if (TOK_TWOSHARPS == tok) { @@ -1613,7 +1610,7 @@ static void pragma_parse(TCCState *s1) } else if (tok == TOK_once) { search_cached_include(s1, file->filename, 1)->once = pp_once; - } else if (s1->ppfp) { + } else if (s1->output_type == TCC_OUTPUT_PREPROCESS) { /* tcc -E: keep pragmas below unchanged */ unget_tok(' '); unget_tok(TOK_PRAGMA); @@ -3043,6 +3040,7 @@ static int paste_tokens(int t1, CValue *v1, int t2, CValue *v2) tcc_open_bf(tcc_state, ":paste:", cstr.size); memcpy(file->buffer, cstr.data, cstr.size); + tok_flags = 0; for (;;) { next_nomacro1(); if (0 == *file->buf_ptr) @@ -3164,6 +3162,8 @@ static int next_argstream(Sym **nested_list, TokenString *ws_str) break; ch = ' '; } + if (ch == '\n') + file->line_num++; if (!(ch == '\f' || ch == '\v' || ch == '\r')) tok_str_add(ws_str, ch); cinp(); @@ -3483,7 +3483,7 @@ ST_INLN void unget_tok(int last_tok) tok = last_tok; } -ST_FUNC void preprocess_start(TCCState *s1) +ST_FUNC void preprocess_start(TCCState *s1, int is_asm) { char *buf; @@ -3496,7 +3496,7 @@ ST_FUNC void preprocess_start(TCCState *s1) s1->pack_stack_ptr = s1->pack_stack; set_idnum('$', s1->dollars_in_identifiers ? IS_ID : 0); - set_idnum('.', (parse_flags & PARSE_FLAG_ASM_FILE) ? IS_ID : 0); + set_idnum('.', is_asm ? IS_ID : 0); buf = tcc_malloc(3 + strlen(file->filename)); sprintf(buf, "\"%s\"", file->filename); @@ -3517,6 +3517,20 @@ ST_FUNC void preprocess_start(TCCState *s1) memcpy(file->buffer, cstr.data, cstr.size); cstr_free(&cstr); } + + if (is_asm) + tcc_define_symbol(s1, "__ASSEMBLER__", NULL); + + parse_flags = is_asm ? PARSE_FLAG_ASM_FILE : 0; + tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; +} + +/* cleanup from error/setjmp */ +ST_FUNC void preprocess_end(TCCState *s1) +{ + while (macro_stack) + end_macro(); + macro_ptr = NULL; } ST_FUNC void tccpp_new(TCCState *s) @@ -3526,6 +3540,7 @@ ST_FUNC void tccpp_new(TCCState *s) /* might be used in error() before preprocess_start() */ s->include_stack_ptr = s->include_stack; + s->ppfp = stdout; /* init isid table */ for(i = CH_EOF; i<128; i++) @@ -3570,14 +3585,6 @@ ST_FUNC void tccpp_delete(TCCState *s) /* free -D and compiler defines */ free_defines(NULL); - /* cleanup from error/setjmp */ - while (macro_stack) - end_macro(); - macro_ptr = NULL; - - while (file) - tcc_close(); - /* free tokens */ n = tok_ident - TOK_IDENT; for(i = 0; i < n; i++) @@ -3606,19 +3613,16 @@ ST_FUNC void tccpp_delete(TCCState *s) static void tok_print(const char *msg, const int *str) { FILE *fp; - int t; + int t, s = 0; CValue cval; fp = tcc_state->ppfp; - if (!fp || !tcc_state->dflag) - fp = stdout; - - fprintf(fp, "%s ", msg); + fprintf(fp, "%s", msg); while (str) { TOK_GET(&t, &str, &cval); if (!t) break; - fprintf(fp,"%s", get_tok_str(t, &cval)); + fprintf(fp, " %s" + s, get_tok_str(t, &cval)), s = 1; } fprintf(fp, "\n"); } @@ -3731,20 +3735,14 @@ ST_FUNC int tcc_preprocess(TCCState *s1) BufferedFile **iptr; int token_seen, spcs, level; const char *p; - Sym *define_start; + char white[400]; - define_start = define_stack; - preprocess_start(s1); - - ch = file->buf_ptr[0]; - tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; parse_flags = PARSE_FLAG_PREPROCESS | (parse_flags & PARSE_FLAG_ASM_FILE) | PARSE_FLAG_LINEFEED | PARSE_FLAG_SPACES | PARSE_FLAG_ACCEPT_STRAYS ; - /* Credits to Fabrice Bellard's initial revision to demonstrate its capability to compile and run itself, provided all numbers are given as decimals. tcc -E -P10 will do. */ @@ -3754,7 +3752,6 @@ ST_FUNC int tcc_preprocess(TCCState *s1) #ifdef PP_BENCH /* for PP benchmarks */ do next(); while (tok != TOK_EOF); - free_defines(define_start); return 0; #endif @@ -3765,48 +3762,43 @@ ST_FUNC int tcc_preprocess(TCCState *s1) token_seen = TOK_LINEFEED, spcs = 0; pp_line(s1, file, 0); - for (;;) { iptr = s1->include_stack_ptr; next(); if (tok == TOK_EOF) break; + level = s1->include_stack_ptr - iptr; if (level) { if (level > 0) pp_line(s1, *iptr, 0); pp_line(s1, file, level); } - - if (s1->dflag) { + if (s1->dflag & 7) { pp_debug_defines(s1); if (s1->dflag & 4) continue; } - if (token_seen == TOK_LINEFEED) { - if (tok == ' ') { - ++spcs; - continue; - } - if (tok == TOK_LINEFEED) { - spcs = 0; - continue; - } - pp_line(s1, file, 0); + if (is_space(tok)) { + if (spcs < sizeof white - 1) + white[spcs++] = tok; + continue; } else if (tok == TOK_LINEFEED) { + spcs = 0; + if (token_seen == TOK_LINEFEED) + continue; ++file->line_ref; - } else { - spcs = pp_need_space(token_seen, tok); + } else if (token_seen == TOK_LINEFEED) { + pp_line(s1, file, 0); + } else if (spcs == 0 && pp_need_space(token_seen, tok)) { + white[spcs++] = ' '; } - while (spcs) - fputs(" ", s1->ppfp), --spcs; + white[spcs] = 0, fputs(white, s1->ppfp), spcs = 0; fputs(p = get_tok_str(tok, &tokc), s1->ppfp); - token_seen = pp_check_he0xE(tok, p);; + token_seen = pp_check_he0xE(tok, p); } - /* reset define stack, but keep -D and built-ins */ - free_defines(define_start); return 0; } diff --git a/tccrun.c b/tccrun.c index 950ffb0..85957b8 100644 --- a/tccrun.c +++ b/tccrun.c @@ -108,6 +108,8 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) int (*prog_main)(int, char **); s1->runtime_main = "main"; + if ((s1->dflag & 16) && !find_elf_sym(s1->symtab, s1->runtime_main)) + return 0; if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0) return -1; prog_main = tcc_get_symbol_err(s1, s1->runtime_main); diff --git a/tcctools.c b/tcctools.c index cfcb03d..53d88be 100644 --- a/tcctools.c +++ b/tcctools.c @@ -543,111 +543,4 @@ ST_FUNC void gen_makedeps(TCCState *s, const char *target, const char *filename) fclose(depout); } -#ifdef TCC_IS_NATIVE -/* -------------------------------------------------------------- */ -/* run test snippets from file */ - -static char *readfile(const char *fname) -{ - char *buf; - int fsize; - FILE *fi; - fi = fopen(fname, "rb"); - if (!fi) - return NULL; - fseek(fi, 0, SEEK_END); - fsize = ftell(fi); - fseek(fi, 0, SEEK_SET); - buf = tcc_malloc(fsize + 1); - fread(buf, fsize, 1, fi); - fclose(fi); - buf[fsize] = 0; - return buf; -} - -static int run_prog(const char *prog, int ac, char **av) -{ - TCCState *s; - int (*func)(int, char**); - int ret = -10000; - - s = tcc_new(); - tcc_parse_args(s, &ac, &av, 1); - tcc_set_output_type(s, TCC_OUTPUT_MEMORY); - if (tcc_compile_string(s, prog) == -1) - goto done; - if (tcc_relocate(s, TCC_RELOCATE_AUTO) < 0) - goto done; - func = tcc_get_symbol(s, "main"); - if (!func) - goto done; - ret = func(ac, av); -done: - tcc_delete(s); - return ret; -} - -static char *trimback(char *a, char *e) -{ - while (e > a && (unsigned char)e[-1] <= ' ') - --e; - *e = 0;; - return a; -} - -ST_FUNC int tcc_tool_test(TCCState *s, int argc, char **argv) -{ - const char *fname; - char *buf, *p, *a, *b, *e, tmp[100]; - int r = 0, c, n; - const char sep[] = "/*-* test"; - - n = s->do_test - argc; - if (!n) - return 0; - fname = argv[0], argv -= n, argc += n; - - buf = readfile(fname); - if (NULL == buf) - return -1; - p = strstr(buf, sep); - if (!p) { - tcc_free(buf); - return -1; - } - - while (*p) { - a = p, p = strchr(p, '\n'); - if (NULL == p) - break; - *p++ = 0; - b = p, p = strstr(p, sep); - if (NULL == p) - p = strchr(b, 0); - c = *p, *p = 0; - - trimback(a, b); - if (r) - printf("\n"); - printf("%s\n", a); - fflush(stdout); - - e = a += sizeof sep - 5; - while (*e && *e != ':') - ++e; - if (!*e || e - a > 32) - e = a + 4; - n = snprintf(tmp, sizeof tmp, "#line 1 \"%.*s\"\n", (int)(e - a), a); - if (b - buf >= n) - b = memcpy(b - n, tmp, n); - n = run_prog(b, argc, argv); - if (n != -10000) - printf("returns %d\n", n); - *p = c, ++r; - } - tcc_free(buf); - exit(0); -} -#endif /* TCC_IS_NATIVE */ - /* -------------------------------------------------------------- */ diff --git a/tests/tests2/56_btype_excess-1.c b/tests/tests2/56_btype_excess-1.c deleted file mode 100644 index 06eabe7..0000000 --- a/tests/tests2/56_btype_excess-1.c +++ /dev/null @@ -1 +0,0 @@ -struct A {} int i; diff --git a/tests/tests2/56_btype_excess-1.expect b/tests/tests2/56_btype_excess-1.expect deleted file mode 100644 index 4e6d2d7..0000000 --- a/tests/tests2/56_btype_excess-1.expect +++ /dev/null @@ -1 +0,0 @@ -56_btype_excess-1.c:1: error: too many basic types diff --git a/tests/tests2/57_btype_excess-2.c b/tests/tests2/57_btype_excess-2.c deleted file mode 100644 index ab95c3e..0000000 --- a/tests/tests2/57_btype_excess-2.c +++ /dev/null @@ -1 +0,0 @@ -char int i; diff --git a/tests/tests2/57_btype_excess-2.expect b/tests/tests2/57_btype_excess-2.expect deleted file mode 100644 index c12ef81..0000000 --- a/tests/tests2/57_btype_excess-2.expect +++ /dev/null @@ -1 +0,0 @@ -57_btype_excess-2.c:1: error: too many basic types diff --git a/tests/tests2/58_function_redefinition.c b/tests/tests2/58_function_redefinition.c deleted file mode 100644 index 33f16ee..0000000 --- a/tests/tests2/58_function_redefinition.c +++ /dev/null @@ -1,9 +0,0 @@ -int f(void) -{ - return 0; -} - -int f(void) -{ - return 1; -} diff --git a/tests/tests2/58_function_redefinition.expect b/tests/tests2/58_function_redefinition.expect deleted file mode 100644 index a95a3f0..0000000 --- a/tests/tests2/58_function_redefinition.expect +++ /dev/null @@ -1 +0,0 @@ -58_function_redefinition.c:7: error: redefinition of 'f' diff --git a/tests/tests2/59_function_array.c b/tests/tests2/59_function_array.c deleted file mode 100644 index 9fcc12d..0000000 --- a/tests/tests2/59_function_array.c +++ /dev/null @@ -1 +0,0 @@ -int (*fct)[42](int x); diff --git a/tests/tests2/59_function_array.expect b/tests/tests2/59_function_array.expect deleted file mode 100644 index bf62c6e..0000000 --- a/tests/tests2/59_function_array.expect +++ /dev/null @@ -1 +0,0 @@ -59_function_array.c:1: error: declaration of an array of functions diff --git a/tests/tests2/60_enum_redefinition.c b/tests/tests2/60_enum_redefinition.c deleted file mode 100644 index 2601560..0000000 --- a/tests/tests2/60_enum_redefinition.c +++ /dev/null @@ -1,4 +0,0 @@ -enum color {RED, GREEN, BLUE}; -enum color {R, G, B}; - -enum color c; diff --git a/tests/tests2/60_enum_redefinition.expect b/tests/tests2/60_enum_redefinition.expect deleted file mode 100644 index 5cb41bc..0000000 --- a/tests/tests2/60_enum_redefinition.expect +++ /dev/null @@ -1 +0,0 @@ -60_enum_redefinition.c:2: error: struct/union/enum already defined diff --git a/tests/tests2/60_errors_and_warnings.c b/tests/tests2/60_errors_and_warnings.c new file mode 100644 index 0000000..0028caf --- /dev/null +++ b/tests/tests2/60_errors_and_warnings.c @@ -0,0 +1,51 @@ +#if defined test_56_btype_excess_1 +struct A {} int i; + +#elif defined test_57_btype_excess_2 +char int i; + +#elif defined test_58_function_redefinition +int f(void) { return 0; } +int f(void) { return 1; } + +#elif defined test_global_redefinition +int xxx = 1; +int xxx; +int xxx = 2; + +#elif defined test_59_function_array +int (*fct)[42](int x); + +#elif defined test_60_enum_redefinition +enum color { RED, GREEN, BLUE }; +enum color { R, G, B }; +enum color c; + +#elif defined test_62_enumerator_redefinition +enum color { RED, GREEN, BLUE }; +enum rgb { RED, G, B}; +enum color c = RED; + +#elif defined test_63_local_enumerator_redefinition +enum { + FOO, + BAR +}; + +int main(void) +{ + enum { + FOO = 2, + BAR + }; + + return BAR - FOO; +} + +#elif defined test_61_undefined_enum +enum rgb3 c = 42; + +#elif defined test_74_non_const_init +int i = i++; + +#endif diff --git a/tests/tests2/60_errors_and_warnings.expect b/tests/tests2/60_errors_and_warnings.expect new file mode 100644 index 0000000..ed6a690 --- /dev/null +++ b/tests/tests2/60_errors_and_warnings.expect @@ -0,0 +1,28 @@ +[test_56_btype_excess_1] +60_errors_and_warnings.c:2: error: too many basic types + +[test_57_btype_excess_2] +60_errors_and_warnings.c:5: error: too many basic types + +[test_58_function_redefinition] +60_errors_and_warnings.c:9: error: redefinition of 'f' + +[test_global_redefinition] +60_errors_and_warnings.c:14: error: redefinition of 'xxx' + +[test_59_function_array] +60_errors_and_warnings.c:17: error: declaration of an array of functions + +[test_60_enum_redefinition] +60_errors_and_warnings.c:21: error: struct/union/enum already defined + +[test_62_enumerator_redefinition] +60_errors_and_warnings.c:26: error: redefinition of enumerator 'RED' + +[test_63_local_enumerator_redefinition] + +[test_61_undefined_enum] +60_errors_and_warnings.c:46: error: unknown type size + +[test_74_non_const_init] +60_errors_and_warnings.c:49: error: initializer element is not constant diff --git a/tests/tests2/61_undefined_enum.c b/tests/tests2/61_undefined_enum.c deleted file mode 100644 index bc7c6ea..0000000 --- a/tests/tests2/61_undefined_enum.c +++ /dev/null @@ -1 +0,0 @@ -enum rgb c = 42; diff --git a/tests/tests2/61_undefined_enum.expect b/tests/tests2/61_undefined_enum.expect deleted file mode 100644 index eb8b774..0000000 --- a/tests/tests2/61_undefined_enum.expect +++ /dev/null @@ -1 +0,0 @@ -61_undefined_enum.c:1: error: unknown type size diff --git a/tests/tests2/62_enumerator_redefinition.c b/tests/tests2/62_enumerator_redefinition.c deleted file mode 100644 index 3da85ae..0000000 --- a/tests/tests2/62_enumerator_redefinition.c +++ /dev/null @@ -1,4 +0,0 @@ -enum color {RED, GREEN, BLUE}; -enum rgb {RED, G, B}; - -enum color c = RED; diff --git a/tests/tests2/62_enumerator_redefinition.expect b/tests/tests2/62_enumerator_redefinition.expect deleted file mode 100644 index 3d0e879..0000000 --- a/tests/tests2/62_enumerator_redefinition.expect +++ /dev/null @@ -1 +0,0 @@ -62_enumerator_redefinition.c:2: error: redefinition of enumerator 'RED' diff --git a/tests/tests2/63_local_enumerator_redefinition.c b/tests/tests2/63_local_enumerator_redefinition.c deleted file mode 100644 index dd4d8e0..0000000 --- a/tests/tests2/63_local_enumerator_redefinition.c +++ /dev/null @@ -1,14 +0,0 @@ -enum { - FOO, - BAR -}; - -int main(void) -{ - enum { - FOO = 2, - BAR - }; - - return BAR - FOO; -} diff --git a/tests/tests2/63_local_enumerator_redefinition.expect b/tests/tests2/63_local_enumerator_redefinition.expect deleted file mode 100644 index e69de29..0000000 diff --git a/tests/tests2/74_nocode_wanted.c b/tests/tests2/74_nocode_wanted.c deleted file mode 100644 index e824d02..0000000 --- a/tests/tests2/74_nocode_wanted.c +++ /dev/null @@ -1 +0,0 @@ -int i = i++; diff --git a/tests/tests2/74_nocode_wanted.expect b/tests/tests2/74_nocode_wanted.expect deleted file mode 100644 index f060ef4..0000000 --- a/tests/tests2/74_nocode_wanted.expect +++ /dev/null @@ -1 +0,0 @@ -74_nocode_wanted.c:1: error: initializer element is not constant diff --git a/tests/tests2/96_nodata_wanted.c b/tests/tests2/96_nodata_wanted.c index 6f7f3c2..1f022c9 100644 --- a/tests/tests2/96_nodata_wanted.c +++ b/tests/tests2/96_nodata_wanted.c @@ -1,36 +1,35 @@ /*****************************************************************************/ /* test 'nodata_wanted' data output suppression */ -/*-* test 1: initializer not computable 1 */ +#if defined test_static_data_error void foo() { if (1) { - static short w = (int)&foo; /* error */ + static short w = (int)&foo; /* initializer not computable */ } } -/*-* test 2: initializer not computable 2 */ +#elif defined test_static_nodata_error void foo() { if (0) { - static short w = (int)&foo; /* error */ + static short w = (int)&foo; /* initializer not computable */ } } -/*-* test 3: initializer not computable 3 */ +#elif defined test_global_data_error void foo(); -static short w = (int)&foo; /* error */ +static short w = (int)&foo; /* initializer not computable */ -/*-* test 4: 2 cast warnings */ +#elif defined test_local_data_noerror void foo() { - short w = &foo; /* no error */ + short w = &foo; /* 2 cast warnings */ } -/*-* test 5; nodata_wanted test */ +#elif defined test_data_suppression #include -#define DATA_LBL(s) \ - __asm__(".global d"#s",t"#s"\n.data\nd"#s":\n.text\nt"#s":\n"); \ - extern char d##s[],t##s[]; +#define ASMLABELS(s) \ + __asm__(".global d"#s",t"#s"\n.data\nd"#s":\n.text\nt"#s":\n") #define PROG \ static void *p = (void*)&main;\ @@ -47,28 +46,29 @@ void foo() { int main() { + extern char ds1[],ts1[]; + extern char ds2[],ts2[]; + extern char de1[],te1[]; + extern char de2[],te2[]; + printf("suppression off\n"); - DATA_LBL(s1); if (1) { + ASMLABELS(s1); PROG + ASMLABELS(e1); } - DATA_LBL(e1); printf(" data length is %s\n", de1 - ds1 ? "not 0":"0"); - //printf(" text length is %s\n", te1 - ts1 ? "not 0":"0"); + printf(" text length is %s\n", te1 - ts1 ? "not 0":"0"); printf("suppression on\n"); - DATA_LBL(s2); if (0) { + ASMLABELS(s2); PROG + ASMLABELS(e2); } - DATA_LBL(e2); printf(" data length is %x\n", de2 - ds2); - //printf(" text length is %X\n", te2 - ts2); + printf(" text length is %X\n", te2 - ts2); return 0; } -/*-* test 6: some test */ -int main() -{ - return 34; -} +#endif diff --git a/tests/tests2/96_nodata_wanted.expect b/tests/tests2/96_nodata_wanted.expect index 0db4ba2..9fd35ca 100644 --- a/tests/tests2/96_nodata_wanted.expect +++ b/tests/tests2/96_nodata_wanted.expect @@ -1,24 +1,22 @@ -/*-* test 1: initializer not computable 1 */ -test 1:3: error: initializer element is not computable at load time +[test_static_data_error] +96_nodata_wanted.c:7: error: initializer element is not computable at load time -/*-* test 2: initializer not computable 2 */ -test 2:3: error: initializer element is not computable at load time +[test_static_nodata_error] +96_nodata_wanted.c:14: error: initializer element is not computable at load time -/*-* test 3: initializer not computable 3 */ -test 3:2: error: initializer element is not computable at load time +[test_global_data_error] +96_nodata_wanted.c:20: error: initializer element is not computable at load time -/*-* test 4: 2 cast warnings */ -test 4:2: warning: assignment makes integer from pointer without a cast -test 4:2: warning: nonportable conversion from pointer to char/short +[test_local_data_noerror] +96_nodata_wanted.c:25: warning: assignment makes integer from pointer without a cast +96_nodata_wanted.c:25: warning: nonportable conversion from pointer to char/short -/*-* test 5; nodata_wanted test */ +[test_data_suppression] suppression off static data: 8 - 8.0 - 8.0 - main - static string static bitfields: 333 44 555555 6 7 data length is not 0 + text length is not 0 suppression on data length is 0 -returns 0 - -/*-* test 6: some test */ -returns 34 + text length is 0 diff --git a/tests/tests2/Makefile b/tests/tests2/Makefile index 832aa49..4dd1591 100644 --- a/tests/tests2/Makefile +++ b/tests/tests2/Makefile @@ -20,7 +20,7 @@ endif ifeq (,$(filter i386 x86_64,$(ARCH))) SKIP += 85_asm-outside-function.test endif -ifeq (-$(findstring gcc,$(CC)-)-,--) +ifeq (-$(findstring gcc,$(CC))-,--) SKIP += $(patsubst %.expect,%.test,$(GEN-ALWAYS)) endif ifeq (-$(CONFIG_WIN32)-$(CONFIG_i386)$(CONFIG_arm)-,--yes-) @@ -40,8 +40,9 @@ NORUN = FLAGS = 76_dollars_in_identifiers.test : FLAGS += -fdollars-in-identifiers -# run the source file cut into snippets -96_nodata_wanted.test : FLAGS = -dT +# These tests run several snippets from the same file one by one +60_errors_and_warnings.test : FLAGS += -dt +96_nodata_wanted.test : FLAGS += -dt # Always generate certain .expects (don't put these in the GIT), GEN-ALWAYS = @@ -90,8 +91,8 @@ F2 = $1 UPDATE="$(patsubst %.test,%.expect,$1)" @$(call GEN,$(SRC)/$*.c) $(FILTER) >$@ 2>&1 @rm -f *.exe *.obj *.pdb -# using TCC for .expect if -dT in FLAGS -GEN = $(if $(findstring -dT,$(FLAGS)),$(GEN-TCC),$(GEN-CC)) +# using TCC for .expect if -dt in FLAGS +GEN = $(if $(filter -dt,$(FLAGS)),$(GEN-TCC),$(GEN-CC)) GEN-CC = $(CC) -w -std=gnu99 $(FLAGS) $1 -o a.exe && ./a.exe $(ARGS) GEN-TCC = $(TCC) $(FLAGS) -run $1 $(ARGS) GEN-MSC = $(MS-CC) $1 && ./$(basename $@).exe