mirror of
https://git.lain.church/bake/bake.git
synced 2025-06-19 12:07:58 +00:00
expunge and whatever
This commit is contained in:
44
README
44
README
@ -64,3 +64,47 @@ needs to be tested a bit more to confirm full compatibility.
|
|||||||
|
|
||||||
changes - Rewrite of the code; Removal of -x --expunge; Addition of
|
changes - Rewrite of the code; Removal of -x --expunge; Addition of
|
||||||
@LINE & @NAME, list, & select.
|
@LINE & @NAME, list, & select.
|
||||||
|
|
||||||
|
24/08/22 - Expunge
|
||||||
|
|
||||||
|
I decided to add expunge back in, after I went back to a project using
|
||||||
|
it, because I didn't feel like writing a regexp that would prune it.
|
||||||
|
|
||||||
|
It works the same. However it's less tested. Backslashes are reliable.
|
||||||
|
It doesn't eat characters around itself and returns a reliable string.
|
||||||
|
It does, however, cover the same space as the origin string.
|
||||||
|
|
||||||
|
Such brutal expressions as '@{\} @{\}@SHORT\}}' -> '} @{}@SHORT}'
|
||||||
|
successfully, with expunge_me correctly containing only that.
|
||||||
|
|
||||||
|
It's the same, as before. Sadly I didn't generalize the search and
|
||||||
|
replace code, that's what sed is for, and I didn't want to implement
|
||||||
|
finite automata for this simple update, so its implementation is primitive.
|
||||||
|
|
||||||
|
The implementation as a whole was meant for simplicity,
|
||||||
|
extensibility. I, before getting it working, got a gorilla version
|
||||||
|
that removed contextless @{ } successfully, and a version that
|
||||||
|
contextually removed each @{ and it's respective } via expand.
|
||||||
|
|
||||||
|
Interesting note: Old Bake's executable is larger than new Bakes.
|
||||||
|
So, not only do we have constant memory, but I've saved space.
|
||||||
|
|
||||||
|
Note that the only real limitation is that, that we can't make a @BAKE
|
||||||
|
command the size of THIS file, or a a @BAKE command inlining all of
|
||||||
|
Bake. If you need such a feature, use the old version of Bake, or
|
||||||
|
simply extend this version. I may do such things, because the code
|
||||||
|
here is better.
|
||||||
|
|
||||||
|
This project really was never meant to be optimized, simply memory
|
||||||
|
confined. if it goes over, it'll SEGV and imply to the diligent user
|
||||||
|
to shorten his commands. If you just need enough in a simple fashion,
|
||||||
|
boosting:
|
||||||
|
#define BUFFER_SIZE (1 << 12) /* 4096 bytes; 4 KiB */
|
||||||
|
TO (1 << 20) /* 1048576 bytes; 1 MiB */
|
||||||
|
|
||||||
|
4 KiB is enough in 99% cases and covers 100% of usage that I am aware
|
||||||
|
of apart from the case of testing this exact faculty. If it does limit
|
||||||
|
you, you can use an external script or <Using Make!/Old Bake>
|
||||||
|
|
||||||
|
I'm not planning to update Shake with @STOP, @LINE, (-x, --expunge),
|
||||||
|
or any new bells and wistles.
|
||||||
|
14
bake.1
14
bake.1
@ -4,7 +4,7 @@
|
|||||||
\- file embeddable scripts
|
\- file embeddable scripts
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B bake
|
.B bake
|
||||||
[\-chln] [\-s <n>] <FILENAME> [ARGS...]
|
[\-chlnx] [\-s <N>] <FILENAME> [ARGS...]
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
|
|
||||||
bake is a simple tool meant to execute embedded shell commands within
|
bake is a simple tool meant to execute embedded shell commands within
|
||||||
@ -16,10 +16,15 @@ instance of \fB@BAKE\fP appears.
|
|||||||
|
|
||||||
It roots the shell execution in the directory of the given file.
|
It roots the shell execution in the directory of the given file.
|
||||||
|
|
||||||
Options must always be put first, and short options may be merged together.
|
Options must always be put first, and short options may be merged together, numerical options must be trailing.
|
||||||
|
|
||||||
.HP
|
.HP
|
||||||
\fB\-c \-\-color\fP, \-h \-\-help, \fB\-n \-\-dry\-run\fP, \fB\-l \-\-list\fP, \fB\-s \-\-select\fP <\fBn\fP>
|
\fB\-c \-\-color\fP, Disables color
|
||||||
|
\-h \-\-help, Help message
|
||||||
|
\fB\-n \-\-dry\-run\fP, don't execute anything
|
||||||
|
\fB\-l \-\-list\fP, lists available shell commands
|
||||||
|
\fB\-s \-\-select\fP <\FBn\fP>, selects Nth shell command
|
||||||
|
\fB\-x \-\-expunge\fP, Removes what's specified in the expunge block
|
||||||
.PP
|
.PP
|
||||||
Macros
|
Macros
|
||||||
|
|
||||||
@ -47,7 +52,8 @@ Additional Features And Notes
|
|||||||
|
|
||||||
Shell execution may be disabled with the \fB-n\fP or \fB--dry-run\fP option.
|
Shell execution may be disabled with the \fB-n\fP or \fB--dry-run\fP option.
|
||||||
|
|
||||||
Colors may be disabled with the \fB-c\fP or \fB--color\fP option.
|
Expunge removes exactly one file specified in the @{...} format. You may use
|
||||||
|
backslashes to remove
|
||||||
|
|
||||||
.SH EXAMPLE
|
.SH EXAMPLE
|
||||||
.\" SRC BEGIN (example.c)
|
.\" SRC BEGIN (example.c)
|
||||||
|
116
bake.c
116
bake.c
@ -1,4 +1,7 @@
|
|||||||
// @BAKE cc -std=c99 -O2 -Wall -Wextra -Wpedantic -Wno-implicit-fallthrough -o @SHORT @FILENAME @ARGS @STOP
|
/* @BAKE cc -std=c99 -O2 -Wall -Wextra -Wpedantic -Wno-implicit-fallthrough -o @SHORT @FILENAME @ARGS @STOP */
|
||||||
|
/* @BAKE cc -std=c99 -O2 -Wall -Wextra -Wpedantic -Wno-implicit-fallthrough -o '@{\} @{\}@SHORT\}}' @FILENAME @ARGS @STOP */
|
||||||
|
/* @BAKE cc -std=c99 -O2 -Wall -Wextra -Wpedantic -Wno-implicit-fallthrough -o '@{\}}' @FILENAME @ARGS @STOP */
|
||||||
|
/* @BAKE cc -std=c99 -O2 -Wall -Wextra -Wpedantic -Wno-implicit-fallthrough -o '@{a}' @FILENAME @ARGS @STOP */
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -16,8 +19,8 @@
|
|||||||
|
|
||||||
#define BUFFER_SIZE (1 << 12)
|
#define BUFFER_SIZE (1 << 12)
|
||||||
|
|
||||||
#define START ("@" "BAKE" " ")
|
#define START "@" "BAKE" " "
|
||||||
#define STOP ("@" "STOP")
|
#define STOP "@" "STOP"
|
||||||
|
|
||||||
#define AUTONOMOUS_COMPILE 0
|
#define AUTONOMOUS_COMPILE 0
|
||||||
|
|
||||||
@ -45,10 +48,8 @@
|
|||||||
|
|
||||||
#define ARRLEN(x) (sizeof (x) / sizeof (x [0]))
|
#define ARRLEN(x) (sizeof (x) / sizeof (x [0]))
|
||||||
|
|
||||||
#if AUTONOMOUS_COMPILE
|
__attribute__((__section__(".text"))) static volatile char autonomous_compile [] =
|
||||||
__attribute__((__section__(".text"))) static char autonomous_compile [] =
|
"@BAKE cc -std=c99 -O2 -Wall -Wextra -Wpedantic -Wno-implicit-fallthrough -o @SHORT @FILENAME.c @ARGS @STOP";
|
||||||
"@BAKE" " cc -w @FILENAME.c -o @FILENAME @ARGS\n";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
swap (char * a, char * b) {
|
swap (char * a, char * b) {
|
||||||
@ -113,8 +114,7 @@ lines (char * buffer, size_t off) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
expand (char * buffer, size_t length, char ** pairs, size_t count) {
|
expand_buffer(char * expanded, char * buffer, size_t length, char ** pairs, size_t count) {
|
||||||
static char expanded [BUFFER_SIZE] = {0};
|
|
||||||
size_t old, new, i, f, off = 0;
|
size_t old, new, i, f, off = 0;
|
||||||
/* I need to test the bounds checking here, it'll crash normally if this provision doesn't do anything, though. */
|
/* I need to test the bounds checking here, it'll crash normally if this provision doesn't do anything, though. */
|
||||||
length &= (1 << 12) - 1;
|
length &= (1 << 12) - 1;
|
||||||
@ -137,6 +137,36 @@ expand (char * buffer, size_t length, char ** pairs, size_t count) {
|
|||||||
return expanded;
|
return expanded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
expand (char * buffer, size_t length, char ** pairs, size_t count) {
|
||||||
|
static char expanded [BUFFER_SIZE] = {0};
|
||||||
|
return expand_buffer (expanded, buffer, length, pairs, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
expunge (char * to, char * from, size_t length, char ** pair, size_t count) {
|
||||||
|
size_t i, f;
|
||||||
|
(void)count; /* count isn't actually used... */
|
||||||
|
static char expunge_me [FILENAME_MAX] = {0};
|
||||||
|
for (i = 0; i < length; ++i) {
|
||||||
|
if (memcmp(from + i, pair[0], strlen(pair[0])) == 0) {
|
||||||
|
if (from[i - 1] == '\\') { --i; memmove(from + i, from + i + 1, length - i); i+=1+strlen(pair[0]); --length; continue; }
|
||||||
|
for (f = i + strlen(pair[0]); f < length; ++f) {
|
||||||
|
if (memcmp(from + f, pair[1], strlen(pair[1])) == 0) {
|
||||||
|
if (from[f - 1] == '\\') { --f; memmove(from + f, from + f + 1, length - f); --length; continue; }
|
||||||
|
memmove(to + i, from + i + strlen(pair[0]), length - i - strlen(pair[0]));
|
||||||
|
memmove(to + f - strlen(pair[1]), from + f - 1, length - f);
|
||||||
|
/* memcpy(to + f - 2, " ", strlen(pair[1])); */
|
||||||
|
memcpy(expunge_me, to + i, f - i - 1 - strlen(pair[1]));
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end:
|
||||||
|
return expunge_me;
|
||||||
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
getmap (char * filename, size_t * length) {
|
getmap (char * filename, size_t * length) {
|
||||||
char * buffer = NULL;
|
char * buffer = NULL;
|
||||||
@ -192,21 +222,24 @@ color_fprintf (FILE * fp, char * format, ...) {
|
|||||||
free (buf);
|
free (buf);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -- */
|
/* -- */
|
||||||
|
|
||||||
int main (int argc, char ** argv) {
|
int main (int argc, char ** argv) {
|
||||||
void help (void);
|
void help (void);
|
||||||
int off, run = 1, list = 0, select_input, select = 1;
|
int off, run = 1, list = 0, ex = 0, select_input, select = 1;
|
||||||
size_t length, begin = 0, end = 0;
|
size_t length, begin = 0, end = 0;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
char line [10], expanded [BUFFER_SIZE], * buffer, * expandedp, * args, * shortened, * filename = NULL;
|
char line [10], expanded [BUFFER_SIZE], * buffer, * expandedp, * args, * shortened, * filename = NULL,
|
||||||
|
* paren [] = { "@{", "}" }, * expunge_me = NULL, * bake_begin = START, * bake_end = STOP;
|
||||||
|
|
||||||
/* opts */
|
/* opts */
|
||||||
for (off = 1; off < argc; ++off) {
|
for (off = 1; off < argc; ++off) {
|
||||||
if (argv [off][0] != '-') { filename = argv [off]; ++off; break; }
|
if (argv [off][0] != '-') { filename = argv [off]; ++off; break; }
|
||||||
if (argv [off][1] != '-') {
|
if (argv [off][1] != '-') {
|
||||||
while (*(++argv [off]))
|
while (*(++argv [off]))
|
||||||
switch (argv [off][0]) {
|
switch (argv [off][0]) {
|
||||||
case_select: case 's':
|
select: case 's':
|
||||||
select = atoi (argv [off] + 1);
|
select = atoi (argv [off] + 1);
|
||||||
if (!select) {
|
if (!select) {
|
||||||
++off;
|
++off;
|
||||||
@ -214,19 +247,23 @@ int main (int argc, char ** argv) {
|
|||||||
select = atoi (argv [off]);
|
select = atoi (argv [off]);
|
||||||
}
|
}
|
||||||
if (select) { goto next; }
|
if (select) { goto next; }
|
||||||
case_help: default: case 'h': help ();
|
default: case 'h': help ();
|
||||||
case_list: case 'l': list = 1;
|
case 'l': list = 1;
|
||||||
case_dryrun: case 'n': run = 0; break;
|
case 'n': run = 0; break;
|
||||||
case_color: case 'c': color = 0; break;
|
case 'c': color = 0; break;
|
||||||
|
case 'x': ex = 1; break;
|
||||||
|
case 'q': fclose(stderr); fclose(stdout); break;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
argv[off] += 2;
|
argv[off] += 2;
|
||||||
if (strcmp(argv[off], "select") == 0) { goto case_select; }
|
if (strcmp(argv[off], "select") == 0) { goto select; }
|
||||||
else if (strcmp(argv[off], "list") == 0) { goto case_list; }
|
else if (strcmp(argv[off], "list") == 0) { list = 1; run = 0; }
|
||||||
else if (strcmp(argv[off], "dry-run") == 0) { goto case_dryrun; }
|
else if (strcmp(argv[off], "dry-run") == 0) { run = 0; }
|
||||||
else if (strcmp(argv[off], "color") == 0) { goto case_color; }
|
else if (strcmp(argv[off], "color") == 0) { color = 0; }
|
||||||
else if (strcmp(argv[off], "help") == 0) { goto case_help; }
|
else if (strcmp(argv[off], "expunge") == 0) { ex = 1; }
|
||||||
|
else if (strcmp(argv[off], "quiet") == 0) { fclose(stderr); fclose(stdout); }
|
||||||
|
else if (strcmp(argv[off], "help") == 0) { help(); }
|
||||||
next:;
|
next:;
|
||||||
}
|
}
|
||||||
if (argc == 1 || !filename) { help (); }
|
if (argc == 1 || !filename) { help (); }
|
||||||
@ -239,14 +276,14 @@ int main (int argc, char ** argv) {
|
|||||||
color_fprintf (stderr, RED "%s" RESET ": Could not access '" BOLD "%s" RESET "'\n", argv [0], filename);
|
color_fprintf (stderr, RED "%s" RESET ": Could not access '" BOLD "%s" RESET "'\n", argv [0], filename);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
for (begin = 0; (list || select) && begin < length - strlen (START); ++begin) {
|
for (begin = 0; (list || select) && begin < length - strlen (bake_begin); ++begin) {
|
||||||
if (memcmp (buffer + begin, START, strlen (START)) == 0) {
|
if (memcmp (buffer + begin, bake_begin, strlen (bake_begin)) == 0) {
|
||||||
size_t stop = begin;
|
size_t stop = begin;
|
||||||
end = begin;
|
end = begin;
|
||||||
again: while (end < length && buffer[end] != '\n') { ++end; }
|
again: while (end < length && buffer[end] != '\n') { ++end; }
|
||||||
if (buffer[end - 1] == '\\') { ++end; goto again; }
|
if (buffer[end - 1] == '\\') { ++end; goto again; }
|
||||||
while (stop < length - strlen(STOP)) {
|
while (stop < length - strlen(bake_end)) {
|
||||||
if (memcmp(buffer + stop, STOP, strlen(STOP)) == 0) {
|
if (memcmp(buffer + stop, bake_end, strlen(bake_end)) == 0) {
|
||||||
if (stop && buffer[stop - 1] == '\\') { ++stop; continue; }
|
if (stop && buffer[stop - 1] == '\\') { ++stop; continue; }
|
||||||
end = stop;
|
end = stop;
|
||||||
break;
|
break;
|
||||||
@ -259,7 +296,7 @@ int main (int argc, char ** argv) {
|
|||||||
color_puts (RESET);
|
color_puts (RESET);
|
||||||
} else { --select; }
|
} else { --select; }
|
||||||
}}
|
}}
|
||||||
begin += strlen (START) - 1;
|
begin += strlen (bake_begin) - 1;
|
||||||
|
|
||||||
if (list) { return 0; }
|
if (list) { return 0; }
|
||||||
if (end < begin) {
|
if (end < begin) {
|
||||||
@ -280,19 +317,33 @@ int main (int argc, char ** argv) {
|
|||||||
"@ARGS", args,
|
"@ARGS", args,
|
||||||
"$+", args,
|
"$+", args,
|
||||||
"@LINE", line
|
"@LINE", line
|
||||||
};
|
};
|
||||||
size_t count = ARRLEN (pair);
|
|
||||||
snprintf (line, 16, "%lu", lines (buffer, begin));
|
snprintf (line, 16, "%lu", lines (buffer, begin));
|
||||||
expandedp = expand (buffer + begin, end - begin, pair, count);
|
expandedp = expand (buffer + begin, end - begin, pair, ARRLEN (pair));
|
||||||
memcpy(expanded, expandedp, BUFFER_SIZE);
|
memcpy(expanded, expandedp, BUFFER_SIZE);
|
||||||
|
expunge_me = expunge (expanded, expanded, strlen(expanded), paren, ARRLEN (paren));
|
||||||
munmap (buffer, length);
|
munmap (buffer, length);
|
||||||
|
|
||||||
/* print and execute */
|
/* print and execute */
|
||||||
color_printf (GREEN "%s" RESET ": " BOLD "%s" RESET, argv [0], expanded);
|
color_fprintf (stderr, GREEN "%s" RESET ": " BOLD "%s" RESET, argv [0], expanded);
|
||||||
if (expanded[strlen(expanded)] != '\n') { puts(""); }
|
if (expanded[strlen(expanded)] != '\n') { puts(""); }
|
||||||
|
|
||||||
|
if (ex) {
|
||||||
|
color_fprintf (stderr, GREEN "%s" RESET ": removing '%s'\n", argv [0], expunge_me);
|
||||||
|
char * jin = ".c";
|
||||||
|
if (expunge_me
|
||||||
|
&& run
|
||||||
|
&& /* just in case */
|
||||||
|
memcmp(expunge_me + strlen(expunge_me) - strlen(jin), jin, strlen(jin)) != 0)
|
||||||
|
{ remove(expunge_me); }
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!run) { return 0; }
|
if (!run) { return 0; }
|
||||||
fflush(stdout);
|
|
||||||
color_fprintf (stderr, GREEN "output" RESET ":\n");
|
color_fprintf (stderr, GREEN "output" RESET ":\n");
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
if ((pid = fork ()) == 0) {
|
if ((pid = fork ()) == 0) {
|
||||||
execl ("/bin/sh", "sh", "-c", expanded, NULL);
|
execl ("/bin/sh", "sh", "-c", expanded, NULL);
|
||||||
return 0; /* execl overwrites the process anyways */
|
return 0; /* execl overwrites the process anyways */
|
||||||
@ -334,7 +385,8 @@ void help (void) {
|
|||||||
"of the shell command (-n, --dry-run); disable color (-c, --color); list\n"
|
"of the shell command (-n, --dry-run); disable color (-c, --color); list\n"
|
||||||
"(-l, --list) and select (-s<n>, --select <n>) which respectively lists\n"
|
"(-l, --list) and select (-s<n>, --select <n>) which respectively lists\n"
|
||||||
"all " BOLD "@BAKE" RESET " commands and select & run the Nth command.\n\n"
|
"all " BOLD "@BAKE" RESET " commands and select & run the Nth command.\n\n"
|
||||||
"It roots the shell execution in the directory of the given file.\n\n"
|
"It roots the shell execution in the directory of the given file.\n"
|
||||||
|
"Expunge with @{filename...}, using (-x, --expunge), \\@{} or @{\\}}.\n\n"
|
||||||
"Licensed under the public domain.\n";
|
"Licensed under the public domain.\n";
|
||||||
color_printf ("%s", help);
|
color_printf ("%s", help);
|
||||||
exit (1);
|
exit (1);
|
||||||
|
Reference in New Issue
Block a user