=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/make/lowparse.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- src/usr.bin/make/lowparse.c 2001/05/14 12:55:48 1.8 +++ src/usr.bin/make/lowparse.c 2001/05/23 12:34:45 1.9 @@ -1,5 +1,5 @@ /* $OpenPackages$ */ -/* $OpenBSD: lowparse.c,v 1.8 2001/05/14 12:55:48 espie Exp $ */ +/* $OpenBSD: lowparse.c,v 1.9 2001/05/23 12:34:45 espie Exp $ */ /* low-level parsing functions. */ @@ -30,114 +30,95 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include -#include #include -#include "make.h" +#include +#include +#include +#include "config.h" +#include "defines.h" #include "buf.h" #include "lowparse.h" +#include "error.h" +#include "lst.h" +#include "memory.h" -#ifdef CLEANUP +/* XXX check whether we can free filenames at the end, for a proper + * definition of `end'. */ + +#if 0 static LIST fileNames; /* file names to free at end */ #endif -/* Definitions for handling #include specifications */ -typedef struct IFile_ { - char *fname; /* name of file */ - unsigned long lineno; /* line number */ - FILE *F; /* open stream */ - char *str; /* read from char area */ - char *ptr; /* where we are */ - char *end; /* don't overdo it */ +/* Input stream structure, file or string. */ +typedef struct { + const char *fname; /* Name of file */ + unsigned long lineno; /* Line number */ + FILE *F; /* Open stream, or NULL if pure string. */ + char *str; /* Input string, if F == NULL. */ + + /* Line buffer. */ + char *ptr; /* Where we are. */ + char *end; /* Don't overdo it. */ } IFile; -static IFile *current; +static IFile *current; /* IFile being parsed. */ -static LIST includes; /* stack of IFiles generated by - * #includes */ +static LIST input_stack; /* Stack of IFiles waiting to be parsed + * (includes and loop reparses) */ -static IFile *new_ifile(char *, FILE *); -static IFile *new_istring(char *, char *, unsigned long); +/* IFile ctors. + * + * obj = new_ifile(filename, filehandle); + * Create input object from filename, filehandle. */ +static IFile *new_ifile(const char *, FILE *); +/* obj = new_istring(str, filename, lineno); + * Create input object from str, filename, lineno. */ +static IFile *new_istring(char *, const char *, unsigned long); +/* free_ifile(obj); + * Discard consumed input object, closing streams, freeing memory. */ static void free_ifile(IFile *); -static void ParseVErrorInternal(char *, unsigned long, int, char *, va_list); + + +/* Handling basic character reading. + * c = ParseReadc(); + * New character c from current input stream, or EOF at end of stream. */ +#define ParseReadc() current->ptr < current->end ? *current->ptr++ : newline() +/* len = newline(); + * Guts for ParseReadc. Grabs a new line off fgetln when we have + * consumed the current line and returns its length. Or EOF at end of + * stream. */ static int newline(void); +/* c = skiptoendofline(); + * Skips to the end of the current line, returns either '\n' or EOF. */ static int skiptoendofline(void); -static void ParseFoldLF(Buffer, int); -static int ParseSkipEmptyLines(Buffer); -static int fatals = 0; -/*- - * ParseVErrorInternal -- - * Error message abort function for parsing. Prints out the context - * of the error (line number and file) as well as the message with - * two optional arguments. - * - * Side Effects: - * "fatals" is incremented if the level is PARSE_FATAL. - */ -/* VARARGS */ -static void -#ifdef __STDC__ -ParseVErrorInternal(char *cfname, unsigned long clineno, int type, char *fmt, - va_list ap) -#else -ParseVErrorInternal(va_alist) - va_dcl -#endif -{ - (void)fprintf(stderr, "\"%s\", line %lu: ", cfname, clineno); - if (type == PARSE_WARNING) - (void)fprintf(stderr, "warning: "); - (void)vfprintf(stderr, fmt, ap); - va_end(ap); - (void)fprintf(stderr, "\n"); - if (type == PARSE_FATAL) - fatals ++; -} -/*- - * Parse_Error -- - * External interface to ParseVErrorInternal; uses the default filename - * Line number. - */ -/* VARARGS */ -void -#ifdef __STDC__ -Parse_Error(int type, char *fmt, ...) -#else -Parse_Error(va_alist) - va_dcl -#endif -{ - va_list ap; -#ifdef __STDC__ - va_start(ap, fmt); -#else - int type; /* Error type (PARSE_WARNING, PARSE_FATAL) */ - char *fmt; +/* Helper functions to handle basic parsing. */ +/* ParseFoldLF(buffer, firstchar); + * Grabs logical line into buffer, the first character has already been + * read into firstchar. */ +static void ParseFoldLF(Buffer, int); - va_start(ap); - type = va_arg(ap, int); - fmt = va_arg(ap, char *); -#endif +/* firstchar = ParseSkipEmptyLines(buffer); + * Scans lines, skipping empty lines. May put some characters into + * buffer, returns the first character useful to continue parsing + * (e.g., not a backslash or a space. */ +static int ParseSkipEmptyLines(Buffer); - ParseVErrorInternal(current->fname, current->lineno, type, fmt, ap); -} - static IFile * new_ifile(name, stream) - char *name; + const char *name; FILE *stream; { IFile *ifile; -#ifdef CLEANUP +#if 0 Lst_AtEnd(&fileNames, name); #endif ifile = emalloc(sizeof(*ifile)); ifile->fname = name; ifile->str = NULL; - /* Naturally enough, we start reading at line 0 */ + /* Naturally enough, we start reading at line 0. */ ifile->lineno = 0; ifile->F = stream; ifile->ptr = ifile->end = NULL; @@ -159,7 +140,7 @@ static IFile * new_istring(str, name, lineno) char *str; - char *name; + const char *name; unsigned long lineno; { IFile *ifile; @@ -168,7 +149,8 @@ /* No malloc, name is always taken from an already existing ifile */ ifile->fname = name; ifile->F = NULL; - /* Strings are used from for loops... */ + /* Strings are used in for loops, so we need to reset the line counter + * to an appropriate value. */ ifile->lineno = lineno; ifile->ptr = ifile->str = str; ifile->end = str + strlen(str); @@ -176,16 +158,6 @@ } -/*- - *--------------------------------------------------------------------- - * Parse_FromString -- - * Start Parsing from the given string - * - * Side Effects: - * A structure is added to the includes Lst and readProc, lineno, - * fname and curFILE are altered for the new file - *--------------------------------------------------------------------- - */ void Parse_FromString(str, lineno) char *str; @@ -195,52 +167,30 @@ (void)fprintf(stderr, "%s\n----\n", str); if (current != NULL) - Lst_AtFront(&includes, current); + Lst_Push(&input_stack, current); current = new_istring(str, current->fname, lineno); } void Parse_FromFile(name, stream) - char *name; + const char *name; FILE *stream; { if (current != NULL) - Lst_AtFront(&includes, current); + Lst_Push(&input_stack, current); current = new_ifile(name, stream); } -/*- - *--------------------------------------------------------------------- - * Parse_NextFile -- - * 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, is closed. The includes list is shortened. - * lineno, curFILE, and fname are changed if CONTINUE is returned. - *--------------------------------------------------------------------- - */ -Boolean +bool Parse_NextFile() { - IFile *next; - - next = (IFile *)Lst_DeQueue(&includes); - if (next != NULL) { - if (current != NULL) - free_ifile(current); - current = next; - return TRUE; - } else - return FALSE; + if (current != NULL) + free_ifile(current); + current = (IFile *)Lst_Pop(&input_stack); + return current != NULL; } -/* guts for ParseReadc. Grab a new line off fgetln when we hit "\n" */ static int newline() { @@ -258,10 +208,6 @@ return EOF; } -#define ParseReadc() current->ptr < current->end ? *current->ptr++ : newline() - -/* Take advantage of fgetln: we don't have to scan a whole line to skip it. - */ static int skiptoendofline() { @@ -282,11 +228,8 @@ } -/* ParseSkipGetLine(): - * Return the first logical line that starts with '.' - */ char * -ParseSkipGetLine(linebuf) +Parse_ReadNextConditionalLine(linebuf) Buffer linebuf; { int c; @@ -308,11 +251,9 @@ } /* This is the line we need to copy */ - return ParseGetLine(linebuf, "conditional"); + return Parse_ReadUnparsedLine(linebuf, "conditional"); } -/* Grab logical line into linebuf. - * The first character is already in c. */ static void ParseFoldLF(linebuf, c) Buffer linebuf; @@ -347,11 +288,8 @@ } } -/* ParseGetLine: - * Simply get line, no parsing beyond \ - */ char * -ParseGetLine(linebuf, type) +Parse_ReadUnparsedLine(linebuf, type) Buffer linebuf; const char *type; { @@ -386,10 +324,8 @@ return Buf_Retrieve(linebuf); } -/* Skip all empty lines, and return the first `useful' character. - * (This does skip blocks of comments at high speed, which justifies - * the complexity of the function.) - */ +/* This is a fairly complex function, but without it, we could not skip + * blocks of comments without reading them. */ static int ParseSkipEmptyLines(linebuf) Buffer linebuf; @@ -462,24 +398,18 @@ } } -/*- - *--------------------------------------------------------------------- - * ParseReadLine -- - * Read an entire line from the input file. +/* Parse_ReadNormalLine removes beginning and trailing blanks (but keeps + * the first tab), handles escaped newlinews, and skip over uninteresting + * lines. * - * Results: - * A line without a new line, or NULL at EOF. + * The line number is advanced, which implies that continuation + * lines are numbered with the last line no (we could do better, at a + * price). * - * Notes: - * Removes beginning and trailing blanks (but keeps first tab). - * Updates line numbers, handles escaped newlines, and skip over - * uninteresting lines. - * All but trivial comments can't be handled at this point, because we - * don't know yet which lines are shell commands or not. - *--------------------------------------------------------------------- - */ + * Trivial comments are also removed, but we can't do more, as + * we don't know which lines are shell commands or not. */ char * -ParseReadLine(linebuf) +Parse_ReadNormalLine(linebuf) Buffer linebuf; { int c; /* the current character */ @@ -511,27 +441,31 @@ void LowParse_Init() { - Lst_Init(&includes); + Lst_Init(&input_stack); current = NULL; } void LowParse_End() { - Lst_Destroy(&includes, NOFREE); /* Should be empty now */ + Lst_Destroy(&input_stack, NOFREE); /* Should be empty now */ +#ifdef 0 + Lst_Destroy(&fileNames, (SimpleProc)free); +#endif } #endif void -Finish_Errors() +Parse_ReportErrors() { - if (current != NULL) { - free_ifile(current); - current = NULL; - } - if (fatals) { + if (fatal_errors) { +#ifdef CLEANUP + while (Parse_NextFile()) + ; +#endif fprintf(stderr, "Fatal errors encountered -- cannot continue\n"); exit(1); - } + } else + assert(current == NULL); }