diff --git a/README b/README index ae69660..112c870 100644 --- a/README +++ b/README @@ -15,12 +15,14 @@ any file. It executes with /bin/sh the command after a "@BAKE " to the end of the line (a UNIX newline: '\n'). It expands some macros, - @FILENAME @FILE @NAME - filename - @SHORT - filename without suffix (abc.x.txt \-> abc.x) - @SHORT:N - removes N suffixes, so (a.b.c 2 -> a) - @ARGS - other arguments to the program - @ARGS:N - Provides the Nth argument, starting from 0 - @LINE - line number at the selected @BAKE + @FILENAME @FILE @NAME - filename + @SHORT - filename without suffix (abc.x.txt \-> abc.x) + @SHORT:N - removes N suffixes, so (a.b.c 2 -> a) + @ARGS - other arguments to the program + @ARGS:N - Provides the Nth argument, starting from 0 + @ARGS:N+ - All arguments at and after Nth + @RECURS - the full path name to the executable + @LINE - line number at the selected @BAKE All macros can be exempted by prefixing them with a backslash, which'll be subtracted in the expansion. commands may be diff --git a/bake.1 b/bake.1 index d2fc450..96bde8c 100644 --- a/bake.1 +++ b/bake.1 @@ -11,25 +11,25 @@ bake is a simple tool meant to execute embedded shell commands within any file. It executes with /bin/sh the command after a "\fB@BAKE\fP " to the end of the line (a UNIX newline: '\fB\\n\fP'). -This format may be embedded within \fBbinary files\fP, or any file where no unwanted preceding -instance of \fB@BAKE\fP appears. +This format may be embedded within \fBany file\fP. 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, numerical options must be trailing. +Options must always be put before the filename, and short options may be merged together, numerical options must be trailing. .HP \-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 + \fB\-n \-\-dry\-run\fP, don't execute anything + \fB\-c \-\-color\fP, disables color + \fB\-l \-\-list\fP, lists available shell commands + \fB\-s \-\-select\fP \, selects Nth shell command + \fB\-x \-\-expunge\fP, Removes what's specified in the expunge block .PP Macros All macros can be exempted by prefixing them with a backslash, -which'll be subtracted in the expansion. multi-line commands may be -done by a leading backslash, which are NOT subtracted. +which'll be subtracted in the expansion. backslashes may be used to +extend a command over several lines. These macros will expand to their counterpart before execution. .TP @@ -41,20 +41,24 @@ returns target\-file without suffix (abc.x.txt \-> abc.x) supports choice syntax, @SHORT:N removes N suffixes, so (a.b.c 2 -> a) .TP .B @ARGS, $+ -returns -.B arguments -, supports choice syntax, @ARGS:0 returns the first argument, @ARGS:N so on. +returns \fBarguments\fP, supports choice syntax: @ARGS:N prints the +Nth argument starting from 0, leading plus prints inclusive remaining +arguments (@ARGS:N+) .TP .B @LINE returns the line number +.TP +.B @RECURS +returns full executable name (e.g. /usr/local/bin/bake) .PP Additional Features And Notes Shell execution may be disabled with the \fB-n\fP or \fB--dry-run\fP option. -Expunge removes exactly one file specified in the @{...} format. You may use -backslashes to remove +Expunge removes exactly one file specified in the @{TEXT} format, and +is not recursive. Expunge simply outputs rm 'TEXT...', where text +expands any instance of ' to \\'. .SH EXAMPLE .\" SRC BEGIN (example.c) diff --git a/bake.l b/bake.l index f8bc334..5a1069c 100644 --- a/bake.l +++ b/bake.l @@ -27,16 +27,19 @@ extern void pipeopen(char * filename, char * mode); %} SPACE [ \t\r\v\f] -MACROS (@BAKE|@FILENAME|@FILE|@NAME|@SHORT|@ARGS|@LINE|@STOP|$@|$*|$+) + /* Everything that can be backslashed */ +FILENAME (@FILENAME|@FILE|@NAME) +CMD @BAKE[[:space:]] +MACROS ({CMD}|@STOP|{FILENAME}|@SHORT|@ARGS|@LINE|@RECURS|$@|$*|$+|@\{) %x FOUND PADDING STOP %option nodefault noinput nounput noyywrap %% -\n { ++line; } -. { ; } +\n { ++line; } +.|\\@BAKE[[:space:]] { ; } -@BAKE[[:space:]] { bake: +{CMD} { bake: static int nth = 0; first_nl = 1; if (yytext[yyleng-1] == '\n') { ++line; } @@ -61,21 +64,21 @@ MACROS (@BAKE|@FILENAME|@FILE|@NAME|@SHORT|@ARGS|@LINE|@STOP|$@|$*|$+) expunge_depth = 0; } - ' { if (g_rm) { STRING("\\'"); } else { ECHO; } } - @BAKE[[:space:]]|@STOP { BEGIN INITIAL; yyless(0); if (first_nl) { CHAR('\n'); } if (!g_select) { return 0; } } - \\\n { BEGIN PADDING; ++line; CHAR(' '); } - @FILENAME|@FILE|@NAME|$@ { STRING(g_filename); } - @SHORT:[[:digit:]]+ { shorten(g_filename, atoi(strrchr(yytext, ':')+1)); } - @SHORT|$\* { shorten(g_filename, 1); } - @ARGS:[[:digit:]]+ { args(atoi(strrchr(yytext, ':')+1), 0); } - @ARGS:[[:digit:]]+\+ { args(atoi(strrchr(yytext, ':')+1), 1); } - @ARGS|$\+ { args(0, 1); } - @LINE { FORMAT("%d", line); } - @RECURS { char * prog = realpath(av0, NULL); STRING(prog); free(prog); } - \\{MACROS} { STRING(yytext + 1); } - {SPACE} { BEGIN PADDING; CHAR(' '); } - \n { CHAR('\n'); ++line; if (first_nl) { BEGIN STOP; first_nl = 0; tmpline = 0; } } - .|\\' { ECHO; } + ' { if (g_rm) { STRING("\\'"); } else { ECHO; } } + {CMD}|@STOP { BEGIN INITIAL; yyless(0); if (first_nl) { CHAR('\n'); } if (!g_select) { return 0; } } + \\\n { BEGIN PADDING; ++line; CHAR(' '); } + {FILENAME}|$@ { STRING(g_filename); } + @SHORT:[[:digit:]]+ { shorten(g_filename, atoi(strrchr(yytext, ':')+1)); } + @SHORT|$\* { shorten(g_filename, 1); } + @ARGS:[[:digit:]]+ { args(atoi(strrchr(yytext, ':')+1), 0); } + @ARGS:[[:digit:]]+\+ { args(atoi(strrchr(yytext, ':')+1), 1); } + @ARGS|$\+ { args(0, 1); } + @LINE { FORMAT("%d", line); } + @RECURS { char * prog = realpath(av0, NULL); STRING(prog); free(prog); } + \\{MACROS} { STRING(yytext + 1); } + {SPACE} { BEGIN PADDING; CHAR(' '); } + \n { CHAR('\n'); ++line; if (first_nl) { BEGIN STOP; first_nl = 0; tmpline = 0; } } + .|\\' { ECHO; } } { @@ -84,10 +87,10 @@ MACROS (@BAKE|@FILENAME|@FILE|@NAME|@SHORT|@ARGS|@LINE|@STOP|$@|$*|$+) } { - @BAKE[[:space:]] { line += tmpline; goto bake; } - @STOP { BEGIN FOUND; yyless(0); } - \n { ++tmpline; yymore(); } - .|\\@ { yymore(); } + {CMD} { line += tmpline; goto bake; } + @STOP { BEGIN FOUND; yyless(0); } + \n { ++tmpline; yymore(); } + .|\\@ { yymore(); } } %%