diff options
Diffstat (limited to 'contrib/bmake/unit-tests/hanoi-include.mk')
-rw-r--r-- | contrib/bmake/unit-tests/hanoi-include.mk | 42 |
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 |