diff --git a/.cache/clangd/index/config.h.1D4220C6FF66C46D.idx b/.cache/clangd/index/config.h.1D4220C6FF66C46D.idx deleted file mode 100644 index bcb14cf..0000000 Binary files a/.cache/clangd/index/config.h.1D4220C6FF66C46D.idx and /dev/null differ diff --git a/.cache/clangd/index/contents.h.2CBC61E2CD5097B6.idx b/.cache/clangd/index/contents.h.2CBC61E2CD5097B6.idx deleted file mode 100644 index a89054b..0000000 Binary files a/.cache/clangd/index/contents.h.2CBC61E2CD5097B6.idx and /dev/null differ diff --git a/.cache/clangd/index/create_project.c.6C9F96E4B534FF2F.idx b/.cache/clangd/index/create_project.c.6C9F96E4B534FF2F.idx deleted file mode 100644 index 7bff9d0..0000000 Binary files a/.cache/clangd/index/create_project.c.6C9F96E4B534FF2F.idx and /dev/null differ diff --git a/.cache/clangd/index/file.c.398C7881CF457486.idx b/.cache/clangd/index/file.c.398C7881CF457486.idx deleted file mode 100644 index 5dd1d90..0000000 Binary files a/.cache/clangd/index/file.c.398C7881CF457486.idx and /dev/null differ diff --git a/.cache/clangd/index/main.c.7FD7D25CC47FF791.idx b/.cache/clangd/index/main.c.7FD7D25CC47FF791.idx deleted file mode 100644 index c3c8ef4..0000000 Binary files a/.cache/clangd/index/main.c.7FD7D25CC47FF791.idx and /dev/null differ diff --git a/.cache/clangd/index/manifest.h.2E308175C3A2DDBB.idx b/.cache/clangd/index/manifest.h.2E308175C3A2DDBB.idx deleted file mode 100644 index 4d67cdb..0000000 Binary files a/.cache/clangd/index/manifest.h.2E308175C3A2DDBB.idx and /dev/null differ diff --git a/.cache/clangd/index/print.c.568C625DB5D5283E.idx b/.cache/clangd/index/print.c.568C625DB5D5283E.idx deleted file mode 100644 index 3b3724f..0000000 Binary files a/.cache/clangd/index/print.c.568C625DB5D5283E.idx and /dev/null differ diff --git a/.cache/clangd/index/standard.c.D171D886C087801F.idx b/.cache/clangd/index/standard.c.D171D886C087801F.idx deleted file mode 100644 index e8c1cba..0000000 Binary files a/.cache/clangd/index/standard.c.D171D886C087801F.idx and /dev/null differ diff --git a/.cache/clangd/index/yait.h.D7502194D2C0AFD2.idx b/.cache/clangd/index/yait.h.D7502194D2C0AFD2.idx deleted file mode 100644 index c55bf45..0000000 Binary files a/.cache/clangd/index/yait.h.D7502194D2C0AFD2.idx and /dev/null differ diff --git a/.clangd b/.clangd index 99e6d2d..2dc4053 100644 --- a/.clangd +++ b/.clangd @@ -1,2 +1,2 @@ CompileFlags: - Add: ["-std=c2x"] + Add: ["--std=c2x", "-xc"] diff --git a/Makefile b/Makefile index 4f47174..bd4f22a 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ all: @exit 1 else -all: build $(YAIT) $(YAIT_DOC) +all: build $(YAIT) build: mkdir -p bin diff --git a/TODO b/TODO new file mode 100644 index 0000000..d5bf250 --- /dev/null +++ b/TODO @@ -0,0 +1,7 @@ +VX yait --- TODO + +Todo: + + * Argument Parsing + +end of file TODO diff --git a/bin/yait b/bin/yait new file mode 100755 index 0000000..17b3c13 Binary files /dev/null and b/bin/yait differ diff --git a/config.h b/config.h index a453cf4..a95c4df 100644 --- a/config.h +++ b/config.h @@ -9,9 +9,4 @@ #define VERSION "alpha" #define YEAR 2025 -/* Custom error codes */ -#define HELP_REQUESTED 2 -#define ERROR_MEMORY_ALLOCATION 3 -#define ERROR_DIRECTORY_CREATION 4 - #endif diff --git a/config.mak b/config.mak new file mode 100644 index 0000000..09c76f2 --- /dev/null +++ b/config.mak @@ -0,0 +1,4 @@ +PREFIX=/usr/bin/ +CFLAGS=-ggdb -std=c23 +LDFLAGS= +CC=gcc diff --git a/configure b/configure index 82d9fed..1cd93d2 100755 --- a/configure +++ b/configure @@ -19,7 +19,7 @@ cmdexists () { type "$1" >/dev/null 2>&1 ; } trycc () { test -z "$CC" && cmdexists "$1" && CC=$1 ; } prefix=/usr/bin/ -CFLAGS="-Wall -Wextra -O2 --std=c23" +CFLAGS="-Wall -Wextra -O2 --std=c23 -Wpedantic" LDFLAGS= CC= diff --git a/doc/simple_project/Makefile b/doc/simple_project/Makefile new file mode 100644 index 0000000..c882a16 --- /dev/null +++ b/doc/simple_project/Makefile @@ -0,0 +1,8 @@ +.POSIX: +CC ::= gcc +CFLAGS ::= -Wall -Wpedenatic -O2 + +all: simple + +clean: + $(RM) simple diff --git a/doc/simple_project/README b/doc/simple_project/README new file mode 100644 index 0000000..87f67af --- /dev/null +++ b/doc/simple_project/README @@ -0,0 +1,3 @@ +simple.c vx-clutch + +A simple program that does simple things. diff --git a/doc/simple_project/simple.c b/doc/simple_project/simple.c new file mode 100644 index 0000000..e69de29 diff --git a/include/yait.h b/include/yait.h index c1e3387..9713199 100644 --- a/include/yait.h +++ b/include/yait.h @@ -9,47 +9,43 @@ #ifndef YAIT_H #define YAIT_H +typedef struct { + bool posix; + bool git; + bool clang; + bool lib; + bool cc; + bool gnu; + /* If this flag is set it will ignore: GNU, and enforce POSIX. */ + bool simple; +} flag_t; + +typedef struct { + bool ncurses; + bool raylib; + bool stb; + bool uthash; + bool linenoise; +} libmap_t; + typedef enum { - BSD3, - GPLv3, MIT, - UNLICENCE, - LICENCE_HELP, + GPL, + BSD, + UNL, } 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 { + libmap_t libraries; licence_t licence; + flag_t flags; + char *project; char *name; - lib_flags_t libraries; - flags_t flag; } manifest_t; -#define HAS_LIBRARY(libs, lib) ((libs) & (lib)) -#define ADD_LIBRARY(libs, lib) ((libs) |= (lib)) -#define REMOVE_LIBRARY(libs, lib) ((libs) &= ~(lib)) - int create_project(manifest_t manifest); int mkdir_p(const char *path); -int create_file_with_content(const char *path, const char *format, ...); +int cfprintf(const char *path, const char *format, ...); #endif // YAIT_H diff --git a/src/contents.h b/src/contents.h index aa59981..3db82a1 100644 --- a/src/contents.h +++ b/src/contents.h @@ -10,10 +10,9 @@ #ifndef CONTENTS_H #define CONTENTS_H -#define line(l) l "\n" +#define line(ln) ln "\n" -/* README template */ -char *readme_template = +char *readme = line ("%s ( concise description )") line () line ("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor") @@ -23,8 +22,7 @@ char *readme_template = line ("fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in") line ("culpa qui officia deserunt mollit anim id est laborum."); -/* configure script template */ -char *configure_template = +char *configure = line ("#!/bin/sh") line () line ("usage() {") @@ -41,7 +39,7 @@ char *configure_template = line ("exit 0") line ("}") line () - line ("echo () { printf \"%s\\n\" \"$*\" ; }") + line ("echo () { printf \"%%s\\n\" \"$*\" ; }") line ("cmdexists () { type \"$1\" >/dev/null 2>&1 ; }") line ("trycc () { test -z \"$CC\" && cmdexists \"$1\" && CC=$1 ; }") line () @@ -59,8 +57,8 @@ char *configure_template = line ("done") line () line ("printf \"checking for C compiler... \"") - line ("%s") - line ("printf \"%s\\n\" \"$CC\"") + line ("%%s") + line ("printf \"%%s\\n\" \"$CC\"") line () line ("printf \"checking weather C compiler works... \"") line ("status=\"fail\"") @@ -69,19 +67,18 @@ char *configure_template = line ("if output=$($CC $CFLAGS -c -o /dev/null \"$tmpc\" 2>&1) ; then") line ("printf \"yes\\n\"") line ("else") - line ("printf \"no; %s\\n\" \"$output\"") + line ("printf \"no; %%s\\n\" \"$output\"") line ("exit 1") line ("fi") line () line ("printf \"creating config.mak... \"") - line ("printf \"PREFIX=%s\\n\" \"$prefix\" > config.mak") - line ("printf \"CFLAGS=%s\\n\" \"$CFLAGS\" >> config.mak") - line ("printf \"LDFLAGS=%s\\n\" \"$LDFLAGS\" >> config.mak") - line ("printf \"CC=%s\\n\" \"$CC\" >> config.mak") + line ("printf \"PREFIX=%%s\\n\" \"$prefix\" > config.mak") + line ("printf \"CFLAGS=%%s\\n\" \"$CFLAGS\" >> config.mak") + line ("printf \"LDFLAGS=%%s\\n\" \"$LDFLAGS\" >> config.mak") + line ("printf \"CC=%%s\\n\" \"$CC\" >> config.mak") line ("printf \"done\\n\""); -/* Makefile template */ -char *makefile_template = +char *makefile = line ("prefix = /usr/bin") line () line ("%s_SRCS := $(wildcard %s/*.c)") @@ -127,12 +124,10 @@ char *makefile_template = line () line (".PHONY: all clean dist-clean install uninstall"); -/* .clang-format template */ -char *clang_format_template = +char *clang_format = line ("BasedOnStyle: GNU"); -/* BSD 3-Clause License template */ -char *bsd3_license_template = +char *bsd3_license = line ("BSD 3-Clause License") line () line ("Copyright (c) %d, %s") @@ -162,16 +157,13 @@ char *bsd3_license_template = line ("OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE") line ("OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."); -/* MIT License template */ -char *mit_license_template = +char *mit_license = line ("THIS IS THE MIT LICENSE"); -/* GPLv3 License template */ -char *gplv3_license_template = +char *gplv3_license = line ("THIS IS THE GPLv3 LICENSE"); -/* config.h template */ -char *config_h_template = +char *config_h = line ("#ifndef CONFIG_H") line ("#define CONFIG_H") line () @@ -188,8 +180,7 @@ char *config_h_template = line () line ("#endif"); -/* main.c (non-GNU) template */ -char *main_c_template = +char *main_c = line ("#include ") line () line ("int main(void) {") @@ -197,8 +188,7 @@ char *main_c_template = line (" return 0;") line ("}"); -/* main.c (GNU) template */ -char *main_c_gnu_template = +char *main_c_gnu = line ("#include ") line ("#include \"standard.h\"") line () @@ -214,8 +204,7 @@ char *main_c_gnu_template = line (" return 0;") line ("}"); -/* standard.c template */ -char *standard_c_template = +char *standard_c = line ("#include \"standard.h\"") line ("#include \"../config.h\"") line ("#include ") @@ -241,8 +230,7 @@ char *standard_c_template = line (" return HELP_REQUESTED;") line ("}"); -/* standard.h template */ -char *standard_h_template = +char *standard_h = line ("#ifndef STANDARD_H") line ("#define STANDARD_H") line () @@ -250,8 +238,7 @@ char *standard_h_template = line () line ("#endif"); -/* WHATNEXT.md template */ -char *what_next_template = +char *what_next = line ("# What next?") line ("") line ("## Steps") diff --git a/src/create_project.c b/src/create_project.c index ee43800..ced71b7 100644 --- a/src/create_project.c +++ b/src/create_project.c @@ -6,9 +6,44 @@ * */ +#include +#include + #include "../include/yait.h" +#include "contents.h" + +char buffer[BUFSIZ]; int create_project(manifest_t manifest) { + mkdir_p(manifest.project); + chdir(manifest.project); + + if (manifest.flags.simple) { + cfprintf( + "Makefile", + ".POSIX:\nCC ::= gcc\nCFLAGS ::= -Wall --std=c23 -Wpedantic\n\nall: %s", + manifest.project); + cfprintf("README", "%s", manifest.project); + + snprintf(buffer, BUFSIZ, "%s.c", manifest.project); + cfprintf(buffer, ""); + return 0; + } + + cfprintf("Makefile", ""); + cfprintf("configure", configure); + cfprintf(".clang-format", ""); + cfprintf("README", readme, manifest.name); + cfprintf("src/main.c", ""); + + snprintf(buffer, BUFSIZ, "include/%s.h", manifest.project); + cfprintf(buffer, ""); + + snprintf(buffer, BUFSIZ, "man/%s.1", manifest.project); + cfprintf(buffer, ""); + + cfprintf("doc/WHATNEXT", what_next); + return 0; } diff --git a/src/file.c b/src/file.c index 2a082f0..538a508 100644 --- a/src/file.c +++ b/src/file.c @@ -47,7 +47,7 @@ int mkdir_p(const char *path) return status; } -int create_file_with_content(const char *path, const char *format, ...) +int cfprintf(const char *path, const char *format, ...) { char *dirpath; const char *slash = strrchr(path, '/'); diff --git a/src/main.c b/src/main.c index 9c33f50..d596ec9 100644 --- a/src/main.c +++ b/src/main.c @@ -10,106 +10,68 @@ #include #include +#define _POSIX_C_SOURCE 200809L // popen extention #include #include #include #include -#include "../config.h" #include "../include/yait.h" -#include "standard.c" +#include "standard.h" +#include "util.h" #define print_option(option, description) \ - printf(" %-20s %-20s\n", option, description) + fprintf(stderr, " %-20s %-20s\n", option, description) -// clang-format off -static void -usage (int status) +static void usage(int status) { - if (status != 0) - { - fprintf (stderr, "Try 'yait --help' for more information.\n"); - return; - } + if (status != 0) { + fputs("Try 'yait --help' for more information.\n", stderr); + return; + } - printf ("Usage: yait [OPTION]... \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"); + fputs("Usage: yait [OPTION]... ", stderr); + fputs("Creates a C project with opinionated defaults.", stderr); + fputs("When only given the first argument it will detect your name.\n", + stderr); + fputs("Mandatory arguments to long options are mandatory for short options too", + stderr); + print_option("--posix", "Enable POSIX compliance"); + print_option("--git", "Do not inititize git reposity"); + print_option("--clang", "Add clang-format files and tooling"); + print_option("-L ", "Set licence"); + print_option("-l ", "Add a library"); + print_option("-C", "Use C++"); + print_option("--GNU", + "Add GNU argument parsing: --version, and --help"); + print_option("-S, --simple", "Enable simple mode"); + fputs(" --help display this help text and exit", stderr); + fputs(" --version output version information and exit", stderr); } -// 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) { + + while ((opt = getopt(argc, argv, "L:l:CS")) != -1) { switch (opt) { - case 'g': - conf->flag.GNU = true; - break; - case 'c': - conf->flag.use_cpp = true; - break; - case 'i': - conf->flag.git = true; + case 'L': + conf->licence = TOlicence(optarg); 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); + case 'C': + conf->flags.cc = true; + break; + case 'S': + conf->flags.simple = true; + break; default: - usage(1); - exit(1); + fprintf(stderr, "Usage: %s [--help]\n", argv[0]); + return 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; } @@ -145,7 +107,24 @@ int get_name(char **output) int main(int argc, char **argv) { int status; - manifest_t manifest = { 0 }; + manifest_t manifest = { + .project = "Project", + .name = "author", + .licence = UNL, + .libraries.ncurses = false, + .libraries.raylib = false, + .libraries.stb = false, + .libraries.uthash = false, + .libraries.linenoise = false, + + .flags.posix = false, + .flags.git = true, + .flags.clang = false, + .flags.lib = false, + .flags.cc = false, + .flags.gnu = true, + .flags.simple = false, + }; status = parse_standard_options(usage, argc, argv); if (status != 0 && status != HELP_REQUESTED) @@ -154,14 +133,8 @@ int main(int argc, char **argv) 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; - } - } - + get_name(&manifest.name); status = create_project(manifest); - return status == 0 ? EXIT_SUCCESS : EXIT_FAILURE; + + return EXIT_SUCCESS; } diff --git a/src/standard.c b/src/standard.c index 176d31b..f11c722 100644 --- a/src/standard.c +++ b/src/standard.c @@ -10,11 +10,13 @@ #define COMMIT 0 #endif -#include "../config.h" #include #include #include +#include "../config.h" +#include "standard.h" + int parse_standard_options(void (*usage)(int), int argc, char **argv) { for (int i = 0; i < argc; ++i) { diff --git a/src/standard.h b/src/standard.h new file mode 100644 index 0000000..a71b41d --- /dev/null +++ b/src/standard.h @@ -0,0 +1,8 @@ +#ifndef STANDARD_H +#define STANDARD_H + +#define HELP_REQUESTED 2 + +int parse_standard_options(void (*usage)(int), int argc, char **argv); + +#endif diff --git a/src/util.c b/src/util.c new file mode 100644 index 0000000..23850ef --- /dev/null +++ b/src/util.c @@ -0,0 +1,14 @@ +#include + +#include "util.h" +#include "../include/yait.h" + +// clang-format off +licence_t TOlicence(const char *s) +{ + if (strcmp(s, "mit")) return MIT; + if (strcmp(s, "gpl")) return GPL; + if (strcmp(s, "bsd")) return BSD; + return UNL; +} +// clang-format on diff --git a/src/util.h b/src/util.h new file mode 100644 index 0000000..ec6abec --- /dev/null +++ b/src/util.h @@ -0,0 +1,8 @@ +#ifndef UTIL_H +#define UTIL_H + +#include "../include/yait.h" + +licence_t TOlicence(const char *s); + +#endif