Some in-between fixes (See Changelog for details).

This commit is contained in:
grischka
2007-11-25 22:14:35 +00:00
parent 2bcb964694
commit 2de1b2d14c
2 changed files with 99 additions and 67 deletions

122
tcc.c
View File

@ -321,6 +321,7 @@ static int tok_flags;
#define TOK_FLAG_BOL 0x0001 /* beginning of line before */ #define TOK_FLAG_BOL 0x0001 /* beginning of line before */
#define TOK_FLAG_BOF 0x0002 /* beginning of file before */ #define TOK_FLAG_BOF 0x0002 /* beginning of file before */
#define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */ #define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */
#define TOK_FLAG_EOF 0x0008 /* end of file */
static int *macro_ptr, *macro_ptr_allocated; static int *macro_ptr, *macro_ptr_allocated;
static int *unget_saved_macro_ptr; static int *unget_saved_macro_ptr;
@ -1032,6 +1033,32 @@ static int strstart(const char *str, const char *val, const char **ptr)
return 1; return 1;
} }
#ifdef WIN32
char *normalize_slashes(char *path)
{
char *p;
for (p = path; *p; ++p)
if (*p == '\\')
*p = '/';
return path;
}
char *w32_tcc_lib_path(void)
{
/* on win32, we suppose the lib and includes are at the location
of 'tcc.exe' */
char path[1024], *p;
GetModuleFileNameA(NULL, path, sizeof path);
p = tcc_basename(normalize_slashes(strlwr(path)));
if (p - 5 > path && 0 == strncmp(p - 5, "/bin/", 5))
p -= 5;
else if (p > path)
p--;
*p = 0;
return strdup(path);
}
#endif
/* memory management */ /* memory management */
#ifdef MEM_DEBUG #ifdef MEM_DEBUG
int mem_cur_size; int mem_cur_size;
@ -1844,7 +1871,6 @@ BufferedFile *tcc_open(TCCState *s1, const char *filename)
{ {
int fd; int fd;
BufferedFile *bf; BufferedFile *bf;
int i, len;
fd = open(filename, O_RDONLY | O_BINARY); fd = open(filename, O_RDONLY | O_BINARY);
if (fd < 0) if (fd < 0)
@ -1859,10 +1885,7 @@ BufferedFile *tcc_open(TCCState *s1, const char *filename)
bf->buf_end = bf->buffer; bf->buf_end = bf->buffer;
bf->buffer[0] = CH_EOB; /* put eob symbol */ bf->buffer[0] = CH_EOB; /* put eob symbol */
pstrcpy(bf->filename, sizeof(bf->filename), filename); pstrcpy(bf->filename, sizeof(bf->filename), filename);
len = strlen(bf->filename); normalize_slashes(bf->filename);
for (i = 0; i < len; i++)
if (bf->filename[i] == '\\')
bf->filename[i] = '/';
bf->line_num = 1; bf->line_num = 1;
bf->ifndef_macro = 0; bf->ifndef_macro = 0;
bf->ifdef_stack_ptr = s1->ifdef_stack_ptr; bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;
@ -3540,13 +3563,17 @@ static inline void next_nomacro1(void)
parse_eof: parse_eof:
{ {
TCCState *s1 = tcc_state; TCCState *s1 = tcc_state;
if (parse_flags & PARSE_FLAG_LINEFEED) { if ((parse_flags & PARSE_FLAG_LINEFEED)
&& !(tok_flags & TOK_FLAG_EOF)) {
tok_flags |= TOK_FLAG_EOF;
tok = TOK_LINEFEED; tok = TOK_LINEFEED;
goto keep_tok_flags;
} else if (s1->include_stack_ptr == s1->include_stack || } else if (s1->include_stack_ptr == s1->include_stack ||
!(parse_flags & PARSE_FLAG_PREPROCESS)) { !(parse_flags & PARSE_FLAG_PREPROCESS)) {
/* no include left : end of file. */ /* no include left : end of file. */
tok = TOK_EOF; tok = TOK_EOF;
} else { } else {
tok_flags &= ~TOK_FLAG_EOF;
/* pop include file */ /* pop include file */
/* test if previous '#endif' was after a #ifdef at /* test if previous '#endif' was after a #ifdef at
@ -3574,15 +3601,13 @@ static inline void next_nomacro1(void)
break; break;
case '\n': case '\n':
if (parse_flags & PARSE_FLAG_LINEFEED) {
tok = TOK_LINEFEED;
} else {
file->line_num++; file->line_num++;
tok_flags |= TOK_FLAG_BOL; tok_flags |= TOK_FLAG_BOL;
p++; p++;
if (0 == (parse_flags & PARSE_FLAG_LINEFEED))
goto redo_no_start; goto redo_no_start;
} tok = TOK_LINEFEED;
break; goto keep_tok_flags;
case '#': case '#':
/* XXX: simplify */ /* XXX: simplify */
@ -3912,8 +3937,9 @@ static inline void next_nomacro1(void)
error("unrecognized character \\x%02x", c); error("unrecognized character \\x%02x", c);
break; break;
} }
file->buf_ptr = p;
tok_flags = 0; tok_flags = 0;
keep_tok_flags:
file->buf_ptr = p;
#if defined(PARSE_DEBUG) #if defined(PARSE_DEBUG)
printf("token = %s\n", get_tok_str(tok, &tokc)); printf("token = %s\n", get_tok_str(tok, &tokc));
#endif #endif
@ -4140,6 +4166,7 @@ static int macro_subst_tok(TokenString *tok_str,
parlevel++; parlevel++;
else if (tok == ')') else if (tok == ')')
parlevel--; parlevel--;
if (tok != TOK_LINEFEED)
tok_str_add2(&str, tok, &tokc); tok_str_add2(&str, tok, &tokc);
next_nomacro(); next_nomacro();
} }
@ -8188,9 +8215,6 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
int v1, v2; int v1, v2;
if (!case_sym) if (!case_sym)
expect("switch"); expect("switch");
/* since a case is like a label, we must skip it with a jmp */
b = gjmp(0);
next_case:
next(); next();
v1 = expr_const(); v1 = expr_const();
v2 = v1; v2 = v1;
@ -8200,26 +8224,24 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
if (v2 < v1) if (v2 < v1)
warning("empty case range"); warning("empty case range");
} }
/* since a case is like a label, we must skip it with a jmp */
b = gjmp(0);
gsym(*case_sym); gsym(*case_sym);
vseti(case_reg, 0); vseti(case_reg, 0);
vpushi(v1); vpushi(v1);
if (v1 == v2) { if (v1 == v2) {
gen_op(TOK_EQ); gen_op(TOK_EQ);
*case_sym = 0; *case_sym = gtst(1, 0);
} else { } else {
gen_op(TOK_GE); gen_op(TOK_GE);
*case_sym = gtst(1, 0); *case_sym = gtst(1, 0);
vseti(case_reg, 0); vseti(case_reg, 0);
vpushi(v2); vpushi(v2);
gen_op(TOK_LE); gen_op(TOK_LE);
}
skip(':');
if (tok == TOK_CASE) {
b = gtst(0, b);
goto next_case;
}
*case_sym = gtst(1, *case_sym); *case_sym = gtst(1, *case_sym);
}
gsym(b); gsym(b);
skip(':');
is_expr = 0; is_expr = 0;
goto block_after_label; goto block_after_label;
} else } else
@ -9015,6 +9037,8 @@ static void func_decl_list(Sym *func_sym)
'cur_text_section' */ 'cur_text_section' */
static void gen_function(Sym *sym) static void gen_function(Sym *sym)
{ {
int saved_nocode_wanted = nocode_wanted;
nocode_wanted = 0;
ind = cur_text_section->data_offset; ind = cur_text_section->data_offset;
/* NOTE: we patch the symbol size later */ /* NOTE: we patch the symbol size later */
put_extern_sym(sym, cur_text_section, ind, 0); put_extern_sym(sym, cur_text_section, ind, 0);
@ -9043,6 +9067,7 @@ static void gen_function(Sym *sym)
funcname = ""; /* for safety */ funcname = ""; /* for safety */
func_vt.t = VT_VOID; /* for safety */ func_vt.t = VT_VOID; /* for safety */
ind = 0; /* for safety */ ind = 0; /* for safety */
nocode_wanted = saved_nocode_wanted;
} }
static void gen_inline_functions(void) static void gen_inline_functions(void)
@ -9350,6 +9375,7 @@ static int tcc_compile(TCCState *s1)
#endif #endif
define_start = define_stack; define_start = define_stack;
nocode_wanted = 1;
if (setjmp(s1->error_jmp_buf) == 0) { if (setjmp(s1->error_jmp_buf) == 0) {
s1->nb_errors = 0; s1->nb_errors = 0;
@ -9400,26 +9426,19 @@ static int tcc_preprocess(TCCState *s1)
last_is_space = 1; last_is_space = 1;
next(); next();
for(;;) { for(;;) {
if (tok == TOK_EOF) if (tok == TOK_EOF) {
break; break;
if (!last_is_space) { } else if (tok == TOK_LINEFEED) {
last_is_space = 1;
} else {
if (!last_is_space)
fputc(' ', s1->outfile); fputc(' ', s1->outfile);
last_is_space = 0;
} }
fputs(get_tok_str(tok, &tokc), s1->outfile); fputs(get_tok_str(tok, &tokc), s1->outfile);
if (tok == TOK_LINEFEED) {
last_is_space = 1;
/* XXX: suppress that hack */
parse_flags &= ~PARSE_FLAG_LINEFEED;
next();
parse_flags |= PARSE_FLAG_LINEFEED;
} else {
last_is_space = 0;
next(); next();
} }
}
free_defines(define_start); free_defines(define_start);
return 0; return 0;
} }
@ -10380,17 +10399,15 @@ int tcc_set_flag(TCCState *s, const char *flag_name, int value)
/* extract the basename of a file */ /* extract the basename of a file */
static char *tcc_basename(const char *name) static char *tcc_basename(const char *name)
{ {
const char *p; char *p = strchr(name, 0);
p = strrchr(name, '/'); while (p > name
&& p[-1] != '/'
#ifdef WIN32 #ifdef WIN32
if (!p) && p[-1] != '\\'
p = strrchr(name, '\\');
#endif #endif
if (!p) )
p = name; --p;
else return p;
p++;
return (char*)p;
} }
#if !defined(LIBTCC) #if !defined(LIBTCC)
@ -10774,22 +10791,7 @@ int main(int argc, char **argv)
int64_t start_time = 0; int64_t start_time = 0;
#ifdef WIN32 #ifdef WIN32
/* on win32, we suppose the lib and includes are at the location tcc_lib_path = w32_tcc_lib_path();
of 'tcc.exe' */
{
static char path[1024];
char *p, *d;
GetModuleFileNameA(NULL, path, sizeof path);
p = d = strlwr(path);
while (*d)
{
if (*d == '\\') *d = '/', p = d;
++d;
}
*p = '\0';
tcc_lib_path = path;
}
#endif #endif
s = tcc_new(); s = tcc_new();

30
win32/build-tcc.bat Normal file
View File

@ -0,0 +1,30 @@
@rem ----------------------------------------------------
@rem batch file to build tcc using gcc and ar from mingw
@rem ----------------------------------------------------
:
@if exist ..\config.h goto configready
:
@echo>..\config.h #define TCC_VERSION "0.9.24pre"
@echo>>..\config.h #define TCC_TARGET_PE 1
@echo>>..\config.h #define CONFIG_TCCDIR NULL
:
:configready
:
gcc -Os -fno-strict-aliasing ../tcc.c -o tcc.exe -s
gcc -Os -fno-strict-aliasing ../tcc.c -D LIBTCC -c -o libtcc.o
gcc -Os -fno-strict-aliasing ../tiny_impdef.c -o tiny_impdef.exe -s
mkdir libtcc
ar rcs libtcc/libtcc.a libtcc.o
del libtcc.o
copy ..\libtcc.h libtcc
:
.\tcc -c lib/crt1.c
.\tcc -c lib/wincrt1.c
.\tcc -c lib/dllcrt1.c
.\tcc -c lib/dllmain.c
.\tcc -c lib/chkstk.S
.\tcc -c ../libtcc1.c
.\tcc -c ../alloca86.S
.\tcc -c ../alloca86-bt.S
ar rcs lib/libtcc1.a crt1.o wincrt1.o dllcrt1.o dllmain.o chkstk.o libtcc1.o alloca86.o alloca86-bt.o
del *.o