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) {