NetBSD Problem Report #15233
Received: (qmail 22917 invoked from network); 13 Jan 2002 14:23:48 -0000
Message-Id: <200201131423.JAA06315@Sparkle.Rodents.Montreal.QC.CA>
Date: Sun, 13 Jan 2002 09:23:45 -0500 (EST)
From: der Mouse <mouse@Rodents.Montreal.QC.CA>
Reply-To: mouse@Rodents.Montreal.QC.CA
To: gnats-bugs@gnats.netbsd.org
Subject: [dM] make: .if broken inside .for
X-Send-Pr-Version: 3.95
>Number: 15233
>Category: bin
>Synopsis: [dM] make: .if broken inside .for
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: bin-bug-people
>State: closed
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sun Jan 13 14:25:00 +0000 2002
>Closed-Date: Sun Dec 21 19:43:56 +0000 2008
>Last-Modified: Sun Dec 21 19:43:56 +0000 2008
>Originator: der Mouse
>Release: 1.4T, appears to be present in 1.5
>Organization:
Dis-
>Environment:
Any (noticed on SPARC 1.4T, verified present on i386 1.5)
>Description:
Attempting to use .if to test the control variable of a .for
loop breaks, complaining about "Malformed conditional". This
appears to be because the .if is replicated by the .for and the
variable expansion occurs then, before the .if is parsed; by
the time the conditional parser runs, there is no variable
reference left for it to notice, and it refuses to compare two
constant strings. This can be worked around with an empty
dummy variable, but it's ugly and shouldn't be necessary.
>How-To-Repeat:
% cat test.make
.PHONY: test
test:
.for x in one two three
.if $(x) == "one"
echo one
.else
echo default $(x)
.endif
.endfor
% make -n -f test.make
"test.make", line 1: Malformed conditional (one == "one")
"test.make", line 1: Need an operator
"test.make", line 3: if-less else
"test.make", line 3: Need an operator
"test.make", line 5: if-less endif
"test.make", line 5: Need an operator
"test.make", line 1: Malformed conditional (two == "one")
"test.make", line 1: Need an operator
"test.make", line 3: if-less else
"test.make", line 3: Need an operator
"test.make", line 5: if-less endif
"test.make", line 5: Need an operator
"test.make", line 1: Malformed conditional (three == "one")
"test.make", line 1: Need an operator
"test.make", line 3: if-less else
"test.make", line 3: Need an operator
"test.make", line 5: if-less endif
"test.make", line 5: Need an operator
Fatal errors encountered -- cannot continue
%
>Fix:
The empty variable workaround I referred to above looks like
this:
d=
.PHONY: test
test:
.for x in one two three
.if $(d)$(x) == "one"
echo one
.else
echo default $(x)
.endif
.endfor
I am working on this and expect to have a fix soon, by making
the conditional parser willing to compare two constant quoted
strings (which will make it work to use `.if "$(x)" == "one"',
perhaps not optimal, but better than nothing - as a side
effect, quoted LHSs will work outside .for loops as well).
This PR has two purposes; (1) ensure it doesn't get totally
forgotten if for any reason I don't have a fix as soon as I
expect and (2) provide something for searches to find if anyone
else runs into this and searches for related PRs.
/~\ The ASCII der Mouse
\ / Ribbon Campaign
X Against HTML mouse@rodents.montreal.qc.ca
/ \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B
>Release-Note:
>Audit-Trail:
From: der Mouse <mouse@Rodents.Montreal.QC.CA>
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: bin/15233: [dM] make: .if broken inside .for
Date: Sun, 13 Jan 2002 10:40:47 -0500 (EST)
Here's the patch I've developed. As the first line implies, this is
for cond.c 1.11; -current is 1.12. I've looked at cvs diff -r 1.11 -r
1.12 and the changes are nowhere near the code affected by this; patch
applies it cleanly except for line number offsets, and the offset is
exactly what it should be. (Indeed, I'd send the 1.12 diff except that
this is the one I've actually been able to test personally.)
/* $NetBSD: cond.c,v 1.11 1998/09/18 20:35:11 christos Exp $ */
--- OLD/usr.bin/make/cond.c Thu Jan 1 00:00:00 1970
+++ NEW/usr.bin/make/cond.c Thu Jan 1 00:00:00 1970
@@ -82,6 +82,8 @@
* T -> $(varspec) op value
* T -> $(varspec) == "string"
* T -> $(varspec) != "string"
+ * T -> "string" == "string"
+ * T -> "string" != "string"
* T -> ( E )
* T -> ! T
* op -> == | != | > | < | >= | <=
@@ -570,6 +572,60 @@
Buf_Destroy(buf, FALSE);
doFree = TRUE;
+ }
+
+ if (0) {
+ char *cp, *cp2;
+ int qt;
+ Buffer buf;
+ case '"':
+ /*
+ * Collect quoted lhs.
+ */
+
+ buf = Buf_Init(0);
+ qt = 1;
+
+ for (cp = &condExpr[qt];
+ (qt ? (*cp != '"')
+ : (strchr(" \t)", *cp) == NULL)) &&
+ (*cp != '\0'); cp++) {
+ if ((*cp == '\\') && (cp[1] != '\0')) {
+ /*
+ * Backslash escapes things -- skip over next
+ * character, if it exists.
+ */
+ cp++;
+ Buf_AddByte(buf, (Byte)*cp);
+ } else if (*cp == '$') {
+ int len;
+ Boolean freeIt;
+
+ cp2 = Var_Parse(cp, VAR_CMD, doEval,&len, &freeIt);
+ if (cp2 != var_Error) {
+ Buf_AddBytes(buf, strlen(cp2), (Byte *)cp2);
+ if (freeIt) {
+ free(cp2);
+ }
+ cp += len - 1;
+ } else {
+ Buf_AddByte(buf, (Byte)*cp);
+ }
+ } else {
+ Buf_AddByte(buf, (Byte)*cp);
+ }
+ }
+
+ /*
+ * At first blush we want to use qt?cp+1:cp here,
+ * but *cp is skippable either way.
+ */
+ condExpr = cp + 1;
+
+ Buf_AddByte(buf, (Byte)0);
+
+ lhs = (char *)Buf_GetAll(buf, (int *)0);
+ Buf_Destroy(buf, FALSE);
}
/*
/~\ The ASCII der Mouse
\ / Ribbon Campaign
X Against HTML mouse@rodents.montreal.qc.ca
/ \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B
From: David Laight <david@l8s.co.uk>
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: bin/15233: ([dM] make: .if broken inside .for)
Date: Sat, 29 Nov 2008 15:07:26 +0000
This happens because make only does a string comparison if the character
after .if is '$' or '"' - but the substition of the loop control variable
has already been done as part of the loop processing.
cond.c rev 1.48 will also detect the == (or !=) following and do a
comparison if present.
The .for loop handling needs fixing though :-)
David
--
David Laight: david@l8s.co.uk
State-Changed-From-To: open->closed
State-Changed-By: dsl@NetBSD.org
State-Changed-When: Sun, 21 Dec 2008 19:43:56 +0000
State-Changed-Why:
The way .for variables are substituted has been changed in for.c rev 1.40
so that the expansion is still a variable.
This makes a lot of things work in the expected way.
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.