libtcc: new function tcc_open_bf to create BufferedFile

Use it in:
- tcc_open
- tcc_compile_string
- tcc_define_symbol
- tcc_assemble_inline
This commit is contained in:
grischka 2010-11-25 13:29:15 +01:00
parent f1c9f649da
commit e97bf88bad
4 changed files with 81 additions and 108 deletions

125
libtcc.c
View File

@ -635,11 +635,41 @@ PUB_FUNC void warning(const char *fmt, ...)
/********************************************************/ /********************************************************/
/* I/O layer */ /* I/O layer */
ST_FUNC BufferedFile *tcc_open(TCCState *s1, const char *filename) ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen)
{
BufferedFile *bf;
int buflen = initlen ? initlen : IO_BUF_SIZE;
bf = tcc_malloc(sizeof(BufferedFile) + buflen);
bf->buf_ptr = bf->buffer;
bf->buf_end = bf->buffer + initlen;
bf->buf_end[0] = CH_EOB; /* put eob symbol */
pstrcpy(bf->filename, sizeof(bf->filename), filename);
#ifdef _WIN32
normalize_slashes(bf->filename);
#endif
bf->line_num = 1;
bf->ifndef_macro = 0;
bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;
bf->fd = -1;
bf->prev = file;
file = bf;
}
ST_FUNC void tcc_close(void)
{
BufferedFile *bf = file;
if (bf->fd > 0) {
close(bf->fd);
total_lines += bf->line_num;
}
file = bf->prev;
tcc_free(bf);
}
ST_FUNC int tcc_open(TCCState *s1, const char *filename)
{ {
int fd; int fd;
BufferedFile *bf;
if (strcmp(filename, "-") == 0) if (strcmp(filename, "-") == 0)
fd = 0, filename = "stdin"; fd = 0, filename = "stdin";
else else
@ -648,28 +678,11 @@ ST_FUNC BufferedFile *tcc_open(TCCState *s1, const char *filename)
printf("%s %*s%s\n", fd < 0 ? "nf":"->", printf("%s %*s%s\n", fd < 0 ? "nf":"->",
(int)(s1->include_stack_ptr - s1->include_stack), "", filename); (int)(s1->include_stack_ptr - s1->include_stack), "", filename);
if (fd < 0) if (fd < 0)
return NULL; return -1;
bf = tcc_malloc(sizeof(BufferedFile));
bf->fd = fd;
bf->buf_ptr = bf->buffer;
bf->buf_end = bf->buffer;
bf->buffer[0] = CH_EOB; /* put eob symbol */
pstrcpy(bf->filename, sizeof(bf->filename), filename);
#ifdef _WIN32
normalize_slashes(bf->filename);
#endif
bf->line_num = 1;
bf->ifndef_macro = 0;
bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;
// printf("opening '%s'\n", filename);
return bf;
}
ST_FUNC void tcc_close(BufferedFile *bf) tcc_open_bf(s1, filename, 0);
{ file->fd = fd;
total_lines += bf->line_num; return fd;
close(bf->fd);
tcc_free(bf);
} }
/* compile the C file opened in 'file'. Return non zero if errors. */ /* compile the C file opened in 'file'. Return non zero if errors. */
@ -780,60 +793,38 @@ static int tcc_compile(TCCState *s1)
LIBTCCAPI int tcc_compile_string(TCCState *s, const char *str) LIBTCCAPI int tcc_compile_string(TCCState *s, const char *str)
{ {
BufferedFile bf1, *bf = &bf1; int len, ret;
int ret, len;
char *buf;
/* init file structure */
bf->fd = -1;
/* XXX: avoid copying */
len = strlen(str); len = strlen(str);
buf = tcc_malloc(len + 1);
if (!buf)
return -1;
memcpy(buf, str, len);
buf[len] = CH_EOB;
bf->buf_ptr = buf;
bf->buf_end = buf + len;
pstrcpy(bf->filename, sizeof(bf->filename), "<string>");
bf->line_num = 1;
file = bf;
ret = tcc_compile(s);
file = NULL;
tcc_free(buf);
/* currently, no need to close */ tcc_open_bf(s, "<string>", len);
memcpy(file->buffer, str, len);
ret = tcc_compile(s);
tcc_close();
return ret; return ret;
} }
/* define a preprocessor symbol. A value can also be provided with the '=' operator */ /* define a preprocessor symbol. A value can also be provided with the '=' operator */
LIBTCCAPI void tcc_define_symbol(TCCState *s1, const char *sym, const char *value) LIBTCCAPI void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
{ {
BufferedFile bf1, *bf = &bf1; int len1, len2;
pstrcpy(bf->buffer, IO_BUF_SIZE, sym);
pstrcat(bf->buffer, IO_BUF_SIZE, " ");
/* default value */ /* default value */
if (!value) if (!value)
value = "1"; value = "1";
pstrcat(bf->buffer, IO_BUF_SIZE, value); len1 = strlen(sym);
len2 = strlen(value);
/* init file structure */ /* init file structure */
bf->fd = -1; tcc_open_bf(s1, "<define>", len1 + len2 + 1);
bf->buf_ptr = bf->buffer; memcpy(file->buffer, sym, len1);
bf->buf_end = bf->buffer + strlen(bf->buffer); file->buffer[len1] = ' ';
*bf->buf_end = CH_EOB; memcpy(file->buffer + len1 + 1, value, len2);
bf->filename[0] = '\0';
bf->line_num = 1;
file = bf;
s1->include_stack_ptr = s1->include_stack;
/* parse with define parser */ /* parse with define parser */
ch = file->buf_ptr[0]; ch = file->buf_ptr[0];
next_nomacro(); next_nomacro();
parse_define(); parse_define();
file = NULL;
tcc_close();
} }
/* undefine a preprocessor symbol */ /* undefine a preprocessor symbol */
@ -1082,9 +1073,6 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
const char *ext; const char *ext;
ElfW(Ehdr) ehdr; ElfW(Ehdr) ehdr;
int fd, ret, size; int fd, ret, size;
BufferedFile *saved_file;
ret = -1;
/* find source file type with extension */ /* find source file type with extension */
ext = tcc_fileextension(filename); ext = tcc_fileextension(filename);
@ -1092,12 +1080,11 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
ext++; ext++;
/* open the file */ /* open the file */
saved_file = file; ret = tcc_open(s1, filename);
file = tcc_open(s1, filename); if (ret < 0) {
if (!file) {
if (flags & AFF_PRINT_ERROR) if (flags & AFF_PRINT_ERROR)
error_noabort("file '%s' not found", filename); error_noabort("file '%s' not found", filename);
goto the_end; return ret;
} }
/* update target deps */ /* update target deps */
@ -1192,9 +1179,7 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
error_noabort("unrecognized file type"); error_noabort("unrecognized file type");
the_end: the_end:
if (file) tcc_close();
tcc_close(file);
file = saved_file;
return ret; return ret;
} }

7
tcc.h
View File

@ -334,6 +334,7 @@ typedef struct BufferedFile {
uint8_t *buf_ptr; uint8_t *buf_ptr;
uint8_t *buf_end; uint8_t *buf_end;
int fd; int fd;
struct BufferedFile *prev;
int line_num; /* current line number - here to simplify code */ int line_num; /* current line number - here to simplify code */
int ifndef_macro; /* #ifndef macro / #endif search */ int ifndef_macro; /* #ifndef macro / #endif search */
int ifndef_macro_saved; /* saved ifndef_macro */ int ifndef_macro_saved; /* saved ifndef_macro */
@ -946,8 +947,10 @@ ST_INLN Sym *struct_find(int v);
ST_INLN Sym *sym_find(int v); ST_INLN Sym *sym_find(int v);
ST_FUNC Sym *global_identifier_push(int v, int t, int c); ST_FUNC Sym *global_identifier_push(int v, int t, int c);
ST_FUNC BufferedFile *tcc_open(TCCState *s1, const char *filename); ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen);
ST_FUNC void tcc_close(BufferedFile *bf); ST_FUNC int tcc_open(TCCState *s1, const char *filename);
ST_FUNC void tcc_close(void);
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);
ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags); ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags);
PUB_FUNC int tcc_set_flag(TCCState *s, const char *flag_name, int value); PUB_FUNC int tcc_set_flag(TCCState *s, const char *flag_name, int value);

View File

@ -825,32 +825,22 @@ ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess)
end */ end */
static void tcc_assemble_inline(TCCState *s1, char *str, int len) static void tcc_assemble_inline(TCCState *s1, char *str, int len)
{ {
BufferedFile *bf, *saved_file;
int saved_parse_flags; int saved_parse_flags;
const int *saved_macro_ptr; const int *saved_macro_ptr;
bf = tcc_malloc(sizeof(BufferedFile));
memset(bf, 0, sizeof(BufferedFile));
bf->fd = -1;
bf->buf_ptr = str;
bf->buf_end = str + len;
str[len] = CH_EOB;
/* same name as current file so that errors are correctly
reported */
pstrcpy(bf->filename, sizeof(bf->filename), file->filename);
bf->line_num = file->line_num;
saved_file = file;
file = bf;
saved_parse_flags = parse_flags; saved_parse_flags = parse_flags;
saved_macro_ptr = macro_ptr; saved_macro_ptr = macro_ptr;
macro_ptr = NULL;
tcc_open_bf(s1, file->filename, len);
file->line_num = file->prev->line_num;
memcpy(file->buffer, str, len);
macro_ptr = NULL;
tcc_assemble_internal(s1, 0); tcc_assemble_internal(s1, 0);
tcc_close();
parse_flags = saved_parse_flags; parse_flags = saved_parse_flags;
macro_ptr = saved_macro_ptr; macro_ptr = saved_macro_ptr;
file = saved_file;
tcc_free(bf);
} }
/* find a constraint by its number or id (gcc 3 extended /* find a constraint by its number or id (gcc 3 extended

31
tccpp.c
View File

@ -1433,10 +1433,9 @@ ST_FUNC void preprocess(int is_bof)
n = s1->nb_include_paths + s1->nb_sysinclude_paths; n = s1->nb_include_paths + s1->nb_sysinclude_paths;
for (i = -2; i < n; ++i) { for (i = -2; i < n; ++i) {
char buf1[sizeof file->filename]; char buf1[sizeof file->filename];
BufferedFile *f;
CachedInclude *e; CachedInclude *e;
const char *path; const char *path;
int size; int size, fd;
if (i == -2) { if (i == -2) {
/* check absolute include path */ /* check absolute include path */
@ -1471,21 +1470,21 @@ ST_FUNC void preprocess(int is_bof)
#ifdef INC_DEBUG #ifdef INC_DEBUG
printf("%s: skipping %s\n", file->filename, buf); printf("%s: skipping %s\n", file->filename, buf);
#endif #endif
f = NULL; fd = 0;
} else { } else {
f = tcc_open(s1, buf1); fd = tcc_open(s1, buf1);
if (!f) if (fd < 0)
continue; continue;
} }
if (tok == TOK_INCLUDE_NEXT) { if (tok == TOK_INCLUDE_NEXT) {
tok = TOK_INCLUDE; tok = TOK_INCLUDE;
if (f) if (fd)
tcc_close(f); tcc_close();
continue; continue;
} }
if (!f) if (0 == fd)
goto include_done; goto include_done;
#ifdef INC_DEBUG #ifdef INC_DEBUG
@ -1494,17 +1493,14 @@ ST_FUNC void preprocess(int is_bof)
/* update target deps */ /* update target deps */
dynarray_add((void ***)&s1->target_deps, &s1->nb_target_deps, dynarray_add((void ***)&s1->target_deps, &s1->nb_target_deps,
tcc_strdup(buf1)); tcc_strdup(buf1));
/* XXX: fix current line init */ /* XXX: fix current line init */
/* push current file in stack */ /* push current file in stack */
*s1->include_stack_ptr++ = file; *s1->include_stack_ptr++ = file->prev;
f->inc_type = c; file->inc_type = c;
pstrcpy(f->inc_filename, sizeof(f->inc_filename), buf1); pstrcpy(file->inc_filename, sizeof(file->inc_filename), buf1);
file = f;
/* add include file debug info */ /* add include file debug info */
if (s1->do_debug) { if (s1->do_debug)
put_stabs(file->filename, N_BINCL, 0, 0, 0); put_stabs(file->filename, N_BINCL, 0, 0, 0);
}
tok_flags |= TOK_FLAG_BOF | TOK_FLAG_BOL; tok_flags |= TOK_FLAG_BOF | TOK_FLAG_BOL;
ch = file->buf_ptr[0]; ch = file->buf_ptr[0];
goto the_end; goto the_end;
@ -2134,9 +2130,8 @@ static inline void next_nomacro1(void)
put_stabd(N_EINCL, 0, 0); put_stabd(N_EINCL, 0, 0);
} }
/* pop include stack */ /* pop include stack */
tcc_close(file); tcc_close();
s1->include_stack_ptr--; s1->include_stack_ptr--;
file = *s1->include_stack_ptr;
p = file->buf_ptr; p = file->buf_ptr;
goto redo_no_start; goto redo_no_start;
} }