Added what I call virtual io to tinycc this way we can make a monolitic executable...
authormingodad <mingodad@gmail.com>
Fri, 11 Jan 2013 00:04:38 +0000 (11 00:04 +0000)
committermingodad <mingodad@gmail.com>
Fri, 11 Jan 2013 00:04:38 +0000 (11 00:04 +0000)
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.

12 files changed:
Makefile
bin2c.c [new file with mode: 0644]
libtcc.c
libtcc.h
mk-attachments.sh [new file with mode: 0755]
mk-it [new file with mode: 0755]
tcc.c
tcc.h
tcccoff.c
tccelf.c
tccpe.c
tccpp.c

index c8bca47..8281d56 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -172,15 +172,20 @@ PROGS+=$(PROGS_CROSS)
 TCCLIBS+=$(LIBTCC1_CROSS)
 endif
 
-all: $(PROGS) $(TCCLIBS) $(TCCDOCS)
+ifdef CONFIG_USE_ATTACHMENTS
+FILE_ATTACHMENTS= tcc_attachments.o
+CFLAGS += -DWITH_ATTACHMENTS=1
+endif
+
+all: $(PROGS) $(TCCLIBS) $(FILE_ATTACHMENTS) $(TCCDOCS) 
 
 # Host Tiny C Compiler
 tcc$(EXESUF): tcc.o $(LIBTCC)
-       $(CC) -o $@ $^ $(LIBS) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(LINK_LIBTCC)
+       $(CC) -o $@ $^ $(LIBS) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)  $(FILE_ATTACHMENTS)  $(LINK_LIBTCC)
 
 # Cross Tiny C Compilers
 %-tcc$(EXESUF):
-       $(CC) -o $@ tcc.c -DONE_SOURCE $(DEFINES) $(CPPFLAGS) $(CFLAGS) $(LIBS) $(LDFLAGS)
+       $(CC) -o $@ tcc.c -DONE_SOURCE $(DEFINES) $(CPPFLAGS) $(CFLAGS) $(FILE_ATTACHMENTS) $(LIBS) $(LDFLAGS)
 
 $(I386_CROSS): DEFINES = -DTCC_TARGET_I386 \
     -DCONFIG_TCCDIR="\"$(tccdir)/i386\""
@@ -227,9 +232,12 @@ 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) $(LDFLAGS_P)
+       $(CC) -o $@ $< $(NATIVE_DEFINES) $(CPPFLAGS_P) $(CFLAGS_P) $(LIBS_P) $(FILE_ATTACHMENTS) $(LDFLAGS_P)
 
 # windows utilities
 tiny_impdef$(EXESUF): win32/tools/tiny_impdef.c
diff --git a/bin2c.c b/bin2c.c
new file mode 100644 (file)
index 0000000..e8d2795
--- /dev/null
+++ b/bin2c.c
@@ -0,0 +1,615 @@
+
+#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;
+}
index b0a9b1a..f554f74 100644 (file)
--- a/libtcc.c
+++ b/libtcc.c
@@ -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;
index 278dca3..791cd29 100644 (file)
--- a/libtcc.h
+++ b/libtcc.h
@@ -13,6 +13,28 @@ 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);
 
@@ -32,6 +54,9 @@ 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 */
 
@@ -58,6 +83,10 @@ 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 */
 
diff --git a/mk-attachments.sh b/mk-attachments.sh
new file mode 100755 (executable)
index 0000000..18cc0b0
--- /dev/null
@@ -0,0 +1,4 @@
+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
diff --git a/mk-it b/mk-it
new file mode 100755 (executable)
index 0000000..f73d3e6
--- /dev/null
+++ b/mk-it
@@ -0,0 +1,8 @@
+rm *.a
+rm *.o
+make
+./mk-attachments.sh
+rm tcc.o
+make CONFIG_USE_ATTACHMENTS=1
+strip tcc
+
diff --git a/tcc.c b/tcc.c
index 5dd5725..f4d94be 100644 (file)
--- a/tcc.c
+++ b/tcc.c
@@ -479,6 +479,98 @@ 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;
@@ -500,6 +592,11 @@ 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
diff --git a/tcc.h b/tcc.h
index 5489b49..b738bc1 100644 (file)
--- a/tcc.h
+++ b/tcc.h
 #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 */
@@ -416,7 +425,7 @@ typedef struct AttributeDef {
 typedef struct BufferedFile {
     uint8_t *buf_ptr;
     uint8_t *buf_end;
-    int fd;
+    vio_fd fd;
     struct BufferedFile *prev;
     int line_num;    /* current line number - here to simplify code */
     int ifndef_macro;  /* #ifndef macro / #endif search */
@@ -661,6 +670,7 @@ struct TCCState {
     unsigned int runtime_plt_and_got_offset;
 #endif
 #endif
+   vio_module_t *vio_module;
 };
 
 /* The current value can be: */
@@ -1031,7 +1041,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 int tcc_open(TCCState *s1, const char *filename);
+ST_FUNC vio_fd 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);
@@ -1212,8 +1222,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, int fd, unsigned long file_offset);
-ST_FUNC int tcc_load_archive(TCCState *s1, int fd);
+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 void *tcc_get_symbol_err(TCCState *s, const char *name);
 ST_FUNC void tcc_add_bcheck(TCCState *s1);
 
@@ -1221,7 +1231,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, int fd, const char *filename, int level);
+ST_FUNC int tcc_load_dll(TCCState *s1, vio_fd 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);
@@ -1305,7 +1315,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, int fd);
+ST_FUNC int tcc_load_coff(TCCState * s1, vio_fd fd);
 #endif
 
 /* ------------ tccasm.c ------------ */
@@ -1327,7 +1337,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, int fd);
+ST_FUNC int pe_load_file(struct TCCState *s1, const char *filename, vio_fd 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);
index 2f52562..76262a1 100644 (file)
--- a/tcccoff.c
+++ b/tcccoff.c
@@ -858,7 +858,7 @@ Section *FindSection(TCCState * s1, const char *sname)
     return 0;
 }
 
-ST_FUNC int tcc_load_coff(TCCState * s1, int fd)
+ST_FUNC int tcc_load_coff(TCCState * s1, vio_fd fd)
 {
 // tktk TokenSym *ts;
 
@@ -870,7 +870,7 @@ ST_FUNC int tcc_load_coff(TCCState * s1, int fd)
     char name2[9];
     FILHDR file_hdr;           /* FILE HEADER STRUCTURE              */
 
-    f = fdopen(fd, "rb");
+    f = fdopen(fd.fd, "rb");
     if (!f) {
        tcc_error("Unable to open .out file for input");
     }
index da81d03..18ea94d 100644 (file)
--- a/tccelf.c
+++ b/tccelf.c
@@ -2326,13 +2326,13 @@ LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
     return ret;
 }
 
-static void *load_data(int fd, unsigned long file_offset, unsigned long size)
+static void *load_data(vio_fd fd, unsigned long file_offset, unsigned long size)
 {
     void *data;
 
     data = tcc_malloc(size);
-    lseek(fd, file_offset, SEEK_SET);
-    read(fd, data, size);
+    vio_lseek(fd, file_offset, SEEK_SET);
+    vio_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, 
-                                int fd, unsigned long file_offset)
+                                vio_fd 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 (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
+    if (vio_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;
-            lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
+            vio_lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
             ptr = section_ptr_add(s, size);
-            read(fd, ptr, size);
+            vio_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, int fd, int size)
+static int tcc_load_alacarte(TCCState *s1, vio_fd 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, int fd, int size)
     ElfW(Sym) *sym;
 
     data = tcc_malloc(size);
-    if (read(fd, data, size) != size)
+    if (vio_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, int fd, int size)
                     printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
 #endif
                     ++bound;
-                    lseek(fd, off, SEEK_SET);
+                    vio_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, int fd, int size)
 }
 
 /* load a '.a' file */
-ST_FUNC int tcc_load_archive(TCCState *s1, int fd)
+ST_FUNC int tcc_load_archive(TCCState *s1, vio_fd fd)
 {
     ArchiveHeader hdr;
     char ar_size[11];
@@ -2703,10 +2703,10 @@ ST_FUNC int tcc_load_archive(TCCState *s1, int fd)
     unsigned long file_offset;
 
     /* skip magic which was already checked */
-    read(fd, magic, sizeof(magic));
+    vio_read(fd, magic, sizeof(magic));
     
     for(;;) {
-        len = read(fd, &hdr, sizeof(hdr));
+        len = vio_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, int fd)
         }
         ar_name[i + 1] = '\0';
         //        printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
-        file_offset = lseek(fd, 0, SEEK_CUR);
+        file_offset = vio_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, int fd)
             if (tcc_load_object_file(s1, fd, file_offset) < 0)
                 return -1;
         }
-        lseek(fd, file_offset + size, SEEK_SET);
+        vio_lseek(fd, file_offset + size, SEEK_SET);
     }
     return 0;
 }
@@ -2748,7 +2748,7 @@ ST_FUNC int tcc_load_archive(TCCState *s1, int 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, int fd, const char *filename, int level)
+ST_FUNC int tcc_load_dll(TCCState *s1, vio_fd 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, int fd, const char *filename, int level)
     const char *name, *soname;
     DLLReference *dllref;
     
-    read(fd, &ehdr, sizeof(ehdr));
+    vio_read(fd, &ehdr, sizeof(ehdr));
 
     /* test CPU specific stuff */
     if (ehdr.e_ident[5] != ELFDATA2LSB ||
@@ -2986,14 +2986,13 @@ 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[])
+static void libname_to_filename(TCCState *s1, const char libname[], char filename[], size_t size)
 {
     if (!s1->static_link) {
-        sprintf(filename, "lib%s.so", libname);
+        snprintf(filename, size, "lib%s.so", libname);
     } else {
-        sprintf(filename, "lib%s.a", libname);
+        snprintf(filename, size, "lib%s.a", libname);
     }
 }
 
@@ -3044,7 +3043,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);
+            libname_to_filename(s1, libname, filename, sizeof(libname));
         } else if (t != LD_TOK_NAME) {
             tcc_error_noabort("filename expected");
             ret = -1;
diff --git a/tccpe.c b/tccpe.c
index 187b710..a956da4 100644 (file)
--- a/tccpe.c
+++ b/tccpe.c
@@ -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, int fd)
+ST_FUNC int pe_load_file(struct TCCState *s1, const char *filename, vio_fd fd)
 {
-    FILE *fp = fdopen(dup(fd), "rb");
+    FILE *fp = fdopen(dup(fd.fd), "rb");
     int ret = -1;
     char buf[10];
     if (fp) {
diff --git a/tccpp.c b/tccpp.c
index c0c7aec..cc54dee 100644 (file)
--- a/tccpp.c
+++ b/tccpp.c
@@ -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 != -1) {
+        if (bf->fd.fd != -1) {
 #if defined(PARSE_DEBUG)
             len = 8;
 #else
             len = IO_BUF_SIZE;
 #endif
-            len = read(bf->fd, bf->buffer, len);
+            len = vio_read(bf->fd, bf->buffer, len);
             if (len < 0)
                 len = 0;
         } else {
@@ -1438,6 +1438,8 @@ 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 */
@@ -1450,8 +1452,9 @@ ST_FUNC void preprocess(int is_bof)
                 /* search in current dir if "header.h" */
                 if (c != '\"')
                     continue;
-                path = file->filename;
-                pstrncpy(buf1, path, tcc_basename(path) - path);
+                size = tcc_basename(file->filename) - file->filename;
+                memcpy(buf1, file->filename, size);
+                buf1[size] = '\0';
 
             } else {
                 /* search in all the include paths */
@@ -1481,10 +1484,13 @@ 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;
             }
 
-            if (tcc_open(s1, buf1) < 0)
+                       fd = tcc_open(s1, buf1);
+            if (fd.fd < 0)
 include_trynext:
                 continue;