aboutsummaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorHartmut Brandt <harti@FreeBSD.org>2005-03-30 15:18:58 +0000
committerHartmut Brandt <harti@FreeBSD.org>2005-03-30 15:18:58 +0000
commitba467ce430c7b108c7f83cd8413a134207451c06 (patch)
tree76bd8e21601dfeeab94e4aab0aa1b9ce981e46a9 /usr.bin
parentf43eb6f83ba19a3567e5d005cc23f08d878b0247 (diff)
downloadsrc-ba467ce430c7b108c7f83cd8413a134207451c06.tar.gz
src-ba467ce430c7b108c7f83cd8413a134207451c06.zip
Make the structure for handling the input stack local to the parse
module. The only module accessing it (the current line number) was the condition module, so pass the current line number as a function argument. Centralize the pushing of new input sources into one function ParsePushInput() and rename the function handling the popping from ParseEOF() to ParsePopInput(). Make the entire thing a little bit clearer, by holding the current input source in the top element of the stack instead of using extra variables for this. Use a type-safe intrusive list for the input stack.
Notes
Notes: svn path=/head/; revision=144341
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/make/cond.c4
-rw-r--r--usr.bin/make/cond.h2
-rw-r--r--usr.bin/make/globals.h3
-rw-r--r--usr.bin/make/parse.c267
-rw-r--r--usr.bin/make/parse.h16
5 files changed, 127 insertions, 165 deletions
diff --git a/usr.bin/make/cond.c b/usr.bin/make/cond.c
index 22dc97547344..76737cb521cb 100644
--- a/usr.bin/make/cond.c
+++ b/usr.bin/make/cond.c
@@ -1034,16 +1034,14 @@ CondE(Boolean doEval)
*-----------------------------------------------------------------------
*/
int
-Cond_Eval(char *line)
+Cond_Eval(char *line, int lineno)
{
struct If *ifp;
Boolean isElse;
Boolean value = FALSE;
int level; /* Level at which to report errors. */
- int lineno;
level = PARSE_FATAL;
- lineno = curFile.lineno;
for (line++; *line == ' ' || *line == '\t'; line++) {
continue;
diff --git a/usr.bin/make/cond.h b/usr.bin/make/cond.h
index 1bae63adcb7d..ecd9a8023c89 100644
--- a/usr.bin/make/cond.h
+++ b/usr.bin/make/cond.h
@@ -48,7 +48,7 @@
#define COND_SKIP 1 /* Skip the next lines */
#define COND_INVALID 2 /* Not a conditional statement */
-int Cond_Eval(char *);
+int Cond_Eval(char *, int);
void Cond_End(void);
#endif /* cond_h_6e96ad7c */
diff --git a/usr.bin/make/globals.h b/usr.bin/make/globals.h
index c0b50502b7c2..8b87ba3d8c84 100644
--- a/usr.bin/make/globals.h
+++ b/usr.bin/make/globals.h
@@ -51,7 +51,6 @@
#include "sprite.h"
struct GNode;
-struct IFile;
struct Path;
/*
@@ -63,8 +62,6 @@ extern Lst create;
/* The list of directories to search when looking for targets */
extern struct Path dirSearchPath;
-extern struct IFile curFile; /* current makefile */
-
/* The list of directories to search when looking for includes */
extern struct Path parseIncPath;
diff --git a/usr.bin/make/parse.c b/usr.bin/make/parse.c
index 364ca3f716a6..ad771bc6da77 100644
--- a/usr.bin/make/parse.c
+++ b/usr.bin/make/parse.c
@@ -81,6 +81,7 @@ __FBSDID("$FreeBSD$");
* Parse_MainName Returns a Lst of the main target to create.
*/
+#include <assert.h>
#include <ctype.h>
#include <stdarg.h>
#include <string.h>
@@ -107,7 +108,7 @@ __FBSDID("$FreeBSD$");
#include "var.h"
/*
- * These values are returned by ParseEOF to tell Parse_File whether to
+ * These values are returned by ParsePopInput to tell Parse_File whether to
* CONTINUE parsing, i.e. it had only reached the end of an include file,
* or if it's DONE.
*/
@@ -128,10 +129,23 @@ static int fatals = 0;
*/
static GNode *mainNode;
-IFile curFile; /* current makefile */
+/*
+ * Definitions for handling #include specifications
+ */
+struct IFile {
+ char *fname; /* name of previous file */
+ int lineno; /* saved line number */
+ FILE *F; /* the open stream */
+ char *str; /* the string when parsing a string */
+ char *ptr; /* the current pointer when parsing a string */
+ TAILQ_ENTRY(IFile) link;/* stack the files */
+};
/* stack of IFiles generated by * #includes */
-static Lst includes = Lst_Initializer(includes);
+static TAILQ_HEAD(, IFile) includes = TAILQ_HEAD_INITIALIZER(includes);
+
+/* access current file */
+#define CURFILE (TAILQ_FIRST(&includes))
/* list of directories for "..." includes */
struct Path parseIncPath = TAILQ_HEAD_INITIALIZER(parseIncPath);
@@ -228,8 +242,6 @@ static struct {
{ ".WAIT", Wait, 0 },
};
-static int ParseEOF(int);
-
/*-
*----------------------------------------------------------------------
* ParseFindKeyword --
@@ -287,7 +299,7 @@ Parse_Error(int type, const char *fmt, ...)
va_list ap;
va_start(ap, fmt);
- fprintf(stderr, "\"%s\", line %d: ", curFile.fname, curFile.lineno);
+ fprintf(stderr, "\"%s\", line %d: ", CURFILE->fname, CURFILE->lineno);
if (type == PARSE_WARNING)
fprintf(stderr, "warning: ");
vfprintf(stderr, fmt, ap);
@@ -298,6 +310,81 @@ Parse_Error(int type, const char *fmt, ...)
fatals += 1;
}
+/**
+ * ParsePushInput
+ *
+ * Push a new input source onto the input stack. If ptr is NULL
+ * the fullname is used to fopen the file. If it is not NULL,
+ * ptr is assumed to point to the string to be parsed. If opening the
+ * file fails, the fullname is freed.
+ */
+static void
+ParsePushInput(char *fullname, FILE *fp, char *ptr, int lineno)
+{
+ struct IFile *nf;
+
+ nf = emalloc(sizeof(*nf));
+ nf->fname = fullname;
+ nf->lineno = lineno;
+
+ if (ptr == NULL) {
+ /* the input source is a file */
+ if ((nf->F = fp) == NULL) {
+ nf->F = fopen(fullname, "r");
+ if (nf->F == NULL) {
+ Parse_Error(PARSE_FATAL, "Cannot open %s",
+ fullname);
+ free(fullname);
+ free(nf);
+ return;
+ }
+ }
+ nf->str = nf->ptr = NULL;
+ Var_Append(".MAKEFILE_LIST", fullname, VAR_GLOBAL);
+ } else {
+ nf->str = nf->ptr = ptr;
+ nf->F = NULL;
+ }
+ TAILQ_INSERT_HEAD(&includes, nf, link);
+}
+
+/**
+ * ParsePopInput
+ * Called when EOF is reached in the current file. If we were reading
+ * an include file, the includes stack is popped and things set up
+ * to go back to reading the previous file at the previous location.
+ *
+ * Results:
+ * CONTINUE if there's more to do. DONE if not.
+ *
+ * Side Effects:
+ * The old curFile.F is closed. The includes list is shortened.
+ * curFile.lineno, curFile.F, and curFile.fname are changed if
+ * CONTINUE is returned.
+ */
+static int
+ParsePopInput(void)
+{
+ struct IFile *ifile; /* the state on the top of the includes stack */
+
+ assert(!TAILQ_EMPTY(&includes));
+
+ ifile = TAILQ_FIRST(&includes);
+ TAILQ_REMOVE(&includes, ifile, link);
+
+ free(ifile->fname);
+ if (ifile->F != NULL) {
+ fclose(ifile->F);
+ Var_Append(".MAKEFILE_LIST", "..", VAR_GLOBAL);
+ }
+ if (ifile->str != NULL) {
+ free(ifile->str);
+ }
+ free(ifile);
+
+ return (TAILQ_EMPTY(&includes) ? DONE : CONTINUE);
+}
+
/*-
*---------------------------------------------------------------------
* ParseLinkSrc --
@@ -1536,15 +1623,13 @@ ParseDoWarning(char *warnmsg)
* None
*
* Side Effects:
- * A structure is added to the includes Lst and readProc, curFile.lineno,
- * curFile.fname and curFile.F are altered for the new file
+ * A structure is added to the includes Lst and readProc.
*---------------------------------------------------------------------
*/
static void
ParseDoInclude(char *file)
{
char *fullname; /* full pathname of file */
- IFile *oldFile; /* state associated with current file */
char endc; /* the character which ends the file spec */
char *cp; /* current position in file spec */
Boolean isSystem; /* TRUE if makefile is a system makefile */
@@ -1613,7 +1698,7 @@ ParseDoInclude(char *file)
char *prefEnd, *Fname;
/* Make a temporary copy of this, to be safe. */
- Fname = estrdup(curFile.fname);
+ Fname = estrdup(CURFILE->fname);
prefEnd = strrchr(Fname, '/');
if (prefEnd != (char *)NULL) {
@@ -1671,37 +1756,11 @@ ParseDoInclude(char *file)
free(file);
/*
- * Once we find the absolute path to the file, we get to save all the
- * state from the current file before we can start reading this
- * include file. The state is stored in an IFile structure which
- * is placed on a list with other IFile structures. The list makes
- * a very nice stack to track how we got here...
- */
- oldFile = emalloc(sizeof(IFile));
- memcpy(oldFile, &curFile, sizeof(IFile));
-
- Lst_AtFront(&includes, oldFile);
-
- /*
- * Once the previous state has been saved, we can get down to reading
- * the new file. We set up the name of the file to be the absolute
+ * We set up the name of the file to be the absolute
* name of the include file so error messages refer to the right
- * place. Naturally enough, we start reading at line number 0.
+ * place.
*/
- curFile.fname = fullname;
- curFile.lineno = 0;
-
- curFile.F = fopen(fullname, "r");
- curFile.p = NULL;
- if (curFile.F == NULL) {
- Parse_Error(PARSE_FATAL, "Cannot open %s", fullname);
- /*
- * Pop to previous file
- */
- ParseEOF(0);
- } else {
- Var_Append(".MAKEFILE_LIST", fullname, VAR_GLOBAL);
- }
+ ParsePushInput(fullname, NULL, NULL, 0);
}
/*-
@@ -1720,20 +1779,10 @@ ParseDoInclude(char *file)
void
Parse_FromString(char *str, int lineno)
{
- IFile *oldFile; /* state associated with this file */
DEBUGF(FOR, ("%s\n---- at line %d\n", str, lineno));
- oldFile = emalloc(sizeof(IFile));
- memcpy(oldFile, &curFile, sizeof(IFile));
-
- Lst_AtFront(&includes, oldFile);
-
- curFile.F = NULL;
- curFile.p = emalloc(sizeof(PTR));
- curFile.p->str = curFile.p->ptr = str;
- curFile.lineno = lineno;
- curFile.fname = estrdup(curFile.fname);
+ ParsePushInput(estrdup(CURFILE->fname), NULL, str, lineno);
}
#ifdef SYSVINCLUDE
@@ -1757,7 +1806,6 @@ static void
ParseTraditionalInclude(char *file)
{
char *fullname; /* full pathname of file */
- IFile *oldFile; /* state associated with current file */
char *cp; /* current position in file spec */
Buffer *buf;
@@ -1816,83 +1864,16 @@ ParseTraditionalInclude(char *file)
/* XXXHB free(file) */
/*
- * Once we find the absolute path to the file, we get to save all the
- * state from the current file before we can start reading this
- * include file. The state is stored in an IFile structure which
- * is placed on a list with other IFile structures. The list makes
- * a very nice stack to track how we got here...
- */
- oldFile = emalloc(sizeof(IFile));
- memcpy(oldFile, &curFile, sizeof(IFile));
-
- Lst_AtFront(&includes, oldFile);
-
- /*
- * Once the previous state has been saved, we can get down to reading
- * the new file. We set up the name of the file to be the absolute
+ * We set up the name of the file to be the absolute
* name of the include file so error messages refer to the right
- * place. Naturally enough, we start reading at line number 0.
+ * place.
*/
- curFile.fname = fullname;
- curFile.lineno = 0;
-
- curFile.F = fopen(fullname, "r");
- curFile.p = NULL;
- if (curFile.F == NULL) {
- Parse_Error(PARSE_FATAL, "Cannot open %s", fullname);
- /*
- * Pop to previous file
- */
- ParseEOF(1);
- } else {
- Var_Append(".MAKEFILE_LIST", fullname, VAR_GLOBAL);
- }
+ ParsePushInput(fullname, NULL, NULL, 0);
}
#endif
/*-
*---------------------------------------------------------------------
- * ParseEOF --
- * Called when EOF is reached in the current file. If we were reading
- * an include file, the includes stack is popped and things set up
- * to go back to reading the previous file at the previous location.
- *
- * Results:
- * CONTINUE if there's more to do. DONE if not.
- *
- * Side Effects:
- * The old curFile.F is closed. The includes list is shortened.
- * curFile.lineno, curFile.F, and curFile.fname are changed if
- * CONTINUE is returned.
- *---------------------------------------------------------------------
- */
-static int
-ParseEOF(int opened)
-{
- IFile *ifile; /* the state on the top of the includes stack */
-
- if (Lst_IsEmpty(&includes)) {
- Var_Append(".MAKEFILE_LIST", "..", VAR_GLOBAL);
- return (DONE);
- }
-
- ifile = Lst_DeQueue(&includes);
- free(curFile.fname);
- if (opened && curFile.F) {
- fclose(curFile.F);
- Var_Append(".MAKEFILE_LIST", "..", VAR_GLOBAL);
- }
- if (curFile.p) {
- free(curFile.p->str);
- free(curFile.p);
- }
- memcpy(&curFile, ifile, sizeof(IFile));
- free(ifile);
- return (CONTINUE);
-}
-
-/*-
- *---------------------------------------------------------------------
* ParseReadc --
* Read a character from the current file
*
@@ -1906,11 +1887,12 @@ static int
ParseReadc(void)
{
- if (curFile.F)
- return (fgetc(curFile.F));
+ if (CURFILE->F != NULL)
+ return (fgetc(CURFILE->F));
+
+ if (CURFILE->str != NULL && *CURFILE->ptr != '\0')
+ return (*CURFILE->ptr++);
- if (curFile.p && *curFile.p->ptr)
- return (*curFile.p->ptr++);
return (EOF);
}
@@ -1930,12 +1912,12 @@ static void
ParseUnreadc(int c)
{
- if (curFile.F) {
- ungetc(c, curFile.F);
+ if (CURFILE->F != NULL) {
+ ungetc(c, CURFILE->F);
return;
}
- if (curFile.p) {
- *--(curFile.p->ptr) = c;
+ if (CURFILE->str != NULL) {
+ *--(CURFILE->ptr) = c;
return;
}
}
@@ -1974,7 +1956,7 @@ ParseSkipLine(int skip, int keep_newline)
Buf_AddByte(buf, (Byte)c);
else
Buf_ReplaceLastByte(buf, (Byte)' ');
- curFile.lineno++;
+ CURFILE->lineno++;
while ((c = ParseReadc()) == ' ' || c == '\t')
continue;
@@ -1994,7 +1976,7 @@ ParseSkipLine(int skip, int keep_newline)
return (NULL);
}
- curFile.lineno++;
+ CURFILE->lineno++;
Buf_AddByte(buf, (Byte)'\0');
line = Buf_Data(buf);
} while (skip == 1 && line[0] != '.');
@@ -2053,7 +2035,7 @@ ParseReadLine(void)
ignComment = ignDepOp = TRUE;
break;
} else if (c == '\n') {
- curFile.lineno++;
+ CURFILE->lineno++;
} else if (c == '#') {
ParseUnreadc(c);
break;
@@ -2084,7 +2066,7 @@ ParseReadLine(void)
* it will be recognized as a newline in the
* code below this...
*/
- curFile.lineno++;
+ CURFILE->lineno++;
lastc = ' ';
while ((c = ParseReadc()) == ' ' || c == '\t') {
continue;
@@ -2202,7 +2184,7 @@ ParseReadLine(void)
lastc = c;
}
line_read:
- curFile.lineno++;
+ CURFILE->lineno++;
if (lastc != '\0') {
Buf_AddByte(buf, (Byte)lastc);
@@ -2230,7 +2212,7 @@ ParseReadLine(void)
* The line might be a conditional. Ask the
* conditional module about it and act accordingly
*/
- switch (Cond_Eval(line)) {
+ switch (Cond_Eval(line, CURFILE->lineno)) {
case COND_SKIP:
/*
* Skip to next conditional that evaluates to
@@ -2239,7 +2221,9 @@ ParseReadLine(void)
do {
free(line);
line = ParseSkipLine(1, 0);
- } while (line && Cond_Eval(line) != COND_PARSE);
+ } while (line &&
+ Cond_Eval(line, CURFILE->lineno) !=
+ COND_PARSE);
if (line == NULL)
break;
/*FALLTHRU*/
@@ -2253,7 +2237,7 @@ ParseReadLine(void)
if (For_Eval(line)) {
int ok;
free(line);
- lineno = curFile.lineno;
+ lineno = CURFILE->lineno;
do {
/*
* Skip after the matching end
@@ -2334,19 +2318,16 @@ ParseFinishLine(void)
*---------------------------------------------------------------------
*/
void
-Parse_File(char *name, FILE *stream)
+Parse_File(const char *name, FILE *stream)
{
char *cp; /* pointer into the line */
char *line; /* the line we're working on */
Buffer *buf;
inLine = FALSE;
- curFile.fname = name;
- curFile.F = stream;
- curFile.lineno = 0;
fatals = 0;
- Var_Append(".MAKEFILE_LIST", name, VAR_GLOBAL);
+ ParsePushInput(estrdup(name), stream, NULL, 0);
do {
while ((line = ParseReadLine()) != NULL) {
@@ -2507,7 +2488,7 @@ Parse_File(char *name, FILE *stream)
/*
* Reached EOF, but it may be just EOF of an include file...
*/
- } while (ParseEOF(1) == CONTINUE);
+ } while (ParsePopInput() == CONTINUE);
ParseFinishLine();
diff --git a/usr.bin/make/parse.h b/usr.bin/make/parse.h
index 04c4df7c22e7..867835b5cb61 100644
--- a/usr.bin/make/parse.h
+++ b/usr.bin/make/parse.h
@@ -48,26 +48,12 @@
struct GNode;
struct Lst;
-/*
- * Definitions for handling #include specifications
- */
-typedef struct {
- char *str;
- char *ptr;
-} PTR;
-typedef struct IFile {
- char *fname; /* name of previous file */
- int lineno; /* saved line number */
- FILE *F; /* the open stream */
- PTR *p; /* the char pointer */
-} IFile;
-
void Parse_Error(int, const char *, ...);
Boolean Parse_AnyExport(void);
Boolean Parse_IsVar(char *);
void Parse_DoVar(char *, struct GNode *);
void Parse_AddIncludeDir(char *);
-void Parse_File(char *, FILE *);
+void Parse_File(const char *, FILE *);
void Parse_Init(void);
void Parse_FromString(char *, int);
void Parse_MainName(struct Lst *);