added hash tables - add -o option for debug output
This commit is contained in:
parent
44b5c9742a
commit
b9455a7484
1 changed files with 145 additions and 80 deletions
225
tcc.c
225
tcc.c
|
@ -34,14 +34,18 @@
|
||||||
#define STRING_MAX_SIZE 1024
|
#define STRING_MAX_SIZE 1024
|
||||||
#define INCLUDE_PATHS_MAX 32
|
#define INCLUDE_PATHS_MAX 32
|
||||||
|
|
||||||
|
#define TOK_HASH_SIZE 521
|
||||||
|
#define TOK_ALLOC_INCR 256 /* must be a power of two */
|
||||||
|
#define SYM_HASH_SIZE 263
|
||||||
|
|
||||||
/* number of available temporary registers */
|
/* number of available temporary registers */
|
||||||
#define NB_REGS 3
|
#define NB_REGS 3
|
||||||
/* defined if function parameters must be evaluated in revert order */
|
/* defined if function parameters must be evaluated in reverse order */
|
||||||
#define INVERT_FUNC_PARAMS
|
#define INVERT_FUNC_PARAMS
|
||||||
|
|
||||||
/* token symbol management */
|
/* token symbol management */
|
||||||
typedef struct TokenSym {
|
typedef struct TokenSym {
|
||||||
struct TokenSym *next;
|
struct TokenSym *hash_next;
|
||||||
int tok; /* token number */
|
int tok; /* token number */
|
||||||
int len;
|
int len;
|
||||||
char str[1];
|
char str[1];
|
||||||
|
@ -54,8 +58,14 @@ typedef struct Sym {
|
||||||
int c; /* associated number */
|
int c; /* associated number */
|
||||||
struct Sym *next; /* next related symbol */
|
struct Sym *next; /* next related symbol */
|
||||||
struct Sym *prev; /* prev symbol in stack */
|
struct Sym *prev; /* prev symbol in stack */
|
||||||
|
struct Sym *hash_next; /* next symbol in hash table */
|
||||||
} Sym;
|
} Sym;
|
||||||
|
|
||||||
|
typedef struct SymStack {
|
||||||
|
struct Sym *top;
|
||||||
|
struct Sym *hash[SYM_HASH_SIZE];
|
||||||
|
} SymStack;
|
||||||
|
|
||||||
#define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
|
#define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
|
||||||
#define SYM_FIELD 0x20000000 /* struct/union field symbol space */
|
#define SYM_FIELD 0x20000000 /* struct/union field symbol space */
|
||||||
|
|
||||||
|
@ -87,10 +97,12 @@ typedef struct {
|
||||||
FILE *file;
|
FILE *file;
|
||||||
int tok, tok1, tokc, rsym, anon_sym,
|
int tok, tok1, tokc, rsym, anon_sym,
|
||||||
prog, ind, loc, glo, vt, vc, const_wanted, line_num;
|
prog, ind, loc, glo, vt, vc, const_wanted, line_num;
|
||||||
TokenSym *first_ident;
|
int tok_ident;
|
||||||
|
TokenSym **table_ident;
|
||||||
|
TokenSym *hash_ident[521];
|
||||||
char token_buf[STRING_MAX_SIZE + 1];
|
char token_buf[STRING_MAX_SIZE + 1];
|
||||||
char *filename, *funcname;
|
char *filename, *funcname;
|
||||||
Sym *define_stack, *global_stack, *local_stack, *label_stack;
|
SymStack define_stack, global_stack, local_stack, label_stack;
|
||||||
|
|
||||||
int vstack[VSTACK_SIZE], *vstack_ptr;
|
int vstack[VSTACK_SIZE], *vstack_ptr;
|
||||||
int *macro_ptr, *macro_ptr_allocated;
|
int *macro_ptr, *macro_ptr_allocated;
|
||||||
|
@ -283,14 +295,14 @@ void *dlsym(void *handle, char *symbol)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int isid(c)
|
inline int isid(c)
|
||||||
{
|
{
|
||||||
return (c >= 'a' & c <= 'z') |
|
return (c >= 'a' && c <= 'z') ||
|
||||||
(c >= 'A' & c <= 'Z') |
|
(c >= 'A' && c <= 'Z') ||
|
||||||
c == '_';
|
c == '_';
|
||||||
}
|
}
|
||||||
|
|
||||||
int isnum(c)
|
inline int isnum(c)
|
||||||
{
|
{
|
||||||
return c >= '0' & c <= '9';
|
return c >= '0' & c <= '9';
|
||||||
}
|
}
|
||||||
|
@ -341,31 +353,40 @@ void test_lvalue()
|
||||||
|
|
||||||
TokenSym *tok_alloc(char *str, int len)
|
TokenSym *tok_alloc(char *str, int len)
|
||||||
{
|
{
|
||||||
TokenSym *ts, **pts;
|
TokenSym *ts, **pts, **ptable;
|
||||||
int t;
|
int h, i;
|
||||||
|
|
||||||
if (len <= 0)
|
if (len <= 0)
|
||||||
len = strlen(str);
|
len = strlen(str);
|
||||||
|
h = 1;
|
||||||
t = TOK_IDENT;
|
for(i=0;i<len;i++)
|
||||||
pts = &first_ident;
|
h = ((h << 8) | (str[i] & 0xff)) % TOK_HASH_SIZE;
|
||||||
|
|
||||||
|
pts = &hash_ident[h];
|
||||||
while (1) {
|
while (1) {
|
||||||
ts = *pts;
|
ts = *pts;
|
||||||
if (!ts)
|
if (!ts)
|
||||||
break;
|
break;
|
||||||
if (ts->len == len && !memcmp(ts->str, str, len))
|
if (ts->len == len && !memcmp(ts->str, str, len))
|
||||||
return ts;
|
return ts;
|
||||||
t++;
|
pts = &(ts->hash_next);
|
||||||
pts = &(ts->next);
|
}
|
||||||
|
/* expand token table if needed */
|
||||||
|
i = tok_ident - TOK_IDENT;
|
||||||
|
if ((i % TOK_ALLOC_INCR) == 0) {
|
||||||
|
ptable = realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *));
|
||||||
|
if (!ptable)
|
||||||
|
error("memory full");
|
||||||
|
table_ident = ptable;
|
||||||
}
|
}
|
||||||
ts = malloc(sizeof(TokenSym) + len);
|
ts = malloc(sizeof(TokenSym) + len);
|
||||||
if (!ts)
|
if (!ts)
|
||||||
error("memory full");
|
error("memory full");
|
||||||
ts->tok = t;
|
table_ident[i] = ts;
|
||||||
|
ts->tok = tok_ident++;
|
||||||
ts->len = len;
|
ts->len = len;
|
||||||
ts->next = NULL;
|
ts->hash_next = NULL;
|
||||||
memcpy(ts->str, str, len + 1);
|
memcpy(ts->str, str, len + 1);
|
||||||
|
|
||||||
*pts = ts;
|
*pts = ts;
|
||||||
return ts;
|
return ts;
|
||||||
}
|
}
|
||||||
|
@ -425,30 +446,16 @@ char *get_tok_str(int v, int c)
|
||||||
*p++ = v;
|
*p++ = v;
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
return buf;
|
return buf;
|
||||||
|
} else if (v < tok_ident) {
|
||||||
|
return table_ident[v - TOK_IDENT]->str;
|
||||||
} else {
|
} else {
|
||||||
ts = first_ident;
|
/* should never happen */
|
||||||
while (ts != NULL) {
|
|
||||||
if (ts->tok == v)
|
|
||||||
return ts->str;
|
|
||||||
ts = ts->next;
|
|
||||||
}
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find a symbol and return its associated structure. 's' is the top
|
/* push, without hashing */
|
||||||
of the symbol stack */
|
Sym *sym_push2(Sym **ps, int v, int t, int c)
|
||||||
Sym *sym_find1(Sym *s, int v)
|
|
||||||
{
|
|
||||||
while (s) {
|
|
||||||
if (s->v == v)
|
|
||||||
return s;
|
|
||||||
s = s->prev;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Sym *sym_push1(Sym **ps, int v, int t, int c)
|
|
||||||
{
|
{
|
||||||
Sym *s;
|
Sym *s;
|
||||||
s = malloc(sizeof(Sym));
|
s = malloc(sizeof(Sym));
|
||||||
|
@ -458,42 +465,83 @@ Sym *sym_push1(Sym **ps, int v, int t, int c)
|
||||||
s->t = t;
|
s->t = t;
|
||||||
s->c = c;
|
s->c = c;
|
||||||
s->next = NULL;
|
s->next = NULL;
|
||||||
|
/* add in stack */
|
||||||
s->prev = *ps;
|
s->prev = *ps;
|
||||||
*ps = s;
|
*ps = s;
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* find a symbol and return its associated structure. 's' is the top
|
||||||
|
of the symbol stack */
|
||||||
|
Sym *sym_find2(Sym *s, int v)
|
||||||
|
{
|
||||||
|
while (s) {
|
||||||
|
if (s->v == v)
|
||||||
|
return s;
|
||||||
|
s = s->prev;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find a symbol and return its associated structure. 'st' is the
|
||||||
|
symbol stack */
|
||||||
|
Sym *sym_find1(SymStack *st, int v)
|
||||||
|
{
|
||||||
|
Sym *s;
|
||||||
|
|
||||||
|
s = st->hash[v % SYM_HASH_SIZE];
|
||||||
|
while (s) {
|
||||||
|
if (s->v == v)
|
||||||
|
return s;
|
||||||
|
s = s->hash_next;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Sym *sym_push1(SymStack *st, int v, int t, int c)
|
||||||
|
{
|
||||||
|
Sym *s, **ps;
|
||||||
|
s = sym_push2(&st->top, v, t, c);
|
||||||
|
/* add in hash table */
|
||||||
|
ps = &st->hash[s->v % SYM_HASH_SIZE];
|
||||||
|
s->hash_next = *ps;
|
||||||
|
*ps = s;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
/* find a symbol in the right symbol space */
|
/* find a symbol in the right symbol space */
|
||||||
Sym *sym_find(int v)
|
Sym *sym_find(int v)
|
||||||
{
|
{
|
||||||
Sym *s;
|
Sym *s;
|
||||||
s = sym_find1(local_stack, v);
|
s = sym_find1(&local_stack, v);
|
||||||
if (!s)
|
if (!s)
|
||||||
s = sym_find1(global_stack, v);
|
s = sym_find1(&global_stack, v);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* push a given symbol on the symbol stack */
|
/* push a given symbol on the symbol stack */
|
||||||
Sym *sym_push(int v, int t, int c)
|
Sym *sym_push(int v, int t, int c)
|
||||||
{
|
{
|
||||||
if (local_stack)
|
if (local_stack.top)
|
||||||
return sym_push1(&local_stack, v, t, c);
|
return sym_push1(&local_stack, v, t, c);
|
||||||
else
|
else
|
||||||
return sym_push1(&global_stack, v, t, c);
|
return sym_push1(&global_stack, v, t, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pop symbols until top reaches 'b' */
|
/* pop symbols until top reaches 'b' */
|
||||||
void sym_pop(Sym **ps, Sym *b)
|
void sym_pop(SymStack *st, Sym *b)
|
||||||
{
|
{
|
||||||
Sym *s, *ss;
|
Sym *s, *ss;
|
||||||
|
|
||||||
s = *ps;
|
s = st->top;
|
||||||
while(s != b) {
|
while(s != b) {
|
||||||
ss = s->prev;
|
ss = s->prev;
|
||||||
|
/* free hash table entry */
|
||||||
|
st->hash[s->v % SYM_HASH_SIZE] = s->hash_next;
|
||||||
free(s);
|
free(s);
|
||||||
s = ss;
|
s = ss;
|
||||||
}
|
}
|
||||||
*ps = b;
|
st->top = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ch, ch1;
|
int ch, ch1;
|
||||||
|
@ -640,7 +688,7 @@ int expr_preprocess()
|
||||||
t = tok;
|
t = tok;
|
||||||
if (t == '(')
|
if (t == '(')
|
||||||
next_nomacro();
|
next_nomacro();
|
||||||
c = sym_find1(define_stack, tok) != 0;
|
c = sym_find1(&define_stack, tok) != 0;
|
||||||
if (t == '(')
|
if (t == '(')
|
||||||
next_nomacro();
|
next_nomacro();
|
||||||
tok = TOK_NUM;
|
tok = TOK_NUM;
|
||||||
|
@ -748,7 +796,7 @@ void preprocess()
|
||||||
s->next = first;
|
s->next = first;
|
||||||
} else if (tok == TOK_UNDEF) {
|
} else if (tok == TOK_UNDEF) {
|
||||||
next_nomacro();
|
next_nomacro();
|
||||||
s = sym_find1(define_stack, tok);
|
s = sym_find1(&define_stack, tok);
|
||||||
/* undefine symbol by putting an invalid name */
|
/* undefine symbol by putting an invalid name */
|
||||||
if (s)
|
if (s)
|
||||||
s->v = 0;
|
s->v = 0;
|
||||||
|
@ -823,7 +871,7 @@ void preprocess()
|
||||||
c = 0;
|
c = 0;
|
||||||
do_ifdef:
|
do_ifdef:
|
||||||
next_nomacro();
|
next_nomacro();
|
||||||
c = (sym_find1(define_stack, tok) != 0) ^ c;
|
c = (sym_find1(&define_stack, tok) != 0) ^ c;
|
||||||
do_if:
|
do_if:
|
||||||
if (ifdef_stack_ptr >= ifdef_stack + IFDEF_STACK_SIZE)
|
if (ifdef_stack_ptr >= ifdef_stack + IFDEF_STACK_SIZE)
|
||||||
error("memory full");
|
error("memory full");
|
||||||
|
@ -1094,7 +1142,7 @@ int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
|
||||||
t = *macro_str++;
|
t = *macro_str++;
|
||||||
if (!t)
|
if (!t)
|
||||||
break;
|
break;
|
||||||
s = sym_find1(args, t);
|
s = sym_find2(args, t);
|
||||||
if (s) {
|
if (s) {
|
||||||
token_buf[0] = '\0';
|
token_buf[0] = '\0';
|
||||||
st = (int *)s->c;
|
st = (int *)s->c;
|
||||||
|
@ -1122,7 +1170,7 @@ int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
|
||||||
} else if (t == TOK_NUM || t == TOK_CCHAR || t == TOK_STR) {
|
} else if (t == TOK_NUM || t == TOK_CCHAR || t == TOK_STR) {
|
||||||
tok_add2(&str, &len, t, *macro_ptr++);
|
tok_add2(&str, &len, t, *macro_ptr++);
|
||||||
} else {
|
} else {
|
||||||
s = sym_find1(args, t);
|
s = sym_find2(args, t);
|
||||||
if (s) {
|
if (s) {
|
||||||
st = (int *)s->c;
|
st = (int *)s->c;
|
||||||
/* if '##' is present before or after , no arg substitution */
|
/* if '##' is present before or after , no arg substitution */
|
||||||
|
@ -1199,7 +1247,7 @@ int *macro_twosharps(int *macro_str)
|
||||||
void macro_subst(int **tok_str, int *tok_len,
|
void macro_subst(int **tok_str, int *tok_len,
|
||||||
Sym **nested_list, int *macro_str)
|
Sym **nested_list, int *macro_str)
|
||||||
{
|
{
|
||||||
Sym *s, *args, *sa;
|
Sym *s, *args, *sa, *sa1;
|
||||||
int *str, parlevel, len, *mstr, t, *saved_macro_ptr;
|
int *str, parlevel, len, *mstr, t, *saved_macro_ptr;
|
||||||
int mstr_allocated, *macro_str1;
|
int mstr_allocated, *macro_str1;
|
||||||
|
|
||||||
|
@ -1228,10 +1276,10 @@ void macro_subst(int **tok_str, int *tok_len,
|
||||||
} else if (tok == TOK___TIME__) {
|
} else if (tok == TOK___TIME__) {
|
||||||
tok_add2(tok_str, tok_len, TOK_STR,
|
tok_add2(tok_str, tok_len, TOK_STR,
|
||||||
(int)tok_alloc("00:00:00", 0));
|
(int)tok_alloc("00:00:00", 0));
|
||||||
} else if ((s = sym_find1(define_stack, tok)) != NULL) {
|
} else if ((s = sym_find1(&define_stack, tok)) != NULL) {
|
||||||
/* if symbol is a macro, prepare substitution */
|
/* if symbol is a macro, prepare substitution */
|
||||||
/* if nested substitution, do nothing */
|
/* if nested substitution, do nothing */
|
||||||
if (sym_find1(*nested_list, tok))
|
if (sym_find2(*nested_list, tok))
|
||||||
goto no_subst;
|
goto no_subst;
|
||||||
mstr = (int *)s->c;
|
mstr = (int *)s->c;
|
||||||
mstr_allocated = 0;
|
mstr_allocated = 0;
|
||||||
|
@ -1270,7 +1318,7 @@ void macro_subst(int **tok_str, int *tok_len,
|
||||||
next_nomacro();
|
next_nomacro();
|
||||||
}
|
}
|
||||||
tok_add(&str, &len, 0);
|
tok_add(&str, &len, 0);
|
||||||
sym_push1(&args, sa->v & ~SYM_FIELD, 0, (int)str);
|
sym_push2(&args, sa->v & ~SYM_FIELD, 0, (int)str);
|
||||||
if (tok != ',')
|
if (tok != ',')
|
||||||
break;
|
break;
|
||||||
next_nomacro();
|
next_nomacro();
|
||||||
|
@ -1283,15 +1331,19 @@ void macro_subst(int **tok_str, int *tok_len,
|
||||||
/* free memory */
|
/* free memory */
|
||||||
sa = args;
|
sa = args;
|
||||||
while (sa) {
|
while (sa) {
|
||||||
|
sa1 = sa->prev;
|
||||||
free((int *)sa->c);
|
free((int *)sa->c);
|
||||||
sa = sa->prev;
|
free(sa);
|
||||||
|
sa = sa1;
|
||||||
}
|
}
|
||||||
sym_pop(&args, NULL);
|
|
||||||
mstr_allocated = 1;
|
mstr_allocated = 1;
|
||||||
}
|
}
|
||||||
sym_push1(nested_list, s->v, 0, 0);
|
sym_push2(nested_list, s->v, 0, 0);
|
||||||
macro_subst(tok_str, tok_len, nested_list, mstr);
|
macro_subst(tok_str, tok_len, nested_list, mstr);
|
||||||
sym_pop(nested_list, (*nested_list)->prev);
|
/* pop nested defined symbol */
|
||||||
|
sa1 = *nested_list;
|
||||||
|
*nested_list = sa1->prev;
|
||||||
|
free(sa1);
|
||||||
if (mstr_allocated)
|
if (mstr_allocated)
|
||||||
free(mstr);
|
free(mstr);
|
||||||
} else {
|
} else {
|
||||||
|
@ -2425,7 +2477,7 @@ void unary()
|
||||||
#ifdef INVERT_FUNC_PARAMS
|
#ifdef INVERT_FUNC_PARAMS
|
||||||
{
|
{
|
||||||
int *str, len, parlevel, *saved_macro_ptr;
|
int *str, len, parlevel, *saved_macro_ptr;
|
||||||
Sym *args;
|
Sym *args, *s1;
|
||||||
|
|
||||||
/* read each argument and store it on a stack */
|
/* read each argument and store it on a stack */
|
||||||
/* XXX: merge it with macro args ? */
|
/* XXX: merge it with macro args ? */
|
||||||
|
@ -2445,7 +2497,7 @@ void unary()
|
||||||
}
|
}
|
||||||
tok_add(&str, &len, -1); /* end of file added */
|
tok_add(&str, &len, -1); /* end of file added */
|
||||||
tok_add(&str, &len, 0);
|
tok_add(&str, &len, 0);
|
||||||
sym_push1(&args, 0, 0, (int)str);
|
sym_push2(&args, 0, 0, (int)str);
|
||||||
if (tok != ',')
|
if (tok != ',')
|
||||||
break;
|
break;
|
||||||
next();
|
next();
|
||||||
|
@ -2462,8 +2514,10 @@ void unary()
|
||||||
next();
|
next();
|
||||||
expr_eq();
|
expr_eq();
|
||||||
gfunc_param();
|
gfunc_param();
|
||||||
|
s1 = args->prev;
|
||||||
free((int *)args->c);
|
free((int *)args->c);
|
||||||
sym_pop(&args, args->prev);
|
free(args);
|
||||||
|
args = s1;
|
||||||
}
|
}
|
||||||
macro_ptr = saved_macro_ptr;
|
macro_ptr = saved_macro_ptr;
|
||||||
/* restore token */
|
/* restore token */
|
||||||
|
@ -2692,7 +2746,7 @@ void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg)
|
||||||
} else if (tok == '{') {
|
} else if (tok == '{') {
|
||||||
next();
|
next();
|
||||||
/* declarations */
|
/* declarations */
|
||||||
s = local_stack;
|
s = local_stack.top;
|
||||||
while (tok != '}') {
|
while (tok != '}') {
|
||||||
decl(VT_LOCAL);
|
decl(VT_LOCAL);
|
||||||
block(bsym, csym, case_sym, def_sym, case_reg);
|
block(bsym, csym, case_sym, def_sym, case_reg);
|
||||||
|
@ -2810,7 +2864,7 @@ void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg)
|
||||||
} else
|
} else
|
||||||
if (tok == TOK_GOTO) {
|
if (tok == TOK_GOTO) {
|
||||||
next();
|
next();
|
||||||
s = sym_find1(label_stack, tok);
|
s = sym_find1(&label_stack, tok);
|
||||||
/* put forward definition if needed */
|
/* put forward definition if needed */
|
||||||
if (!s)
|
if (!s)
|
||||||
s = sym_push1(&label_stack, tok, VT_FORWARD, 0);
|
s = sym_push1(&label_stack, tok, VT_FORWARD, 0);
|
||||||
|
@ -2827,7 +2881,7 @@ void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg)
|
||||||
if (tok == ':') {
|
if (tok == ':') {
|
||||||
next();
|
next();
|
||||||
/* label case */
|
/* label case */
|
||||||
s = sym_find1(label_stack, b);
|
s = sym_find1(&label_stack, b);
|
||||||
if (s) {
|
if (s) {
|
||||||
if (!(s->t & VT_FORWARD))
|
if (!(s->t & VT_FORWARD))
|
||||||
error("multiple defined label");
|
error("multiple defined label");
|
||||||
|
@ -2988,7 +3042,6 @@ void decl_assign(int t, int c, int first)
|
||||||
} else {
|
} else {
|
||||||
if ((t & VT_VALMASK) == VT_CONST) {
|
if ((t & VT_VALMASK) == VT_CONST) {
|
||||||
v = expr_const();
|
v = expr_const();
|
||||||
printf("v=%d\n", v);
|
|
||||||
if (t & VT_BYTE)
|
if (t & VT_BYTE)
|
||||||
*(char *)c = v;
|
*(char *)c = v;
|
||||||
else if (t & VT_SHORT)
|
else if (t & VT_SHORT)
|
||||||
|
@ -3135,11 +3188,20 @@ void open_dll(char *libname)
|
||||||
error((char *)dlerror());
|
error((char *)dlerror());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* output a binary file (for testing) */
|
||||||
|
void build_exe(char *filename)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
f = fopen(filename, "w");
|
||||||
|
fwrite((void *)prog, 1, ind - prog, f);
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
Sym *s;
|
Sym *s;
|
||||||
int (*t)();
|
int (*t)();
|
||||||
char *p, *r;
|
char *p, *r, *outfile;
|
||||||
int optind;
|
int optind;
|
||||||
|
|
||||||
include_paths[0] = "/usr/include";
|
include_paths[0] = "/usr/include";
|
||||||
|
@ -3148,6 +3210,7 @@ int main(int argc, char **argv)
|
||||||
nb_include_paths = 3;
|
nb_include_paths = 3;
|
||||||
|
|
||||||
/* add all tokens */
|
/* add all tokens */
|
||||||
|
tok_ident = TOK_IDENT;
|
||||||
p = "int\0void\0char\0if\0else\0while\0break\0return\0for\0extern\0static\0unsigned\0goto\0do\0continue\0switch\0case\0const\0volatile\0long\0register\0signed\0auto\0inline\0restrict\0float\0double\0short\0struct\0union\0typedef\0default\0enum\0sizeof\0define\0include\0ifdef\0ifndef\0elif\0endif\0defined\0undef\0error\0line\0__LINE__\0__FILE__\0__DATE__\0__TIME__\0__VA_ARGS__\0__func__\0main\0";
|
p = "int\0void\0char\0if\0else\0while\0break\0return\0for\0extern\0static\0unsigned\0goto\0do\0continue\0switch\0case\0const\0volatile\0long\0register\0signed\0auto\0inline\0restrict\0float\0double\0short\0struct\0union\0typedef\0default\0enum\0sizeof\0define\0include\0ifdef\0ifndef\0elif\0endif\0defined\0undef\0error\0line\0__LINE__\0__FILE__\0__DATE__\0__TIME__\0__VA_ARGS__\0__func__\0main\0";
|
||||||
while (*p) {
|
while (*p) {
|
||||||
r = p;
|
r = p;
|
||||||
|
@ -3163,8 +3226,10 @@ int main(int argc, char **argv)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
optind = 1;
|
optind = 1;
|
||||||
|
outfile = NULL;
|
||||||
while (1) {
|
while (1) {
|
||||||
if (optind >= argc) {
|
if (optind >= argc) {
|
||||||
|
show_help:
|
||||||
printf("tcc version 0.9 - Tiny C Compiler - Copyright (C) 2001 Fabrice Bellard\n"
|
printf("tcc version 0.9 - Tiny C Compiler - Copyright (C) 2001 Fabrice Bellard\n"
|
||||||
"usage: tcc [-Idir] [-Dsym] [-llib] infile [infile_arg...]\n");
|
"usage: tcc [-Idir] [-Dsym] [-llib] infile [infile_arg...]\n");
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -3172,6 +3237,7 @@ int main(int argc, char **argv)
|
||||||
r = argv[optind];
|
r = argv[optind];
|
||||||
if (r[0] != '-')
|
if (r[0] != '-')
|
||||||
break;
|
break;
|
||||||
|
optind++;
|
||||||
if (r[1] == 'I') {
|
if (r[1] == 'I') {
|
||||||
if (nb_include_paths >= INCLUDE_PATHS_MAX)
|
if (nb_include_paths >= INCLUDE_PATHS_MAX)
|
||||||
error("too many include paths");
|
error("too many include paths");
|
||||||
|
@ -3180,11 +3246,15 @@ int main(int argc, char **argv)
|
||||||
define_symbol(r + 2);
|
define_symbol(r + 2);
|
||||||
} else if (r[1] == 'l') {
|
} else if (r[1] == 'l') {
|
||||||
open_dll(r + 2);
|
open_dll(r + 2);
|
||||||
|
} else if (r[1] == 'o') {
|
||||||
|
/* currently, only for testing, so not documented */
|
||||||
|
if (optind >= argc)
|
||||||
|
goto show_help;
|
||||||
|
outfile = argv[optind++];
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "invalid option -- '%s'\n", r);
|
fprintf(stderr, "invalid option -- '%s'\n", r);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
optind++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
filename = argv[optind];
|
filename = argv[optind];
|
||||||
|
@ -3210,23 +3280,18 @@ int main(int argc, char **argv)
|
||||||
decl(VT_CONST);
|
decl(VT_CONST);
|
||||||
if (tok != -1)
|
if (tok != -1)
|
||||||
expect("declaration");
|
expect("declaration");
|
||||||
#ifdef TEST
|
if (outfile) {
|
||||||
{
|
build_exe(outfile);
|
||||||
FILE *f;
|
|
||||||
f = fopen(argv[optind + 1], "w");
|
|
||||||
fwrite((void *)prog, 1, ind - prog, f);
|
|
||||||
fclose(f);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
} else {
|
||||||
#else
|
s = sym_find(TOK_MAIN);
|
||||||
s = sym_find(TOK_MAIN);
|
if (!s)
|
||||||
if (!s)
|
error("main() not defined");
|
||||||
error("main() not defined");
|
t = (int (*)())s->c;
|
||||||
t = (int (*)())s->c;
|
|
||||||
#ifdef PROFILE
|
#ifdef PROFILE
|
||||||
return 1;
|
return 1;
|
||||||
#else
|
#else
|
||||||
return (*t)(argc - optind, argv + optind);
|
return (*t)(argc - optind, argv + optind);
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue