Reworked the fix to print the useful line number on error in
the .for loop: - Replaced four global variables in parse.c with one. - Made Parse_FromString() accept the "lineno" as an argument. - Fixed line numbering when there are escaped newlines in the body of the .for loop. Adopted from: NetBSD
This commit is contained in:
parent
39a78f8cf4
commit
30b800de8e
@ -81,6 +81,7 @@ typedef struct _For {
|
||||
Buffer buf; /* Unexpanded buffer */
|
||||
char* var; /* Index name */
|
||||
Lst lst; /* List of variables */
|
||||
int lineno; /* Line # */
|
||||
} For;
|
||||
|
||||
static int ForExec(void *, void *);
|
||||
@ -254,7 +255,7 @@ ForExec(void *namep, void *argp)
|
||||
Var_Set(arg->var, name, VAR_GLOBAL);
|
||||
DEBUGF(FOR, ("--- %s = %s\n", arg->var, name));
|
||||
Parse_FromString(Var_Subst(arg->var, (char *) Buf_GetAll(arg->buf, &len),
|
||||
VAR_GLOBAL, FALSE));
|
||||
VAR_GLOBAL, FALSE), arg->lineno);
|
||||
Var_Delete(arg->var, VAR_GLOBAL);
|
||||
|
||||
return 0;
|
||||
@ -275,7 +276,7 @@ ForExec(void *namep, void *argp)
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
void
|
||||
For_Run(void)
|
||||
For_Run(int lineno)
|
||||
{
|
||||
For arg;
|
||||
|
||||
@ -284,6 +285,7 @@ For_Run(void)
|
||||
arg.var = forVar;
|
||||
arg.buf = forBuf;
|
||||
arg.lst = forLst;
|
||||
arg.lineno = lineno;
|
||||
forVar = NULL;
|
||||
forBuf = NULL;
|
||||
forLst = NULL;
|
||||
|
@ -59,7 +59,7 @@ void Cond_End(void);
|
||||
|
||||
/* for.c */
|
||||
int For_Eval(char *);
|
||||
void For_Run(void);
|
||||
void For_Run(int);
|
||||
|
||||
/* main.c */
|
||||
void Main_ParseArgLine(char *);
|
||||
@ -86,7 +86,7 @@ void Parse_AddIncludeDir(char *);
|
||||
void Parse_File(char *, FILE *);
|
||||
void Parse_Init(void);
|
||||
void Parse_End(void);
|
||||
void Parse_FromString(char *);
|
||||
void Parse_FromString(char *, int);
|
||||
Lst Parse_MainName(void);
|
||||
|
||||
/* str.c */
|
||||
|
@ -55,9 +55,9 @@ __FBSDID("$FreeBSD$");
|
||||
* those for the #include <...> are kept in the 'sysIncPath' Lst. The
|
||||
* targets currently being defined are kept in the 'targets' Lst.
|
||||
*
|
||||
* The variables 'fname' and 'lineno' are used to track the name
|
||||
* of the current file and the line number in that file so that error
|
||||
* messages can be more meaningful.
|
||||
* The variables 'curFile.fname' and 'curFile.lineno' are used to track
|
||||
* the name of the current file and the line number in that file so that
|
||||
* error messages can be more meaningful.
|
||||
*
|
||||
* Interface:
|
||||
* Parse_Init Initialization function which must be
|
||||
@ -110,13 +110,6 @@ typedef struct {
|
||||
char *ptr;
|
||||
} PTR;
|
||||
|
||||
static char *fname; /* name of current file (for errors) */
|
||||
static int lineno; /* line number in current file */
|
||||
static int savedlineno; /* saved line number */
|
||||
static FILE *curFILE = NULL; /* current makefile */
|
||||
|
||||
static PTR *curPTR = NULL; /* current makefile */
|
||||
|
||||
static int fatals = 0;
|
||||
|
||||
static GNode *mainNode; /* The main target to create. This is the
|
||||
@ -132,6 +125,8 @@ typedef struct IFile {
|
||||
PTR * p; /* the char pointer */
|
||||
} IFile;
|
||||
|
||||
static IFile curFile;
|
||||
|
||||
static Lst includes; /* stack of IFiles generated by
|
||||
* #includes */
|
||||
Lst parseIncPath; /* list of directories for "..." includes */
|
||||
@ -251,7 +246,7 @@ static void ParseTraditionalInclude(char *);
|
||||
#endif
|
||||
static int ParseEOF(int);
|
||||
static char *ParseReadLine(void);
|
||||
static char *ParseSkipLine(int);
|
||||
static char *ParseSkipLine(int, int);
|
||||
static void ParseFinishLine(void);
|
||||
|
||||
/*-
|
||||
@ -311,7 +306,8 @@ Parse_Error(int type, const char *fmt, ...)
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
(void)fprintf(stderr, "\"%s\", line %d: ", fname, lineno);
|
||||
(void)fprintf(stderr, "\"%s\", line %d: ",
|
||||
curFile.fname, curFile.lineno);
|
||||
if (type == PARSE_WARNING)
|
||||
(void)fprintf(stderr, "warning: ");
|
||||
(void)vfprintf(stderr, fmt, ap);
|
||||
@ -1576,7 +1572,8 @@ ParseDoError(char *errmsg)
|
||||
errmsg = Var_Subst(NULL, errmsg, VAR_GLOBAL, FALSE);
|
||||
|
||||
/* use fprintf/exit instead of Parse_Error to terminate immediately */
|
||||
fprintf(stderr, "\"%s\", line %d: %s\n", fname, lineno, errmsg);
|
||||
fprintf(stderr, "\"%s\", line %d: %s\n",
|
||||
curFile.fname, curFile.lineno, errmsg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -1594,8 +1591,8 @@ ParseDoError(char *errmsg)
|
||||
* None
|
||||
*
|
||||
* Side Effects:
|
||||
* A structure is added to the includes Lst and readProc, lineno,
|
||||
* fname and curFILE are altered for the new file
|
||||
* A structure is added to the includes Lst and readProc, curFile.lineno,
|
||||
* curFile.fname and curFile.F are altered for the new file
|
||||
*---------------------------------------------------------------------
|
||||
*/
|
||||
static void
|
||||
@ -1670,7 +1667,7 @@ ParseDoInclude (char *file)
|
||||
char *prefEnd, *Fname;
|
||||
|
||||
/* Make a temporary copy of this, to be safe. */
|
||||
Fname = estrdup(fname);
|
||||
Fname = estrdup(curFile.fname);
|
||||
|
||||
prefEnd = strrchr (Fname, '/');
|
||||
if (prefEnd != (char *)NULL) {
|
||||
@ -1732,11 +1729,7 @@ ParseDoInclude (char *file)
|
||||
* a very nice stack to track how we got here...
|
||||
*/
|
||||
oldFile = (IFile *) emalloc (sizeof (IFile));
|
||||
oldFile->fname = fname;
|
||||
|
||||
oldFile->F = curFILE;
|
||||
oldFile->p = curPTR;
|
||||
oldFile->lineno = lineno;
|
||||
memcpy(oldFile, &curFile, sizeof (IFile));
|
||||
|
||||
(void) Lst_AtFront (includes, (void *)oldFile);
|
||||
|
||||
@ -1746,12 +1739,12 @@ ParseDoInclude (char *file)
|
||||
* name of the include file so error messages refer to the right
|
||||
* place. Naturally enough, we start reading at line number 0.
|
||||
*/
|
||||
fname = fullname;
|
||||
lineno = 0;
|
||||
curFile.fname = fullname;
|
||||
curFile.lineno = 0;
|
||||
|
||||
curFILE = fopen (fullname, "r");
|
||||
curPTR = NULL;
|
||||
if (curFILE == (FILE * ) NULL) {
|
||||
curFile.F = fopen (fullname, "r");
|
||||
curFile.p = NULL;
|
||||
if (curFile.F == (FILE * ) NULL) {
|
||||
Parse_Error (PARSE_FATAL, "Cannot open %s", fullname);
|
||||
/*
|
||||
* Pop to previous file
|
||||
@ -1771,30 +1764,27 @@ ParseDoInclude (char *file)
|
||||
* None
|
||||
*
|
||||
* Side Effects:
|
||||
* A structure is added to the includes Lst and readProc, lineno,
|
||||
* fname and curFILE are altered for the new file
|
||||
* A structure is added to the includes Lst and readProc, curFile.lineno,
|
||||
* curFile.fname and curFile.F are altered for the new file
|
||||
*---------------------------------------------------------------------
|
||||
*/
|
||||
void
|
||||
Parse_FromString(char *str)
|
||||
Parse_FromString(char *str, int lineno)
|
||||
{
|
||||
IFile *oldFile; /* state associated with this file */
|
||||
|
||||
DEBUGF(FOR, ("%s\n----\n", str));
|
||||
DEBUGF(FOR, ("%s\n---- at line %d\n", str, lineno));
|
||||
|
||||
oldFile = (IFile *) emalloc (sizeof (IFile));
|
||||
oldFile->lineno = lineno;
|
||||
oldFile->fname = fname;
|
||||
oldFile->F = curFILE;
|
||||
oldFile->p = curPTR;
|
||||
memcpy(oldFile, &curFile, sizeof (IFile));
|
||||
|
||||
(void) Lst_AtFront (includes, (void *)oldFile);
|
||||
|
||||
curFILE = NULL;
|
||||
curPTR = (PTR *) emalloc (sizeof (PTR));
|
||||
curPTR->str = curPTR->ptr = str;
|
||||
lineno = savedlineno;
|
||||
fname = estrdup(fname);
|
||||
curFile.F = NULL;
|
||||
curFile.p = (PTR *) emalloc (sizeof (PTR));
|
||||
curFile.p->str = curFile.p->ptr = str;
|
||||
curFile.lineno = lineno;
|
||||
curFile.fname = estrdup(curFile.fname);
|
||||
}
|
||||
|
||||
|
||||
@ -1811,8 +1801,8 @@ Parse_FromString(char *str)
|
||||
* None
|
||||
*
|
||||
* Side Effects:
|
||||
* A structure is added to the includes Lst and readProc, lineno,
|
||||
* fname and curFILE are altered for the new file
|
||||
* A structure is added to the includes Lst and readProc, curFile.lineno,
|
||||
* curFile.fname and curFile.F are altered for the new file
|
||||
*---------------------------------------------------------------------
|
||||
*/
|
||||
static void
|
||||
@ -1881,11 +1871,7 @@ ParseTraditionalInclude (char *file)
|
||||
* a very nice stack to track how we got here...
|
||||
*/
|
||||
oldFile = (IFile *) emalloc (sizeof (IFile));
|
||||
oldFile->fname = fname;
|
||||
|
||||
oldFile->F = curFILE;
|
||||
oldFile->p = curPTR;
|
||||
oldFile->lineno = lineno;
|
||||
memcpy(oldFile, &curFile, sizeof (IFile));
|
||||
|
||||
(void) Lst_AtFront (includes, (void *)oldFile);
|
||||
|
||||
@ -1895,12 +1881,12 @@ ParseTraditionalInclude (char *file)
|
||||
* name of the include file so error messages refer to the right
|
||||
* place. Naturally enough, we start reading at line number 0.
|
||||
*/
|
||||
fname = fullname;
|
||||
lineno = 0;
|
||||
curFile.fname = fullname;
|
||||
curFile.lineno = 0;
|
||||
|
||||
curFILE = fopen (fullname, "r");
|
||||
curPTR = NULL;
|
||||
if (curFILE == (FILE * ) NULL) {
|
||||
curFile.F = fopen (fullname, "r");
|
||||
curFile.p = NULL;
|
||||
if (curFile.F == (FILE * ) NULL) {
|
||||
Parse_Error (PARSE_FATAL, "Cannot open %s", fullname);
|
||||
/*
|
||||
* Pop to previous file
|
||||
@ -1921,8 +1907,9 @@ ParseTraditionalInclude (char *file)
|
||||
* 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.
|
||||
* 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
|
||||
@ -1935,17 +1922,14 @@ ParseEOF (int opened)
|
||||
}
|
||||
|
||||
ifile = (IFile *) Lst_DeQueue (includes);
|
||||
free (fname);
|
||||
fname = ifile->fname;
|
||||
lineno = ifile->lineno;
|
||||
if (opened && curFILE)
|
||||
(void) fclose (curFILE);
|
||||
if (curPTR) {
|
||||
free(curPTR->str);
|
||||
free(curPTR);
|
||||
free (curFile.fname);
|
||||
if (opened && curFile.F)
|
||||
(void) fclose (curFile.F);
|
||||
if (curFile.p) {
|
||||
free(curFile.p->str);
|
||||
free(curFile.p);
|
||||
}
|
||||
curFILE = ifile->F;
|
||||
curPTR = ifile->p;
|
||||
memcpy(&curFile, ifile, sizeof (IFile));
|
||||
free (ifile);
|
||||
return (CONTINUE);
|
||||
}
|
||||
@ -1964,11 +1948,11 @@ ParseEOF (int opened)
|
||||
static int
|
||||
ParseReadc(void)
|
||||
{
|
||||
if (curFILE)
|
||||
return fgetc(curFILE);
|
||||
if (curFile.F)
|
||||
return fgetc(curFile.F);
|
||||
|
||||
if (curPTR && *curPTR->ptr)
|
||||
return *curPTR->ptr++;
|
||||
if (curFile.p && *curFile.p->ptr)
|
||||
return *curFile.p->ptr++;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
@ -1987,12 +1971,12 @@ ParseReadc(void)
|
||||
static void
|
||||
ParseUnreadc(int c)
|
||||
{
|
||||
if (curFILE) {
|
||||
ungetc(c, curFILE);
|
||||
if (curFile.F) {
|
||||
ungetc(c, curFile.F);
|
||||
return;
|
||||
}
|
||||
if (curPTR) {
|
||||
*--(curPTR->ptr) = c;
|
||||
if (curFile.p) {
|
||||
*--(curFile.p->ptr) = c;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -2003,7 +1987,7 @@ ParseUnreadc(int c)
|
||||
* ignore such lines.
|
||||
*/
|
||||
static char *
|
||||
ParseSkipLine(int skip)
|
||||
ParseSkipLine(int skip, int keep_newline)
|
||||
{
|
||||
char *line;
|
||||
int c, lastc, lineLength = 0;
|
||||
@ -2018,8 +2002,11 @@ ParseSkipLine(int skip)
|
||||
while (((c = ParseReadc()) != '\n' || lastc == '\\')
|
||||
&& c != EOF) {
|
||||
if (c == '\n') {
|
||||
Buf_ReplaceLastByte(buf, (Byte)' ');
|
||||
lineno++;
|
||||
if (keep_newline)
|
||||
Buf_AddByte(buf, (Byte)c);
|
||||
else
|
||||
Buf_ReplaceLastByte(buf, (Byte)' ');
|
||||
curFile.lineno++;
|
||||
|
||||
while ((c = ParseReadc()) == ' ' || c == '\t')
|
||||
continue;
|
||||
@ -2038,7 +2025,7 @@ ParseSkipLine(int skip)
|
||||
return((char *)NULL);
|
||||
}
|
||||
|
||||
lineno++;
|
||||
curFile.lineno++;
|
||||
Buf_AddByte(buf, (Byte)'\0');
|
||||
line = (char *)Buf_GetAll(buf, &lineLength);
|
||||
} while (skip == 1 && line[0] != '.');
|
||||
@ -2079,6 +2066,7 @@ ParseReadLine (void)
|
||||
char *line; /* Result */
|
||||
char *ep; /* to strip trailing blanks */
|
||||
int lineLength; /* Length of result */
|
||||
int lineno; /* Saved line # */
|
||||
|
||||
semiNL = FALSE;
|
||||
ignDepOp = FALSE;
|
||||
@ -2098,7 +2086,7 @@ ParseReadLine (void)
|
||||
ignComment = ignDepOp = TRUE;
|
||||
break;
|
||||
} else if (c == '\n') {
|
||||
lineno++;
|
||||
curFile.lineno++;
|
||||
} else if (c == '#') {
|
||||
ParseUnreadc(c);
|
||||
break;
|
||||
@ -2128,7 +2116,7 @@ ParseReadLine (void)
|
||||
* semi-colon and semiNL is TRUE, it will be recognized as a
|
||||
* newline in the code below this...
|
||||
*/
|
||||
lineno++;
|
||||
curFile.lineno++;
|
||||
lastc = ' ';
|
||||
while ((c = ParseReadc ()) == ' ' || c == '\t') {
|
||||
continue;
|
||||
@ -2229,7 +2217,7 @@ ParseReadLine (void)
|
||||
|
||||
}
|
||||
line_read:
|
||||
lineno++;
|
||||
curFile.lineno++;
|
||||
|
||||
if (lastc != '\0') {
|
||||
Buf_AddByte (buf, (Byte)lastc);
|
||||
@ -2265,7 +2253,7 @@ ParseReadLine (void)
|
||||
*/
|
||||
do {
|
||||
free (line);
|
||||
line = ParseSkipLine(1);
|
||||
line = ParseSkipLine(1, 0);
|
||||
} while (line && Cond_Eval(line) != COND_PARSE);
|
||||
if (line == NULL)
|
||||
break;
|
||||
@ -2278,12 +2266,12 @@ ParseReadLine (void)
|
||||
if (For_Eval(line)) {
|
||||
int ok;
|
||||
free(line);
|
||||
savedlineno = lineno;
|
||||
lineno = curFile.lineno;
|
||||
do {
|
||||
/*
|
||||
* Skip after the matching end
|
||||
*/
|
||||
line = ParseSkipLine(0);
|
||||
line = ParseSkipLine(0, 1);
|
||||
if (line == NULL) {
|
||||
Parse_Error (PARSE_FATAL,
|
||||
"Unexpected end of file in for loop.\n");
|
||||
@ -2294,7 +2282,7 @@ ParseReadLine (void)
|
||||
}
|
||||
while (ok);
|
||||
if (line != NULL)
|
||||
For_Run();
|
||||
For_Run(lineno);
|
||||
line = ParseReadLine();
|
||||
}
|
||||
break;
|
||||
@ -2359,9 +2347,9 @@ Parse_File(char *name, FILE *stream)
|
||||
*line; /* the line we're working on */
|
||||
|
||||
inLine = FALSE;
|
||||
fname = name;
|
||||
curFILE = stream;
|
||||
lineno = 0;
|
||||
curFile.fname = name;
|
||||
curFile.F = stream;
|
||||
curFile.lineno = 0;
|
||||
fatals = 0;
|
||||
|
||||
do {
|
||||
|
Loading…
Reference in New Issue
Block a user