diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | Doc/Zsh/expn.yo | 17 | ||||
-rw-r--r-- | Src/subst.c | 56 | ||||
-rw-r--r-- | Test/D04parameter.ztst | 20 |
4 files changed, 96 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog index c59967ba7..8027def03 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2011-05-19 Mikael Magnusson <mikachu@gmail.com> + * 29261: Add g:: parameter expansion flag. Add note that s:: + can take an empty string. + +2011-05-19 Mikael Magnusson <mikachu@gmail.com> + * 29307, 29308 + replies: Fix some doubled words in docs and comments. @@ -14752,5 +14757,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5312 $ +* $Revision: 1.5313 $ ***************************************************** diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo index 6ac348605..e39589447 100644 --- a/Doc/Zsh/expn.yo +++ b/Doc/Zsh/expn.yo @@ -859,6 +859,14 @@ item(tt(F))( Join the words of arrays together using newline as a separator. This is a shorthand for `tt(pj:\n:)'. ) +item(tt(g:opts:))( +Process escape sequences like the echo builtin when no options are given +(tt(g::)). With the tt(o) option, octal escapes don't take a leading +zero. With the tt(c) option, sequences like `tt(^X)' are also processed. +With the tt(e) option, processes `tt(\M-t)' and similar sequences like the +print builtin. With both of the tt(o) and tt(e) options, behaves like the +print builtin except that in none of these modes is `tt(\c)' interpreted. +) item(tt(i))( Sort case-insensitively. May be combined with `tt(n)' or `tt(O)'. ) @@ -1104,7 +1112,9 @@ Force field splitting at the separator var(string). Note that a var(string) of two or more characters means that all of them must match in sequence; this differs from the treatment of two or more characters in the tt(IFS) parameter. -See also the tt(=) flag and the tt(SH_WORD_SPLIT) option. +See also the tt(=) flag and the tt(SH_WORD_SPLIT) option. An empty +string may also be given in which case every character will be a separate +element. For historical reasons, the usual behaviour that empty array elements are retained inside double quotes is disabled for arrays generated @@ -1288,8 +1298,9 @@ item(tt(11.) em(Case modification))( Any case modification from one of the flags tt((L)), tt((U)) or tt((C)) is applied. ) -item(tt(12.) em(Prompt evaluation))( -Any prompt-style formatting from the tt((%)) family of flags is applied. +item(tt(12.) em(Escape sequence replacement))( +First any replacements from the tt((g)) flag are performed, then any +prompt-style formatting from the tt((%)) family of flags is applied. ) item(tt(13.) em(Quote application))( Any quoting or unquoting using tt((q)) and tt((Q)) and related flags diff --git a/Src/subst.c b/Src/subst.c index 244c066d4..822b24a40 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -1607,6 +1607,10 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) */ int presc = 0; /* + * The (g) flag. Process escape sequences with various GETKEY_ flags. + */ + int getkeys = -1; + /* * The (@) flag; interacts obscurely with qt and isarr. * This is one of the things that decides whether multsub * will produce an array, but in an extremely indirect fashion. @@ -1932,6 +1936,36 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) presc++; break; + case 'g': + t = get_strarg(++s, &arglen); + if (getkeys < 0) + getkeys = 0; + if (*t) { + sav = *t; + *t = 0; + while (*++s) { + switch (*s) { + case 'e': + getkeys |= GETKEY_EMACS; + break; + case 'o': + getkeys |= GETKEY_OCTAL_ESC; + break; + case 'c': + getkeys |= GETKEY_CTRL; + break; + + default: + *t = sav; + goto flagerr; + } + } + *t = sav; + s = t + arglen - 1; + } else + goto flagerr; + break; + case 'z': shsplit = LEXFLAGS_ACTIVE; break; @@ -3083,6 +3117,28 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) } } /* + * Process echo- and print-style escape sequences. + */ + if (getkeys >= 0) { + int len; + + copied = 1; /* string is always copied */ + if (isarr) { + char **ap, **ap2; + + ap = aval; + aval = (char **) zhalloc(sizeof(char *) * (arrlen(aval)+1)); + for (ap2 = aval; *ap; ap++, ap2++) { + *ap2 = getkeystring(*ap, &len, getkeys, NULL); + *ap2 = metafy(*ap2, len, META_USEHEAP); + } + *ap2++ = NULL; + } else { + val = getkeystring(val, &len, getkeys, NULL); + val = metafy(val, len, META_USEHEAP); + } + } + /* * Perform prompt-style modifications. */ if (presc) { diff --git a/Test/D04parameter.ztst b/Test/D04parameter.ztst index 36462456b..84b9c1a9f 100644 --- a/Test/D04parameter.ztst +++ b/Test/D04parameter.ztst @@ -298,6 +298,26 @@ >Howzat >usay + foo='\u65\123' + print -r ${(g:o:)foo} + foo='\u65\0123' + print -r ${(g::)foo} + foo='\u65^X' + print -r ${(V)${(g:c:)foo}} + foo='\u65\C-x\M-a' + print -r ${(V)${(g:e:)foo}} + foo='\u65\123\C-x' + print -r ${(V)${(g:eo:)foo}} + foo=('\u65' '\0123' '^X\M-a') + print -r ${(V)${(g:e:)foo}} +0:${(g)...} +>eS +>eS +>e^X +>e^X\M-a +>eS^X +>e S ^X\M-a + foo='I'\''m nearly out of my mind with tedium' bar=foo print ${(P)bar} |