Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: On the quoting of braces
On Tue, 06 Dec 2011 23:16:35 +0100
Christian Neukirchen <chneukirchen@xxxxxxxxx> wrote:
> comparing different shells, I noticed zsh is overly careful for unquoted
> braces:
> zsh% echo { foo,bar }
> zsh: parse error near `}'
>
> Why does this error appear?
zsh allows a "}" to appear other than in command position at the end of
a shell construct or a function definition:
{ echo }
and
fn() { echo }
aren't complete statements in other shells. So this means a "}" is
treated as special everywhere on the command line.
> The only way to disable it seems to be
> IGNORE_BRACES, which completely disables (the much used) brace expansion.
Yes, this is really a different thing, since it doesn't involve a brace
on its own as an argument. They shouldn't really be tied together. In
fact, it looks like this additional effect of IGNORE_BRACES isn't even
documented.
Here's an option IGNORE_CLOSE_BRACES that only disables the first effect.
> ("disable -r '}'" would break "{ cmd; cmd2 }")
More to the point it would break "}" everywere, even in command
position, i.e. "{ cmd; cmd2; }" too. If you want the shell to treat
close braces as ordinary characters you'll need the semicolon after
"cmd2".
Index: Doc/Zsh/options.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/options.yo,v
retrieving revision 1.103
diff -p -u -r1.103 options.yo
--- Doc/Zsh/options.yo 18 May 2011 01:54:36 -0000 1.103
+++ Doc/Zsh/options.yo 7 Dec 2011 20:28:41 -0000
@@ -548,7 +548,32 @@ cindex(disabling brace expansion)
cindex(brace expansion, disabling)
cindex(expansion, brace, disabling)
item(tt(IGNORE_BRACES) (tt(-I)) <S>)(
-Do not perform brace expansion.
+Do not perform brace expansion. For historical reasons this
+also includes the effect of the tt(IGNORE_CLOSE_BRACES) option.
+)
+pindex(IGNORE_CLOSE_BRACES)
+pindex(NO_IGNORE_CLOSE_BRACES)
+pindex(IGNORECLOSEBRACES)
+pindex(NOIGNORECLOSEBRACES)
+item(tt(IGNORE_CLOSE_BRACES))(
+When neither this option no tt(IGNORE_BRACES) is set, a sole
+close brace character `tt(})' is syntactically significant at any
+point on a command line. This has the effect that no semicolon
+or newline is necessarry before the brace terminating a function
+or current shell construct. When either option is set, a closing brace
+is syntactically significant only in command position. Unlike
+tt(IGNORE_BRACES), this option does not disable brace expansion.
+
+For example, with both options unset a function may be defined
+in the following fashion:
+
+example(args() { echo $# })
+
+while if either option is set, this does not work and something
+equivalent to the following is required:
+
+example(args() { echo $#; })
+
)
pindex(KSH_GLOB)
pindex(NO_KSH_GLOB)
Index: Src/lex.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/lex.c,v
retrieving revision 1.69
diff -p -u -r1.69 lex.c
--- Src/lex.c 3 Dec 2011 17:24:46 -0000 1.69
+++ Src/lex.c 7 Dec 2011 20:28:41 -0000
@@ -1857,7 +1857,8 @@ exalias(void)
/* Then check for a reserved word */
if ((incmdpos ||
- (unset(IGNOREBRACES) && zshlextext[0] == '}' && !zshlextext[1])) &&
+ (unset(IGNOREBRACES) && unset(IGNORECLOSEBRACES) &&
+ zshlextext[0] == '}' && !zshlextext[1])) &&
(rw = (Reswd) reswdtab->getnode(reswdtab, zshlextext))) {
tok = rw->token;
if (tok == DINBRACK)
Index: Src/options.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/options.c,v
retrieving revision 1.57
diff -p -u -r1.57 options.c
--- Src/options.c 22 Nov 2010 11:42:47 -0000 1.57
+++ Src/options.c 7 Dec 2011 20:28:41 -0000
@@ -159,6 +159,7 @@ static struct optname optns[] = {
{{NULL, "histverify", 0}, HISTVERIFY},
{{NULL, "hup", OPT_EMULATE|OPT_ZSH}, HUP},
{{NULL, "ignorebraces", OPT_EMULATE|OPT_SH}, IGNOREBRACES},
+{{NULL, "ignoreclosebraces", 0}, IGNORECLOSEBRACES},
{{NULL, "ignoreeof", 0}, IGNOREEOF},
{{NULL, "incappendhistory", 0}, INCAPPENDHISTORY},
{{NULL, "interactive", OPT_SPECIAL}, INTERACTIVE},
Index: Src/zsh.h
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/zsh.h,v
retrieving revision 1.177
diff -p -u -r1.177 zsh.h
--- Src/zsh.h 14 Aug 2011 18:34:28 -0000 1.177
+++ Src/zsh.h 7 Dec 2011 20:28:41 -0000
@@ -2005,6 +2005,7 @@ enum {
HISTVERIFY,
HUP,
IGNOREBRACES,
+ IGNORECLOSEBRACES,
IGNOREEOF,
INCAPPENDHISTORY,
INTERACTIVE,
Index: Test/E01options.ztst
===================================================================
RCS file: /cvsroot/zsh/zsh/Test/E01options.ztst,v
retrieving revision 1.25
diff -p -u -r1.25 E01options.ztst
--- Test/E01options.ztst 1 Jul 2011 15:23:03 -0000 1.25
+++ Test/E01options.ztst 7 Dec 2011 20:28:41 -0000
@@ -256,6 +256,8 @@
?next one should fail
?(eval):1: parse error near `end'
+# ` emacs deconfusion
+
setopt cshjunkiequotes
print this should cause an error >&2
eval "print 'line one
@@ -271,6 +273,8 @@
?(eval):1: unmatched '
?this should not
+# ' emacs deconfusion
+
nullcmd() { print '$NULLCMD run'; }
readnullcmd() { print 'Running $READNULLCMD'; cat; }
NULLCMD=nullcmd
@@ -901,6 +905,8 @@
?(eval):exec:6: ls: restricted
?(eval):unsetopt:7: can't change option: restricted
+# ' emacs deconfusion
+
fn() {
print =ls ={ls,}
local foo='=ls'
@@ -1081,3 +1087,12 @@
?+(eval):4> fn
?+fn:0> print message
?+(eval):5> unsetopt xtrace
+
+ setopt ignoreclosebraces
+ eval "icb_test() { echo this is OK; }"
+ icb_test
+ icb_args() { print $#; }
+ eval "icb_args { this, is, ok, too }"
+0:IGNORE_CLOSE_BRACES option
+>this is OK
+>6
--
Peter Stephenson <p.w.stephenson@xxxxxxxxxxxx>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/
Messages sorted by:
Reverse Date,
Date,
Thread,
Author