besides more code reuse, fix $'…' everywhere (but keep it ignored in here document bodies that aren’t here strings)

This commit is contained in:
tg 2013-01-19 19:47:13 +00:00
parent e307cb34c4
commit 9111faeeb5
4 changed files with 45 additions and 24 deletions

28
check.t
View File

@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/check.t,v 1.587 2013/01/19 18:32:54 tg Exp $
# $MirOS: src/bin/mksh/check.t,v 1.588 2013/01/19 19:47:05 tg Exp $
# $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $
# $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $
# $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $
@ -29,7 +29,7 @@
# http://www.freebsd.org/cgi/cvsweb.cgi/src/tools/regression/bin/test/regress.sh?rev=HEAD
expected-stdout:
@(#)MIRBSD KSH R41 2013/01/06
@(#)MIRBSD KSH R41 2013/01/19
description:
Check version of shell.
stdin:
@ -38,7 +38,7 @@ name: KSH_VERSION
category: shell:legacy-no
---
expected-stdout:
@(#)LEGACY KSH R41 2013/01/06
@(#)LEGACY KSH R41 2013/01/19
description:
Check version of legacy shell.
stdin:
@ -7677,18 +7677,34 @@ expected-stdout:
---
name: dollar-quotes-in-herestrings
description:
They are, not parsed in here strings either
On the other hand, they are parsed in here strings and
parameter substitutions
stdin:
cat <<<"dollar = strchr(s, '$'); /* ' */"
cat <<<'dollar = strchr(s, '\''$'\''); /* '\'' */'
x="dollar = strchr(s, '$'); /* ' */"
cat <<<"$x"
cat <<<$'a\E[0m\tb'
unset nl; print -r -- "x${nl:=$'\n'}y"
echo "1 foo\"bar"
cat <<EOF
2 foo\"bar
EOF
cat <<<"3 foo\"bar"
cat <<<"4 foo\\\"bar"
cat <<<'5 foo\"bar'
expected-stdout:
dollar = strchr(s, '); /* */
dollar = strchr(s, '$'); /* ' */
dollar = strchr(s, '$'); /* ' */
dollar = strchr(s, '$'); /* ' */
dollar = strchr(s, '); /* */
a b
x
y
1 foo"bar
2 foo\"bar
3 foo"bar
4 foo\"bar
5 foo\"bar
---
name: dot-needs-argument
description:

24
exec.c
View File

@ -23,7 +23,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.112 2013/01/06 18:51:42 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.113 2013/01/19 19:47:10 tg Exp $");
#ifndef MKSH_DEFAULT_EXECSHELL
#define MKSH_DEFAULT_EXECSHELL "/bin/sh"
@ -34,7 +34,7 @@ static int comexec(struct op *, struct tbl * volatile, const char **,
static void scriptexec(struct op *, const char **) MKSH_A_NORETURN;
static int call_builtin(struct tbl *, const char **, const char *);
static int iosetup(struct ioword *, struct tbl *);
static int herein(const char *, int, char **);
static int herein(struct ioword *, char **);
static const char *do_selectargs(const char **, bool);
static Test_op dbteste_isa(Test_env *, Test_meta);
static const char *dbteste_getopnd(Test_env *, Test_op, bool);
@ -96,8 +96,7 @@ execute(struct op * volatile t,
/* and has no right-hand side (i.e. "varname=") */
ccp[0] == CHAR && ccp[1] == '=' && ccp[2] == EOS &&
/* plus we can have a here document content */
herein(t->ioact[0]->heredoc, t->ioact[0]->flag & IOEVAL,
&cp) == 0 && cp && *cp) {
herein(t->ioact[0], &cp) == 0 && cp && *cp) {
char *sp = cp, *dp;
size_t n = ccp - t->vars[0] + 2, z;
@ -1332,7 +1331,7 @@ iosetup(struct ioword *iop, struct tbl *tp)
case IOHERE:
do_open = false;
/* herein() returns -2 if error has been printed */
u = herein(iop->heredoc, iop->flag & IOEVAL, NULL);
u = herein(iop, NULL);
/* cp may have wrong name */
break;
@ -1452,7 +1451,7 @@ hereinval(const char *content, int sub, char **resbuf, struct shf *shf)
s = pushs(SSTRING, ATEMP);
s->start = s->str = ccp;
source = s;
if (yylex(ONEWORD|HEREDOC) != LWORD)
if (yylex(sub) != LWORD)
internal_errorf("%s: %s", "herein", "yylex");
source = osource;
ccp = evalstr(yylval.cp, 0);
@ -1468,7 +1467,7 @@ hereinval(const char *content, int sub, char **resbuf, struct shf *shf)
}
static int
herein(const char *content, int sub, char **resbuf)
herein(struct ioword *iop, char **resbuf)
{
int fd = -1;
struct shf *shf;
@ -1476,15 +1475,20 @@ herein(const char *content, int sub, char **resbuf)
int i;
/* ksh -c 'cat << EOF' can cause this... */
if (content == NULL) {
if (iop->heredoc == NULL) {
warningf(true, "%s missing", "here document");
/* special to iosetup(): don't print error */
return (-2);
}
/* lexer substitution flags */
i = (iop->flag & IOEVAL) ?
(ONEWORD | ((iop->flag & IOHERESTR) ? HERESTRBODY : HEREDOCBODY)) :
0;
/* skip all the fd setup if we just want the value */
if (resbuf != NULL)
return (hereinval(content, sub, resbuf, NULL));
return (hereinval(iop->heredoc, i, resbuf, NULL));
/*
* Create temp file to hold content (done before newenv
@ -1501,7 +1505,7 @@ herein(const char *content, int sub, char **resbuf)
return (-2);
}
if (hereinval(content, sub, NULL, shf) == -2) {
if (hereinval(iop->heredoc, i, NULL, shf) == -2) {
close(fd);
/* special to iosetup(): don't print error */
return (-2);

10
lex.c
View File

@ -2,7 +2,7 @@
/*-
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
* 2011, 2012
* 2011, 2012, 2013
* Thorsten Glaser <tg@mirbsd.org>
*
* Provided that these terms and disclaimer and all copyright notices
@ -23,7 +23,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.177 2013/01/19 18:32:56 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.178 2013/01/19 19:47:11 tg Exp $");
/*
* states while lexing word
@ -359,7 +359,7 @@ yylex(int cf)
c = getsc();
switch (c) {
case '"':
if ((cf & HEREDOC))
if ((cf & (HEREDOCBODY | HERESTRBODY)))
goto heredocquote;
/* FALLTHROUGH */
case '\\':
@ -504,13 +504,13 @@ yylex(int cf)
*wp++ = '\0';
*wp++ = CSUBST;
*wp++ = 'X';
} else if (c == '\'' && !(cf & HEREDOC)) {
} else if (c == '\'' && !(cf & HEREDOCBODY)) {
*wp++ = OQUOTE;
ignore_backslash_newline++;
PUSH_STATE(SEQUOTE);
statep->ls_bool = false;
break;
} else if (c == '"' && !(cf & HEREDOC)) {
} else if (c == '"' && !(cf & HEREDOCBODY)) {
goto DEQUOTE;
} else {
*wp++ = CHAR;

7
sh.h
View File

@ -164,9 +164,9 @@
#endif
#ifdef EXTERN
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.627 2013/01/06 18:51:43 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.628 2013/01/19 19:47:13 tg Exp $");
#endif
#define MKSH_VERSION "R41 2013/01/06"
#define MKSH_VERSION "R41 2013/01/19"
/* arithmetic types: C implementation */
#if !HAVE_CAN_INTTYPES
@ -1580,7 +1580,8 @@ typedef union {
#define CMDWORD BIT(8) /* parsing simple command (alias related) */
#define HEREDELIM BIT(9) /* parsing <<,<<- delimiter */
#define LQCHAR BIT(10) /* source string contains QCHAR */
#define HEREDOC BIT(11) /* parsing a here document */
#define HEREDOCBODY BIT(11) /* parsing a here document body */
#define HERESTRBODY BIT(12) /* parsing a here string body */
#define HERES 10 /* max number of << in line */