aboutsummaryrefslogtreecommitdiff
path: root/contrib/bmake/unit-tests/hanoi-include.mk
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bmake/unit-tests/hanoi-include.mk')
-rw-r--r--contrib/bmake/unit-tests/hanoi-include.mk42
1 files changed, 25 insertions, 17 deletions
diff --git a/contrib/bmake/unit-tests/hanoi-include.mk b/contrib/bmake/unit-tests/hanoi-include.mk
index 3b9438bf2169..f243af83d1df 100644
--- a/contrib/bmake/unit-tests/hanoi-include.mk
+++ b/contrib/bmake/unit-tests/hanoi-include.mk
@@ -1,41 +1,49 @@
-# $NetBSD: hanoi-include.mk,v 1.2 2022/01/08 22:13:43 rillig Exp $
+# $NetBSD: hanoi-include.mk,v 1.5 2023/10/19 18:24:33 rillig Exp $
#
-# Implements the Towers of Hanoi puzzle, thereby demonstrating a bunch of
-# more or less useful programming techniques:
+# Implements the Towers of Hanoi puzzle, demonstrating a bunch of more or less
+# useful programming techniques:
#
-# * default assignment using the ?= assignment operator
-# * including the same file recursively (rather unusual)
-# * extracting the current value of a variable using the .for loop
-# * using shell commands for calculations since make is a text processor
-# * using the :: dependency operator for adding commands to a target
-# * on-the-fly variable assignment expressions using the ::= modifier
+# * default assignment using the ?= assignment operator
+# * including the same file recursively (rather unusual)
+# * extracting the current value of a variable using the .for loop
+# * using the :: dependency operator for adding commands to a target
+# * on-the-fly variable assignment expressions using the ::= modifier
#
# usage:
-# env N=3 make -f hanoi-include.mk
-# endless loop:
-# make -f hanoi-include.mk N=3
+# env N=3 make -r -f hanoi-include.mk
+#
+# Specifying N in the command line instead of in the environment would produce
+# an endless loop, since variables from the command line cannot be overridden
+# by global variables:
+# make -r -f hanoi-include.mk N=3
N?= 5 # Move this number of disks ...
FROM?= A # ... from this stack ...
VIA?= B # ... via this stack ...
TO?= C # ... to this stack.
-.if $N == 1
+# Since make has no built-in arithmetic functions, convert N to a list of
+# words and use the built-in word counting instead.
+.if ${N:[#]} == 1
+N:= count ${:U:${:Urange=$N}} # 'count' + one word for every disk
+.endif
+
+.if ${N:[#]} == 2
. for from to in ${FROM} ${TO}
all::
@echo "Move the upper disk from stack ${from} to stack ${to}."
. endfor
.else
-_:= ${N::!=expr $N - 1} ${TMP::=${VIA}} ${VIA::=${TO}} ${TO::=${TMP}}
+_:= ${N::=${N:[1..-2]}} ${TMP::=${VIA}} ${VIA::=${TO}} ${TO::=${TMP}}
. include "${.PARSEDIR}/${.PARSEFILE}"
-_:= ${N::!=expr $N + 1} ${TMP::=${VIA}} ${VIA::=${TO}} ${TO::=${TMP}}
+_:= ${N::+=D} ${TMP::=${VIA}} ${VIA::=${TO}} ${TO::=${TMP}}
. for from to in ${FROM} ${TO}
all::
@echo "Move the upper disk from stack ${from} to stack ${to}."
. endfor
-_:= ${N::!=expr $N - 1} ${TMP::=${VIA}} ${VIA::=${FROM}} ${FROM::=${TMP}}
+_:= ${N::=${N:[1..-2]}} ${TMP::=${VIA}} ${VIA::=${FROM}} ${FROM::=${TMP}}
. include "${.PARSEDIR}/${.PARSEFILE}"
-_:= ${N::!=expr $N + 1} ${TMP::=${VIA}} ${VIA::=${FROM}} ${FROM::=${TMP}}
+_:= ${N::+=D} ${TMP::=${VIA}} ${VIA::=${FROM}} ${FROM::=${TMP}}
.endif