URI:
       bc: Add support for long names - sbase - suckless unix tools
  HTML git clone git://git.suckless.org/sbase
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit c5bfe949dca7001f5e1d456b0c6aebef8fbe07c8
   DIR parent 759ef4f504aec455083582f18431127d7cdf8e73
  HTML Author: Roberto E. Vargas Caballero <k0ga@shike2.net>
       Date:   Tue, 20 Jan 2026 16:31:13 +0100
       
       bc: Add support for long names
       
       As dc supports extended identifiers and we already had
       the option -s in bc that modifies the standard behaviour
       we can extend bc in the -s mode to support longer names.
       The lower case restriction is maintained just for
       simplicity but it is possible to extend bc to support
       full utf8 identifers.
       
       Diffstat:
         M bc.1                                |      13 +++++++++++--
         M bc.y                                |      69 +++++++++++++++++++++----------
         A tests/0050-bc.sh                    |      26 ++++++++++++++++++++++++++
       
       3 files changed, 85 insertions(+), 23 deletions(-)
       ---
   DIR diff --git a/bc.1 b/bc.1
       @@ -41,10 +41,19 @@ Enable yacc parser debugging output.
        Load the mathematical library
        that is loaded before any file from the command line.
        .It Fl s
       -Suppresses the automatic printing of expression results.
       -In this mode, only explicit
       +Enable the extended mode.
       +In this mode,
       +the automatic printing of expression results is suppressed,
       +and only explicit
        .Ic print
        statements produce output.
       +Names of variables and functions can be longer than 1 character,
       +but still constrained to lower case latin characters.
       +The output of
       +.Ar bc
       +in this mode is suitable only for the suckless
       +.Ar dc
       +version.
        .El
        .Sh LANGUAGE
        .Ss Comments
   DIR diff --git a/bc.y b/bc.y
       @@ -26,6 +26,7 @@ typedef struct macro Macro;
        struct macro {
                int op;
                int id;
       +        char *name;
                int flowid;
                int nested;
        };
       @@ -348,6 +349,7 @@ macro(int op)
                d = &macros[nested];
                d->op = op;
                d->nested = nested++;
       +        d->name = NULL;
        
                switch (op) {
                case HOME:
       @@ -359,6 +361,7 @@ macro(int op)
                        unwind = estrdup("");
                        inhome = 0;
                        d->id = funid(yytext);
       +                d->name = estrdup(yytext);
                        d->flowid = macros[0].flowid;
                        break;
                default:
       @@ -417,17 +420,26 @@ funcode(Macro *d, char *params, char *vars, char *body)
        {
                char *s;
        
       -        s = code("[%s%s%s%s]s%c",
       -                 vars, params,
       -                 body,
       -                 retcode(code(" 0")),
       -                 d->id);
       +        if (strlen(d->name) > 1) {
       +                s = code("[%s%s%s%s]s\"()%s\"",
       +                         vars, params,
       +                         body,
       +                         retcode(code(" 0")),
       +                         d->name);
       +        } else {
       +                s = code(sflag ? "[%s%s%s%s]s<%d>" : "[%s%s%s%s]s%c",
       +                         vars, params,
       +                         body,
       +                         retcode(code(" 0")),
       +                         d->id);
       +                free(d->name);
       +        }
       +
                free(unwind);
                unwind = NULL;
                nested--;
                inhome = 0;
        
       -
                return s;
        }
        
       @@ -448,14 +460,17 @@ forcode(Macro *d, char *init, char *cmp, char *inc, char *body)
        {
                char *s;
        
       -        s = code("[%s%ss.%s%c]s%c",
       +        s = code(sflag ? "[%s%ss.%s<%d>]s<%d>" : "[%s%ss.%s%c]s%c",
                         body,
                         inc,
                         estrdup(cmp),
                         d->id, d->id);
                writeout(s);
        
       -        s = code("%ss.%s%c ", init, cmp, d->id);
       +        s = code(sflag ? "%ss.%s<%d> " : "%ss.%s%c ",
       +                 init,
       +                 cmp,
       +                 d->id);
                nested--;
        
                return s;
       @@ -466,13 +481,14 @@ whilecode(Macro *d, char *cmp, char *body)
        {
                char *s;
        
       -        s = code("[%s%s%c]s%c",
       +        s = code(sflag ? "[%s%s<%d>]s<%d>" : "[%s%s%c]s%c",
                         body,
                         estrdup(cmp),
                         d->id, d->id);
                writeout(s);
        
       -        s = code("%s%c ", cmp, d->id);
       +        s = code(sflag ? "%s<%d> " : "%s%c ",
       +                 cmp, d->id);
                nested--;
        
                return s;
       @@ -483,10 +499,12 @@ ifcode(Macro *d, char *cmp, char *body)
        {
                char *s;
        
       -        s = code("[%s]s%c", body, d->id);
       +        s = code(sflag ? "[%s]s<%d>" : "[%s]s%c",
       +                 body, d->id);
                writeout(s);
        
       -        s = code("%s%c ", cmp, d->id);
       +        s = code(sflag ? "%s<%d> " : "%s%c ",
       +                 cmp, d->id);
                nested--;
        
                return s;
       @@ -505,19 +523,25 @@ retcode(char *expr)
        static char *
        ary(char *s)
        {
       -        return code("%c", toupper(s[0]));
       +        if (strlen(s) == 1)
       +                return code("%c", toupper(s[0]));
       +        return code("\"[]%s\"", estrdup(s));
        }
        
        static char *
        ftn(char *s)
        {
       -        return code("%c", funid(s));
       +        if (strlen(s) == 1)
       +                return code(sflag ? "<%d>" : "%c", funid(s));
       +        return code("\"()%s\"", estrdup(s));
        }
        
        static char *
        var(char *s)
        {
       -        return code(s);
       +        if (strlen(s) == 1)
       +                return code(s);
       +        return code("\"%s\"", estrdup(s));
        }
        
        static void
       @@ -531,7 +555,7 @@ skipspaces(void)
        {
                int ch;
        
       -        while (isspace(ch = getc(filep))) {
       +        while (isascii(ch = getc(filep)) && isspace(ch)) {
                        if (ch == '\n') {
                                lineno++;
                                break;
       @@ -569,7 +593,7 @@ iden(int ch)
                ungetc(ch, filep);
                for (bp = yytext; bp < &yytext[BUFSIZ]; ++bp) {
                        ch = getc(filep);
       -                if (!islower(ch))
       +                if (!isascii || !islower(ch))
                                break;
                        *bp = ch;
                }
       @@ -586,11 +610,13 @@ iden(int ch)
        
                for (p = keywords; p->str && strcmp(p->str, yytext); ++p)
                        ;
       +        if (p->str)
       +                return p->token;
        
       -        if (!p->str)
       +        if (!sflag)
                        yyerror("invalid keyword");
       -
       -        return p->token;
       +        strcpy(yylval.id, yytext);
       +        return ID;
        }
        
        static char *
       @@ -785,6 +811,7 @@ static void
        spawn(void)
        {
                int fds[2];
       +        char *par = sflag ? "-i" : NULL;
                char errmsg[] = "bc:error execing dc\n";
        
                if (pipe(fds) < 0)
       @@ -804,7 +831,7 @@ spawn(void)
                        dup(fds[0]);
                        close(fds[0]);
                        close(fds[1]);
       -                execlp(dcprog, "dc", (char *) NULL);
       +                execlp(dcprog, "dc", par, (char *) NULL);
        
                        /* it shouldn't happen */
                        write(3, errmsg, sizeof(errmsg)-1);
   DIR diff --git a/tests/0050-bc.sh b/tests/0050-bc.sh
       @@ -0,0 +1,26 @@
       +#!/bin/sh
       +
       +tmp=$$.tmp
       +
       +trap 'rm -f $tmp' EXIT
       +trap 'exit $?' HUP INT TERM
       +
       +cat <<'EOF' > $tmp
       +par=1
       +inc=4
       +EOF
       +
       +$EXEC ../bc -sp ../dc <<'EOF' | diff -u - $tmp
       +define alpha(par, inc) {
       +        auto cnt
       +
       +        par = par + 1
       +        cnt = par + inc
       +        return (cnt)
       +}
       +
       +par = 1
       +inc = alpha(par, 2)
       +print "par=",par
       +print "inc=",inc
       +EOF