Subject: make: only read first makefile found via path
To: None <tech-toolchain@netbsd.org>
From: Simon J. Gerraty <sjg@crufty.net>
List: tech-toolchain
Date: 04/11/2006 11:17:27
Ok the following behavior has existed since rev 1.1 in our repository.

ln = Lst_Find(sysMkPath, (ClientData)NULL, ReadMakefile);

uses Lst_FindFrom to call ReadMakefile to tell it when it has found
the correct node - ReadMakefile is treated as a compare function and
is expected to return 0 on a match.

Yet ReadMakefile returns TRUE if it successfully reads the makefile.

This means that if there are several dirs in MAKESYSPATH that each
contain a sys.mk, then each one will be read by our make.   
Normally this is just a waste of effort, but it apparently causes
grief for pkgsrc.

I can't find any indication that the above is more than a simple
miss-match of expectations, that simply goes unnoticed in normal
usage. 

The patch below makes ReadMakefile return 0 on success and -1 on
failure, to better match the expectations of Lst_Find.
It also now matches its prototype ;-)

--sjg

Index: main.c
===================================================================
RCS file: /cvsroot/src/usr.bin/make/main.c,v
retrieving revision 1.123
diff -u -p -r1.123 main.c
--- main.c	31 Mar 2006 21:05:34 -0000	1.123
+++ main.c	11 Apr 2006 18:14:54 -0000
@@ -906,7 +906,7 @@ main(int argc, char **argv)
 			Fatal("%s: no system rules (%s).", progname,
 			    _PATH_DEFSYSMK);
 		ln = Lst_Find(sysMkPath, (ClientData)NULL, ReadMakefile);
-		if (ln != NILLNODE)
+		if (ln == NILLNODE)
 			Fatal("%s: cannot open %s.", progname,
 			    (char *)Lst_Datum(ln));
 	}
@@ -915,10 +915,10 @@ main(int argc, char **argv)
 		LstNode ln;
 
 		ln = Lst_Find(makefiles, (ClientData)NULL, ReadMakefile);
-		if (ln != NILLNODE)
+		if (ln == NILLNODE)
 			Fatal("%s: cannot open %s.", progname, 
 			    (char *)Lst_Datum(ln));
-	} else if (!ReadMakefile(UNCONST("makefile"), NULL))
+	} else if (ReadMakefile(UNCONST("makefile"), NULL))
 		(void)ReadMakefile(UNCONST("Makefile"), NULL);
 
 	(void)ReadMakefile(UNCONST(".depend"), NULL);
@@ -1072,12 +1072,12 @@ main(int argc, char **argv)
  *	Open and parse the given makefile.
  *
  * Results:
- *	TRUE if ok. FALSE if couldn't open file.
+ *	0 if ok. -1 if couldn't open file.
  *
  * Side Effects:
  *	lots
  */
-static Boolean
+static int
 ReadMakefile(ClientData p, ClientData q __unused)
 {
 	char *fname = p;		/* makefile to read */
@@ -1122,7 +1122,7 @@ ReadMakefile(ClientData p, ClientData q 
 				Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath);
 		if (!name || !(stream = fopen(name, "r"))) {
 			free(path);
-			return(FALSE);
+			return(-1);
 		}
 		fname = name;
 		/*
@@ -1137,7 +1137,7 @@ found:
 		(void)fclose(stream);
 	}
 	free(path);
-	return(TRUE);
+	return(0);
 }