Module Name:    src
Committed By:   rillig
Date:           Sat Apr 27 20:41:32 UTC 2024

Modified Files:
        src/usr.bin/make: arch.c job.c make.h var.c
        src/usr.bin/make/unit-tests: depsrc-end.mk depsrc-nopath.exp
            depsrc-nopath.mk depsrc-phony.mk

Log Message:
make: clean up, test .NOPATH

Trim down the comments in the archive module, as they mainly repeated
the code.  Trim down the binary code size in the archive module, as it
is rarely used.

In Var_Parse, delay two variable assignments until they are actually
needed.


To generate a diff of this commit:
cvs rdiff -u -r1.216 -r1.217 src/usr.bin/make/arch.c
cvs rdiff -u -r1.469 -r1.470 src/usr.bin/make/job.c
cvs rdiff -u -r1.331 -r1.332 src/usr.bin/make/make.h
cvs rdiff -u -r1.1105 -r1.1106 src/usr.bin/make/var.c
cvs rdiff -u -r1.1 -r1.2 src/usr.bin/make/unit-tests/depsrc-end.mk \
    src/usr.bin/make/unit-tests/depsrc-nopath.exp
cvs rdiff -u -r1.2 -r1.3 src/usr.bin/make/unit-tests/depsrc-nopath.mk
cvs rdiff -u -r1.3 -r1.4 src/usr.bin/make/unit-tests/depsrc-phony.mk

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/make/arch.c
diff -u src/usr.bin/make/arch.c:1.216 src/usr.bin/make/arch.c:1.217
--- src/usr.bin/make/arch.c:1.216	Sat Apr 27 17:33:46 2024
+++ src/usr.bin/make/arch.c	Sat Apr 27 20:41:32 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: arch.c,v 1.216 2024/04/27 17:33:46 rillig Exp $	*/
+/*	$NetBSD: arch.c,v 1.217 2024/04/27 20:41:32 rillig Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -126,7 +126,7 @@
 #include "config.h"
 
 /*	"@(#)arch.c	8.2 (Berkeley) 1/2/94"	*/
-MAKE_RCSID("$NetBSD: arch.c,v 1.216 2024/04/27 17:33:46 rillig Exp $");
+MAKE_RCSID("$NetBSD: arch.c,v 1.217 2024/04/27 20:41:32 rillig Exp $");
 
 typedef struct List ArchList;
 typedef struct ListNode ArchListNode;
@@ -134,7 +134,7 @@ typedef struct ListNode ArchListNode;
 static ArchList archives;	/* The archives we've already examined */
 
 typedef struct Arch {
-	char *name;		/* Name of archive */
+	char *name;
 	HashTable members;	/* All the members of the archive described
 				 * by <name, struct ar_hdr *> key/value pairs */
 	char *fnametab;		/* Extended name table strings */
@@ -155,7 +155,6 @@ ArchFree(Arch *a)
 {
 	HashIter hi;
 
-	/* Free memory from hash entries */
 	HashIter_Init(&hi, &a->members);
 	while (HashIter_Next(&hi) != NULL)
 		free(hi.entry->value);
@@ -168,32 +167,22 @@ ArchFree(Arch *a)
 #endif
 
 /* Return "archive(member)". */
-static char *
+MAKE_ATTR_NOINLINE static char *
 FullName(const char *archive, const char *member)
 {
-	size_t len1 = strlen(archive);
-	size_t len3 = strlen(member);
-	char *result = bmake_malloc(len1 + 1 + len3 + 1 + 1);
-	memcpy(result, archive, len1);
-	memcpy(result + len1, "(", 1);
-	memcpy(result + len1 + 1, member, len3);
-	memcpy(result + len1 + 1 + len3, ")", 1 + 1);
-	return result;
+	Buffer buf;
+	Buf_Init(&buf);
+	Buf_AddStr(&buf, archive);
+	Buf_AddStr(&buf, "(");
+	Buf_AddStr(&buf, member);
+	Buf_AddStr(&buf, ")");
+	return Buf_DoneData(&buf);
 }
 
 /*
  * Parse an archive specification such as "archive.a(member1 member2.${EXT})",
- * adding nodes for the expanded members to gns.  Nodes are created as
- * necessary.
- *
- * Input:
- *	pp		The start of the specification.
- *	gns		The list on which to place the nodes.
- *	scope		The scope in which to expand variables.
- *
- * Output:
- *	return		True if it was a valid specification.
- *	*pp		Points to the first non-space after the archive spec.
+ * adding nodes for the expanded members to gns.  If successful, advance pp
+ * beyond the archive specification and any trailing whitespace.
  */
 bool
 Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
@@ -274,12 +263,6 @@ Arch_ParseArchive(char **pp, GNodeList *
 			}
 		}
 
-		/*
-		 * If the specification ends without a closing parenthesis,
-		 * chances are there's something wrong (like a missing
-		 * backslash), so it's better to return failure than allow
-		 * such things to happen
-		 */
 		if (*cp == '\0') {
 			Parse_Error(PARSE_FATAL,
 			    "No closing parenthesis "
@@ -287,9 +270,6 @@ Arch_ParseArchive(char **pp, GNodeList *
 			return false;
 		}
 
-		/*
-		 * If we didn't move anywhere, we must be done
-		 */
 		if (cp == mem.str)
 			break;
 
@@ -326,8 +306,7 @@ Arch_ParseArchive(char **pp, GNodeList *
 				/*
 				 * Must contain dynamic sources, so we can't
 				 * deal with it now. Just create an ARCHV node
-				 * for the thing and let SuffExpandChildren
-				 * handle it.
+				 * and let SuffExpandChildren handle it.
 				 */
 				gn = Targ_GetNode(fullName);
 				gn->type |= OP_ARCHV;
@@ -364,13 +343,6 @@ Arch_ParseArchive(char **pp, GNodeList *
 			gn = Targ_GetNode(fullname);
 			free(fullname);
 
-			/*
-			 * We've found the node, but have to make sure the
-			 * rest of the world knows it's an archive member,
-			 * without having to constantly check for parentheses,
-			 * so we type the thing with the OP_ARCHV bit before
-			 * we place it on the end of the provided list.
-			 */
 			gn->type |= OP_ARCHV;
 			Lst_Append(gns, gn);
 		}
@@ -382,23 +354,13 @@ Arch_ParseArchive(char **pp, GNodeList *
 	FStr_Done(&lib);
 
 	cp++;			/* skip the ')' */
-	/* We promised that pp would be set up at the next non-space. */
 	cpp_skip_whitespace(&cp);
 	*pp += cp - *pp;
 	return true;
 }
 
 /*
- * Locate a member of an archive, given the path of the archive and the path
- * of the desired member.
- *
- * Input:
- *	archive		Path to the archive
- *	member		Name of member; only its basename is used.
- *	addToCache	True if archive should be cached if not already so.
- *
- * Results:
- *	The ar_hdr for the member, or NULL.
+ * Locate a member in an archive.
  *
  * See ArchFindMember for an almost identical copy of this code.
  */
@@ -410,15 +372,11 @@ ArchStatMember(const char *archive, cons
 	size_t size;		/* Size of archive member */
 	char magic[SARMAG];
 	ArchListNode *ln;
-	Arch *ar;		/* Archive descriptor */
-	struct ar_hdr arh;	/* archive-member header for reading archive */
+	Arch *ar;
+	struct ar_hdr arh;
 	char memName[MAXPATHLEN + 1];
 	/* Current member name while hashing. */
 
-	/*
-	 * Because of space constraints and similar things, files are archived
-	 * using their basename, not the entire path.
-	 */
 	member = str_basename(member);
 
 	for (ln = archives.first; ln != NULL; ln = ln->next) {
@@ -450,11 +408,8 @@ ArchStatMember(const char *archive, cons
 
 	if (!addToCache) {
 		/*
-		 * Caller doesn't want the thing cached, just use
-		 * ArchFindMember to read the header for the member out and
-		 * close down the stream again. Since the archive is not to be
-		 * cached, we assume there's no need to allocate extra room
-		 * for the header we're returning, so just declare it static.
+		 * Since the archive is not to be cached, assume there's no
+		 * need to allocate the header, so just declare it static.
 		 */
 		static struct ar_hdr sarh;
 
@@ -466,18 +421,10 @@ ArchStatMember(const char *archive, cons
 		return &sarh;
 	}
 
-	/*
-	 * We don't have this archive on the list yet, so we want to find out
-	 * everything that's in it and cache it so we can get at it quickly.
-	 */
 	arch = fopen(archive, "r");
 	if (arch == NULL)
 		return NULL;
 
-	/*
-	 * We use the ARMAG string to make sure this is an archive we
-	 * can handle...
-	 */
 	if (fread(magic, SARMAG, 1, arch) != 1 ||
 	    strncmp(magic, ARMAG, SARMAG) != 0) {
 		(void)fclose(arch);
@@ -494,17 +441,9 @@ ArchStatMember(const char *archive, cons
 	while (fread(&arh, sizeof arh, 1, arch) == 1) {
 		char *nameend;
 
-		/* If the header is bogus, there's no way we can recover. */
 		if (strncmp(arh.ar_fmag, ARFMAG, sizeof arh.ar_fmag) != 0)
-			goto badarch;
+			goto bad_archive;
 
-		/*
-		 * We need to advance the stream's pointer to the start of the
-		 * next header. Files are padded with newlines to an even-byte
-		 * boundary, so we need to extract the size of the file from
-		 * the 'size' field of the header and round it up during the
-		 * seek.
-		 */
 		arh.ar_size[sizeof arh.ar_size - 1] = '\0';
 		size = (size_t)strtol(arh.ar_size, NULL, 10);
 
@@ -523,7 +462,7 @@ ArchStatMember(const char *archive, cons
 			/* svr4 magic mode; handle it */
 			switch (ArchSVR4Entry(ar, memName, size, arch)) {
 			case -1:	/* Invalid data */
-				goto badarch;
+				goto bad_archive;
 			case 0:		/* List of files entry */
 				continue;
 			default:	/* Got the entry */
@@ -547,12 +486,12 @@ ArchStatMember(const char *archive, cons
 			    memName + sizeof AR_EFMT1 - 1);
 
 			if (elen > MAXPATHLEN)
-				goto badarch;
+				goto bad_archive;
 			if (fread(memName, elen, 1, arch) != 1)
-				goto badarch;
+				goto bad_archive;
 			memName[elen] = '\0';
 			if (fseek(arch, -(long)elen, SEEK_CUR) != 0)
-				goto badarch;
+				goto bad_archive;
 			if (DEBUG(ARCH) || DEBUG(MAKE))
 				debug_printf(
 				    "ArchStatMember: "
@@ -568,21 +507,18 @@ ArchStatMember(const char *archive, cons
 			HashTable_Set(&ar->members, memName, cached_hdr);
 		}
 
+		/* Files are padded with newlines to an even-byte boundary. */
 		if (fseek(arch, ((long)size + 1) & ~1, SEEK_CUR) != 0)
-			goto badarch;
+			goto bad_archive;
 	}
 
 	fclose(arch);
 
 	Lst_Append(&archives, ar);
 
-	/*
-	 * Now that the archive has been read and cached, we can look into
-	 * the addToCache table to find the desired member's header.
-	 */
 	return HashTable_FindValue(&ar->members, member);
 
-badarch:
+bad_archive:
 	fclose(arch);
 	HashTable_Done(&ar->members);
 	free(ar->fnametab);
@@ -687,37 +623,27 @@ ArchiveMember_HasName(const struct ar_hd
 	 * In archives created by GNU binutils 2.27, the member names end
 	 * with a slash.
 	 */
-	if (ar_name[namelen] == '/' &&
-	    (namelen == ar_name_len || ar_name[namelen + 1] == ' '))
+	if (ar_name[namelen] == '/' && ar_name[namelen + 1] == ' ')
 		return true;
 
 	return false;
 }
 
 /*
- * Locate a member of an archive, given the path of the archive and the path
- * of the desired member.
+ * Load the header of an archive member.  The mode is "r" for read-only
+ * access, "r+" for read-write access.
  *
- * Input:
- *	archive		Path to the archive
- *	member		Name of member. If it is a path, only the last
- *			component is used.
- *	out_arh		Archive header to be filled in
- *	mode		"r" for read-only access, "r+" for read-write access
- *
- * Output:
- *	return		The archive file, positioned at the start of the
- *			member's struct ar_hdr, or NULL if the member doesn't
- *			exist.
- *	*out_arh	The current struct ar_hdr for member.
+ * Upon successful return, the archive file is positioned at the start of the
+ * member's struct ar_hdr.  In case of a failure or if the member doesn't
+ * exist, return NULL.
  *
  * See ArchStatMember for an almost identical copy of this code.
  */
 static FILE *
-ArchFindMember(const char *archive, const char *member, struct ar_hdr *out_arh,
-	       const char *mode)
+ArchFindMember(const char *archive, const char *member,
+	       struct ar_hdr *out_arh, const char *mode)
 {
-	FILE *arch;		/* Stream to archive */
+	FILE *arch;
 	int size;		/* Size of archive member */
 	char magic[SARMAG];
 	size_t len;
@@ -726,32 +652,20 @@ ArchFindMember(const char *archive, cons
 	if (arch == NULL)
 		return NULL;
 
-	/*
-	 * We use the ARMAG string to make sure this is an archive we
-	 * can handle...
-	 */
 	if (fread(magic, SARMAG, 1, arch) != 1 ||
 	    strncmp(magic, ARMAG, SARMAG) != 0) {
 		fclose(arch);
 		return NULL;
 	}
 
-	/*
-	 * Because of space constraints and similar things, files are archived
-	 * using their basename, not the entire path.
-	 */
+	/* Files are archived using their basename, not the entire path. */
 	member = str_basename(member);
-
 	len = strlen(member);
 
 	while (fread(out_arh, sizeof *out_arh, 1, arch) == 1) {
 
 		if (strncmp(out_arh->ar_fmag, ARFMAG,
 			    sizeof out_arh->ar_fmag) != 0) {
-			/*
-			 * The header is bogus, so the archive is bad
-			 * and there's no way we can recover...
-			 */
 			fclose(arch);
 			return NULL;
 		}
@@ -762,14 +676,6 @@ ArchFindMember(const char *archive, cons
 		    (int)sizeof out_arh->ar_date, out_arh->ar_date);
 
 		if (ArchiveMember_HasName(out_arh, member, len)) {
-			/*
-			 * To make life easier for callers that want to update
-			 * the archive, we reposition the file at the start of
-			 * the header we just read before we return the
-			 * stream. In a more general situation, it might be
-			 * better to leave the file at the actual member,
-			 * rather than its header, but not here.
-			 */
 			if (fseek(arch, -(long)sizeof *out_arh, SEEK_CUR) !=
 			    0) {
 				fclose(arch);
@@ -821,15 +727,10 @@ ArchFindMember(const char *archive, cons
 		}
 #endif
 
-		/*
-		 * This isn't the member we're after, so we need to advance the
-		 * stream's pointer to the start of the next header. Files are
-		 * padded with newlines to an even-byte boundary, so we need to
-		 * extract the size of the file from the 'size' field of the
-		 * header and round it up during the seek.
-		 */
+		/* Advance to the next member. */
 		out_arh->ar_size[sizeof out_arh->ar_size - 1] = '\0';
 		size = (int)strtol(out_arh->ar_size, NULL, 10);
+		/* Files are padded with newlines to an even-byte boundary. */
 		if (fseek(arch, (size + 1) & ~1L, SEEK_CUR) != 0) {
 			fclose(arch);
 			return NULL;
@@ -841,17 +742,9 @@ ArchFindMember(const char *archive, cons
 }
 
 /*
- * Touch a member of an archive, on disk.
- * The GNode's modification time is left as-is.
- *
- * The st_mtime of the entire archive is also changed.
- * For a library, it may be required to run ranlib after this.
- *
- * Input:
- *	gn		Node of member to touch
- *
- * Results:
- *	The 'time' field of the member's header is updated.
+ * Update the ar_date of the member of an archive, on disk but not in the
+ * GNode.  Update the st_mtime of the entire archive as well.  For a library,
+ * it may be required to run ranlib after this.
  */
 void
 Arch_Touch(GNode *gn)
@@ -966,9 +859,6 @@ Arch_UpdateMemberMTime(GNode *gn)
  * TARGET variable for this node to be the node's name. Otherwise,
  * we set the TARGET variable to be the full path of the library,
  * as returned by Dir_FindFile.
- *
- * Input:
- *	gn		Node of library to find
  */
 void
 Arch_FindLib(GNode *gn, SearchPath *path)
@@ -1010,20 +900,18 @@ RanlibOODate(const GNode *gn MAKE_ATTR_U
 }
 
 /*
- * Decide if a node with the OP_LIB attribute is out-of-date. Called from
- * GNode_IsOODate to make its life easier.
+ * Decide if a node with the OP_LIB attribute is out-of-date.
  * The library is cached if it hasn't been already.
  *
- * There are several ways for a library to be out-of-date that are
- * not available to ordinary files. In addition, there are ways
- * that are open to regular files that are not available to
- * libraries.
- *
- * A library that is only used as a source is never
- * considered out-of-date by itself. This does not preclude the
- * library's modification time from making its parent be out-of-date.
- * A library will be considered out-of-date for any of these reasons,
- * given that it is a target on a dependency line somewhere:
+ * There are several ways for a library to be out-of-date that are not
+ * available to ordinary files.  In addition, there are ways that are open to
+ * regular files that are not available to libraries.
+ *
+ * A library that is only used as a source is never considered out-of-date by
+ * itself.  This does not preclude the library's modification time from making
+ * its parent be out-of-date.  A library will be considered out-of-date for
+ * any of these reasons, given that it is a target on a dependency line
+ * somewhere:
  *
  *	Its modification time is less than that of one of its sources
  *	(gn->mtime < gn->youngestChild->mtime).
@@ -1043,18 +931,16 @@ bool
 Arch_LibOODate(GNode *gn)
 {
 
-	if (gn->type & OP_PHONY) {
+	if (gn->type & OP_PHONY)
 		return true;
-	} else if (!GNode_IsTarget(gn) && Lst_IsEmpty(&gn->children)) {
+	if (!GNode_IsTarget(gn) && Lst_IsEmpty(&gn->children))
 		return false;
-	} else if ((!Lst_IsEmpty(&gn->children) && gn->youngestChild == NULL) ||
+	if ((!Lst_IsEmpty(&gn->children) && gn->youngestChild == NULL) ||
 		   (gn->mtime > now) ||
 		   (gn->youngestChild != NULL &&
-		    gn->mtime < gn->youngestChild->mtime)) {
+		    gn->mtime < gn->youngestChild->mtime))
 		return true;
-	} else {
-		return RanlibOODate(gn);
-	}
+	return RanlibOODate(gn);
 }
 
 /* Initialize the archives module. */
@@ -1080,19 +966,14 @@ Arch_End(void)
 bool
 Arch_IsLib(GNode *gn)
 {
-	static const char armag[] = "!<arch>\n";
-	char buf[sizeof armag - 1];
+	char buf[8];
 	int fd;
+	bool isLib;
 
 	if ((fd = open(gn->path, O_RDONLY)) == -1)
 		return false;
-
-	if (read(fd, buf, sizeof buf) != sizeof buf) {
-		(void)close(fd);
-		return false;
-	}
-
+	isLib = read(fd, buf, sizeof buf) == sizeof buf
+	    && memcmp(buf, "!<arch>\n", sizeof buf) == 0;
 	(void)close(fd);
-
-	return memcmp(buf, armag, sizeof buf) == 0;
+	return isLib;
 }

Index: src/usr.bin/make/job.c
diff -u src/usr.bin/make/job.c:1.469 src/usr.bin/make/job.c:1.470
--- src/usr.bin/make/job.c:1.469	Fri Apr 26 17:11:22 2024
+++ src/usr.bin/make/job.c	Sat Apr 27 20:41:32 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: job.c,v 1.469 2024/04/26 17:11:22 rillig Exp $	*/
+/*	$NetBSD: job.c,v 1.470 2024/04/27 20:41:32 rillig Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -141,7 +141,7 @@
 #include "trace.h"
 
 /*	"@(#)job.c	8.2 (Berkeley) 3/19/94"	*/
-MAKE_RCSID("$NetBSD: job.c,v 1.469 2024/04/26 17:11:22 rillig Exp $");
+MAKE_RCSID("$NetBSD: job.c,v 1.470 2024/04/27 20:41:32 rillig Exp $");
 
 /*
  * A shell defines how the commands are run.  All commands for a target are
@@ -1757,7 +1757,7 @@ JobStart(GNode *gn, bool special)
  * itself.
  */
 static char *
-PrintFilteredOutput(char *p, char *endp)	/* XXX: should all be const */
+PrintFilteredOutput(char *p, const char *endp)	/* XXX: p should be const */
 {
 	char *ep;		/* XXX: should be const */
 

Index: src/usr.bin/make/make.h
diff -u src/usr.bin/make/make.h:1.331 src/usr.bin/make/make.h:1.332
--- src/usr.bin/make/make.h:1.331	Tue Apr 23 22:51:28 2024
+++ src/usr.bin/make/make.h	Sat Apr 27 20:41:32 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: make.h,v 1.331 2024/04/23 22:51:28 rillig Exp $	*/
+/*	$NetBSD: make.h,v 1.332 2024/04/27 20:41:32 rillig Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -136,6 +136,12 @@
 #define MAKE_ATTR_USE		/* delete */
 #endif
 
+#if MAKE_GNUC_PREREQ(8, 0)
+#define MAKE_ATTR_NOINLINE		__attribute__((__noinline__))
+#else
+#define MAKE_ATTR_NOINLINE		/* delete */
+#endif
+
 #if __STDC_VERSION__ >= 199901L || defined(lint)
 #define MAKE_INLINE static inline MAKE_ATTR_UNUSED
 #else

Index: src/usr.bin/make/var.c
diff -u src/usr.bin/make/var.c:1.1105 src/usr.bin/make/var.c:1.1106
--- src/usr.bin/make/var.c:1.1105	Tue Apr 23 22:51:28 2024
+++ src/usr.bin/make/var.c	Sat Apr 27 20:41:32 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: var.c,v 1.1105 2024/04/23 22:51:28 rillig Exp $	*/
+/*	$NetBSD: var.c,v 1.1106 2024/04/27 20:41:32 rillig Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -132,7 +132,7 @@
 #include "metachar.h"
 
 /*	"@(#)var.c	8.3 (Berkeley) 3/19/94" */
-MAKE_RCSID("$NetBSD: var.c,v 1.1105 2024/04/23 22:51:28 rillig Exp $");
+MAKE_RCSID("$NetBSD: var.c,v 1.1106 2024/04/27 20:41:32 rillig Exp $");
 
 /*
  * Variables are defined using one of the VAR=value assignments.  Their
@@ -3117,28 +3117,20 @@ ok:
 static char *
 str_toupper(const char *str)
 {
-	char *res;
-	size_t i, len;
-
-	len = strlen(str);
-	res = bmake_malloc(len + 1);
-	for (i = 0; i < len + 1; i++)
+	size_t i, n = strlen(str) + 1;
+	char *res = bmake_malloc(n);
+	for (i = 0; i < n; i++)
 		res[i] = ch_toupper(str[i]);
-
 	return res;
 }
 
 static char *
 str_tolower(const char *str)
 {
-	char *res;
-	size_t i, len;
-
-	len = strlen(str);
-	res = bmake_malloc(len + 1);
-	for (i = 0; i < len + 1; i++)
+	size_t i, n = strlen(str) + 1;
+	char *res = bmake_malloc(n);
+	for (i = 0; i < n; i++)
 		res[i] = ch_tolower(str[i]);
-
 	return res;
 }
 
@@ -4429,7 +4421,7 @@ Expr_Init(const char *name, FStr value,
  * by .for loops and are boring, so evaluate them without debug logging.
  */
 static bool
-Var_Parse_FastLane(const char **pp, VarEvalMode emode, FStr *out_value)
+Var_Parse_U(const char **pp, VarEvalMode emode, FStr *out_value)
 {
 	const char *p;
 
@@ -4488,8 +4480,7 @@ Var_Parse_FastLane(const char **pp, VarE
 FStr
 Var_Parse(const char **pp, GNode *scope, VarEvalMode emode)
 {
-	const char *p = *pp;
-	const char *const start = p;
+	const char *start, *p;
 	bool haveModifier;	/* true for ${VAR:...}, false for ${VAR} */
 	char startc;		/* the actual '{' or '(' or '\0' */
 	char endc;		/* the expected '}' or ')' or '\0' */
@@ -4506,9 +4497,11 @@ Var_Parse(const char **pp, GNode *scope,
 	    scope, DEF_REGULAR);
 	FStr val;
 
-	if (Var_Parse_FastLane(pp, emode, &val))
+	if (Var_Parse_U(pp, emode, &val))
 		return val;
 
+	p = *pp;
+	start = p;
 	DEBUG2(VAR, "Var_Parse: %s (%s)\n", start, VarEvalMode_Name[emode]);
 
 	val = FStr_InitRefer(NULL);

Index: src/usr.bin/make/unit-tests/depsrc-end.mk
diff -u src/usr.bin/make/unit-tests/depsrc-end.mk:1.1 src/usr.bin/make/unit-tests/depsrc-end.mk:1.2
--- src/usr.bin/make/unit-tests/depsrc-end.mk:1.1	Fri Oct 23 19:23:01 2020
+++ src/usr.bin/make/unit-tests/depsrc-end.mk	Sat Apr 27 20:41:32 2024
@@ -1,6 +1,6 @@
-# $NetBSD: depsrc-end.mk,v 1.1 2020/10/23 19:23:01 rillig Exp $
+# $NetBSD: depsrc-end.mk,v 1.2 2024/04/27 20:41:32 rillig Exp $
 #
-# Demonstrate the edge case that .BEGIN depends on .END, which sounds a bit
+# Demonstrate an edge case in which .BEGIN depends on .END, which sounds a bit
 # paradox but works since these special nodes are not in the dependency
 # hierarchy where the cycles are detected.
 
Index: src/usr.bin/make/unit-tests/depsrc-nopath.exp
diff -u src/usr.bin/make/unit-tests/depsrc-nopath.exp:1.1 src/usr.bin/make/unit-tests/depsrc-nopath.exp:1.2
--- src/usr.bin/make/unit-tests/depsrc-nopath.exp:1.1	Sun Aug 16 12:07:51 2020
+++ src/usr.bin/make/unit-tests/depsrc-nopath.exp	Sat Apr 27 20:41:32 2024
@@ -1 +1,3 @@
+: Making test-regular from depsrc-nopath.dir/regular.file
+: Making test-nopath from nopath.file
 exit status 0

Index: src/usr.bin/make/unit-tests/depsrc-nopath.mk
diff -u src/usr.bin/make/unit-tests/depsrc-nopath.mk:1.2 src/usr.bin/make/unit-tests/depsrc-nopath.mk:1.3
--- src/usr.bin/make/unit-tests/depsrc-nopath.mk:1.2	Sun Aug 16 14:25:16 2020
+++ src/usr.bin/make/unit-tests/depsrc-nopath.mk	Sat Apr 27 20:41:32 2024
@@ -1,8 +1,27 @@
-# $NetBSD: depsrc-nopath.mk,v 1.2 2020/08/16 14:25:16 rillig Exp $
+# $NetBSD: depsrc-nopath.mk,v 1.3 2024/04/27 20:41:32 rillig Exp $
 #
 # Tests for the special source .NOPATH in dependency declarations.
 
-# TODO: Implementation
+.if !target(test-*)
+_!=	rm -rf depsrc-nopath.dir
+_!=	mkdir depsrc-nopath.dir
+_!=	touch depsrc-nopath.dir/regular.file
+_!=	touch depsrc-nopath.dir/nopath.file
+.endif
 
 all:
-	@:;
+	@${MAKE} -f ${MAKEFILE} test-regular
+	@${MAKE} -f ${MAKEFILE} test-nopath || echo "should have failed"
+	@rm -rf depsrc-nopath.dir
+
+.PATH: depsrc-nopath.dir
+
+test-regular: regular.file
+	: Making ${.TARGET} from ${.ALLSRC}
+test-nopath: nopath.file
+	: Making ${.TARGET} from ${.ALLSRC}
+
+nopath.file: .NOPATH
+
+# expect: : Making test-regular from depsrc-nopath.dir/regular.file
+# expect: : Making test-nopath from nopath.file

Index: src/usr.bin/make/unit-tests/depsrc-phony.mk
diff -u src/usr.bin/make/unit-tests/depsrc-phony.mk:1.3 src/usr.bin/make/unit-tests/depsrc-phony.mk:1.4
--- src/usr.bin/make/unit-tests/depsrc-phony.mk:1.3	Sat Sep  5 15:57:12 2020
+++ src/usr.bin/make/unit-tests/depsrc-phony.mk	Sat Apr 27 20:41:32 2024
@@ -1,9 +1,10 @@
-# $NetBSD: depsrc-phony.mk,v 1.3 2020/09/05 15:57:12 rillig Exp $
+# $NetBSD: depsrc-phony.mk,v 1.4 2024/04/27 20:41:32 rillig Exp $
 #
 # Tests for the special source .PHONY in dependency declarations,
 # which executes the commands for the target even if a file of the same
 # name exists and would be considered up to date.
 
 # Without the .PHONY, this target would be "up to date".
+# expect: : depsrc-phony.mk is made.
 ${MAKEFILE}: .PHONY
 	: ${.TARGET:T} is made.

Reply via email to