mirror of
https://github.com/mirror/tinycc.git
synced 2025-02-26 08:00:09 +08:00
move minor things from libtcc.c to other files
This commit is contained in:
parent
92204e8818
commit
b8f6e1ae30
278
libtcc.c
278
libtcc.c
@ -92,8 +92,6 @@ static int nb_sym_pools;
|
||||
static SValue vstack[VSTACK_SIZE], *vtop;
|
||||
/* some predefined types */
|
||||
static CType char_pointer_type, func_old_type, int_type;
|
||||
/* true if isid(c) || isnum(c) */
|
||||
static unsigned char isidnum_table[256-CH_EOF];
|
||||
|
||||
/* display some information during compilation */
|
||||
static int verbose = 0;
|
||||
@ -105,9 +103,6 @@ static int do_debug = 0;
|
||||
static int do_bounds_check = 0;
|
||||
|
||||
/* display benchmark infos */
|
||||
#if !defined(LIBTCC)
|
||||
static int do_bench = 0;
|
||||
#endif
|
||||
static int total_lines;
|
||||
static int total_bytes;
|
||||
|
||||
@ -251,34 +246,6 @@ static char *pstrcat(char *buf, int buf_size, const char *s)
|
||||
return buf;
|
||||
}
|
||||
|
||||
#ifndef LIBTCC
|
||||
static int strstart(const char *str, const char *val, const char **ptr)
|
||||
{
|
||||
const char *p, *q;
|
||||
p = str;
|
||||
q = val;
|
||||
while (*q != '\0') {
|
||||
if (*p != *q)
|
||||
return 0;
|
||||
p++;
|
||||
q++;
|
||||
}
|
||||
if (ptr)
|
||||
*ptr = p;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define IS_PATHSEP(c) (c == '/' || c == '\\')
|
||||
#define IS_ABSPATH(p) (IS_PATHSEP(p[0]) || (p[0] && p[1] == ':' && IS_PATHSEP(p[2])))
|
||||
#define PATHCMP stricmp
|
||||
#else
|
||||
#define IS_PATHSEP(c) (c == '/')
|
||||
#define IS_ABSPATH(p) IS_PATHSEP(p[0])
|
||||
#define PATHCMP strcmp
|
||||
#endif
|
||||
|
||||
/* extract the basename of a file */
|
||||
static char *tcc_basename(const char *name)
|
||||
{
|
||||
@ -556,8 +523,6 @@ Section *find_section(TCCState *s1, const char *name)
|
||||
return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
|
||||
}
|
||||
|
||||
#define SECTION_ABS ((void *)1)
|
||||
|
||||
/* update sym->c so that it points to an external symbol in section
|
||||
'section' with value 'value' */
|
||||
static void put_extern_sym2(Sym *sym, Section *section,
|
||||
@ -809,66 +774,6 @@ static void test_lvalue(void)
|
||||
expect("lvalue");
|
||||
}
|
||||
|
||||
/* allocate a new token */
|
||||
static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len)
|
||||
{
|
||||
TokenSym *ts, **ptable;
|
||||
int i;
|
||||
|
||||
if (tok_ident >= SYM_FIRST_ANOM)
|
||||
error("memory full");
|
||||
|
||||
/* expand token table if needed */
|
||||
i = tok_ident - TOK_IDENT;
|
||||
if ((i % TOK_ALLOC_INCR) == 0) {
|
||||
ptable = tcc_realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *));
|
||||
if (!ptable)
|
||||
error("memory full");
|
||||
table_ident = ptable;
|
||||
}
|
||||
|
||||
ts = tcc_malloc(sizeof(TokenSym) + len);
|
||||
table_ident[i] = ts;
|
||||
ts->tok = tok_ident++;
|
||||
ts->sym_define = NULL;
|
||||
ts->sym_label = NULL;
|
||||
ts->sym_struct = NULL;
|
||||
ts->sym_identifier = NULL;
|
||||
ts->len = len;
|
||||
ts->hash_next = NULL;
|
||||
memcpy(ts->str, str, len);
|
||||
ts->str[len] = '\0';
|
||||
*pts = ts;
|
||||
return ts;
|
||||
}
|
||||
|
||||
#define TOK_HASH_INIT 1
|
||||
#define TOK_HASH_FUNC(h, c) ((h) * 263 + (c))
|
||||
|
||||
/* find a token and add it if not found */
|
||||
static TokenSym *tok_alloc(const char *str, int len)
|
||||
{
|
||||
TokenSym *ts, **pts;
|
||||
int i;
|
||||
unsigned int h;
|
||||
|
||||
h = TOK_HASH_INIT;
|
||||
for(i=0;i<len;i++)
|
||||
h = TOK_HASH_FUNC(h, ((unsigned char *)str)[i]);
|
||||
h &= (TOK_HASH_SIZE - 1);
|
||||
|
||||
pts = &hash_ident[h];
|
||||
for(;;) {
|
||||
ts = *pts;
|
||||
if (!ts)
|
||||
break;
|
||||
if (ts->len == len && !memcmp(ts->str, str, len))
|
||||
return ts;
|
||||
pts = &(ts->hash_next);
|
||||
}
|
||||
return tok_alloc_new(pts, str, len);
|
||||
}
|
||||
|
||||
/* CString handling */
|
||||
|
||||
static void cstr_realloc(CString *cstr, int new_size)
|
||||
@ -958,108 +863,6 @@ static void add_char(CString *cstr, int c)
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX: buffer overflow */
|
||||
/* XXX: float tokens */
|
||||
char *get_tok_str(int v, CValue *cv)
|
||||
{
|
||||
static char buf[STRING_MAX_SIZE + 1];
|
||||
static CString cstr_buf;
|
||||
CString *cstr;
|
||||
unsigned char *q;
|
||||
char *p;
|
||||
int i, len;
|
||||
|
||||
/* NOTE: to go faster, we give a fixed buffer for small strings */
|
||||
cstr_reset(&cstr_buf);
|
||||
cstr_buf.data = buf;
|
||||
cstr_buf.size_allocated = sizeof(buf);
|
||||
p = buf;
|
||||
|
||||
switch(v) {
|
||||
case TOK_CINT:
|
||||
case TOK_CUINT:
|
||||
/* XXX: not quite exact, but only useful for testing */
|
||||
sprintf(p, "%u", cv->ui);
|
||||
break;
|
||||
case TOK_CLLONG:
|
||||
case TOK_CULLONG:
|
||||
/* XXX: not quite exact, but only useful for testing */
|
||||
sprintf(p, "%Lu", cv->ull);
|
||||
break;
|
||||
case TOK_LCHAR:
|
||||
cstr_ccat(&cstr_buf, 'L');
|
||||
case TOK_CCHAR:
|
||||
cstr_ccat(&cstr_buf, '\'');
|
||||
add_char(&cstr_buf, cv->i);
|
||||
cstr_ccat(&cstr_buf, '\'');
|
||||
cstr_ccat(&cstr_buf, '\0');
|
||||
break;
|
||||
case TOK_PPNUM:
|
||||
cstr = cv->cstr;
|
||||
len = cstr->size - 1;
|
||||
for(i=0;i<len;i++)
|
||||
add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
|
||||
cstr_ccat(&cstr_buf, '\0');
|
||||
break;
|
||||
case TOK_LSTR:
|
||||
cstr_ccat(&cstr_buf, 'L');
|
||||
case TOK_STR:
|
||||
cstr = cv->cstr;
|
||||
cstr_ccat(&cstr_buf, '\"');
|
||||
if (v == TOK_STR) {
|
||||
len = cstr->size - 1;
|
||||
for(i=0;i<len;i++)
|
||||
add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
|
||||
} else {
|
||||
len = (cstr->size / sizeof(nwchar_t)) - 1;
|
||||
for(i=0;i<len;i++)
|
||||
add_char(&cstr_buf, ((nwchar_t *)cstr->data)[i]);
|
||||
}
|
||||
cstr_ccat(&cstr_buf, '\"');
|
||||
cstr_ccat(&cstr_buf, '\0');
|
||||
break;
|
||||
case TOK_LT:
|
||||
v = '<';
|
||||
goto addv;
|
||||
case TOK_GT:
|
||||
v = '>';
|
||||
goto addv;
|
||||
case TOK_DOTS:
|
||||
return strcpy(p, "...");
|
||||
case TOK_A_SHL:
|
||||
return strcpy(p, "<<=");
|
||||
case TOK_A_SAR:
|
||||
return strcpy(p, ">>=");
|
||||
default:
|
||||
if (v < TOK_IDENT) {
|
||||
/* search in two bytes table */
|
||||
q = tok_two_chars;
|
||||
while (*q) {
|
||||
if (q[2] == v) {
|
||||
*p++ = q[0];
|
||||
*p++ = q[1];
|
||||
*p = '\0';
|
||||
return buf;
|
||||
}
|
||||
q += 3;
|
||||
}
|
||||
addv:
|
||||
*p++ = v;
|
||||
*p = '\0';
|
||||
} else if (v < tok_ident) {
|
||||
return table_ident[v - TOK_IDENT]->str;
|
||||
} else if (v >= SYM_FIRST_ANOM) {
|
||||
/* special name for anonymous symbol */
|
||||
sprintf(p, "L.%u", v - SYM_FIRST_ANOM);
|
||||
} else {
|
||||
/* should never happen */
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return cstr_buf.data;
|
||||
}
|
||||
|
||||
/* push, without hashing */
|
||||
static Sym *sym_push2(Sym **ps, int v, int t, long c)
|
||||
{
|
||||
@ -1220,21 +1023,6 @@ void tcc_close(BufferedFile *bf)
|
||||
#include "tccpp.c"
|
||||
#include "tccgen.c"
|
||||
|
||||
/* better than nothing, but needs extension to handle '-E' option
|
||||
correctly too */
|
||||
static void preprocess_init(TCCState *s1)
|
||||
{
|
||||
s1->include_stack_ptr = s1->include_stack;
|
||||
/* XXX: move that before to avoid having to initialize
|
||||
file->ifdef_stack_ptr ? */
|
||||
s1->ifdef_stack_ptr = s1->ifdef_stack;
|
||||
file->ifdef_stack_ptr = s1->ifdef_stack_ptr;
|
||||
|
||||
/* XXX: not ANSI compliant: bound checking says error */
|
||||
vtop = vstack - 1;
|
||||
s1->pack_stack[0] = 0;
|
||||
s1->pack_stack_ptr = s1->pack_stack;
|
||||
}
|
||||
|
||||
/* compile the C file opened in 'file'. Return non zero if errors. */
|
||||
static int tcc_compile(TCCState *s1)
|
||||
@ -1342,48 +1130,6 @@ static int tcc_compile(TCCState *s1)
|
||||
return s1->nb_errors != 0 ? -1 : 0;
|
||||
}
|
||||
|
||||
/* Preprocess the current file */
|
||||
static int tcc_preprocess(TCCState *s1)
|
||||
{
|
||||
Sym *define_start;
|
||||
BufferedFile *file_ref;
|
||||
int token_seen, line_ref;
|
||||
|
||||
preprocess_init(s1);
|
||||
define_start = define_stack;
|
||||
ch = file->buf_ptr[0];
|
||||
tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
|
||||
parse_flags = PARSE_FLAG_ASM_COMMENTS | PARSE_FLAG_PREPROCESS |
|
||||
PARSE_FLAG_LINEFEED | PARSE_FLAG_SPACES;
|
||||
token_seen = 0;
|
||||
line_ref = 0;
|
||||
file_ref = NULL;
|
||||
|
||||
for (;;) {
|
||||
next();
|
||||
if (tok == TOK_EOF) {
|
||||
break;
|
||||
} else if (tok == TOK_LINEFEED) {
|
||||
if (!token_seen)
|
||||
continue;
|
||||
++line_ref;
|
||||
token_seen = 0;
|
||||
} else if (!token_seen) {
|
||||
int d = file->line_num - line_ref;
|
||||
if (file != file_ref || d < 0 || d >= 8)
|
||||
fprintf(s1->outfile, "# %d \"%s\"\n", file->line_num, file->filename);
|
||||
else
|
||||
while (d)
|
||||
fputs("\n", s1->outfile), --d;
|
||||
line_ref = (file_ref = file)->line_num;
|
||||
token_seen = 1;
|
||||
}
|
||||
fputs(get_tok_str(tok, &tokc), s1->outfile);
|
||||
}
|
||||
free_defines(define_start);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef LIBTCC
|
||||
int tcc_compile_string(TCCState *s, const char *str)
|
||||
{
|
||||
@ -1909,10 +1655,7 @@ static void tcc_cleanup(void)
|
||||
|
||||
TCCState *tcc_new(void)
|
||||
{
|
||||
const char *p, *r;
|
||||
TCCState *s;
|
||||
TokenSym *ts;
|
||||
int i, c;
|
||||
|
||||
tcc_cleanup();
|
||||
|
||||
@ -1922,26 +1665,7 @@ TCCState *tcc_new(void)
|
||||
tcc_state = s;
|
||||
s->output_type = TCC_OUTPUT_MEMORY;
|
||||
|
||||
/* init isid table */
|
||||
for(i=CH_EOF;i<256;i++)
|
||||
isidnum_table[i-CH_EOF] = isid(i) || isnum(i);
|
||||
|
||||
/* add all tokens */
|
||||
table_ident = NULL;
|
||||
memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *));
|
||||
|
||||
tok_ident = TOK_IDENT;
|
||||
p = tcc_keywords;
|
||||
while (*p) {
|
||||
r = p;
|
||||
for(;;) {
|
||||
c = *r++;
|
||||
if (c == '\0')
|
||||
break;
|
||||
}
|
||||
ts = tok_alloc(p, r - p - 1);
|
||||
p = r;
|
||||
}
|
||||
preprocess_new();
|
||||
|
||||
/* we add dummy defines for some special macros to speed up tests
|
||||
and to have working defined() */
|
||||
|
59
tcc.c
59
tcc.c
@ -22,19 +22,6 @@
|
||||
|
||||
#if !defined(LIBTCC)
|
||||
|
||||
static int64_t getclock_us(void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
struct _timeb tb;
|
||||
_ftime(&tb);
|
||||
return (tb.time * 1000LL + tb.millitm) * 1000LL;
|
||||
#else
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
return tv.tv_sec * 1000000LL + tv.tv_usec;
|
||||
#endif
|
||||
}
|
||||
|
||||
void help(void)
|
||||
{
|
||||
printf("tcc version " TCC_VERSION " - Tiny C Compiler - Copyright (C) 2001-2006 Fabrice Bellard\n"
|
||||
@ -76,6 +63,15 @@ void help(void)
|
||||
);
|
||||
}
|
||||
|
||||
static char **files;
|
||||
static int nb_files, nb_libraries;
|
||||
static int multiple_files;
|
||||
static int print_search_dirs;
|
||||
static int output_type;
|
||||
static int reloc_output;
|
||||
static const char *outfile;
|
||||
static int do_bench = 0;
|
||||
|
||||
#define TCC_OPTION_HAS_ARG 0x0001
|
||||
#define TCC_OPTION_NOSEP 0x0002 /* cannot have space before option and arg */
|
||||
|
||||
@ -157,6 +153,35 @@ static const TCCOption tcc_options[] = {
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
static int64_t getclock_us(void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
struct _timeb tb;
|
||||
_ftime(&tb);
|
||||
return (tb.time * 1000LL + tb.millitm) * 1000LL;
|
||||
#else
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
return tv.tv_sec * 1000000LL + tv.tv_usec;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int strstart(const char *str, const char *val, const char **ptr)
|
||||
{
|
||||
const char *p, *q;
|
||||
p = str;
|
||||
q = val;
|
||||
while (*q != '\0') {
|
||||
if (*p != *q)
|
||||
return 0;
|
||||
p++;
|
||||
q++;
|
||||
}
|
||||
if (ptr)
|
||||
*ptr = p;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* convert 'str' into an array of space separated strings */
|
||||
static int expand_args(char ***pargv, const char *str)
|
||||
{
|
||||
@ -184,14 +209,6 @@ static int expand_args(char ***pargv, const char *str)
|
||||
return argc;
|
||||
}
|
||||
|
||||
static char **files;
|
||||
static int nb_files, nb_libraries;
|
||||
static int multiple_files;
|
||||
static int print_search_dirs;
|
||||
static int output_type;
|
||||
static int reloc_output;
|
||||
static const char *outfile;
|
||||
|
||||
int parse_args(TCCState *s, int argc, char **argv)
|
||||
{
|
||||
int optind;
|
||||
|
22
tcc.h
22
tcc.h
@ -210,6 +210,9 @@ typedef struct Sym {
|
||||
the other ones */
|
||||
#define SHF_PRIVATE 0x80000000
|
||||
|
||||
/* special flag, too */
|
||||
#define SECTION_ABS ((void *)1)
|
||||
|
||||
typedef struct Section {
|
||||
unsigned long data_offset; /* current data offset */
|
||||
unsigned char *data; /* section data */
|
||||
@ -580,9 +583,6 @@ struct TCCState {
|
||||
#define countof(tab) (sizeof(tab) / sizeof((tab)[0]))
|
||||
#endif
|
||||
|
||||
/* WARNING: the content of this string encodes token numbers */
|
||||
static char tok_two_chars[] = "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266";
|
||||
|
||||
#define TOK_EOF (-1) /* end of file */
|
||||
#define TOK_LINEFEED 10 /* line feed */
|
||||
|
||||
@ -655,12 +655,6 @@ enum tcc_token {
|
||||
#undef DEF
|
||||
};
|
||||
|
||||
static const char tcc_keywords[] =
|
||||
#define DEF(id, str) str "\0"
|
||||
#include "tcctok.h"
|
||||
#undef DEF
|
||||
;
|
||||
|
||||
#define TOK_UIDENT TOK_DEFINE
|
||||
|
||||
#ifdef _WIN32
|
||||
@ -688,6 +682,16 @@ extern float strtof (const char *__nptr, char **__endptr);
|
||||
extern long double strtold (const char *__nptr, char **__endptr);
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define IS_PATHSEP(c) (c == '/' || c == '\\')
|
||||
#define IS_ABSPATH(p) (IS_PATHSEP(p[0]) || (p[0] && p[1] == ':' && IS_PATHSEP(p[2])))
|
||||
#define PATHCMP stricmp
|
||||
#else
|
||||
#define IS_PATHSEP(c) (c == '/')
|
||||
#define IS_ABSPATH(p) IS_PATHSEP(p[0])
|
||||
#define PATHCMP strcmp
|
||||
#endif
|
||||
|
||||
static char *pstrcpy(char *buf, int buf_size, const char *s);
|
||||
static char *pstrcat(char *buf, int buf_size, const char *s);
|
||||
static char *tcc_basename(const char *name);
|
||||
|
262
tccpp.c
262
tccpp.c
@ -18,6 +18,182 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
static const char tcc_keywords[] =
|
||||
#define DEF(id, str) str "\0"
|
||||
#include "tcctok.h"
|
||||
#undef DEF
|
||||
;
|
||||
|
||||
/* WARNING: the content of this string encodes token numbers */
|
||||
static char tok_two_chars[] = "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266";
|
||||
|
||||
/* true if isid(c) || isnum(c) */
|
||||
static unsigned char isidnum_table[256-CH_EOF];
|
||||
|
||||
|
||||
/* allocate a new token */
|
||||
static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len)
|
||||
{
|
||||
TokenSym *ts, **ptable;
|
||||
int i;
|
||||
|
||||
if (tok_ident >= SYM_FIRST_ANOM)
|
||||
error("memory full");
|
||||
|
||||
/* expand token table if needed */
|
||||
i = tok_ident - TOK_IDENT;
|
||||
if ((i % TOK_ALLOC_INCR) == 0) {
|
||||
ptable = tcc_realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *));
|
||||
if (!ptable)
|
||||
error("memory full");
|
||||
table_ident = ptable;
|
||||
}
|
||||
|
||||
ts = tcc_malloc(sizeof(TokenSym) + len);
|
||||
table_ident[i] = ts;
|
||||
ts->tok = tok_ident++;
|
||||
ts->sym_define = NULL;
|
||||
ts->sym_label = NULL;
|
||||
ts->sym_struct = NULL;
|
||||
ts->sym_identifier = NULL;
|
||||
ts->len = len;
|
||||
ts->hash_next = NULL;
|
||||
memcpy(ts->str, str, len);
|
||||
ts->str[len] = '\0';
|
||||
*pts = ts;
|
||||
return ts;
|
||||
}
|
||||
|
||||
#define TOK_HASH_INIT 1
|
||||
#define TOK_HASH_FUNC(h, c) ((h) * 263 + (c))
|
||||
|
||||
/* find a token and add it if not found */
|
||||
static TokenSym *tok_alloc(const char *str, int len)
|
||||
{
|
||||
TokenSym *ts, **pts;
|
||||
int i;
|
||||
unsigned int h;
|
||||
|
||||
h = TOK_HASH_INIT;
|
||||
for(i=0;i<len;i++)
|
||||
h = TOK_HASH_FUNC(h, ((unsigned char *)str)[i]);
|
||||
h &= (TOK_HASH_SIZE - 1);
|
||||
|
||||
pts = &hash_ident[h];
|
||||
for(;;) {
|
||||
ts = *pts;
|
||||
if (!ts)
|
||||
break;
|
||||
if (ts->len == len && !memcmp(ts->str, str, len))
|
||||
return ts;
|
||||
pts = &(ts->hash_next);
|
||||
}
|
||||
return tok_alloc_new(pts, str, len);
|
||||
}
|
||||
|
||||
/* XXX: buffer overflow */
|
||||
/* XXX: float tokens */
|
||||
char *get_tok_str(int v, CValue *cv)
|
||||
{
|
||||
static char buf[STRING_MAX_SIZE + 1];
|
||||
static CString cstr_buf;
|
||||
CString *cstr;
|
||||
unsigned char *q;
|
||||
char *p;
|
||||
int i, len;
|
||||
|
||||
/* NOTE: to go faster, we give a fixed buffer for small strings */
|
||||
cstr_reset(&cstr_buf);
|
||||
cstr_buf.data = buf;
|
||||
cstr_buf.size_allocated = sizeof(buf);
|
||||
p = buf;
|
||||
|
||||
switch(v) {
|
||||
case TOK_CINT:
|
||||
case TOK_CUINT:
|
||||
/* XXX: not quite exact, but only useful for testing */
|
||||
sprintf(p, "%u", cv->ui);
|
||||
break;
|
||||
case TOK_CLLONG:
|
||||
case TOK_CULLONG:
|
||||
/* XXX: not quite exact, but only useful for testing */
|
||||
sprintf(p, "%Lu", cv->ull);
|
||||
break;
|
||||
case TOK_LCHAR:
|
||||
cstr_ccat(&cstr_buf, 'L');
|
||||
case TOK_CCHAR:
|
||||
cstr_ccat(&cstr_buf, '\'');
|
||||
add_char(&cstr_buf, cv->i);
|
||||
cstr_ccat(&cstr_buf, '\'');
|
||||
cstr_ccat(&cstr_buf, '\0');
|
||||
break;
|
||||
case TOK_PPNUM:
|
||||
cstr = cv->cstr;
|
||||
len = cstr->size - 1;
|
||||
for(i=0;i<len;i++)
|
||||
add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
|
||||
cstr_ccat(&cstr_buf, '\0');
|
||||
break;
|
||||
case TOK_LSTR:
|
||||
cstr_ccat(&cstr_buf, 'L');
|
||||
case TOK_STR:
|
||||
cstr = cv->cstr;
|
||||
cstr_ccat(&cstr_buf, '\"');
|
||||
if (v == TOK_STR) {
|
||||
len = cstr->size - 1;
|
||||
for(i=0;i<len;i++)
|
||||
add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
|
||||
} else {
|
||||
len = (cstr->size / sizeof(nwchar_t)) - 1;
|
||||
for(i=0;i<len;i++)
|
||||
add_char(&cstr_buf, ((nwchar_t *)cstr->data)[i]);
|
||||
}
|
||||
cstr_ccat(&cstr_buf, '\"');
|
||||
cstr_ccat(&cstr_buf, '\0');
|
||||
break;
|
||||
case TOK_LT:
|
||||
v = '<';
|
||||
goto addv;
|
||||
case TOK_GT:
|
||||
v = '>';
|
||||
goto addv;
|
||||
case TOK_DOTS:
|
||||
return strcpy(p, "...");
|
||||
case TOK_A_SHL:
|
||||
return strcpy(p, "<<=");
|
||||
case TOK_A_SAR:
|
||||
return strcpy(p, ">>=");
|
||||
default:
|
||||
if (v < TOK_IDENT) {
|
||||
/* search in two bytes table */
|
||||
q = tok_two_chars;
|
||||
while (*q) {
|
||||
if (q[2] == v) {
|
||||
*p++ = q[0];
|
||||
*p++ = q[1];
|
||||
*p = '\0';
|
||||
return buf;
|
||||
}
|
||||
q += 3;
|
||||
}
|
||||
addv:
|
||||
*p++ = v;
|
||||
*p = '\0';
|
||||
} else if (v < tok_ident) {
|
||||
return table_ident[v - TOK_IDENT]->str;
|
||||
} else if (v >= SYM_FIRST_ANOM) {
|
||||
/* special name for anonymous symbol */
|
||||
sprintf(p, "L.%u", v - SYM_FIRST_ANOM);
|
||||
} else {
|
||||
/* should never happen */
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return cstr_buf.data;
|
||||
}
|
||||
|
||||
/* fill input buffer and peek next char */
|
||||
static int tcc_peekc_slow(BufferedFile *bf)
|
||||
{
|
||||
@ -2661,3 +2837,89 @@ static inline void unget_tok(int last_tok)
|
||||
}
|
||||
|
||||
|
||||
/* better than nothing, but needs extension to handle '-E' option
|
||||
correctly too */
|
||||
static void preprocess_init(TCCState *s1)
|
||||
{
|
||||
s1->include_stack_ptr = s1->include_stack;
|
||||
/* XXX: move that before to avoid having to initialize
|
||||
file->ifdef_stack_ptr ? */
|
||||
s1->ifdef_stack_ptr = s1->ifdef_stack;
|
||||
file->ifdef_stack_ptr = s1->ifdef_stack_ptr;
|
||||
|
||||
/* XXX: not ANSI compliant: bound checking says error */
|
||||
vtop = vstack - 1;
|
||||
s1->pack_stack[0] = 0;
|
||||
s1->pack_stack_ptr = s1->pack_stack;
|
||||
}
|
||||
|
||||
void preprocess_new()
|
||||
{
|
||||
int i, c;
|
||||
const char *p, *r;
|
||||
TokenSym *ts;
|
||||
|
||||
/* init isid table */
|
||||
for(i=CH_EOF;i<256;i++)
|
||||
isidnum_table[i-CH_EOF] = isid(i) || isnum(i);
|
||||
|
||||
/* add all tokens */
|
||||
table_ident = NULL;
|
||||
memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *));
|
||||
|
||||
tok_ident = TOK_IDENT;
|
||||
p = tcc_keywords;
|
||||
while (*p) {
|
||||
r = p;
|
||||
for(;;) {
|
||||
c = *r++;
|
||||
if (c == '\0')
|
||||
break;
|
||||
}
|
||||
ts = tok_alloc(p, r - p - 1);
|
||||
p = r;
|
||||
}
|
||||
}
|
||||
|
||||
/* Preprocess the current file */
|
||||
static int tcc_preprocess(TCCState *s1)
|
||||
{
|
||||
Sym *define_start;
|
||||
BufferedFile *file_ref;
|
||||
int token_seen, line_ref;
|
||||
|
||||
preprocess_init(s1);
|
||||
define_start = define_stack;
|
||||
ch = file->buf_ptr[0];
|
||||
tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
|
||||
parse_flags = PARSE_FLAG_ASM_COMMENTS | PARSE_FLAG_PREPROCESS |
|
||||
PARSE_FLAG_LINEFEED | PARSE_FLAG_SPACES;
|
||||
token_seen = 0;
|
||||
line_ref = 0;
|
||||
file_ref = NULL;
|
||||
|
||||
for (;;) {
|
||||
next();
|
||||
if (tok == TOK_EOF) {
|
||||
break;
|
||||
} else if (tok == TOK_LINEFEED) {
|
||||
if (!token_seen)
|
||||
continue;
|
||||
++line_ref;
|
||||
token_seen = 0;
|
||||
} else if (!token_seen) {
|
||||
int d = file->line_num - line_ref;
|
||||
if (file != file_ref || d < 0 || d >= 8)
|
||||
fprintf(s1->outfile, "# %d \"%s\"\n", file->line_num, file->filename);
|
||||
else
|
||||
while (d)
|
||||
fputs("\n", s1->outfile), --d;
|
||||
line_ref = (file_ref = file)->line_num;
|
||||
token_seen = 1;
|
||||
}
|
||||
fputs(get_tok_str(tok, &tokc), s1->outfile);
|
||||
}
|
||||
free_defines(define_start);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user