Module Name:    src
Committed By:   rillig
Date:           Sat Nov  7 21:04:44 UTC 2020

Modified Files:
        src/usr.bin/make: for.c

Log Message:
make(1): clean up Buf_AddEscaped in .for loops

All this dance of determining the needed escape characters before
iterating, saving them upfront, evaluating them later using complicated
boolean expressions was not necessary at all.  All that is needed is a
simple NeedsEscapes, called at just the right time.


To generate a diff of this commit:
cvs rdiff -u -r1.114 -r1.115 src/usr.bin/make/for.c

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/for.c
diff -u src/usr.bin/make/for.c:1.114 src/usr.bin/make/for.c:1.115
--- src/usr.bin/make/for.c:1.114	Sat Nov  7 14:11:58 2020
+++ src/usr.bin/make/for.c	Sat Nov  7 21:04:43 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: for.c,v 1.114 2020/11/07 14:11:58 rillig Exp $	*/
+/*	$NetBSD: for.c,v 1.115 2020/11/07 21:04:43 rillig Exp $	*/
 
 /*
  * Copyright (c) 1992, The Regents of the University of California.
@@ -60,15 +60,7 @@
 #include "make.h"
 
 /*	"@(#)for.c	8.1 (Berkeley) 6/6/93"	*/
-MAKE_RCSID("$NetBSD: for.c,v 1.114 2020/11/07 14:11:58 rillig Exp $");
-
-/* The .for loop substitutes the items as ${:U<value>...}, which means
- * that characters that break this syntax must be backslash-escaped. */
-typedef enum ForEscapes {
-    FOR_SUB_ESCAPE_CHAR = 0x0001,
-    FOR_SUB_ESCAPE_BRACE = 0x0002,
-    FOR_SUB_ESCAPE_PAREN = 0x0004
-} ForEscapes;
+MAKE_RCSID("$NetBSD: for.c,v 1.115 2020/11/07 21:04:43 rillig Exp $");
 
 static int forLevel = 0;	/* Nesting level */
 
@@ -120,30 +112,6 @@ For_Free(For *f)
     free(f);
 }
 
-static ForEscapes
-GetEscapes(const char *word)
-{
-    const char *p;
-    ForEscapes escapes = 0;
-
-    for (p = word; *p != '\0'; p++) {
-	switch (*p) {
-	case ':':
-	case '$':
-	case '\\':
-	    escapes |= FOR_SUB_ESCAPE_CHAR;
-	    break;
-	case ')':
-	    escapes |= FOR_SUB_ESCAPE_PAREN;
-	    break;
-	case '}':
-	    escapes |= FOR_SUB_ESCAPE_BRACE;
-	    break;
-	}
-    }
-    return escapes;
-}
-
 static Boolean
 IsFor(const char *p)
 {
@@ -326,18 +294,30 @@ for_var_len(const char *var)
     return 0;
 }
 
+/* The .for loop substitutes the items as ${:U<value>...}, which means
+ * that characters that break this syntax must be backslash-escaped. */
+static Boolean
+NeedsEscapes(const char *word, char endc)
+{
+    const char *p;
+
+    for (p = word; *p != '\0'; p++) {
+	if (*p == ':' || *p == '$' || *p == '\\' || *p == endc)
+	    return TRUE;
+    }
+    return FALSE;
+}
+
 /* While expanding the body of a .for loop, write the item in the ${:U...}
- * expression, escaping characters as needed. See ApplyModifier_Defined. */
+ * expression, escaping characters as needed.
+ *
+ * The result is later unescaped by ApplyModifier_Defined. */
 static void
 Buf_AddEscaped(Buffer *cmds, const char *item, char ech)
 {
-    ForEscapes escapes = GetEscapes(item);
     char ch;
 
-    /* If there were no escapes, or the only escape is the other variable
-     * terminator, then just substitute the full string */
-    if (!(escapes & (ech == ')' ? ~(unsigned)FOR_SUB_ESCAPE_BRACE
-				: ~(unsigned)FOR_SUB_ESCAPE_PAREN))) {
+    if (!NeedsEscapes(item, ech)) {
 	Buf_AddStr(cmds, item);
 	return;
     }

Reply via email to