cleanup
This commit is contained in:
parent
db865b407e
commit
2af003b2d1
112
cbake.l
112
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 */
|
/* 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 <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
#undef ECHO
|
#undef ECHO
|
||||||
#define ECHO do { fprintf(stdout, yytext); if (gpipe) { fprintf(gpipe, yytext); } } 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 (gpipe) { fputc(c, gpipe); } } 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 (gpipe) { fputs(s, gpipe); } } 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 (gpipe) { fprintf(gpipe, __VA_ARGS__); } } 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 (gpipe) { fwrite(str, 1, len, gpipe); } } 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;
|
/* input from main to lexer */
|
||||||
char * filename;
|
FILE * g_pipe;
|
||||||
int gac;
|
char * g_filename;
|
||||||
char ** gav;
|
int g_ac;
|
||||||
int gselect = 1, line = 1, first_nl, expunge_depth = 0;
|
char ** g_av;
|
||||||
int nth = 0, tmpline;
|
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 root(char * filename);
|
||||||
extern void args(int n);
|
extern void args(int n);
|
||||||
@ -28,40 +30,48 @@ MACROS (@BAKE|@FILENAME|@FILE|@SHORT|@ARGS|@LINE|@STOP|$@|$*|$+)
|
|||||||
%x FOUND PADDING STOP
|
%x FOUND PADDING STOP
|
||||||
%option nodefault noinput nounput noyywrap
|
%option nodefault noinput nounput noyywrap
|
||||||
%%
|
%%
|
||||||
|
|
||||||
@BAKE[[:space:]] { bake:
|
@BAKE[[:space:]] { bake:
|
||||||
first_nl = 1;
|
first_nl = 1;
|
||||||
|
|
||||||
if (yytext[yyleng-1] == '\n') { ++line; }
|
if (yytext[yyleng-1] == '\n') { ++line; }
|
||||||
if (gselect < 0) { printf("\n%s:%d:s%d: ", filename, line, ++nth); BEGIN FOUND; }
|
if (!g_select) { ; }
|
||||||
else if (!--gselect) { BEGIN FOUND; }
|
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; }
|
\n { ++line; }
|
||||||
. {;}
|
. {;}
|
||||||
|
|
||||||
<FOUND>{
|
<FOUND>{
|
||||||
@BAKE|@STOP { BEGIN INITIAL; yyless(0); if (first_nl) { putchar('\n'); } if (!gselect) { return 0; } }
|
@BAKE[[:space:]]|@STOP { BEGIN INITIAL; yyless(0); if (first_nl) { CHAR('\n'); } if (!g_select) { return 0; } }
|
||||||
@FILENAME|@FILE|$@ { STRING(filename); }
|
@FILENAME|@FILE|$@ { STRING(g_filename); }
|
||||||
@SHORT:[[:digit:]]+ { shorten(filename, atoi(strrchr(yytext, ':')+1)); }
|
@SHORT:[[:digit:]]+ { shorten(g_filename, atoi(strrchr(yytext, ':')+1)); }
|
||||||
@SHORT|$\* { shorten(filename, 1); }
|
@SHORT|$\* { shorten(g_filename, 1); }
|
||||||
@ARGS:[[:digit:]]+ { args(atoi(strrchr(yytext, ':')+1)); }
|
@ARGS:[[:digit:]]+ { args(atoi(strrchr(yytext, ':')+1)); }
|
||||||
@ARGS|$\+ { args(-1); }
|
@ARGS|$\+ { args(-1); }
|
||||||
@LINE { FORMAT("%d", line); }
|
@LINE { FORMAT("%d", line); }
|
||||||
@\{ { ++expunge_depth; }
|
@\{ { ++expunge_depth; }
|
||||||
\} { if (!expunge_depth--) { ECHO; } }
|
\} { if (!expunge_depth--) { ECHO; } }
|
||||||
\\\n { ++line; CHAR(' '); BEGIN PADDING; }
|
\\\n { BEGIN PADDING; ++line; CHAR(' '); }
|
||||||
\\{MACROS} { STRING(yytext + 1); }
|
\\{MACROS} { STRING(yytext + 1); }
|
||||||
\n { putchar('\n'); ++line; if (first_nl) { first_nl = 0; tmpline = 0; BEGIN STOP; } }
|
\n { CHAR('\n'); ++line; if (first_nl) { BEGIN STOP; first_nl = 0; tmpline = 0; } }
|
||||||
{SPACE} { BEGIN PADDING; CHAR(' '); }
|
{SPACE} { BEGIN PADDING; CHAR(' '); }
|
||||||
. { ECHO; }
|
. { ECHO; }
|
||||||
}
|
}
|
||||||
|
|
||||||
<PADDING>{
|
<PADDING>{
|
||||||
{SPACE} { ; }
|
{SPACE} { ; }
|
||||||
.|\n { yyless(0); BEGIN FOUND; }
|
.|\n { yyless(0); BEGIN FOUND; }
|
||||||
}
|
}
|
||||||
|
|
||||||
<STOP>{
|
<STOP>{
|
||||||
@BAKE[[:space:]] { line += tmpline; goto bake; }
|
@BAKE[[:space:]] { line += tmpline; goto bake; }
|
||||||
@STOP { yyless(0); BEGIN FOUND; }
|
@STOP { BEGIN FOUND; yyless(0); }
|
||||||
\n { ++tmpline; yymore(); }
|
\n { ++tmpline; yymore(); }
|
||||||
.|\\@ { yymore(); }
|
.|\\@ { yymore(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
void root(char * filename) {
|
void root(char * filename) {
|
||||||
@ -75,32 +85,38 @@ void root(char * filename) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void args(int n) {
|
void args(int n) {
|
||||||
if (n < 0) { for (int i = 0; i < gac; ++i) { STRING(gav[i]); if (i + 1 < gac) { CHAR(' '); } } }
|
if (n < 0) { for (int i = 0; i < g_ac; ++i) { STRING(g_av[i]); if (i + 1 < g_ac) { CHAR(' '); } } }
|
||||||
else if (n < gac) { STRING(gav[n]); }
|
else if (n < g_ac) { STRING(g_av[n]); }
|
||||||
}
|
}
|
||||||
|
|
||||||
void shorten(char * filename, int n) {
|
void shorten(char * filename, int n) {
|
||||||
char * end = filename + strlen(filename);
|
char * end = filename + strlen(filename);
|
||||||
while (n && (end = memrchr(filename, '.', end - filename))) { --n; }
|
while (n && (end = memrchr(filename, '.', end - filename))) { --n; }
|
||||||
if (!end) { fprintf(stderr, "<SHORTEN> context error: Argument out of range.\n"); STRING("idiot"); return; }
|
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;
|
||||||
|
}
|
||||||
FWRITE(filename, end - filename);
|
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 main (int ac, char ** av) {
|
||||||
int run = 1;
|
int run = 1;
|
||||||
char * av0 = av[0];
|
char * av0 = av[0];
|
||||||
FILE * fp;
|
FILE * fp;
|
||||||
|
|
||||||
|
/* supports long/short, -allinone, (-X ... -X=... -X<NUM>) */
|
||||||
while (++av, --ac) {
|
while (++av, --ac) {
|
||||||
size_t i;
|
size_t i;
|
||||||
if (av[0][0] != '-') { goto start; }
|
if (av[0][0] != '-') { goto start; }
|
||||||
if (av[0][1] == '-') {
|
if (av[0][1] == '-') {
|
||||||
if (av[0][2] == '\0') { ++av, --ac; goto start; }
|
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, "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;
|
if (!strcmp(av[0]+2, "select" )) { if (!ac-1 || isdigit(av[1][0])) { goto opt_arg; }
|
||||||
i = strlen(av[0]); goto opt_select; }
|
++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, "list" )) { i = strlen(av[0]); goto opt_list; }
|
||||||
if (!strcmp(av[0]+2, "help" )) { goto opt_help; }
|
if (!strcmp(av[0]+2, "help" )) { goto opt_help; }
|
||||||
goto opt_default;
|
goto opt_default;
|
||||||
@ -108,8 +124,15 @@ int main (int ac, char ** av) {
|
|||||||
for (i = 1; i < strlen(av[0]); ++i) {
|
for (i = 1; i < strlen(av[0]); ++i) {
|
||||||
switch (av[0][i]) {
|
switch (av[0][i]) {
|
||||||
opt_dry_run: case 'n': run = 0; break;
|
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;
|
case 's':
|
||||||
opt_list: case 'l': run = 0; gselect = -1; break;
|
/* Covers cases -<LAST>s<NUM> -<LAST>s <NUM> */
|
||||||
|
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_help: case 'h': help(); return 0;
|
||||||
opt_default: default: fprintf(stderr, "%s: Unknown option '%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;
|
opt_arg: fprintf(stderr, "%s: Argument missing for '%s'\n", av0, av[0]); return 1;
|
||||||
@ -119,34 +142,35 @@ int main (int ac, char ** av) {
|
|||||||
|
|
||||||
start:
|
start:
|
||||||
if (!ac) { fprintf(stderr, "%s: Missing filename\n", av0); return 1; }
|
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 */
|
g_filename = av[0];
|
||||||
filename = av[0];
|
root(g_filename);
|
||||||
root(filename);
|
{ /* ensures the filename doesn't have a relative path that would misdirect the command within the new root */
|
||||||
{
|
char * tmp = strrchr(g_filename, '/');
|
||||||
char * tmp = strrchr(filename, '/');
|
if (tmp) { g_filename = tmp+1; }
|
||||||
if (tmp) { filename = tmp+1; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* open and prepare ac, av */
|
/* open and prepare ac, av */
|
||||||
if (!(yyin = fp = fopen(filename, "rb")))
|
if (!(yyin = fp = fopen(g_filename, "rb")))
|
||||||
{ fprintf(stderr, "%s: '%s' %s\n", av0, filename, strerror(errno)); return 1; }
|
{ fprintf(stderr, "%s: '%s' %s\n", av0, g_filename, strerror(errno)); return 1; }
|
||||||
gac = --ac, gav = ++av;
|
g_ac = --ac, g_av = ++av;
|
||||||
|
|
||||||
|
/* Prepares our UNIX pipe for input */
|
||||||
if (run) {
|
if (run) {
|
||||||
gpipe = popen("/bin/sh -e", "w");
|
g_pipe = popen("/bin/sh -e", "w");
|
||||||
if (!gpipe) { fprintf(stderr, "%s: <gpipe> %s\n", av0, strerror(errno)); return 1; }
|
if (!g_pipe) { fprintf(stderr, "%s: <g_pipe> %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);
|
yylex(); fflush(stdout);
|
||||||
fclose(fp);
|
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; }
|
if (!run) { return 0; }
|
||||||
fprintf(stderr, "output: "); fflush(stderr);
|
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); }
|
if (run) { printf("%s: Exit code %d\n", av0, run); }
|
||||||
return run;
|
return run;
|
||||||
|
out_of_range: fprintf(stderr, "%s: <%d> Out of range\n", av0, g_select); return 1;
|
||||||
}
|
}
|
||||||
|
BIN
test.a.txt
BIN
test.a.txt
Binary file not shown.
Loading…
Reference in New Issue
Block a user