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:
christos 2002-01-26 20:42:14 +00:00
parent 62a708c06d
commit 933b6f81c0

View File

@ -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++;
} }