Module Name:    src
Committed By:   rillig
Date:           Sun Jan  2 01:54:43 UTC 2022

Modified Files:
        src/usr.bin/make: for.c nonints.h parse.c

Log Message:
make: clean up handling of .for loops and .include directives

No functional change.


To generate a diff of this commit:
cvs rdiff -u -r1.153 -r1.154 src/usr.bin/make/for.c
cvs rdiff -u -r1.228 -r1.229 src/usr.bin/make/nonints.h
cvs rdiff -u -r1.615 -r1.616 src/usr.bin/make/parse.c

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/for.c
diff -u src/usr.bin/make/for.c:1.153 src/usr.bin/make/for.c:1.154
--- src/usr.bin/make/for.c:1.153	Sun Jan  2 00:12:47 2022
+++ src/usr.bin/make/for.c	Sun Jan  2 01:54:43 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: for.c,v 1.153 2022/01/02 00:12:47 rillig Exp $	*/
+/*	$NetBSD: for.c,v 1.154 2022/01/02 01:54:43 rillig Exp $	*/
 
 /*
  * Copyright (c) 1992, The Regents of the University of California.
@@ -58,7 +58,7 @@
 #include "make.h"
 
 /*	"@(#)for.c	8.1 (Berkeley) 6/6/93"	*/
-MAKE_RCSID("$NetBSD: for.c,v 1.153 2022/01/02 00:12:47 rillig Exp $");
+MAKE_RCSID("$NetBSD: for.c,v 1.154 2022/01/02 01:54:43 rillig Exp $");
 
 
 /* One of the variables to the left of the "in" in a .for loop. */
@@ -71,7 +71,6 @@ typedef struct ForLoop {
 	Buffer body;		/* Unexpanded body of the loop */
 	Vector /* of ForVar */ vars; /* Iteration variables */
 	SubstringWords items;	/* Substitution items */
-	Buffer curBody;		/* Expanded body of the current iteration */
 	unsigned int nextItem;	/* Where to continue iterating */
 } ForLoop;
 
@@ -88,7 +87,6 @@ ForLoop_New(void)
 	Buf_Init(&f->body);
 	Vector_Init(&f->vars, sizeof(ForVar));
 	SubstringWords_Init(&f->items);
-	Buf_Init(&f->curBody);
 	f->nextItem = 0;
 
 	return f;
@@ -106,7 +104,6 @@ ForLoop_Free(ForLoop *f)
 	Vector_Done(&f->vars);
 
 	SubstringWords_Free(f->items);
-	Buf_Done(&f->curBody);
 
 	free(f);
 }
@@ -484,40 +481,32 @@ ForLoop_SubstBody(ForLoop *f, Buffer *bo
  * Compute the body for the current iteration by copying the unexpanded body,
  * replacing the expressions for the iteration variables on the way.
  */
-static char *
-ForReadMore(void *v_arg, size_t *out_len)
+bool
+For_NextIteration(ForLoop *f, Buffer *body)
 {
-	ForLoop *f = v_arg;
-
 	if (f->nextItem == f->items.len) {
 		/* No more iterations */
 		ForLoop_Free(f);
-		return NULL;
+		return false;
 	}
 
-	ForLoop_SubstBody(f, &f->curBody);
-	DEBUG1(FOR, "For: loop body:\n%s", f->curBody.data);
+	ForLoop_SubstBody(f, body);
+	DEBUG1(FOR, "For: loop body:\n%s", body->data);
 	f->nextItem += (unsigned int)f->vars.len;
-
-	*out_len = f->curBody.len;
-	return f->curBody.data;
+	return true;
 }
 
 /* Run the .for loop, imitating the actions of an include file. */
 void
 For_Run(int lineno)
 {
+	Buffer buf;
 	ForLoop *f = accumFor;
 	accumFor = NULL;
 
-	if (f->items.len == 0) {
-		/*
-		 * Nothing to expand - possibly due to an earlier syntax
-		 * error.
-		 */
+	if (f->items.len > 0) {
+		Buf_Init(&buf);
+		Parse_PushInput(NULL, lineno, buf, f);
+	} else
 		ForLoop_Free(f);
-		return;
-	}
-
-	Parse_PushInput(NULL, lineno, ForReadMore, f);
 }

Index: src/usr.bin/make/nonints.h
diff -u src/usr.bin/make/nonints.h:1.228 src/usr.bin/make/nonints.h:1.229
--- src/usr.bin/make/nonints.h:1.228	Sat Jan  1 21:50:29 2022
+++ src/usr.bin/make/nonints.h	Sun Jan  2 01:54:43 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: nonints.h,v 1.228 2022/01/01 21:50:29 rillig Exp $	*/
+/*	$NetBSD: nonints.h,v 1.229 2022/01/02 01:54:43 rillig Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -116,9 +116,11 @@ SearchPath_New(void)
 void SearchPath_Free(SearchPath *);
 
 /* for.c */
+struct ForLoop;
 int For_Eval(const char *) MAKE_ATTR_USE;
 bool For_Accum(const char *) MAKE_ATTR_USE;
 void For_Run(int);
+bool For_NextIteration(struct ForLoop *, Buffer *);
 
 /* job.c */
 void JobReapChild(pid_t, int, bool);
@@ -141,13 +143,11 @@ const char *cached_realpath(const char *
 void Parse_Init(void);
 void Parse_End(void);
 
-typedef char *(*ReadMoreProc)(void *, size_t *);
-
 void Parse_Error(ParseErrorLevel, const char *, ...) MAKE_ATTR_PRINTFLIKE(2, 3);
 bool Parse_VarAssign(const char *, bool, GNode *) MAKE_ATTR_USE;
 void Parse_AddIncludeDir(const char *);
 void Parse_File(const char *, int);
-void Parse_PushInput(const char *, int, ReadMoreProc, void *);
+void Parse_PushInput(const char *, int, Buffer, struct ForLoop *);
 void Parse_MainName(GNodeList *);
 int Parse_NumErrors(void) MAKE_ATTR_USE;
 

Index: src/usr.bin/make/parse.c
diff -u src/usr.bin/make/parse.c:1.615 src/usr.bin/make/parse.c:1.616
--- src/usr.bin/make/parse.c:1.615	Sun Jan  2 00:07:20 2022
+++ src/usr.bin/make/parse.c	Sun Jan  2 01:54:43 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: parse.c,v 1.615 2022/01/02 00:07:20 rillig Exp $	*/
+/*	$NetBSD: parse.c,v 1.616 2022/01/02 01:54:43 rillig Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -110,7 +110,7 @@
 #include "pathnames.h"
 
 /*	"@(#)parse.c	8.3 (Berkeley) 3/19/94"	*/
-MAKE_RCSID("$NetBSD: parse.c,v 1.615 2022/01/02 00:07:20 rillig Exp $");
+MAKE_RCSID("$NetBSD: parse.c,v 1.616 2022/01/02 01:54:43 rillig Exp $");
 
 /* types and constants */
 
@@ -119,6 +119,7 @@ MAKE_RCSID("$NetBSD: parse.c,v 1.615 202
  */
 typedef struct IFile {
 	FStr name;		/* absolute or relative to the cwd */
+	/* TODO: merge with forLoop */
 	bool fromForLoop;	/* simulated .include by the .for loop */
 	int lineno;		/* current line number in file */
 	int first_lineno;	/* line number of start of text */
@@ -126,19 +127,14 @@ typedef struct IFile {
 	bool depending;	/* state of doing_depend on EOF */
 
 	/*
-	 * The buffer from which the file's content is read.  The buffer
-	 * always ends with '\n', the buffer is not null-terminated, that is,
-	 * buf_end[0] is already out of bounds.
+	 * The buffer from which the file's content or the body of the .for
+	 * loop is read.  The buffer always ends with '\n'.
 	 */
-	char *buf_freeIt;
+	Buffer buf;
 	char *buf_ptr;		/* next char to be read */
 	char *buf_end;		/* buf_end[-1] == '\n' */
 
-	/* Function to read more data, with a single opaque argument. */
-	ReadMoreProc readMore;
-	void *readMoreArg;
-
-	struct loadedfile *lf;	/* loadedfile object, if any */
+	struct ForLoop *forLoop;
 } IFile;
 
 /*
@@ -315,52 +311,8 @@ static const struct {
     { ".WAIT",		SP_WAIT,	OP_NONE },
 };
 
-/* file loader */
-
-struct loadedfile {
-	char *buf;		/* contents buffer, not null-terminated */
-	size_t len;		/* length of contents */
-	bool used;		/* XXX: have we used the data yet */
-};
-
-/* XXX: What is the lifetime of the path? Who manages the memory? */
-static struct loadedfile *
-loadedfile_create(char *buf, size_t buflen)
-{
-	struct loadedfile *lf;
-
-	lf = bmake_malloc(sizeof *lf);
-	lf->buf = buf;
-	lf->len = buflen;
-	lf->used = false;
-	return lf;
-}
-
-static void
-loadedfile_destroy(struct loadedfile *lf)
-{
-	free(lf->buf);
-	free(lf);
-}
 
-/*
- * readMore() operation for loadedfile, as needed by the weird and twisted
- * logic below. Once that's cleaned up, we can get rid of lf->used.
- */
-static char *
-loadedfile_readMore(void *x, size_t *len)
-{
-	struct loadedfile *lf = x;
-
-	if (lf->used)
-		return NULL;
-
-	lf->used = true;
-	*len = lf->len;
-	return lf->buf;
-}
-
-static struct loadedfile *
+static Buffer
 loadfile(const char *path, int fd)
 {
 	ssize_t n;
@@ -398,7 +350,7 @@ loadfile(const char *path, int fd)
 	if (!Buf_EndsWith(&buf, '\n'))
 		Buf_AddByte(&buf, '\n');
 
-	return loadedfile_create(buf.data, buf.len);
+	return buf;
 }
 
 static void
@@ -1936,7 +1888,7 @@ Parse_AddIncludeDir(const char *dir)
 static void
 IncludeFile(const char *file, bool isSystem, bool depinc, bool silent)
 {
-	struct loadedfile *lf;
+	Buffer buf;
 	char *fullname;		/* full pathname of file */
 	char *newName;
 	char *slash, *incdir;
@@ -2029,13 +1981,10 @@ IncludeFile(const char *file, bool isSys
 		return;
 	}
 
-	/* load it */
-	lf = loadfile(fullname, fd);
+	buf = loadfile(fullname, fd);
 	(void)close(fd);
 
-	/* Start reading from this file next */
-	Parse_PushInput(fullname, 0, loadedfile_readMore, lf);
-	CurFile()->lf = lf;
+	Parse_PushInput(fullname, 0, buf, NULL);
 	if (depinc)
 		doing_depend = depinc;	/* only turn it on */
 	free(fullname);
@@ -2215,12 +2164,10 @@ TrackInput(const char *name)
  * The given file is added to the includes stack.
  */
 void
-Parse_PushInput(const char *name, int lineno,
-	       ReadMoreProc readMore, void *readMoreArg)
+Parse_PushInput(const char *name, int lineno, Buffer buf,
+		struct ForLoop *forLoop)
 {
 	IFile *curFile;
-	char *buf;
-	size_t len;
 	bool fromForLoop = name == NULL;
 
 	if (fromForLoop)
@@ -2229,7 +2176,7 @@ Parse_PushInput(const char *name, int li
 		TrackInput(name);
 
 	DEBUG3(PARSE, "Parse_PushInput: %s %s, line %d\n",
-	    readMore == loadedfile_readMore ? "file" : ".for loop in",
+	    !fromForLoop ? "file" : ".for loop in",
 	    name, lineno);
 
 	curFile = Vector_Push(&includes);
@@ -2237,25 +2184,15 @@ Parse_PushInput(const char *name, int li
 	curFile->fromForLoop = fromForLoop;
 	curFile->lineno = lineno;
 	curFile->first_lineno = lineno;
-	curFile->readMore = readMore;
-	curFile->readMoreArg = readMoreArg;
-	curFile->lf = NULL;
+	curFile->buf = buf;
 	curFile->depending = doing_depend;	/* restore this on EOF */
+	curFile->forLoop = forLoop;
 
-	assert(readMore != NULL);
-
-	/* Get first block of input data */
-	buf = curFile->readMore(curFile->readMoreArg, &len);
-	if (buf == NULL) {
-		/* Was all a waste of time ... */
-		FStr_Done(&curFile->name);
-		free(curFile);
-		return;
-	}
-	curFile->buf_freeIt = buf;
-	curFile->buf_ptr = buf;
-	curFile->buf_end = buf + len;
+	if (forLoop != NULL && !For_NextIteration(forLoop, &curFile->buf))
+		abort();	/* see For_Run */
 
+	curFile->buf_ptr = curFile->buf.data;
+	curFile->buf_end = curFile->buf.data + curFile->buf.len;
 	curFile->cond_depth = Cond_save_depth();
 	SetParseFile(name);
 }
@@ -2378,21 +2315,15 @@ ParseGmakeExport(char *line)
 static bool
 ParseEOF(void)
 {
-	char *ptr;
-	size_t len;
 	IFile *curFile = CurFile();
 
-	assert(curFile->readMore != NULL);
-
-	doing_depend = curFile->depending;	/* restore this */
-	/* get next input buffer, if any */
-	ptr = curFile->readMore(curFile->readMoreArg, &len);
-	curFile->buf_ptr = ptr;
-	curFile->buf_freeIt = ptr;
-	curFile->buf_end = ptr == NULL ? NULL : ptr + len;
-	if (ptr != NULL) {
+	doing_depend = curFile->depending;
+	if (curFile->forLoop != NULL &&
+	    For_NextIteration(curFile->forLoop, &curFile->buf)) {
+		curFile->buf_ptr = curFile->buf.data;
+		curFile->buf_end = curFile->buf.data + curFile->buf.len;
 		curFile->lineno = curFile->first_lineno;
-		return true;	/* Iterate again */
+		return true;
 	}
 
 	/*
@@ -2401,13 +2332,8 @@ ParseEOF(void)
 	 */
 	Cond_restore_depth(curFile->cond_depth);
 
-	if (curFile->lf != NULL) {
-		loadedfile_destroy(curFile->lf);
-		curFile->lf = NULL;
-	}
-
 	FStr_Done(&curFile->name);
-	free(curFile->buf_freeIt);
+	Buf_Done(&curFile->buf);
 	Vector_Pop(&includes);
 
 	if (includes.len == 0) {
@@ -2687,7 +2613,7 @@ ParseForLoop(const char *line)
 
 	firstLineno = CurFile()->lineno;
 
-	/* Accumulate loop lines until matching .endfor */
+	/* Accumulate the loop body until the matching '.endfor'. */
 	do {
 		line = ReadLowLevelLine(LK_FOR_BODY);
 		if (line == NULL) {
@@ -2697,9 +2623,8 @@ ParseForLoop(const char *line)
 		}
 	} while (For_Accum(line));
 
-	For_Run(firstLineno);	/* Stash each iteration as a new 'input file' */
-
-	return true;		/* Read next line from for-loop buffer */
+	For_Run(firstLineno);
+	return true;
 }
 
 /*
@@ -3014,16 +2939,15 @@ void
 Parse_File(const char *name, int fd)
 {
 	char *line;
-	struct loadedfile *lf;
+	Buffer buf;
 
-	lf = loadfile(name, fd != -1 ? fd : STDIN_FILENO);
+	buf = loadfile(name, fd != -1 ? fd : STDIN_FILENO);
 	if (fd != -1)
 		(void)close(fd);
 
 	assert(targets == NULL);
 
-	Parse_PushInput(name, 0, loadedfile_readMore, lf);
-	CurFile()->lf = lf;
+	Parse_PushInput(name, 0, buf, NULL);
 
 	do {
 		while ((line = ReadHighLevelLine()) != NULL) {

Reply via email to