commit a189c0ebc2acd1eb54392056f94ab98927a0320b
parent 0e6e155c155e8c0be06fd9bf07151cd4e2393bb3
Author: vx-clutch <[email protected]>
Date: Mon, 11 Aug 2025 11:31:52 -0400
save
Diffstat:
4 files changed, 122 insertions(+), 67 deletions(-)
diff --git a/core/create_project.c b/core/create_project.c
@@ -1,3 +1,11 @@
+/* Copyright (C) vx_clutch
+ *
+ * This file is part of yait
+ *
+ * This project and file is licenced under the BSD-3-Clause licence.
+ * <https://opensource.org/licence/bsd-3-clause>
+ */
+
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
@@ -10,15 +18,14 @@
#include "contents.h"
#include "yait.h"
-#error "TODO: make path project root"
-
#define DEFAULT_USER_NAME "unknown"
#define DEFAULT_PROJECT_NAME "Project"
#define DEFAULT_LICENCE BSD3
#define DEFAULT_GIT_INIT true
#define DEFAULT_CLANG_FORMAT true
+#define DEFAULT_GNU false
-int depth;
+int depth = 0;
static int reset_path(void)
{
@@ -175,9 +182,12 @@ int setup_git(manifest_t manifest)
return ret;
int status = system("git init --quiet");
- if (status != 0)
- fprintf(stderr, "setup_git: failed to initialize git: %s\n",
- strerror(status));
+ if (status == -1) {
+ fprintf(stderr, "...: %s\n", strerror(errno));
+ } else if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
+ fprintf(stderr, "...: exited with status %d\n",
+ WEXITSTATUS(status));
+ }
return status;
}
@@ -201,7 +211,8 @@ int create_makefile(manifest_t manifest)
return ret;
}
- int status = create_file_with_content("Makefile", makefile_template, M, m, M, m, M, M, m, M, m, M, m);
+ int status = create_file_with_content("Makefile", makefile_template, M,
+ m, M, m, M, M, m, M, m, M, m);
free(m);
free(M);
@@ -242,14 +253,15 @@ int generate_source_code(manifest_t manifest, char *licence_line)
struct tm tm = *localtime(&t);
int year = tm.tm_year + 1900;
- // Uncomment or fix when create_file_with_content supports this
- // status = create_file_with_content("config.h", manifest.project, licence_line, year);
- // if (status != 0) {
- // fprintf(stderr, "generate_source_code: failed to create config.h: %s\n", strerror(status));
- // return status;
- // }
+ status = create_file_with_content("config.h", config_h_template,
+ manifest.project, licence_line, year);
+ if (status != 0) {
+ fprintf(stderr,
+ "generate_source_code: failed to create config.h: %s\n",
+ strerror(status));
+ return status;
+ }
- status = create_and_enter_directory(manifest.project);
if (status != 0) {
fprintf(stderr,
"generate_source_code: failed to create or enter directory: %s\n",
@@ -259,13 +271,13 @@ int generate_source_code(manifest_t manifest, char *licence_line)
depth++;
if (manifest.flag.GNU) {
- status = create_file_with_content("main.c", main_c_gnu_template,
- manifest.project,
- manifest.name);
+ status = create_file_with_content(
+ strcat(manifest.project, "main.c"), main_c_gnu_template,
+ manifest.project, manifest.name);
} else {
- status = create_file_with_content("main.c", main_c_template,
- manifest.project,
- manifest.name);
+ status = create_file_with_content(
+ strcat(manifest.project, "main.c"), main_c_template,
+ manifest.project, manifest.name);
}
return status;
@@ -277,9 +289,8 @@ int create_project(manifest_t manifest)
sanitize(&manifest);
- depth = 0;
+ // TODO(vx-clutch): make the path the project root.
if (strcmp(manifest.path, ".") != 0) {
- status = create_and_enter_directory(manifest.project);
if (status != 0) {
fprintf(stderr,
"create_project: failed to create or enter directory: %s\n",
@@ -305,13 +316,6 @@ int create_project(manifest_t manifest)
return status;
}
- status = setup_git(manifest);
- if (status != 0) {
- fprintf(stderr,
- "create_project: warning: git initialization failed: %s\n",
- strerror(status));
- }
-
status = maybe_create_clang_format(manifest);
if (status != 0) {
fprintf(stderr,
@@ -353,5 +357,15 @@ int create_project(manifest_t manifest)
return status;
}
+ status = setup_git(manifest);
+ if (status != 0) {
+ fprintf(stderr,
+ "create_project: warning: git initialization failed: %s\n",
+ strerror(status));
+ }
+
+ // TODO(vx-clutch): Make path absolute.
+ fprintf(stderr, "Created %s at\n %s", manifest.project, manifest.path);
+
return 0;
}
diff --git a/core/file.c b/core/file.c
@@ -9,56 +9,80 @@
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "yait.h"
-int create_file_with_content(char *path, char *format, ...)
-{
- FILE *fp = fopen(path, "w");
- if (!fp) {
- return -1;
- }
- va_list args;
- va_start(args, format);
- vfprintf(fp, format, args);
- va_end(args);
+int files_made = 0;
- fclose(fp);
- return 0;
-}
-
-int create_directory(char *format, ...)
+static int mkdir_p(const char *path)
{
- va_list args;
- va_start(args, format);
+ char *copypath = strdup(path);
+ char *p = copypath;
+ int status = 0;
- char path[MAX_PATH_LENGTH];
- int result = vsnprintf(path, sizeof(path), format, args);
- va_end(args);
+ if (!copypath)
+ return -1;
- /* Check if the path was truncated */
- if (result >= (int)sizeof(path)) {
- return ENAMETOOLONG;
- }
+ if (copypath[0] == '/')
+ p++;
- if (mkdir(path, DEFAULT_DIR_PERMISSIONS) < 0) {
- return errno;
+ for (; *p; p++) {
+ if (*p == '/') {
+ *p = '\0';
+ if (mkdir(copypath, 0777) && errno != EEXIST) {
+ status = -1;
+ break;
+ }
+ *p = '/';
+ }
}
- return 0;
+ if (!status && mkdir(copypath, 0777) && errno != EEXIST)
+ status = -1;
+
+ free(copypath);
+ return status;
}
-int create_and_enter_directory(const char *dirname)
+int create_file_with_content(const char *path, const char *format, ...)
{
- int err = create_directory("%s", dirname);
- if (err) {
- return err;
+ char *dirpath;
+ const char *slash = strrchr(path, '/');
+ if (slash) {
+ size_t len = slash - path;
+ dirpath = malloc(len + 1);
+ if (!dirpath)
+ return -1;
+ memcpy(dirpath, path, len);
+ dirpath[len] = '\0';
+ if (mkdir_p(dirpath)) {
+ free(dirpath);
+ return -1;
+ }
+ free(dirpath);
}
- if (chdir(dirname) != 0) {
- return errno;
+
+ FILE *fp = fopen(path, "w");
+ if (!fp)
+ return -1;
+
+ va_list args;
+ va_start(args, format);
+ if (vfprintf(fp, format, args) < 0) {
+ va_end(args);
+ fclose(fp);
+ return -1;
}
+ va_end(args);
+
+ ++files_made;
+ emit_progress("Creating files", files_made);
+
+ fclose(fp);
return 0;
}
diff --git a/core/util.c b/core/util.c
@@ -0,0 +1,19 @@
+/* Copyright (C) vx_clutch
+ *
+ * This file is part of yait
+ *
+ * This project and file is licenced under the BSD-3-Clause licence.
+ * <https://opensource.org/licence/bsd-3-clause>
+ */
+
+#include "yait.h"
+
+void emit_progress(const char *action, int count)
+{
+ if (count > 0) {
+ fprintf(stderr, "%s %d", strcat("\r", action), count);
+ fflush(stderr);
+ } else {
+ fprintf(stderr, ", done\n");
+ }
+}
diff --git a/core/yait.h b/core/yait.h
@@ -15,11 +15,7 @@
int printfn(char *format, ...);
-int create_and_enter_directory(const char *dirname);
-
-int create_file_with_content(char *path, char *format, ...);
-
-int create_directory(char *format, ...);
+int create_file_with_content(const char *path, const char *format, ...);
int parse_standard_options(void (*usage_func)(), int argc, char **argv);
@@ -28,4 +24,6 @@ int program_exists(const char *prog);
#include "manifest.h"
int create_project(manifest_t manifest);
+void emit_progress(const char *action, int count);
+
#endif // YAIT_H