Revert "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."

This reverts commit 59e18aee0e.
tcc is being stabilized now in order to do a new release soon.
Therefore, such a change is not appropriate now.
This commit is contained in:
Thomas Preud'homme 2013-01-14 17:34:07 +01:00
parent 60a3ff5f2c
commit 8c56b0cf90
12 changed files with 62 additions and 903 deletions

View File

@ -161,20 +161,15 @@ PROGS+=$(PROGS_CROSS)
TCCLIBS+=$(LIBTCC1_CROSS)
endif
ifdef CONFIG_USE_ATTACHMENTS
FILE_ATTACHMENTS= tcc_attachments.o
CFLAGS += -DWITH_ATTACHMENTS=1
endif
all: $(PROGS) $(TCCLIBS) $(FILE_ATTACHMENTS) $(TCCDOCS)
all: $(PROGS) $(TCCLIBS) $(TCCDOCS)
# Host Tiny C Compiler
tcc$(EXESUF): tcc.o $(LIBTCC)
$(CC) -o $@ $^ $(LIBS) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(FILE_ATTACHMENTS) $(LINK_LIBTCC)
$(CC) -o $@ $^ $(LIBS) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(LINK_LIBTCC)
# Cross Tiny C Compilers
%-tcc$(EXESUF):
$(CC) -o $@ tcc.c -DONE_SOURCE $(DEFINES) $(CPPFLAGS) $(CFLAGS) $(FILE_ATTACHMENTS) $(LIBS) $(LDFLAGS)
$(CC) -o $@ tcc.c -DONE_SOURCE $(DEFINES) $(CPPFLAGS) $(CFLAGS) $(LIBS) $(LDFLAGS)
$(I386_CROSS): DEFINES = -DTCC_TARGET_I386 \
-DCONFIG_TCCDIR="\"$(tccdir)/i386\""
@ -221,12 +216,9 @@ libtcc.so.1.0: $(LIBTCC_OBJ)
libtcc.so.1.0: CFLAGS+=-fPIC
#tcc_attachments.o: libtcc.c
# mk-attachments.sh
# profiling version
tcc_p$(EXESUF): $(NATIVE_FILES)
$(CC) -o $@ $< $(NATIVE_DEFINES) $(CPPFLAGS_P) $(CFLAGS_P) $(LIBS_P) $(FILE_ATTACHMENTS) $(LDFLAGS_P)
$(CC) -o $@ $< $(NATIVE_DEFINES) $(CPPFLAGS_P) $(CFLAGS_P) $(LIBS_P) $(LDFLAGS_P)
# windows utilities
tiny_impdef$(EXESUF): win32/tools/tiny_impdef.c

615
bin2c.c
View File

@ -1,615 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#include <assert.h>
/* Version information */
const char *versionInfo =
"bin2c version 1.0 by Fatih Aygun\n"
"\n"
"Visit sourceforge.net/projects/bin2c to for new versions.\n"
"This program is public domain, do whatever you want with it.\n"
;
/* Command line help */
const char *commandLineHelp =
"Usage: bin2c [OPTION...] FILE [FILE...]\n"
"bin2c creates a C soures and headers from binary files.\n"
"\n"
"Examples:\n"
" bin2c -o foo.h bar.bin # Create 'foo.h' from the contents of\n"
" 'bar.bin'\n"
" bin2c -o foo.h file1 file2 # Create 'foo.h' from the contents of 'file1'\n"
" and 'file2'\n"
" bin2c -d foo.h -o foo.c bar.bin # Create 'foo.c' and 'foo.h' from the\n"
" contents of 'bar.bin'\n"
"\n"
"Options:\n"
" -d, --header <file name> Name a header file (A header file will not be\n"
" created unless explicitly named)\n"
" -h, --help Print this command line help and exit immediately\n"
" -o, --output <file name> Name an output file\n"
" -m, --macro Create the size definition as a macro instead of\n"
" a const\n"
" -n, --name <symbol name> Name the symbol to be defined\n"
" -v, --version Print version information and exit immediately\n"
"\n"
"Visit sourceforge.net/projects/bin2c to for new versions.\n"
"This program is public domain, do whatever you want with it.\n"
;
/* Output formatting macros */
#define bytesPerLine 16
#define indentString " "
#define outputFormatBase "0x%.2X"
#define outputFormat outputFormatBase", "
#define outputFormatEOL outputFormatBase",\n"
#define outputFormatEOF outputFormatBase"\n"
#define sizeDefinition "const long int bin2c_%s_size = %d;\n"
#define sizeMacroDefinition "#define bin2c_%s_size %d\n"
#define typeName "const unsigned char"
/* Define bool */
#define bool int
#define false 0
#define true 1
/* Global variables */
FILE *outputFile=0; /* Current output file stream */
const char *outputFileName=0; /* Current output file name */
FILE *headerFile=0; /* Current header file */
const char *headerFileName=0; /* Current header file name */
FILE *tmpFuncFile=0; /* File to write final function that search for files */
const char *tmpFuncFileName=0; /* Current tmpFunc file name */
char *symbolName=0; /* Current symbol name */
char *headerSymbol=0; /* Symbol for multiple inclusion protection */
bool createMacro = false; /* Should we create a define instead of a const? */
/* Error messages */
const char* cantOpen = "Can't open file '%s'";
const char* cantClose = "Can't close file '%s'";
const char* cantRemove = "Can't remove file '%s'";
const char* cantWrite = "Can't write to file '%s'";
const char* noOutputFilesAreNamed = "No output files are named";
const char* noHeaderFilesAreNamed = "No header files are named";
const char* cantMalloc = "Can't allocate memory for '%s'";
const char* cantSeek = "Can't seek in the file '%s'";
const char* cantDetermine = "Can't determine the file size of '%s'";
const char* cantRead = "Can't read from file %s";
const char* unknownOption = "Unknown option '%s'";
const char* tryHelp = "Try 'bin2c --help' for more information.\n";
const char* noSymbolName = "No symbol name is given";
const char* notValidId = "'%s' is not a valid identifier";
const char* symbolNameGiven = "Symbol name is given twice";
/* Print a formatted error message */
static void vprintfError(const char *format, va_list args)
{
fprintf(stderr, "bin2c: ");
vfprintf(stderr, format, args);
if (errno) {
fprintf(stderr, ": ");
perror("");
errno = 0;
} else {
fprintf(stderr, "\n");
}
}
static void printfError(const char *format, ...)
{
va_list args;
va_start(args, format);
vprintfError(format, args);
va_end(args);
}
/* Panic */
static void panic()
{
/* Close and remove the output file if it's open */
if (outputFile) {
if (fclose(outputFile)) {
printfError(cantClose, outputFileName);
}
if (remove(outputFileName)) {
printfError(cantRemove, outputFileName);
}
}
/* Close and remove the header file if it's open */
if (headerFile) {
if (fclose(headerFile)) {
printfError(cantClose, headerFileName);
}
if (remove(headerFileName)) {
printfError(cantRemove, headerFileName);
}
}
/* Close and remove the header file if it's open */
if (tmpFuncFile) {
if (fclose(tmpFuncFile)) {
printfError(cantClose, tmpFuncFileName);
}
if (remove(tmpFuncFileName)) {
printfError(cantRemove, tmpFuncFileName);
}
}
/* Exit with an error code */
exit(EXIT_FAILURE);
}
/* Check a contidion and panic if it's false */
static void check(bool condition, const char *format, ...)
{
va_list args;
if (!condition) {
va_start(args, format);
vprintfError(format, args);
va_end(args);
panic();
}
}
/* Write a formatted string to the output file and check for errors */
static void output(const char *format, ...)
{
va_list args;
/* Try to write to the file */
va_start(args, format);
vfprintf(outputFile, format, args);
va_end(args);
/* Check for errors */
check(!ferror(outputFile), cantWrite, outputFileName);
}
/* Write a formatted string to the header file and check for errors */
static void header(const char *format, ...)
{
va_list args;
/* Try to write to the file */
va_start(args, format);
vfprintf(headerFile, format, args);
va_end(args);
/* Check for errors */
check(!ferror(headerFile), cantWrite, headerFileName);
}
/* Write a formatted string to the tmp file and check for errors */
static void tmpFunc(const char *format, ...)
{
va_list args;
/* Try to write to the file */
va_start(args, format);
vfprintf(tmpFuncFile, format, args);
va_end(args);
/* Check for errors */
check(!ferror(tmpFuncFile), cantWrite, tmpFuncFileName);
}
/* Allocate a valid C identifier from a file name */
static char *fileNameToSymbol(const char *fileName)
{
char *name;
int i;
name = malloc(strlen(fileName) + 1);
check(name != 0, cantMalloc, "the symbol name");
/* Copy the file name to symbolName */
strcpy(name, fileName);
/* Replace every non alphanumerical character with '_' */
for (i = 0; name[i]; ++i) {
if (!((name[i] >= 'a' && name[i] <= 'z') ||
(name[i] >= 'A' && name[i] <= 'Z') ||
(name[i] >= '0' && name[i] <= '9'))) {
name[i] = '_';
}
}
/* Replace the first character with '_' if it's a digit */
if (name[0] >= '0' && name[0] <= '9') {
name[0] = '_';
}
return name;
}
int isdir(const char * path)
{
int bOK = 0;
#ifndef _MSC_VER
struct stat buf;
if (path == NULL) return 0;
if (stat(path, &buf) == 0 && S_ISDIR(buf.st_mode)) bOK=1;
#else
wchar_t *wcpath = to_wide_string((char*)path);
if (wcpath == NULL) return FALSE;
bOK = isdirW(wcpath);
FREE(wcpath);
#endif
return bOK;
}
/* Process an input file */
static int processFile(const char *fileName, long int from, long int to)
{
bool symbolNameAllocated = false; /* Did we allocate the symbolName? */
long int i, j; /* Indexes for various purposes */
FILE *inputFile; /* Input file stream */
int byte; /* Byte read from the input */
long int fsize=0;
if(isdir(fileName)) return 0;
/* Be sure that the output file is open */
check(outputFile != 0, noOutputFilesAreNamed);
/* Write the comment */
output("\n/* Contents of file %s */\n", fileName);
if (headerFile) {
header("\n/* Contents of file %s */\n", fileName);
}
/* Make up a suitable symbolName if we don't have one */
if (!symbolName) {
symbolName = fileNameToSymbol(fileName);
symbolNameAllocated = true;
}
/* Open the input file */
inputFile = fopen(fileName, "rb");
check(inputFile != 0, cantOpen, fileName);
/* If to == -1, set it to the last byte of the file */
if (to == -1) {
check(!fseek(inputFile, 0, SEEK_END), cantSeek, fileName);
to = ftell(inputFile);
check(to >= 0, cantDetermine, fileName);
--to;
}
assert(from <= to - 1);
/* Position the file to "from" */
check(!fseek(inputFile, from, SEEK_SET), cantSeek, fileName);
fsize = to - from + 1;
/* Output the size definition */
if (headerFile) {
if (createMacro) {
header(sizeMacroDefinition, symbolName, fsize);
} else {
header("extern "sizeDefinition, symbolName, fsize);
output(sizeDefinition, symbolName, fsize);
}
} else {
if (createMacro) {
output(sizeMacroDefinition, symbolName, fsize);
} else {
output(sizeDefinition, symbolName, fsize);
}
}
if (tmpFuncFile) {
tmpFunc("\t{\"/_attach_/%s\", bin2c_%s, %d},\n", fileName, symbolName, fsize);
}
/* Output the definition */
output("%s bin2c_%s[%d] = {\n", typeName, symbolName, fsize);
if (headerFile) {
header("extern %s *bin2c_%s;\n", typeName, symbolName, fsize);
}
/* Output the contents */
j = 1;
for (i = from; i <= to; ++i) {
/* Read a byte from the input file */
byte = fgetc(inputFile);
check(byte != EOF, cantRead, fileName);
/* Output the indentation if it's the first byte of a line */
if (j == 1) {
output(indentString);
}
/* Output the actual byte */
if (i == to) {
/* Output the last byte */
output(outputFormatEOF, byte);
} else if (j == bytesPerLine) {
/* Output the last byte of a line */
output(outputFormatEOL, byte);
} else {
/* Output a normal byte */
output(outputFormat, byte);
}
/* Next byte */
++j;
if (j > bytesPerLine) {
j = 1;
}
}
/* Output the end of definition */
output("};\n");
/* Free the symbol name if it was allocated by us */
if (symbolNameAllocated) {
free(symbolName);
}
/* Clear the symbol name */
symbolName = 0;
return 1;
}
/* Unknown option error */
static void handleUnknownOption(const char *s)
{
printfError(unknownOption, s);
fprintf(stderr, tryHelp);
panic();
}
/* Open an output file */
static void openOutputFile(const char *fileName)
{
/* Be sure that a file name is given */
if (!fileName) {
printfError(noOutputFilesAreNamed);
fprintf(stderr, tryHelp);
panic();
}
/* Close previous output file if any */
if (outputFile) {
check(!fclose(outputFile), cantClose, outputFileName);
}
/* Open the new output file */
outputFile = fopen(fileName, "w");
check(outputFile != 0, cantOpen, outputFileName);
outputFileName = fileName;
output("/* Generated by bin2c, do not edit manually */\n");
}
/* Open a header file */
static void openHeaderFile(const char *fileName)
{
/* Be sure that a file name is given */
if (!fileName) {
printfError(noHeaderFilesAreNamed);
fprintf(stderr, tryHelp);
panic();
}
/* Close previous header file if any */
if (headerFile) {
header("\n#endif /* __%s_included */\n", headerSymbol);
free(headerSymbol);
headerSymbol = 0;
check(!fclose(headerFile), cantClose, headerFileName);
}
/* Open the new header file */
headerFile = fopen(fileName, "w");
check(headerFile != 0, cantOpen, headerFileName);
headerFileName = fileName;
headerSymbol = fileNameToSymbol(fileName);
header("/* Generated by bin2c, do not edit manually */\n");
header("#ifndef __%s_included\n", headerSymbol);
header("#define __%s_included\n", headerSymbol);
}
typedef void writeFileFunc(const char *format, ...);
void writeAttchmentStruct(writeFileFunc *writeFunc){
(*writeFunc)("\ntypedef struct {\n");
(*writeFunc)("\tconst char *file_name;\n");
(*writeFunc)("\tconst unsigned char *sym_name;\n");
(*writeFunc)("\tlong size;\n");
(*writeFunc)("} bin2c_filesAttached_st;\n");
}
/* Open a header file */
static void openFuncFile(const char *fileName)
{
static char fnBuf[1024];
/* Be sure that a file name is given */
if (!fileName) {
printfError(noHeaderFilesAreNamed);
fprintf(stderr, tryHelp);
panic();
}
/* Close previous header file if any */
if (tmpFuncFile) {
tmpFunc("\n};\n");
check(!fclose(tmpFuncFile), cantClose, tmpFuncFileName);
}
snprintf(fnBuf, sizeof(fnBuf), "%s.tmp", fileName);
/* Open the new header file */
tmpFuncFile = fopen(fnBuf, "w");
check(tmpFuncFile != 0, cantOpen, fnBuf);
tmpFuncFileName = fnBuf;
tmpFunc("\n/* Generated by bin2c, do not edit manually */\n");
writeAttchmentStruct(&tmpFunc);
tmpFunc("const bin2c_filesAttached_st bin2c_filesAttached[] = {\n");
}
/* Set the symbol name for next file */
static void setSymbolName(char *name)
{
int i;
if (symbolName) {
printfError(symbolNameGiven);
fprintf(stderr, tryHelp);
panic();
}
/* Be sure that a symbol name is given */
if (!name) {
printfError(noSymbolName);
fprintf(stderr, tryHelp);
panic();
}
/* Check if the symbol is a valid C identifier */
check((name[0] >= 'a' && name[0] <='z') ||
(name[0] >= 'A' && name[0] <='Z') ||
(name[0] == '_'), notValidId, name);
for (i = 1; name[i]; ++i) {
check((name[i] >= 'a' && name[i] <='z') ||
(name[i] >= 'A' && name[i] <='Z') ||
(name[i] >= '0' && name[i] <='9') ||
(name[i] == '_'), notValidId, name);
}
/* Set the symbol name */
symbolName = name;
}
void concatenate(const char *dest, const char *src){
int i,ch;
FILE *fpdest=fopen(dest,"a");
FILE *fpsrc=fopen(src,"r");
while((ch=getc(fpsrc))!=EOF) putc(ch,fpdest);
}
/* Main function */
int main(int argc, char **argv)
{
int i; /* Index to process commandline arguments */
int ipf = 0; /*total files processed*/
/* Scan for a -h or --help option */
for (i = 1; i < argc; ++i) {
if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
/* Print command line arguments help and exit immediately */
printf("%s", commandLineHelp);
return EXIT_SUCCESS;
}
}
/* Scan for a -v or --version option */
for (i = 1; i < argc; ++i) {
if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) {
/* Print version information and exit immediately */
printf("%s", versionInfo);
return EXIT_SUCCESS;
}
}
/* Process command line arguments */
for (i = 1; i < argc; ++i) {
/* Check if it's an option or file name */
if (argv[i][0] == '-') {
/* Process the option */
switch (argv[i][1]) {
case '-':
/* Long options */
if (!strcmp(argv[i], "--output")) {
/* Name an output file */
openOutputFile(argv[i+1]);
openFuncFile(argv[i+1]);
++i;
} else if (!strcmp(argv[i], "--header")) {
/* Name a header file */
openHeaderFile(argv[i+1]);
++i;
} else if (!strcmp(argv[i], "--macro")) {
/* Create a macro for the size definition */
createMacro = true;
} else if (!strcmp(argv[i], "--name")) {
/* Name the symbol */
setSymbolName(argv[i+1]);
++i;
} else {
/* Unknown option */
handleUnknownOption(argv[i]);
}
break;
case 'o':
/* Name an output file */
openOutputFile(argv[i+1]);
openFuncFile(argv[i+1]);
++i;
break;
case 'd':
/* Name a header file */
openHeaderFile(argv[i+1]);
++i;
break;
case 'm':
/* Create a macro for the size definition */
createMacro = true;
break;
case 'n':
/* Name the symbol */
setSymbolName(argv[i+1]);
++i;
break;
default:
/* Unknown option */
handleUnknownOption(argv[i]);
}
} else {
/* Process the file */
if(processFile(argv[i], 0, -1)) ipf++;
}
}
/* Close any remaining output files */
if (headerFile) {
writeAttchmentStruct(&header);
header("extern const bin2c_filesAttached_st bin2c_filesAttached[%d];\n", ipf);
header("\n#endif /* __%s_included */\n", headerSymbol);
free(headerSymbol);
headerSymbol = 0;
check(!fclose(headerFile), cantClose, headerFileName);
}
if (tmpFuncFile) {
tmpFunc("};\n");
check(!fclose(tmpFuncFile), cantClose, tmpFuncFileName);
}
if (outputFile) {
check(!fclose(outputFile), cantClose, outputFileName);
}
if (tmpFuncFile && outputFile) {
concatenate(outputFileName, tmpFuncFileName);
remove(tmpFuncFileName);
}
return EXIT_SUCCESS;
}

105
libtcc.c
View File

@ -267,62 +267,6 @@ PUB_FUNC void tcc_memstats(void)
#define malloc(s) use_tcc_malloc(s)
#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 */
@ -722,7 +666,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;
vio_initialize(&bf->fd);
bf->fd = -1;
bf->prev = file;
file = bf;
}
@ -730,28 +674,26 @@ 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.fd > 0) {
vio_close(&bf->fd);
if (bf->fd > 0) {
close(bf->fd);
total_lines += bf->line_num;
}
file = bf->prev;
tcc_free(bf);
}
ST_FUNC vio_fd tcc_open(TCCState *s1, const char *filename)
ST_FUNC int tcc_open(TCCState *s1, const char *filename)
{
vio_fd fd;
if (strcmp(filename, "-") == 0) {
vio_initialize(&fd);
fd.fd = 0, filename = "stdin";
}
int fd;
if (strcmp(filename, "-") == 0)
fd = 0, filename = "stdin";
else
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":"->",
fd = open(filename, O_RDONLY | O_BINARY);
if ((s1->verbose == 2 && fd >= 0) || s1->verbose == 3)
printf("%s %*s%s\n", fd < 0 ? "nf":"->",
(int)(s1->include_stack_ptr - s1->include_stack), "", filename);
if (fd.fd < 0)
return fd;
if (fd < 0)
return -1;
tcc_open_bf(s1, filename, 0);
file->fd = fd;
@ -875,23 +817,18 @@ static int tcc_compile(TCCState *s1)
return s1->nb_errors != 0 ? -1 : 0;
}
LIBTCCAPI int tcc_compile_named_string(TCCState *s, const char *str, const char *strname)
LIBTCCAPI int tcc_compile_string(TCCState *s, const char *str)
{
int len, ret;
len = strlen(str);
tcc_open_bf(s, strname ? strname : "<string>", len);
tcc_open_bf(s, "<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)
{
@ -1091,7 +1028,6 @@ LIBTCCAPI TCCState *tcc_new(void)
#ifdef TCC_TARGET_I386
s->seg_size = 32;
#endif
s->vio_module = NULL;
return s;
}
@ -1158,8 +1094,7 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
{
const char *ext;
ElfW(Ehdr) ehdr;
int ret=0, size;
vio_fd fd;
int fd, ret, size;
/* find source file type with extension */
ext = tcc_fileextension(filename);
@ -1173,11 +1108,11 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
#endif
/* open the file */
fd = tcc_open(s1, filename);
if (fd.fd < 0) {
ret = tcc_open(s1, filename);
if (ret < 0) {
if (flags & AFF_PRINT_ERROR)
tcc_error_noabort("file '%s' not found", filename);
return fd.fd;
return ret;
}
/* update target deps */
@ -1211,8 +1146,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 = vio_read(fd, &ehdr, sizeof(ehdr));
vio_lseek(fd, 0, SEEK_SET);
size = read(fd, &ehdr, sizeof(ehdr));
lseek(fd, 0, SEEK_SET);
if (size <= 0) {
tcc_error_noabort("could not read header");
goto the_end;

View File

@ -13,28 +13,6 @@ struct TCCState;
typedef struct TCCState TCCState;
struct vio_module_t;
typedef struct vio_fd {
int fd;
void *vio_udata;
struct vio_module_t *vio_module;
} vio_fd;
#define CALL_VIO_OPEN_FIRST 0x01
#define CALL_VIO_OPEN_LAST 0x02
typedef struct vio_module_t {
void *user_data;
struct TCCState *tcc_state;
int call_vio_open_flags; /*CALL_VIO_OPEN_FIRST, CALL_VIO_OPEN_LAST, one or both */
int (*vio_open)(vio_fd *fd, const char *fn, int oflag) ;
off_t (*vio_lseek)(vio_fd fd, off_t offset, int whence);
size_t (*vio_read)(vio_fd fd, void *buf, size_t bytes);
int (*vio_close)(vio_fd *fd);
} vio_module_t;
/* create a new TCC compilation context */
LIBTCCAPI TCCState *tcc_new(void);
@ -54,9 +32,6 @@ LIBTCCAPI int tcc_set_warning(TCCState *s, const char *warning_name, int value);
/* set linker option */
LIBTCCAPI const char * tcc_set_linker(TCCState *s, char *option, int multi);
/* set virtual io module */
LIBTCCAPI void tcc_set_vio_module(TCCState *s, vio_module_t *vio_module);
/*****************************/
/* preprocessor */
@ -83,10 +58,6 @@ LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename);
error. */
LIBTCCAPI int tcc_compile_string(TCCState *s, const char *buf);
/* compile a string containing a C source. Return non zero if
error. Can associate a name with string for errors. */
int tcc_compile_named_string(TCCState *s, const char *buf, const char *strname);
/*****************************/
/* linking commands */

View File

@ -1,4 +0,0 @@
FNAME=tcc_attachments
gcc -o bin2c bin2c.c
./bin2c -m -d ${FNAME}.h -o ${FNAME}.c include/* libtcc.a libtcc1.a
gcc -c ${FNAME}.c

8
mk-it
View File

@ -1,8 +0,0 @@
rm *.a
rm *.o
make
./mk-attachments.sh
rm tcc.o
make CONFIG_USE_ATTACHMENTS=1
strip tcc

97
tcc.c
View File

@ -479,98 +479,6 @@ static int parse_args(TCCState *s, int argc, char **argv)
return optind;
}
#ifdef WITH_ATTACHMENTS
#include "tcc_attachments.h"
#define ATTACH_PREFIX "/_attach_"
static vio_module_t vio_module;
typedef struct vio_memfile_t {
off_t size;
off_t pos;
const unsigned char *mem;
} vio_memfile_t;
static int vio_mem_open(vio_fd *fd, const char *fn, int oflag) {
//printf("%d:%s\n", fd->fd, fn);
if(fd->vio_module && strncmp(ATTACH_PREFIX, fn, sizeof(ATTACH_PREFIX)-1) == 0){
int i, count = sizeof(bin2c_filesAttached)/sizeof(bin2c_filesAttached_st);
for(i=0; i < count; ++i) {
//printf("%s:%s\n", fn, bin2c_filesAttached[i].file_name);
if(strcmp(fn, bin2c_filesAttached[i].file_name) == 0) {
vio_memfile_t *mf = (vio_memfile_t*)tcc_malloc(sizeof(vio_memfile_t));
mf->mem = bin2c_filesAttached[i].sym_name;
mf->size = bin2c_filesAttached[i].size;
mf->pos = 0;
fd->fd = 1;
fd->vio_udata = mf;
//printf("%d:%s\n", fd->fd, fn);
return fd->fd;
}
}
}
return -1;
}
static off_t vio_mem_lseek(vio_fd fd, off_t offset, int whence) {
if(fd.vio_udata) {
off_t loffset = 0;
vio_memfile_t *mf = (vio_memfile_t*)fd.vio_udata;
if (whence == SEEK_CUR)
loffset = mf->pos + offset;
else if (whence == SEEK_SET)
loffset = offset;
else if (whence == SEEK_END)
loffset = ((off_t)mf->size) + offset;
if (loffset < 0 && loffset > mf->size)
return -1;
mf->pos = loffset;
return mf->pos;
}
return lseek(fd.fd, offset, whence);
}
static size_t vio_mem_read(vio_fd fd, void *buf, size_t bytes) {
if(fd.vio_udata) {
vio_memfile_t *mf = (vio_memfile_t*)fd.vio_udata;
if( (mf->pos + bytes) > mf->size) {
long bc = mf->size - mf->pos;
if(bc > 0) {
memcpy(buf, mf->mem + mf->pos, bc);
mf->pos = mf->size;
return bc;
}
return 0;
}
memcpy(buf, mf->mem + mf->pos, bytes);
mf->pos += bytes;
return bytes;
}
return 0;
}
static int vio_mem_close(vio_fd *fd) {
if(fd->vio_udata){
tcc_free(fd->vio_udata);
}
return 0;
}
void set_vio_module(TCCState *s){
vio_module.user_data = NULL;
vio_module.call_vio_open_flags = CALL_VIO_OPEN_FIRST;
vio_module.vio_open = &vio_mem_open;
vio_module.vio_lseek = &vio_mem_lseek;
vio_module.vio_read = &vio_mem_read;
vio_module.vio_close = &vio_mem_close;
tcc_set_vio_module(s, &vio_module);
}
#endif
int main(int argc, char **argv)
{
int i;
@ -592,11 +500,6 @@ int main(int argc, char **argv)
m_option = NULL;
ret = 0;
#ifdef WITH_ATTACHMENTS
tcc_set_lib_path(s, ATTACH_PREFIX);
tcc_add_include_path(s, ATTACH_PREFIX);
set_vio_module(s);
#endif
optind = parse_args(s, argc - 1, argv + 1);
#if defined TCC_TARGET_X86_64 || defined TCC_TARGET_I386

24
tcc.h
View File

@ -81,15 +81,6 @@
#include "stab.h"
#include "libtcc.h"
/* virtual io to allow in memory files*/
void vio_initialize(vio_fd *fd);
int vio_open(struct TCCState *s, vio_fd *fd, const char *fn, int oflag);
off_t vio_lseek(vio_fd fd, off_t offset, int whence);
size_t vio_read(vio_fd fd, void *buf, size_t bytes);
int vio_close(vio_fd *fd);
/* parser debug */
//#define PARSE_DEBUG
/* preprocessor debug */
@ -425,7 +416,7 @@ typedef struct AttributeDef {
typedef struct BufferedFile {
uint8_t *buf_ptr;
uint8_t *buf_end;
vio_fd fd;
int fd;
struct BufferedFile *prev;
int line_num; /* current line number - here to simplify code */
int ifndef_macro; /* #ifndef macro / #endif search */
@ -670,7 +661,6 @@ struct TCCState {
unsigned int runtime_plt_and_got_offset;
#endif
#endif
vio_module_t *vio_module;
};
/* The current value can be: */
@ -1041,7 +1031,7 @@ ST_INLN Sym *sym_find(int v);
ST_FUNC Sym *global_identifier_push(int v, int t, int c);
ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen);
ST_FUNC vio_fd tcc_open(TCCState *s1, const char *filename);
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);
@ -1222,8 +1212,8 @@ ST_FUNC void relocate_syms(TCCState *s1, int do_resolve);
ST_FUNC void relocate_section(TCCState *s1, Section *s);
ST_FUNC void tcc_add_linker_symbols(TCCState *s1);
ST_FUNC int tcc_load_object_file(TCCState *s1, vio_fd fd, unsigned long file_offset);
ST_FUNC int tcc_load_archive(TCCState *s1, vio_fd fd);
ST_FUNC int tcc_load_object_file(TCCState *s1, int fd, unsigned long file_offset);
ST_FUNC int tcc_load_archive(TCCState *s1, int fd);
ST_FUNC void *tcc_get_symbol_err(TCCState *s, const char *name);
ST_FUNC void tcc_add_bcheck(TCCState *s1);
@ -1231,7 +1221,7 @@ ST_FUNC void build_got_entries(TCCState *s1);
ST_FUNC void tcc_add_runtime(TCCState *s1);
#ifndef TCC_TARGET_PE
ST_FUNC int tcc_load_dll(TCCState *s1, vio_fd fd, const char *filename, int level);
ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level);
ST_FUNC int tcc_load_ldscript(TCCState *s1);
ST_FUNC uint8_t *parse_comment(uint8_t *p);
ST_FUNC void minp(void);
@ -1315,7 +1305,7 @@ ST_FUNC void gen_cvt_itof1(int t);
#ifdef TCC_TARGET_COFF
ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f);
ST_FUNC int tcc_load_coff(TCCState * s1, vio_fd fd);
ST_FUNC int tcc_load_coff(TCCState * s1, int fd);
#endif
/* ------------ tccasm.c ------------ */
@ -1337,7 +1327,7 @@ ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str);
#endif
/* ------------ tccpe.c -------------- */
#ifdef TCC_TARGET_PE
ST_FUNC int pe_load_file(struct TCCState *s1, const char *filename, vio_fd fd);
ST_FUNC int pe_load_file(struct TCCState *s1, const char *filename, int fd);
ST_FUNC int pe_output_file(TCCState * s1, const char *filename);
ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, const void *value);
ST_FUNC SValue *pe_getimport(SValue *sv, SValue *v2);

View File

@ -858,7 +858,7 @@ Section *FindSection(TCCState * s1, const char *sname)
return 0;
}
ST_FUNC int tcc_load_coff(TCCState * s1, vio_fd fd)
ST_FUNC int tcc_load_coff(TCCState * s1, int fd)
{
// tktk TokenSym *ts;
@ -870,7 +870,7 @@ ST_FUNC int tcc_load_coff(TCCState * s1, vio_fd fd)
char name2[9];
FILHDR file_hdr; /* FILE HEADER STRUCTURE */
f = fdopen(fd.fd, "rb");
f = fdopen(fd, "rb");
if (!f) {
tcc_error("Unable to open .out file for input");
}

View File

@ -2326,13 +2326,13 @@ LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
return ret;
}
static void *load_data(vio_fd fd, unsigned long file_offset, unsigned long size)
static void *load_data(int fd, unsigned long file_offset, unsigned long size)
{
void *data;
data = tcc_malloc(size);
vio_lseek(fd, file_offset, SEEK_SET);
vio_read(fd, data, size);
lseek(fd, file_offset, SEEK_SET);
read(fd, data, size);
return data;
}
@ -2346,7 +2346,7 @@ typedef struct SectionMergeInfo {
/* load an object file and merge it with current files */
/* XXX: handle correctly stab (debug) info */
ST_FUNC int tcc_load_object_file(TCCState *s1,
vio_fd fd, unsigned long file_offset)
int fd, unsigned long file_offset)
{
ElfW(Ehdr) ehdr;
ElfW(Shdr) *shdr, *sh;
@ -2364,7 +2364,7 @@ ST_FUNC int tcc_load_object_file(TCCState *s1,
stab_index = stabstr_index = 0;
if (vio_read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
goto fail1;
if (ehdr.e_ident[0] != ELFMAG0 ||
ehdr.e_ident[1] != ELFMAG1 ||
@ -2491,9 +2491,9 @@ ST_FUNC int tcc_load_object_file(TCCState *s1,
size = sh->sh_size;
if (sh->sh_type != SHT_NOBITS) {
unsigned char *ptr;
vio_lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
ptr = section_ptr_add(s, size);
vio_read(fd, ptr, size);
read(fd, ptr, size);
} else {
s->data_offset += size;
}
@ -2649,7 +2649,7 @@ static int get_be32(const uint8_t *b)
}
/* load only the objects which resolve undefined symbols */
static int tcc_load_alacarte(TCCState *s1, vio_fd fd, int size)
static int tcc_load_alacarte(TCCState *s1, int fd, int size)
{
int i, bound, nsyms, sym_index, off, ret;
uint8_t *data;
@ -2658,7 +2658,7 @@ static int tcc_load_alacarte(TCCState *s1, vio_fd fd, int size)
ElfW(Sym) *sym;
data = tcc_malloc(size);
if (vio_read(fd, data, size) != size)
if (read(fd, data, size) != size)
goto fail;
nsyms = get_be32(data);
ar_index = data + 4;
@ -2676,7 +2676,7 @@ static int tcc_load_alacarte(TCCState *s1, vio_fd fd, int size)
printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
#endif
++bound;
vio_lseek(fd, off, SEEK_SET);
lseek(fd, off, SEEK_SET);
if(tcc_load_object_file(s1, fd, off) < 0) {
fail:
ret = -1;
@ -2693,7 +2693,7 @@ static int tcc_load_alacarte(TCCState *s1, vio_fd fd, int size)
}
/* load a '.a' file */
ST_FUNC int tcc_load_archive(TCCState *s1, vio_fd fd)
ST_FUNC int tcc_load_archive(TCCState *s1, int fd)
{
ArchiveHeader hdr;
char ar_size[11];
@ -2703,10 +2703,10 @@ ST_FUNC int tcc_load_archive(TCCState *s1, vio_fd fd)
unsigned long file_offset;
/* skip magic which was already checked */
vio_read(fd, magic, sizeof(magic));
read(fd, magic, sizeof(magic));
for(;;) {
len = vio_read(fd, &hdr, sizeof(hdr));
len = read(fd, &hdr, sizeof(hdr));
if (len == 0)
break;
if (len != sizeof(hdr)) {
@ -2723,7 +2723,7 @@ ST_FUNC int tcc_load_archive(TCCState *s1, vio_fd fd)
}
ar_name[i + 1] = '\0';
// printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
file_offset = vio_lseek(fd, 0, SEEK_CUR);
file_offset = lseek(fd, 0, SEEK_CUR);
/* align to even */
size = (size + 1) & ~1;
if (!strcmp(ar_name, "/")) {
@ -2739,7 +2739,7 @@ ST_FUNC int tcc_load_archive(TCCState *s1, vio_fd fd)
if (tcc_load_object_file(s1, fd, file_offset) < 0)
return -1;
}
vio_lseek(fd, file_offset + size, SEEK_SET);
lseek(fd, file_offset + size, SEEK_SET);
}
return 0;
}
@ -2748,7 +2748,7 @@ ST_FUNC int tcc_load_archive(TCCState *s1, vio_fd fd)
/* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
is referenced by the user (so it should be added as DT_NEEDED in
the generated ELF file) */
ST_FUNC int tcc_load_dll(TCCState *s1, vio_fd fd, const char *filename, int level)
ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
{
ElfW(Ehdr) ehdr;
ElfW(Shdr) *shdr, *sh, *sh1;
@ -2759,7 +2759,7 @@ ST_FUNC int tcc_load_dll(TCCState *s1, vio_fd fd, const char *filename, int leve
const char *name, *soname;
DLLReference *dllref;
vio_read(fd, &ehdr, sizeof(ehdr));
read(fd, &ehdr, sizeof(ehdr));
/* test CPU specific stuff */
if (ehdr.e_ident[5] != ELFDATA2LSB ||
@ -2986,13 +2986,14 @@ static int ld_next(TCCState *s1, char *name, int name_size)
/*
* Extract the file name from the library name
*
* /!\ No test on filename capacity, be careful
*/
static void libname_to_filename(TCCState *s1, const char libname[], char filename[], size_t size)
static void libname_to_filename(TCCState *s1, const char libname[], char filename[])
{
if (!s1->static_link) {
snprintf(filename, size, "lib%s.so", libname);
sprintf(filename, "lib%s.so", libname);
} else {
snprintf(filename, size, "lib%s.a", libname);
sprintf(filename, "lib%s.a", libname);
}
}
@ -3043,7 +3044,7 @@ static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
goto lib_parse_error;
}
strcpy(libname, &filename[1]);
libname_to_filename(s1, libname, filename, sizeof(libname));
libname_to_filename(s1, libname, filename);
} else if (t != LD_TOK_NAME) {
tcc_error_noabort("filename expected");
ret = -1;

View File

@ -1638,9 +1638,9 @@ static int pe_load_dll(TCCState *s1, const char *dllname, FILE *fp)
}
/* ------------------------------------------------------------- */
ST_FUNC int pe_load_file(struct TCCState *s1, const char *filename, vio_fd fd)
ST_FUNC int pe_load_file(struct TCCState *s1, const char *filename, int fd)
{
FILE *fp = fdopen(dup(fd.fd), "rb");
FILE *fp = fdopen(dup(fd), "rb");
int ret = -1;
char buf[10];
if (fp) {

16
tccpp.c
View File

@ -360,13 +360,13 @@ static int tcc_peekc_slow(BufferedFile *bf)
int len;
/* only tries to read if really end of buffer */
if (bf->buf_ptr >= bf->buf_end) {
if (bf->fd.fd != -1) {
if (bf->fd != -1) {
#if defined(PARSE_DEBUG)
len = 8;
#else
len = IO_BUF_SIZE;
#endif
len = vio_read(bf->fd, bf->buffer, len);
len = read(bf->fd, bf->buffer, len);
if (len < 0)
len = 0;
} else {
@ -1438,8 +1438,6 @@ ST_FUNC void preprocess(int is_bof)
CachedInclude *e;
BufferedFile **f;
const char *path;
int size;
vio_fd fd;
if (i == -2) {
/* check absolute include path */
@ -1452,9 +1450,8 @@ ST_FUNC void preprocess(int is_bof)
/* search in current dir if "header.h" */
if (c != '\"')
continue;
size = tcc_basename(file->filename) - file->filename;
memcpy(buf1, file->filename, size);
buf1[size] = '\0';
path = file->filename;
pstrncpy(buf1, path, tcc_basename(path) - path);
} else {
/* search in all the include paths */
@ -1484,13 +1481,10 @@ ST_FUNC void preprocess(int is_bof)
#ifdef INC_DEBUG
printf("%s: skipping cached %s\n", file->filename, buf1);
#endif
vio_initialize(&fd);
fd.fd = 0;
goto include_done;
}
fd = tcc_open(s1, buf1);
if (fd.fd < 0)
if (tcc_open(s1, buf1) < 0)
include_trynext:
continue;