Module Name: src Committed By: rillig Date: Tue May 9 16:27:00 UTC 2023
Modified Files: src/usr.bin/make: var.c src/usr.bin/make/unit-tests: var-eval-short.exp var-eval-short.mk varmod-gmtime.exp varmod-gmtime.mk varmod-localtime.exp varmod-localtime.mk Log Message: make: allow ':gmtime' and ':localtime' with dynamic argument This allows ${%Y:L:gmtime=${mtime}} instead of the indirect ${%Y:L:${:Ugmtime=${mtime}}}. The direct form also prevents any ':' from the nested expression to be interpreted as a separator, which doesn't matter for the ':gmtime' and ':localtime' modifiers but will prove useful for other modifiers that follow the same pattern. To generate a diff of this commit: cvs rdiff -u -r1.1049 -r1.1050 src/usr.bin/make/var.c cvs rdiff -u -r1.21 -r1.22 src/usr.bin/make/unit-tests/var-eval-short.exp cvs rdiff -u -r1.8 -r1.9 src/usr.bin/make/unit-tests/var-eval-short.mk cvs rdiff -u -r1.13 -r1.14 src/usr.bin/make/unit-tests/varmod-gmtime.exp cvs rdiff -u -r1.11 -r1.12 src/usr.bin/make/unit-tests/varmod-gmtime.mk cvs rdiff -u -r1.10 -r1.11 src/usr.bin/make/unit-tests/varmod-localtime.exp cvs rdiff -u -r1.9 -r1.10 src/usr.bin/make/unit-tests/varmod-localtime.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/var.c diff -u src/usr.bin/make/var.c:1.1049 src/usr.bin/make/var.c:1.1050 --- src/usr.bin/make/var.c:1.1049 Tue Mar 28 14:39:31 2023 +++ src/usr.bin/make/var.c Tue May 9 16:26:59 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: var.c,v 1.1049 2023/03/28 14:39:31 rillig Exp $ */ +/* $NetBSD: var.c,v 1.1050 2023/05/09 16:26:59 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -139,7 +139,7 @@ #include "metachar.h" /* "@(#)var.c 8.3 (Berkeley) 3/19/94" */ -MAKE_RCSID("$NetBSD: var.c,v 1.1049 2023/03/28 14:39:31 rillig Exp $"); +MAKE_RCSID("$NetBSD: var.c,v 1.1050 2023/05/09 16:26:59 rillig Exp $"); /* * Variables are defined using one of the VAR=value assignments. Their @@ -2188,6 +2188,8 @@ ParseModifierPartBalanced(const char **p static bool ParseModifierPartSubst( const char **pp, + /* If true, parse up to but excluding the next ':' or ch->endc. */ + bool whole, char delim, VarEvalMode emode, ModChain *ch, @@ -2205,11 +2207,14 @@ ParseModifierPartSubst( ) { const char *p; + char end1, end2; p = *pp; LazyBuf_Init(part, p); - while (*p != '\0' && *p != delim) { + end1 = whole ? ':' : delim; + end2 = whole ? ch->endc : delim; + while (*p != '\0' && *p != end1 && *p != end2) { if (IsEscapedModifierPart(p, delim, subst)) { LazyBuf_Add(part, p[1]); p += 2; @@ -2231,15 +2236,15 @@ ParseModifierPartSubst( ParseModifierPartExpr(&p, part, ch, emode); } - if (*p != delim) { - *pp = p; + *pp = p; + if (*p != end1 && *p != end2) { Error("Unfinished modifier for \"%s\" ('%c' missing)", - ch->expr->name, delim); + ch->expr->name, end2); LazyBuf_Done(part); return false; } - - *pp = p + 1; + if (!whole) + (*pp)++; { Substring sub = LazyBuf_Get(part); @@ -2272,7 +2277,8 @@ ParseModifierPart( LazyBuf *part ) { - return ParseModifierPartSubst(pp, delim, emode, ch, part, NULL, NULL); + return ParseModifierPartSubst(pp, false, delim, emode, ch, part, + NULL, NULL); } MAKE_INLINE bool @@ -2568,11 +2574,23 @@ ApplyModifier_Time(const char **pp, ModC if (args[0] == '=') { const char *p = args + 1; - if (!TryParseTime(&p, &t)) { - Parse_Error(PARSE_FATAL, - "Invalid time value at \"%s\"", p); + LazyBuf buf; + if (!ParseModifierPartSubst(&p, true, '\0', ch->expr->emode, + ch, &buf, NULL, NULL)) return AMR_CLEANUP; - } + if (ModChain_ShouldEval(ch)) { + Substring arg = LazyBuf_Get(&buf); + const char *arg_p = arg.start; + if (!TryParseTime(&arg_p, &t) || arg_p != arg.end) { + Parse_Error(PARSE_FATAL, + "Invalid time value \"%.*s\"", + (int)Substring_Length(arg), arg.start); + LazyBuf_Done(&buf); + return AMR_CLEANUP; + } + } else + t = 0; + LazyBuf_Done(&buf); *pp = p; } else { t = 0; @@ -2862,13 +2880,13 @@ ApplyModifier_Subst(const char **pp, Mod (*pp)++; } - if (!ParseModifierPartSubst(pp, delim, ch->expr->emode, ch, &lhsBuf, - &args.pflags, NULL)) + if (!ParseModifierPartSubst(pp, + false, delim, ch->expr->emode, ch, &lhsBuf, &args.pflags, NULL)) return AMR_CLEANUP; args.lhs = LazyBuf_Get(&lhsBuf); - if (!ParseModifierPartSubst(pp, delim, ch->expr->emode, ch, &rhsBuf, - NULL, &args)) { + if (!ParseModifierPartSubst(pp, + false, delim, ch->expr->emode, ch, &rhsBuf, NULL, &args)) { LazyBuf_Done(&lhsBuf); return AMR_CLEANUP; } Index: src/usr.bin/make/unit-tests/var-eval-short.exp diff -u src/usr.bin/make/unit-tests/var-eval-short.exp:1.21 src/usr.bin/make/unit-tests/var-eval-short.exp:1.22 --- src/usr.bin/make/unit-tests/var-eval-short.exp:1.21 Sat Feb 18 11:16:09 2023 +++ src/usr.bin/make/unit-tests/var-eval-short.exp Tue May 9 16:27:00 2023 @@ -1,9 +1,5 @@ make: "var-eval-short.mk" line 44: In the :@ modifier of "", the variable name "${FAIL}" must not contain a dollar make: "var-eval-short.mk" line 44: Malformed conditional (0 && ${:Uword:@${FAIL}@expr@}) -make: "var-eval-short.mk" line 84: Invalid time value at "${FAIL}}" -make: "var-eval-short.mk" line 84: Malformed conditional (0 && ${:Uword:gmtime=${FAIL}}) -make: "var-eval-short.mk" line 98: Invalid time value at "${FAIL}}" -make: "var-eval-short.mk" line 98: Malformed conditional (0 && ${:Uword:localtime=${FAIL}}) CondParser_Eval: 0 && ${0:?${FAIL}then:${FAIL}else} Var_Parse: ${0:?${FAIL}then:${FAIL}else} (parse-only) Parsing modifier ${0:?...} @@ -12,7 +8,7 @@ Modifier part: "${FAIL}then" Var_Parse: ${FAIL}else} (parse-only) Modifier part: "${FAIL}else" Result of ${0:?${FAIL}then:${FAIL}else} is "" (parse-only, defined) -Parsing line 163: DEFINED= defined +Parsing line 165: DEFINED= defined Global: DEFINED = defined CondParser_Eval: 0 && ${DEFINED:L:?${FAIL}then:${FAIL}else} Var_Parse: ${DEFINED:L:?${FAIL}then:${FAIL}else} (parse-only) @@ -24,7 +20,7 @@ Modifier part: "${FAIL}then" Var_Parse: ${FAIL}else} (parse-only) Modifier part: "${FAIL}else" Result of ${DEFINED:?${FAIL}then:${FAIL}else} is "defined" (parse-only, regular) -Parsing line 166: .MAKEFLAGS: -d0 +Parsing line 168: .MAKEFLAGS: -d0 ParseDependency(.MAKEFLAGS: -d0) Global: .MAKEFLAGS = -r -k -d cpv -d Global: .MAKEFLAGS = -r -k -d cpv -d 0 Index: src/usr.bin/make/unit-tests/var-eval-short.mk diff -u src/usr.bin/make/unit-tests/var-eval-short.mk:1.8 src/usr.bin/make/unit-tests/var-eval-short.mk:1.9 --- src/usr.bin/make/unit-tests/var-eval-short.mk:1.8 Mon Dec 27 18:54:19 2021 +++ src/usr.bin/make/unit-tests/var-eval-short.mk Tue May 9 16:27:00 2023 @@ -1,4 +1,4 @@ -# $NetBSD: var-eval-short.mk,v 1.8 2021/12/27 18:54:19 rillig Exp $ +# $NetBSD: var-eval-short.mk,v 1.9 2023/05/09 16:27:00 rillig Exp $ # # Tests for each variable modifier to ensure that they only do the minimum # necessary computations. If the result of the expression is irrelevant, @@ -79,8 +79,9 @@ DEFINED= # defined .if 0 && ${:Uword:E} .endif -# As of 2021-03-14, the error 'Invalid time value: ${FAIL}}' is ok since -# ':gmtime' does not expand its argument. +# Before var.c 1.1050 from 2023-05-09, the ':gmtime' modifier produced the +# error message 'Invalid time value: ${FAIL}}' since it did not expand its +# argument. .if 0 && ${:Uword:gmtime=${FAIL}} .endif @@ -93,8 +94,9 @@ DEFINED= # defined .if 0 && ${value:L} .endif -# As of 2021-03-14, the error 'Invalid time value: ${FAIL}}' is ok since -# ':localtime' does not expand its argument. +# Before var.c 1.1050 from 2023-05-09, the ':localtime' modifier produced the +# error message 'Invalid time value: ${FAIL}}' since it did not expand its +# argument. .if 0 && ${:Uword:localtime=${FAIL}} .endif Index: src/usr.bin/make/unit-tests/varmod-gmtime.exp diff -u src/usr.bin/make/unit-tests/varmod-gmtime.exp:1.13 src/usr.bin/make/unit-tests/varmod-gmtime.exp:1.14 --- src/usr.bin/make/unit-tests/varmod-gmtime.exp:1.13 Tue May 9 08:26:14 2023 +++ src/usr.bin/make/unit-tests/varmod-gmtime.exp Tue May 9 16:27:00 2023 @@ -1,13 +1,13 @@ -make: "varmod-gmtime.mk" line 60: Invalid time value at "${:U1593536400}} != "mtime=11593536400}"" -make: "varmod-gmtime.mk" line 60: Malformed conditional (${%Y:L:gmtime=${:U1593536400}} != "mtime=11593536400}") -make: "varmod-gmtime.mk" line 70: Invalid time value at "-1} != """ +make: "varmod-gmtime.mk" line 70: Invalid time value "-1" make: "varmod-gmtime.mk" line 70: Malformed conditional (${:L:gmtime=-1} != "") -make: "varmod-gmtime.mk" line 79: Invalid time value at " 1} != """ +make: "varmod-gmtime.mk" line 79: Invalid time value " 1" make: "varmod-gmtime.mk" line 79: Malformed conditional (${:L:gmtime= 1} != "") -make: "varmod-gmtime.mk" line 125: Invalid time value at "10000000000000000000000000000000} != """ +make: "varmod-gmtime.mk" line 125: Invalid time value "10000000000000000000000000000000" make: "varmod-gmtime.mk" line 125: Malformed conditional (${:L:gmtime=10000000000000000000000000000000} != "") -make: "varmod-gmtime.mk" line 136: Invalid time value at "error} != """ +make: "varmod-gmtime.mk" line 136: Invalid time value "error" make: "varmod-gmtime.mk" line 136: Malformed conditional (${:L:gmtime=error} != "") +make: "varmod-gmtime.mk" line 145: Invalid time value "100000S,1970,bad," +make: "varmod-gmtime.mk" line 145: Malformed conditional (${%Y:L:gmtime=100000S,1970,bad,} != "bad") make: Fatal errors encountered -- cannot continue make: stopped in unit-tests exit status 1 Index: src/usr.bin/make/unit-tests/varmod-gmtime.mk diff -u src/usr.bin/make/unit-tests/varmod-gmtime.mk:1.11 src/usr.bin/make/unit-tests/varmod-gmtime.mk:1.12 --- src/usr.bin/make/unit-tests/varmod-gmtime.mk:1.11 Tue May 9 08:26:14 2023 +++ src/usr.bin/make/unit-tests/varmod-gmtime.mk Tue May 9 16:27:00 2023 @@ -1,4 +1,4 @@ -# $NetBSD: varmod-gmtime.mk,v 1.11 2023/05/09 08:26:14 rillig Exp $ +# $NetBSD: varmod-gmtime.mk,v 1.12 2023/05/09 16:27:00 rillig Exp $ # # Tests for the :gmtime variable modifier, which formats a timestamp # using strftime(3) in UTC. @@ -44,20 +44,20 @@ .endif -# As of 2020-08-16, it is not possible to pass the seconds via a -# variable expression. This is because parsing of the :gmtime -# modifier stops at the '$' and returns to ApplyModifiers. -# -# There, a colon would be skipped but not a dollar. -# Parsing therefore continues at the '$' of the ${:U159...}, looking -# for an ordinary variable modifier. -# -# At this point, the ${:U} is expanded and interpreted as a variable -# modifier, which results in the error message "Unknown modifier '1'". -# -# If ApplyModifier_Gmtime were to pass its argument through -# ParseModifierPart, this would work. -.if ${%Y:L:gmtime=${:U1593536400}} != "mtime=11593536400}" +# Before var.c 1.1050 from 2023-05-09, it was not possible to pass the +# seconds via a variable expression. +# delete me +# delete me +# delete me +# delete me +# delete me +# delete me +# delete me +# delete me +# delete me +# delete me +# delete me +.if ${%Y:L:gmtime=${:U1593536400}} != "2020" . error .endif @@ -139,7 +139,7 @@ . error .endif -# Before var.c 1.TODO from XXXX-XX-XX, the timestamp could be directly +# Before var.c 1.1050 from 2023-05-09, the timestamp could be directly # followed by the next modifier, without a ':' separator. This is the same # bug as for the ':L' and ':P' modifiers. .if ${%Y:L:gmtime=100000S,1970,bad,} != "bad" Index: src/usr.bin/make/unit-tests/varmod-localtime.exp diff -u src/usr.bin/make/unit-tests/varmod-localtime.exp:1.10 src/usr.bin/make/unit-tests/varmod-localtime.exp:1.11 --- src/usr.bin/make/unit-tests/varmod-localtime.exp:1.10 Tue May 9 08:26:14 2023 +++ src/usr.bin/make/unit-tests/varmod-localtime.exp Tue May 9 16:27:00 2023 @@ -1,13 +1,13 @@ -make: "varmod-localtime.mk" line 60: Invalid time value at "${:U1593536400}} != "mtime=11593536400}"" -make: "varmod-localtime.mk" line 60: Malformed conditional (${%Y:L:localtime=${:U1593536400}} != "mtime=11593536400}") -make: "varmod-localtime.mk" line 70: Invalid time value at "-1} != """ +make: "varmod-localtime.mk" line 70: Invalid time value "-1" make: "varmod-localtime.mk" line 70: Malformed conditional (${:L:localtime=-1} != "") -make: "varmod-localtime.mk" line 79: Invalid time value at " 1} != """ +make: "varmod-localtime.mk" line 79: Invalid time value " 1" make: "varmod-localtime.mk" line 79: Malformed conditional (${:L:localtime= 1} != "") -make: "varmod-localtime.mk" line 125: Invalid time value at "10000000000000000000000000000000} != """ +make: "varmod-localtime.mk" line 125: Invalid time value "10000000000000000000000000000000" make: "varmod-localtime.mk" line 125: Malformed conditional (${:L:localtime=10000000000000000000000000000000} != "") -make: "varmod-localtime.mk" line 136: Invalid time value at "error} != """ +make: "varmod-localtime.mk" line 136: Invalid time value "error" make: "varmod-localtime.mk" line 136: Malformed conditional (${:L:localtime=error} != "") +make: "varmod-localtime.mk" line 145: Invalid time value "100000S,1970,bad," +make: "varmod-localtime.mk" line 145: Malformed conditional (${%Y:L:localtime=100000S,1970,bad,} != "bad") make: Fatal errors encountered -- cannot continue make: stopped in unit-tests exit status 1 Index: src/usr.bin/make/unit-tests/varmod-localtime.mk diff -u src/usr.bin/make/unit-tests/varmod-localtime.mk:1.9 src/usr.bin/make/unit-tests/varmod-localtime.mk:1.10 --- src/usr.bin/make/unit-tests/varmod-localtime.mk:1.9 Tue May 9 08:26:14 2023 +++ src/usr.bin/make/unit-tests/varmod-localtime.mk Tue May 9 16:27:00 2023 @@ -1,4 +1,4 @@ -# $NetBSD: varmod-localtime.mk,v 1.9 2023/05/09 08:26:14 rillig Exp $ +# $NetBSD: varmod-localtime.mk,v 1.10 2023/05/09 16:27:00 rillig Exp $ # # Tests for the :localtime variable modifier, which formats a timestamp # using strftime(3) in local time. @@ -44,20 +44,20 @@ .endif -# As of 2020-08-16, it is not possible to pass the seconds via a -# variable expression. This is because parsing of the :localtime -# modifier stops at the '$' and returns to ApplyModifiers. -# -# There, a colon would be skipped but not a dollar. -# Parsing therefore continues at the '$' of the ${:U159...}, looking -# for an ordinary variable modifier. -# -# At this point, the ${:U} is expanded and interpreted as a variable -# modifier, which results in the error message "Unknown modifier '1'". -# -# If ApplyModifier_Localtime were to pass its argument through -# ParseModifierPart, this would work. -.if ${%Y:L:localtime=${:U1593536400}} != "mtime=11593536400}" +# Before var.c 1.1050 from 2023-05-09, it was not possible to pass the +# seconds via a variable expression. +# delete me +# delete me +# delete me +# delete me +# delete me +# delete me +# delete me +# delete me +# delete me +# delete me +# delete me +.if ${%Y:L:localtime=${:U1593536400}} != "2020" . error .endif @@ -139,7 +139,7 @@ . error .endif -# Before var.c 1.TODO from XXXX-XX-XX, the timestamp could be directly +# Before var.c 1.1050 from 2023-05-09, the timestamp could be directly # followed by the next modifier, without a ':' separator. This is the same # bug as for the ':L' and ':P' modifiers. .if ${%Y:L:localtime=100000S,1970,bad,} != "bad"