summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2008-03-14 11:40:57 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2008-03-14 11:40:57 +0000
commit948f015df0fee27f4e2c73b442a75c9434702550 (patch)
tree0d28c6e4ad0bd849702de39e544c597634ff7283
parent2ca42b2025cceaabd64889aa3b932195e8d5720c (diff)
downloadzsh-948f015df0fee27f4e2c73b442a75c9434702550.tar.gz
zsh-948f015df0fee27f4e2c73b442a75c9434702550.zip
24711: fix re-presentation of here-documents munged internally
to here-strings
-rw-r--r--ChangeLog6
-rw-r--r--Src/parse.c6
-rw-r--r--Src/text.c19
-rw-r--r--Src/zsh.h12
-rw-r--r--Test/A04redirect.ztst52
5 files changed, 87 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index 49c76fe05..ca3eb3ccd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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,
diff --git a/Src/parse.c b/Src/parse.c
index af3cba9d3..54543a642 100644
--- a/Src/parse.c
+++ b/Src/parse.c
@@ -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
diff --git a/Src/text.c b/Src/text.c
index 593c25776..7fdc5757f 100644
--- a/Src/text.c
+++ b/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(' ');
diff --git a/Src/zsh.h b/Src/zsh.h
index fb4d51ecd..495f51ad2 100644
--- a/Src/zsh.h
+++ b/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)
diff --git a/Test/A04redirect.ztst b/Test/A04redirect.ztst
index 2813d0e28..e27442c25 100644
--- a/Test/A04redirect.ztst
+++ b/Test/A04redirect.ztst
@@ -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.