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