Fixed the bug reported in PR 33866, which is that the :Q operator does not

handle newlines correctly. Ok'ed by christos.
This commit is contained in:
rillig 2006-06-29 22:01:17 +00:00
parent fbdae7393a
commit a3ea8b9d59
4 changed files with 47 additions and 18 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: job.c,v 1.111 2006/03/31 21:05:34 dsl Exp $ */ /* $NetBSD: job.c,v 1.112 2006/06/29 22:01:17 rillig Exp $ */
/* /*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California. * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@ -70,14 +70,14 @@
*/ */
#ifndef MAKE_NATIVE #ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: job.c,v 1.111 2006/03/31 21:05:34 dsl Exp $"; static char rcsid[] = "$NetBSD: job.c,v 1.112 2006/06/29 22:01:17 rillig Exp $";
#else #else
#include <sys/cdefs.h> #include <sys/cdefs.h>
#ifndef lint #ifndef lint
#if 0 #if 0
static char sccsid[] = "@(#)job.c 8.2 (Berkeley) 3/19/94"; static char sccsid[] = "@(#)job.c 8.2 (Berkeley) 3/19/94";
#else #else
__RCSID("$NetBSD: job.c,v 1.111 2006/03/31 21:05:34 dsl Exp $"); __RCSID("$NetBSD: job.c,v 1.112 2006/06/29 22:01:17 rillig Exp $");
#endif #endif
#endif /* not lint */ #endif /* not lint */
#endif #endif
@ -215,7 +215,7 @@ static Shell shells[] = {
{ {
"csh", "csh",
TRUE, "unset verbose", "set verbose", "unset verbose", 10, TRUE, "unset verbose", "set verbose", "unset verbose", 10,
FALSE, "echo \"%s\"\n", "csh -c \"%s || exit 0\"\n", "", '#', FALSE, "echo \"%s\"\n", "csh -c \"%s || exit 0\"\n", "", "'\\\n'", '#',
"v", "e", "v", "e",
}, },
/* /*
@ -225,7 +225,7 @@ static Shell shells[] = {
{ {
"sh", "sh",
FALSE, "", "", "", 0, FALSE, "", "", "", 0,
FALSE, "echo \"%s\"\n", "%s\n", "{ %s \n} || exit $?\n", '#', FALSE, "echo \"%s\"\n", "%s\n", "{ %s \n} || exit $?\n", "'\n'", '#',
#ifdef __NetBSD__ #ifdef __NetBSD__
"q", "q",
#else #else
@ -239,7 +239,7 @@ static Shell shells[] = {
{ {
"ksh", "ksh",
TRUE, "set +v", "set -v", "set +v", 6, TRUE, "set +v", "set -v", "set +v", 6,
FALSE, "echo \"%s\"\n", "%s\n", "{ %s \n} || exit $?\n", '#', FALSE, "echo \"%s\"\n", "%s\n", "{ %s \n} || exit $?\n", "'\n'", '#',
"v", "v",
"", "",
}, },
@ -249,7 +249,7 @@ static Shell shells[] = {
{ {
NULL, NULL,
FALSE, NULL, NULL, NULL, 0, FALSE, NULL, NULL, NULL, 0,
FALSE, NULL, NULL, NULL, 0, FALSE, NULL, NULL, NULL, NULL, 0,
NULL, NULL, NULL, NULL,
} }
}; };
@ -2186,6 +2186,17 @@ Shell_Init()
} }
} }
/*-
* Returns the string literal that is used in the current command shell
* to produce a newline character.
*/
const char *
Shell_GetNewline(void)
{
return commandShell->newline;
}
/*- /*-
*----------------------------------------------------------------------- *-----------------------------------------------------------------------
* Job_Init -- * Job_Init --
@ -2364,6 +2375,7 @@ JobMatchShell(const char *name)
* echoFlag Flag to turn echoing on at the start * echoFlag Flag to turn echoing on at the start
* errFlag Flag to turn error checking on at the start * errFlag Flag to turn error checking on at the start
* hasErrCtl True if shell has error checking control * hasErrCtl True if shell has error checking control
* newline String literal to represent a newline char
* check Command to turn on error checking if hasErrCtl * check Command to turn on error checking if hasErrCtl
* is TRUE or template of command to echo a command * is TRUE or template of command to echo a command
* for which error checking is off if hasErrCtl is * for which error checking is off if hasErrCtl is
@ -2422,6 +2434,8 @@ Job_ParseShell(char *line)
char c = argv[0][10]; char c = argv[0][10];
newShell.hasErrCtl = !((c != 'Y') && (c != 'y') && newShell.hasErrCtl = !((c != 'Y') && (c != 'y') &&
(c != 'T') && (c != 't')); (c != 'T') && (c != 't'));
} else if (strncmp(*argv, "newline=", 8) == 0) {
newShell.newline = &argv[0][8];
} else if (strncmp(*argv, "check=", 6) == 0) { } else if (strncmp(*argv, "check=", 6) == 0) {
newShell.errCheck = &argv[0][6]; newShell.errCheck = &argv[0][6];
} else if (strncmp(*argv, "ignore=", 7) == 0) { } else if (strncmp(*argv, "ignore=", 7) == 0) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: job.h,v 1.27 2006/03/31 21:05:34 dsl Exp $ */ /* $NetBSD: job.h,v 1.28 2006/06/29 22:01:17 rillig Exp $ */
/* /*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California. * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@ -250,6 +250,9 @@ typedef struct Shell {
const char *errCheck; /* string to turn error checking on */ const char *errCheck; /* string to turn error checking on */
const char *ignErr; /* string to turn off error checking */ const char *ignErr; /* string to turn off error checking */
const char *errOut; /* string to use for testing exit code */ const char *errOut; /* string to use for testing exit code */
const char *newline; /* string literal that results in a newline
* character when it appears outside of any
* 'quote' or "quote" characters */
char commentChar; /* character used by shell for comment lines */ char commentChar; /* character used by shell for comment lines */
/* /*
@ -268,6 +271,7 @@ extern int maxJobs; /* Max jobs we can run */
extern int maxJobTokens; /* Number of token for the job pipe */ extern int maxJobTokens; /* Number of token for the job pipe */
void Shell_Init(void); void Shell_Init(void);
const char *Shell_GetNewline(void);
void Job_Touch(GNode *, Boolean); void Job_Touch(GNode *, Boolean);
Boolean Job_CheckCommands(GNode *, void (*abortProc )(const char *, ...)); Boolean Job_CheckCommands(GNode *, void (*abortProc )(const char *, ...));
void Job_CatchChildren(Boolean); void Job_CatchChildren(Boolean);

View File

@ -1,4 +1,4 @@
.\" $NetBSD: make.1,v 1.126 2006/06/17 02:15:22 reed Exp $ .\" $NetBSD: make.1,v 1.127 2006/06/29 22:01:17 rillig Exp $
.\" .\"
.\" Copyright (c) 1990, 1993 .\" Copyright (c) 1990, 1993
.\" The Regents of the University of California. All rights reserved. .\" The Regents of the University of California. All rights reserved.
@ -29,7 +29,7 @@
.\" .\"
.\" from: @(#)make.1 8.4 (Berkeley) 3/19/94 .\" from: @(#)make.1 8.4 (Berkeley) 3/19/94
.\" .\"
.Dd March 18, 2006 .Dd June 29, 2006
.Dt MAKE 1 .Dt MAKE 1
.Os .Os
.Sh NAME .Sh NAME
@ -1574,13 +1574,16 @@ It is typically identical to
The flag to pass the shell to enable error checking. The flag to pass the shell to enable error checking.
.It Ar echoFlag .It Ar echoFlag
The flag to pass the shell to enable command echoing. The flag to pass the shell to enable command echoing.
.It Ar newline
The string literal to pass the shell that results in a single newline
character when used outside of any quoting characters.
.El .El
Example: Example:
.Bd -literal .Bd -literal
\&.SHELL: name=ksh path=/bin/ksh hasErrCtl=true \\ \&.SHELL: name=ksh path=/bin/ksh hasErrCtl=true \\
check="set -e" ignore="set +e" \\ check="set -e" ignore="set +e" \\
echo="set -v" quiet="set +v" filter="set +v" \\ echo="set -v" quiet="set +v" filter="set +v" \\
echoFlag=v errFlag=e echoFlag=v errFlag=e newline="'\\n'"
.Ed .Ed
.It Ic .SILENT .It Ic .SILENT
Apply the Apply the

View File

@ -1,4 +1,4 @@
/* $NetBSD: var.c,v 1.110 2006/05/19 17:29:01 christos Exp $ */ /* $NetBSD: var.c,v 1.111 2006/06/29 22:01:17 rillig Exp $ */
/* /*
* Copyright (c) 1988, 1989, 1990, 1993 * Copyright (c) 1988, 1989, 1990, 1993
@ -69,14 +69,14 @@
*/ */
#ifndef MAKE_NATIVE #ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: var.c,v 1.110 2006/05/19 17:29:01 christos Exp $"; static char rcsid[] = "$NetBSD: var.c,v 1.111 2006/06/29 22:01:17 rillig Exp $";
#else #else
#include <sys/cdefs.h> #include <sys/cdefs.h>
#ifndef lint #ifndef lint
#if 0 #if 0
static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94"; static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94";
#else #else
__RCSID("$NetBSD: var.c,v 1.110 2006/05/19 17:29:01 christos Exp $"); __RCSID("$NetBSD: var.c,v 1.111 2006/06/29 22:01:17 rillig Exp $");
#endif #endif
#endif /* not lint */ #endif /* not lint */
#endif #endif
@ -134,6 +134,7 @@ __RCSID("$NetBSD: var.c,v 1.110 2006/05/19 17:29:01 christos Exp $");
#include "make.h" #include "make.h"
#include "buf.h" #include "buf.h"
#include "dir.h" #include "dir.h"
#include "job.h"
/* /*
* This is a harmless return value for Var_Parse that can be used by Var_Subst * This is a harmless return value for Var_Parse that can be used by Var_Subst
@ -1835,12 +1836,19 @@ VarQuote(char *str)
Buffer buf; Buffer buf;
/* This should cover most shells :-( */ /* This should cover most shells :-( */
static char meta[] = "\n \t'`\";&<>()|*?{}[]\\$!#^~"; static char meta[] = "\n \t'`\";&<>()|*?{}[]\\$!#^~";
const char *newline;
newline = Shell_GetNewline();
buf = Buf_Init(MAKE_BSIZE); buf = Buf_Init(MAKE_BSIZE);
for (; *str; str++) { for (; *str; str++) {
if (strchr(meta, *str) != NULL) if (*str == '\n' && newline != NULL) {
Buf_AddByte(buf, (Byte)'\\'); Buf_AddBytes(buf, strlen(newline), newline);
Buf_AddByte(buf, (Byte)*str); } else {
if (strchr(meta, *str) != NULL)
Buf_AddByte(buf, (Byte)'\\');
Buf_AddByte(buf, (Byte)*str);
}
} }
Buf_AddByte(buf, (Byte)'\0'); Buf_AddByte(buf, (Byte)'\0');
str = (char *)Buf_GetAll(buf, NULL); str = (char *)Buf_GetAll(buf, NULL);
@ -2016,7 +2024,7 @@ ApplyModifiers(char *nstr, const char *tstr,
v, ctxt, err, &used, freePtr); v, ctxt, err, &used, freePtr);
if (nstr == var_Error if (nstr == var_Error
|| (nstr == varNoError && err == 0) || (nstr == varNoError && err == 0)
|| strlen(rval) != used) { || strlen(rval) != (size_t) used) {
if (freeIt) if (freeIt)
free(freeIt); free(freeIt);
goto out; /* error already reported */ goto out; /* error already reported */