From: Mikael Magnusson <mikachu@gmail.com>
To: zsh-workers@zsh.org
Subject: PATCH: Add g:: parameter expansion flag
Date: Fri, 13 May 2011 14:38:43 +0200 [thread overview]
Message-ID: <1305290323-25573-1-git-send-email-mikachu@gmail.com> (raw)
In-Reply-To: <20110513125408.314f6359@pwslap01u.europe.root.pri>
On 13 May 2011 13:54, Peter Stephenson <Peter.Stephenson@csr.com> wrote:
> On Fri, 13 May 2011 11:51:13 +0200
> Mikael Magnusson <mikachu@gmail.com> wrote:
>> >> So I am pretty sure I want to use META_HREALLOC, is that correct?
>> > That would do, as it's what untok_and_escape() does, although
>> > META_HEAPDUP would probably be OK at this point. Reallocating
>> > what's on the heap is a slightly strange thing to do, since the
>> > point of the heap is to provide quick storage without the need to
>> > micromanage it;
>>
>> In that case, isn't USEHEAP better? It'll allocate on the heap if
>> there's anything to escape and otherwise do it in-place. Which is what
>> I thought HREALLOC would do, but I guess that one would do more stuff
>> to try and just grow. Won't it always succeed though, since the to-be
>> reallocated value was just allocated on the line before? (At least
>> when the heap isn't full).
>
> USEHEAP is fine if you don't mind further modifications to the string
> propagating back to the original. In some places the string might not
> be modifiable, or might refer to a permanently stored string, so you
> wouldn't want to do that. That may not be the case here; it needs
> deciding case by case.
Right, it isn't the case here, so I'll use this one.
Actually, it turns out getkeystring() always performs a copy, so I can
skip the dupstring and always set copied = 1, like for casemodify above
it. I also added an array to the test case, since it turns out you can
write code that works in one branch and code that doesn't work in the
other branch ;).
--
Mikael Magnusson
---
Doc/Zsh/expn.yo | 17 ++++++++++++--
Src/subst.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++
Test/D04parameter.ztst | 20 +++++++++++++++++
3 files changed, 90 insertions(+), 3 deletions(-)
diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo
index 1cad3d2..9d5c81b 100644
--- a/Doc/Zsh/expn.yo
+++ b/Doc/Zsh/expn.yo
@@ -863,6 +863,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)'.
)
@@ -1108,7 +1116,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
@@ -1292,8 +1302,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 5d7a8b4..6bc0a82 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;
@@ -3100,6 +3134,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 b91caaa..6379c8c 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}
--
1.7.4-rc1
prev parent reply other threads:[~2011-05-13 12:39 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-05-11 13:02 PATCH: expanding parameters like echo/print builtins Mikael Magnusson
2011-05-11 15:03 ` Bart Schaefer
2011-05-11 15:14 ` Mikael Magnusson
2011-05-11 16:03 ` Bart Schaefer
2011-05-11 16:22 ` Mikael Magnusson
2011-05-11 16:48 ` Bart Schaefer
2011-05-11 17:11 ` Mikael Magnusson
2011-05-11 15:47 ` Oliver Kiddle
2011-05-11 16:21 ` Peter Stephenson
2011-05-11 16:38 ` Mikael Magnusson
2011-05-11 17:07 ` Peter Stephenson
2011-05-11 17:19 ` Mikael Magnusson
2011-05-11 17:26 ` Peter Stephenson
2011-05-11 17:35 ` Mikael Magnusson
2011-05-11 17:43 ` Mikael Magnusson
2011-05-12 10:10 ` Bart Schaefer
2011-05-12 10:40 ` Mikael Magnusson
2011-05-12 14:04 ` Bart Schaefer
2011-05-12 15:49 ` PATCH: Add g:: parameter expansion flag Mikael Magnusson
2011-05-12 19:41 ` Mikael Magnusson
2011-05-13 8:54 ` Peter Stephenson
2011-05-13 9:51 ` Mikael Magnusson
2011-05-13 11:54 ` Peter Stephenson
2011-05-13 12:38 ` Mikael Magnusson [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1305290323-25573-1-git-send-email-mikachu@gmail.com \
--to=mikachu@gmail.com \
--cc=zsh-workers@zsh.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/zsh/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).