save
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
2
Makefile
2
Makefile
@@ -12,7 +12,7 @@ all:
|
||||
@exit 1
|
||||
else
|
||||
|
||||
all: build $(YAIT) $(YAIT_DOC)
|
||||
all: build $(YAIT)
|
||||
|
||||
build:
|
||||
mkdir -p bin
|
||||
|
||||
7
TODO
Normal file
7
TODO
Normal file
@@ -0,0 +1,7 @@
|
||||
VX yait --- TODO
|
||||
|
||||
Todo:
|
||||
|
||||
* Argument Parsing
|
||||
|
||||
end of file TODO
|
||||
5
config.h
5
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
|
||||
|
||||
4
config.mak
Normal file
4
config.mak
Normal file
@@ -0,0 +1,4 @@
|
||||
PREFIX=/usr/bin/
|
||||
CFLAGS=-ggdb -std=c23
|
||||
LDFLAGS=
|
||||
CC=gcc
|
||||
2
configure
vendored
2
configure
vendored
@@ -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=
|
||||
|
||||
|
||||
8
doc/simple_project/Makefile
Normal file
8
doc/simple_project/Makefile
Normal file
@@ -0,0 +1,8 @@
|
||||
.POSIX:
|
||||
CC ::= gcc
|
||||
CFLAGS ::= -Wall -Wpedenatic -O2
|
||||
|
||||
all: simple
|
||||
|
||||
clean:
|
||||
$(RM) simple
|
||||
3
doc/simple_project/README
Normal file
3
doc/simple_project/README
Normal file
@@ -0,0 +1,3 @@
|
||||
simple.c vx-clutch
|
||||
|
||||
A simple program that does simple things.
|
||||
0
doc/simple_project/simple.c
Normal file
0
doc/simple_project/simple.c
Normal file
@@ -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
|
||||
|
||||
@@ -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 <stdio.h>")
|
||||
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 <stdio.h>")
|
||||
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 <stdio.h>")
|
||||
@@ -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")
|
||||
|
||||
@@ -6,9 +6,44 @@
|
||||
* <https://opensource.org/licence/bsd-3-clause>
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
@@ -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, '/');
|
||||
|
||||
145
src/main.c
145
src/main.c
@@ -10,106 +10,68 @@
|
||||
|
||||
#include <getopt.h>
|
||||
#include <pwd.h>
|
||||
#define _POSIX_C_SOURCE 200809L // popen extention
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#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]... <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");
|
||||
fputs("Usage: yait [OPTION]... <PATH>", 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 <licence>", "Set licence");
|
||||
print_option("-l <library>", "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;
|
||||
}
|
||||
|
||||
@@ -10,11 +10,13 @@
|
||||
#define COMMIT 0
|
||||
#endif
|
||||
|
||||
#include "../config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../config.h"
|
||||
#include "standard.h"
|
||||
|
||||
int parse_standard_options(void (*usage)(int), int argc, char **argv)
|
||||
{
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
|
||||
8
src/standard.h
Normal file
8
src/standard.h
Normal file
@@ -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
|
||||
14
src/util.c
Normal file
14
src/util.c
Normal file
@@ -0,0 +1,14 @@
|
||||
#include <string.h>
|
||||
|
||||
#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
|
||||
8
src/util.h
Normal file
8
src/util.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef UTIL_H
|
||||
#define UTIL_H
|
||||
|
||||
#include "../include/yait.h"
|
||||
|
||||
licence_t TOlicence(const char *s);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user