mirror of git://git.code.sf.net/p/zsh/code
24711: fix re-presentation of here-documents munged internally
to here-strings
This commit is contained in:
parent
2ca42b2025
commit
948f015df0
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
19
Src/text.c
19
Src/text.c
|
@ -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(' ');
|
||||
|
|
12
Src/zsh.h
12
Src/zsh.h
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue