Bug 31339

Summary: make's .if processing buggy
Product: Base System Reporter: Mikhail T. <freebsd-2024>
Component: binAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 5.0-CURRENT   
Hardware: Any   
OS: Any   

Description Mikhail T. 2001-10-17 17:00:01 UTC
	The following makefile breaks make for unknown reason:
	.if o != a
	all:
		@echo "not equal"
	.else
		@echo "equal"
	.endif

	Modifying it to instead start with
	o=o
	.if $o != a
	...
	works around the problem. It will work even if o is explicitly
	set to "", but will not if it is not set at all (which is supposed
	to imply an empty string "" too).

Fix: 

See description.
How-To-Repeat: 	See description.
Comment 1 Juli Mallett freebsd_committer freebsd_triage 2002-10-24 01:16:10 UTC
State Changed
From-To: open->feedback

I'll take responsibility for this... 

Can the submitter verify general string compare support in NetBSD make(1) 
or similar?  We specifically don't support LHS being a bareword in string 
compares, it's been documented in comments in Makefiles that I've seen 
dating to the late 1980s...  But if you can provide an example in a BSD 
make(1) implementation of this not working as it does, I'll do my best 
to merge in the required changes. 


Comment 2 Juli Mallett freebsd_committer freebsd_triage 2002-10-24 01:16:10 UTC
Responsible Changed
From-To: freebsd-bugs->jmallett

I'll take responsibility for this... 

Can the submitter verify general string compare support in NetBSD make(1) 
or similar?  We specifically don't support LHS being a bareword in string 
compares, it's been documented in comments in Makefiles that I've seen 
dating to the late 1980s...  But if you can provide an example in a BSD 
make(1) implementation of this not working as it does, I'll do my best 
to merge in the required changes.
Comment 3 Juli Mallett freebsd_committer freebsd_triage 2002-11-04 19:03:42 UTC
State Changed
From-To: feedback->closed

Verified as not an "issue".
Comment 4 Juli Mallett freebsd_committer freebsd_triage 2002-11-04 19:28:56 UTC
State Changed
From-To: closed->open

Submitter has other issues here than what I recalled, 
assing it back to -bugs for whoever wants it. 

Sorry! 


Comment 5 Juli Mallett freebsd_committer freebsd_triage 2002-11-04 19:28:56 UTC
Responsible Changed
From-To: jmallett->freebsd-bugs

Submitter has other issues here than what I recalled, 
assing it back to -bugs for whoever wants it. 

Sorry!
Comment 6 ru freebsd_committer freebsd_triage 2002-11-22 09:18:57 UTC
On Thu, Nov 21, 2002 at 05:56:07PM -0500, Mikhail Teterin wrote:
> On Thursday 21 November 2002 01:23 pm, you wrote:
> = Juli, Mikhail!
> = 
> = What are these "other" issues that you've mentioned in the audit trail
> = so briefly?
> 
> Inconsitency. make's general rule is, being not defined is the same
> as being defined empty -- except when the "definedness" is explicitly
> queried (with defined() or ?= ).
> 
No, this is not the general rule -- here are a few interesting
examples from the PMake tutorial in /usr/share/doc/psd/12.make:

:    empty    This  syntax  is  much  like the others, except the
:             string inside the parentheses is of the  same  form
:             as you would put between parentheses when expanding
:             a variable, complete with modifiers and everything.
:             The  function  returns true if the resulting string
:             is empty (NOTE: an undefined variable in this  con-
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
:             text will cause at the very least a warning message
:             about a malformed conditional,  and  at  the  worst
:             will cause the process to stop once it has read the
:             makefile. If you want to check for a variable being
:             defined    or    empty,    use    the    expression
:             ``!defined(var) || empty(var)'' as  the  definition
:             of || will prevent the empty() from being evaluated
:             and causing an error,  if  the  variable  is  unde-
:             fined).  This can be used to see if a variable con-
:             tains a given word, for example:
: 
:                  #if !empty(var:Mword)
: 
:    The arithmetic and string operators may only be used to test
:    the  value of a variable. The lefthand side must contain the
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
:    variable expansion, while the righthand side contains either
     ^^^^^^^^^^^^^^^^^^
:    a  string, enclosed in double-quotes, or a number. The stan-
:    dard C numeric conventions (except for specifying  an  octal
:    number) apply to both sides. E.g.

> The example in the PR shows how the rule is gratuitously broken...
> 
All of the examples in PR are broken.  It is now documented (as of
make.1,v 1.60) that the LHS in comparison conditionals is required
to be a variable expansion, so your first example is incorrect.
As for your second example,

.if ${notdef} == value

it is also documented to not work in the PMake tutorial:

:    -B   Forces PMake to be as backwards-compatible with Make as
:         possible while still being itself.  This includes:
:         o Executing one shell per shell command
:         o Expanding  anything  that  looks  even vaguely like a
:           variable, with the empty string replacing  any  vari-
:           able PMake doesn't know.
:         o Refusing  to  allow  you to escape a `#' with a back-
:           slash.
:         o Permitting undefined variables  on  dependency  lines
:           and  conditionals  (see  below). Normally this causes
                                             ^^^^^^^^^^^^^^^^^^^^
:           PMake to abort.
            ^^^^^^^^^^^^^^

Despite this statement about -B, PMake (ports/devel/pmake) does
not permit undefined variables on conditionals.  Nevertheless,
it does not make them permissible without -B either.

What you want is achieved by the patch below, but I consider
the exising behavior more correct:

.if ${notdef1} == ${notdef2}

should not result in TRUE, as would be with the below patch.
(See also my .sig later on, and realize that undefined values
are treated differently from empty strings in SQL.  :-)

%%%
Index: cond.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/make/cond.c,v
retrieving revision 1.25
diff -u -p -u -p -r1.25 cond.c
--- cond.c	23 Oct 2002 23:16:42 -0000	1.25
+++ cond.c	22 Nov 2002 09:11:25 -0000
@@ -512,7 +512,7 @@ CondToken(Boolean doEval)
 		 * value in lhs.
 		 */
 		t = Err;
-		lhs = Var_Parse(condExpr, VAR_CMD, doEval,&varSpecLen,&doFree);
+		lhs = Var_Parse(condExpr, VAR_CMD, FALSE,&varSpecLen,&doFree);
 		if (lhs == var_Error) {
 		    /*
 		     * Even if !doEval, we still report syntax errors, which
@@ -620,7 +620,7 @@ do_string_compare:
 			    int	len;
 			    Boolean freeIt;
 
-			    cp2 = Var_Parse(cp, VAR_CMD, doEval,&len, &freeIt);
+			    cp2 = Var_Parse(cp, VAR_CMD, FALSE,&len, &freeIt);
 			    if (cp2 != var_Error) {
 				Buf_AddBytes(buf, strlen(cp2), (Byte *)cp2);
 				if (freeIt) {
@@ -672,7 +672,7 @@ do_string_compare:
 			int 	len;
 			Boolean	freeIt;
 
-			string = Var_Parse(rhs, VAR_CMD, doEval,&len,&freeIt);
+			string = Var_Parse(rhs, VAR_CMD, FALSE,&len,&freeIt);
 			if (string == var_Error) {
 			    right = 0.0;
 			} else {
%%%

I'd like to close this PR now.


Cheers,
-- 
Ruslan Ermilov		Sysadmin and DBA,
ru@sunbay.com		Sunbay Software AG,
ru@FreeBSD.org		FreeBSD committer,
+380.652.512.251	Simferopol, Ukraine

http://www.FreeBSD.org	The Power To Serve
http://www.oracle.com	Enabling The Information Age
Comment 7 Tom Rhodes freebsd_committer freebsd_triage 2002-12-24 03:07:14 UTC
State Changed
From-To: open->closed

ru has wanted to close this PR for over a month now, so do so.