diff options
| author | mingodad <mingodad@gmail.com> | 2013-01-11 00:04:38 +0000 |
|---|---|---|
| committer | mingodad <mingodad@gmail.com> | 2013-01-11 00:04:38 +0000 |
| commit | 59e18aee0e509a3ca75dbe6f909e18c1d17893d1 (patch) | |
| tree | 1ee20b231505273a1b1ba678b67c6c9e5812a414 /libtcc.c | |
| parent | 0a8c7d143eb0dcae15db9b61feb7b93228645d5f (diff) | |
| download | tinycc-59e18aee0e509a3ca75dbe6f909e18c1d17893d1.tar.gz tinycc-59e18aee0e509a3ca75dbe6f909e18c1d17893d1.tar.bz2 | |
Added what I call virtual io to tinycc this way we can make a monolitic executable or library that contains all needed to compile programs, truly tinycc portable.
Tested under linux exec the "mk-it" shell script and you'll end up with a portable tinycc executable that doesn't depend on anything else.
Diffstat (limited to 'libtcc.c')
| -rw-r--r-- | libtcc.c | 105 |
1 files changed, 85 insertions, 20 deletions
@@ -268,6 +268,62 @@ PUB_FUNC void tcc_memstats(void) #define realloc(p, s) use_tcc_realloc(p, s) /********************************************************/ +/* virtual io */ + +LIBTCCAPI void tcc_set_vio_module(TCCState *s, vio_module_t *vio_module){ + s->vio_module = vio_module; + vio_module->tcc_state = s; +} + +void vio_initialize(vio_fd *fd) { + fd->fd = -1; + fd->vio_udata = NULL; + fd->vio_module = NULL; +} + +int vio_open(struct TCCState *s, vio_fd *fd, const char *fn, int oflag) { + int rc; + vio_initialize(fd); + fd->vio_module = s->vio_module; + if(s->vio_module && (s->vio_module->call_vio_open_flags & CALL_VIO_OPEN_FIRST)) { + rc = s->vio_module->vio_open(fd, fn, oflag); + if(rc >= 0) return rc; + } + + fd->fd = open(fn, oflag); + + if(fd->fd < 0 && s->vio_module && (s->vio_module->call_vio_open_flags & CALL_VIO_OPEN_LAST)) { + rc = s->vio_module->vio_open(fd, fn, oflag); + if(rc >= 0) return rc; + } + //printf("vio_open = %d %s\n", fd->fd, fn); + return fd->fd; +} + +off_t vio_lseek(vio_fd fd, off_t offset, int whence) { + if(fd.vio_udata) { + return fd.vio_module->vio_lseek(fd, offset, whence); + } + return lseek(fd.fd, offset, whence); +} + +size_t vio_read(vio_fd fd, void *buf, size_t bytes) { + if(fd.vio_udata) { + return fd.vio_module->vio_read(fd, buf, bytes); + } + return read(fd.fd, buf, bytes); +} + +int vio_close(vio_fd *fd) { + int rc = 0; + if(fd->vio_udata){ + fd->vio_module->vio_close(fd); + } else rc = close(fd->fd); + vio_initialize(fd); + return rc; +} + +/********************************************************/ /* dynarrays */ PUB_FUNC void dynarray_add(void ***ptab, int *nb_ptr, void *data) @@ -666,7 +722,7 @@ ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen) bf->line_num = 1; bf->ifndef_macro = 0; bf->ifdef_stack_ptr = s1->ifdef_stack_ptr; - bf->fd = -1; + vio_initialize(&bf->fd); bf->prev = file; file = bf; } @@ -674,26 +730,28 @@ ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen) ST_FUNC void tcc_close(void) { BufferedFile *bf = file; - if (bf->fd > 0) { - close(bf->fd); + if (bf->fd.fd > 0) { + vio_close(&bf->fd); total_lines += bf->line_num; } file = bf->prev; tcc_free(bf); } -ST_FUNC int tcc_open(TCCState *s1, const char *filename) +ST_FUNC vio_fd tcc_open(TCCState *s1, const char *filename) { - int fd; - if (strcmp(filename, "-") == 0) - fd = 0, filename = "stdin"; + vio_fd fd; + if (strcmp(filename, "-") == 0) { + vio_initialize(&fd); + fd.fd = 0, filename = "stdin"; + } else - fd = open(filename, O_RDONLY | O_BINARY); - if ((s1->verbose == 2 && fd >= 0) || s1->verbose == 3) - printf("%s %*s%s\n", fd < 0 ? "nf":"->", + vio_open(s1, &fd, filename, O_RDONLY | O_BINARY); + if ((s1->verbose == 2 && fd.fd >= 0) || s1->verbose == 3) + printf("%s %*s%s\n", fd.fd < 0 ? "nf":"->", (int)(s1->include_stack_ptr - s1->include_stack), "", filename); - if (fd < 0) - return -1; + if (fd.fd < 0) + return fd; tcc_open_bf(s1, filename, 0); file->fd = fd; @@ -817,18 +875,23 @@ static int tcc_compile(TCCState *s1) return s1->nb_errors != 0 ? -1 : 0; } -LIBTCCAPI int tcc_compile_string(TCCState *s, const char *str) +LIBTCCAPI int tcc_compile_named_string(TCCState *s, const char *str, const char *strname) { int len, ret; len = strlen(str); - tcc_open_bf(s, "<string>", len); + tcc_open_bf(s, strname ? strname : "<string>", len); memcpy(file->buffer, str, len); ret = tcc_compile(s); tcc_close(); return ret; } +LIBTCCAPI int tcc_compile_string(TCCState *s, const char *str) +{ + return tcc_compile_named_string(s, str, NULL); +} + /* 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) { @@ -1028,6 +1091,7 @@ LIBTCCAPI TCCState *tcc_new(void) #ifdef TCC_TARGET_I386 s->seg_size = 32; #endif + s->vio_module = NULL; return s; } @@ -1094,7 +1158,8 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) { const char *ext; ElfW(Ehdr) ehdr; - int fd, ret, size; + int ret=0, size; + vio_fd fd; /* find source file type with extension */ ext = tcc_fileextension(filename); @@ -1108,11 +1173,11 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) #endif /* open the file */ - ret = tcc_open(s1, filename); - if (ret < 0) { + fd = tcc_open(s1, filename); + if (fd.fd < 0) { if (flags & AFF_PRINT_ERROR) tcc_error_noabort("file '%s' not found", filename); - return ret; + return fd.fd; } /* update target deps */ @@ -1146,8 +1211,8 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) fd = file->fd; /* assume executable format: auto guess file type */ - size = read(fd, &ehdr, sizeof(ehdr)); - lseek(fd, 0, SEEK_SET); + size = vio_read(fd, &ehdr, sizeof(ehdr)); + vio_lseek(fd, 0, SEEK_SET); if (size <= 0) { tcc_error_noabort("could not read header"); goto the_end; |
