24711: fix re-presentation of here-documents munged internally

to here-strings
This commit is contained in:
Peter Stephenson 2008-03-14 11:40:57 +00:00
parent 2ca42b2025
commit 948f015df0
5 changed files with 87 additions and 8 deletions

View File

@ -1,3 +1,9 @@
2008-03-14 Peter Stephenson <pws@csr.com>
* 24711: Src/parse.c, Src/text.c, Src/zsh.h,
Test/A04redirect.ztst: fix re-presentation of here-documents
munged internally to here-strings.
2008-03-13 Peter Stephenson <pws@csr.com>
* 24705: configure.ac, Config/defs.mk.in, Src/zsh.mdd,

View File

@ -1861,7 +1861,7 @@ par_redir(int *rp, char *idstring)
void
setheredoc(int pc, int type, char *str)
{
ecbuf[pc] = WCB_REDIR(type);
ecbuf[pc] = WCB_REDIR(type | REDIR_FROM_HEREDOC_MASK);
ecbuf[pc + 2] = ecstrcode(str);
}
@ -2409,6 +2409,10 @@ ecgetredirs(Estate s)
r->type = WC_REDIR_TYPE(code);
r->fd1 = *s->pc++;
r->name = ecgetstr(s, EC_DUP, NULL);
if (WC_REDIR_FROM_HEREDOC(code))
r->flags = REDIRF_FROM_HEREDOC;
else
r->flags = 0;
if (WC_REDIR_VARID(code))
r->varid = ecgetstr(s, EC_DUP, NULL);
else

View File

@ -831,17 +831,22 @@ getredirs(LinkList redirs)
taddstr(fstr[f->type]);
if (f->type != REDIR_MERGEIN && f->type != REDIR_MERGEOUT)
taddchr(' ');
if (f->type == REDIR_HERESTR && !has_token(f->name)) {
if (f->type == REDIR_HERESTR &&
(f->flags & REDIRF_FROM_HEREDOC)) {
/*
* Strings that came from here-documents are converted
* to here strings without quotation, so add that
* now. If tokens are already present taddstr()
* will do the right thing (anyway, adding more
* quotes certainly isn't right in that case).
* now. If tokens are present we need to do double quoting.
*/
taddchr('\'');
taddstr(quotestring(f->name, NULL, QT_SINGLE));
taddchr('\'');
if (!has_token(f->name)) {
taddchr('\'');
taddstr(quotestring(f->name, NULL, QT_SINGLE));
taddchr('\'');
} else {
taddchr('"');
taddstr(quotestring(f->name, NULL, QT_DOUBLE));
taddchr('"');
}
} else
taddstr(f->name);
taddchr(' ');

View File

@ -309,7 +309,10 @@ enum {
REDIR_OUTPIPE /* > >(...) */
};
#define REDIR_TYPE_MASK (0x1f)
/* Redir using {var} syntax */
#define REDIR_VARID_MASK (0x20)
/* Mark here-string that came from a here-document */
#define REDIR_FROM_HEREDOC_MASK (0x40)
#define IS_WRITE_FILE(X) ((X)>=REDIR_WRITE && (X)<=REDIR_READWRITE)
#define IS_APPEND_REDIR(X) (IS_WRITE_FILE(X) && ((X) & 2))
@ -550,10 +553,18 @@ struct conddef {
#define CONDDEF(name, flags, handler, min, max, condid) \
{ NULL, name, flags, handler, min, max, condid, NULL }
/* Flags for redirections */
enum {
/* Mark a here-string that came from a here-document */
REDIRF_FROM_HEREDOC = 1
};
/* tree element for redirection lists */
struct redir {
int type;
int flags;
int fd1, fd2;
char *name;
char *varid;
@ -744,6 +755,7 @@ struct eccstr {
#define WC_REDIR_TYPE(C) ((int)(wc_data(C) & REDIR_TYPE_MASK))
#define WC_REDIR_VARID(C) ((int)(wc_data(C) & REDIR_VARID_MASK))
#define WC_REDIR_FROM_HEREDOC(C) ((int)(wc_data(C) & REDIR_FROM_HEREDOC_MASK))
#define WCB_REDIR(T) wc_bld(WC_REDIR, (T))
/* Size of redir is 4 words if REDIR_VARID_MASK is set, else 3 */
#define WC_REDIR_WORDS(C) (WC_REDIR_VARID(C) ? 4 : 3)

View File

@ -82,6 +82,58 @@
>b
>c
# The following tests check that output of parsed here-documents works.
# This isn't completely trivial because we convert the here-documents
# internally to here-strings. So we check again that we can output
# the reevaluated here-strings correctly. Hence there are three slightly
# different stages. We don't care how the output actually looks, so
# we don't test that.
heretest() {
print First line
cat <<-HERE
$foo$foo met celeste 'but with extra' "stuff to test quoting"
HERE
print Last line
}
heretest
eval "$(functions heretest)"
heretest
eval "$(functions heretest)"
heretest
0:Re-evaluation of function output with here document, unquoted
>First line
>barbar met celeste 'but with extra' "stuff to test quoting"
>Last line
>First line
>barbar met celeste 'but with extra' "stuff to test quoting"
>Last line
>First line
>barbar met celeste 'but with extra' "stuff to test quoting"
>Last line
heretest() {
print First line
cat <<' HERE'
$foo$foo met celeste 'but with extra' "stuff to test quoting"
HERE
print Last line
}
heretest
eval "$(functions heretest)"
heretest
eval "$(functions heretest)"
heretest
0:Re-evaluation of function output with here document, quoted
>First line
> $foo$foo met celeste 'but with extra' "stuff to test quoting"
>Last line
>First line
> $foo$foo met celeste 'but with extra' "stuff to test quoting"
>Last line
>First line
> $foo$foo met celeste 'but with extra' "stuff to test quoting"
>Last line
#
# exec tests: perform these in subshells so if they fail the
# shell won't exit.