Process escaped characters properly. Now:
foo\:bar: touch $@ works. Of course I am lazy right now, and I am not removing the '\' escapes so the output looks fine, but it is functionally correct.
This commit is contained in:
parent
62a708c06d
commit
933b6f81c0
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: parse.c,v 1.76 2002/01/24 01:39:03 reinoud Exp $ */
|
/* $NetBSD: parse.c,v 1.77 2002/01/26 20:42:14 christos Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1988, 1989, 1990, 1993
|
* Copyright (c) 1988, 1989, 1990, 1993
|
||||||
@ -39,14 +39,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef MAKE_BOOTSTRAP
|
#ifdef MAKE_BOOTSTRAP
|
||||||
static char rcsid[] = "$NetBSD: parse.c,v 1.76 2002/01/24 01:39:03 reinoud Exp $";
|
static char rcsid[] = "$NetBSD: parse.c,v 1.77 2002/01/26 20:42:14 christos Exp $";
|
||||||
#else
|
#else
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
#if 0
|
||||||
static char sccsid[] = "@(#)parse.c 8.3 (Berkeley) 3/19/94";
|
static char sccsid[] = "@(#)parse.c 8.3 (Berkeley) 3/19/94";
|
||||||
#else
|
#else
|
||||||
__RCSID("$NetBSD: parse.c,v 1.76 2002/01/24 01:39:03 reinoud Exp $");
|
__RCSID("$NetBSD: parse.c,v 1.77 2002/01/26 20:42:14 christos Exp $");
|
||||||
#endif
|
#endif
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
#endif
|
#endif
|
||||||
@ -195,6 +195,8 @@ typedef enum {
|
|||||||
static ParseSpecial specType;
|
static ParseSpecial specType;
|
||||||
static int waiting;
|
static int waiting;
|
||||||
|
|
||||||
|
#define LPAREN '('
|
||||||
|
#define RPAREN ')'
|
||||||
/*
|
/*
|
||||||
* Predecessor node for handling .ORDER. Initialized to NILGNODE when .ORDER
|
* Predecessor node for handling .ORDER. Initialized to NILGNODE when .ORDER
|
||||||
* seen, then set to each successive source on the line.
|
* seen, then set to each successive source on the line.
|
||||||
@ -253,6 +255,7 @@ static struct {
|
|||||||
{ ".WAIT", Wait, 0 },
|
{ ".WAIT", Wait, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int ParseIsEscaped __P((const char *, const char *));
|
||||||
static void ParseErrorInternal __P((char *, size_t, int, char *, ...))
|
static void ParseErrorInternal __P((char *, size_t, int, char *, ...))
|
||||||
__attribute__((__format__(__printf__, 4, 5)));
|
__attribute__((__format__(__printf__, 4, 5)));
|
||||||
static void ParseVErrorInternal __P((char *, size_t, int, char *, va_list))
|
static void ParseVErrorInternal __P((char *, size_t, int, char *, va_list))
|
||||||
@ -283,6 +286,33 @@ static void ParseMark __P((GNode *));
|
|||||||
|
|
||||||
extern int maxJobs;
|
extern int maxJobs;
|
||||||
|
|
||||||
|
|
||||||
|
/*-
|
||||||
|
*----------------------------------------------------------------------
|
||||||
|
* ParseIsEscaped --
|
||||||
|
* Check if the current character is escaped on the current line
|
||||||
|
*
|
||||||
|
* Results:
|
||||||
|
* 0 if the character is not backslash escaped, 1 otherwise
|
||||||
|
*
|
||||||
|
* Side Effects:
|
||||||
|
* None
|
||||||
|
*----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
ParseIsEscaped(line, c)
|
||||||
|
const char *line, *c;
|
||||||
|
{
|
||||||
|
int active = 0;
|
||||||
|
for (;;) {
|
||||||
|
if (line == c)
|
||||||
|
return active;
|
||||||
|
if (*--c != '\\')
|
||||||
|
return active;
|
||||||
|
active = !active;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
*----------------------------------------------------------------------
|
*----------------------------------------------------------------------
|
||||||
* ParseFindKeyword --
|
* ParseFindKeyword --
|
||||||
@ -827,6 +857,7 @@ ParseDoDependency (line)
|
|||||||
Lst curTargs; /* list of target names to be found and added
|
Lst curTargs; /* list of target names to be found and added
|
||||||
* to the targets list */
|
* to the targets list */
|
||||||
Lst curSrcs; /* list of sources in order */
|
Lst curSrcs; /* list of sources in order */
|
||||||
|
char *lstart = line;
|
||||||
|
|
||||||
tOp = 0;
|
tOp = 0;
|
||||||
|
|
||||||
@ -839,8 +870,9 @@ ParseDoDependency (line)
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
for (cp = line;
|
for (cp = line;
|
||||||
*cp && !isspace ((unsigned char)*cp) &&
|
*cp && (ParseIsEscaped(lstart, cp) ||
|
||||||
(*cp != '!') && (*cp != ':') && (*cp != '(');
|
(!isspace ((unsigned char)*cp) &&
|
||||||
|
(*cp != '!') && (*cp != ':') && (*cp != LPAREN)));
|
||||||
cp++)
|
cp++)
|
||||||
{
|
{
|
||||||
if (*cp == '$') {
|
if (*cp == '$') {
|
||||||
@ -864,7 +896,7 @@ ParseDoDependency (line)
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (*cp == '(') {
|
if (!ParseIsEscaped(lstart, cp) && *cp == LPAREN) {
|
||||||
/*
|
/*
|
||||||
* Archives must be handled specially to make sure the OP_ARCHV
|
* Archives must be handled specially to make sure the OP_ARCHV
|
||||||
* flag is set in their 'type' field, for one thing, and because
|
* flag is set in their 'type' field, for one thing, and because
|
||||||
@ -1060,8 +1092,10 @@ ParseDoDependency (line)
|
|||||||
if (specType != Not && specType != ExPath) {
|
if (specType != Not && specType != ExPath) {
|
||||||
Boolean warn = FALSE;
|
Boolean warn = FALSE;
|
||||||
|
|
||||||
while ((*cp != '!') && (*cp != ':') && *cp) {
|
while (*cp && (ParseIsEscaped(lstart, cp) ||
|
||||||
if (*cp != ' ' && *cp != '\t') {
|
((*cp != '!') && (*cp != ':')))) {
|
||||||
|
if (ParseIsEscaped(lstart, cp) ||
|
||||||
|
(*cp != ' ' && *cp != '\t')) {
|
||||||
warn = TRUE;
|
warn = TRUE;
|
||||||
}
|
}
|
||||||
cp++;
|
cp++;
|
||||||
@ -1075,7 +1109,8 @@ ParseDoDependency (line)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
line = cp;
|
line = cp;
|
||||||
} while ((*line != '!') && (*line != ':') && *line);
|
} while (*line && (ParseIsEscaped(lstart, line) ||
|
||||||
|
((*line != '!') && (*line != ':'))));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Don't need the list of target names anymore...
|
* Don't need the list of target names anymore...
|
||||||
@ -1268,7 +1303,7 @@ ParseDoDependency (line)
|
|||||||
* and handle them accordingly.
|
* and handle them accordingly.
|
||||||
*/
|
*/
|
||||||
while (*cp && !isspace ((unsigned char)*cp)) {
|
while (*cp && !isspace ((unsigned char)*cp)) {
|
||||||
if ((*cp == '(') && (cp > line) && (cp[-1] != '$')) {
|
if ((*cp == LPAREN) && (cp > line) && (cp[-1] != '$')) {
|
||||||
/*
|
/*
|
||||||
* Only stop for a left parenthesis if it isn't at the
|
* Only stop for a left parenthesis if it isn't at the
|
||||||
* start of a word (that'll be for variable changes
|
* start of a word (that'll be for variable changes
|
||||||
@ -1281,7 +1316,7 @@ ParseDoDependency (line)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*cp == '(') {
|
if (*cp == LPAREN) {
|
||||||
GNode *gn;
|
GNode *gn;
|
||||||
|
|
||||||
sources = Lst_Init (FALSE);
|
sources = Lst_Init (FALSE);
|
||||||
@ -1377,13 +1412,13 @@ Parse_IsVar (line)
|
|||||||
wasSpace = TRUE;
|
wasSpace = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '(':
|
case LPAREN:
|
||||||
case '{':
|
case '{':
|
||||||
level++;
|
level++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '}':
|
case '}':
|
||||||
case ')':
|
case RPAREN:
|
||||||
level--;
|
level--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2677,7 +2712,8 @@ Parse_File(name, stream)
|
|||||||
goto nextLine;
|
goto nextLine;
|
||||||
}
|
}
|
||||||
#ifndef POSIX
|
#ifndef POSIX
|
||||||
while ((*cp != ':') && (*cp != '!') && (*cp != '\0')) {
|
while (*cp && (ParseIsEscaped(line, cp) ||
|
||||||
|
(*cp != ':') && (*cp != '!'))) {
|
||||||
nonSpace = TRUE;
|
nonSpace = TRUE;
|
||||||
cp++;
|
cp++;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user