commit 41cfafbaf00e52fda1a7fc6d3b67bbb6ced20387
parent 5ea2f16ba9ed229010561678a146840075ac37ea
Author: vx-clutch <[email protected]>
Date: Sun, 20 Jul 2025 15:50:48 -0400
save
Diffstat:
10 files changed, 165 insertions(+), 66 deletions(-)
diff --git a/Makefile b/Makefile
@@ -22,10 +22,9 @@ build:
c-out/obj/%.o: yait/%.c
$(CC) $(CFLAGS) -c $< -o $@
-$(YAIT): $(YAIT_OBJS)
+$(YAIT): $(YAIT_OBJS) $(EMBED_HEADER)
$(CC) $(CFLAGS) -DCOMMIT=$(shell git rev-list --count --all) $^ -o $@
-
endif
install:
@@ -38,8 +37,10 @@ uninstall:
clean:
rm -rf c-out
+ rm -f $(EMBED_HEADER)
+ rm -f $(EMBED_HEADERS)
dist-clean: clean
rm -f config.mak
-.PHONY: all clean dist-clean install uninstall build format
+.PHONY: all clean dist-clean install uninstall build format gen-file-embeds
diff --git a/README b/README
@@ -6,8 +6,4 @@ project files needed for your new C ( maybe C++ ) project. It provides you with
a build system and some basic source files to give you a kick start on your new
project--with optional libraries!
-The future of this project may be uncertain--however there are a few features I
-for sure want to have.
-
- A --GNU flag that will add basic flag parsing into the project for the
- --version and --help flags.
+For more detailed documentation vist: <https://vx-clutch.github.io/vxserver.dev/docs/yait.html>
diff --git a/config.mak b/config.mak
@@ -0,0 +1,4 @@
+PREFIX=/usr/bin/
+CFLAGS=-Wall -Wextra -O2
+LDFLAGS=
+CC=gcc
diff --git a/configure b/configure
@@ -37,6 +37,9 @@ trycc cc
trycc clang
printf "%s\n" "$CC"
+printf "checking for xxd... "
+trycc xxd
+
printf "checking weather C compiler works... "
status="fail"
tmpc="$(mktemp -d)/test.c"
diff --git a/embed/Makefile b/embed/Makefile
@@ -0,0 +1,58 @@
+prefix = /usr/bin
+
+YAIT_SRCS := $(wildcard yait/*.c) $(wildcard core/*.c)
+YAIT_OBJS := $(patsubst yait/%.c,c-out/obj/%.o,$(YAIT_SRCS))
+
+YAIT := c-out/bin/yait
+
+-include config.mak
+
+ifeq ($(wildcard config.mak),)
+all:
+ @echo "File config.mak not found, run configure"
+ @exit 1
+else
+
+all: build $(YAIT) $(YAIT_DOC)
+
+build:
+ mkdir -p c-out/bin
+ mkdir -p c-out/obj
+
+EMBED_FILES := $(wildcard embed/*)
+gen-file-embeds:
+ @echo "// Generated header with embedded files" > $(EMBED_HEADER)
+ @echo "#ifndef EMBEDDED_FILES_H" >> $(EMBED_HEADER)
+ @echo "#define EMBEDDED_FILES_H" >> $(EMBED_HEADER)
+ @echo "" >> $(EMBED_HEADER)
+ @for f in $(EMBED_FILES); do \
+ var=$$(echo $$f | tr './-' '__' | tr '[:lower:]' '[:upper:]'); \
+ xxd -i $$f | sed "s/^unsigned char/${var}_data/" | sed "s/^unsigned int/${var}_len/" >> $(EMBED_HEADER); \
+ echo "" >> $(EMBED_HEADER); \
+ done
+ @echo "#endif // EMBEDDED_FILES_H" >> $(EMBED_HEADER)
+
+c-out/obj/%.o: yait/%.c
+ $(CC) $(CFLAGS) -c $< -o $@
+
+$(YAIT): $(YAIT_OBJS)
+ $(CC) $(CFLAGS) -DCOMMIT=$(shell git rev-list --count --all) $^ -o $@
+
+
+endif
+
+install:
+ @echo "NOT IMPL"
+ exit 1
+
+uninstall:
+ @echo "NOT IMPL"
+ exit 1
+
+clean:
+ rm -rf c-out
+
+dist-clean: clean
+ rm -f config.mak
+
+.PHONY: all clean dist-clean install uninstall build format gen-file-embeds
diff --git a/configure b/embed/configure
diff --git a/tools/file_to_string.py b/tools/file_to_string.py
@@ -1,42 +0,0 @@
-#!/usr/bin/env python3
-import argparse
-
-
-def c_escape_byte(b):
- if b == 0x09:
- return r'\t'
- elif b == 0x0A:
- return r'\n'
- elif b == 0x0D:
- return r'\r'
- elif b == 0x5C: # \
- return r'\\'
- elif b == 0x22: # "
- return r'\"'
- elif 0x20 <= b <= 0x7E:
- return chr(b)
- elif b == 0x25: # %
- return '%%'
- else:
- return f'\\x{b:02x}'
-
-
-def file_to_c_string(filepath):
- with open(filepath, 'rb') as f:
- content = f.read()
- escaped = ''.join(c_escape_byte(b) for b in content)
- return f'"{escaped}"'
-
-
-def main():
- parser = argparse.ArgumentParser(
- description='Convert file contents to a valid C string literal.')
- parser.add_argument('input', help='Path to input file')
- args = parser.parse_args()
-
- c_string = file_to_c_string(args.input)
- print(c_string)
-
-
-if __name__ == '__main__':
- main()
diff --git a/tools/gen-embed-header b/tools/gen-embed-header
@@ -0,0 +1,10 @@
+#!/bin/env bash
+
+files=./embed/*
+
+touch embed_header.h
+echo "" > embed_header.h
+
+for f in $files; do
+ xxd -i >> embed_header.h
+done
diff --git a/yait/format.h b/yait/format.h
@@ -25,14 +25,20 @@ typedef enum {
*/
} lib_flags_t;
+/* Flag option type struct */
+typedef struct {
+ bool GNU;
+ bool git;
+ bool clang_format;
+} flags_t;
+
/* Project configuration structure */
typedef struct {
- bool git; /* Whether to initialize git repository */
- bool clang_format; /* Whether to create .clang-format file */
licence_t licence; /* License type for the project */
char *project; /* Project name */
char *name; /* Author/creator name */
lib_flags_t libraries; /* Selected libraries (bit field) */
+ flags_t flag; /* Flags */
} format_t;
/* Default values */
diff --git a/yait/main.c b/yait/main.c
@@ -3,7 +3,6 @@
#include "../core/print.h"
#include "../core/standard.h"
#include "format.h"
-#include <ctype.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
@@ -81,8 +80,11 @@ main (int argc, char **argv)
else
conf.name = DEFAULT_USER_NAME;
}
- conf.git = DEFAULT_GIT_INIT;
- conf.clang_format = DEFAULT_CLANG_FORMAT;
+ conf.flag.git = DEFAULT_GIT_INIT;
+ conf.flag.clang_format = DEFAULT_CLANG_FORMAT;
+
+ conf.flag.GNU = true; // debug
+
conf.licence = DEFAULT_LICENSE;
int result = create_project (conf);
@@ -103,7 +105,7 @@ create_project (format_t fmt)
printfn ("failed to create or enter directory: %s", strerror (err));
return 1;
}
- if (fmt.git)
+ if (fmt.flag.git)
err = system ("git init --quiet");
if (err)
{
@@ -202,7 +204,7 @@ create_project (format_t fmt)
create_file_with_content (
"Makefile",
"prefix = /usr/bin\n\n"
- "%s_SRCS := $(wildcard *.c)\n"
+ "%s_SRCS := $(wildcard %s*.c)\n"
"%s_OBJS := $(patsubst %%.c,c-out/obj/%%.o,$(%s_SRCS))\n\n"
"%s := c-out/bin/%s\n\n"
"-include config.mak\n\n"
@@ -232,15 +234,18 @@ create_project (format_t fmt)
"dist-clean: clean\n"
"\trm -f config.mak\n\n"
".PHONY: all clean dist-clean install uninstall build format\n",
- mkfile_name, mkfile_name, mkfile_name, mkfile_name, fmt.project,
- mkfile_name, mkfile_name, mkfile_name);
+ mkfile_name, mkfile_name, mkfile_name, mkfile_name, mkfile_name,
+ fmt.project, mkfile_name, mkfile_name, mkfile_name);
free (mkfile_name);
- if (fmt.clang_format)
+ if (fmt.flag.clang_format)
create_file_with_content (".clang-format",
"Language: Cpp\nBasedOnStyle: GNU\n");
+ char *license_line = "";
switch (fmt.licence)
{
case BSD3:
+ license_line = "License BSD-3-Clause: BSD-3-Clause "
+ "<https://opensource.org/licence/bsd-3-clause>";
create_file_with_content (
"COPYING",
"BSD 3-Clause License\n\nCopyright (c) %d, "
@@ -274,12 +279,70 @@ create_project (format_t fmt)
default:
break;
}
+ create_file_with_content ("config.h",
+ "#ifndef CONFIG_H\n"
+ "#define CONFIG_H\n\n"
+ "/* Program information */\n"
+ "#define PROGRAM \"%s\"\n"
+ "#define LICENSE_LINE \"%s\"\n"
+ "#define AUTHORS \"%s\"\n"
+ "#define VERSION \"pre-alpha\"\n"
+ "#define YEAR 2025\n\n"
+ "#endif",
+ fmt.project, license_line, fmt.name, YEAR);
create_and_enter_directory (fmt.project);
- create_file_with_content (
- "main.c",
- "#include <stdio.h>\n\nint main(void) {\n printf(\"%s: Hello "
- "%s!\\n\");\nreturn 0;\n}",
- fmt.project ? fmt.project : DEFAULT_PROJECT_NAME,
- fmt.name ? fmt.name : "World");
+ if (!fmt.flag.GNU)
+ {
+ create_file_with_content (
+ "main.c",
+ "#include <stdio.h>\n\nint main(void) {\n printf(\"%s: Hello "
+ "%s!\\n\");\n return 0;\n}",
+ fmt.project ? fmt.project : DEFAULT_PROJECT_NAME,
+ fmt.name ? fmt.name : "World");
+ }
+ else
+ {
+ create_file_with_content (
+ "main.c",
+ "#include <stdio.h>\n"
+ "#include \"standard.h\"\n"
+ "\n"
+ "void usage(int status) {\nprintf(\"Usage: %s [OPTION...]\\n\")\n}\n"
+ "\n"
+ "int main(void) {\n"
+ "parse_standard_options(NULL, argc, argv);\n"
+ "printf(\"%s: Hello "
+ "%s!\\n\");\n return 0;\n}",
+ fmt.project, fmt.project ? fmt.project : DEFAULT_PROJECT_NAME,
+ fmt.name ? fmt.name : "World");
+ }
+ if (fmt.flag.GNU)
+ {
+ create_file_with_content (
+ "standard.c",
+ "#include \"standard.h\"\n#include \"../config.h\"\n#include "
+ "<stdio.h>\n#include <stdlib.h>\n#include "
+ "<string.h>\n\nint\nparse_standard_options (void (*usage) (int), "
+ "int argc, char **argv)\n{\n for (int i = 1; i < argc; ++i)\n "
+ "{\n if (strcmp (argv[i], \"--help\") == 0)\n {\n "
+ " usage (0);\n exit (EXIT_SUCCESS);\n }\n "
+ "else if (strcmp (argv[i], \"--version\") == 0)\n {\n "
+ " printf (\"%%s %%s %%d\\nCopyright (C) %%d %%s.\\n%%s\\nThis is "
+ "free "
+ "software: \"\n \"you are free to change and "
+ "redistribute it.\\nThere is NO \"\n \"WARRNTY, to "
+ "the extent permitted by law.\\n\",\n PROGRAM, "
+ "VERSION, COMMIT, YEAR, AUTHORS, LICENSE_LINE);\n exit "
+ "(EXIT_SUCCESS);\n }\n }\n return HELP_REQUESTED;\n}\n");
+ create_file_with_content (
+ "standard.h",
+ "#ifndef STANDARD_H\n#define STANDARD_H\n\n/**\n * Parse standard "
+ "command line options (--help, --version)\n * @param usage_func "
+ "Function pointer to usage display function\n * @param argc "
+ "Argument count\n * @param argv Argument vector\n * @return 0 on "
+ "success, 1 if help/version requested, errno on error\n */\nint "
+ "parse_standard_options(void (*usage_func)(), int argc, char "
+ "**argv);\n\n#endif\n");
+ }
return 0;
}