[hackers] [sbase] bc: Add support for long names || Roberto E. Vargas Caballero

From: <git_AT_suckless.org>
Date: Tue, 20 Jan 2026 16:33:23 +0100 (CET)

commit c5bfe949dca7001f5e1d456b0c6aebef8fbe07c8
Author: Roberto E. Vargas Caballero <k0ga_AT_shike2.net>
AuthorDate: Tue Jan 20 16:31:13 2026 +0100
Commit: Roberto E. Vargas Caballero <k0ga_AT_shike2.net>
CommitDate: Tue Jan 20 16:31:13 2026 +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.

diff --git a/bc.1 b/bc.1
index 7e95ff8..faf3164 100644
--- a/bc.1
+++ b/bc.1
_AT_@ -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
diff --git a/bc.y b/bc.y
index 65a1148..b6463b5 100644
--- a/bc.y
+++ b/bc.y
_AT_@ -26,6 +26,7 @@ typedef struct macro Macro;
 struct macro {
         int op;
         int id;
+ char *name;
         int flowid;
         int nested;
 };
_AT_@ -348,6 +349,7 @@ macro(int op)
         d = &macros[nested];
         d->op = op;
         d->nested = nested++;
+ d->name = NULL;
 
         switch (op) {
         case HOME:
_AT_@ -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:
_AT_@ -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;
 }
 
_AT_@ -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;
_AT_@ -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;
_AT_@ -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;
_AT_@ -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
_AT_@ -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;
_AT_@ -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;
         }
_AT_@ -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 *
_AT_@ -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)
_AT_@ -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);
diff --git a/tests/0050-bc.sh b/tests/0050-bc.sh
new file mode 100755
index 0000000..a9ec190
--- /dev/null
+++ b/tests/0050-bc.sh
_AT_@ -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
Received on Tue Jan 20 2026 - 16:33:23 CET

This archive was generated by hypermail 2.3.0 : Tue Jan 20 2026 - 16:36:34 CET