Skip to content

Commit

Permalink
tests/make: extend tests for expression modifiers, especially ':N'
Browse files Browse the repository at this point in the history
  • Loading branch information
rillig committed Feb 26, 2023
1 parent cab670e commit acfa39c
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 9 deletions.
98 changes: 93 additions & 5 deletions usr.bin/make/unit-tests/varmod-no-match.mk
@@ -1,9 +1,97 @@
# $NetBSD: varmod-no-match.mk,v 1.2 2020/08/16 14:25:16 rillig Exp $
# $NetBSD: varmod-no-match.mk,v 1.3 2023/02/26 06:08:06 rillig Exp $
#
# Tests for the :N variable modifier, which filters words that do not match
# the given pattern.
# Tests for the expression modifier ':N', which filters words that do not
# match the given pattern.


# Keep all words except for 'two'.
.if ${:U one two three :Ntwo} != "one three"
. error
.endif

# Keep all words except those starting with 't'.
# See varmod-match.mk for the details of pattern matching.
.if ${:U one two three four six :Nt*} != "one four six"
. error
.endif


# Idiom: normalize whitespace
#
# The modifier ':N' can be used with an empty pattern. As that pattern never
# matches a word, the only effect is that the string is split into words and
# then joined again, thereby normalizing whitespace around and between the
# words. And even though the 'N' in ':N' might serve as a mnemonic for
# "normalize whitespace", this idiom is not used in practice, resorting to the
# much more common ':M*' to "select all words" instead.
.if ${:U :N} != ""
. error
.endif
.if ${:U one two three :N} != "one two three"
. error
.endif
.if ${:U one two three :M*} != "one two three"
. error
.endif


# Idiom: single-word expression equals any of several words or patterns
#
# If an expression is guaranteed to consist of a single word, the modifier
# ':N' can be chained to compare the expression to several words or even
# patterns in a sequence. If one of the patterns matches, the final
# expression will be the empty string.
#
.if ${:U word :None:Ntwo:Nthree} != ""
# good
.else
. error
.endif
.if ${:U two :None:Ntwo:Nthree} != ""
. error
.else
# good
.endif
#
# The modifier ':N' is seldom used in general since positive matches with ':M'
# are easier to grasp. Chaining the ':N' modifier is even more difficult to
# grasp due to the many negations involved.
#
# The final '!= ""' adds to the confusion because at first glance, the
# condition may look like '${VAR} != ""', which for a single-word variable is
# always true.
#
# The '!= ""' can be omitted if the expression cannot have the numeric value
# 0, which is common in practice. In that form, each ':N' can be pronounced
# as 'neither' or 'nor', which makes the expression sound more natural.
#
.if ${:U word :None:Ntwo:Nthree}
# good
.else
. error
.endif
.if ${:U two :None:Ntwo:Nthree}
. error
.else
# good
.endif
#
# Replacing the '${...} != ""' with '!empty(...)' doesn't improve the
# situation as the '!' adds another level of negations, and the word 'empty'
# is a negation on its own, thereby creating a triple negation. Furthermore,
# due to the '!empty', the expression to be evaluated no longer starts with
# '$' and is thus more difficult to spot quickly.
#
.if !empty(:U word :None:Ntwo:Nthree)
# good
.else
. error
.endif
.if !empty(:U two :None:Ntwo:Nthree)
. error
.else
# good
.endif

# TODO: Implementation

all:
@:;
7 changes: 4 additions & 3 deletions usr.bin/make/unit-tests/varmod-order-shuffle.mk
@@ -1,13 +1,14 @@
# $NetBSD: varmod-order-shuffle.mk,v 1.7 2021/08/03 04:46:49 rillig Exp $
# $NetBSD: varmod-order-shuffle.mk,v 1.8 2023/02/26 06:08:06 rillig Exp $
#
# Tests for the :Ox variable modifier, which returns the words of the
# variable, shuffled.
#
# The variable modifier :Ox is available since 2005-06-01.
#
# As of 2020-08-16, make uses random(3) seeded by the current time in seconds.
# This makes the random numbers completely predictable since there is no other
# part of make that uses random numbers.
# This makes the random numbers completely predictable since the only other
# part of make that uses random numbers is the 'randomize-targets' mode, which
# is off by default.
#
# Tags: probabilistic

Expand Down
2 changes: 2 additions & 0 deletions usr.bin/make/unit-tests/varmod-order.exp
Expand Up @@ -19,6 +19,8 @@ make: Bad modifier ":Onrr" for variable "NUMBERS"
make: "varmod-order.mk" line 77: Malformed conditional (${NUMBERS:Onrr})
make: Bad modifier ":Orrn" for variable "NUMBERS"
make: "varmod-order.mk" line 86: Malformed conditional (${NUMBERS:Orrn})
make: Bad modifier ":On=Off" for variable "SWITCH"
make: "varmod-order.mk" line 96: Malformed conditional (${SWITCH:UOn:On=Off} != "Off")
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
12 changes: 11 additions & 1 deletion usr.bin/make/unit-tests/varmod-order.mk
@@ -1,4 +1,4 @@
# $NetBSD: varmod-order.mk,v 1.8 2022/01/15 12:35:18 rillig Exp $
# $NetBSD: varmod-order.mk,v 1.9 2023/02/26 06:08:06 rillig Exp $
#
# Tests for the :O variable modifier and its variants, which either sort the
# words of the value or shuffle them.
Expand Down Expand Up @@ -89,4 +89,14 @@ _:= ${NUMBERS:Onr
. error
.endif


# Any modifier that starts with 'O' either sorts or shuffles the words. Other
# than for many other modifiers, there is no fallback to the SysV modifier
# ':from=to'.
.if ${SWITCH:UOn:On=Off} != "Off"
. error
.else
. error
.endif

all:

0 comments on commit acfa39c

Please sign in to comment.