]> git.xolatile.top Git - emil-bake.git/commitdiff
cleanup
authorEmil Williams <emilemilemil@cock.li>
Fri, 27 Sep 2024 02:35:33 +0000 (02:35 +0000)
committerEmil Williams <emilemilemil@cock.li>
Fri, 27 Sep 2024 02:35:33 +0000 (02:35 +0000)
cbake.l
test.a.txt

diff --git a/cbake.l b/cbake.l
index 7f091262960b42e7d3050f8104c008989252445a..de640846aa9af1a83d8d436ebbc040967bebdc76 100644 (file)
--- 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 <ctype.h>
 
 #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;
+#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)
+
+/* 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; }
 .  {;}
+
 <FOUND>{
- @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;                                                                                   }
 }
+
 <PADDING>{
-  {SPACE} { ; }
+  {SPACE} {                       ; }
   .|\n    { yyless(0); BEGIN FOUND; }
 }
+
 <STOP>{
  @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, "<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);
 }
 
-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<NUM>) */
   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 -<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_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; }
-
-  /* filename and self placement */
-  filename = av[0];
-  root(filename);
-  {
-    char * tmp = strrchr(filename, '/');
-    if (tmp) { filename = tmp+1; }
+  if (!g_select) { goto out_of_range; }
+
+  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: <gpipe> %s\n", av0, strerror(errno)); return 1; }
+    g_pipe = popen("/bin/sh -e", "w");
+    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);
   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;
 }
index ca2ff7fd0e9fcb2e11fa46ca29db1d391949ffdc..ee1f9eaadebc4899c4a9371548a8cc08a7456efe 100644 (file)
Binary files a/test.a.txt and b/test.a.txt differ