Module Name: src Committed By: rillig Date: Sat Nov 30 00:38:51 UTC 2019
Modified Files: src/usr.bin/make/unit-tests: Makefile Added Files: src/usr.bin/make/unit-tests: varmod-edge.exp varmod-edge.mk Log Message: Add unit tests for variable modifiers like :M and :N To generate a diff of this commit: cvs rdiff -u -r1.53 -r1.54 src/usr.bin/make/unit-tests/Makefile cvs rdiff -u -r0 -r1.1 src/usr.bin/make/unit-tests/varmod-edge.exp \ src/usr.bin/make/unit-tests/varmod-edge.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/Makefile diff -u src/usr.bin/make/unit-tests/Makefile:1.53 src/usr.bin/make/unit-tests/Makefile:1.54 --- src/usr.bin/make/unit-tests/Makefile:1.53 Thu May 24 00:25:44 2018 +++ src/usr.bin/make/unit-tests/Makefile Sat Nov 30 00:38:51 2019 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.53 2018/05/24 00:25:44 christos Exp $ +# $NetBSD: Makefile,v 1.54 2019/11/30 00:38:51 rillig Exp $ # # Unit tests for make(1) # The main targets are: @@ -50,6 +50,7 @@ TESTNAMES= \ unexport-env \ varcmd \ varmisc \ + varmod-edge \ varquote \ varshell Added files: Index: src/usr.bin/make/unit-tests/varmod-edge.exp diff -u /dev/null src/usr.bin/make/unit-tests/varmod-edge.exp:1.1 --- /dev/null Sat Nov 30 00:38:51 2019 +++ src/usr.bin/make/unit-tests/varmod-edge.exp Sat Nov 30 00:38:51 2019 @@ -0,0 +1,7 @@ +make: Unclosed variable specification (expecting '}') for "" (value "*)") modifier U +ok M-paren +ok M-mixed +ok M-nest-mix +ok M-nest-brk +ok M-pat-err +exit status 0 Index: src/usr.bin/make/unit-tests/varmod-edge.mk diff -u /dev/null src/usr.bin/make/unit-tests/varmod-edge.mk:1.1 --- /dev/null Sat Nov 30 00:38:51 2019 +++ src/usr.bin/make/unit-tests/varmod-edge.mk Sat Nov 30 00:38:51 2019 @@ -0,0 +1,70 @@ +# $NetBSD: varmod-edge.mk,v 1.1 2019/11/30 00:38:51 rillig Exp $ +# +# Tests for edge cases in variable modifiers. +# +# These tests demonstrate the current implementation in small examples. +# They may contain surprising behavior. +# +# Each test consists of: +# - INP, the input to the test +# - MOD, the expression for testing the modifier +# - EXP, the expected output + +TESTS+= M-paren +INP.M-paren= (parentheses) {braces} (opening closing) () +MOD.M-paren= ${INP.M-paren:M(*)} +EXP.M-paren= (parentheses) () + +# The first closing brace matches the opening parenthesis. +# The second closing brace actually ends the variable expression. +# +# XXX: This is unexpected but rarely occurs in practice. +TESTS+= M-mixed +INP.M-mixed= (paren-brace} ( +MOD.M-mixed= ${INP.M-mixed:M(*}} +EXP.M-mixed= (paren-brace} + +# When the :M and :N modifiers are parsed, the pattern finishes as soon +# as open_parens + open_braces == closing_parens + closing_braces. This +# means that ( and } form a matching pair. +# +# Nested variable expressions are not parsed as such. Instead, only the +# parentheses and braces are counted. This leads to a parse error since +# the nested expression is not "${:U*)}" but only "${:U*)", which is +# missing the closing brace. The expression is evaluated anyway. +# The final brace in the output comes from the end of M.nest-mix. +# +# XXX: This is unexpected but rarely occurs in practice. +TESTS+= M-nest-mix +INP.M-nest-mix= (parentheses) +MOD.M-nest-mix= ${INP.M-nest-mix:M${:U*)}} +EXP.M-nest-mix= (parentheses)} + +# In contrast to parentheses and braces, the brackets are not counted +# when the :M modifier is parsed since Makefile variables only take the +# ${VAR} or $(VAR) forms, but not $[VAR]. +# +# The final ] in the pattern is needed to close the character class. +TESTS+= M-nest-brk +INP.M-nest-brk= [ [[ [[[ +MOD.M-nest-brk= ${INP.M-nest-brk:M${:U[[[[[]}} +EXP.M-nest-brk= [ + +# The pattern in the nested variable has an unclosed character class. +# No error is reported though, and the pattern is closed implicitly. +# +# XXX: It is unexpected that no error is reported. +TESTS+= M-pat-err +INP.M-pat-err= [ [[ [[[ +MOD.M-pat-err= ${INP.M-pat-err:M${:U[[}} +EXP.M-pat-err= [ + +all: +.for test in ${TESTS} +. if ${MOD.${test}} == ${EXP.${test}} + @printf 'ok %s\n' ${test:Q}'' +. else + @printf 'error in %s: expected %s, got %s\n' \ + ${test:Q}'' ${EXP.${test}:Q}'' ${MOD.${test}:Q}'' +. endif +.endfor