diff --git a/README b/README index f1d1699..510d4af 100644 --- a/README +++ b/README @@ -1,35 +1,49 @@ -Baked, embed scripts into files. +Bake scripts into files. Executes @EXEC to the end of the line or STOP@ within in any given file. +If there is no STOP@, it'll simply execute until the end of line, supports +backslashes to include additional lines. -you may see a real example in the primary and only source file: `baked.c'. +you may see a real example in the primary and only source file: `bake.c'. this is not targeted toward any language and should be fairly flexible, especially when multi-line comments are available. +The execution takes place at the root of the target file, so if you have: +/my/test/file.c, and then execution takes place at /my/test. + Buildng +Bootstrapping may be done with Shake, simply run `./shake ./bake.c' + Initial building may be done by examining and running `install.sh', if you don't want to install it right away, run `SUDO= TARGET=. ./install.sh' -Name/Arg extension +Name/Arg Extension $@: the name of the executed file $*: the text of the filename before the last dot -$+: the remaining arguments to Baked +$+: the remaining arguments to Bake -Options extension +Options Extension only one option may be in use at a time, and must come as the first argument. -h, --help: displays help message, similiarly to empty input. -n, --dry-run: DRYRUN, does NOT run anything! -Notes +Shake -Baked was inspired by the Bash-based Shake utility (formerly eMake, +Bake was inspired by the Bash-based Shake utility (formerly eMake, he liked my suggestion for a name), written by an anon, which you may view at: -Baked is licensed under the GPLv3, See LICENSE. +Bake includes Shake, both in installation, and as a bootstrapper. It +is included under creator's permission. It is not a replacement for +Bake, but it is platform independent in regards to it's use of Bash. -Baked began on September 13th, 2023. +Shake is a bash based build utility which only seaches for, and executes +the first line including @COMPILECMD. It supports $@, and $*. + +Bake is licensed under the GPLv3, See LICENSE. + +Bake began on September 13th, 2023. diff --git a/baked.c b/bake.c similarity index 94% rename from baked.c rename to bake.c index 9c1c379..01e3b70 100644 --- a/baked.c +++ b/bake.c @@ -1,9 +1,10 @@ -/* baked.c - Ever burned a cake? +/* bake.c - Ever burned a cake? * Copyright 2023 Emil Williams * * Licensed under the GNU Public License version 3 only, see LICENSE. * - * @EXEC cc $@ -o $* -std=gnu89 -O2 -Wall -Wextra -Wpedantic -pipe $CFLAGS STOP@ + * Using COMPILECMD and including the # STOP for bake/shake support + * @COMPILECMD cc $@ -o $* -std=gnu89 -O2 -Wall -Wextra -Wpedantic -pipe $CFLAGS # STOP@ */ #include @@ -20,12 +21,12 @@ #include #include -/* Require space after @ABC and before STOP@ (no space required around newline) */ +/* Require space after COMPILECMD/EXEC and before STOP (no space required around newline) */ #define REQUIRE_SPACE -/* May be undefined */ -#define OTHER_START "@COMPILECMD" +/* May be be left undefined, comes second */ +#define OTHER_START "@EXEC" -#define START "@EXEC" +#define START "@COMPILECMD" #define STOP "STOP@" #define HELP \ "target-file [arguments ...]\n" \ diff --git a/baked-nobloat.c b/baked-nobloat.c deleted file mode 100644 index 69b8d84..0000000 --- a/baked-nobloat.c +++ /dev/null @@ -1,227 +0,0 @@ -/* baked-nobloat.c - cake makes you fat. This version just removes features I don't find entirely necessary ($+, require space, shake support, ctype, and options). - * Copyright 2023 Emil Williams - * Licensed under the GNU Public License version 3 only, see LICENSE. - * @EXEC cc $@ -o $* -std=gnu89 -O2 -Wall -Wextra -Wpedantic -pipe $CFLAGS STOP@ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define START "@EXEC" -#define STOP "STOP@" -#define HELP \ - "target-file [arguments ...]\n" \ - "Use the format `@EXEC cmd ...' within the target-file, this will execute the\n" \ - "rest of line, or if found within the file, until the STOP@ marker.\n" - -#define DESC \ - "Expansions\n" \ - "\t$@ returns target-file (abc.x.txt)\n" \ - "\t$* returns target-file without suffix (^-> abc.x)\n" - -char * g_filename, * g_short; - -static char * -map(char * fn, size_t * len) -{ - struct stat s; - int fd; - char * addr = NULL; - fd = open(fn, O_RDONLY); - if (fd != -1) - { - if (!fstat(fd,&s) - && s.st_mode & S_IFREG - && s.st_size) - { - *len = s.st_size; - addr = mmap(NULL, s.st_size, PROT_READ, MAP_SHARED, fd, 0); - } - close(fd); - } - return addr; -} - -static char * -find(char * x, char * buf, size_t max, size_t min) -{ - char * start = buf; - for (; *buf; ++buf) - { - if (max - (buf - start) > min && !strncmp(buf, x, min)) - { return buf; } - } - return NULL; -} - -static char * -find_region(char * fn, char * start, char * stop) -{ - size_t len = 0; - char * buf = NULL, * addr; - char * pb, * pe; - addr = map(fn, &len); - if (addr != MAP_FAILED) - { - if ((pb = find(start, addr, len, strlen(start)))) - { - pb += strlen(start); - pe = find(stop, pb, len - (pb - addr), strlen(stop)); - if (pe) - { buf = strndup(pb, (pe - addr) - (pb - addr)); } - } - munmap(addr, len); - } - return buf; -} - - -static char * -insert(char * new, char * str, size_t offset, size_t shift) -{ - size_t len, max; - if (!new || !str) { return NULL; } - len = strlen(new); - max = (strlen(str) + 1 - offset - shift); - memmove(str + offset + len, str + offset + shift, max); - memcpy(str + offset, new, len); - return str; -} - -static char * -shorten(char * fn) -{ - size_t i, last = 0, len; - char * sh; - len = strlen(fn); - sh = malloc(len + 1); - if (!sh) { return NULL; } - for (i = 0; i < len; ++i) - { - if (fn[i] == '.') - { last = i; } - } - last = last ? last : i; - strncpy(sh, fn, last); - sh[last] = '\0'; - return sh; -} - -static size_t -expand_size(char * buf) -{ - size_t i, len, max; - len = max = strlen(buf) + 1; - for (i = 0; i < len; ++i) - { - if (buf[i] == '\\') - { i += 2; continue; } - else if (buf[i] == '$') - { - switch (buf[++i]) - { - case '@': - max += strlen(g_filename); - break; - case '*': - if (!g_short) - { g_short = shorten(g_filename); } - max += g_short ? strlen(g_short) : 0; - break; - } - } - } - return max; -} - -static char * -expand(char * buf) -{ - size_t i; - char * ptr = NULL; - buf = realloc(buf, expand_size(buf)); - if (!buf) { return NULL; } - for (i = 0; buf[i]; ++i) - { - if (buf[i] == '\\') - { i += 2; continue; } - else if (buf[i] == '$') - { - switch (buf[++i]) - { - case '@': - ptr = g_filename; - break; - case '*': - ptr = g_short; - break; - default: continue; - } - buf = insert(ptr, buf, i - 1, 2); - } - } - free(g_short); - return buf; -} - -static void -swap(char * a, char * b) -{ - *a ^= *b; - *b ^= *a; - *a ^= *b; -} - -static int -root(char * root) -{ - int ret; - char x[1] = "\0"; - size_t len = strlen(root); - while (len && root[len] != '/') - { --len; } - if (!len) - { return 0; } - swap(root + len, x); - ret = chdir(root); - swap(root + len, x); - return ret; -} - -int -main(int argc, char ** argv) -{ - char * buf; - setlocale(LC_ALL, "C"); - if (argc < 2) { goto help; } - g_filename = argv[1]; - buf = find_region(g_filename, START, STOP); - if (!buf) - { - if (errno) - { perror(argv[0]); } - else - { fprintf(stderr, "%s: File unrecognized.\n", argv[0]); } - return 1; - } - buf = expand(buf); - root(argv[0]); - fprintf(stderr, "Exec: %s\n", buf); - if (!buf) { return 1; } - fputs("Output:\n", stderr); - fflush(stderr); - system(buf); - free(buf); - return 0; -help: - fprintf(stderr, "%s: %s", argv[0], HELP DESC); - return 1; -} diff --git a/install.sh b/install.sh index 5435c1f..1c7eb3c 100755 --- a/install.sh +++ b/install.sh @@ -1,5 +1,6 @@ #!/bin/sh cd $(dirname "$(readlink -f "$0")") SUDO=${SUDO:-sudo} -cc baked.c -o baked -std=gnu89 -O2 -Wall -Wextra -Wpedantic -pipe $CFLAGS -$SUDO install -m 755 baked ${TARGET:-/usr/local/bin} +chmod +x shake +./shake bake.c +$SUDO install -m 755 shake bake ${TARGET:-/usr/local/bin} diff --git a/shake b/shake new file mode 100755 index 0000000..5044f51 --- /dev/null +++ b/shake @@ -0,0 +1,56 @@ +#!/bin/bash + +BLUE='\033[34m' +GREEN='\033[32m' +BOLD='\033[1m' +NORMAL='\033[0m' + +MARK="@COMPILECMD " +MARKSTR="${BLUE}@COMPILECMD${NORMAL}" + +enable -n echo + +usage() { + IFSTR="${GREEN}${NORMAL}" + echo -e "${BOLD}Usage: $0 ${NORMAL}" >&2 + echo -e "\t$0 runs the value of ${MARKSTR}." >&2 + echo -e "\tThe point of this script is ease to compialation of singe source file (toy) programs." >&2 + echo -e "\tThe value of ${MARKSTR} is read from ${IFSTR} in is whatever comes after '${MARK}' until the end of the line." >&2 + echo -e "\tInside the value of ${MARKSTR} all mentions of special placeholders are replaced:" >&2 + echo -e "\t\t${BLUE}\$@${NORMAL} - ${IFSTR}" + echo -e "\t\t${BLUE}\$*${NORMAL} - ${IFSTR} with the last extension cut off" +} + + + +if [[ $# -ne 1 ]]; then + usage + exit 1 +fi + +if [[ $1 == "-h" ]] || [[ $1 == "--help" ]]; then + usage + exit 0 +fi + + + +input_file=$1 + +if [[ ! -f $input_file ]]; then + echo -e "Input file '$input_file' does not exist." >&2 + exit 1 +fi + +line=$(grep "$MARK" "$input_file" | head -1) +line=${line//\$@/$input_file} +line=${line//\$\*/${input_file%.*}} + +if [[ -n $line ]]; then + command="${line#*@COMPILECMD }" + + echo "$command" + eval "$command" +else + echo -e "${MARKSTR} is not defined." >&2 +fi