dc: Relax tail call optimization - sbase - suckless unix tools
HTML git clone git://git.suckless.org/sbase
DIR Log
DIR Files
DIR Refs
DIR README
DIR LICENSE
---
DIR commit 2544b70216bb71aec663a9657142e13ad0c6ac41
DIR parent 9439e85c041626dfac86d3011d9f8392823dd768
HTML Author: Roberto E. Vargas Caballero <k0ga@shike2.net>
Date: Sat, 17 Jan 2026 10:57:43 +0100
dc: Relax tail call optimization
Classical dc implementations only apply tail recursion optimization
but we were applying tail call recursion, removing one frame even
when no recursion was involved. This creates problems with bc that
does not track this optimization and it generates values for the Q
command without caring about this optimization.
Diffstat:
M dc.c | 6 +++---
A tests/0045-dc.sh | 19 +++++++++++++++++++
2 files changed, 22 insertions(+), 3 deletions(-)
---
DIR diff --git a/dc.c b/dc.c
@@ -1892,14 +1892,14 @@ execmacro(void)
return;
}
- /* check for tail recursion */
- for (ch = *input->s; ch > 0 && ch < UCHAR_MAX; ch = *input->s) {
+ for (ch = *input->s; ch > 0 && ch <= UCHAR_MAX; ch = *input->s) {
if (!isspace(ch))
break;
++input->s;
}
- if (ch == '\0') {
+ /* check for tail recursion */
+ if (ch == '\0' && strcmp(input->buf, v.u.s) == 0) {
free(input->buf);
input->buf = input->s = v.u.s;
return;
DIR diff --git a/tests/0045-dc.sh b/tests/0045-dc.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+set -e
+
+tmp=$$.tmp
+
+trap 'rm -f $tmp' EXIT
+trap 'exit $?' HUP INT TERM
+
+echo 0 > $tmp
+
+../dc -i <<'EOF' | diff -u - $tmp
+[ 0 Lxs. 2Q]s<128>
+[ .7853981633974483096156608458198757210492923498437764 1/ Lxs. 3Q]s<130>
+[K 52><130> ]s<129>
+[Sxlx 0=<128> lx 1=<129> 0 Lxs. 1Q]s<1>
+
+ 1l<1>xps.
+EOF