From b0a2fc6331f2a05485713d98e2162ed7b7709b74 Mon Sep 17 00:00:00 2001 From: Emil Williams Date: Sun, 22 Sep 2024 21:21:10 +0000 Subject: [PATCH 1/8] flex bake --- .gitignore | 2 + cbake.l | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ install.sh | 5 +++ 3 files changed, 142 insertions(+) create mode 100644 .gitignore create mode 100644 cbake.l create mode 100644 install.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0fcb3f7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +cbake +lex.yy.c diff --git a/cbake.l b/cbake.l new file mode 100644 index 0000000..56f551b --- /dev/null +++ b/cbake.l @@ -0,0 +1,135 @@ +/* cbake.l @BAKE flex @FILE && cc -std=c99 -D_GNU_SOURCE -o @SHORT lex.yy.c @ARGS -lfl @STOP */ +%{ + +#include + +#define backspace(fs) fputs("\x08", fs) +#undef ECHO +#define ECHO do { fprintf(stdout, yytext); if (gpipe) { fprintf(gpipe, yytext); } } while (0) +#define CHAR(c) do { fputc(c, stdout); if (gpipe) { fputc(c, gpipe); } } while (0) +#define STRING(s) do { fputs(s, stdout); if (gpipe) { fputs(s, gpipe); } } while (0) +#define FORMAT(...) do { fprintf(stdout, __VA_ARGS__); if (gpipe) { fprintf(gpipe, __VA_ARGS__); } } while (0) +#define FWRITE(str, len) do { fwrite(str, 1, len, stdout); if (gpipe) { fwrite(str, 1, len, gpipe); } } while (0) + +FILE * gpipe; + +char * filename; +int gac; +char ** gav; +/* Options */ +int gselect = 1; +/* Line accum */ +int line = 1; + +extern void root(char * filename); +extern void args(int n); +extern void shorten(char * filename, int n); +%} + +SPACE [[:space:]] +NUM [[:digit:]] + +%x FOUND + +%option nodefault +%% +{ + \\. { /* skip next char */ ; } + @FILENAME|@FILE|$@ { STRING(filename); } + @SHORT:{NUM}+ { shorten(filename, atoi(strrchr(yytext, ':')+1)); } + @SHORT|$\* { shorten(filename, 1); } + @ARGS:{NUM}+ { args(atoi(strrchr(yytext, ':')+1)); } + @ARGS|$\+ { args(-1); } + @STOP { CHAR('\n'); if (gpipe) { fprintf(stderr, "output: "); } if (!gselect) { return 0; } BEGIN INITIAL; } + {SPACE}+ { CHAR(' '); } + . { ECHO; } +} + +@BAKE{SPACE} { if (gselect < 0) { static int nth = 0; printf("%s:%d:s%d: ", filename, line, ++nth); BEGIN FOUND; } if (!--gselect) { BEGIN FOUND; } } +\n|\n { ++line; } +. { ; } +%% + +void root(char * filename) { + char * path, * terminator; + if (!(path = realpath(filename, NULL))) { return; } + if (terminator = strrchr(path, '/')) { + *terminator = '\0'; + chroot(path); + } + free(path); +} + +void args(int n) { + if (n < 0) { for (int i = 0; i < gac; ++i) { STRING(gav[i]); if (i + 1 < gac) { CHAR(' '); } } } + else if (n < gac) { STRING(gav[n]); } +} + +void shorten(char * filename, int n) { + char * end = filename + strlen(filename); + while (n && (end = memrchr(filename, '.', end - filename))) { --n; } + if (!end) { fprintf(stderr, " context error: Argument out of range.\n"); STRING("idiot"); return; } + FWRITE(filename, end - filename); +} + +#define HELP \ + "bake(1) - \"Buy high. Sell low.\"\n" +void help(void) { puts(HELP); } + +int main (int ac, char ** av) { + int run = 1; + char * av0 = av[0]; + FILE * fp, * op; + + while (++av, --ac) { + int i; + if (av[0][0] != '-') { goto start; } + if (av[0][1] == '-') { + if (av[0][2] == '\0') { ++av, --ac; goto start; } + if (!strcmp(av[0]+2, "dry-run")) { i = strlen(av[0]); goto opt_dry_run; } + if (!strcmp(av[0]+2, "select" )) { if (!ac-1 || isdigit(av[1][0])) { goto opt_arg; } ++av, --ac; + i = strlen(av[0]); goto opt_select; } + if (!strcmp(av[0]+2, "list" )) { i = strlen(av[0]); goto opt_list; } + if (!strcmp(av[0]+2, "help" )) { goto opt_help; } + goto opt_default; + } + for (i = 1; i < strlen(av[0]); ++i) { + switch (av[0][i]) { + opt_dry_run: case 'n': run = 0; break; + opt_select: case 's': gselect = atoi(av[0]+2+(av[0][2] == '=')); break; + opt_list: case 'l': run = 0; gselect = -1; break; + opt_help: case 'h': help(); return 0; + opt_default: default: fprintf(stderr, "%s: Unknown option '%s'\n", av0, av[0]); return 1; + opt_arg: fprintf(stderr, "%s: Argument missing for '%s'\n", av0, av[0]); return 1; + } + } + } + + start: + if (!ac) { fprintf(stderr, "%s: Missing filename\n", av0); return 1; } + + /* filename and self placement */ + filename = av[0]; + root(filename); + { + char * tmp = strrchr(filename, '/'); + if (tmp) { filename = tmp+1; } + } + + /* open and prepare ac, av */ + if (!(yyin = fp = fopen(filename, "rb"))) + { fprintf(stderr, "%s: '%s' %s\n", av0, filename, strerror(errno)); return 1; } + gac = --ac, gav = ++av; + + if (run) { + gpipe = popen("/bin/sh -e", "w"); + if (!gpipe) { fprintf(stderr, "%s: %s\n", av0, strerror(errno)); return 1; } + } + if (gselect > 0) { fprintf(stderr, "%s: ", av0); fflush(stderr); } + yylex(); + if (gselect > 0) { fprintf(stderr, "%s: Out of range\n", av0); } + fclose(fp); + + if (run) { run = pclose(gpipe); if (run) { printf("%s: Exit code %d\n", av0, run); } return run; } + return 0; +} diff --git a/install.sh b/install.sh new file mode 100644 index 0000000..806173b --- /dev/null +++ b/install.sh @@ -0,0 +1,5 @@ +cd "$(dirname "$(readlink -f $0)")" +PREFIX=${PREFIX:-/usr/local} +echo "PREFIX=$PREFIX" +bake cbake.l +install -m755 -sv ./cbake $PREFIX/bin/ From 6ede1232709548c5cdc6f35e3abd0bf71b875043 Mon Sep 17 00:00:00 2001 From: Emil Williams Date: Sun, 22 Sep 2024 21:37:27 +0000 Subject: [PATCH 2/8] discard expunge for backwards compat --- cbake.l | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/cbake.l b/cbake.l index 56f551b..5e90348 100644 --- a/cbake.l +++ b/cbake.l @@ -1,4 +1,4 @@ -/* cbake.l @BAKE flex @FILE && cc -std=c99 -D_GNU_SOURCE -o @SHORT lex.yy.c @ARGS -lfl @STOP */ +/* cbake.l @BAKE flex @FILE && cc -std=c99 -D_GNU_SOURCE -o @{@SHORT} lex.yy.c @ARGS -lfl @STOP */ %{ #include @@ -18,8 +18,9 @@ int gac; char ** gav; /* Options */ int gselect = 1; -/* Line accum */ -int line = 1; +/* accum */ +int line = 1, expunge_depth = 0; + extern void root(char * filename); extern void args(int n); @@ -41,6 +42,8 @@ NUM [[:digit:]] @ARGS:{NUM}+ { args(atoi(strrchr(yytext, ':')+1)); } @ARGS|$\+ { args(-1); } @STOP { CHAR('\n'); if (gpipe) { fprintf(stderr, "output: "); } if (!gselect) { return 0; } BEGIN INITIAL; } + @\{ { ++expunge_depth; } + \} {if (!expunge_depth--) { ECHO; } } {SPACE}+ { CHAR(' '); } . { ECHO; } } From 591d3734ef75230e3cae08acf18f943d2cb62e58 Mon Sep 17 00:00:00 2001 From: Emil Williams Date: Tue, 24 Sep 2024 22:29:08 +0000 Subject: [PATCH 3/8] 80% there to total bakery --- cbake.l | 46 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/cbake.l b/cbake.l index 5e90348..b66524e 100644 --- a/cbake.l +++ b/cbake.l @@ -19,8 +19,7 @@ char ** gav; /* Options */ int gselect = 1; /* accum */ -int line = 1, expunge_depth = 0; - + int line = 1, expunge_depth = 0, first_nl, nth = 0; extern void root(char * filename); extern void args(int n); @@ -30,27 +29,52 @@ extern void shorten(char * filename, int n); SPACE [[:space:]] NUM [[:digit:]] -%x FOUND +%x FOUND STOP -%option nodefault +%option nodefault noinput noyywrap %% + +@BAKE{SPACE} { + first_nl = 1; + if (gselect < 0) { + printf("%s:%d s%d: ", filename, line, ++nth); + BEGIN FOUND; + } + if (!--gselect) { BEGIN FOUND; } +} + +\n { ++line; } +. { ; } + { - \\. { /* skip next char */ ; } @FILENAME|@FILE|$@ { STRING(filename); } @SHORT:{NUM}+ { shorten(filename, atoi(strrchr(yytext, ':')+1)); } @SHORT|$\* { shorten(filename, 1); } @ARGS:{NUM}+ { args(atoi(strrchr(yytext, ':')+1)); } @ARGS|$\+ { args(-1); } + @LINE { FORMAT("%d", line); } @STOP { CHAR('\n'); if (gpipe) { fprintf(stderr, "output: "); } if (!gselect) { return 0; } BEGIN INITIAL; } - @\{ { ++expunge_depth; } - \} {if (!expunge_depth--) { ECHO; } } + \\\n { CHAR('\n'); } + \\[@$] { ; } + @\{ { ++expunge_depth; } + \} { if (!expunge_depth--) { ECHO; } } + \n { ++line; if (first_nl) { first_nl = 0; BEGIN STOP; } } {SPACE}+ { CHAR(' '); } . { ECHO; } } -@BAKE{SPACE} { if (gselect < 0) { static int nth = 0; printf("%s:%d:s%d: ", filename, line, ++nth); BEGIN FOUND; } if (!--gselect) { BEGIN FOUND; } } -\n|\n { ++line; } -. { ; } + /* FIXME +1. fucked up line count when multiline + -2. dropping everything after @BAKE...\n */ +{ + @BAKE{SPACE} { + first_nl = 1; + if (gselect < 0) { printf("\n%s:%d s%d: ", filename, line, ++nth); } + BEGIN FOUND; + } + @STOP { yyless(-1); BEGIN FOUND; } + \n { yymore(); ++line; } + .|\\@ { yymore(); } +} %% void root(char * filename) { @@ -99,7 +123,7 @@ int main (int ac, char ** av) { for (i = 1; i < strlen(av[0]); ++i) { switch (av[0][i]) { opt_dry_run: case 'n': run = 0; break; - opt_select: case 's': gselect = atoi(av[0]+2+(av[0][2] == '=')); break; + opt_select: case 's': gselect = atoi(av[0]+2+(av[0][2] == '=')); i = strlen(av[0]); break; opt_list: case 'l': run = 0; gselect = -1; break; opt_help: case 'h': help(); return 0; opt_default: default: fprintf(stderr, "%s: Unknown option '%s'\n", av0, av[0]); return 1; From f493890ec8af0929274920c78f71829f84a84980 Mon Sep 17 00:00:00 2001 From: Emil Williams Date: Thu, 26 Sep 2024 22:14:37 +0000 Subject: [PATCH 4/8] intermediary 1 --- cbake.l | 68 ++++++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 40 insertions(+), 28 deletions(-) diff --git a/cbake.l b/cbake.l index b66524e..6be8db2 100644 --- a/cbake.l +++ b/cbake.l @@ -3,13 +3,12 @@ #include -#define backspace(fs) fputs("\x08", fs) #undef ECHO -#define ECHO do { fprintf(stdout, yytext); if (gpipe) { fprintf(gpipe, yytext); } } while (0) -#define CHAR(c) do { fputc(c, stdout); if (gpipe) { fputc(c, gpipe); } } while (0) -#define STRING(s) do { fputs(s, stdout); if (gpipe) { fputs(s, gpipe); } } while (0) +#define ECHO do { fprintf(stdout, yytext); if (gpipe) { fprintf(gpipe, yytext); } } while (0) +#define CHAR(c) do { fputc(c, stdout); if (gpipe) { fputc(c, gpipe); } } while (0) +#define STRING(s) do { fputs(s, stdout); if (gpipe) { fputs(s, gpipe); } } while (0) #define FORMAT(...) do { fprintf(stdout, __VA_ARGS__); if (gpipe) { fprintf(gpipe, __VA_ARGS__); } } while (0) -#define FWRITE(str, len) do { fwrite(str, 1, len, stdout); if (gpipe) { fwrite(str, 1, len, gpipe); } } while (0) +#define FWRITE(str, len) do { fwrite(str, 1, len, stdout); if (gpipe) { fwrite(str, 1, len, gpipe); } } while (0) FILE * gpipe; @@ -26,45 +25,35 @@ extern void args(int n); extern void shorten(char * filename, int n); %} -SPACE [[:space:]] +SPACE [ \t\r\v\f] NUM [[:digit:]] -%x FOUND STOP +%x FOUND STOP PADDING + +MACROS (@BAKE|@FILENAME|@FILE|@SHORT|@ARGS|@LINE|@STOP|$@|$*|$+) %option nodefault noinput noyywrap %% -@BAKE{SPACE} { - first_nl = 1; - if (gselect < 0) { - printf("%s:%d s%d: ", filename, line, ++nth); - BEGIN FOUND; - } - if (!--gselect) { BEGIN FOUND; } -} - -\n { ++line; } -. { ; } - { + /* New behavior */ + @BAKE { if (!gselect) { return 0; } yyless(yyleng - strlen("@BAKE")); BEGIN INITIAL; } @FILENAME|@FILE|$@ { STRING(filename); } @SHORT:{NUM}+ { shorten(filename, atoi(strrchr(yytext, ':')+1)); } @SHORT|$\* { shorten(filename, 1); } @ARGS:{NUM}+ { args(atoi(strrchr(yytext, ':')+1)); } @ARGS|$\+ { args(-1); } @LINE { FORMAT("%d", line); } - @STOP { CHAR('\n'); if (gpipe) { fprintf(stderr, "output: "); } if (!gselect) { return 0; } BEGIN INITIAL; } - \\\n { CHAR('\n'); } - \\[@$] { ; } + @STOP { CHAR('\n'); if (!gselect) { return 0; } BEGIN INITIAL; } + \\\n { ++line; CHAR(' '); BEGIN PADDING; } + \\{MACROS} { putchar(yytext[1]); } @\{ { ++expunge_depth; } \} { if (!expunge_depth--) { ECHO; } } \n { ++line; if (first_nl) { first_nl = 0; BEGIN STOP; } } - {SPACE}+ { CHAR(' '); } + {SPACE} { CHAR(' '); BEGIN PADDING; } . { ECHO; } } - /* FIXME +1. fucked up line count when multiline - -2. dropping everything after @BAKE...\n */ { @BAKE{SPACE} { first_nl = 1; @@ -75,6 +64,22 @@ NUM [[:digit:]] \n { yymore(); ++line; } .|\\@ { yymore(); } } + +{ + {SPACE} { ; } + .|\n { yyless(0); BEGIN FOUND; } +} + +@BAKE[[:space:]] { + first_nl = 1; + if (gselect < 0) { printf("%s:%d s%d: ", filename, line, ++nth); BEGIN FOUND; } + else if (gselect == 0) { BEGIN FOUND; } + else { --gselect; } +} + +\n { ++line; } +. { ; } + %% void root(char * filename) { @@ -134,6 +139,7 @@ int main (int ac, char ** av) { start: if (!ac) { fprintf(stderr, "%s: Missing filename\n", av0); return 1; } + if (gselect == 0) { fprintf(stderr, "%s: Out of range\n", av0); return 1; } /* filename and self placement */ filename = av[0]; @@ -152,11 +158,17 @@ int main (int ac, char ** av) { gpipe = popen("/bin/sh -e", "w"); if (!gpipe) { fprintf(stderr, "%s: %s\n", av0, strerror(errno)); return 1; } } + if (gselect > 0) { fprintf(stderr, "%s: ", av0); fflush(stderr); } yylex(); - if (gselect > 0) { fprintf(stderr, "%s: Out of range\n", av0); } + /* putchar('\n'); */ fclose(fp); + if (gselect > 0) { fprintf(stderr, "%s: Out of range\n", av0); } - if (run) { run = pclose(gpipe); if (run) { printf("%s: Exit code %d\n", av0, run); } return run; } - return 0; + if (!run) { return 0; } + fprintf(stderr, "output: "); fflush(stderr); + run = pclose(gpipe); + /* repurposed run */ + if (run) { printf("%s: Exit code %d\n", av0, run); } + return run; } From dc5b39058782e25ff4d141b822086fa642338f20 Mon Sep 17 00:00:00 2001 From: Emil Williams Date: Thu, 26 Sep 2024 22:14:56 +0000 Subject: [PATCH 5/8] intermediary 2 --- cbake.l | 159 +++++++++++++++++++++++----------------------------------------- 1 file changed, 56 insertions(+), 103 deletions(-) diff --git a/cbake.l b/cbake.l index 6be8db2..504ace3 100644 --- a/cbake.l +++ b/cbake.l @@ -1,87 +1,48 @@ /* cbake.l @BAKE flex @FILE && cc -std=c99 -D_GNU_SOURCE -o @{@SHORT} lex.yy.c @ARGS -lfl @STOP */ %{ - -#include - -#undef ECHO -#define ECHO do { fprintf(stdout, yytext); if (gpipe) { fprintf(gpipe, yytext); } } while (0) -#define CHAR(c) do { fputc(c, stdout); if (gpipe) { fputc(c, gpipe); } } while (0) -#define STRING(s) do { fputs(s, stdout); if (gpipe) { fputs(s, gpipe); } } while (0) -#define FORMAT(...) do { fprintf(stdout, __VA_ARGS__); if (gpipe) { fprintf(gpipe, __VA_ARGS__); } } while (0) -#define FWRITE(str, len) do { fwrite(str, 1, len, stdout); if (gpipe) { fwrite(str, 1, len, gpipe); } } while (0) - -FILE * gpipe; - char * filename; -int gac; -char ** gav; -/* Options */ -int gselect = 1; -/* accum */ - int line = 1, expunge_depth = 0, first_nl, nth = 0; +int gac; char ** gav; +int gmax = 0, line = 1, expunge_depth = 0; -extern void root(char * filename); extern void args(int n); extern void shorten(char * filename, int n); %} - -SPACE [ \t\r\v\f] -NUM [[:digit:]] - -%x FOUND STOP PADDING - -MACROS (@BAKE|@FILENAME|@FILE|@SHORT|@ARGS|@LINE|@STOP|$@|$*|$+) - +%x FOUND PADDING %option nodefault noinput noyywrap %% - { - /* New behavior */ - @BAKE { if (!gselect) { return 0; } yyless(yyleng - strlen("@BAKE")); BEGIN INITIAL; } - @FILENAME|@FILE|$@ { STRING(filename); } - @SHORT:{NUM}+ { shorten(filename, atoi(strrchr(yytext, ':')+1)); } - @SHORT|$\* { shorten(filename, 1); } - @ARGS:{NUM}+ { args(atoi(strrchr(yytext, ':')+1)); } - @ARGS|$\+ { args(-1); } - @LINE { FORMAT("%d", line); } - @STOP { CHAR('\n'); if (!gselect) { return 0; } BEGIN INITIAL; } - \\\n { ++line; CHAR(' '); BEGIN PADDING; } - \\{MACROS} { putchar(yytext[1]); } - @\{ { ++expunge_depth; } - \} { if (!expunge_depth--) { ECHO; } } - \n { ++line; if (first_nl) { first_nl = 0; BEGIN STOP; } } - {SPACE} { CHAR(' '); BEGIN PADDING; } - . { ECHO; } + @FILENAME|@FILE|$@ { printf(filename); } + @SHORT:[[:digit:]]+ { shorten(filename, atoi(strrchr(yytext, ':')+1)); } + @SHORT|$\* { shorten(filename, 1); } + @ARGS:[[:digit:]]+ { args(atoi(strrchr(yytext, ':')+1)); } + @ARGS|$\+ { args(-1); } + @LINE { printf("%d", line); } + @BAKE { yyless(yyleng - strlen("@BAKE")); BEGIN INITIAL; } + @STOP { printf("@STOP\n"); BEGIN INITIAL; } + \\[@$] { putchar(yytext[1]); } + \\\n { ++line; } + @\{ { ++expunge_depth; } + \} { if (!expunge_depth--) { ECHO; } } + \n { ++line; putchar(yytext[0]); } + [ \v\t\r\f] { putchar(' '); BEGIN PADDING; } + . { putchar(yytext[0]); } } - -{ - @BAKE{SPACE} { - first_nl = 1; - if (gselect < 0) { printf("\n%s:%d s%d: ", filename, line, ++nth); } - BEGIN FOUND; - } - @STOP { yyless(-1); BEGIN FOUND; } - \n { yymore(); ++line; } - .|\\@ { yymore(); } -} - { - {SPACE} { ; } - .|\n { yyless(0); BEGIN FOUND; } + [ \v\t\r\f] { ; } + .|\n { yyless(0); BEGIN FOUND; } } - -@BAKE[[:space:]] { - first_nl = 1; - if (gselect < 0) { printf("%s:%d s%d: ", filename, line, ++nth); BEGIN FOUND; } - else if (gselect == 0) { BEGIN FOUND; } - else { --gselect; } -} - -\n { ++line; } -. { ; } - +\\[^\n] { ; } +\\\n { ++line; } +@BAKE[ \t\r\v\f] { goto bake; } +@BAKE\n { ++line; bake: ++gmax; printf("@BAKE "); BEGIN FOUND; } +\n { ++line; } +. { ; } %% +#include + +void help(void) { puts("See bake(1) - \"Buy high. Sell low.\"\n"); } + void root(char * filename) { char * path, * terminator; if (!(path = realpath(filename, NULL))) { return; } @@ -93,26 +54,21 @@ void root(char * filename) { } void args(int n) { - if (n < 0) { for (int i = 0; i < gac; ++i) { STRING(gav[i]); if (i + 1 < gac) { CHAR(' '); } } } - else if (n < gac) { STRING(gav[n]); } + if (n < 0) { for (int i = 0; i < gac; ++i) { printf(gav[i]); if (i + 1 < gac) { putchar(' '); } } } + else if (n < gac) { printf(gav[n]); } } void shorten(char * filename, int n) { char * end = filename + strlen(filename); while (n && (end = memrchr(filename, '.', end - filename))) { --n; } - if (!end) { fprintf(stderr, " context error: Argument out of range.\n"); STRING("idiot"); return; } - FWRITE(filename, end - filename); + if (!end) { fprintf(stderr, " context error: Argument out of range.\n"); printf("idiot"); return; } + fwrite(filename, 1, end - filename, stdout); } -#define HELP \ - "bake(1) - \"Buy high. Sell low.\"\n" -void help(void) { puts(HELP); } - int main (int ac, char ** av) { - int run = 1; + int run = 1, select = 1, list = 0; char * av0 = av[0]; - FILE * fp, * op; - + FILE * fp; while (++av, --ac) { int i; if (av[0][0] != '-') { goto start; } @@ -128,47 +84,44 @@ int main (int ac, char ** av) { for (i = 1; i < strlen(av[0]); ++i) { switch (av[0][i]) { opt_dry_run: case 'n': run = 0; break; - opt_select: case 's': gselect = atoi(av[0]+2+(av[0][2] == '=')); i = strlen(av[0]); break; - opt_list: case 'l': run = 0; gselect = -1; break; + opt_select: case 's': select = atoi(av[0]+2+(av[0][2] == '=')); i = strlen(av[0]); break; + opt_list: case 'l': run = 0; select = -1; break; opt_help: case 'h': help(); return 0; opt_default: default: fprintf(stderr, "%s: Unknown option '%s'\n", av0, av[0]); return 1; opt_arg: fprintf(stderr, "%s: Argument missing for '%s'\n", av0, av[0]); return 1; } } } - - start: +start: if (!ac) { fprintf(stderr, "%s: Missing filename\n", av0); return 1; } - if (gselect == 0) { fprintf(stderr, "%s: Out of range\n", av0); return 1; } - /* filename and self placement */ + /* filename and renaming */ filename = av[0]; root(filename); { char * tmp = strrchr(filename, '/'); if (tmp) { filename = tmp+1; } } - /* open and prepare ac, av */ if (!(yyin = fp = fopen(filename, "rb"))) { fprintf(stderr, "%s: '%s' %s\n", av0, filename, strerror(errno)); return 1; } gac = --ac, gav = ++av; - - if (run) { - gpipe = popen("/bin/sh -e", "w"); - if (!gpipe) { fprintf(stderr, "%s: %s\n", av0, strerror(errno)); return 1; } + { + FILE * bp = fmemopen(buf, 1 << 16, "wb+"), * stdout_old = stdout; + stdout = bp; + yylex(); + stdout = stdout_old; + fclose(bp); + } + if (select > gmax) { fprintf(stderr, "%s: Out of range\n", av0); return 1; } + if (!list) { + fprintf(stderr, "%s: ", av0); fflush(stderr); + fwrite(buf,1,1000,stdout); + if (run) { + FILE * gpipe = popen("/bin/sh -e", "w"); + if (!gpipe) { fprintf(stderr, "%s: %s\n", av0, strerror(errno)); return 1; } + run = pclose(gpipe); if (run) { printf("%s: Exit code %d\n", av0, run); } return run; + } } - if (gselect > 0) { fprintf(stderr, "%s: ", av0); fflush(stderr); } - yylex(); - /* putchar('\n'); */ - fclose(fp); - if (gselect > 0) { fprintf(stderr, "%s: Out of range\n", av0); } - - if (!run) { return 0; } - fprintf(stderr, "output: "); fflush(stderr); - run = pclose(gpipe); - /* repurposed run */ - if (run) { printf("%s: Exit code %d\n", av0, run); } - return run; } From 688db98864665ff35c4bdbd567aa239246af358c Mon Sep 17 00:00:00 2001 From: Emil Williams Date: Thu, 26 Sep 2024 22:16:01 +0000 Subject: [PATCH 6/8] newlines --- cbake.l | 133 ++++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 79 insertions(+), 54 deletions(-) diff --git a/cbake.l b/cbake.l index 504ace3..6796588 100644 --- a/cbake.l +++ b/cbake.l @@ -1,48 +1,69 @@ -/* cbake.l @BAKE flex @FILE && cc -std=c99 -D_GNU_SOURCE -o @{@SHORT} lex.yy.c @ARGS -lfl @STOP */ +/* cbake.l @BAKE flex @FILE && cc -Wall -Wextra -std=c99 -D_GNU_SOURCE -o @{@SHORT} lex.yy.c @ARGS -lfl @STOP */ +/* TODO: implement expunge */ %{ -char * filename; -int gac; char ** gav; -int gmax = 0, line = 1, expunge_depth = 0; +#include +#undef ECHO +#define ECHO do { fprintf(stdout, yytext); if (gpipe) { fprintf(gpipe, yytext); } } while (0) +#define CHAR(c) do { fputc(c, stdout); if (gpipe) { fputc(c, gpipe); } } while (0) +#define STRING(s) do { fputs(s, stdout); if (gpipe) { fputs(s, gpipe); } } while (0) +#define FORMAT(...) do { fprintf(stdout, __VA_ARGS__); if (gpipe) { fprintf(gpipe, __VA_ARGS__); } } while (0) +#define FWRITE(str, len) do { fwrite(str, 1, len, stdout); if (gpipe) { fwrite(str, 1, len, gpipe); } } while (0) + +FILE * gpipe; +char * filename; +int gac; +char ** gav; +int gselect = 1, line = 1, first_nl, expunge_depth = 0; +int nth = 0, tmpline; + +extern void root(char * filename); extern void args(int n); extern void shorten(char * filename, int n); %} -%x FOUND PADDING -%option nodefault noinput noyywrap + +SPACE [ \t\r\v\f] +MACROS (@BAKE|@FILENAME|@FILE|@SHORT|@ARGS|@LINE|@STOP|$@|$*|$+) + +%x FOUND PADDING STOP +%option nodefault noinput nounput noyywrap %% +@BAKE[[:space:]] { bake: + first_nl = 1; + if (yytext[yyleng-1] == '\n') { ++line; } + if (gselect < 0) { printf("\n%s:%d:s%d: ", filename, line, ++nth); BEGIN FOUND; } + else if (!--gselect) { BEGIN FOUND; } +} +\n { ++line; } +. {;} { - @FILENAME|@FILE|$@ { printf(filename); } + @BAKE|@STOP { BEGIN INITIAL; yyless(0); if (first_nl) { putchar('\n'); } if (!gselect) { return 0; } } + @FILENAME|@FILE|$@ { STRING(filename); } @SHORT:[[:digit:]]+ { shorten(filename, atoi(strrchr(yytext, ':')+1)); } @SHORT|$\* { shorten(filename, 1); } @ARGS:[[:digit:]]+ { args(atoi(strrchr(yytext, ':')+1)); } @ARGS|$\+ { args(-1); } - @LINE { printf("%d", line); } - @BAKE { yyless(yyleng - strlen("@BAKE")); BEGIN INITIAL; } - @STOP { printf("@STOP\n"); BEGIN INITIAL; } - \\[@$] { putchar(yytext[1]); } - \\\n { ++line; } + @LINE { FORMAT("%d", line); } @\{ { ++expunge_depth; } \} { if (!expunge_depth--) { ECHO; } } - \n { ++line; putchar(yytext[0]); } - [ \v\t\r\f] { putchar(' '); BEGIN PADDING; } - . { putchar(yytext[0]); } + \\\n { ++line; CHAR(' '); BEGIN PADDING; } + \\{MACROS} { STRING(yytext + 1); } + \n { putchar('\n'); ++line; if (first_nl) { first_nl = 0; tmpline = 0; BEGIN STOP; } } + {SPACE} { BEGIN PADDING; CHAR(' '); } + . { ECHO; } } { - [ \v\t\r\f] { ; } - .|\n { yyless(0); BEGIN FOUND; } + {SPACE} { ; } + .|\n { yyless(0); BEGIN FOUND; } +} +{ + @BAKE[[:space:]] { line += tmpline; goto bake; } + @STOP { yyless(0); BEGIN FOUND; } + \n { ++tmpline; yymore(); } + .|\\@ { yymore(); } } -\\[^\n] { ; } -\\\n { ++line; } -@BAKE[ \t\r\v\f] { goto bake; } -@BAKE\n { ++line; bake: ++gmax; printf("@BAKE "); BEGIN FOUND; } -\n { ++line; } -. { ; } %% -#include - -void help(void) { puts("See bake(1) - \"Buy high. Sell low.\"\n"); } - void root(char * filename) { char * path, * terminator; if (!(path = realpath(filename, NULL))) { return; } @@ -54,23 +75,26 @@ void root(char * filename) { } void args(int n) { - if (n < 0) { for (int i = 0; i < gac; ++i) { printf(gav[i]); if (i + 1 < gac) { putchar(' '); } } } - else if (n < gac) { printf(gav[n]); } + if (n < 0) { for (int i = 0; i < gac; ++i) { STRING(gav[i]); if (i + 1 < gac) { CHAR(' '); } } } + else if (n < gac) { STRING(gav[n]); } } void shorten(char * filename, int n) { char * end = filename + strlen(filename); while (n && (end = memrchr(filename, '.', end - filename))) { --n; } - if (!end) { fprintf(stderr, " context error: Argument out of range.\n"); printf("idiot"); return; } - fwrite(filename, 1, end - filename, stdout); + if (!end) { fprintf(stderr, " context error: Argument out of range.\n"); STRING("idiot"); return; } + FWRITE(filename, end - filename); } +void help(void) { puts("bake(1) - \"Buy high. Sell low.\"\n"); } + int main (int ac, char ** av) { - int run = 1, select = 1, list = 0; + int run = 1; char * av0 = av[0]; FILE * fp; + while (++av, --ac) { - int i; + size_t i; if (av[0][0] != '-') { goto start; } if (av[0][1] == '-') { if (av[0][2] == '\0') { ++av, --ac; goto start; } @@ -84,44 +108,45 @@ int main (int ac, char ** av) { for (i = 1; i < strlen(av[0]); ++i) { switch (av[0][i]) { opt_dry_run: case 'n': run = 0; break; - opt_select: case 's': select = atoi(av[0]+2+(av[0][2] == '=')); i = strlen(av[0]); break; - opt_list: case 'l': run = 0; select = -1; break; + opt_select: case 's': gselect = atoi(av[0]+i+1+(av[0][i+1] == '=')); i = strlen(av[0]); break; + opt_list: case 'l': run = 0; gselect = -1; break; opt_help: case 'h': help(); return 0; opt_default: default: fprintf(stderr, "%s: Unknown option '%s'\n", av0, av[0]); return 1; opt_arg: fprintf(stderr, "%s: Argument missing for '%s'\n", av0, av[0]); return 1; } } } -start: - if (!ac) { fprintf(stderr, "%s: Missing filename\n", av0); return 1; } - /* filename and renaming */ + start: + if (!ac) { fprintf(stderr, "%s: Missing filename\n", av0); return 1; } + if (!gselect) { fprintf(stderr, "%s: Out of range\n", av0); return 1; } + + /* filename and self placement */ filename = av[0]; root(filename); { char * tmp = strrchr(filename, '/'); if (tmp) { filename = tmp+1; } } + /* open and prepare ac, av */ if (!(yyin = fp = fopen(filename, "rb"))) { fprintf(stderr, "%s: '%s' %s\n", av0, filename, strerror(errno)); return 1; } gac = --ac, gav = ++av; - { - FILE * bp = fmemopen(buf, 1 << 16, "wb+"), * stdout_old = stdout; - stdout = bp; - yylex(); - stdout = stdout_old; - fclose(bp); - } - if (select > gmax) { fprintf(stderr, "%s: Out of range\n", av0); return 1; } - if (!list) { - fprintf(stderr, "%s: ", av0); fflush(stderr); - fwrite(buf,1,1000,stdout); - if (run) { - FILE * gpipe = popen("/bin/sh -e", "w"); - if (!gpipe) { fprintf(stderr, "%s: %s\n", av0, strerror(errno)); return 1; } - run = pclose(gpipe); if (run) { printf("%s: Exit code %d\n", av0, run); } return run; - } + + if (run) { + gpipe = popen("/bin/sh -e", "w"); + if (!gpipe) { fprintf(stderr, "%s: %s\n", av0, strerror(errno)); return 1; } } + if (gselect > 0) { fprintf(stderr, "%s: ", av0); fflush(stderr); } + yylex(); fflush(stdout); + fclose(fp); + if (gselect > 0) { fprintf(stderr, "%s: Out of range\n", av0); } + + if (!run) { return 0; } + fprintf(stderr, "output: "); fflush(stderr); + run = pclose(gpipe); /* repurposed run */ + if (run) { printf("%s: Exit code %d\n", av0, run); } + return run; } From db865b407ec2cdd42c7c87e1a27a0ff585c8f920 Mon Sep 17 00:00:00 2001 From: Emil Williams Date: Thu, 26 Sep 2024 22:20:29 +0000 Subject: [PATCH 7/8] appease warnings & TDD gods --- cbake.l | 2 +- test.a.txt | Bin 0 -> 989 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 test.a.txt diff --git a/cbake.l b/cbake.l index 6796588..7f09126 100644 --- a/cbake.l +++ b/cbake.l @@ -67,7 +67,7 @@ MACROS (@BAKE|@FILENAME|@FILE|@SHORT|@ARGS|@LINE|@STOP|$@|$*|$+) void root(char * filename) { char * path, * terminator; if (!(path = realpath(filename, NULL))) { return; } - if (terminator = strrchr(path, '/')) { + if ((terminator = strrchr(path, '/'))) { *terminator = '\0'; chroot(path); } diff --git a/test.a.txt b/test.a.txt new file mode 100644 index 0000000000000000000000000000000000000000..ca2ff7fd0e9fcb2e11fa46ca29db1d391949ffdc GIT binary patch literal 989 zcmZ`&(N4lJ6!p1ZaUzMnz#=H3Bi^*QfxWM9QaV;AD-fmszR^yg*-R-%j zxA&ZecehU?M)6vr3ms0z&m)vi3woWXAPCr;e-JvVhwy$paqBIpwam0zJS`VF=7`b4 zRw|yYph;DbGcP|)1T_GC53t##I>}LOzm#(iskS^$#0p1PCYjP0O(zZJfsdzHibVx$ zL+nx{B2IS;TDT)!cu7$d30&dWy!B&UdN4uXw&ra{p8=LKL(xFK)MTe_gYHQ^we>Ho z+k}m#_qKp=_BMTCEX*}Tp<&Ny7=^RP>Fe9jq`HX<85wP;hfc@LeU8&#j@#FV+0YbO zej__E1Vx~SGGI0-0{LbI+e~fVoTJahDg{C(5V$l9(PYxP)P_FV!hKd`@5 z=cYY($V&ctZw79a3#r#eiV7tpglr=to~HYNv4cjz7cOs48h$P!W^M>JG9x>1W2^kn z(A0FfbR3GlDC21%wSpAJ*aXE*yYhD2pq69YQC`S*Qcb#Ubyrhfce`!aVQ!Gl^&$HK DTw)T) literal 0 HcmV?d00001 From 2af003b2d11cde17349790eafe9ca7a9ec27c92f Mon Sep 17 00:00:00 2001 From: Emil Williams Date: Fri, 27 Sep 2024 02:35:33 +0000 Subject: [PATCH 8/8] cleanup --- cbake.l | 146 +++++++++++++++++++++++++++++++++++-------------------------- test.a.txt | Bin 989 -> 784 bytes 2 files changed, 85 insertions(+), 61 deletions(-) diff --git a/cbake.l b/cbake.l index 7f09126..de64084 100644 --- a/cbake.l +++ b/cbake.l @@ -1,21 +1,23 @@ /* cbake.l @BAKE flex @FILE && cc -Wall -Wextra -std=c99 -D_GNU_SOURCE -o @{@SHORT} lex.yy.c @ARGS -lfl @STOP */ -/* TODO: implement expunge */ +/* TODO: implement expunge, color */ %{ #include #undef ECHO -#define ECHO do { fprintf(stdout, yytext); if (gpipe) { fprintf(gpipe, yytext); } } while (0) -#define CHAR(c) do { fputc(c, stdout); if (gpipe) { fputc(c, gpipe); } } while (0) -#define STRING(s) do { fputs(s, stdout); if (gpipe) { fputs(s, gpipe); } } while (0) -#define FORMAT(...) do { fprintf(stdout, __VA_ARGS__); if (gpipe) { fprintf(gpipe, __VA_ARGS__); } } while (0) -#define FWRITE(str, len) do { fwrite(str, 1, len, stdout); if (gpipe) { fwrite(str, 1, len, gpipe); } } while (0) +#define ECHO do { fprintf(stdout, yytext); if (g_pipe) { fprintf(g_pipe, yytext); } } while (0) +#define CHAR(c) do { fputc(c, stdout); if (g_pipe) { fputc(c, g_pipe); } } while (0) +#define STRING(s) do { fputs(s, stdout); if (g_pipe) { fputs(s, g_pipe); } } while (0) +#define FORMAT(...) do { fprintf(stdout, __VA_ARGS__); if (g_pipe) { fprintf(g_pipe, __VA_ARGS__); } } while (0) +#define FWRITE(str, len) do { fwrite(str, 1, len, stdout); if (g_pipe) { fwrite(str, 1, len, g_pipe); } } while (0) -FILE * gpipe; -char * filename; -int gac; -char ** gav; -int gselect = 1, line = 1, first_nl, expunge_depth = 0; -int nth = 0, tmpline; +/* input from main to lexer */ +FILE * g_pipe; +char * g_filename; +int g_ac; +char ** g_av; +int g_select = 1; +/* for the lexers eyes only */ +int line = 1, nth = 0, expunge_depth = 0, first_nl, tmpline; extern void root(char * filename); extern void args(int n); @@ -28,40 +30,48 @@ MACROS (@BAKE|@FILENAME|@FILE|@SHORT|@ARGS|@LINE|@STOP|$@|$*|$+) %x FOUND PADDING STOP %option nodefault noinput nounput noyywrap %% + @BAKE[[:space:]] { bake: first_nl = 1; + if (yytext[yyleng-1] == '\n') { ++line; } - if (gselect < 0) { printf("\n%s:%d:s%d: ", filename, line, ++nth); BEGIN FOUND; } - else if (!--gselect) { BEGIN FOUND; } + if (!g_select) { ; } + else if (g_select < 0) { BEGIN FOUND; printf("\n%s:%d:s%d: ", g_filename, line, ++nth); } + else if (!--g_select) { BEGIN FOUND; } } + \n { ++line; } . {;} + { - @BAKE|@STOP { BEGIN INITIAL; yyless(0); if (first_nl) { putchar('\n'); } if (!gselect) { return 0; } } - @FILENAME|@FILE|$@ { STRING(filename); } - @SHORT:[[:digit:]]+ { shorten(filename, atoi(strrchr(yytext, ':')+1)); } - @SHORT|$\* { shorten(filename, 1); } - @ARGS:[[:digit:]]+ { args(atoi(strrchr(yytext, ':')+1)); } - @ARGS|$\+ { args(-1); } - @LINE { FORMAT("%d", line); } - @\{ { ++expunge_depth; } - \} { if (!expunge_depth--) { ECHO; } } - \\\n { ++line; CHAR(' '); BEGIN PADDING; } - \\{MACROS} { STRING(yytext + 1); } - \n { putchar('\n'); ++line; if (first_nl) { first_nl = 0; tmpline = 0; BEGIN STOP; } } - {SPACE} { BEGIN PADDING; CHAR(' '); } - . { ECHO; } + @BAKE[[:space:]]|@STOP { BEGIN INITIAL; yyless(0); if (first_nl) { CHAR('\n'); } if (!g_select) { return 0; } } + @FILENAME|@FILE|$@ { STRING(g_filename); } + @SHORT:[[:digit:]]+ { shorten(g_filename, atoi(strrchr(yytext, ':')+1)); } + @SHORT|$\* { shorten(g_filename, 1); } + @ARGS:[[:digit:]]+ { args(atoi(strrchr(yytext, ':')+1)); } + @ARGS|$\+ { args(-1); } + @LINE { FORMAT("%d", line); } + @\{ { ++expunge_depth; } + \} { if (!expunge_depth--) { ECHO; } } + \\\n { BEGIN PADDING; ++line; CHAR(' '); } + \\{MACROS} { STRING(yytext + 1); } + \n { CHAR('\n'); ++line; if (first_nl) { BEGIN STOP; first_nl = 0; tmpline = 0; } } + {SPACE} { BEGIN PADDING; CHAR(' '); } + . { ECHO; } } + { - {SPACE} { ; } + {SPACE} { ; } .|\n { yyless(0); BEGIN FOUND; } } + { @BAKE[[:space:]] { line += tmpline; goto bake; } - @STOP { yyless(0); BEGIN FOUND; } - \n { ++tmpline; yymore(); } - .|\\@ { yymore(); } + @STOP { BEGIN FOUND; yyless(0); } + \n { ++tmpline; yymore(); } + .|\\@ { yymore(); } } + %% void root(char * filename) { @@ -75,78 +85,92 @@ void root(char * filename) { } void args(int n) { - if (n < 0) { for (int i = 0; i < gac; ++i) { STRING(gav[i]); if (i + 1 < gac) { CHAR(' '); } } } - else if (n < gac) { STRING(gav[n]); } + if (n < 0) { for (int i = 0; i < g_ac; ++i) { STRING(g_av[i]); if (i + 1 < g_ac) { CHAR(' '); } } } + else if (n < g_ac) { STRING(g_av[n]); } } void shorten(char * filename, int n) { char * end = filename + strlen(filename); while (n && (end = memrchr(filename, '.', end - filename))) { --n; } - if (!end) { fprintf(stderr, " context error: Argument out of range.\n"); STRING("idiot"); return; } + if (!end) { + fprintf(stderr, " context error: Argument out of range.\n"); + /* Ensures consistency. @SHORT will always return *something* that isn't filename */ + STRING("idiot"); + return; + } FWRITE(filename, end - filename); } -void help(void) { puts("bake(1) - \"Buy high. Sell low.\"\n"); } +void help(void) { fputs("see bake(1) - \"Buy high. Sell low.\"\n", stderr); } int main (int ac, char ** av) { int run = 1; char * av0 = av[0]; FILE * fp; + /* supports long/short, -allinone, (-X ... -X=... -X) */ while (++av, --ac) { size_t i; if (av[0][0] != '-') { goto start; } if (av[0][1] == '-') { - if (av[0][2] == '\0') { ++av, --ac; goto start; } - if (!strcmp(av[0]+2, "dry-run")) { i = strlen(av[0]); goto opt_dry_run; } - if (!strcmp(av[0]+2, "select" )) { if (!ac-1 || isdigit(av[1][0])) { goto opt_arg; } ++av, --ac; - i = strlen(av[0]); goto opt_select; } - if (!strcmp(av[0]+2, "list" )) { i = strlen(av[0]); goto opt_list; } - if (!strcmp(av[0]+2, "help" )) { goto opt_help; } + if (av[0][2] == '\0') { ++av, --ac; goto start; } + if (!strcmp(av[0]+2, "dry-run")) { i = strlen(av[0]); goto opt_dry_run; } + if (!strcmp(av[0]+2, "select" )) { if (!ac-1 || isdigit(av[1][0])) { goto opt_arg; } + ++av, --ac; i = strlen(av[0]); goto opt_select; } + if (!strcmp(av[0]+2, "list" )) { i = strlen(av[0]); goto opt_list; } + if (!strcmp(av[0]+2, "help" )) { goto opt_help; } goto opt_default; } for (i = 1; i < strlen(av[0]); ++i) { switch (av[0][i]) { opt_dry_run: case 'n': run = 0; break; - opt_select: case 's': gselect = atoi(av[0]+i+1+(av[0][i+1] == '=')); i = strlen(av[0]); break; - opt_list: case 'l': run = 0; gselect = -1; break; + case 's': + /* Covers cases -s -s */ + if (isdigit(av[0][i+1])) { g_select = atoi(av[0]+i+1); } + else if (ac > 1 && isdigit(av[1][0])) { ++av, --ac; opt_select: g_select = atoi(av[0]); } + else { g_select = 0; } + if (!g_select) { fprintf(stderr, "%s: Invalid argument for -s\n", av0); return 1; } + i = strlen(av[0]); + break; + opt_list: case 'l': run = 0; g_select = -1; break; opt_help: case 'h': help(); return 0; - opt_default: default: fprintf(stderr, "%s: Unknown option '%s'\n", av0, av[0]); return 1; - opt_arg: fprintf(stderr, "%s: Argument missing for '%s'\n", av0, av[0]); return 1; + opt_default: default: fprintf(stderr, "%s: Unknown option '%s'\n", av0, av[0]); return 1; + opt_arg: fprintf(stderr, "%s: Argument missing for '%s'\n", av0, av[0]); return 1; } } } start: if (!ac) { fprintf(stderr, "%s: Missing filename\n", av0); return 1; } - if (!gselect) { fprintf(stderr, "%s: Out of range\n", av0); return 1; } + if (!g_select) { goto out_of_range; } - /* filename and self placement */ - filename = av[0]; - root(filename); - { - char * tmp = strrchr(filename, '/'); - if (tmp) { filename = tmp+1; } + g_filename = av[0]; + root(g_filename); + { /* ensures the filename doesn't have a relative path that would misdirect the command within the new root */ + char * tmp = strrchr(g_filename, '/'); + if (tmp) { g_filename = tmp+1; } } /* open and prepare ac, av */ - if (!(yyin = fp = fopen(filename, "rb"))) - { fprintf(stderr, "%s: '%s' %s\n", av0, filename, strerror(errno)); return 1; } - gac = --ac, gav = ++av; + if (!(yyin = fp = fopen(g_filename, "rb"))) + { fprintf(stderr, "%s: '%s' %s\n", av0, g_filename, strerror(errno)); return 1; } + g_ac = --ac, g_av = ++av; + /* Prepares our UNIX pipe for input */ if (run) { - gpipe = popen("/bin/sh -e", "w"); - if (!gpipe) { fprintf(stderr, "%s: %s\n", av0, strerror(errno)); return 1; } + g_pipe = popen("/bin/sh -e", "w"); + if (!g_pipe) { fprintf(stderr, "%s: %s\n", av0, strerror(errno)); return 1; } } - if (gselect > 0) { fprintf(stderr, "%s: ", av0); fflush(stderr); } + if (g_select > 0) { fprintf(stderr, "%s: ", av0); fflush(stderr); } yylex(); fflush(stdout); fclose(fp); - if (gselect > 0) { fprintf(stderr, "%s: Out of range\n", av0); } + if (g_select > 0) { pclose(g_pipe); goto out_of_range; } if (!run) { return 0; } fprintf(stderr, "output: "); fflush(stderr); - run = pclose(gpipe); /* repurposed run */ + run = pclose(g_pipe); /* repurposed run */ if (run) { printf("%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; } diff --git a/test.a.txt b/test.a.txt index ca2ff7fd0e9fcb2e11fa46ca29db1d391949ffdc..ee1f9eaadebc4899c4a9371548a8cc08a7456efe 100644 GIT binary patch delta 269 zcmcc1K7p;?!O79vl`AzlBcDr8KRGEeJ5@oq*hrxywYWqtQLm(;1WDK!yRZp%VN>kF vW+=k-a68RW#Nomg*o7^z3mY2X5H~~?cL)yg58&bgd42K;MzhU~Om`Ro@cUH1 literal 989 zcmZ`&(N4lJ6!p1ZaUzMnz#=H3Bi^*QfxWM9QaV;AD-fmszR^yg*-R-%j zxA&ZecehU?M)6vr3ms0z&m)vi3woWXAPCr;e-JvVhwy$paqBIpwam0zJS`VF=7`b4 zRw|yYph;DbGcP|)1T_GC53t##I>}LOzm#(iskS^$#0p1PCYjP0O(zZJfsdzHibVx$ zL+nx{B2IS;TDT)!cu7$d30&dWy!B&UdN4uXw&ra{p8=LKL(xFK)MTe_gYHQ^we>Ho z+k}m#_qKp=_BMTCEX*}Tp<&Ny7=^RP>Fe9jq`HX<85wP;hfc@LeU8&#j@#FV+0YbO zej__E1Vx~SGGI0-0{LbI+e~fVoTJahDg{C(5V$l9(PYxP)P_FV!hKd`@5 z=cYY($V&ctZw79a3#r#eiV7tpglr=to~HYNv4cjz7cOs48h$P!W^M>JG9x>1W2^kn z(A0FfbR3GlDC21%wSpAJ*aXE*yYhD2pq69YQC`S*Qcb#Ubyrhfce`!aVQ!Gl^&$HK DTw)T)