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: 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: 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 $ # $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 # http://www.freebsd.org/cgi/cvsweb.cgi/src/tools/regression/bin/test/regress.sh?rev=HEAD
expected-stdout: expected-stdout:
@(#)MIRBSD KSH R41 2013/01/06 @(#)MIRBSD KSH R41 2013/01/19
description: description:
Check version of shell. Check version of shell.
stdin: stdin:
@ -38,7 +38,7 @@ name: KSH_VERSION
category: shell:legacy-no category: shell:legacy-no
--- ---
expected-stdout: expected-stdout:
@(#)LEGACY KSH R41 2013/01/06 @(#)LEGACY KSH R41 2013/01/19
description: description:
Check version of legacy shell. Check version of legacy shell.
stdin: stdin:
@ -7677,18 +7677,34 @@ expected-stdout:
--- ---
name: dollar-quotes-in-herestrings name: dollar-quotes-in-herestrings
description: description:
They are, not parsed in here strings either On the other hand, they are parsed in here strings and
parameter substitutions
stdin: stdin:
cat <<<"dollar = strchr(s, '$'); /* ' */" cat <<<"dollar = strchr(s, '$'); /* ' */"
cat <<<'dollar = strchr(s, '\''$'\''); /* '\'' */' cat <<<'dollar = strchr(s, '\''$'\''); /* '\'' */'
x="dollar = strchr(s, '$'); /* ' */" x="dollar = strchr(s, '$'); /* ' */"
cat <<<"$x" cat <<<"$x"
cat <<<$'a\E[0m\tb' 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: expected-stdout:
dollar = strchr(s, '); /* */
dollar = strchr(s, '$'); /* ' */ dollar = strchr(s, '$'); /* ' */
dollar = strchr(s, '$'); /* ' */ dollar = strchr(s, '); /* */
dollar = strchr(s, '$'); /* ' */
a b a b
x
y
1 foo"bar
2 foo\"bar
3 foo"bar
4 foo\"bar
5 foo\"bar
--- ---
name: dot-needs-argument name: dot-needs-argument
description: description:

24
exec.c
View File

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

10
lex.c
View File

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

7
sh.h
View File

@ -164,9 +164,9 @@
#endif #endif
#ifdef EXTERN #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 #endif
#define MKSH_VERSION "R41 2013/01/06" #define MKSH_VERSION "R41 2013/01/19"
/* arithmetic types: C implementation */ /* arithmetic types: C implementation */
#if !HAVE_CAN_INTTYPES #if !HAVE_CAN_INTTYPES
@ -1580,7 +1580,8 @@ typedef union {
#define CMDWORD BIT(8) /* parsing simple command (alias related) */ #define CMDWORD BIT(8) /* parsing simple command (alias related) */
#define HEREDELIM BIT(9) /* parsing <<,<<- delimiter */ #define HEREDELIM BIT(9) /* parsing <<,<<- delimiter */
#define LQCHAR BIT(10) /* source string contains QCHAR */ #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 */ #define HERES 10 /* max number of << in line */