sbase

suckless unix tools
git clone git://git.suckless.org/sbase
Log | Files | Refs | README | LICENSE

commit a49b87f927866a08d7cedbebed2f64dcd346afb9
parent abce467a9d5f61d41957f435cec34f28d1c5e1dc
Author: Roberto E. Vargas Caballero <k0ga@shike2.net>
Date:   Sat, 22 Nov 2025 19:29:56 +0100

bc: Add support for multi files

Bc was supporting only reading programs from stdin, and this patch uses
freopen() to redirect input files (if any) to stdin.

Diffstat:
Mbc.y | 47++++++++++++++++++++++++++++++++++++-----------
1 file changed, 36 insertions(+), 11 deletions(-)

diff --git a/bc.y b/bc.y @@ -46,6 +46,7 @@ static void writeout(char *); static size_t used; static char *yytext, *buff; +static char *filename = "<stdin>"; static int lineno, nerr; static jmp_buf recover; static int nested; @@ -62,7 +63,6 @@ int cflag, dflag, lflag, sflag; %token <id> ID %token <str> STRING NUMBER %token <str> EQOP '+' '-' '*' '/' '%' '^' INCDEC -%token EOFTOK %token EQ %token LE %token GE @@ -96,7 +96,7 @@ int cflag, dflag, lflag, sflag; %% -program : EOFTOK {quit();} +program : | item program ; @@ -104,17 +104,17 @@ item : scolonlst '\n' {used = 0;} | function {writeout($1); used = 0;} ; -scolonlst: /* empty */ +scolonlst: | stat {writeout($1);} | scolonlst ';' stat {writeout($3);} | scolonlst ';' ; -statlst : /* empty */ {$$ = code("");} +statlst : {$$ = code("");} | stat | statlst '\n' stat {$$ = code("%s%s", $1, $3);} | statlst ';' stat {$$ = code("%s%s", $1, $3);} - | statlst '\n' + | statlst '\n' | statlst ';' ; @@ -147,7 +147,7 @@ parlst : '(' ')' {$$ = "%s";} | '(' locals ')' {$$ = $2;} ; -autolst : /* empty */ {$$ = "%s";} +autolst : {$$ = "%s";} | AUTO locals '\n' {$$ = $2;} | AUTO locals ';' {$$ = $2;} ; @@ -233,7 +233,7 @@ ary : '[' expr ']' {$$ = $2;} static int yyerror(char *s) { - fprintf(stderr, "bc: %s:%d:%s\n", "<stdin>", lineno, s); + fprintf(stderr, "bc: %s:%d:%s\n", filename, lineno, s); nerr++; longjmp(recover, 1); } @@ -600,7 +600,7 @@ repeat: ch = getchar(); if (ch == EOF) { - return EOFTOK; + return EOF; } else if (!isascii(ch)) { yyerror("invalid input character"); } else if (islower(ch)) { @@ -654,7 +654,8 @@ spawn(void) static void init(void) { - nested = used = 0; + used = 0; + if (!yytext) yytext = malloc(BUFSIZ); if (!buff) @@ -666,6 +667,9 @@ init(void) static int run(void) { + if (feof(stdin)) + return 0; + if (setjmp(recover)) return 1; @@ -674,6 +678,21 @@ run(void) } static void +bc(char *fname) +{ + lineno = 0; + if (fname) { + filename = fname; + if (!freopen(fname, "r", stdin)) + eprintf("bc: %s:", fname); + } + + for (init(); run(); init()) + ; + nested = used = 0; +} + +static void usage(void) { eprintf("usage: %s [-cdls]\n", argv0); @@ -703,6 +722,12 @@ main(int argc, char *argv[]) if (!cflag) spawn(); - for (init(); run(); init()) - ; + if (*argv == NULL) { + bc(NULL); + } else { + while (*argv) + bc(*argv++); + } + + quit(); }