the exceptions of multi-line commands. It is not a general
replacement for Bake.
+Shake doesn't support multi-line commands.
+
Changelog
Bake was created on 2023/09/13, and complete as of 2024/03/02.
Lex. As adviced by the original creator, I learned and implemented a
Bake with lex. It's fully featured, and has new stuff.
+
+2024-10-24 - Awake
+
+Egor (some dead guy) made a AWK implementation of Bake, it's POSIX.
+It doesn't support multi-line, expunge, parses options after filename,
+or changing directory to file's directory - it's compatible with Bake
+otherwise.
+
+ cd /dir/of/file; awake file
+
+See ./awake --help
#!/bin/sh
# vim:set ft=awk:
+# Written by Egor, modified for compatibility by Emil.
# SPDX-License-Identifier: Unlicense
-"exec" "${AWK:-awk}" "-f" "$0" "--" "$@" && 0
+"exec" "${AWK:-awk}" "-f" "$(basename $0)" "--" "$@" && 0
function usage() {
print "awake: usage: awake [-nl] [-s num] filename [args...]"
exit
if (list) {
print bakenum": "$0
} else if (select == bakenum) {
- gsub(/@FILENAME/, filename)
- gsub(/@NAME/, filename)
- gsub(/@SHORT/, shortname)
- gsub(/@ARGS/, extraargs)
- print
+ gsub(/\$@|@(FILE|FILENAME|NAME)/, filename)
+ gsub(/\$\*|@SHORT/, shortname)
+ gsub(/\$\+|@ARGS/, extraargs)
+ gsub(/@RECURS/, ARGV[0])
+ print "Awake: " $0
+ printf "Output: "
if (!dryrun) {
system($0)
+ print ""
}
}
}
-/* cbake.l @BAKE flex @FILE && cc -Wall -Wextra -std=c99 -D_GNU_SOURCE -o @SHORT lex.yy.c @ARGS @STOP */
-/* expunge @BAKE flex @FILE && cc -Wall -Wextra -std=c99 -D_GNU_SOURCE -o @{@SHORT} lex.yy.c @ARGS @STOP */
+/* @BAKE flex @FILE && cc -Wall -Wextra -Wwrite-strings -std=c99 -D_GNU_SOURCE -o @SHORT lex.yy.c @ARGS @STOP */
/* Licensed under the public domain. */
%{
extern void root(char * filename);
extern void args(int n, int rest);
extern void shorten(char * filename, int n);
-extern void pipeopen(char * filename, char * mode);
%}
SPACE [ \t\r\v\f]
%%
#include <limits.h>
+#include <stdarg.h>
# define RED "\033[91m"
# define GREEN "\033[92m"
char * end = filename + strlen(filename);
while (n && (end = memrchr(filename, '.', end - filename))) { --n; }
if (!end) {
- fprintf(stderr, "<SHORTEN> context error: Argument out of range.\n");
- /* Ensures consistency. @SHORT will always return *something* that isn't filename */
- STRING("idiot");
- return;
+ fprintf(stderr, "%s: Cannot shorten '%s' any further, aborting due to paranoia\n", av0, filename);
+ abort();
}
FWRITE(filename, end - filename);
}
void help(void) { fprintf(stderr, g_color ? BOLD "%s" RESET : "%s", "see bake(1) - \"Buy high. Sell low.\"\n"); }
-void pipeopen(char * filename, char * mode) {
- g_pipe = popen(filename, mode);
- if (!g_pipe) { fprintf(stderr, "%s: <g_pipe> %s\n", av0, strerror(errno)); exit(1); }
+FILE * pipeopen(char * filename, char * mode) {
+ FILE * pipe = popen(filename, mode);
+ if (!pipe) { fprintf(stderr, "%s: <pipeopen> %s\n", av0, strerror(errno)); exit(1); }
+ return pipe;
+}
+
+void print(FILE * fp, char * color_prefix, char * format, ...) {
+ va_list ap;
+ size_t len = strlen(format);
+ g_color ? fprintf(fp, "%s%s: ", color_prefix, av0)
+ : fprintf(fp, "%s: ", av0);
+ va_start(ap, format);
+ for (size_t i = 0, f = 0; i < len; ++i) {
+ if (!(format[i] ^ '\033')) {
+ while (format[i] && format[i] != 'm') ++i;
+ } else format[f++] = format[i];
+ }
+ vfprintf(fp, format, ap);
+ va_end(ap);
}
int main (int ac, char ** av) {
/* setup pipe and output */
if (run) {
- pipeopen("/bin/sh -e /dev/stdin", "w");
+#define pipeopen(a,b) pipeopen((char*)(a), (char*)(b))
+ g_pipe = pipeopen("/bin/sh -e /dev/stdin", "w");
}
if (g_rm) {
g_restore = stdout;
yylex(); fflush(stdout);
if (g_rm) {
- fputs("\n", g_restore);
+ fputc('\n', g_restore);
stdout = g_restore;
g_pipe = g_expunge;
}
run = pclose(g_pipe); /* repurposed run */
if (!g_rm) { putchar('\n'); }
- if (run) { fprintf(stderr, "%s: Exit code %d\n", av0, run); }
+ if (run < 0) { fprintf(stderr, "%s: Exit failure\n", av0); }
+ if (run > 0) { fprintf(stderr, "%s: Exit code %d\n", av0, run); }
return run;
out_of_range: fprintf(stderr, "%s: <%d> Out of range\n", av0, g_select); return 1;
}
#!/bin/sh
# source install
-TARGET=${TARGET:-/usr/local}
-INSTALL=${INSTALL:-bake}
+TARGET="${TARGET:-/usr/local}"
+INSTALL="bake"
-cd "$(dirname "$(readlink -f $0)")"
+usage() {
+ echo "compiles and installs Bake into /usr/local (or TARGET) in bin/"
+ echo ""
+ echo "--alternatives Includes awake and shake into the build"
+ echo "--target=DIRECTORY Target directory like /usr or /usr/local"
+ echo ""
+ exit 1
+}
+
+while [ ! -z $1 ]; do
+ case $(echo "$1" | cut -d= -f1) in
+ "--target")
+ TARGET=$(echo "$1" | cut -d= -f2)
+ ;;
+ "--alternatives")
+ INSTALL="bake shake awake"
+ ;;
+ "--help")
+ usage
+ ;;
+ *)
+ echo "Unknown option: " $1
+ usage
+ ;;
+ esac
+ shift
+done
-./shake bake.l -s $@ && \
-mkdir $TARGET/bin $TARGET/man/man1 -p && \
-install -m 755 $INSTALL $TARGET/bin
+cd "$(dirname "$(readlink -f $0)")"
-gzip -c bake.1 > $TARGET/man/man1/bake.1.gz
+./awake bake.l
+mkdir -p "$TARGET/bin" "$TARGET/man/man1"
+install -m 755 $INSTALL "$TARGET/bin"
+gzip -c bake.1 > "$TARGET/man/man1/bake.1.gz"