From 5fbbadcc9be4e18d91a157621f0773e8739d4909 Mon Sep 17 00:00:00 2001 From: Greg Gauthier Date: Mon, 30 Mar 2026 23:29:26 +0100 Subject: [PATCH] initial commit --- .gitignore | 2 + Makefile | 0 README.md | 21 ++++++++ TODO.md | 0 src/main.c | 137 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 160 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 README.md create mode 100644 TODO.md create mode 100644 src/main.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..41f7f34 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.idea/ +build/ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e69de29 diff --git a/README.md b/README.md new file mode 100644 index 0000000..de82a38 --- /dev/null +++ b/README.md @@ -0,0 +1,21 @@ +# proj + +A project skeleton generator written in strict C90/ANSI C for C, Python, Rexx, and Go + +## Overview + +TBD + +## Installation + +TBD + +## Usage + +TBD + +## Customization / COnfiguration + +TBD + + diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..e69de29 diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..fb7dd2d --- /dev/null +++ b/src/main.c @@ -0,0 +1,137 @@ +/* proj - project skeleton generator + * Strict ANSI C89 + * Generates basic project layouts for C, Go, Python, REXX + */ + +#include +#include +#include +#include + +#define MAX_PATH 256 +#define MAX_CMD 512 + +/* Simple template substitution */ +static void substitute(FILE *in, FILE *out, const char *projname, const char *author, const char *year) +{ + char line[1024]; + while (fgets(line, sizeof(line), in)) { + char *p = line; + while ((p = strstr(p, "{{"))) { + char *end = strstr(p + 2, "}}"); + if (!end) break; + *p = '\0'; + fputs(p, out); /* text before placeholder */ + p += 2; + if (strncmp(p, "PROJECT_NAME", end - p) == 0) + fputs(projname, out); + else if (strncmp(p, "AUTHOR", end - p) == 0) + fputs(author, out); + else if (strncmp(p, "YEAR", end - p) == 0) + fputs(year, out); + else + fputs("{{UNKNOWN}}", out); + p = end + 2; + } + fputs(p, out); /* remaining text */ + } +} + +/* Create directory (via system for portability) */ +static int make_dir(const char *path) +{ + char cmd[MAX_CMD]; + sprintf(cmd, "mkdir -p %s", path); + return system(cmd); +} + +/* Generate a basic C CLI project */ +static int generate_c_cli(const char *projname, const char *author) +{ + char year[16], path[MAX_PATH]; + time_t now = time(NULL); + strftime(year, sizeof(year), "%Y", localtime(&now)); + + /* Create directories */ + sprintf(path, "%s/src", projname); + make_dir(path); + sprintf(path, "%s/include", projname); + make_dir(path); + + /* README */ + { + FILE *f = fopen("README", "w"); + if (f) { + fprintf(f, "# %s\n\nA simple CLI tool.\n\n", projname); + fclose(f); + } + } + + /* Makefile */ + { + FILE *f = fopen("Makefile", "w"); + if (f) { + fprintf(f, "CC = cc\n"); + fprintf(f, "CFLAGS = -Wall -Wextra -std=c89 -pedantic\n\n"); + fprintf(f, "all: %s\n\n", projname); + fprintf(f, "%s: src/main.c\n", projname); + fprintf(f, "\t$(CC) $(CFLAGS) -o $@ $<\n\n"); + fprintf(f, "clean:\n"); + fprintf(f, "\trm -f %s\n", projname); + fclose(f); + } + } + + /* src/main.c */ + { + FILE *f = fopen("src/main.c", "w"); + if (f) { + fprintf(f, "/* %s - CLI tool */\n\n", projname); + fprintf(f, "#include \n\n"); + fprintf(f, "int main(int argc, char *argv[])\n"); + fprintf(f, "{\n"); + fprintf(f, " printf(\"Hello from %s!\\n\");\n", projname); + fprintf(f, " return 0;\n"); + fprintf(f, "}\n"); + fclose(f); + } + } + + printf("Created C CLI project: %s\n", projname); + return 0; +} + +static void usage(void) +{ + printf("Usage: proj [options]\n"); + printf(" c Generate ANSI C CLI skeleton\n"); + printf(" go Generate Go module skeleton\n"); + printf(" python Generate Python package skeleton\n"); + printf(" rexx Generate REXX script skeleton\n"); + printf("\nOptions:\n"); + printf(" --quote Insert a random quote from cquote into README\n"); + printf(" --desc TEXT Short project description\n"); + printf(" --author NAME Author name\n"); +} + +int main(int argc, char *argv[]) +{ + if (argc < 3) { + usage(); + return 1; + } + + const char *lang = argv[1]; + const char *name = argv[2]; + const char *author = "Greg Gauthier"; /* default - change or add flag */ + + if (strcmp(lang, "c") == 0) { + generate_c_cli(name, author); + } else { + printf("Language '%s' not yet supported.\n", lang); + return 1; + } + + return 0; +} +