fmake

make any project just by typing `fmake`
git clone git@getsh.org:fmake.git
Log | Files | Refs | README | LICENSE

commit 25f0c3f420d1df1bc71228ba96bcf0dc7ff5eed9
parent fdaf28d9eec999deef4b0ae67ed6b0106a26041e
Author: Bharatvaj Hemanth <bharatvaj@yahoo.com>
Date:   Thu,  4 Jul 2024 04:39:05 +0530

Add enum for describing file type: file, dir or ext

Fix properly close dir with closedir

Diffstat:
Mconfig.h | 55+++++++++++++++++++++++++++++++------------------------
Mfmake.c | 56+++++++++++++++++++++++++++++---------------------------
2 files changed, 60 insertions(+), 51 deletions(-)

diff --git a/config.h b/config.h @@ -1,30 +1,37 @@ +typedef enum { + FMAKE_FILE, + FMAKE_DIR, + FMAKE_EXT +} file_type_t; + #define BUILD_SYSTEMS \ - X(0, "Makefile" , "make") \ - X(0, "makefile" , "make") \ - X(0, "GNUMakefile" , "gmake") \ - X(0, "BSDMakefile" , "bmake") \ - X(1, "pro" , "qmake") \ - X(0, "make" , "sh" , "make") \ - X(0, "build.sh" , "sh" , "build.sh") \ - X(0, "build.ninja" , "ninja") \ - X(0, "OMakefile" , "omake") \ - X(0, "configure" , "sh" , "configure") \ - X(0, "configure.ac" , "autoreconf" , "-fiv") \ - X(0, "CMakeLists.txt" , "cmake" , "-B" , "out/") \ - X(0, "BUILD.gn" , "gn" , "gen" , "out/") \ - X(0, "nob" , "./nob" , "./nob") \ - X(0, "nob.c" , "cc" , "cc" , "./nob.c" , "-o" , "nob") \ - X(0, "nobuild" , "./nobuild" , ) \ - X(0, "nobuild.c" , "cc" , "./nobuild.c" , "-o" , "nobuild") \ - X(0, "package.json" , "npm" , "run") \ - X(0, "Cargo.toml" , "cargo" , "build") \ - X(0, "setup.py" , "pip" , "install" , ".") \ - X(0, "gradlew.bat" , "./gradlew.bat" , "./gradlew.bat") \ - X(0, "gradlew" , "sh" , "gradlew") \ - X(0, "PKGBUILD" , "makepkg" , "-i") + X(0 , "Makefile" , "make") \ + X(0 , "makefile" , "make") \ + X(0 , "GNUMakefile" , "gmake") \ + X(0 , "BSDMakefile" , "bmake") \ + X(2 , "pro" , "qmake") \ + X(0 , "make" , "sh" , "make") \ + X(0 , "build.sh" , "sh" , "build.sh") \ + X(0 , "build.ninja" , "ninja") \ + X(0 , "OMakefile" , "omake") \ + X(0 , "configure" , "sh" , "configure") \ + X(0 , "configure.ac" , "autoreconf" , "-fiv") \ + X(0 , "CMakeLists.txt" , "cmake" , "-B" , "out/") \ + X(0 , "BUILD.gn" , "gn" , "gen" , "out/") \ + X(0 , "nob" , "./nob") \ + X(0 , "nob.c" , "cc" , "./nob.c" , "-o" , "nob") \ + X(0 , "nobuild" , "./nobuild" , ) \ + X(0 , "nobuild.c" , "cc" , "./nobuild.c" , "-o" , "nobuild") \ + X(0 , "package.json" , "npm" , "install") \ + X(1 , "node_modules" , "npm" , "run") \ + X(0 , "Cargo.toml" , "cargo" , "build") \ + X(0 , "setup.py" , "pip" , "install" , ".") \ + X(0 , "gradlew.bat" , "./gradlew.bat") \ + X(0 , "gradlew" , "sh" , "gradlew") \ + X(0 , "PKGBUILD" , "makepkg" , "-i") typedef struct { -short check_extension; +file_type_t file_type; const char* filename; const char* cmd; const char* args[256]; diff --git a/fmake.c b/fmake.c @@ -7,7 +7,8 @@ #include "config.h" static maker_config_t maker; -static DIR *dir; +// TODO assigning NULL can be avoided +static DIR *dir = NULL; static struct dirent *entry; static short should_execute_commands = 0; static short is_accepting_cmd_args = 0; @@ -15,7 +16,7 @@ static short is_accepting_cmd_args = 0; #define info(...) \ if (should_execute_commands) { \ - fprintf(stderr, __VA_ARGS__); \ + fprintf(stderr, __VA_ARGS__); \ } int process_build(char* argv[]) { @@ -34,7 +35,8 @@ int process_build(char* argv[]) { status = execvp(maker.cmd, (char* const*)maker.args); } if (status == -1) { - printf("Error: %d\n", status); + perror(maker.cmd); + //printf("Error: %d\n", status); } } return status; @@ -42,7 +44,8 @@ int process_build(char* argv[]) { int main(int argc, char* argv[]) { - int i; + int i = 0; + int makers_size = sizeof(makers) / sizeof(maker_config_t); for(i = 1; i < argc; i++) { if (!(argv[i][0] == '-' && argv[i][1] != '\0')) { printf("Usage: fmake [-l]\n"); @@ -68,34 +71,33 @@ int main(int argc, char* argv[]) { FMAKE_AFTER_ARG_CHECK: argc = i; argv = argv + i; - for (size_t i = 0; i < (sizeof(makers) / sizeof(maker_config_t)); i++) { - if (makers[i].check_extension) { - // TODO optimize this code - // FIXME it's not sure if the '.' is found from first or last - // last should be preferred - dir = opendir("./"); - if (dir == NULL) { - perror("fmake:"); - return -1; - } - while ((entry = readdir(dir)) != NULL) { - if (entry->d_type == DT_REG) { - char* dot = strrchr(entry->d_name, '.'); - if (dot && strcmp(dot + 1, makers[i].filename) == 0) { - maker = makers[i]; - return process_build(argv); - } - } - } - printf("extension check %s\n", makers[i].filename); + for (i = 0; i < makers_size; i++) { + if (makers[i].file_type == FMAKE_EXT) { + // TODO optimize this code + // FIXME it's not sure if the '.' is found from first or last + // last should be preferred + dir = opendir("./"); + if (dir == NULL) { + perror("fmake"); + return -1; + } + while ((entry = readdir(dir)) != NULL) { + if (entry->d_type == DT_REG) { + char* dot = strrchr(entry->d_name, '.'); + if (dot && strcmp(dot + 1, makers[i].filename) == 0) { + goto FMAKE_FOUND_MATCH; + } + } + } } else { const char* filename = makers[i].filename; if (access(filename, F_OK) == 0) { - maker = makers[i]; - return process_build(argv); + goto FMAKE_FOUND_MATCH; } } } - maker = makers[0]; +FMAKE_FOUND_MATCH: + if (dir) closedir(dir); + maker = makers[i == makers_size? 0 : i]; return process_build(argv); }