Subject: make: make :P work as intended.
To: None <tech-toolchain@netbsd.org>
From: Simon J. Gerraty <sjg@crufty.net>
List: tech-toolchain
Date: 03/17/2006 10:43:10
I imported :P from ODE's make several years ago, and could never
satisfy myself that it worked as intended - indeed it appeared to be
broken in ODE ;-)

The idea is that if you have

foo:	one.c two.c three.c
	@echo one=${one.c:P}

should report the location of one.c as found via .PATH.
This behavior is useful in many situations... but never worked.
Using (for example) ${.ALLSRC:M*one.c} offered a workaround...

The patch below fixes that.  Now :P works as expected.

Also, documented a nasty quirk of := which can be seen with the
following makefile:

--------------------8<--------------------
# $Id: vund,v 1.1 2006/03/17 18:38:44 sjg Exp sjg $

# test behavior of := when a variable with modifiers is undefined

A=4
B=2
# note that anUndefinedVariable isn't defined
C=${anUndefinedVariable:S/e/3/}
# in C:S below we expect the substitution to apply to the content,
# not the modifiers being applied to anUndefinedVariable.
D= ${A}${B}${C:S,/,,}
# touble happens here - since := will skip expanding undefined vars
# and so the :S for C ends up applying to the modifiers for 
# anUndefinedVariable
E:= ${D}

all:
.if "${D}" == "${E}"
	@echo -n "Ok "
.endif
	@echo 'D=${D} E=$E'
--------------------8<--------------------

which produces

make: Unclosed substitution for anUndefinedVariable (e missing)
Ok make: Unclosed substitution for anUndefinedVariable (e missing)
D=42 E=42

Index: make.1
===================================================================
RCS file: /cvsroot/src/usr.bin/make/make.1,v
retrieving revision 1.123
diff -u -p -r1.123 make.1
--- make.1	11 Mar 2006 12:02:20 -0000	1.123
+++ make.1	17 Mar 2006 18:31:47 -0000
@@ -29,7 +29,7 @@
 .\"
 .\"	from: @(#)make.1	8.4 (Berkeley) 3/19/94
 .\"
-.Dd February 26, 2006
+.Dd March 17, 2006
 .Dt MAKE 1
 .Os
 .Sh NAME
@@ -417,6 +417,10 @@ Assign the value to the variable if it i
 Assign with expansion, i.e. expand the value before assigning it
 to the variable.
 Normally, expansion is not done until the variable is referenced.
+.Em NOTE :
+References to undefined variables are
+.Em not
+expanded.  This can cause problems when variable modifiers are used.
 .It Ic \&!=
 Expand the value and pass it to the shell for execution and assign
 the result to the variable.
Index: var.c
===================================================================
RCS file: /cvsroot/src/usr.bin/make/var.c,v
retrieving revision 1.102
diff -u -p -r1.102 var.c
--- var.c	26 Feb 2006 21:43:00 -0000	1.102
+++ var.c	17 Mar 2006 18:31:48 -0000
@@ -133,6 +133,7 @@ __RCSID("$NetBSD: var.c,v 1.102 2006/02/
 
 #include    "make.h"
 #include    "buf.h"
+#include    "dir.h"
 
 /*
  * This is a harmless return value for Var_Parse that can be used by Var_Subst
@@ -2467,10 +2468,16 @@ Var_Parse(const char *str, GNode *ctxt, 
 		    if ((v->flags & VAR_JUNK) != 0)
 			v->flags |= VAR_KEEP;
 		    gn = Targ_FindNode(v->name, TARG_NOCREATE);
-		    if (gn == NILGNODE || gn->path == NULL)
-			newStr = strdup(v->name);
-		    else
+		    if (gn == NILGNODE || gn->type & OP_NOPATH) {
+			newStr = NULL;
+		    } else if (gn->path) {
 			newStr = strdup(gn->path);
+		    } else {
+			newStr = Dir_FindFile(v->name, Suff_FindPath(gn));
+		    }
+		    if (!newStr) {
+			newStr = strdup(v->name);
+		    }
 		    cp = ++tstr;
 		    termc = *tstr;
 		    break;