Wed Jul 29 19:48:33 2020 UTC ()
make(1): add enough tests to cover the ApplyModifier functions

Only a few return statements are still missing from the code coverage.

In ApplyModifier_Assign, the test for an empty variable name is skipped
for now since it segfaults.

In ApplyModifier_SysV after the second ParseModifierPart, the branch for
the missing delimiter is not reached since this case is already checked
for in the first part of the function. To trigger this branch, a
specially crafted, unrealistic string needs to be created, and that's too
complicated for the moment.


(rillig)
diff -r1.353 -r1.354 src/usr.bin/make/var.c
diff -r1.75 -r1.76 src/usr.bin/make/unit-tests/Makefile
diff -r1.7 -r1.8 src/usr.bin/make/unit-tests/moderrs.exp
diff -r1.6 -r1.7 src/usr.bin/make/unit-tests/moderrs.mk

cvs diff -r1.353 -r1.354 src/usr.bin/make/var.c (expand / switch to unified diff)

--- src/usr.bin/make/var.c 2020/07/28 17:18:40 1.353
+++ src/usr.bin/make/var.c 2020/07/29 19:48:33 1.354
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: var.c,v 1.353 2020/07/28 17:18:40 rillig Exp $ */ 1/* $NetBSD: var.c,v 1.354 2020/07/29 19:48:33 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1988, 1989, 1990, 1993 4 * Copyright (c) 1988, 1989, 1990, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * Adam de Boor. 8 * Adam de Boor.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -59,34 +59,34 @@ @@ -59,34 +59,34 @@
59 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 59 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
60 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 60 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
61 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 61 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
62 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 62 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
68 * SUCH DAMAGE. 68 * SUCH DAMAGE.
69 */ 69 */
70 70
71#ifndef MAKE_NATIVE 71#ifndef MAKE_NATIVE
72static char rcsid[] = "$NetBSD: var.c,v 1.353 2020/07/28 17:18:40 rillig Exp $"; 72static char rcsid[] = "$NetBSD: var.c,v 1.354 2020/07/29 19:48:33 rillig Exp $";
73#else 73#else
74#include <sys/cdefs.h> 74#include <sys/cdefs.h>
75#ifndef lint 75#ifndef lint
76#if 0 76#if 0
77static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94"; 77static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94";
78#else 78#else
79__RCSID("$NetBSD: var.c,v 1.353 2020/07/28 17:18:40 rillig Exp $"); 79__RCSID("$NetBSD: var.c,v 1.354 2020/07/29 19:48:33 rillig Exp $");
80#endif 80#endif
81#endif /* not lint */ 81#endif /* not lint */
82#endif 82#endif
83 83
84/*- 84/*-
85 * var.c -- 85 * var.c --
86 * Variable-handling functions 86 * Variable-handling functions
87 * 87 *
88 * Interface: 88 * Interface:
89 * Var_Set Set the value of a variable in the given 89 * Var_Set Set the value of a variable in the given
90 * context. The variable is created if it doesn't 90 * context. The variable is created if it doesn't
91 * yet exist. 91 * yet exist.
92 * 92 *
@@ -2513,27 +2513,27 @@ ApplyModifier_Regex(const char *mod, App @@ -2513,27 +2513,27 @@ ApplyModifier_Regex(const char *mod, App
2513#endif 2513#endif
2514 2514
2515static void 2515static void
2516ModifyWord_Copy(const char *word, SepBuf *buf, void *data MAKE_ATTR_UNUSED) 2516ModifyWord_Copy(const char *word, SepBuf *buf, void *data MAKE_ATTR_UNUSED)
2517{ 2517{
2518 SepBuf_AddStr(buf, word); 2518 SepBuf_AddStr(buf, word);
2519} 2519}
2520 2520
2521/* :ts<separator> */ 2521/* :ts<separator> */
2522static Boolean 2522static Boolean
2523ApplyModifier_ToSep(const char *sep, ApplyModifiersState *st) 2523ApplyModifier_ToSep(const char *sep, ApplyModifiersState *st)
2524{ 2524{
2525 if (sep[0] != st->endc && (sep[1] == st->endc || sep[1] == ':')) { 2525 if (sep[0] != st->endc && (sep[1] == st->endc || sep[1] == ':')) {
2526 /* ":ts<unrecognised><endc>" or ":ts<unrecognised>:" */ 2526 /* ":ts<any><endc>" or ":ts<any>:" */
2527 st->sep = sep[0]; 2527 st->sep = sep[0];
2528 st->next = sep + 1; 2528 st->next = sep + 1;
2529 } else if (sep[0] == st->endc || sep[0] == ':') { 2529 } else if (sep[0] == st->endc || sep[0] == ':') {
2530 /* ":ts<endc>" or ":ts:" */ 2530 /* ":ts<endc>" or ":ts:" */
2531 st->sep = '\0'; /* no separator */ 2531 st->sep = '\0'; /* no separator */
2532 st->next = sep; 2532 st->next = sep;
2533 } else if (sep[0] == '\\') { 2533 } else if (sep[0] == '\\') {
2534 const char *xp = sep + 1; 2534 const char *xp = sep + 1;
2535 int base = 8; /* assume octal */ 2535 int base = 8; /* assume octal */
2536 2536
2537 switch (sep[1]) { 2537 switch (sep[1]) {
2538 case 'n': 2538 case 'n':
2539 st->sep = '\n'; 2539 st->sep = '\n';

cvs diff -r1.75 -r1.76 src/usr.bin/make/unit-tests/Makefile (expand / switch to unified diff)

--- src/usr.bin/make/unit-tests/Makefile 2020/07/28 22:44:44 1.75
+++ src/usr.bin/make/unit-tests/Makefile 2020/07/29 19:48:33 1.76
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1# $NetBSD: Makefile,v 1.75 2020/07/28 22:44:44 rillig Exp $ 1# $NetBSD: Makefile,v 1.76 2020/07/29 19:48:33 rillig Exp $
2# 2#
3# Unit tests for make(1) 3# Unit tests for make(1)
4# 4#
5# The main targets are: 5# The main targets are:
6# 6#
7# all: 7# all:
8# run all the tests 8# run all the tests
9# test: 9# test:
10# run 'all', and compare to expected results 10# run 'all', and compare to expected results
11# accept: 11# accept:
12# move generated output to expected results 12# move generated output to expected results
13# 13#
14# Settable variables 14# Settable variables
@@ -84,26 +84,27 @@ ENV.envfirst= FROM_ENV=value-from-env @@ -84,26 +84,27 @@ ENV.envfirst= FROM_ENV=value-from-env
84ENV.export= -i PATH=${PATH:Q} 84ENV.export= -i PATH=${PATH:Q}
85ENV.varmisc= FROM_ENV=env 85ENV.varmisc= FROM_ENV=env
86ENV.varmisc+= FROM_ENV_BEFORE=env 86ENV.varmisc+= FROM_ENV_BEFORE=env
87ENV.varmisc+= FROM_ENV_AFTER=env 87ENV.varmisc+= FROM_ENV_AFTER=env
88 88
89# Override make flags for some of the tests; default is -k. 89# Override make flags for some of the tests; default is -k.
90FLAGS.doterror= # none 90FLAGS.doterror= # none
91FLAGS.envfirst= -e 91FLAGS.envfirst= -e
92FLAGS.export= -r 92FLAGS.export= -r
93FLAGS.order= -j1 93FLAGS.order= -j1
94FLAGS.vardebug= -k -dv FROM_CMDLINE= 94FLAGS.vardebug= -k -dv FROM_CMDLINE=
95 95
96# Some tests need extra post-processing. 96# Some tests need extra post-processing.
 97SED_CMDS.moderrs+= -e 's,\(substitution error:\).*,\1 (details omitted),'
97SED_CMDS.modmisc+= -e 's,\(substitution error:\).*,\1 (details omitted),' 98SED_CMDS.modmisc+= -e 's,\(substitution error:\).*,\1 (details omitted),'
98SED_CMDS.varshell+= -e 's,^[a-z]*sh: ,,' 99SED_CMDS.varshell+= -e 's,^[a-z]*sh: ,,'
99SED_CMDS.varshell+= -e '/command/s,No such.*,not found,' 100SED_CMDS.varshell+= -e '/command/s,No such.*,not found,'
100 101
101# Some tests need an additional round of postprocessing. 102# Some tests need an additional round of postprocessing.
102POSTPROC.vardebug= ${TOOL_SED} -n -e '/:RELEVANT = yes/,/:RELEVANT = no/p' 103POSTPROC.vardebug= ${TOOL_SED} -n -e '/:RELEVANT = yes/,/:RELEVANT = no/p'
103 104
104# End of the configuration section. 105# End of the configuration section.
105 106
106.MAIN: all 107.MAIN: all
107 108
108UNIT_TESTS:= ${.PARSEDIR} 109UNIT_TESTS:= ${.PARSEDIR}
109.PATH: ${UNIT_TESTS} 110.PATH: ${UNIT_TESTS}

cvs diff -r1.7 -r1.8 src/usr.bin/make/unit-tests/moderrs.exp (expand / switch to unified diff)

--- src/usr.bin/make/unit-tests/moderrs.exp 2020/07/29 18:48:47 1.7
+++ src/usr.bin/make/unit-tests/moderrs.exp 2020/07/29 19:48:33 1.8
@@ -52,14 +52,86 @@ TheVariable @@ -52,14 +52,86 @@ TheVariable
52make: Unclosed variable specification (expecting '}') for "VAR" (value "TheVariable") modifier S 52make: Unclosed variable specification (expecting '}') for "VAR" (value "TheVariable") modifier S
531: TheVariable 531: TheVariable
54make: Unclosed substitution for VAR (, missing) 54make: Unclosed substitution for VAR (, missing)
552: 552:
56make: Unclosed substitution for VAR (, missing) 56make: Unclosed substitution for VAR (, missing)
573: 573:
58make: Unclosed substitution for VAR (, missing) 58make: Unclosed substitution for VAR (, missing)
59 59
60make: Unclosed substitution for VAR (, missing) 60make: Unclosed substitution for VAR (, missing)
61 61
62make: Unclosed variable specification (expecting '}') for "VAR" (value "TheVariable") modifier S 62make: Unclosed variable specification (expecting '}') for "VAR" (value "TheVariable") modifier S
63TheVariable 63TheVariable
64TheVariable 64TheVariable
 65mod-regex-delimiter:
 66make: RE substitution error: (details omitted)
 67make: Unclosed substitution for VAR (, missing)
 68echo
 69make: Unclosed substitution for VAR (, missing)
 70
 71make: Unclosed substitution for VAR (, missing)
 72
 73make: Unclosed substitution for VAR (, missing)
 74
 75make: Unclosed substitution for VAR (, missing)
 76
 77make: Unclosed variable specification (expecting '}') for "VAR" (value "TheVariable") modifier C
 78TheVariable
 79TheVariable
 80make: RE substitution error: (details omitted)
 811:
 82make: Unclosed substitution for VAR (, missing)
 832:
 84make: Unclosed substitution for VAR (, missing)
 853:
 86make: Unclosed substitution for VAR (, missing)
 87
 88make: Unclosed substitution for VAR (, missing)
 89
 90make: Unclosed variable specification (expecting '}') for "VAR" (value "TheVariable") modifier C
 91TheVariable
 92TheVariable
 93mod-ts-parse:
 94112358132134
 9515152535558513521534
 96make: Bad modifier `:ts\65oct' for FIB
 9765oct}
 98make: Bad modifier `:tsxy' for FIB
 99xy}
 100mod-t-parse:
 101make: Bad modifier `:txy' for FIB
 102y}
 103make: Bad modifier `:t' for FIB
 104
 105make: Bad modifier `:t' for FIB
 106M*}
 107mod-ifelse-parse:
 108make: Unclosed substitution for FIB (: missing)
 109
 110make: Unclosed substitution for FIB (: missing)
 111
 112make: Unclosed substitution for FIB (} missing)
 113
 114make: Unclosed substitution for FIB (} missing)
 115
 116then
 117mod-assign-parse:
 118make: Unknown modifier ':'
 119
 120make: Unclosed substitution for ASSIGN (} missing)
 121
 122mod-remember-parse:
 1231 1 2 3 5 8 13 21 34
 124make: Unknown modifier '_'
 125
 126mod-sysv-parse:
 127make: Unknown modifier '3'
 128make: Unclosed variable specification (expecting '}') for "FIB" (value "") modifier 3
 129
 130make: Unknown modifier '3'
 131make: Unclosed variable specification (expecting '}') for "FIB" (value "") modifier 3
 132
 133make: Unknown modifier '3'
 134make: Unclosed variable specification (expecting '}') for "FIB" (value "") modifier 3
 135
 1361 1 2 x3 5 8 1x3 21 34
65exit status 0 137exit status 0

cvs diff -r1.6 -r1.7 src/usr.bin/make/unit-tests/moderrs.mk (expand / switch to unified diff)

--- src/usr.bin/make/unit-tests/moderrs.mk 2020/07/29 18:48:47 1.6
+++ src/usr.bin/make/unit-tests/moderrs.mk 2020/07/29 19:48:33 1.7
@@ -1,28 +1,37 @@ @@ -1,28 +1,37 @@
1# $Id: moderrs.mk,v 1.6 2020/07/29 18:48:47 rillig Exp $ 1# $Id: moderrs.mk,v 1.7 2020/07/29 19:48:33 rillig Exp $
2# 2#
3# various modifier error tests 3# various modifier error tests
4 4
5VAR=TheVariable 5VAR=TheVariable
6# incase we have to change it ;-) 6# incase we have to change it ;-)
7MOD_UNKN=Z 7MOD_UNKN=Z
8MOD_TERM=S,V,v 8MOD_TERM=S,V,v
9MOD_S:= ${MOD_TERM}, 9MOD_S:= ${MOD_TERM},
10 10
 11FIB= 1 1 2 3 5 8 13 21 34
 12
11all: modunkn modunknV varterm vartermV modtermV modloop 13all: modunkn modunknV varterm vartermV modtermV modloop
12all: modloop-close 14all: modloop-close
13all: modwords 15all: modwords
14all: modexclam 16all: modexclam
15all: mod-subst-delimiter 17all: mod-subst-delimiter
 18all: mod-regex-delimiter
 19all: mod-ts-parse
 20all: mod-t-parse
 21all: mod-ifelse-parse
 22all: mod-assign-parse
 23all: mod-remember-parse
 24all: mod-sysv-parse
16 25
17modunkn: 26modunkn:
18 @echo "Expect: Unknown modifier 'Z'" 27 @echo "Expect: Unknown modifier 'Z'"
19 @echo "VAR:Z=${VAR:Z}" 28 @echo "VAR:Z=${VAR:Z}"
20 29
21modunknV: 30modunknV:
22 @echo "Expect: Unknown modifier 'Z'" 31 @echo "Expect: Unknown modifier 'Z'"
23 @echo "VAR:${MOD_UNKN}=${VAR:${MOD_UNKN}}" 32 @echo "VAR:${MOD_UNKN}=${VAR:${MOD_UNKN}}"
24 33
25varterm: 34varterm:
26 @echo "Expect: Unclosed variable specification for VAR" 35 @echo "Expect: Unclosed variable specification for VAR"
27 @echo VAR:S,V,v,=${VAR:S,V,v, 36 @echo VAR:S,V,v,=${VAR:S,V,v,
28 37
@@ -89,13 +98,72 @@ mod-subst-delimiter: @@ -89,13 +98,72 @@ mod-subst-delimiter:
89 @echo ${VAR:S, 98 @echo ${VAR:S,
90 @echo ${VAR:S,from 99 @echo ${VAR:S,from
91 @echo ${VAR:S,from, 100 @echo ${VAR:S,from,
92 @echo ${VAR:S,from,to 101 @echo ${VAR:S,from,to
93 @echo ${VAR:S,from,to, 102 @echo ${VAR:S,from,to,
94 @echo ${VAR:S,from,to,} 103 @echo ${VAR:S,from,to,}
95 @echo 1: ${VAR:S 104 @echo 1: ${VAR:S
96 @echo 2: ${VAR:S, 105 @echo 2: ${VAR:S,
97 @echo 3: ${VAR:S,from 106 @echo 3: ${VAR:S,from
98 @echo ${VAR:S,from, 107 @echo ${VAR:S,from,
99 @echo ${VAR:S,from,to 108 @echo ${VAR:S,from,to
100 @echo ${VAR:S,from,to, 109 @echo ${VAR:S,from,to,
101 @echo ${VAR:S,from,to,} 110 @echo ${VAR:S,from,to,}
 111
 112# XXX: Where does the "echo" in the output of "${VAR:C" come from?
 113mod-regex-delimiter:
 114 @echo $@:
 115 @echo ${VAR:C
 116 @echo ${VAR:C,
 117 @echo ${VAR:C,from
 118 @echo ${VAR:C,from,
 119 @echo ${VAR:C,from,to
 120 @echo ${VAR:C,from,to,
 121 @echo ${VAR:C,from,to,}
 122 @echo 1: ${VAR:C
 123 @echo 2: ${VAR:C,
 124 @echo 3: ${VAR:C,from
 125 @echo ${VAR:C,from,
 126 @echo ${VAR:C,from,to
 127 @echo ${VAR:C,from,to,
 128 @echo ${VAR:C,from,to,}
 129
 130mod-ts-parse:
 131 @echo $@:
 132 @echo ${FIB:ts}
 133 @echo ${FIB:ts\65} # octal 065 == U+0035 == '5'
 134 @echo ${FIB:ts\65oct} # bad modifier
 135 @echo ${FIB:tsxy} # modifier too long
 136
 137mod-t-parse:
 138 @echo $@:
 139 @echo ${FIB:txy}
 140 @echo ${FIB:t}
 141 @echo ${FIB:t:M*}
 142
 143mod-ifelse-parse:
 144 @echo $@:
 145 @echo ${FIB:?
 146 @echo ${FIB:?then
 147 @echo ${FIB:?then:
 148 @echo ${FIB:?then:else
 149 @echo ${FIB:?then:else}
 150
 151mod-assign-parse:
 152 @echo $@:
 153 @echo ${ASSIGN::x} # 'x' is an unknown assignment operator
 154# disabled for now; segfaults on NetBSD-8.0-x86_64 in Var_Parse line 3636:
 155# *lengthPtr = tstr - str + (*tstr ? 1 : 0);
 156# @echo ${::=value} # trying to set the empty variable
 157 @echo ${ASSIGN::=value # missing closing brace
 158
 159mod-remember-parse:
 160 @echo $@:
 161 @echo ${FIB:_} # ok
 162 @echo ${FIB:__} # modifier name too long
 163
 164mod-sysv-parse:
 165 @echo $@:
 166 @echo ${FIB:3
 167 @echo ${FIB:3=
 168 @echo ${FIB:3=x3
 169 @echo ${FIB:3=x3} # ok