tcc -dt -run ... : simpler is better
* -dt now with lowercase t
* test snippets now separated by real preprocessor statements
  which is valid C also for other compilers
    #if defined test_xxx
       < test snippet x >
    #elif defined test_yyy
       < test snippet y >
    #elif ...
    #endif
* simpler implementation, behaves like -run if no 'test_...' macros
  are seen, works with -E too
* for demonstration I combined some of the small tests for errors
  and warnings (56..63,74) in "60_errors_and_warnings.c"
Also:
* libtcc.c:
  put tcc_preprocess() and tcc_assemble() under the setjmp clause
  to let them return to caller after errors.  This is for -dt -E.
* tccgen.c:
  - get rid of save/restore_parse_state(), macro_ptr is saved
    by begin_macro anyway, now line_num too.
  - use expr_eq for parsing _Generic's controlling_type
  - set nocode_wanted with const_wanted. too, This is to keep
    VT_JMP on vtop when parsing preprocessor expressions.
* tccpp.c: tcc -E: suppress trailing whitespace from lines with
  comments (that -E removes) such as
       NO_GOTPLT_ENTRY,\t    /* never generate ... */
			
			
This commit is contained in:
		
							parent
							
								
									ba2b25e4ea
								
							
						
					
					
						commit
						0cc24d0e84
					
				
					 31 changed files with 323 additions and 446 deletions
				
			
		
							
								
								
									
										117
									
								
								libtcc.c
									
										
									
									
									
								
							
							
						
						
									
										117
									
								
								libtcc.c
									
										
									
									
									
								
							| 
						 | 
					@ -508,8 +508,9 @@ static void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!s1->error_func) {
 | 
					    if (!s1->error_func) {
 | 
				
			||||||
        /* default case: stderr */
 | 
					        /* default case: stderr */
 | 
				
			||||||
        if (s1->ppfp) /* print a newline during tcc -E */
 | 
					        if (s1->output_type == TCC_OUTPUT_PREPROCESS && s1->ppfp == stdout)
 | 
				
			||||||
            fprintf(s1->ppfp, "\n"), fflush(s1->ppfp);
 | 
					            /* print a newline during tcc -E */
 | 
				
			||||||
 | 
					            printf("\n"), fflush(stdout);
 | 
				
			||||||
        fflush(stdout); /* flush -v output */
 | 
					        fflush(stdout); /* flush -v output */
 | 
				
			||||||
        fprintf(stderr, "%s\n", buf);
 | 
					        fprintf(stderr, "%s\n", buf);
 | 
				
			||||||
        fflush(stderr); /* print error/warning now (win32) */
 | 
					        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->fd = -1;
 | 
				
			||||||
    bf->prev = file;
 | 
					    bf->prev = file;
 | 
				
			||||||
    file = bf;
 | 
					    file = bf;
 | 
				
			||||||
 | 
					    tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ST_FUNC void tcc_close(void)
 | 
					ST_FUNC void tcc_close(void)
 | 
				
			||||||
| 
						 | 
					@ -622,36 +624,36 @@ ST_FUNC int tcc_open(TCCState *s1, const char *filename)
 | 
				
			||||||
    return fd;
 | 
					    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)
 | 
					static int tcc_compile(TCCState *s1)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    Sym *define_start;
 | 
					    Sym *define_start;
 | 
				
			||||||
 | 
					    int filetype, is_asm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    define_start = define_stack;
 | 
					    define_start = define_stack;
 | 
				
			||||||
 | 
					    filetype = s1->filetype;
 | 
				
			||||||
 | 
					    is_asm = filetype == AFF_TYPE_ASM || filetype == AFF_TYPE_ASMPP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (setjmp(s1->error_jmp_buf) == 0) {
 | 
					    if (setjmp(s1->error_jmp_buf) == 0) {
 | 
				
			||||||
        s1->nb_errors = 0;
 | 
					        s1->nb_errors = 0;
 | 
				
			||||||
        s1->error_set_jmp_enabled = 1;
 | 
					        s1->error_set_jmp_enabled = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        preprocess_start(s1);
 | 
					        preprocess_start(s1, is_asm);
 | 
				
			||||||
        tccgen_start(s1);
 | 
					        if (s1->output_type == TCC_OUTPUT_PREPROCESS) {
 | 
				
			||||||
#ifdef INC_DEBUG
 | 
					            tcc_preprocess(s1);
 | 
				
			||||||
        printf("%s: **** new file\n", file->filename);
 | 
					        } else if (is_asm) {
 | 
				
			||||||
 | 
					#ifdef CONFIG_TCC_ASM
 | 
				
			||||||
 | 
					            tcc_assemble(s1, filetype == AFF_TYPE_ASMPP);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					            tcc_error_noabort("asm not supported");
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
        ch = file->buf_ptr[0];
 | 
					        } else {
 | 
				
			||||||
        tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
 | 
					            tccgen_compile(s1);
 | 
				
			||||||
        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);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    s1->error_set_jmp_enabled = 0;
 | 
					    s1->error_set_jmp_enabled = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    preprocess_end(s1);
 | 
				
			||||||
    free_inline_functions(s1);
 | 
					    free_inline_functions(s1);
 | 
				
			||||||
    /* reset define stack, but keep -D and built-ins */
 | 
					    /* reset define stack, but keep -D and built-ins */
 | 
				
			||||||
    free_defines(define_start);
 | 
					    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);
 | 
					    memcpy(file->buffer + len1 + 1, value, len2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* parse with define parser */
 | 
					    /* parse with define parser */
 | 
				
			||||||
    ch = file->buf_ptr[0];
 | 
					 | 
				
			||||||
    next_nomacro();
 | 
					    next_nomacro();
 | 
				
			||||||
    parse_define();
 | 
					    parse_define();
 | 
				
			||||||
 | 
					 | 
				
			||||||
    tcc_close();
 | 
					    tcc_close();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -713,6 +713,8 @@ static void tcc_cleanup(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (NULL == tcc_state)
 | 
					    if (NULL == tcc_state)
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
 | 
					    while (file)
 | 
				
			||||||
 | 
					        tcc_close();
 | 
				
			||||||
    tccpp_delete(tcc_state);
 | 
					    tccpp_delete(tcc_state);
 | 
				
			||||||
    tcc_state = NULL;
 | 
					    tcc_state = NULL;
 | 
				
			||||||
    /* free sym_pools */
 | 
					    /* 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)
 | 
					ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int ret, filetype;
 | 
					    int ret;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    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;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* open the file */
 | 
					    /* open the file */
 | 
				
			||||||
    ret = tcc_open(s1, filename);
 | 
					    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,
 | 
					    dynarray_add(&s1->target_deps, &s1->nb_target_deps,
 | 
				
			||||||
            tcc_strdup(filename));
 | 
					            tcc_strdup(filename));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    parse_flags = 0;
 | 
					    if (flags & AFF_TYPE_BIN) {
 | 
				
			||||||
    /* 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 {
 | 
					 | 
				
			||||||
        ElfW(Ehdr) ehdr;
 | 
					        ElfW(Ehdr) ehdr;
 | 
				
			||||||
        int fd, obj_type;
 | 
					        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");
 | 
					                tcc_error_noabort("unrecognized file type");
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        ret = tcc_compile(s1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    tcc_close();
 | 
					    tcc_close();
 | 
				
			||||||
    return ret;
 | 
					    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)
 | 
					LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (s->output_type == TCC_OUTPUT_PREPROCESS)
 | 
					    int filetype = s->filetype;
 | 
				
			||||||
        return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR | AFF_PREPROCESS | s->filetype);
 | 
					    int flags = AFF_PRINT_ERROR;
 | 
				
			||||||
    else
 | 
					    if (filetype == 0) {
 | 
				
			||||||
        return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR | s->filetype);
 | 
					        /* 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)
 | 
					LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname)
 | 
				
			||||||
| 
						 | 
					@ -1799,8 +1782,8 @@ reparse:
 | 
				
			||||||
                s->dflag = 3;
 | 
					                s->dflag = 3;
 | 
				
			||||||
            else if (*optarg == 'M')
 | 
					            else if (*optarg == 'M')
 | 
				
			||||||
                s->dflag = 7;
 | 
					                s->dflag = 7;
 | 
				
			||||||
            else if (*optarg == 'T')
 | 
					            else if (*optarg == 't')
 | 
				
			||||||
                s->do_test = argc;
 | 
					                s->dflag = 16;
 | 
				
			||||||
            else if (isnum(*optarg))
 | 
					            else if (isnum(*optarg))
 | 
				
			||||||
                g_debug = atoi(optarg);
 | 
					                g_debug = atoi(optarg);
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										40
									
								
								tcc.c
									
										
									
									
									
								
							
							
						
						
									
										40
									
								
								tcc.c
									
										
									
									
									
								
							| 
						 | 
					@ -91,6 +91,7 @@ static const char help2[] =
 | 
				
			||||||
    "  -static                       link to static libraries (not recommended)\n"
 | 
					    "  -static                       link to static libraries (not recommended)\n"
 | 
				
			||||||
    "  -dumpversion                  print version\n"
 | 
					    "  -dumpversion                  print version\n"
 | 
				
			||||||
    "  -print-search-dirs            print search paths\n"
 | 
					    "  -print-search-dirs            print search paths\n"
 | 
				
			||||||
 | 
					    "  -dt                           with -run/-E: auto-define 'test_...' macros\n"
 | 
				
			||||||
    "Ignored options:\n"
 | 
					    "Ignored options:\n"
 | 
				
			||||||
    "  --param  -pedantic  -pipe  -s  -std  -traditional\n"
 | 
					    "  --param  -pedantic  -pipe  -s  -std  -traditional\n"
 | 
				
			||||||
    "-W... warnings:\n"
 | 
					    "-W... warnings:\n"
 | 
				
			||||||
| 
						 | 
					@ -244,18 +245,21 @@ static unsigned getclock_ms(void)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main(int argc, char **argv)
 | 
					int main(int argc0, char **argv0)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    TCCState *s;
 | 
					    TCCState *s;
 | 
				
			||||||
    int ret, opt, n = 0;
 | 
					    int ret, opt, n = 0, t = 0;
 | 
				
			||||||
    unsigned start_time = 0;
 | 
					    unsigned start_time = 0;
 | 
				
			||||||
    const char *first_file;
 | 
					    const char *first_file;
 | 
				
			||||||
 | 
					    int argc; char **argv;
 | 
				
			||||||
 | 
					    FILE *ppfp = stdout;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
redo:
 | 
					redo:
 | 
				
			||||||
 | 
					    argc = argc0, argv = argv0;
 | 
				
			||||||
    s = tcc_new();
 | 
					    s = tcc_new();
 | 
				
			||||||
    opt = tcc_parse_args(s, &argc, &argv, 1);
 | 
					    opt = tcc_parse_args(s, &argc, &argv, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (n == 0) {
 | 
					    if ((n | t) == 0) {
 | 
				
			||||||
        if (opt == OPT_HELP)
 | 
					        if (opt == OPT_HELP)
 | 
				
			||||||
            return printf(help), 1;
 | 
					            return printf(help), 1;
 | 
				
			||||||
        if (opt == OPT_HELP2)
 | 
					        if (opt == OPT_HELP2)
 | 
				
			||||||
| 
						 | 
					@ -282,17 +286,11 @@ redo:
 | 
				
			||||||
        n = s->nb_files;
 | 
					        n = s->nb_files;
 | 
				
			||||||
        if (n == 0)
 | 
					        if (n == 0)
 | 
				
			||||||
            tcc_error("no input files\n");
 | 
					            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->output_type == TCC_OUTPUT_PREPROCESS) {
 | 
				
			||||||
            if (!s->outfile) {
 | 
					            if (s->outfile) {
 | 
				
			||||||
                s->ppfp = stdout;
 | 
					                ppfp = fopen(s->outfile, "w");
 | 
				
			||||||
            } else {
 | 
					                if (!ppfp)
 | 
				
			||||||
                s->ppfp = fopen(s->outfile, "w");
 | 
					 | 
				
			||||||
                if (!s->ppfp)
 | 
					 | 
				
			||||||
                    tcc_error("could not write '%s'", s->outfile);
 | 
					                    tcc_error("could not write '%s'", s->outfile);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } else if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r) {
 | 
					        } else if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r) {
 | 
				
			||||||
| 
						 | 
					@ -313,6 +311,11 @@ redo:
 | 
				
			||||||
    if (s->output_type == 0)
 | 
					    if (s->output_type == 0)
 | 
				
			||||||
        s->output_type = TCC_OUTPUT_EXE;
 | 
					        s->output_type = TCC_OUTPUT_EXE;
 | 
				
			||||||
    tcc_set_output_type(s, s->output_type);
 | 
					    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 */
 | 
					    /* compile or add each files or library */
 | 
				
			||||||
    for (first_file = NULL, ret = 0;;) {
 | 
					    for (first_file = NULL, ret = 0;;) {
 | 
				
			||||||
| 
						 | 
					@ -338,8 +341,7 @@ redo:
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (s->output_type == TCC_OUTPUT_PREPROCESS) {
 | 
					    if (s->output_type == TCC_OUTPUT_PREPROCESS) {
 | 
				
			||||||
        if (s->outfile)
 | 
					        ;
 | 
				
			||||||
            fclose(s->ppfp);
 | 
					 | 
				
			||||||
    } else if (0 == ret) {
 | 
					    } else if (0 == ret) {
 | 
				
			||||||
        if (s->output_type == TCC_OUTPUT_MEMORY) {
 | 
					        if (s->output_type == TCC_OUTPUT_MEMORY) {
 | 
				
			||||||
#ifdef TCC_IS_NATIVE
 | 
					#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_print_stats(s, getclock_ms() - start_time);
 | 
				
			||||||
    tcc_delete(s);
 | 
					    tcc_delete(s);
 | 
				
			||||||
    if (ret == 0 && n)
 | 
					    if (ret == 0 && n)
 | 
				
			||||||
        goto redo; /* compile more files with -c */
 | 
					        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;
 | 
					    return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										31
									
								
								tcc.h
									
										
									
									
									
								
							
							
						
						
									
										31
									
								
								tcc.h
									
										
									
									
									
								
							| 
						 | 
					@ -556,15 +556,6 @@ typedef struct BufferedFile {
 | 
				
			||||||
#define CH_EOB   '\\'       /* end of buffer or '\0' char in file */
 | 
					#define CH_EOB   '\\'       /* end of buffer or '\0' char in file */
 | 
				
			||||||
#define CH_EOF   (-1)   /* end of 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 */
 | 
					/* used to record tokens */
 | 
				
			||||||
typedef struct TokenString {
 | 
					typedef struct TokenString {
 | 
				
			||||||
    int *str;
 | 
					    int *str;
 | 
				
			||||||
| 
						 | 
					@ -572,6 +563,7 @@ typedef struct TokenString {
 | 
				
			||||||
    int lastlen;
 | 
					    int lastlen;
 | 
				
			||||||
    int allocated_len;
 | 
					    int allocated_len;
 | 
				
			||||||
    int last_line_num;
 | 
					    int last_line_num;
 | 
				
			||||||
 | 
					    int save_line_num;
 | 
				
			||||||
    /* used to chain token-strings with begin/end_macro() */
 | 
					    /* used to chain token-strings with begin/end_macro() */
 | 
				
			||||||
    struct TokenString *prev;
 | 
					    struct TokenString *prev;
 | 
				
			||||||
    const int *prev_ptr;
 | 
					    const int *prev_ptr;
 | 
				
			||||||
| 
						 | 
					@ -675,6 +667,7 @@ struct TCCState {
 | 
				
			||||||
#ifdef TCC_TARGET_ARM
 | 
					#ifdef TCC_TARGET_ARM
 | 
				
			||||||
    enum float_abi float_abi; /* float ABI of the generated code*/
 | 
					    enum float_abi float_abi; /* float ABI of the generated code*/
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					    int run_test; /* nth test to run with -dt -run */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    addr_t text_addr; /* address of text section */
 | 
					    addr_t text_addr; /* address of text section */
 | 
				
			||||||
    int has_text_addr;
 | 
					    int has_text_addr;
 | 
				
			||||||
| 
						 | 
					@ -813,7 +806,6 @@ struct TCCState {
 | 
				
			||||||
    int option_pthread; /* -pthread option */
 | 
					    int option_pthread; /* -pthread option */
 | 
				
			||||||
    int argc;
 | 
					    int argc;
 | 
				
			||||||
    char **argv;
 | 
					    char **argv;
 | 
				
			||||||
    int do_test;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct filespec {
 | 
					struct filespec {
 | 
				
			||||||
| 
						 | 
					@ -1145,14 +1137,13 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
 | 
				
			||||||
/* flags: */
 | 
					/* flags: */
 | 
				
			||||||
#define AFF_PRINT_ERROR     0x10 /* print error if file not found */
 | 
					#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_REFERENCED_DLL  0x20 /* load a referenced dll from another dll */
 | 
				
			||||||
#define AFF_PREPROCESS      0x40 /* preprocess file */
 | 
					#define AFF_TYPE_BIN        0x40 /* file to add is binary */
 | 
				
			||||||
/* combined with: */
 | 
					/* s->filetype: */
 | 
				
			||||||
#define AFF_TYPE_NONE   0
 | 
					#define AFF_TYPE_NONE   0
 | 
				
			||||||
#define AFF_TYPE_C      1
 | 
					#define AFF_TYPE_C      1
 | 
				
			||||||
#define AFF_TYPE_ASM    2
 | 
					#define AFF_TYPE_ASM    2
 | 
				
			||||||
#define AFF_TYPE_ASMPP  3
 | 
					#define AFF_TYPE_ASMPP  3
 | 
				
			||||||
#define AFF_TYPE_BIN    4
 | 
					#define AFF_TYPE_LIB    4
 | 
				
			||||||
#define AFF_TYPE_LIB    5
 | 
					 | 
				
			||||||
/* values from tcc_object_type(...) */
 | 
					/* values from tcc_object_type(...) */
 | 
				
			||||||
#define AFF_BINTYPE_REL 1
 | 
					#define AFF_BINTYPE_REL 1
 | 
				
			||||||
#define AFF_BINTYPE_DYN 2
 | 
					#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 const char *get_tok_str(int v, CValue *cv);
 | 
				
			||||||
ST_FUNC void begin_macro(TokenString *str, int alloc);
 | 
					ST_FUNC void begin_macro(TokenString *str, int alloc);
 | 
				
			||||||
ST_FUNC void end_macro(void);
 | 
					ST_FUNC void end_macro(void);
 | 
				
			||||||
ST_FUNC void set_idnum(int c, int val);
 | 
					ST_FUNC int set_idnum(int c, int val);
 | 
				
			||||||
ST_FUNC void save_parse_state(ParseState *s);
 | 
					 | 
				
			||||||
ST_FUNC void restore_parse_state(ParseState *s);
 | 
					 | 
				
			||||||
ST_INLN void tok_str_new(TokenString *s);
 | 
					ST_INLN void tok_str_new(TokenString *s);
 | 
				
			||||||
ST_FUNC TokenString *tok_str_alloc(void);
 | 
					ST_FUNC TokenString *tok_str_alloc(void);
 | 
				
			||||||
ST_FUNC void tok_str_free(TokenString *s);
 | 
					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_nomacro(void);
 | 
				
			||||||
ST_FUNC void next(void);
 | 
					ST_FUNC void next(void);
 | 
				
			||||||
ST_INLN void unget_tok(int last_tok);
 | 
					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_new(TCCState *s);
 | 
				
			||||||
ST_FUNC void tccpp_delete(TCCState *s);
 | 
					ST_FUNC void tccpp_delete(TCCState *s);
 | 
				
			||||||
ST_FUNC int tcc_preprocess(TCCState *s1);
 | 
					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_funcend(TCCState *s1, int size);
 | 
				
			||||||
ST_FUNC void tcc_debug_line(TCCState *s1);
 | 
					ST_FUNC void tcc_debug_line(TCCState *s1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ST_FUNC void tccgen_start(TCCState *s1);
 | 
					ST_FUNC int tccgen_compile(TCCState *s1);
 | 
				
			||||||
ST_FUNC void tccgen_end(TCCState *s1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ST_FUNC void free_inline_functions(TCCState *s);
 | 
					ST_FUNC void free_inline_functions(TCCState *s);
 | 
				
			||||||
ST_FUNC void check_vstack(void);
 | 
					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 expr_sum(void);
 | 
				
			||||||
ST_FUNC void gexpr(void);
 | 
					ST_FUNC void gexpr(void);
 | 
				
			||||||
ST_FUNC int expr_const(void);
 | 
					ST_FUNC int expr_const(void);
 | 
				
			||||||
ST_FUNC void decl(int l);
 | 
					 | 
				
			||||||
#if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_C67
 | 
					#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);
 | 
					ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										38
									
								
								tccasm.c
									
										
									
									
									
								
							
							
						
						
									
										38
									
								
								tccasm.c
									
										
									
									
									
								
							| 
						 | 
					@ -628,20 +628,16 @@ static void asm_parse_directive(TCCState *s1, int global)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            int repeat;
 | 
					            int repeat;
 | 
				
			||||||
            TokenString *init_str;
 | 
					            TokenString *init_str;
 | 
				
			||||||
            ParseState saved_parse_state = {0};
 | 
					 | 
				
			||||||
            next();
 | 
					            next();
 | 
				
			||||||
            repeat = asm_int_expr(s1);
 | 
					            repeat = asm_int_expr(s1);
 | 
				
			||||||
            init_str = tok_str_alloc();
 | 
					            init_str = tok_str_alloc();
 | 
				
			||||||
            next();
 | 
					            while (next(), tok != TOK_ASMDIR_endr) {
 | 
				
			||||||
            while ((tok != TOK_ASMDIR_endr) && (tok != CH_EOF)) {
 | 
					                if (tok == CH_EOF)
 | 
				
			||||||
 | 
					                    tcc_error("we at end of file, .endr not found");
 | 
				
			||||||
                tok_str_add_tok(init_str);
 | 
					                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, -1);
 | 
				
			||||||
            tok_str_add(init_str, 0);
 | 
					            tok_str_add(init_str, 0);
 | 
				
			||||||
            save_parse_state(&saved_parse_state);
 | 
					 | 
				
			||||||
            begin_macro(init_str, 1);
 | 
					            begin_macro(init_str, 1);
 | 
				
			||||||
            while (repeat-- > 0) {
 | 
					            while (repeat-- > 0) {
 | 
				
			||||||
                tcc_assemble_internal(s1, (parse_flags & PARSE_FLAG_PREPROCESS),
 | 
					                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;
 | 
					                macro_ptr = init_str->str;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            end_macro();
 | 
					            end_macro();
 | 
				
			||||||
            restore_parse_state(&saved_parse_state);
 | 
					            next();
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    case TOK_ASMDIR_org:
 | 
					    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)
 | 
					static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int opcode;
 | 
					    int opcode;
 | 
				
			||||||
 | 
					    int saved_parse_flags = parse_flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* XXX: undefine C labels */
 | 
					    /* 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;
 | 
					    parse_flags = PARSE_FLAG_ASM_FILE | PARSE_FLAG_TOK_STR;
 | 
				
			||||||
    set_idnum('.', IS_ID);
 | 
					 | 
				
			||||||
    if (do_preprocess)
 | 
					    if (do_preprocess)
 | 
				
			||||||
        parse_flags |= PARSE_FLAG_PREPROCESS;
 | 
					        parse_flags |= PARSE_FLAG_PREPROCESS;
 | 
				
			||||||
    for(;;) {
 | 
					    for(;;) {
 | 
				
			||||||
| 
						 | 
					@ -990,30 +983,22 @@ static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    asm_free_labels(s1);
 | 
					    asm_free_labels(s1);
 | 
				
			||||||
 | 
					    parse_flags = saved_parse_flags;
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Assemble the current file */
 | 
					/* Assemble the current file */
 | 
				
			||||||
ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess)
 | 
					ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    Sym *define_start;
 | 
					 | 
				
			||||||
    int ret;
 | 
					    int ret;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    define_start = define_stack;
 | 
					 | 
				
			||||||
    preprocess_start(s1);
 | 
					 | 
				
			||||||
    tcc_debug_start(s1);
 | 
					    tcc_debug_start(s1);
 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* default section is text */
 | 
					    /* default section is text */
 | 
				
			||||||
    cur_text_section = text_section;
 | 
					    cur_text_section = text_section;
 | 
				
			||||||
    ind = cur_text_section->data_offset;
 | 
					    ind = cur_text_section->data_offset;
 | 
				
			||||||
    nocode_wanted = 0;
 | 
					    nocode_wanted = 0;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    ret = tcc_assemble_internal(s1, do_preprocess, 1);
 | 
					    ret = tcc_assemble_internal(s1, do_preprocess, 1);
 | 
				
			||||||
 | 
					 | 
				
			||||||
    cur_text_section->data_offset = ind;
 | 
					    cur_text_section->data_offset = ind;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    tcc_debug_end(s1);
 | 
					    tcc_debug_end(s1);
 | 
				
			||||||
    free_defines(define_start); 
 | 
					 | 
				
			||||||
    return ret;
 | 
					    return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1025,21 +1010,16 @@ ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess)
 | 
				
			||||||
   end */
 | 
					   end */
 | 
				
			||||||
static void tcc_assemble_inline(TCCState *s1, char *str, int len, int global)
 | 
					static void tcc_assemble_inline(TCCState *s1, char *str, int len, int global)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int saved_parse_flags;
 | 
					    const int *saved_macro_ptr = macro_ptr;
 | 
				
			||||||
    const int *saved_macro_ptr;
 | 
					    int dotid = set_idnum('.', IS_ID);
 | 
				
			||||||
 | 
					 | 
				
			||||||
    saved_parse_flags = parse_flags;
 | 
					 | 
				
			||||||
    saved_macro_ptr = macro_ptr;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    tcc_open_bf(s1, ":asm:", len);
 | 
					    tcc_open_bf(s1, ":asm:", len);
 | 
				
			||||||
    memcpy(file->buffer, str, len);
 | 
					    memcpy(file->buffer, str, len);
 | 
				
			||||||
 | 
					 | 
				
			||||||
    macro_ptr = NULL;
 | 
					    macro_ptr = NULL;
 | 
				
			||||||
    tcc_assemble_internal(s1, 0, global);
 | 
					    tcc_assemble_internal(s1, 0, global);
 | 
				
			||||||
    tcc_close();
 | 
					    tcc_close();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    parse_flags = saved_parse_flags;
 | 
					    set_idnum('.', dotid);
 | 
				
			||||||
    set_idnum('.', (parse_flags & PARSE_FLAG_ASM_FILE) ? IS_ID : 0);
 | 
					 | 
				
			||||||
    macro_ptr = saved_macro_ptr;
 | 
					    macro_ptr = saved_macro_ptr;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										92
									
								
								tccgen.c
									
										
									
									
									
								
							
							
						
						
									
										92
									
								
								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 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 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_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 int decl0(int l, int is_for_loop_init, Sym *);
 | 
				
			||||||
static void expr_eq(void);
 | 
					static void expr_eq(void);
 | 
				
			||||||
static void vla_runtime_type_size(CType *type, int *a);
 | 
					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 void vla_sp_restore_root(void);
 | 
				
			||||||
static int is_compatible_unqualified_types(CType *type1, CType *type2);
 | 
					static int is_compatible_unqualified_types(CType *type1, CType *type2);
 | 
				
			||||||
static inline int64_t expr_const64(void);
 | 
					static inline int64_t expr_const64(void);
 | 
				
			||||||
ST_FUNC void vpush64(int ty, unsigned long long v);
 | 
					static void vpush64(int ty, unsigned long long v);
 | 
				
			||||||
ST_FUNC void vpush(CType *type);
 | 
					static void vpush(CType *type);
 | 
				
			||||||
ST_FUNC int gvtst(int inv, int t);
 | 
					static int gvtst(int inv, int t);
 | 
				
			||||||
static void gen_inline_functions(TCCState *s);
 | 
					static void gen_inline_functions(TCCState *s);
 | 
				
			||||||
static void skip_or_save_block(TokenString **str);
 | 
					static void skip_or_save_block(TokenString **str);
 | 
				
			||||||
static void gv_dup(void);
 | 
					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;
 | 
					    cur_text_section = NULL;
 | 
				
			||||||
    funcname = "";
 | 
					    funcname = "";
 | 
				
			||||||
| 
						 | 
					@ -253,14 +254,22 @@ ST_FUNC void tccgen_start(TCCState *s1)
 | 
				
			||||||
#ifdef TCC_TARGET_ARM
 | 
					#ifdef TCC_TARGET_ARM
 | 
				
			||||||
    arm_init(s1);
 | 
					    arm_init(s1);
 | 
				
			||||||
#endif
 | 
					#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);
 | 
					    gen_inline_functions(s1);
 | 
				
			||||||
    check_vstack();
 | 
					    check_vstack();
 | 
				
			||||||
    /* end of translation unit info */
 | 
					    /* end of translation unit info */
 | 
				
			||||||
    tcc_debug_end(s1);
 | 
					    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.
 | 
					/* 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, void (*expr_fn)(void))
 | 
				
			||||||
static void expr_type(CType *type, int unry)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    nocode_wanted++;
 | 
					    nocode_wanted++;
 | 
				
			||||||
    if (unry)
 | 
					    expr_fn();
 | 
				
			||||||
        unary();
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
        gexpr();
 | 
					 | 
				
			||||||
    *type = vtop->type;
 | 
					    *type = vtop->type;
 | 
				
			||||||
    vpop();
 | 
					    vpop();
 | 
				
			||||||
    nocode_wanted--;
 | 
					    nocode_wanted--;
 | 
				
			||||||
| 
						 | 
					@ -4466,7 +4471,7 @@ static void parse_expr_type(CType *type)
 | 
				
			||||||
    if (parse_btype(type, &ad)) {
 | 
					    if (parse_btype(type, &ad)) {
 | 
				
			||||||
        type_decl(type, &ad, &n, TYPE_ABSTRACT);
 | 
					        type_decl(type, &ad, &n, TYPE_ABSTRACT);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        expr_type(type, 0);
 | 
					        expr_type(type, gexpr);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    skip(')');
 | 
					    skip(')');
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -4694,7 +4699,7 @@ ST_FUNC void unary(void)
 | 
				
			||||||
        t = tok;
 | 
					        t = tok;
 | 
				
			||||||
        next();
 | 
					        next();
 | 
				
			||||||
        in_sizeof++;
 | 
					        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 */
 | 
					        s = vtop[1].sym; /* hack: accessing previous vtop */
 | 
				
			||||||
        size = type_size(&type, &align);
 | 
					        size = type_size(&type, &align);
 | 
				
			||||||
        if (s && s->a.aligned)
 | 
					        if (s && s->a.aligned)
 | 
				
			||||||
| 
						 | 
					@ -4896,70 +4901,60 @@ ST_FUNC void unary(void)
 | 
				
			||||||
	CType controlling_type;
 | 
						CType controlling_type;
 | 
				
			||||||
	int has_default = 0;
 | 
						int has_default = 0;
 | 
				
			||||||
	int has_match = 0;
 | 
						int has_match = 0;
 | 
				
			||||||
	CType cur_type;
 | 
					 | 
				
			||||||
	AttributeDef ad_tmp;
 | 
					 | 
				
			||||||
	int learn = 0;
 | 
						int learn = 0;
 | 
				
			||||||
	TokenString *str = NULL;
 | 
						TokenString *str = NULL;
 | 
				
			||||||
	ParseState saved_parse_state;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	next();
 | 
						next();
 | 
				
			||||||
	skip('(');
 | 
						skip('(');
 | 
				
			||||||
	expr_type(&controlling_type, 1);
 | 
						expr_type(&controlling_type, expr_eq);
 | 
				
			||||||
	if (controlling_type.t & VT_ARRAY)
 | 
						controlling_type.t &= ~(VT_CONSTANT|VT_VOLATILE|VT_ARRAY);
 | 
				
			||||||
		controlling_type.t = VT_PTR;
 | 
					 | 
				
			||||||
	controlling_type.t &= ~VT_CONSTANT;
 | 
					 | 
				
			||||||
	controlling_type.t &= ~VT_VOLATILE;
 | 
					 | 
				
			||||||
	for (;;) {
 | 
						for (;;) {
 | 
				
			||||||
	    learn = 0;
 | 
						    learn = 0;
 | 
				
			||||||
	    skip(',');
 | 
						    skip(',');
 | 
				
			||||||
	    if (tok == TOK_DEFAULT) {
 | 
						    if (tok == TOK_DEFAULT) {
 | 
				
			||||||
		if (has_default)
 | 
							if (has_default)
 | 
				
			||||||
		    tcc_error("too many 'default'");
 | 
							    tcc_error("too many 'default'");
 | 
				
			||||||
		if (!has_match) {
 | 
							has_default = 1;
 | 
				
			||||||
		    has_default = 1;
 | 
							if (!has_match)
 | 
				
			||||||
		    learn = 1;
 | 
							    learn = 1;
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		next();
 | 
							next();
 | 
				
			||||||
	    } else {
 | 
						    } else {
 | 
				
			||||||
 | 
						        AttributeDef ad_tmp;
 | 
				
			||||||
		int itmp;
 | 
							int itmp;
 | 
				
			||||||
 | 
						        CType cur_type;
 | 
				
			||||||
		parse_btype(&cur_type, &ad_tmp);
 | 
							parse_btype(&cur_type, &ad_tmp);
 | 
				
			||||||
		type_decl(&cur_type, &ad_tmp, &itmp, TYPE_ABSTRACT);
 | 
							type_decl(&cur_type, &ad_tmp, &itmp, TYPE_ABSTRACT);
 | 
				
			||||||
		if (compare_types(&controlling_type, &cur_type, 0)) {
 | 
							if (compare_types(&controlling_type, &cur_type, 0)) {
 | 
				
			||||||
		    if (has_match) {
 | 
							    if (has_match) {
 | 
				
			||||||
		      // tcc_error("type match twice");
 | 
							      // tcc_error("type match twice");
 | 
				
			||||||
		    }
 | 
							    }
 | 
				
			||||||
		    if (str)
 | 
					 | 
				
			||||||
			tok_str_free(str);
 | 
					 | 
				
			||||||
		    has_match = 1;
 | 
							    has_match = 1;
 | 
				
			||||||
		    learn = 1;
 | 
							    learn = 1;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
	    skip(':');
 | 
						    skip(':');
 | 
				
			||||||
	    if (learn) {
 | 
						    if (learn) {
 | 
				
			||||||
 | 
							if (str)
 | 
				
			||||||
 | 
							    tok_str_free(str);
 | 
				
			||||||
		skip_or_save_block(&str);
 | 
							skip_or_save_block(&str);
 | 
				
			||||||
	    } else {
 | 
						    } else {
 | 
				
			||||||
		skip_or_save_block(NULL);
 | 
							skip_or_save_block(NULL);
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
	    if (tok == ',')
 | 
						    if (tok == ')')
 | 
				
			||||||
		continue;
 | 
					 | 
				
			||||||
	    else if (tok == ')')
 | 
					 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (!has_match && !has_default) {
 | 
						if (!str) {
 | 
				
			||||||
	    char buf[256];
 | 
						    char buf[60];
 | 
				
			||||||
 | 
						    type_to_str(buf, sizeof buf, &controlling_type, NULL);
 | 
				
			||||||
	    type_to_str(buf, 256, &controlling_type, NULL);
 | 
						    tcc_error("type '%s' does not match any association", buf);
 | 
				
			||||||
	    tcc_error("_Generic selector of type '%s' is not compatible with any assosiation",
 | 
					 | 
				
			||||||
		      buf);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	skip(')');
 | 
					 | 
				
			||||||
	save_parse_state(&saved_parse_state);
 | 
					 | 
				
			||||||
	begin_macro(str, 1);
 | 
						begin_macro(str, 1);
 | 
				
			||||||
	next();
 | 
						next();
 | 
				
			||||||
	expr_eq();
 | 
						expr_eq();
 | 
				
			||||||
 | 
						if (tok != TOK_EOF)
 | 
				
			||||||
 | 
						    expect(",");
 | 
				
			||||||
	end_macro();
 | 
						end_macro();
 | 
				
			||||||
	restore_parse_state(&saved_parse_state);
 | 
					        next();
 | 
				
			||||||
	break;
 | 
						break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    // special qnan , snan and infinity values
 | 
					    // special qnan , snan and infinity values
 | 
				
			||||||
| 
						 | 
					@ -5599,7 +5594,9 @@ ST_FUNC void gexpr(void)
 | 
				
			||||||
static void expr_const1(void)
 | 
					static void expr_const1(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    const_wanted++;
 | 
					    const_wanted++;
 | 
				
			||||||
 | 
					    nocode_wanted++;
 | 
				
			||||||
    expr_cond();
 | 
					    expr_cond();
 | 
				
			||||||
 | 
					    nocode_wanted--;
 | 
				
			||||||
    const_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 has_init, int v, int scope)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int size, align, addr;
 | 
					    int size, align, addr;
 | 
				
			||||||
    ParseState saved_parse_state = {0};
 | 
					 | 
				
			||||||
    TokenString *init_str = NULL;
 | 
					    TokenString *init_str = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Section *sec;
 | 
					    Section *sec;
 | 
				
			||||||
    Sym *flexible_array;
 | 
					    Sym *flexible_array;
 | 
				
			||||||
    Sym *sym = NULL;
 | 
					    Sym *sym = NULL;
 | 
				
			||||||
| 
						 | 
					@ -6768,10 +6765,9 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
	    skip_or_save_block(&init_str);
 | 
						    skip_or_save_block(&init_str);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        unget_tok(0);
 | 
				
			||||||
        /* compute size */
 | 
					 | 
				
			||||||
        save_parse_state(&saved_parse_state);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* compute size */
 | 
				
			||||||
        begin_macro(init_str, 1);
 | 
					        begin_macro(init_str, 1);
 | 
				
			||||||
        next();
 | 
					        next();
 | 
				
			||||||
        decl_initializer(type, NULL, 0, 1, 1);
 | 
					        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 */
 | 
					    /* restore parse state if needed */
 | 
				
			||||||
    if (init_str) {
 | 
					    if (init_str) {
 | 
				
			||||||
        end_macro();
 | 
					        end_macro();
 | 
				
			||||||
        restore_parse_state(&saved_parse_state);
 | 
					        next();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    nocode_wanted = saved_nocode_wanted;
 | 
					    nocode_wanted = saved_nocode_wanted;
 | 
				
			||||||
| 
						 | 
					@ -7328,7 +7324,7 @@ found:
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ST_FUNC void decl(int l)
 | 
					static void decl(int l)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    decl0(l, 0, NULL);
 | 
					    decl0(l, 0, NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										136
									
								
								tccpp.c
									
										
									
									
									
								
							
							
						
						
									
										136
									
								
								tccpp.c
									
										
									
									
									
								
							| 
						 | 
					@ -820,9 +820,11 @@ ST_FUNC uint8_t *parse_comment(uint8_t *p)
 | 
				
			||||||
    return 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;
 | 
					    isidnum_table[c - CH_EOF] = val;
 | 
				
			||||||
 | 
					    return prev;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define cinp minp
 | 
					#define cinp minp
 | 
				
			||||||
| 
						 | 
					@ -999,30 +1001,6 @@ _default:
 | 
				
			||||||
    file->buf_ptr = p;
 | 
					    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
 | 
					#if 0
 | 
				
			||||||
/* return the number of additional 'ints' necessary to store the
 | 
					/* return the number of additional 'ints' necessary to store the
 | 
				
			||||||
   token */
 | 
					   token */
 | 
				
			||||||
| 
						 | 
					@ -1124,6 +1102,7 @@ ST_FUNC void begin_macro(TokenString *str, int alloc)
 | 
				
			||||||
    str->alloc = alloc;
 | 
					    str->alloc = alloc;
 | 
				
			||||||
    str->prev = macro_stack;
 | 
					    str->prev = macro_stack;
 | 
				
			||||||
    str->prev_ptr = macro_ptr;
 | 
					    str->prev_ptr = macro_ptr;
 | 
				
			||||||
 | 
					    str->save_line_num = file->line_num;
 | 
				
			||||||
    macro_ptr = str->str;
 | 
					    macro_ptr = str->str;
 | 
				
			||||||
    macro_stack = str;
 | 
					    macro_stack = str;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1133,6 +1112,7 @@ ST_FUNC void end_macro(void)
 | 
				
			||||||
    TokenString *str = macro_stack;
 | 
					    TokenString *str = macro_stack;
 | 
				
			||||||
    macro_stack = str->prev;
 | 
					    macro_stack = str->prev;
 | 
				
			||||||
    macro_ptr = str->prev_ptr;
 | 
					    macro_ptr = str->prev_ptr;
 | 
				
			||||||
 | 
					    file->line_num = str->save_line_num;
 | 
				
			||||||
    if (str->alloc == 2) {
 | 
					    if (str->alloc == 2) {
 | 
				
			||||||
        str->alloc = 3; /* just mark as finished */
 | 
					        str->alloc = 3; /* just mark as finished */
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
| 
						 | 
					@ -1402,6 +1382,21 @@ ST_FUNC void label_pop(Sym **ptop, Sym *slast, int keep)
 | 
				
			||||||
        *ptop = slast;
 | 
					        *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 */
 | 
					/* eval an expression for #if/#elif */
 | 
				
			||||||
static int expr_preprocess(void)
 | 
					static int expr_preprocess(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -1420,6 +1415,8 @@ static int expr_preprocess(void)
 | 
				
			||||||
            if (tok < TOK_IDENT)
 | 
					            if (tok < TOK_IDENT)
 | 
				
			||||||
                expect("identifier");
 | 
					                expect("identifier");
 | 
				
			||||||
            c = define_find(tok) != 0;
 | 
					            c = define_find(tok) != 0;
 | 
				
			||||||
 | 
					            if (tcc_state->run_test)
 | 
				
			||||||
 | 
					                maybe_run_test(tcc_state, &c);
 | 
				
			||||||
            if (t == '(') {
 | 
					            if (t == '(') {
 | 
				
			||||||
                next_nomacro();
 | 
					                next_nomacro();
 | 
				
			||||||
                if (tok != ')')
 | 
					                if (tok != ')')
 | 
				
			||||||
| 
						 | 
					@ -1467,7 +1464,7 @@ ST_FUNC void parse_define(void)
 | 
				
			||||||
    /* '(' must be just after macro definition for MACRO_FUNC */
 | 
					    /* '(' must be just after macro definition for MACRO_FUNC */
 | 
				
			||||||
    next_nomacro_spc();
 | 
					    next_nomacro_spc();
 | 
				
			||||||
    if (tok == '(') {
 | 
					    if (tok == '(') {
 | 
				
			||||||
        set_idnum('.', 0);
 | 
					        int dotid = set_idnum('.', 0);
 | 
				
			||||||
        next_nomacro();
 | 
					        next_nomacro();
 | 
				
			||||||
        ps = &first;
 | 
					        ps = &first;
 | 
				
			||||||
        if (tok != ')') for (;;) {
 | 
					        if (tok != ')') for (;;) {
 | 
				
			||||||
| 
						 | 
					@ -1495,6 +1492,7 @@ ST_FUNC void parse_define(void)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        next_nomacro_spc();
 | 
					        next_nomacro_spc();
 | 
				
			||||||
        t = MACRO_FUNC;
 | 
					        t = MACRO_FUNC;
 | 
				
			||||||
 | 
					        set_idnum('.', dotid);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    tokstr_buf.len = 0;
 | 
					    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
 | 
					       ID character in asm mode).  But '#' should be retained instead of
 | 
				
			||||||
       regarded as line comment leader, so still don't set ASM_FILE
 | 
					       regarded as line comment leader, so still don't set ASM_FILE
 | 
				
			||||||
       in parse_flags. */
 | 
					       in parse_flags. */
 | 
				
			||||||
    set_idnum('.', (saved_parse_flags & PARSE_FLAG_ASM_FILE) ? IS_ID : 0);
 | 
					 | 
				
			||||||
    while (tok != TOK_LINEFEED && tok != TOK_EOF) {
 | 
					    while (tok != TOK_LINEFEED && tok != TOK_EOF) {
 | 
				
			||||||
        /* remove spaces around ## and after '#' */
 | 
					        /* remove spaces around ## and after '#' */
 | 
				
			||||||
        if (TOK_TWOSHARPS == tok) {
 | 
					        if (TOK_TWOSHARPS == tok) {
 | 
				
			||||||
| 
						 | 
					@ -1613,7 +1610,7 @@ static void pragma_parse(TCCState *s1)
 | 
				
			||||||
    } else if (tok == TOK_once) {
 | 
					    } else if (tok == TOK_once) {
 | 
				
			||||||
        search_cached_include(s1, file->filename, 1)->once = pp_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 */
 | 
					        /* tcc -E: keep pragmas below unchanged */
 | 
				
			||||||
        unget_tok(' ');
 | 
					        unget_tok(' ');
 | 
				
			||||||
        unget_tok(TOK_PRAGMA);
 | 
					        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);
 | 
					    tcc_open_bf(tcc_state, ":paste:", cstr.size);
 | 
				
			||||||
    memcpy(file->buffer, cstr.data, cstr.size);
 | 
					    memcpy(file->buffer, cstr.data, cstr.size);
 | 
				
			||||||
 | 
					    tok_flags = 0;
 | 
				
			||||||
    for (;;) {
 | 
					    for (;;) {
 | 
				
			||||||
        next_nomacro1();
 | 
					        next_nomacro1();
 | 
				
			||||||
        if (0 == *file->buf_ptr)
 | 
					        if (0 == *file->buf_ptr)
 | 
				
			||||||
| 
						 | 
					@ -3164,6 +3162,8 @@ static int next_argstream(Sym **nested_list, TokenString *ws_str)
 | 
				
			||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
                        ch = ' ';
 | 
					                        ch = ' ';
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					                    if (ch == '\n')
 | 
				
			||||||
 | 
					                        file->line_num++;
 | 
				
			||||||
                    if (!(ch == '\f' || ch == '\v' || ch == '\r'))
 | 
					                    if (!(ch == '\f' || ch == '\v' || ch == '\r'))
 | 
				
			||||||
                        tok_str_add(ws_str, ch);
 | 
					                        tok_str_add(ws_str, ch);
 | 
				
			||||||
                    cinp();
 | 
					                    cinp();
 | 
				
			||||||
| 
						 | 
					@ -3483,7 +3483,7 @@ ST_INLN void unget_tok(int last_tok)
 | 
				
			||||||
    tok = last_tok;
 | 
					    tok = last_tok;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ST_FUNC void preprocess_start(TCCState *s1)
 | 
					ST_FUNC void preprocess_start(TCCState *s1, int is_asm)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    char *buf;
 | 
					    char *buf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3496,7 +3496,7 @@ ST_FUNC void preprocess_start(TCCState *s1)
 | 
				
			||||||
    s1->pack_stack_ptr = s1->pack_stack;
 | 
					    s1->pack_stack_ptr = s1->pack_stack;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    set_idnum('$', s1->dollars_in_identifiers ? IS_ID : 0);
 | 
					    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));
 | 
					    buf = tcc_malloc(3 + strlen(file->filename));
 | 
				
			||||||
    sprintf(buf, "\"%s\"", 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);
 | 
						memcpy(file->buffer, cstr.data, cstr.size);
 | 
				
			||||||
	cstr_free(&cstr);
 | 
						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)
 | 
					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() */
 | 
					    /* might be used in error() before preprocess_start() */
 | 
				
			||||||
    s->include_stack_ptr = s->include_stack;
 | 
					    s->include_stack_ptr = s->include_stack;
 | 
				
			||||||
 | 
					    s->ppfp = stdout;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* init isid table */
 | 
					    /* init isid table */
 | 
				
			||||||
    for(i = CH_EOF; i<128; i++)
 | 
					    for(i = CH_EOF; i<128; i++)
 | 
				
			||||||
| 
						 | 
					@ -3570,14 +3585,6 @@ ST_FUNC void tccpp_delete(TCCState *s)
 | 
				
			||||||
    /* free -D and compiler defines */
 | 
					    /* free -D and compiler defines */
 | 
				
			||||||
    free_defines(NULL);
 | 
					    free_defines(NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* cleanup from error/setjmp */
 | 
					 | 
				
			||||||
    while (macro_stack)
 | 
					 | 
				
			||||||
        end_macro();
 | 
					 | 
				
			||||||
    macro_ptr = NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    while (file)
 | 
					 | 
				
			||||||
        tcc_close();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* free tokens */
 | 
					    /* free tokens */
 | 
				
			||||||
    n = tok_ident - TOK_IDENT;
 | 
					    n = tok_ident - TOK_IDENT;
 | 
				
			||||||
    for(i = 0; i < n; i++)
 | 
					    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)
 | 
					static void tok_print(const char *msg, const int *str)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    FILE *fp;
 | 
					    FILE *fp;
 | 
				
			||||||
    int t;
 | 
					    int t, s = 0;
 | 
				
			||||||
    CValue cval;
 | 
					    CValue cval;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fp = tcc_state->ppfp;
 | 
					    fp = tcc_state->ppfp;
 | 
				
			||||||
    if (!fp || !tcc_state->dflag)
 | 
					    fprintf(fp, "%s", msg);
 | 
				
			||||||
        fp = stdout;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fprintf(fp, "%s ", msg);
 | 
					 | 
				
			||||||
    while (str) {
 | 
					    while (str) {
 | 
				
			||||||
	TOK_GET(&t, &str, &cval);
 | 
						TOK_GET(&t, &str, &cval);
 | 
				
			||||||
	if (!t)
 | 
						if (!t)
 | 
				
			||||||
	    break;
 | 
						    break;
 | 
				
			||||||
	fprintf(fp,"%s", get_tok_str(t, &cval));
 | 
						fprintf(fp, " %s" + s, get_tok_str(t, &cval)), s = 1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    fprintf(fp, "\n");
 | 
					    fprintf(fp, "\n");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -3731,20 +3735,14 @@ ST_FUNC int tcc_preprocess(TCCState *s1)
 | 
				
			||||||
    BufferedFile **iptr;
 | 
					    BufferedFile **iptr;
 | 
				
			||||||
    int token_seen, spcs, level;
 | 
					    int token_seen, spcs, level;
 | 
				
			||||||
    const char *p;
 | 
					    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_PREPROCESS
 | 
				
			||||||
                | (parse_flags & PARSE_FLAG_ASM_FILE)
 | 
					                | (parse_flags & PARSE_FLAG_ASM_FILE)
 | 
				
			||||||
                | PARSE_FLAG_LINEFEED
 | 
					                | PARSE_FLAG_LINEFEED
 | 
				
			||||||
                | PARSE_FLAG_SPACES
 | 
					                | PARSE_FLAG_SPACES
 | 
				
			||||||
                | PARSE_FLAG_ACCEPT_STRAYS
 | 
					                | PARSE_FLAG_ACCEPT_STRAYS
 | 
				
			||||||
                ;
 | 
					                ;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* Credits to Fabrice Bellard's initial revision to demonstrate its
 | 
					    /* Credits to Fabrice Bellard's initial revision to demonstrate its
 | 
				
			||||||
       capability to compile and run itself, provided all numbers are
 | 
					       capability to compile and run itself, provided all numbers are
 | 
				
			||||||
       given as decimals. tcc -E -P10 will do. */
 | 
					       given as decimals. tcc -E -P10 will do. */
 | 
				
			||||||
| 
						 | 
					@ -3754,7 +3752,6 @@ ST_FUNC int tcc_preprocess(TCCState *s1)
 | 
				
			||||||
#ifdef PP_BENCH
 | 
					#ifdef PP_BENCH
 | 
				
			||||||
    /* for PP benchmarks */
 | 
					    /* for PP benchmarks */
 | 
				
			||||||
    do next(); while (tok != TOK_EOF);
 | 
					    do next(); while (tok != TOK_EOF);
 | 
				
			||||||
    free_defines(define_start);
 | 
					 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3765,48 +3762,43 @@ ST_FUNC int tcc_preprocess(TCCState *s1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    token_seen = TOK_LINEFEED, spcs = 0;
 | 
					    token_seen = TOK_LINEFEED, spcs = 0;
 | 
				
			||||||
    pp_line(s1, file, 0);
 | 
					    pp_line(s1, file, 0);
 | 
				
			||||||
 | 
					 | 
				
			||||||
    for (;;) {
 | 
					    for (;;) {
 | 
				
			||||||
        iptr = s1->include_stack_ptr;
 | 
					        iptr = s1->include_stack_ptr;
 | 
				
			||||||
        next();
 | 
					        next();
 | 
				
			||||||
        if (tok == TOK_EOF)
 | 
					        if (tok == TOK_EOF)
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        level = s1->include_stack_ptr - iptr;
 | 
					        level = s1->include_stack_ptr - iptr;
 | 
				
			||||||
        if (level) {
 | 
					        if (level) {
 | 
				
			||||||
            if (level > 0)
 | 
					            if (level > 0)
 | 
				
			||||||
                pp_line(s1, *iptr, 0);
 | 
					                pp_line(s1, *iptr, 0);
 | 
				
			||||||
            pp_line(s1, file, level);
 | 
					            pp_line(s1, file, level);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        if (s1->dflag & 7) {
 | 
				
			||||||
        if (s1->dflag) {
 | 
					 | 
				
			||||||
            pp_debug_defines(s1);
 | 
					            pp_debug_defines(s1);
 | 
				
			||||||
            if (s1->dflag & 4)
 | 
					            if (s1->dflag & 4)
 | 
				
			||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (token_seen == TOK_LINEFEED) {
 | 
					        if (is_space(tok)) {
 | 
				
			||||||
            if (tok == ' ') {
 | 
					            if (spcs < sizeof white - 1)
 | 
				
			||||||
                ++spcs;
 | 
					                white[spcs++] = tok;
 | 
				
			||||||
                continue;
 | 
					            continue;
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            if (tok == TOK_LINEFEED) {
 | 
					 | 
				
			||||||
                spcs = 0;
 | 
					 | 
				
			||||||
                continue;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            pp_line(s1, file, 0);
 | 
					 | 
				
			||||||
        } else if (tok == TOK_LINEFEED) {
 | 
					        } else if (tok == TOK_LINEFEED) {
 | 
				
			||||||
 | 
					            spcs = 0;
 | 
				
			||||||
 | 
					            if (token_seen == TOK_LINEFEED)
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
            ++file->line_ref;
 | 
					            ++file->line_ref;
 | 
				
			||||||
        } else {
 | 
					        } else if (token_seen == TOK_LINEFEED) {
 | 
				
			||||||
            spcs = pp_need_space(token_seen, tok);
 | 
					            pp_line(s1, file, 0);
 | 
				
			||||||
 | 
					        } else if (spcs == 0 && pp_need_space(token_seen, tok)) {
 | 
				
			||||||
 | 
					            white[spcs++] = ' ';
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        while (spcs)
 | 
					        white[spcs] = 0, fputs(white, s1->ppfp), spcs = 0;
 | 
				
			||||||
            fputs(" ", s1->ppfp), --spcs;
 | 
					 | 
				
			||||||
        fputs(p = get_tok_str(tok, &tokc), s1->ppfp);
 | 
					        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;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										2
									
								
								tccrun.c
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								tccrun.c
									
										
									
									
									
								
							| 
						 | 
					@ -108,6 +108,8 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
 | 
				
			||||||
    int (*prog_main)(int, char **);
 | 
					    int (*prog_main)(int, char **);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    s1->runtime_main = "main";
 | 
					    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)
 | 
					    if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0)
 | 
				
			||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
    prog_main = tcc_get_symbol_err(s1, s1->runtime_main);
 | 
					    prog_main = tcc_get_symbol_err(s1, s1->runtime_main);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										107
									
								
								tcctools.c
									
										
									
									
									
								
							
							
						
						
									
										107
									
								
								tcctools.c
									
										
									
									
									
								
							| 
						 | 
					@ -543,111 +543,4 @@ ST_FUNC void gen_makedeps(TCCState *s, const char *target, const char *filename)
 | 
				
			||||||
    fclose(depout);
 | 
					    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 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* -------------------------------------------------------------- */
 | 
					/* -------------------------------------------------------------- */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1 +0,0 @@
 | 
				
			||||||
struct A {} int i;
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1 +0,0 @@
 | 
				
			||||||
56_btype_excess-1.c:1: error: too many basic types
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1 +0,0 @@
 | 
				
			||||||
char int i;
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1 +0,0 @@
 | 
				
			||||||
57_btype_excess-2.c:1: error: too many basic types
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,9 +0,0 @@
 | 
				
			||||||
int f(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int f(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1 +0,0 @@
 | 
				
			||||||
58_function_redefinition.c:7: error: redefinition of 'f'
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1 +0,0 @@
 | 
				
			||||||
int (*fct)[42](int x);
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1 +0,0 @@
 | 
				
			||||||
59_function_array.c:1: error: declaration of an array of functions
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,4 +0,0 @@
 | 
				
			||||||
enum color {RED, GREEN, BLUE};
 | 
					 | 
				
			||||||
enum color {R, G, B};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum color c;
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1 +0,0 @@
 | 
				
			||||||
60_enum_redefinition.c:2: error: struct/union/enum already defined
 | 
					 | 
				
			||||||
							
								
								
									
										51
									
								
								tests/tests2/60_errors_and_warnings.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								tests/tests2/60_errors_and_warnings.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -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
 | 
				
			||||||
							
								
								
									
										28
									
								
								tests/tests2/60_errors_and_warnings.expect
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								tests/tests2/60_errors_and_warnings.expect
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					@ -1 +0,0 @@
 | 
				
			||||||
enum rgb c = 42;
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1 +0,0 @@
 | 
				
			||||||
61_undefined_enum.c:1: error: unknown type size
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,4 +0,0 @@
 | 
				
			||||||
enum color {RED, GREEN, BLUE};
 | 
					 | 
				
			||||||
enum rgb {RED, G, B};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum color c = RED;
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1 +0,0 @@
 | 
				
			||||||
62_enumerator_redefinition.c:2: error: redefinition of enumerator 'RED'
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,14 +0,0 @@
 | 
				
			||||||
enum {
 | 
					 | 
				
			||||||
    FOO,
 | 
					 | 
				
			||||||
    BAR
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int main(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    enum {
 | 
					 | 
				
			||||||
        FOO = 2,
 | 
					 | 
				
			||||||
        BAR
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return BAR - FOO;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1 +0,0 @@
 | 
				
			||||||
int i = i++;
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1 +0,0 @@
 | 
				
			||||||
74_nocode_wanted.c:1: error: initializer element is not constant
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,36 +1,35 @@
 | 
				
			||||||
/*****************************************************************************/
 | 
					/*****************************************************************************/
 | 
				
			||||||
/* test 'nodata_wanted' data output suppression */
 | 
					/* test 'nodata_wanted' data output suppression */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*-* test 1: initializer not computable 1 */
 | 
					#if defined test_static_data_error
 | 
				
			||||||
void foo() {
 | 
					void foo() {
 | 
				
			||||||
    if (1) {
 | 
					    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() {
 | 
					void foo() {
 | 
				
			||||||
    if (0) {
 | 
					    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();
 | 
					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() {
 | 
					void foo() {
 | 
				
			||||||
    short w = &foo; /* no error */
 | 
					    short w = &foo; /* 2 cast warnings */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*-* test 5; nodata_wanted test */
 | 
					#elif defined test_data_suppression
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define DATA_LBL(s) \
 | 
					#define ASMLABELS(s) \
 | 
				
			||||||
    __asm__(".global d"#s",t"#s"\n.data\nd"#s":\n.text\nt"#s":\n"); \
 | 
					    __asm__(".global d"#s",t"#s"\n.data\nd"#s":\n.text\nt"#s":\n")
 | 
				
			||||||
    extern char d##s[],t##s[];
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define PROG \
 | 
					#define PROG \
 | 
				
			||||||
        static void *p = (void*)&main;\
 | 
					        static void *p = (void*)&main;\
 | 
				
			||||||
| 
						 | 
					@ -47,28 +46,29 @@ void foo() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main()
 | 
					int main()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    extern char ds1[],ts1[];
 | 
				
			||||||
 | 
					    extern char ds2[],ts2[];
 | 
				
			||||||
 | 
					    extern char de1[],te1[];
 | 
				
			||||||
 | 
					    extern char de2[],te2[];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    printf("suppression off\n");
 | 
					    printf("suppression off\n");
 | 
				
			||||||
    DATA_LBL(s1);
 | 
					 | 
				
			||||||
    if (1) {
 | 
					    if (1) {
 | 
				
			||||||
 | 
					        ASMLABELS(s1);
 | 
				
			||||||
        PROG
 | 
					        PROG
 | 
				
			||||||
 | 
					        ASMLABELS(e1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    DATA_LBL(e1);
 | 
					 | 
				
			||||||
    printf("  data length is %s\n", de1 - ds1 ? "not 0":"0");
 | 
					    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");
 | 
					    printf("suppression on\n");
 | 
				
			||||||
    DATA_LBL(s2);
 | 
					 | 
				
			||||||
    if (0) {
 | 
					    if (0) {
 | 
				
			||||||
 | 
					        ASMLABELS(s2);
 | 
				
			||||||
        PROG
 | 
					        PROG
 | 
				
			||||||
 | 
					        ASMLABELS(e2);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    DATA_LBL(e2);
 | 
					 | 
				
			||||||
    printf("  data length is %x\n", de2 - ds2);
 | 
					    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;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*-* test 6: some test */
 | 
					#endif
 | 
				
			||||||
int main()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return 34;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,24 +1,22 @@
 | 
				
			||||||
/*-* test 1: initializer not computable 1 */
 | 
					[test_static_data_error]
 | 
				
			||||||
test 1:3: error: initializer element is not computable at load time
 | 
					96_nodata_wanted.c:7: error: initializer element is not computable at load time
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*-* test 2: initializer not computable 2 */
 | 
					[test_static_nodata_error]
 | 
				
			||||||
test 2:3: error: initializer element is not computable at load time
 | 
					96_nodata_wanted.c:14: error: initializer element is not computable at load time
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*-* test 3: initializer not computable 3 */
 | 
					[test_global_data_error]
 | 
				
			||||||
test 3:2: error: initializer element is not computable at load time
 | 
					96_nodata_wanted.c:20: error: initializer element is not computable at load time
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*-* test 4: 2 cast warnings */
 | 
					[test_local_data_noerror]
 | 
				
			||||||
test 4:2: warning: assignment makes integer from pointer without a cast
 | 
					96_nodata_wanted.c:25: warning: assignment makes integer from pointer without a cast
 | 
				
			||||||
test 4:2: warning: nonportable conversion from pointer to char/short
 | 
					96_nodata_wanted.c:25: warning: nonportable conversion from pointer to char/short
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*-* test 5; nodata_wanted test */
 | 
					[test_data_suppression]
 | 
				
			||||||
suppression off
 | 
					suppression off
 | 
				
			||||||
  static data: 8 - 8.0 - 8.0 - main - static string
 | 
					  static data: 8 - 8.0 - 8.0 - main - static string
 | 
				
			||||||
  static bitfields: 333 44 555555 6 7
 | 
					  static bitfields: 333 44 555555 6 7
 | 
				
			||||||
  data length is not 0
 | 
					  data length is not 0
 | 
				
			||||||
 | 
					  text length is not 0
 | 
				
			||||||
suppression on
 | 
					suppression on
 | 
				
			||||||
  data length is 0
 | 
					  data length is 0
 | 
				
			||||||
returns 0
 | 
					  text length is 0
 | 
				
			||||||
 | 
					 | 
				
			||||||
/*-* test 6: some test */
 | 
					 | 
				
			||||||
returns 34
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,7 +20,7 @@ endif
 | 
				
			||||||
ifeq (,$(filter i386 x86_64,$(ARCH)))
 | 
					ifeq (,$(filter i386 x86_64,$(ARCH)))
 | 
				
			||||||
 SKIP += 85_asm-outside-function.test
 | 
					 SKIP += 85_asm-outside-function.test
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
ifeq (-$(findstring gcc,$(CC)-)-,--)
 | 
					ifeq (-$(findstring gcc,$(CC))-,--)
 | 
				
			||||||
 SKIP += $(patsubst %.expect,%.test,$(GEN-ALWAYS))
 | 
					 SKIP += $(patsubst %.expect,%.test,$(GEN-ALWAYS))
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
ifeq (-$(CONFIG_WIN32)-$(CONFIG_i386)$(CONFIG_arm)-,--yes-)
 | 
					ifeq (-$(CONFIG_WIN32)-$(CONFIG_i386)$(CONFIG_arm)-,--yes-)
 | 
				
			||||||
| 
						 | 
					@ -40,8 +40,9 @@ NORUN =
 | 
				
			||||||
FLAGS =
 | 
					FLAGS =
 | 
				
			||||||
76_dollars_in_identifiers.test : FLAGS += -fdollars-in-identifiers
 | 
					76_dollars_in_identifiers.test : FLAGS += -fdollars-in-identifiers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# run the source file cut into snippets
 | 
					# These tests run several snippets from the same file one by one
 | 
				
			||||||
96_nodata_wanted.test : FLAGS = -dT
 | 
					60_errors_and_warnings.test : FLAGS += -dt
 | 
				
			||||||
 | 
					96_nodata_wanted.test : FLAGS += -dt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Always generate certain .expects (don't put these in the GIT),
 | 
					# Always generate certain .expects (don't put these in the GIT),
 | 
				
			||||||
GEN-ALWAYS =
 | 
					GEN-ALWAYS =
 | 
				
			||||||
| 
						 | 
					@ -90,8 +91,8 @@ F2 = $1 UPDATE="$(patsubst %.test,%.expect,$1)"
 | 
				
			||||||
	@$(call GEN,$(SRC)/$*.c) $(FILTER) >$@ 2>&1
 | 
						@$(call GEN,$(SRC)/$*.c) $(FILTER) >$@ 2>&1
 | 
				
			||||||
	@rm -f *.exe *.obj *.pdb
 | 
						@rm -f *.exe *.obj *.pdb
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# using TCC for .expect if -dT in FLAGS
 | 
					# using TCC for .expect if -dt in FLAGS
 | 
				
			||||||
GEN = $(if $(findstring -dT,$(FLAGS)),$(GEN-TCC),$(GEN-CC))
 | 
					GEN = $(if $(filter -dt,$(FLAGS)),$(GEN-TCC),$(GEN-CC))
 | 
				
			||||||
GEN-CC = $(CC) -w -std=gnu99 $(FLAGS) $1 -o a.exe && ./a.exe $(ARGS)
 | 
					GEN-CC = $(CC) -w -std=gnu99 $(FLAGS) $1 -o a.exe && ./a.exe $(ARGS)
 | 
				
			||||||
GEN-TCC = $(TCC) $(FLAGS) -run $1 $(ARGS)
 | 
					GEN-TCC = $(TCC) $(FLAGS) -run $1 $(ARGS)
 | 
				
			||||||
GEN-MSC = $(MS-CC) $1 && ./$(basename $@).exe
 | 
					GEN-MSC = $(MS-CC) $1 && ./$(basename $@).exe
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue