fmake

make any project just by typing `fmake`

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
2 files changed, 60 insertions(+), 51 deletions(-)
M
config.h
|
55
+++++++++++++++++++++++++++++++------------------------
M
fmake.c
|
56
+++++++++++++++++++++++++++++---------------------------
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);
 }