Module Name:    src
Committed By:   rillig
Date:           Sun Nov 15 14:58:14 UTC 2020

Modified Files:
        src/usr.bin/make/unit-tests: cond-op-not.exp cond-op-not.mk
            cond-op-parentheses.exp cond-op-parentheses.mk cond-op.exp
            cond-op.mk cond-short.mk cond-token-number.exp cond-token-number.mk
            cond-token-plain.mk cond-token-var.exp cond-token-var.mk
            cond-undef-lint.exp cond-undef-lint.mk cond1.exp cond1.mk

Log Message:
make(1): add remarks to the tests about conditions


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/usr.bin/make/unit-tests/cond-op-not.exp \
    src/usr.bin/make/unit-tests/cond-op-parentheses.mk \
    src/usr.bin/make/unit-tests/cond-token-var.exp \
    src/usr.bin/make/unit-tests/cond-undef-lint.mk \
    src/usr.bin/make/unit-tests/cond1.exp \
    src/usr.bin/make/unit-tests/cond1.mk
cvs rdiff -u -r1.5 -r1.6 src/usr.bin/make/unit-tests/cond-op-not.mk \
    src/usr.bin/make/unit-tests/cond-token-plain.mk
cvs rdiff -u -r1.1 -r1.2 src/usr.bin/make/unit-tests/cond-op-parentheses.exp
cvs rdiff -u -r1.6 -r1.7 src/usr.bin/make/unit-tests/cond-op.exp
cvs rdiff -u -r1.9 -r1.10 src/usr.bin/make/unit-tests/cond-op.mk
cvs rdiff -u -r1.11 -r1.12 src/usr.bin/make/unit-tests/cond-short.mk
cvs rdiff -u -r1.3 -r1.4 src/usr.bin/make/unit-tests/cond-token-number.exp \
    src/usr.bin/make/unit-tests/cond-undef-lint.exp
cvs rdiff -u -r1.4 -r1.5 src/usr.bin/make/unit-tests/cond-token-number.mk \
    src/usr.bin/make/unit-tests/cond-token-var.mk

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/make/unit-tests/cond-op-not.exp
diff -u src/usr.bin/make/unit-tests/cond-op-not.exp:1.2 src/usr.bin/make/unit-tests/cond-op-not.exp:1.3
--- src/usr.bin/make/unit-tests/cond-op-not.exp:1.2	Sun Nov 15 14:14:24 2020
+++ src/usr.bin/make/unit-tests/cond-op-not.exp	Sun Nov 15 14:58:14 2020
@@ -1,6 +1,6 @@
-make: "cond-op-not.mk" line 27: Not empty evaluates to true.
-make: "cond-op-not.mk" line 35: Not space evaluates to false.
-make: "cond-op-not.mk" line 39: Not 0 evaluates to true.
-make: "cond-op-not.mk" line 47: Not 1 evaluates to false.
-make: "cond-op-not.mk" line 53: Not word evaluates to false.
+make: "cond-op-not.mk" line 29: Not empty evaluates to true.
+make: "cond-op-not.mk" line 37: Not space evaluates to false.
+make: "cond-op-not.mk" line 41: Not 0 evaluates to true.
+make: "cond-op-not.mk" line 49: Not 1 evaluates to false.
+make: "cond-op-not.mk" line 55: Not word evaluates to false.
 exit status 0
Index: src/usr.bin/make/unit-tests/cond-op-parentheses.mk
diff -u src/usr.bin/make/unit-tests/cond-op-parentheses.mk:1.2 src/usr.bin/make/unit-tests/cond-op-parentheses.mk:1.3
--- src/usr.bin/make/unit-tests/cond-op-parentheses.mk:1.2	Sun Aug 16 14:25:16 2020
+++ src/usr.bin/make/unit-tests/cond-op-parentheses.mk	Sun Nov 15 14:58:14 2020
@@ -1,8 +1,19 @@
-# $NetBSD: cond-op-parentheses.mk,v 1.2 2020/08/16 14:25:16 rillig Exp $
+# $NetBSD: cond-op-parentheses.mk,v 1.3 2020/11/15 14:58:14 rillig Exp $
 #
 # Tests for parentheses in .if conditions.
 
 # TODO: Implementation
 
+# Test for deeply nested conditions.
+.if	((((((((((((((((((((((((((((((((((((((((((((((((((((((((	\
+	((((((((((((((((((((((((((((((((((((((((((((((((((((((((	\
+	1								\
+	))))))))))))))))))))))))))))))))))))))))))))))))))))))))	\
+	))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+.  info Parentheses can be nested at least to depth 112.
+.else
+.  error
+.endif
+
 all:
 	@:;
Index: src/usr.bin/make/unit-tests/cond-token-var.exp
diff -u src/usr.bin/make/unit-tests/cond-token-var.exp:1.2 src/usr.bin/make/unit-tests/cond-token-var.exp:1.3
--- src/usr.bin/make/unit-tests/cond-token-var.exp:1.2	Thu Aug 20 19:43:42 2020
+++ src/usr.bin/make/unit-tests/cond-token-var.exp	Sun Nov 15 14:58:14 2020
@@ -1,7 +1,7 @@
-make: "cond-token-var.mk" line 9: ok
-make: "cond-token-var.mk" line 15: Malformed conditional (${UNDEF} == ${DEF})
-make: "cond-token-var.mk" line 20: Malformed conditional (${DEF} == ${UNDEF})
-make: "cond-token-var.mk" line 29: Malformed conditional (${UNDEF})
+make: "cond-token-var.mk" line 20: ok
+make: "cond-token-var.mk" line 27: Malformed conditional (${UNDEF} == ${DEF})
+make: "cond-token-var.mk" line 33: Malformed conditional (${DEF} == ${UNDEF})
+make: "cond-token-var.mk" line 42: Malformed conditional (${UNDEF})
 make: Fatal errors encountered -- cannot continue
 make: stopped in unit-tests
 exit status 1
Index: src/usr.bin/make/unit-tests/cond-undef-lint.mk
diff -u src/usr.bin/make/unit-tests/cond-undef-lint.mk:1.2 src/usr.bin/make/unit-tests/cond-undef-lint.mk:1.3
--- src/usr.bin/make/unit-tests/cond-undef-lint.mk:1.2	Mon Sep 14 07:13:29 2020
+++ src/usr.bin/make/unit-tests/cond-undef-lint.mk	Sun Nov 15 14:58:14 2020
@@ -1,4 +1,4 @@
-# $NetBSD: cond-undef-lint.mk,v 1.2 2020/09/14 07:13:29 rillig Exp $
+# $NetBSD: cond-undef-lint.mk,v 1.3 2020/11/15 14:58:14 rillig Exp $
 #
 # Tests for defined and undefined variables in .if conditions, in lint mode.
 #
@@ -42,6 +42,10 @@ DEF=		defined
 .endif
 
 # The variable VAR.defined is not defined and thus generates an error message.
+#
+# TODO: This pattern looks a lot like CFLAGS.${OPSYS}, which is at least
+# debatable.  Or would any practical use of CFLAGS.${OPSYS} be via an indirect
+# expression, as in the next example?
 .if ${VAR.${DEF}}
 .  error
 .else
Index: src/usr.bin/make/unit-tests/cond1.exp
diff -u src/usr.bin/make/unit-tests/cond1.exp:1.2 src/usr.bin/make/unit-tests/cond1.exp:1.3
--- src/usr.bin/make/unit-tests/cond1.exp:1.2	Sat Sep 12 10:39:34 2020
+++ src/usr.bin/make/unit-tests/cond1.exp	Sun Nov 15 14:58:14 2020
@@ -1,5 +1,5 @@
-make: "cond1.mk" line 75: warning: extra else
-make: "cond1.mk" line 85: warning: extra else
+make: "cond1.mk" line 80: warning: extra else
+make: "cond1.mk" line 90: warning: extra else
 2 is  prime
 A='other' B='unknown' C='clever' o='no,no'
 Passed:
Index: src/usr.bin/make/unit-tests/cond1.mk
diff -u src/usr.bin/make/unit-tests/cond1.mk:1.2 src/usr.bin/make/unit-tests/cond1.mk:1.3
--- src/usr.bin/make/unit-tests/cond1.mk:1.2	Sat Oct 24 08:34:59 2020
+++ src/usr.bin/make/unit-tests/cond1.mk	Sun Nov 15 14:58:14 2020
@@ -1,4 +1,9 @@
-# $NetBSD: cond1.mk,v 1.2 2020/10/24 08:34:59 rillig Exp $
+# $NetBSD: cond1.mk,v 1.3 2020/11/15 14:58:14 rillig Exp $
+
+# TODO: Convert these tests into tutorial form.
+# TODO: Split these tests by topic.
+# TODO: Use better variable names and expression values that actually express
+# the intended behavior.  uname(1) has nothing to do with conditions.
 
 # hard code these!
 TEST_UNAME_S= NetBSD

Index: src/usr.bin/make/unit-tests/cond-op-not.mk
diff -u src/usr.bin/make/unit-tests/cond-op-not.mk:1.5 src/usr.bin/make/unit-tests/cond-op-not.mk:1.6
--- src/usr.bin/make/unit-tests/cond-op-not.mk:1.5	Sun Nov 15 14:14:24 2020
+++ src/usr.bin/make/unit-tests/cond-op-not.mk	Sun Nov 15 14:58:14 2020
@@ -1,4 +1,4 @@
-# $NetBSD: cond-op-not.mk,v 1.5 2020/11/15 14:14:24 rillig Exp $
+# $NetBSD: cond-op-not.mk,v 1.6 2020/11/15 14:58:14 rillig Exp $
 #
 # Tests for the ! operator in .if conditions, which negates its argument.
 
@@ -18,7 +18,9 @@
 .  error
 .endif
 
-# The '==' binds more tightly than '!'.
+# The operator '==' binds more tightly than '!'.
+# This is unusual since most other programming languages define the precedence
+# to be the other way round.
 .if !${:Uexpression} == "expression"
 .  error
 .endif
Index: src/usr.bin/make/unit-tests/cond-token-plain.mk
diff -u src/usr.bin/make/unit-tests/cond-token-plain.mk:1.5 src/usr.bin/make/unit-tests/cond-token-plain.mk:1.6
--- src/usr.bin/make/unit-tests/cond-token-plain.mk:1.5	Mon Nov  9 00:07:06 2020
+++ src/usr.bin/make/unit-tests/cond-token-plain.mk	Sun Nov 15 14:58:14 2020
@@ -1,4 +1,4 @@
-# $NetBSD: cond-token-plain.mk,v 1.5 2020/11/09 00:07:06 rillig Exp $
+# $NetBSD: cond-token-plain.mk,v 1.6 2020/11/15 14:58:14 rillig Exp $
 #
 # Tests for plain tokens (that is, string literals without quotes)
 # in .if conditions.
@@ -14,7 +14,7 @@
 # parser gets to see it.
 #
 # XXX: The error message is missing for this malformed condition.
-# The right-hand side of the comparison is just a '"'.
+# The right-hand side of the comparison is just a '"', before unescaping.
 .if ${:U} != "#hash"
 .  error
 .endif
@@ -35,15 +35,15 @@
 # original problems.  This workaround is probably not needed anymore.
 #
 # XXX: Missing error message for the malformed condition. The right-hand
-# side is double-quotes, backslash, backslash.
-# XXX: It is unexpected that the right-hand side evaluates to a single
-# backslash.
+# side before unescaping is double-quotes, backslash, backslash.
 .if ${:U\\} != "\\#hash"
 .  error
 .endif
 
 # The right-hand side of a comparison is not parsed as a token, therefore
 # the code from CondParser_Token does not apply to it.
+# TODO: Explain the consequences.
+# TODO: Does this mean that more syntactic variants are allowed here?
 .if ${:U\#hash} != \#hash
 .  error
 .endif

Index: src/usr.bin/make/unit-tests/cond-op-parentheses.exp
diff -u src/usr.bin/make/unit-tests/cond-op-parentheses.exp:1.1 src/usr.bin/make/unit-tests/cond-op-parentheses.exp:1.2
--- src/usr.bin/make/unit-tests/cond-op-parentheses.exp:1.1	Sun Aug 16 12:07:51 2020
+++ src/usr.bin/make/unit-tests/cond-op-parentheses.exp	Sun Nov 15 14:58:14 2020
@@ -1 +1,2 @@
+make: "cond-op-parentheses.mk" line 13: Parentheses can be nested at least to depth 112.
 exit status 0

Index: src/usr.bin/make/unit-tests/cond-op.exp
diff -u src/usr.bin/make/unit-tests/cond-op.exp:1.6 src/usr.bin/make/unit-tests/cond-op.exp:1.7
--- src/usr.bin/make/unit-tests/cond-op.exp:1.6	Sun Nov 15 14:04:26 2020
+++ src/usr.bin/make/unit-tests/cond-op.exp	Sun Nov 15 14:58:14 2020
@@ -1,16 +1,16 @@
-make: "cond-op.mk" line 45: Malformed conditional ("!word" == !word)
-make: "cond-op.mk" line 70: Malformed conditional (0 ${ERR::=evaluated})
-make: "cond-op.mk" line 74: warning: After detecting a parse error, the rest is evaluated.
-make: "cond-op.mk" line 78: Parsing continues until here.
-make: "cond-op.mk" line 81: A B C   =>   (A || B) && C   A || B && C   A || (B && C)
-make: "cond-op.mk" line 88: 0 0 0   =>   0               0             0
-make: "cond-op.mk" line 88: 0 0 1   =>   0               0             0
-make: "cond-op.mk" line 88: 0 1 0   =>   0               0             0
-make: "cond-op.mk" line 88: 0 1 1   =>   1               1             1
-make: "cond-op.mk" line 88: 1 0 0   =>   0               1             1
-make: "cond-op.mk" line 88: 1 0 1   =>   1               1             1
-make: "cond-op.mk" line 88: 1 1 0   =>   0               1             1
-make: "cond-op.mk" line 88: 1 1 1   =>   1               1             1
+make: "cond-op.mk" line 50: Malformed conditional ("!word" == !word)
+make: "cond-op.mk" line 75: Malformed conditional (0 ${ERR::=evaluated})
+make: "cond-op.mk" line 79: After detecting a parse error, the rest is evaluated.
+make: "cond-op.mk" line 83: Parsing continues until here.
+make: "cond-op.mk" line 86: A B C   =>   (A || B) && C   A || B && C   A || (B && C)
+make: "cond-op.mk" line 93: 0 0 0   =>   0               0             0
+make: "cond-op.mk" line 93: 0 0 1   =>   0               0             0
+make: "cond-op.mk" line 93: 0 1 0   =>   0               0             0
+make: "cond-op.mk" line 93: 0 1 1   =>   1               1             1
+make: "cond-op.mk" line 93: 1 0 0   =>   0               1             1
+make: "cond-op.mk" line 93: 1 0 1   =>   1               1             1
+make: "cond-op.mk" line 93: 1 1 0   =>   0               1             1
+make: "cond-op.mk" line 93: 1 1 1   =>   1               1             1
 make: Fatal errors encountered -- cannot continue
 make: stopped in unit-tests
 exit status 1

Index: src/usr.bin/make/unit-tests/cond-op.mk
diff -u src/usr.bin/make/unit-tests/cond-op.mk:1.9 src/usr.bin/make/unit-tests/cond-op.mk:1.10
--- src/usr.bin/make/unit-tests/cond-op.mk:1.9	Sun Nov 15 14:04:26 2020
+++ src/usr.bin/make/unit-tests/cond-op.mk	Sun Nov 15 14:58:14 2020
@@ -1,4 +1,4 @@
-# $NetBSD: cond-op.mk,v 1.9 2020/11/15 14:04:26 rillig Exp $
+# $NetBSD: cond-op.mk,v 1.10 2020/11/15 14:58:14 rillig Exp $
 #
 # Tests for operators like &&, ||, ! in .if conditions.
 #
@@ -9,8 +9,8 @@
 #	cond-op-parentheses.mk
 
 # In make, && binds more tightly than ||, like in C.
-# If make had the same precedence for both && and ||, the result would be
-# different.
+# If make had the same precedence for both && and ||, like in the shell,
+# the result would be different.
 # If || were to bind more tightly than &&, the result would be different
 # as well.
 .if !(1 || 1 && 0)
@@ -18,13 +18,17 @@
 .endif
 
 # If make were to interpret the && and || operators like the shell, the
-# implicit binding would be this:
+# previous condition would be interpreted as:
 .if (1 || 1) && 0
 .  error
 .endif
 
 # The precedence of the ! operator is different from C though. It has a
-# lower precedence than the comparison operators.
+# lower precedence than the comparison operators.  Negating a condition
+# does not need parentheses.
+#
+# This kind of condition looks so unfamiliar that it doesn't occur in
+# practice.
 .if !"word" == "word"
 .  error
 .endif
@@ -36,7 +40,8 @@
 
 # TODO: Demonstrate that the precedence of the ! and == operators actually
 # makes a difference.  There is a simple example for sure, I just cannot
-# wrap my head around it.
+# wrap my head around it right now.  See the truth table generator below
+# for an example that doesn't require much thought.
 
 # This condition is malformed because the '!' on the right-hand side must not
 # appear unquoted.  If any, it must be enclosed in quotes.
@@ -71,7 +76,7 @@
 .  error
 .endif
 .if ${ERR:Uundefined} == evaluated
-.  warning After detecting a parse error, the rest is evaluated.
+.  info After detecting a parse error, the rest is evaluated.
 .endif
 
 # Just in case that parsing should ever stop on the first error.

Index: src/usr.bin/make/unit-tests/cond-short.mk
diff -u src/usr.bin/make/unit-tests/cond-short.mk:1.11 src/usr.bin/make/unit-tests/cond-short.mk:1.12
--- src/usr.bin/make/unit-tests/cond-short.mk:1.11	Sat Oct 24 08:50:17 2020
+++ src/usr.bin/make/unit-tests/cond-short.mk	Sun Nov 15 14:58:14 2020
@@ -1,11 +1,14 @@
-# $NetBSD: cond-short.mk,v 1.11 2020/10/24 08:50:17 rillig Exp $
+# $NetBSD: cond-short.mk,v 1.12 2020/11/15 14:58:14 rillig Exp $
 #
 # Demonstrates that in conditions, the right-hand side of an && or ||
 # is only evaluated if it can actually influence the result.
+# This is called 'short-circuit evaluation' and is the usual evaluation
+# mode in most programming languages.  A notable exception is Ada, which
+# distinguishes between the operators 'And', 'And Then', 'Or', 'Or Else'.
 #
 # Between 2015-10-11 and 2020-06-28, the right-hand side of an && or ||
 # operator was always evaluated, which was wrong.
-#
+# TODO: Had the evaluation been correct at some time before 2015-11-12?
 
 # The && operator.
 
@@ -113,6 +116,9 @@ VAR=	# empty again, for the following te
 # make sure these do not cause complaint
 #.MAKEFLAGS: -dc
 
+# TODO: Rewrite this whole section and check all the conditions and variables.
+# Several of the assumptions are probably wrong here.
+# TODO: replace 'x=' with '.info' or '.error'.
 V42=	42
 iV1=	${V42}
 iV2=	${V66}
@@ -167,5 +173,16 @@ x=	Fail
 .endif
 x!=	echo '0 || ${iV2:U2} < ${V42}: $x' >&2; echo
 
+# TODO: Has this always worked?  There may have been a time, maybe around
+# 2000, when make would complain about the "Malformed conditional" because
+# UNDEF is not defined.
+.if defined(UNDEF) && ${UNDEF} != "undefined"
+.  error
+.endif
+
+# TODO: Test each modifier to make sure it is skipped when it is irrelevant
+# for the result.  Since this test is already quite long, do that in another
+# test.
+
 all:
 	@:;:

Index: src/usr.bin/make/unit-tests/cond-token-number.exp
diff -u src/usr.bin/make/unit-tests/cond-token-number.exp:1.3 src/usr.bin/make/unit-tests/cond-token-number.exp:1.4
--- src/usr.bin/make/unit-tests/cond-token-number.exp:1.3	Sun Nov  8 22:28:05 2020
+++ src/usr.bin/make/unit-tests/cond-token-number.exp	Sun Nov 15 14:58:14 2020
@@ -1,8 +1,8 @@
-make: "cond-token-number.mk" line 13: Malformed conditional (-0)
-make: "cond-token-number.mk" line 21: Malformed conditional (+0)
-make: "cond-token-number.mk" line 29: Malformed conditional (!-1)
-make: "cond-token-number.mk" line 37: Malformed conditional (!+1)
-make: "cond-token-number.mk" line 70: End of the tests.
+make: "cond-token-number.mk" line 15: Malformed conditional (-0)
+make: "cond-token-number.mk" line 25: Malformed conditional (+0)
+make: "cond-token-number.mk" line 35: Malformed conditional (!-1)
+make: "cond-token-number.mk" line 45: Malformed conditional (!+1)
+make: "cond-token-number.mk" line 80: End of the tests.
 make: Fatal errors encountered -- cannot continue
 make: stopped in unit-tests
 exit status 1
Index: src/usr.bin/make/unit-tests/cond-undef-lint.exp
diff -u src/usr.bin/make/unit-tests/cond-undef-lint.exp:1.3 src/usr.bin/make/unit-tests/cond-undef-lint.exp:1.4
--- src/usr.bin/make/unit-tests/cond-undef-lint.exp:1.3	Mon Sep 14 07:13:29 2020
+++ src/usr.bin/make/unit-tests/cond-undef-lint.exp	Sun Nov 15 14:58:14 2020
@@ -1,7 +1,7 @@
 make: "cond-undef-lint.mk" line 23: Variable "UNDEF" is undefined
 make: "cond-undef-lint.mk" line 38: Variable "UNDEF" is undefined
 make: "cond-undef-lint.mk" line 38: Variable "VAR." is undefined
-make: "cond-undef-lint.mk" line 45: Variable "VAR.defined" is undefined
+make: "cond-undef-lint.mk" line 49: Variable "VAR.defined" is undefined
 make: Fatal errors encountered -- cannot continue
 make: stopped in unit-tests
 exit status 1

Index: src/usr.bin/make/unit-tests/cond-token-number.mk
diff -u src/usr.bin/make/unit-tests/cond-token-number.mk:1.4 src/usr.bin/make/unit-tests/cond-token-number.mk:1.5
--- src/usr.bin/make/unit-tests/cond-token-number.mk:1.4	Sun Nov  8 22:28:05 2020
+++ src/usr.bin/make/unit-tests/cond-token-number.mk	Sun Nov 15 14:58:14 2020
@@ -1,6 +1,8 @@
-# $NetBSD: cond-token-number.mk,v 1.4 2020/11/08 22:28:05 rillig Exp $
+# $NetBSD: cond-token-number.mk,v 1.5 2020/11/15 14:58:14 rillig Exp $
 #
 # Tests for number tokens in .if conditions.
+#
+# TODO: Add introduction.
 
 .if 0
 .  error
@@ -12,6 +14,8 @@
 # See the ch_isdigit call in CondParser_String.
 .if -0
 .  error
+.else
+.  error
 .endif
 
 # Even though +0 is a number and would be accepted by strtod, it is not
@@ -20,6 +24,8 @@
 # See the ch_isdigit call in CondParser_String.
 .if +0
 .  error
+.else
+.  error
 .endif
 
 # Even though -1 is a number and would be accepted by strtod, it is not
@@ -28,6 +34,8 @@
 # See the ch_isdigit call in CondParser_String.
 .if !-1
 .  error
+.else
+.  error
 .endif
 
 # Even though +1 is a number and would be accepted by strtod, it is not
@@ -36,6 +44,8 @@
 # See the ch_isdigit call in CondParser_String.
 .if !+1
 .  error
+.else
+.  error
 .endif
 
 # When the number comes from a variable expression though, it may be signed.
Index: src/usr.bin/make/unit-tests/cond-token-var.mk
diff -u src/usr.bin/make/unit-tests/cond-token-var.mk:1.4 src/usr.bin/make/unit-tests/cond-token-var.mk:1.5
--- src/usr.bin/make/unit-tests/cond-token-var.mk:1.4	Sat Oct 24 08:46:08 2020
+++ src/usr.bin/make/unit-tests/cond-token-var.mk	Sun Nov 15 14:58:14 2020
@@ -1,6 +1,17 @@
-# $NetBSD: cond-token-var.mk,v 1.4 2020/10/24 08:46:08 rillig Exp $
+# $NetBSD: cond-token-var.mk,v 1.5 2020/11/15 14:58:14 rillig Exp $
 #
-# Tests for variables in .if conditions.
+# Tests for variable expressions in .if conditions.
+#
+# Note the fine distinction between a variable and a variable expression.
+# A variable has a name and a value.  To access the value, one writes a
+# variable expression of the form ${VAR}.  This is a simple variable
+# expression.  Variable expressions can get more complicated by adding
+# variable modifiers such as in ${VAR:Mpattern}.
+#
+# XXX: Strictly speaking, variable modifiers should be called expression
+# modifiers instead since they only modify the expression, not the variable.
+# Well, except for the assignment modifiers, these do indeed change the value
+# of the variable.
 
 DEF=	defined
 
@@ -12,11 +23,13 @@ DEF=	defined
 .endif
 
 # A variable that appears on the left-hand side must be defined.
+# The following line thus generates a parse error.
 .if ${UNDEF} == ${DEF}
 .  error
 .endif
 
 # A variable that appears on the right-hand side must be defined.
+# The following line thus generates a parse error.
 .if ${DEF} == ${UNDEF}
 .  error
 .endif
@@ -25,10 +38,11 @@ DEF=	defined
 .if ${DEF}
 .endif
 
-# An undefined variable generates a warning.
+# An undefined variable on its own generates a parse error.
 .if ${UNDEF}
 .endif
 
-# The :U modifier turns an undefined variable into an ordinary expression.
+# The :U modifier turns an undefined expression into a defined expression.
+# Since the expression is defined now, it doesn't generate any parse error.
 .if ${UNDEF:U}
 .endif

Reply via email to