Subject: bin/15233: [dM] make: .if broken inside .for
To: None <gnats-bugs@gnats.netbsd.org>
From: der Mouse <mouse@Rodents.Montreal.QC.CA>
List: netbsd-bugs
Date: 01/13/2002 09:23:45
>Number:         15233
>Category:       bin
>Synopsis:       [dM] make: .if broken inside .for
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Jan 13 06:25:00 PST 2002
>Closed-Date:
>Last-Modified:
>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:
>Unformatted: