yait

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit f92a896ca2f137530422f31ca594fffca6c8e8e3
parent a386594b1feb956efbeaf3510553422ae9b3d71a
Author: vx-clutch <[email protected]>
Date:   Sun, 17 Aug 2025 21:37:58 -0400

save

Diffstat:
MMakefile | 21+++++++--------------
Mconfigure | 0
Dcore/create_project.c | 358-------------------------------------------------------------------------------
Dcore/manifest.h | 78------------------------------------------------------------------------------
Dcore/print.c | 23-----------------------
Dcore/util.c | 19-------------------
Ainclude/yait.h | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rcore/contents.h -> src/contents.h | 0
Asrc/create_project.c | 340+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rcore/file.c -> src/file.c | 0
Asrc/main.c | 167+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rcore/standard.c -> src/standard.c | 0
Rcore/yait.h -> src/yait.h | 0
Dtools/Cleanup | 20--------------------
Dtools/check_header | 44--------------------------------------------
Mtools/format | 0
Dyait/main.c | 177-------------------------------------------------------------------------------
17 files changed, 588 insertions(+), 733 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,9 +1,8 @@ prefix = /usr/bin -YAIT_SRCS := $(wildcard yait/*.c) $(wildcard core/*.c) -YAIT_OBJS := $(patsubst yait/%.c,c-out/obj/%.o,$(YAIT_SRCS)) +YAIT_SRCS := $(wildcard src/*.c) -YAIT := c-out/bin/yait +YAIT := bin/yait -include config.mak @@ -16,14 +15,10 @@ else all: build $(YAIT) $(YAIT_DOC) build: - mkdir -p c-out/bin - mkdir -p c-out/obj + mkdir bin -c-out/obj/%.o: yait/%.c - $(CC) $(CFLAGS) -c $< -o $@ - -$(YAIT): $(YAIT_OBJS) $(EMBED_HEADER) - $(CC) $(CFLAGS) -DCOMMIT=$(shell git rev-list --count --all) $^ -o $@ +$(YAIT): $(YAIT_SRCS) + $(CC) $(CFLAGS) -Iinclude -DCOMMIT=$(shell git rev-list --count --all) $^ -o $@ endif @@ -36,11 +31,9 @@ uninstall: exit 1 clean: - rm -rf c-out - rm -f $(EMBED_HEADER) - rm -f $(EMBED_HEADERS) + $(RM) -rf bin dist-clean: clean - rm -f config.mak + $(RM) -f config.mak .PHONY: all clean dist-clean install uninstall build diff --git a/configure b/configure diff --git a/core/create_project.c b/core/create_project.c @@ -1,358 +0,0 @@ -/* 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 <limits.h> -#include <stdlib.h> -#include <time.h> -#include <string.h> -#include <unistd.h> -#include <pwd.h> -#include <sys/stat.h> - -#include "manifest.h" -#include "contents.h" -#include "yait.h" - -#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 program_exists(const char *prog) -{ - char *path = getenv("PATH"); - if (!path) - return -1; - - char *copy = strdup(path); - if (!copy) - return -1; - - char *dir = strtok(copy, ":"); - while (dir) { - char buf[4096]; - snprintf(buf, sizeof(buf), "%s/%s", dir, prog); - if (access(buf, X_OK) == 0) { - free(copy); - return 0; - } - dir = strtok(NULL, ":"); - } - - free(copy); - return 1; -} - -int sanitize(manifest_t *m) -{ - if (!m->project) - m->project = DEFAULT_PROJECT_NAME; - - if (!m->name) { - struct passwd *pw = getpwuid(getuid()); - m->name = (pw && pw->pw_name) ? pw->pw_name : DEFAULT_USER_NAME; - } - - if (m->licence == UNLICENCE) - m->licence = DEFAULT_LICENCE; - - if (!m->flag.git) - m->flag.git = DEFAULT_GIT_INIT; - - if (!m->flag.clang_format) - m->flag.clang_format = DEFAULT_CLANG_FORMAT; - - if (!m->flag.GNU) - m->flag.GNU = DEFAULT_GNU; - - if (strcmp(".", m->project) == 0) { - - } - - return 0; -} - -int create_libraries(manifest_t manifest) -{ - int status = 0; - - if (!manifest.libraries) { - return status; - } - - if (HAS_LIBRARY(manifest.libraries, LIB_RAYLIB)) { - fputs("Pulling raylib", stderr); - REMOVE_LIBRARY(manifest.libraries, LIB_RAYLIB); - status = system( - "git submodule add --quiet https://github.com/raysan5/raylib"); - if (status != 0) - return status; - fputs(", done.\n", stderr); - } - - if (HAS_LIBRARY(manifest.libraries, LIB_NCURSES)) { - fputs("Pulling ncurses", stderr); - REMOVE_LIBRARY(manifest.libraries, LIB_NCURSES); - status = system( - "git submodule add --quiet https://github.com/mirror/ncurses"); - if (status != 0) - return status; - fputs(", done.\n", stderr); - } - - if (HAS_LIBRARY(manifest.libraries, LIB_CURL)) { - fputs("Pulling curl", stderr); - REMOVE_LIBRARY(manifest.libraries, LIB_CURL); - status = system( - "git submodule add --quiet https://github.com/curl/curl"); - if (status != 0) - return status; - fputs(", done.\n", stderr); - } - - return status; -} - -int create_licence(manifest_t manifest, char **licence_line_buffer) -{ - if (manifest.licence == UNLICENCE) - return 0; - - if (!licence_line_buffer) - return EINVAL; - - switch (manifest.licence) { - case BSD3: - *licence_line_buffer = "Bsd"; - fprintf(stderr, - "create_licence: BSD3 license generation not implemented\n"); - return ENOSYS; - case GPLv3: - fprintf(stderr, - "create_licence: GPLv3 license generation not implemented\n"); - return ENOSYS; - case MIT: - fprintf(stderr, - "create_licence: MIT license generation not implemented\n"); - return ENOSYS; - default: - fprintf(stderr, "create_licence: unknown license type\n"); - return EINVAL; - } -} - -int maybe_create_clang_format(manifest_t manifest) -{ - if (!manifest.flag.clang_format) - return 0; - - int status = create_file_with_content(".clang-format", - clang_format_template); - return status; -} - -int setup_git(manifest_t manifest) -{ - if (!manifest.flag.git) - return 0; - - int status = system("git init --quiet"); - 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; -} - -int create_makefile(manifest_t manifest) -{ - char *m = strdup(manifest.project); - char *M = strdup(manifest.project); - if (!M) { - fputs("create_makefile: fatal: out of memory\n", stderr); - return ENOMEM; - } - - for (char *p = M; *p; ++p) - if (*p >= 'a' && *p <= 'z') - *p -= 'a' - 'A'; - - int status = create_file_with_content(strcat(m, "Makefile"), - makefile_template, M, m, M, m, M, - M, m, M, m, M, m); - - free(m); - free(M); - return status; -} - -int create_configure(manifest_t manifest) -{ - const char *cc; - if (manifest.flag.use_cpp) { - cc = "trycc g++\ntrycc CC\ntrycc clang++\n"; - } else { - cc = "trycc gcc\ntrycc cc\ntrycc clang\n"; - } - - int status = - create_file_with_content("configure", configure_template, cc); - if (status != 0) - return status; - - status = system("chmod +x configure"); - if (status != 0) - fprintf(stderr, "create_configure: chmod failed: %s\n", - strerror(status)); - - return status; -} - -int generate_source_code(manifest_t manifest, char *licence_line) -{ - int status = 0; - - time_t t = time(NULL); - struct tm tm = *localtime(&t); - int year = tm.tm_year + 1900; - - 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; - } - - if (status != 0) { - fprintf(stderr, - "generate_source_code: failed to create or enter directory: %s\n", - strerror(status)); - return status; - } - - if (manifest.flag.GNU) { - status = create_file_with_content( - strcat(manifest.project, "main.c"), main_c_gnu_template, - manifest.project, manifest.name); - } else { - status = create_file_with_content( - strcat(manifest.project, "main.c"), main_c_template, - manifest.project, manifest.name); - } - - return status; -} - -int create_project(manifest_t manifest) -{ - int status; - - sanitize(&manifest); - - if (strcmp(manifest.path, ".") != 0) { - status = mkdir(manifest.path, 0755); - if (status != 0 && errno != EEXIST) { - fprintf(stderr, - "create_project: failed to create directory '%s': %s\n", - manifest.path, strerror(errno)); - return errno; - } - - status = chdir(manifest.path); - if (status != 0) { - fprintf(stderr, - "create_project: failed to enter directory '%s': %s\n", - manifest.path, strerror(errno)); - return errno; - } - } else { - manifest.path = ""; - } - - status = create_makefile(manifest); - if (status != 0) { - fprintf(stderr, - "create_project: failed to create Makefile: %s\n", - strerror(status)); - return status; - } - - status = create_configure(manifest); - if (status != 0) { - fprintf(stderr, - "create_project: failed to create configure: %s\n", - strerror(status)); - return status; - } - - status = maybe_create_clang_format(manifest); - if (status != 0) { - fprintf(stderr, - "create_project: warning: clang-format setup failed: %s\n", - strerror(status)); - } - - char *licence_line = malloc(1024); - if (!licence_line) { - fputs("create_project: failed to allocate memory for licence line\n", - stderr); - return ENOMEM; - } - - status = create_licence(manifest, &licence_line); - if (status != 0) { - fprintf(stderr, - "create_project: failed to create licence: %s\n", - strerror(status)); - free(licence_line); - return status; - } - - status = generate_source_code(manifest, licence_line); - if (status != 0) { - fprintf(stderr, - "create_project: failed to generate source code: %s\n", - strerror(status)); - free(licence_line); - return status; - } - - free(licence_line); - - status = create_libraries(manifest); - if (status != 0) { - printfn("failed to get libraries: %s", strerror(status)); - return status; - } - - status = setup_git(manifest); - if (status != 0) { - printfn("warning: git initialization failed: %s", - strerror(status)); - } - - char *resolved = realpath(manifest.path, NULL); - if (!resolved) { - fprintf(stderr, "Failed to get realpath for '%s': %s\n", - manifest.path, strerror(errno)); - return 2; - } - fprintf(stderr, "Created %s at\n %s\n", manifest.project, resolved); - free(resolved); - - return 0; -} diff --git a/core/manifest.h b/core/manifest.h @@ -1,78 +0,0 @@ -/* 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> - */ - -#ifndef FORMAT_H -#define FORMAT_H - -#include <stdbool.h> -#include <string.h> -#include <stdio.h> - -typedef enum { - BSD3, /* BSD 3-Clause Licence */ - GPLv3, /* GNU General Public Licence v3 */ - MIT, /* MIT Licence */ - UNLICENCE, /* Unlicence */ - LICENCE_HELP, /* Help case */ -} licence_t; - -/* A bit field is used so that we can accomplish two things. (a) store lots of - libraries without taxing memory; and (b) a dynamic array is not neccescary. - */ -typedef enum { - LIB_NONE = 0, /* No libraries selected */ - LIB_RAYLIB = 1 << 0, /* Raylib game library */ - LIB_NCURSES = 1 << 1, /* Windows API */ - LIB_CURL = 1 << 2, /* cURL library */ - LIB_COUNT_, /* Number of Libraries */ - LIB_HELP, /* Help case */ -} lib_flags_t; - -typedef struct { - bool GNU; - bool git; - bool clang_format; - bool use_cpp; -} flags_t; - -typedef struct { - licence_t licence; /* Licence type for the project */ - char *project; /* Project name */ - char *path; /* Path */ - char *name; /* Author/creator name ( if not provided infered on sanitize ) */ - lib_flags_t libraries; /* Selected libraries (bit field) */ - flags_t flag; /* Flags */ -} manifest_t; - -#define DEFAULT_CLANG_FORMAT true -#define DEFAULT_GIT_INIT true -#define DEFAULT_GNU false -#define DEFAULT_LIBRARIES LIB_NONE -#define DEFAULT_LICENCE BSD3 - -#define HAS_LIBRARY(libs, lib) ((libs) & (lib)) -#define ADD_LIBRARY(libs, lib) ((libs) |= (lib)) -#define REMOVE_LIBRARY(libs, lib) ((libs) &= ~(lib)) - -[[maybe_unused]] static lib_flags_t TOLibrary(char *src) -{ - if (strcmp(src, "raylib")) - return LIB_RAYLIB; - if (strcmp(src, "ncurse")) - return LIB_NCURSES; - if (strcmp(src, "ncurses")) - return LIB_NCURSES; - if (strcmp(src, "curl")) - return LIB_CURL; - if (strcmp(src, "help")) - return LIB_HELP; - fprintf(stderr, "could not find library %s", src); - return LIB_COUNT_; /* bad case */ -} - -#endif diff --git a/core/print.c b/core/print.c @@ -1,23 +0,0 @@ -/* 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/license/bsd-3-clause> - */ - -#include "yait.h" -#include <stdarg.h> -#include <stdio.h> - -int printfn(char *format, ...) -{ - int len; - va_list args; - va_start(args, format); - fprintf(stderr, "yait: "); - len = vfprintf(stderr, format, args); - fprintf(stderr, "\n"); /* Use stderr consistently */ - va_end(args); - return len; -} diff --git a/core/util.c b/core/util.c @@ -1,19 +0,0 @@ -/* 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/include/yait.h b/include/yait.h @@ -0,0 +1,74 @@ +/* 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/license/bsd-3-clause> + */ + +#ifndef YAIT_H +#define YAIT_H + +#include <string.h> + +typedef enum { + BSD3, + GPLv3, + MIT, + UNLICENCE, + LICENCE_HELP, +} licence_t; + +/* A bit field is used so that we can accomplish two things. (a) store lots of + libraries without taxing memory; and (b) a dynamic array is not neccescary. + */ +typedef enum { + LIB_NONE = 0, + LIB_RAYLIB = 1 << 0, + LIB_NCURSES = 1 << 1, + LIB_CURL = 1 << 2, + LIB_COUNT_, + LIB_HELP, +} lib_flags_t; + +typedef struct { + bool GNU; + bool git; + bool clang_format; + bool use_cpp; +} flags_t; + +typedef struct { + licence_t licence; + char *project; + char *name; + lib_flags_t libraries; + flags_t flag; +} manifest_t; + +#define DEFAULT_CLANG_FORMAT true +#define DEFAULT_GIT_INIT true +#define DEFAULT_GNU false +#define DEFAULT_LIBRARIES LIB_NONE +#define DEFAULT_LICENCE BSD3 + +#define HAS_LIBRARY(libs, lib) ((libs) & (lib)) +#define ADD_LIBRARY(libs, lib) ((libs) |= (lib)) +#define REMOVE_LIBRARY(libs, lib) ((libs) &= ~(lib)) + +[[maybe_unused]] static lib_flags_t TOLibrary(char *src) +{ + if (strcmp(src, "raylib")) + return LIB_RAYLIB; + if (strcmp(src, "ncurse")) + return LIB_NCURSES; + if (strcmp(src, "ncurses")) + return LIB_NCURSES; + if (strcmp(src, "curl")) + return LIB_CURL; + if (strcmp(src, "help")) + return LIB_HELP; + return LIB_COUNT_; /* bad case */ +} + +#endif // YAIT_H diff --git a/core/contents.h b/src/contents.h diff --git a/src/create_project.c b/src/create_project.c @@ -0,0 +1,340 @@ +/* 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> +#include <time.h> +#include <string.h> +#include <unistd.h> +#include <pwd.h> +#include <sys/stat.h> + +#include "manifest.h" +#include "contents.h" +#include "yait.h" + +#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 program_exists(const char *prog) +{ + char *path = getenv("PATH"); + if (!path) + return -1; + + char *copy = strdup(path); + if (!copy) + return -1; + + char *dir = strtok(copy, ":"); + while (dir) { + char buf[4096]; + snprintf(buf, sizeof(buf), "%s/%s", dir, prog); + if (access(buf, X_OK) == 0) { + free(copy); + return 0; + } + dir = strtok(NULL, ":"); + } + + free(copy); + return 1; +} + +int sanitize(manifest_t *m) +{ + int status; + struct passwd *pw = getpwuid(getuid()); + + status = program_exists("git"); + if (status != 0) + return fprintf(stderr, "git binary not present\n"), + EXIT_FAILURE; + + if (!m->project) + m->project = DEFAULT_PROJECT_NAME; + + if (!m->name) + m->name = (pw && pw->pw_name) ? pw->pw_name : DEFAULT_USER_NAME; + + if (m->licence == UNLICENCE) + m->licence = DEFAULT_LICENCE; + + if (!m->flag.git) + m->flag.git = DEFAULT_GIT_INIT; + + if (!m->flag.clang_format) + m->flag.clang_format = DEFAULT_CLANG_FORMAT; + + if (!m->flag.GNU) + m->flag.GNU = DEFAULT_GNU; + + return 0; +} + +int create_libraries(manifest_t manifest) +{ + int status = 0; + + if (!manifest.libraries) { + return status; + } + + if (HAS_LIBRARY(manifest.libraries, LIB_RAYLIB)) { + fputs("Pulling raylib", stderr); + REMOVE_LIBRARY(manifest.libraries, LIB_RAYLIB); + status = system( + "git submodule add --quiet https://github.com/raysan5/raylib"); + if (status != 0) + return status; + fputs(", done.\n", stderr); + } + + if (HAS_LIBRARY(manifest.libraries, LIB_NCURSES)) { + fputs("Pulling ncurses", stderr); + REMOVE_LIBRARY(manifest.libraries, LIB_NCURSES); + status = system( + "git submodule add --quiet https://github.com/mirror/ncurses"); + if (status != 0) + return status; + fputs(", done.\n", stderr); + } + + if (HAS_LIBRARY(manifest.libraries, LIB_CURL)) { + fputs("Pulling curl", stderr); + REMOVE_LIBRARY(manifest.libraries, LIB_CURL); + status = system( + "git submodule add --quiet https://github.com/curl/curl"); + if (status != 0) + return status; + fputs(", done.\n", stderr); + } + + return status; +} + +int create_licence(manifest_t manifest, char **licence_line_buffer) +{ + if (manifest.licence == UNLICENCE) + return 0; + + if (!licence_line_buffer) + return EINVAL; + + switch (manifest.licence) { + case BSD3: + *licence_line_buffer = "Bsd"; + fprintf(stderr, + "create_licence: BSD3 license generation not implemented\n"); + return ENOSYS; + case GPLv3: + fprintf(stderr, + "create_licence: GPLv3 license generation not implemented\n"); + return ENOSYS; + case MIT: + fprintf(stderr, + "create_licence: MIT license generation not implemented\n"); + return ENOSYS; + default: + fprintf(stderr, "create_licence: unknown license type\n"); + return EINVAL; + } +} + +int maybe_create_clang_format(manifest_t manifest) +{ + if (!manifest.flag.clang_format) + return 0; + + int status = create_file_with_content(".clang-format", + clang_format_template); + return status; +} + +int setup_git(manifest_t manifest) +{ + if (!manifest.flag.git) + return 0; + + int status = system("git init --quiet"); + 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; +} + +int create_makefile(manifest_t manifest) +{ + char *m = strdup(manifest.project); + char *M = strdup(manifest.project); + if (!M) { + fputs("create_makefile: fatal: out of memory\n", stderr); + return ENOMEM; + } + + for (char *p = M; *p; ++p) + if (*p >= 'a' && *p <= 'z') + *p -= 'a' - 'A'; + + int status = create_file_with_content(strcat(m, "Makefile"), + makefile_template, M, m, M, m, M, + M, m, M, m, M, m); + + free(m); + free(M); + return status; +} + +int create_configure(manifest_t manifest) +{ + const char *cc; + if (manifest.flag.use_cpp) { + cc = "trycc g++\ntrycc CC\ntrycc clang++\n"; + } else { + cc = "trycc gcc\ntrycc cc\ntrycc clang\n"; + } + + int status = + create_file_with_content("configure", configure_template, cc); + if (status != 0) + return status; + + status = system("chmod +x configure"); + if (status != 0) + fprintf(stderr, "create_configure: chmod failed: %s\n", + strerror(status)); + + return status; +} + +int generate_source_code(manifest_t manifest, char *licence_line) +{ + int status = 0; + + time_t t = time(NULL); + struct tm tm = *localtime(&t); + int year = tm.tm_year + 1900; + + 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; + } + + if (status != 0) { + fprintf(stderr, + "generate_source_code: failed to create or enter directory: %s\n", + strerror(status)); + return status; + } + + if (manifest.flag.GNU) { + status = create_file_with_content( + strcat(manifest.project, "main.c"), main_c_gnu_template, + manifest.project, manifest.name); + } else { + status = create_file_with_content( + strcat(manifest.project, "main.c"), main_c_template, + manifest.project, manifest.name); + } + + return status; +} + +int create_project(manifest_t manifest) +{ + int status; + + sanitize(&manifest); + + // TODO(vx-clutch): take dir. + + // status = create_makefile(manifest); + // if (status != 0) { + // fprintf(stderr, + // "create_project: failed to create Makefile: %s\n", + // strerror(status)); + // return status; + // } + // + // status = create_configure(manifest); + // if (status != 0) { + // fprintf(stderr, + // "create_project: failed to create configure: %s\n", + // strerror(status)); + // return status; + // } + // + // status = maybe_create_clang_format(manifest); + // if (status != 0) { + // fprintf(stderr, + // "create_project: warning: clang-format setup failed: %s\n", + // strerror(status)); + // } + // + // char *licence_line = malloc(1024); + // if (!licence_line) { + // fputs("create_project: failed to allocate memory for licence line\n", + // stderr); + // return ENOMEM; + // } + // + // status = create_licence(manifest, &licence_line); + // if (status != 0) { + // fprintf(stderr, + // "create_project: failed to create licence: %s\n", + // strerror(status)); + // free(licence_line); + // return status; + // } + // + // status = generate_source_code(manifest, licence_line); + // if (status != 0) { + // fprintf(stderr, + // "create_project: failed to generate source code: %s\n", + // strerror(status)); + // free(licence_line); + // return status; + // } + // + // free(licence_line); + // + // status = create_libraries(manifest); + // if (status != 0) { + // printfn("failed to get libraries: %s", strerror(status)); + // return status; + // } + // + // status = setup_git(manifest); + // if (status != 0) { + // printfn("warning: git initialization failed: %s", + // strerror(status)); + // } + + char *cwd = getcwd(NULL, 0); + if (!cwd) { + printfn("could not get current working directory"); + return 1; + } + fprintf(stderr, "Created %s at\n %s\n", manifest.project, cwd); + free(cwd); + + return 0; +} diff --git a/core/file.c b/src/file.c diff --git a/src/main.c b/src/main.c @@ -0,0 +1,167 @@ +/* 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> + */ + +// Usage: yait [OPTION]... <PATH> + +#include <getopt.h> +#include <pwd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "../config.h" +#include "../core/yait.h" +#include "../core/manifest.h" + +#define print_option(option, description) \ + printf(" %-20s %-20s\n", option, description) + +// clang-format off +static void +usage (int status) +{ + if (status != 0) + { + fprintf (stderr, "Try 'yait --help' for more information.\n"); + return; + } + + printf ("Usage: yait [OPTION]... <PATH>\n"); + printf ("Creates a C project with opinionated defaults.\n"); + printf ("When only given the first argument it will detect your name.\n\n"); + printf ("Mandatory arguments to long options are mandatory for short options too\n"); + print_option ("-l, --licence=NAME", "Set licence (gpl, mit, bsd) [default: bsd]"); + print_option ("--lib=LIB", "Add a library to the project. You can list libraries with --lib=help."); + print_option ("--use-cpp", "Uses the CPP language instead of C"); + print_option ("--git", "Initialize git repository"); + print_option ("--GNU", "Adds standard GNU argument parsing to your project"); + printf (" --help display this help text and exit\n"); + printf (" --version output version information and exit\n"); +} +// clang-format on + +static int parse_arguments(manifest_t *conf, int argc, char **argv) +{ + static struct option long_options[] = { + { "GNU", no_argument, 0, 'g' }, + { "use-cpp", no_argument, 0, 'c' }, + { "git", no_argument, 0, 'i' }, + { "licence", required_argument, 0, 'l' }, + { "lib", required_argument, 0, 'L' }, + { "help", no_argument, 0, 'h' }, + { 0, 0, 0, 0 } + }; + + int opt; + while ((opt = getopt_long(argc, argv, "gcil:L:h", long_options, + NULL)) != -1) { + switch (opt) { + case 'g': + conf->flag.GNU = true; + break; + case 'c': + conf->flag.use_cpp = true; + break; + case 'i': + conf->flag.git = true; + break; + case 'l': + if (strcmp(optarg, "bsd") == 0) + conf->licence = BSD3; + else if (strcmp(optarg, "gpl") == 0) + conf->licence = GPLv3; + else if (strcmp(optarg, "mit") == 0) + conf->licence = MIT; + else { + fprintf(stderr, "Unknown licence: %s\n", + optarg); + exit(EXIT_FAILURE); + } + break; + case 'L': + if (strcmp(optarg, "help")) + fprintf(stderr, "raylib\nncurses\ncurl\n"); + else + ADD_LIBRARY(conf->libraries, TOLibrary(optarg)); + break; + case 'h': + usage(0); + exit(0); + default: + usage(1); + exit(1); + } + } + + if (optind >= argc) { + fprintf(stderr, "Missing required path argument\n"); + usage(1); + exit(EXIT_FAILURE); + } + + conf->project = argv[optind++]; + + if (optind < argc) + conf->name = argv[optind++]; + + return 0; +} + +int get_name(char **output) +{ + FILE *pipe; + char buffer[128]; + size_t output_len = 0; + + *output = NULL; // make sure it's NULL before realloc + + pipe = popen("git config user.name", "r"); + if (!pipe) + exit(EXIT_FAILURE); + + while (fgets(buffer, sizeof(buffer), pipe) != NULL) { + size_t chunk_len = strlen(buffer); + char *new_output = realloc(*output, output_len + chunk_len + 1); + if (!new_output) { + free(*output); + pclose(pipe); + exit(EXIT_FAILURE); + } + *output = new_output; + memcpy((*output) + output_len, buffer, chunk_len); + output_len += chunk_len; + (*output)[output_len] = '\0'; + } + pclose(pipe); + return 0; +} + +int main(int argc, char **argv) +{ + int status; + manifest_t manifest = { 0 }; + + status = parse_standard_options(usage, argc, argv); + if (status != 0 && status != HELP_REQUESTED) + return fprintf(stderr, "error: %s\n", strerror(status)), + EXIT_FAILURE; + + parse_arguments(&manifest, argc, argv); + + if (!manifest.name) { + status = get_name(&manifest.name); + if (status != 0 || !manifest.name || manifest.name[0] == '\0') { + fprintf(stderr, "Could not determine user name\n"); + return EXIT_FAILURE; + } + } + + status = create_project(manifest); + return status == 0 ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/core/standard.c b/src/standard.c diff --git a/core/yait.h b/src/yait.h diff --git a/tools/Cleanup b/tools/Cleanup @@ -1,20 +0,0 @@ -#!/bin/env bash - -# Usage: ./Cleanup [FILE]... - -make dist-clean - -process_file() { - clang-format -i "$1" - tools/check_header_footer "$1" -} - -if [[ $# -gt 0 ]]; then - for file in "$@"; do - process_file "$file" - done -else - for file in $(find yait core -type f \( -name "*.c" -o -name "*.h" \)); do - process_file "$file" - done -fi diff --git a/tools/check_header b/tools/check_header @@ -1,44 +0,0 @@ -#!/bin/env bash - -# Usage: ./check_header - -if pwd | grep -q tools; then - cd .. -fi - -files=$(find yait \( -name '*.c' -o -name '*.h' \)) -files+=" " -files+=$(find core \( -name '*.c' -o -name '*.h' \)) -files+=" $(find . -maxdepth 1 -type f)" - -ignore="README COPYING .clang-format config.mak" - -if [ -z "$files" ]; then - echo "No files found" - exit 0 -fi - -missing="" - -for file in $files; do - if echo "$ignore" | grep -qw "$(basename "$file")"; then - continue - fi - echo -ne "$file... " - if grep -q "Copyright (C)" "$file"; then - echo -e "\033[1;32mOK\033[0m" - else - echo -e "\033[0;31mFAIL\033[0m" - missing+="$file " - fi -done - -if [ "$missing" = "" ]; then - echo -e "\033[1;32mAll checks pass.\033[0m" -else - echo -e "\033[0;31mThe follwing files are missing copyright information.\033[0m" -fi - -for file in $missing; do - echo " - $file" -done diff --git a/tools/format b/tools/format diff --git a/yait/main.c b/yait/main.c @@ -1,177 +0,0 @@ -/* 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> - */ - -// Usage: yait [OPTION]... <PATH> - -#include <getopt.h> -#include <pwd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "../config.h" -#include "../core/yait.h" -#include "../core/manifest.h" - -#define print_option(option, description) \ - printf(" %-20s %-20s\n", option, description) - -// clang-format off -static void -usage (int status) -{ - if (status != 0) - { - fprintf (stderr, "Try 'yait --help' for more information.\n"); - return; - } - - printf ("Usage: yait [OPTION]... <PATH>\n"); - printf ("Creates a C project with opinionated defaults.\n"); - printf ("When only given the first argument it will detect your name.\n\n"); - printf ("Mandatory arguments to long options are mandatory for short options too\n"); - print_option ("-l, --licence=NAME", "Set licence (gpl, mit, bsd) [default: bsd]"); - print_option ("--lib=LIB", "Add a library to the project. You can list libraries with --lib=help."); - print_option ("--use-cpp", "Uses the CPP language instead of C"); - print_option ("--git", "Initialize git repository"); - print_option ("--GNU", "Adds standard GNU argument parsing to your project"); - printf (" --help display this help text and exit\n"); - printf (" --version output version information and exit\n"); -} -// clang-format on - -static int parse_arguments(manifest_t *conf, int argc, char **argv) -{ - static struct option long_options[] = { - { "GNU", no_argument, 0, 'g' }, - { "use-cpp", no_argument, 0, 'c' }, - { "git", no_argument, 0, 'i' }, - { "licence", required_argument, 0, 'l' }, - { "lib", required_argument, 0, 'L' }, - { "help", no_argument, 0, 'h' }, - { 0, 0, 0, 0 } - }; - - int opt; - while ((opt = getopt_long(argc, argv, "gcil:L:h", long_options, - NULL)) != -1) { - switch (opt) { - case 'g': - conf->flag.GNU = true; - break; - case 'c': - conf->flag.use_cpp = true; - break; - case 'i': - conf->flag.git = true; - break; - case 'l': - if (strcmp(optarg, "bsd") == 0) - conf->licence = BSD3; - else if (strcmp(optarg, "gpl") == 0) - conf->licence = GPLv3; - else if (strcmp(optarg, "mit") == 0) - conf->licence = MIT; - else { - fprintf(stderr, "Unknown licence: %s\n", - optarg); - exit(EXIT_FAILURE); - } - break; - case 'L': - if (strcmp(optarg, "help")) - fprintf(stderr, "raylib\nncurses\ncurl\n"); - else - ADD_LIBRARY(conf->libraries, TOLibrary(optarg)); - break; - case 'h': - usage(0); - exit(0); - default: - usage(1); - exit(1); - } - } - - if (optind >= argc) { - fprintf(stderr, "Missing required path argument\n"); - usage(1); - exit(EXIT_FAILURE); - } - - conf->project = argv[optind++]; - - if (optind < argc) - conf->name = argv[optind++]; - - return 0; -} - -int get_name(char **output) -{ - FILE *pipe; - char buffer[128]; - size_t output_len = 0; - - *output = NULL; // make sure it's NULL before realloc - - pipe = popen("git config user.name", "r"); - if (!pipe) - exit(EXIT_FAILURE); - - while (fgets(buffer, sizeof(buffer), pipe) != NULL) { - size_t chunk_len = strlen(buffer); - char *new_output = realloc(*output, output_len + chunk_len + 1); - if (!new_output) { - free(*output); - pclose(pipe); - exit(EXIT_FAILURE); - } - *output = new_output; - memcpy((*output) + output_len, buffer, chunk_len); - output_len += chunk_len; - (*output)[output_len] = '\0'; - } - pclose(pipe); - return 0; -} - -int main(int argc, char **argv) -{ - int status; - manifest_t manifest = { 0 }; - - status = parse_standard_options(usage, argc, argv); - if (status != 0 && status != HELP_REQUESTED) { - fprintf(stderr, "error: %s\n", strerror(status)); - return EXIT_FAILURE; - } - - status = program_exists("git"); - if (status != 0) { - fprintf(stderr, "git binary not present\n"); - return EXIT_FAILURE; - } - - parse_arguments(&manifest, argc, argv); - - if (!manifest.name) { - status = get_name(&manifest.name); - if (status != 0 || !manifest.name || manifest.name[0] == '\0') { - fprintf(stderr, "Could not determine user name\n"); - return EXIT_FAILURE; - } - } - - manifest.path = manifest.project; - // TODO(vx-clutch): get name from path. - - status = create_project(manifest); - return status == 0 ? EXIT_SUCCESS : EXIT_FAILURE; -}