]> git.xolatile.top Git - emil-bake.git/commitdiff
newlines
authorEmil Williams <emilemilemil@cock.li>
Thu, 26 Sep 2024 22:16:01 +0000 (22:16 +0000)
committerEmil Williams <emilemilemil@cock.li>
Thu, 26 Sep 2024 22:16:01 +0000 (22:16 +0000)
cbake.l

diff --git a/cbake.l b/cbake.l
index 504ace3a3a4fd9c2b91f55e2d43e8bc1e93edd53..6796588b5173e920b4e0d902807a8955f9afaad1 100644 (file)
--- 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 */
 %{
+#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 gmax = 0, line = 1, expunge_depth = 0;
+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; }
+.  {;}
 <FOUND>{
- @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; }
 }
 <PADDING>{
-  [ \v\t\r\f] { ; }
-  .|\n        { yyless(0); BEGIN FOUND; }
+  {SPACE} { ; }
+  .|\n    { yyless(0); BEGIN FOUND; }
+}
+<STOP>{
+ @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 <ctype.h>
-
-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, "<SHORTEN> context error: Argument out of range.\n"); printf("idiot"); return; }
-  fwrite(filename, 1, end - filename, stdout);
+  if (!end) { fprintf(stderr, "<SHORTEN> 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:
+
+ 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 renaming */
+  /* 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: <gpipe> %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: <gpipe> %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;
 }