mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-09-02 10:01:11 +02:00
24711: fix re-presentation of here-documents munged internally
to here-strings
This commit is contained in:
parent
2ca42b2025
commit
948f015df0
5 changed files with 87 additions and 8 deletions
|
@ -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>
|
2008-03-13 Peter Stephenson <pws@csr.com>
|
||||||
|
|
||||||
* 24705: configure.ac, Config/defs.mk.in, Src/zsh.mdd,
|
* 24705: configure.ac, Config/defs.mk.in, Src/zsh.mdd,
|
||||||
|
|
|
@ -1861,7 +1861,7 @@ par_redir(int *rp, char *idstring)
|
||||||
void
|
void
|
||||||
setheredoc(int pc, int type, char *str)
|
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);
|
ecbuf[pc + 2] = ecstrcode(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2409,6 +2409,10 @@ ecgetredirs(Estate s)
|
||||||
r->type = WC_REDIR_TYPE(code);
|
r->type = WC_REDIR_TYPE(code);
|
||||||
r->fd1 = *s->pc++;
|
r->fd1 = *s->pc++;
|
||||||
r->name = ecgetstr(s, EC_DUP, NULL);
|
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))
|
if (WC_REDIR_VARID(code))
|
||||||
r->varid = ecgetstr(s, EC_DUP, NULL);
|
r->varid = ecgetstr(s, EC_DUP, NULL);
|
||||||
else
|
else
|
||||||
|
|
19
Src/text.c
19
Src/text.c
|
@ -831,17 +831,22 @@ getredirs(LinkList redirs)
|
||||||
taddstr(fstr[f->type]);
|
taddstr(fstr[f->type]);
|
||||||
if (f->type != REDIR_MERGEIN && f->type != REDIR_MERGEOUT)
|
if (f->type != REDIR_MERGEIN && f->type != REDIR_MERGEOUT)
|
||||||
taddchr(' ');
|
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
|
* Strings that came from here-documents are converted
|
||||||
* to here strings without quotation, so add that
|
* to here strings without quotation, so add that
|
||||||
* now. If tokens are already present taddstr()
|
* now. If tokens are present we need to do double quoting.
|
||||||
* will do the right thing (anyway, adding more
|
|
||||||
* quotes certainly isn't right in that case).
|
|
||||||
*/
|
*/
|
||||||
taddchr('\'');
|
if (!has_token(f->name)) {
|
||||||
taddstr(quotestring(f->name, NULL, QT_SINGLE));
|
taddchr('\'');
|
||||||
taddchr('\'');
|
taddstr(quotestring(f->name, NULL, QT_SINGLE));
|
||||||
|
taddchr('\'');
|
||||||
|
} else {
|
||||||
|
taddchr('"');
|
||||||
|
taddstr(quotestring(f->name, NULL, QT_DOUBLE));
|
||||||
|
taddchr('"');
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
taddstr(f->name);
|
taddstr(f->name);
|
||||||
taddchr(' ');
|
taddchr(' ');
|
||||||
|
|
12
Src/zsh.h
12
Src/zsh.h
|
@ -309,7 +309,10 @@ enum {
|
||||||
REDIR_OUTPIPE /* > >(...) */
|
REDIR_OUTPIPE /* > >(...) */
|
||||||
};
|
};
|
||||||
#define REDIR_TYPE_MASK (0x1f)
|
#define REDIR_TYPE_MASK (0x1f)
|
||||||
|
/* Redir using {var} syntax */
|
||||||
#define REDIR_VARID_MASK (0x20)
|
#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_WRITE_FILE(X) ((X)>=REDIR_WRITE && (X)<=REDIR_READWRITE)
|
||||||
#define IS_APPEND_REDIR(X) (IS_WRITE_FILE(X) && ((X) & 2))
|
#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) \
|
#define CONDDEF(name, flags, handler, min, max, condid) \
|
||||||
{ NULL, name, flags, handler, min, max, condid, NULL }
|
{ 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 */
|
/* tree element for redirection lists */
|
||||||
|
|
||||||
struct redir {
|
struct redir {
|
||||||
int type;
|
int type;
|
||||||
|
int flags;
|
||||||
int fd1, fd2;
|
int fd1, fd2;
|
||||||
char *name;
|
char *name;
|
||||||
char *varid;
|
char *varid;
|
||||||
|
@ -744,6 +755,7 @@ struct eccstr {
|
||||||
|
|
||||||
#define WC_REDIR_TYPE(C) ((int)(wc_data(C) & REDIR_TYPE_MASK))
|
#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_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))
|
#define WCB_REDIR(T) wc_bld(WC_REDIR, (T))
|
||||||
/* Size of redir is 4 words if REDIR_VARID_MASK is set, else 3 */
|
/* 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)
|
#define WC_REDIR_WORDS(C) (WC_REDIR_VARID(C) ? 4 : 3)
|
||||||
|
|
|
@ -82,6 +82,58 @@
|
||||||
>b
|
>b
|
||||||
>c
|
>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
|
# exec tests: perform these in subshells so if they fail the
|
||||||
# shell won't exit.
|
# shell won't exit.
|
||||||
|
|
Loading…
Reference in a new issue