From c0bdb33ac1e3bd3549c446ae7bc70b0a68dd71dd Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Sat, 5 Oct 2024 11:15:20 +0200 Subject: [PATCH 1/5] feat: Added execution of files in a directory --- src/cjit.c | 14 ++++++++- src/file.c | 66 ++++++++++++++++++++++++++++++++++++++++- test/multifile/main.c | 11 +++++++ test/multifile/myfunc.c | 5 ++++ test/multifile/myfunc.h | 1 + 5 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 test/multifile/main.c create mode 100644 test/multifile/myfunc.c create mode 100644 test/multifile/myfunc.h diff --git a/src/cjit.c b/src/cjit.c index 0741691..0a3e784 100644 --- a/src/cjit.c +++ b/src/cjit.c @@ -64,6 +64,7 @@ extern unsigned int lib_tinycc_include_varargs_h_len; // from file.c extern long file_size(const char *filename); extern char* file_load(const char *filename); +extern char* dir_load(const char *path); extern bool write_to_file(char *path, char *filename, char *buf, unsigned int len); extern bool rm_recursive(char *path); #ifdef LIBC_MINGW32 @@ -857,13 +858,16 @@ int main(int argc, char **argv) { // const char *progname = "cjit"; static bool verbose = false; static bool version = false; + static bool directory = false; char tmptemplate[] = "/tmp/CJIT-exec.XXXXXX"; char *tmpdir = NULL; + char *code = NULL; int res = 1; static const struct cflag options[] = { CFLAG(bool, "verbose", 'v', &verbose, "Verbosely show progress"), CFLAG(bool, "version", 'V', &version, "Show build version"), + CFLAG(bool, "directory", 'd', &directory, "Execute program spread over multiple files in the directory"), CFLAG_HELP, CFLAG_END }; @@ -924,7 +928,15 @@ int main(int argc, char **argv) { goto endgame; } _err("Source to execute: %s",code_path); - char *code = file_load(code_path); + + if (directory) { + _err("(it is a directory path)"); + tcc_add_include_path(TCC, code_path); + code = dir_load(code_path); + } else { + code = file_load(code_path); + } + char *err_msg = NULL; if(!code) { _err("File not found: %s",code_path); diff --git a/src/file.c b/src/file.c index 22fdfcc..0eebe1b 100644 --- a/src/file.c +++ b/src/file.c @@ -32,8 +32,11 @@ #include #pragma comment(lib, "rpcrt4.lib") #pragma comment(lib, "shlwapi.lib") +#else +#include +#include +#include #endif - extern void _err(const char *fmt, ...); // Function to get the length of a file in bytes @@ -115,6 +118,67 @@ bool rm_recursive(char *path) { return true; } +#ifndef LIBC_MINGW32 +char *dir_load(const char *path) +{ + struct stat sb; + struct dirent *de; + DIR *dir; + FILE *fd; + char *content = NULL; + char *full_content = NULL; + + if (stat(path, &sb) != 0) { + _err("Error: %s",path); + _err("%s",strerror(errno)); + return NULL; + } + if (!S_ISDIR(sb.st_mode)) { + _err("Error: %s is not a directory",path); + return NULL; + } + dir = opendir(path); + if (dir == NULL) { + _err("Error: opendir %s",path); + _err("%s",strerror(errno)); + return NULL; + } + for (de = readdir(dir); de != NULL; de = readdir(dir)) { + if (de->d_type == DT_REG) { + char fullpath[256]; + snprintf(fullpath,255,"%s/%s",path,de->d_name); + content = file_load(fullpath); + if (content == NULL) { + _err("Error: file_load %s",fullpath); + return NULL; + } + if (full_content == NULL) { + full_content = content; + } else { + full_content = realloc(full_content, strlen(full_content) + strlen(content) + 1); + if (full_content == NULL) { + _err("Error: realloc full_content"); + return NULL; + } + strcat(full_content, content); + } + } + } + return full_content; +} + +#else +char *dir_load(const char *path) +{ + /* FIXME */ + _err("Error: dir_load not implemented on Windows"); + return NULL; +} + + +#endif + + #ifdef LIBC_MINGW32 /////////////// // WINDOWS SHIT diff --git a/test/multifile/main.c b/test/multifile/main.c new file mode 100644 index 0000000..52974d8 --- /dev/null +++ b/test/multifile/main.c @@ -0,0 +1,11 @@ +#include +#include "myfunc.h" + + + +int main(void) +{ + myfunc(); + return 0; + +} diff --git a/test/multifile/myfunc.c b/test/multifile/myfunc.c new file mode 100644 index 0000000..28fa932 --- /dev/null +++ b/test/multifile/myfunc.c @@ -0,0 +1,5 @@ +int myfunc(void) +{ + printf("hello from myfunc()\n"); + return 0; +} diff --git a/test/multifile/myfunc.h b/test/multifile/myfunc.h new file mode 100644 index 0000000..ca80884 --- /dev/null +++ b/test/multifile/myfunc.h @@ -0,0 +1 @@ +int myfunc(void); From 4123e97aff7389695db38220abb9dc0f581a26a7 Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Sat, 5 Oct 2024 11:26:57 +0200 Subject: [PATCH 2/5] only include C files. Recurse through subdirs. --- src/file.c | 53 +++++++++++++++++++++++++--------- test/multifile/a/b/c/myfunc3.c | 7 +++++ test/multifile/main.c | 2 ++ test/multifile/myfunc.h | 2 ++ test/multifile/myfunc2.c | 6 ++++ 5 files changed, 57 insertions(+), 13 deletions(-) create mode 100644 test/multifile/a/b/c/myfunc3.c create mode 100644 test/multifile/myfunc2.c diff --git a/src/file.c b/src/file.c index 0eebe1b..2046a62 100644 --- a/src/file.c +++ b/src/file.c @@ -145,22 +145,49 @@ char *dir_load(const char *path) } for (de = readdir(dir); de != NULL; de = readdir(dir)) { if (de->d_type == DT_REG) { - char fullpath[256]; - snprintf(fullpath,255,"%s/%s",path,de->d_name); - content = file_load(fullpath); - if (content == NULL) { - _err("Error: file_load %s",fullpath); - return NULL; - } - if (full_content == NULL) { - full_content = content; - } else { - full_content = realloc(full_content, strlen(full_content) + strlen(content) + 1); + int name_len = strlen(de->d_name); + /* Only add C files */ + if ((de->d_name[name_len - 1] == 'c') && + (de->d_name[name_len - 2] == '.')) { + char fullpath[256]; + snprintf(fullpath,255,"%s/%s",path,de->d_name); + content = file_load(fullpath); + if (content == NULL) { + _err("Error: file_load %s",fullpath); + return NULL; + } if (full_content == NULL) { - _err("Error: realloc full_content"); + full_content = content; + } else { + full_content = realloc(full_content, strlen(full_content) + strlen(content) + 1); + if (full_content == NULL) { + _err("Error: realloc full_content"); + return NULL; + } + strcat(full_content, content); + } + } + } else if (de->d_type == DT_DIR) { + /* Exclude '.', '..' and hidden directories */ + if (de->d_name[0] != '.') { + /* Recurse into subdirectories */ + char fullpath[256]; + snprintf(fullpath,255,"%s/%s",path,de->d_name); + content = dir_load(fullpath); + if (content == NULL) { + _err("Error: dir_load %s",fullpath); return NULL; } - strcat(full_content, content); + if (full_content == NULL) { + full_content = content; + } else { + full_content = realloc(full_content, strlen(full_content) + strlen(content) + 1); + if (full_content == NULL) { + _err("Error: realloc full_content"); + return NULL; + } + strcat(full_content, content); + } } } } diff --git a/test/multifile/a/b/c/myfunc3.c b/test/multifile/a/b/c/myfunc3.c new file mode 100644 index 0000000..806775b --- /dev/null +++ b/test/multifile/a/b/c/myfunc3.c @@ -0,0 +1,7 @@ +#include + +int myfunc3(void) +{ + printf("hello from myfunc3\n"); + return 0; +} diff --git a/test/multifile/main.c b/test/multifile/main.c index 52974d8..ee99f17 100644 --- a/test/multifile/main.c +++ b/test/multifile/main.c @@ -6,6 +6,8 @@ int main(void) { myfunc(); + myfunc2(); + myfunc3(); return 0; } diff --git a/test/multifile/myfunc.h b/test/multifile/myfunc.h index ca80884..909bff8 100644 --- a/test/multifile/myfunc.h +++ b/test/multifile/myfunc.h @@ -1 +1,3 @@ int myfunc(void); +int myfunc2(void); +int myfunc3(void); diff --git a/test/multifile/myfunc2.c b/test/multifile/myfunc2.c new file mode 100644 index 0000000..80d536e --- /dev/null +++ b/test/multifile/myfunc2.c @@ -0,0 +1,6 @@ +#include +int myfunc2(void) +{ + printf("hello from myfunc2\n"); + return 0; +} From 1a366037a97f250c711324a74c8e99cdf7547676 Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Sun, 6 Oct 2024 11:56:06 +0200 Subject: [PATCH 3/5] Multi-file: use nftw(3) --- src/file.c | 89 +++++++++++++++++++++--------------------------------- 1 file changed, 35 insertions(+), 54 deletions(-) diff --git a/src/file.c b/src/file.c index 2046a62..61843ee 100644 --- a/src/file.c +++ b/src/file.c @@ -71,6 +71,8 @@ char* file_load(const char *filename) { return NULL; } + _err("Loading source file %s",filename); + fread(contents, 1, length, file); contents[length] = '\0'; // Null-terminate the string fclose(file); @@ -119,14 +121,41 @@ bool rm_recursive(char *path) { } #ifndef LIBC_MINGW32 + +static char *full_content = NULL; + + +static int file_load_ftw(const char *pathname, + const struct stat *sbuf, + int type, struct FTW *ftwb) { + FILE *fd; + char *content = NULL; + if (type == FTW_F) { + content = file_load(pathname); + if (content == NULL) { + _err("Error: file_load %s",pathname); + return -1; + } + if (full_content == NULL) { + full_content = content; + } else { + full_content = realloc(full_content, strlen(full_content) + strlen(content) + 1); + if (full_content == NULL) { + _err("Error: realloc full_content"); + return -1; + } + strcat(full_content, content); + } + } + return 0; +} + +/* dir_load: nftw version */ char *dir_load(const char *path) { struct stat sb; - struct dirent *de; - DIR *dir; FILE *fd; char *content = NULL; - char *full_content = NULL; if (stat(path, &sb) != 0) { _err("Error: %s",path); @@ -137,63 +166,15 @@ char *dir_load(const char *path) _err("Error: %s is not a directory",path); return NULL; } - dir = opendir(path); - if (dir == NULL) { - _err("Error: opendir %s",path); + if (nftw(path, file_load_ftw, 10, FTW_DEPTH|FTW_MOUNT|FTW_PHYS) < 0) { + _err("Error: nftw path %s",path); _err("%s",strerror(errno)); return NULL; } - for (de = readdir(dir); de != NULL; de = readdir(dir)) { - if (de->d_type == DT_REG) { - int name_len = strlen(de->d_name); - /* Only add C files */ - if ((de->d_name[name_len - 1] == 'c') && - (de->d_name[name_len - 2] == '.')) { - char fullpath[256]; - snprintf(fullpath,255,"%s/%s",path,de->d_name); - content = file_load(fullpath); - if (content == NULL) { - _err("Error: file_load %s",fullpath); - return NULL; - } - if (full_content == NULL) { - full_content = content; - } else { - full_content = realloc(full_content, strlen(full_content) + strlen(content) + 1); - if (full_content == NULL) { - _err("Error: realloc full_content"); - return NULL; - } - strcat(full_content, content); - } - } - } else if (de->d_type == DT_DIR) { - /* Exclude '.', '..' and hidden directories */ - if (de->d_name[0] != '.') { - /* Recurse into subdirectories */ - char fullpath[256]; - snprintf(fullpath,255,"%s/%s",path,de->d_name); - content = dir_load(fullpath); - if (content == NULL) { - _err("Error: dir_load %s",fullpath); - return NULL; - } - if (full_content == NULL) { - full_content = content; - } else { - full_content = realloc(full_content, strlen(full_content) + strlen(content) + 1); - if (full_content == NULL) { - _err("Error: realloc full_content"); - return NULL; - } - strcat(full_content, content); - } - } - } - } return full_content; } + #else char *dir_load(const char *path) { From 3eb54b9995f799b1375874a55094fe2ce2158add Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Sun, 6 Oct 2024 12:03:08 +0200 Subject: [PATCH 4/5] Removed '-d' command option Directory is automatically recognized and added recursively --- src/cjit.c | 21 +++++++++++++++------ test/multifile/myfunc.c | 2 +- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/cjit.c b/src/cjit.c index 0a3e784..35c3eef 100644 --- a/src/cjit.c +++ b/src/cjit.c @@ -858,7 +858,6 @@ int main(int argc, char **argv) { // const char *progname = "cjit"; static bool verbose = false; static bool version = false; - static bool directory = false; char tmptemplate[] = "/tmp/CJIT-exec.XXXXXX"; char *tmpdir = NULL; char *code = NULL; @@ -867,7 +866,6 @@ int main(int argc, char **argv) { static const struct cflag options[] = { CFLAG(bool, "verbose", 'v', &verbose, "Verbosely show progress"), CFLAG(bool, "version", 'V', &version, "Show build version"), - CFLAG(bool, "directory", 'd', &directory, "Execute program spread over multiple files in the directory"), CFLAG_HELP, CFLAG_END }; @@ -929,13 +927,24 @@ int main(int argc, char **argv) { } _err("Source to execute: %s",code_path); - if (directory) { - _err("(it is a directory path)"); - tcc_add_include_path(TCC, code_path); - code = dir_load(code_path); + +#ifndef LIBC_MINGW32 // POSIX only + struct stat st; + if (stat(code_path, &st) == -1) { + _err("File not found: %s",code_path); + goto endgame; + } + if (S_ISDIR(st.st_mode)) { + _err("%s: it is a directory path. Recursively adding all sources.", code_path); + tcc_add_include_path(TCC, code_path); + code = dir_load(code_path); } else { code = file_load(code_path); } +#else + /* FIXME: Add Windows support for directory */ + code = file_load(code_path); +#endif char *err_msg = NULL; if(!code) { diff --git a/test/multifile/myfunc.c b/test/multifile/myfunc.c index 28fa932..ad2069a 100644 --- a/test/multifile/myfunc.c +++ b/test/multifile/myfunc.c @@ -1,5 +1,5 @@ int myfunc(void) { - printf("hello from myfunc()\n"); + printf("hello from myfunc\n"); return 0; } From 3887d98e6c061dad7bfecfaac956085502d64356 Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Sun, 6 Oct 2024 12:27:04 +0200 Subject: [PATCH 5/5] Only add C files in directory load --- src/file.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/file.c b/src/file.c index 61843ee..9593381 100644 --- a/src/file.c +++ b/src/file.c @@ -131,20 +131,24 @@ static int file_load_ftw(const char *pathname, FILE *fd; char *content = NULL; if (type == FTW_F) { - content = file_load(pathname); - if (content == NULL) { - _err("Error: file_load %s",pathname); - return -1; - } - if (full_content == NULL) { - full_content = content; - } else { - full_content = realloc(full_content, strlen(full_content) + strlen(content) + 1); - if (full_content == NULL) { - _err("Error: realloc full_content"); + size_t pathlen = strlen(pathname); + if (pathname[pathlen-1] == 'c' && + pathname[pathlen-2] == '.') { + content = file_load(pathname); + if (content == NULL) { + _err("Error: file_load %s",pathname); return -1; } - strcat(full_content, content); + if (full_content == NULL) { + full_content = content; + } else { + full_content = realloc(full_content, strlen(full_content) + strlen(content) + 1); + if (full_content == NULL) { + _err("Error: realloc full_content"); + return -1; + } + strcat(full_content, content); + } } } return 0;