Module Name:    src
Committed By:   rillig
Date:           Mon Jul 20 19:53:40 UTC 2020

Modified Files:
        src/usr.bin/make: nonints.h var.c
        src/usr.bin/make/unit-tests: modmisc.exp

Log Message:
make(1): fix edge cases with $ at the end of the :@ modifier

In both parts of the :@ modifier, by passing &pflags to
ParseModifierPart, a final $ was interpreted as an anchor, which only
makes sense in the :S and :C modifiers.

This edge case is neither used by src nor by pkgsrc, except for the unit
tests that have been adjusted.


To generate a diff of this commit:
cvs rdiff -u -r1.81 -r1.82 src/usr.bin/make/nonints.h
cvs rdiff -u -r1.286 -r1.287 src/usr.bin/make/var.c
cvs rdiff -u -r1.22 -r1.23 src/usr.bin/make/unit-tests/modmisc.exp

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/nonints.h
diff -u src/usr.bin/make/nonints.h:1.81 src/usr.bin/make/nonints.h:1.82
--- src/usr.bin/make/nonints.h:1.81	Mon Jul 20 18:12:48 2020
+++ src/usr.bin/make/nonints.h	Mon Jul 20 19:53:40 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nonints.h,v 1.81 2020/07/20 18:12:48 sjg Exp $	*/
+/*	$NetBSD: nonints.h,v 1.82 2020/07/20 19:53:40 rillig Exp $	*/
 
 /*-
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -179,9 +179,14 @@ void Targ_Propagate_Wait(void);
 /* var.c */
 
 typedef enum {
-	VARE_UNDEFERR = 1,
-	VARE_WANTRES = 2,
-	VARE_ASSIGN = 4
+    /* Treat undefined variables as errors. */
+    VARE_UNDEFERR	= 0x01,
+    /* Actually evaluate the text, fully expanding variables.
+     * Without this flag, the text is only parsed but not evaluated. */
+    VARE_WANTRES	= 0x02,
+    VARE_ASSIGN		= 0x04,
+    /* Return the literal text, without expanding variables. */
+    VARE_NOSUBST	= 0x08
 } VarEvalFlags;
 
 void Var_Delete(const char *, GNode *);

Index: src/usr.bin/make/var.c
diff -u src/usr.bin/make/var.c:1.286 src/usr.bin/make/var.c:1.287
--- src/usr.bin/make/var.c:1.286	Mon Jul 20 18:12:48 2020
+++ src/usr.bin/make/var.c	Mon Jul 20 19:53:40 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: var.c,v 1.286 2020/07/20 18:12:48 sjg Exp $	*/
+/*	$NetBSD: var.c,v 1.287 2020/07/20 19:53:40 rillig Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -69,14 +69,14 @@
  */
 
 #ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: var.c,v 1.286 2020/07/20 18:12:48 sjg Exp $";
+static char rcsid[] = "$NetBSD: var.c,v 1.287 2020/07/20 19:53:40 rillig Exp $";
 #else
 #include <sys/cdefs.h>
 #ifndef lint
 #if 0
 static char sccsid[] = "@(#)var.c	8.3 (Berkeley) 3/19/94";
 #else
-__RCSID("$NetBSD: var.c,v 1.286 2020/07/20 18:12:48 sjg Exp $");
+__RCSID("$NetBSD: var.c,v 1.287 2020/07/20 19:53:40 rillig Exp $");
 #endif
 #endif /* not lint */
 #endif
@@ -241,11 +241,7 @@ typedef enum {
     VARP_SUB_ONE	= 0x02,	/* Apply substitution to one word */
     VARP_SUB_MATCHED	= 0x04,	/* There was a match */
     VARP_MATCH_START	= 0x08,	/* Match at start of word */
-    VARP_MATCH_END	= 0x10,	/* Match at end of word */
-
-    /* FIXME: This constant doesn't belong here.
-     * It is not related to pattern matching. */
-    VAR_NOSUBST	= 0x20		/* don't expand vars in ParseModifierPart */
+    VARP_MATCH_END	= 0x10	/* Match at end of word */
 } VarPatternFlags;
 
 typedef enum {
@@ -1879,7 +1875,7 @@ VarRange(const char *str, int ac)
 /*-
  * Parse a text part of a modifier such as the "from" and "to" in :S/from/to/
  * or the :@ modifier. Nested variables in the text are expanded unless
- * VAR_NOSUBST is set.
+ * VARE_NOSUBST is set.
  *
  * The text part is parsed until the next delimiter.  To escape the delimiter,
  * a backslash or a dollar, put a backslash before it.
@@ -1930,8 +1926,7 @@ ParseModifierPart(GNode *ctxt, const cha
 		     */
 		    *mpflags |= VARP_MATCH_END;
 	    } else {
-		/* FIXME: mismatch between mpflags and VAR_NOSUBST */
-		if (mpflags == NULL || !(*mpflags & VAR_NOSUBST)) {
+		if (!(eflags & VARE_NOSUBST)) {
 		    char   *cp2;
 		    int     len;
 		    void   *freeIt;
@@ -2166,17 +2161,16 @@ typedef struct {
 static Boolean
 ApplyModifier_At(ApplyModifiersState *st) {
     VarLoop loop;
-    VarPatternFlags pflags = VAR_NOSUBST; /* FIXME: mismatch between pflags and VAR_NOSUBST */
 
     st->cp = ++st->tstr;
     st->delim = '@';
     loop.tvar = ParseModifierPart(
-	st->ctxt, &st->cp, st->delim, st->eflags, &pflags, NULL, NULL);
+	st->ctxt, &st->cp, st->delim, st->eflags | VARE_NOSUBST, NULL, NULL, NULL);
     if (loop.tvar == NULL)
 	return FALSE;
 
     loop.str = ParseModifierPart(
-	st->ctxt, &st->cp, st->delim, st->eflags, &pflags, NULL, NULL);
+	st->ctxt, &st->cp, st->delim, st->eflags | VARE_NOSUBST, NULL, NULL, NULL);
     if (loop.str == NULL)
 	return FALSE;
 
@@ -2942,8 +2936,6 @@ ApplyModifier_Assign(ApplyModifiersState
 	return 'd';		/* "::<unrecognised>" */
 
     GNode *v_ctxt;		/* context where v belongs */
-    VarPatternFlags pflags;
-    /* FIXME: Assign has nothing to do with VarPatternFlags */
 
     if (st->v->name[0] == 0)
 	return 'b';
@@ -2977,9 +2969,9 @@ ApplyModifier_Assign(ApplyModifiersState
     }
     st->delim = st->startc == PROPEN ? PRCLOSE : BRCLOSE;
 
-    pflags = (st->eflags & VARE_WANTRES) ? 0 : VAR_NOSUBST;
-    char *val = ParseModifierPart(st->ctxt, &st->cp, st->delim, st->eflags,
-				  &pflags, NULL, NULL);
+    VarEvalFlags eflags = (st->eflags & VARE_WANTRES) ? 0 : VARE_NOSUBST;
+    char *val = ParseModifierPart(st->ctxt, &st->cp, st->delim,
+				  st->eflags | eflags, NULL, NULL, NULL);
     if (st->v->flags & VAR_JUNK) {
 	/* restore original name */
 	free(st->v->name);

Index: src/usr.bin/make/unit-tests/modmisc.exp
diff -u src/usr.bin/make/unit-tests/modmisc.exp:1.22 src/usr.bin/make/unit-tests/modmisc.exp:1.23
--- src/usr.bin/make/unit-tests/modmisc.exp:1.22	Mon Jul 20 19:03:25 2020
+++ src/usr.bin/make/unit-tests/modmisc.exp	Mon Jul 20 19:53:40 2020
@@ -33,7 +33,7 @@ make: Unclosed substitution for  (, miss
 :+one+ +two+ +three+:
 mod-at-resolve:w1d2d3w w2i3w w1i2d3 2i${RES3}w w1d2d3 2i${RES3} 1i${RES2}w:
 mod-at-dollar:(1) (2) (3).
-mod-at-dollar:(1) (2) (3).
+mod-at-dollar:() () ().
 mod-at-dollar:() () ().
 mod-subst-dollar:$1:
 mod-subst-dollar:$2:
@@ -46,11 +46,11 @@ mod-subst-dollar:$8:
 mod-subst-dollar:U8:
 mod-subst-dollar:$$$$:
 mod-loop-dollar:1:
-mod-loop-dollar:${word}:
+mod-loop-dollar:${word}$:
 mod-loop-dollar:$3$:
-mod-loop-dollar:$${word}$:
+mod-loop-dollar:$${word}$$:
 mod-loop-dollar:$$5$$:
-mod-loop-dollar:$$${word}$$:
+mod-loop-dollar:$$${word}$$$:
 mod-C-limits:00-ok:1 2323 45456
 make: No subexpression \1
 make: No subexpression \1

Reply via email to