Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.bin/make make: document ExprLen, which is part of a .for...
details: https://anonhg.NetBSD.org/src/rev/9fcd686003d7
branches: trunk
changeset: 366760:9fcd686003d7
user: rillig <rillig%NetBSD.org@localhost>
date: Sun Jun 12 16:09:21 2022 +0000
description:
make: document ExprLen, which is part of a .for loop
No binary change
diffstat:
usr.bin/make/for.c | 13 +++-
usr.bin/make/unit-tests/directive-for-escape.exp | 67 +++++++++++++----------
usr.bin/make/unit-tests/directive-for-escape.mk | 59 +++++++++++++++-----
3 files changed, 91 insertions(+), 48 deletions(-)
diffs (243 lines):
diff -r da041efb03ca -r 9fcd686003d7 usr.bin/make/for.c
--- a/usr.bin/make/for.c Sun Jun 12 15:08:38 2022 +0000
+++ b/usr.bin/make/for.c Sun Jun 12 16:09:21 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: for.c,v 1.167 2022/02/04 23:22:19 rillig Exp $ */
+/* $NetBSD: for.c,v 1.168 2022/06/12 16:09:21 rillig Exp $ */
/*
* Copyright (c) 1992, The Regents of the University of California.
@@ -58,7 +58,7 @@
#include "make.h"
/* "@(#)for.c 8.1 (Berkeley) 6/6/93" */
-MAKE_RCSID("$NetBSD: for.c,v 1.167 2022/02/04 23:22:19 rillig Exp $");
+MAKE_RCSID("$NetBSD: for.c,v 1.168 2022/06/12 16:09:21 rillig Exp $");
typedef struct ForLoop {
@@ -269,7 +269,14 @@
return true;
}
-
+/*
+ * When the body of a '.for i' loop is prepared for an iteration, each
+ * occurrence of $i in the body is replaced with ${:U...}, inserting the
+ * value of the item. If this item contains a '$', it may be the start of a
+ * variable expression. This expression is copied verbatim, its length is
+ * determined here, in a rather naive way, ignoring escape characters and
+ * funny delimiters in modifiers like ':S}from}to}'.
+ */
static size_t
ExprLen(const char *s, const char *e)
{
diff -r da041efb03ca -r 9fcd686003d7 usr.bin/make/unit-tests/directive-for-escape.exp
--- a/usr.bin/make/unit-tests/directive-for-escape.exp Sun Jun 12 15:08:38 2022 +0000
+++ b/usr.bin/make/unit-tests/directive-for-escape.exp Sun Jun 12 16:09:21 2022 +0000
@@ -26,30 +26,37 @@
make: "directive-for-escape.mk" line 43: value-with-modifier
For: end for 1
For: loop body:
+# ${:U\${UNDEF\:U\\$\\$}
+For: loop body:
+# ${:U{{\}\}}
+For: loop body:
+# ${:Uend\}}
+For: end for 1
+For: loop body:
. info ${:U\${UNDEF\:U\\$\\$}
-make: "directive-for-escape.mk" line 72: ${UNDEF:U\backslash$
+make: "directive-for-escape.mk" line 92: ${UNDEF:U\backslash$
For: loop body:
. info ${:U{{\}\}}
-make: "directive-for-escape.mk" line 72: {{}}
+make: "directive-for-escape.mk" line 92: {{}}
For: loop body:
. info ${:Uend\}}
-make: "directive-for-escape.mk" line 72: end}
+make: "directive-for-escape.mk" line 92: end}
For: end for 1
For: loop body:
. info ${:Ubegin<${UNDEF:Ufallback:N{{{}}}}>end}
-make: "directive-for-escape.mk" line 84: begin<fallback>end
+make: "directive-for-escape.mk" line 113: begin<fallback>end
For: end for 1
For: loop body:
. info ${:U\$}
-make: "directive-for-escape.mk" line 92: $
+make: "directive-for-escape.mk" line 121: $
For: end for 1
For: loop body:
. info ${NUMBERS} ${:Ureplaced}
-make: "directive-for-escape.mk" line 100: one two three replaced
+make: "directive-for-escape.mk" line 129: one two three replaced
For: end for 1
For: loop body:
. info ${:Ureplaced}
-make: "directive-for-escape.mk" line 110: replaced
+make: "directive-for-escape.mk" line 139: replaced
For: end for 1
For: loop body:
. info . $$i: ${:Uinner}
@@ -62,46 +69,46 @@
. info . $${i2}: ${i2}
. info . $${i,}: ${i,}
. info . adjacent: ${:Uinner}${:Uinner}${:Uinner:M*}${:Uinner}
-make: "directive-for-escape.mk" line 118: . $i: inner
-make: "directive-for-escape.mk" line 119: . ${i}: inner
-make: "directive-for-escape.mk" line 120: . ${i:M*}: inner
-make: "directive-for-escape.mk" line 121: . $(i): inner
-make: "directive-for-escape.mk" line 122: . $(i:M*): inner
-make: "directive-for-escape.mk" line 123: . ${i${:U}}: outer
-make: "directive-for-escape.mk" line 124: . ${i\}}: inner}
-make: "directive-for-escape.mk" line 125: . ${i2}: two
-make: "directive-for-escape.mk" line 126: . ${i,}: comma
-make: "directive-for-escape.mk" line 127: . adjacent: innerinnerinnerinner
+make: "directive-for-escape.mk" line 147: . $i: inner
+make: "directive-for-escape.mk" line 148: . ${i}: inner
+make: "directive-for-escape.mk" line 149: . ${i:M*}: inner
+make: "directive-for-escape.mk" line 150: . $(i): inner
+make: "directive-for-escape.mk" line 151: . $(i:M*): inner
+make: "directive-for-escape.mk" line 152: . ${i${:U}}: outer
+make: "directive-for-escape.mk" line 153: . ${i\}}: inner}
+make: "directive-for-escape.mk" line 154: . ${i2}: two
+make: "directive-for-escape.mk" line 155: . ${i,}: comma
+make: "directive-for-escape.mk" line 156: . adjacent: innerinnerinnerinner
For: end for 1
For: loop body:
. info eight $$$$$$$$ and no cents.
. info eight ${:Udollar}${:Udollar}${:Udollar}${:Udollar} and no cents.
-make: "directive-for-escape.mk" line 135: eight $$$$ and no cents.
-make: "directive-for-escape.mk" line 136: eight dollardollardollardollar and no cents.
-make: "directive-for-escape.mk" line 145: eight and no cents.
+make: "directive-for-escape.mk" line 164: eight $$$$ and no cents.
+make: "directive-for-escape.mk" line 165: eight dollardollardollardollar and no cents.
+make: "directive-for-escape.mk" line 174: eight and no cents.
For: end for 1
-make: "directive-for-escape.mk" line 152: newline in .for value
-make: "directive-for-escape.mk" line 152: newline in .for value
+make: "directive-for-escape.mk" line 181: newline in .for value
+make: "directive-for-escape.mk" line 181: newline in .for value
For: loop body:
. info short: ${:U" "}
. info long: ${:U" "}
-make: "directive-for-escape.mk" line 153: short: " "
-make: "directive-for-escape.mk" line 154: long: " "
+make: "directive-for-escape.mk" line 182: short: " "
+make: "directive-for-escape.mk" line 183: long: " "
For: end for 1
For: loop body:
For: end for 1
-Parse_PushInput: .for loop in directive-for-escape.mk, line 167
-make: "directive-for-escape.mk" line 167: newline in .for value
- in .for loop from directive-for-escape.mk:167 with i = "
+Parse_PushInput: .for loop in directive-for-escape.mk, line 196
+make: "directive-for-escape.mk" line 196: newline in .for value
+ in .for loop from directive-for-escape.mk:196 with i = "
"
For: loop body:
: ${:U" "}
SetFilenameVars: ${.PARSEDIR} = <some-dir> ${.PARSEFILE} = `directive-for-escape.mk'
-Parsing line 168: : ${:U" "}
+Parsing line 197: : ${:U" "}
ParseDependency(: " ")
-ParseEOF: returning to file directive-for-escape.mk, line 170
+ParseEOF: returning to file directive-for-escape.mk, line 199
SetFilenameVars: ${.PARSEDIR} = <some-dir> ${.PARSEFILE} = `directive-for-escape.mk'
-Parsing line 170: .MAKEFLAGS: -d0
+Parsing line 199: .MAKEFLAGS: -d0
ParseDependency(.MAKEFLAGS: -d0)
For: end for 1
For: loop body:
diff -r da041efb03ca -r 9fcd686003d7 usr.bin/make/unit-tests/directive-for-escape.mk
--- a/usr.bin/make/unit-tests/directive-for-escape.mk Sun Jun 12 15:08:38 2022 +0000
+++ b/usr.bin/make/unit-tests/directive-for-escape.mk Sun Jun 12 16:09:21 2022 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: directive-for-escape.mk,v 1.15 2022/01/27 20:15:14 rillig Exp $
+# $NetBSD: directive-for-escape.mk,v 1.16 2022/06/12 16:09:21 rillig Exp $
#
# Test escaping of special characters in the iteration values of a .for loop.
# These values get expanded later using the :U variable modifier, and this
@@ -43,38 +43,67 @@
. info $i
.endfor
+
# Try to cover the code for nested '{}' in ExprLen, without success.
#
# The value of the variable VALUES is not meant to be a variable expression.
# Instead, it is meant to represent literal text, the only escaping mechanism
# being that each '$' is written as '$$'.
+VALUES= $${UNDEF:U\$$\$$ {{}} end}
#
# The .for loop splits ${VALUES} into 3 words, at the space characters, since
# the '$$' is an ordinary character and the spaces are not escaped.
# Word 1 is '${UNDEF:U\$\$'
# Word 2 is '{{}}'
# Word 3 is 'end}'
-# The first iteration expands the body of the .for loop to:
-# expect: . info ${:U\${UNDEF\:U\\$\\$}
-# The modifier ':U' unescapes the '\$' to a simple '$'.
-# The modifier ':U' unescapes the '\:' to a simple ':'.
-# The modifier ':U' unescapes the '\\' to a simple '\'.
-# The modifier ':U' resolves the expression '$\' to the word 'backslash', due
-# to the following variable definition.
+#
+# Each of these words is now inserted in the body of the .for loop.
+.for i in ${VALUES}
+# $i
+.endfor
+#
+# When these words are injected into the body of the .for loop, each inside a
+# '${:U...}' expression, the result is:
+#
+# expect: For: loop body:
+# expect: # ${:U\${UNDEF\:U\\$\\$}
+# expect: For: loop body:
+# expect: # ${:U{{\}\}}
+# expect: For: loop body:
+# expect: # ${:Uend\}}
+# expect: For: end for 1
+#
+# The first of these expressions is the most interesting one, due to its many
+# special characters. This expression is properly balanced:
+#
+# Text Meaning Explanation
+# \$ $ escaped
+# { { ordinary text
+# UNDEF UNDEF ordinary text
+# \: : escaped
+# U U ordinary text
+# \\ \ escaped
+# $\ (expr) an expression, the variable name is '\'
+# \$ $ escaped
+#
+# To make the expression '$\' visible, define it to an actual word:
${:U\\}= backslash
-# FIXME: There was no expression '$\' in the original text of the previous
-# line, that's a surprise in the parser.
-# The modifier ':U' unescapes the '\$' to a simple '$'.
-# expect+4: ${UNDEF:U\backslash$
-VALUES= $${UNDEF:U\$$\$$ {{}} end}
-# XXX: Where in the code does the '\$\$' get converted into a single '\$'?
.for i in ${VALUES}
. info $i
.endfor
+#
+# expect-3: ${UNDEF:U\backslash$
+# expect-4: {{}}
+# expect-5: end}
+#
+# FIXME: There was no expression '$\' in the original text of the variable
+# 'VALUES', that's a surprise in the parser.
+
# Second try to cover the code for nested '{}' in ExprLen.
#
-# XXX: It is wrong that ExprLen requires the braces to be balanced.
+# XXX: It is not the job of ExprLen to parse an expression, it is naive to
+# expect ExprLen to get all the details right in just a few lines of code.
# Each variable modifier has its own inconsistent way of parsing nested
# variable expressions, braces and parentheses. (Compare ':M', ':S', and
# ':D' for details.) The only sensible thing to do is therefore to let
Home |
Main Index |
Thread Index |
Old Index