From: Bart Schaefer <schaefer@brasslantern.com>
To: Zsh hackers list <zsh-workers@zsh.org>
Subject: [PATCH] Fixes and tests for namespace prefixes
Date: Sun, 5 Mar 2023 15:38:06 -0800 [thread overview]
Message-ID: <CAH+w=7YQEUizfBBD8BJOAUqs3ecdPQh4v9Y+mvSn5XYFwEao_Q@mail.gmail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 354 bytes --]
This causes parameters with a leading "." to be skipped by "set" and
by "typeset" without other arguments.
Also included are tests, and a fix for my misunderstanding of the use
of the "once" argument in itype_end().
Patch applies with fuzz if workers/51509 is not applied first, but one
of the tests is for ${!...} so that test will fail in that case.
[-- Attachment #2: namespace-fix.txt --]
[-- Type: text/plain, Size: 5902 bytes --]
diff --git a/Src/builtin.c b/Src/builtin.c
index 11c1ab3a4..d99802f5f 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -2240,7 +2240,8 @@ typeset_single(char *cname, char *pname, Param pm, int func,
paramtab->printnode(&pm->node, PRINT_TYPESET);
else if (!OPT_ISSET(ops,'g') &&
(unset(TYPESETSILENT) || OPT_ISSET(ops,'m')))
- paramtab->printnode(&pm->node, PRINT_INCLUDEVALUE);
+ paramtab->printnode(&pm->node,
+ PRINT_INCLUDEVALUE|PRINT_WITH_NAMESPACE);
return pm;
}
if ((pm->node.flags & PM_RESTRICTED) && isset(RESTRICTED)) {
@@ -2274,7 +2275,7 @@ typeset_single(char *cname, char *pname, Param pm, int func,
}
}
if (OPT_ISSET(ops,'p')) {
- paramtab->printnode(&pm->node, PRINT_TYPESET);
+ paramtab->printnode(&pm->node, PRINT_TYPESET|PRINT_WITH_NAMESPACE);
return pm;
}
if (usepm == 2) /* do not change the PM_UNSET flag */
@@ -2662,7 +2663,7 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func)
char *optstr = TYPESET_OPTSTR;
int on = 0, off = 0, roff, bit = PM_ARRAY;
int i;
- int returnval = 0, printflags = 0;
+ int returnval = 0, printflags = PRINT_WITH_NAMESPACE;
int hasargs = *argv != NULL || (assigns && firstnode(assigns));
/* POSIXBUILTINS is set for bash/ksh and both ignore -p with args */
@@ -2730,7 +2731,6 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func)
queue_signals();
- /* Given no arguments, list whatever the options specify. */
if (OPT_ISSET(ops,'p')) {
if (isset(POSIXBUILTINS) && SHELL_EMULATION() != EMULATE_KSH) {
@@ -2756,8 +2756,14 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func)
/* -p0 treated as -p for consistency */
}
}
+
+ /* Given no arguments, list whatever the options specify. */
if (!hasargs) {
int exclude = 0;
+
+ if (!OPT_ISSET(ops,'m'))
+ printflags &= ~PRINT_WITH_NAMESPACE;
+
if (!OPT_ISSET(ops,'p')) {
if (!(on|roff))
printflags |= PRINT_TYPE;
diff --git a/Src/params.c b/Src/params.c
index 85eaee609..021d341e8 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -5966,6 +5966,10 @@ printparamnode(HashNode hn, int printflags)
Param p = (Param) hn;
Param peer = NULL;
+ if (!(p->node.flags & PM_HASHELEM) &&
+ !(printflags & PRINT_WITH_NAMESPACE) && *(p->node.nam) == '.')
+ return;
+
if (p->node.flags & PM_UNSET) {
if ((printflags & (PRINT_POSIX_READONLY|PRINT_POSIX_EXPORT) &&
p->node.flags & (PM_READONLY|PM_EXPORTED)) ||
diff --git a/Src/utils.c b/Src/utils.c
index 8ce9a175d..14ff0ed47 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -4319,13 +4319,13 @@ itype_end(const char *ptr, int itype, int once)
{
if (itype == INAMESPC) {
itype = IIDENT;
- if (once == 0 && (!isset(POSIXIDENTIFIERS) || EMULATION(EMULATE_KSH))) {
+ if (!isset(POSIXIDENTIFIERS) || EMULATION(EMULATE_KSH)) {
/* Special case for names containing ".", ksh93 namespaces */
char *t = itype_end(ptr + (*ptr == '.'), itype, 0);
- if (t > ptr+1) {
+ if (t > ptr + (*ptr == '.')) {
if (*t == '.')
- return itype_end(t+1, itype, 0);
- else
+ ptr = t + 1; /* Fall through */
+ else if (!once)
return t;
}
}
diff --git a/Src/zsh.h b/Src/zsh.h
index f3a777045..a0243e98e 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -2184,6 +2184,7 @@ typedef groupset *Groupset;
#define PRINT_LINE (1<<6)
#define PRINT_POSIX_EXPORT (1<<7)
#define PRINT_POSIX_READONLY (1<<8)
+#define PRINT_WITH_NAMESPACE (1<<9)
/* flags for printing for the whence builtin */
#define PRINT_WHENCE_CSH (1<<7)
diff --git a/Test/K02parameter.ztst b/Test/K02parameter.ztst
new file mode 100644
index 000000000..8a1be1e36
--- /dev/null
+++ b/Test/K02parameter.ztst
@@ -0,0 +1,106 @@
+# Test parameter expansion with namespace syntax
+# (heavily borrowed from D04parameter.ztst)
+
+%prep
+
+%test
+
+ .k02.foo='the first parameter'
+ .k02.bar='the second parameter'
+ print -l $.k02.foo ${.k02.bar}
+0:Basic scalars with namespace
+F:Braces are required
+>$.k02.foo
+>the second parameter
+
+ typeset .k02.bar='the second parameter'
+ print -l ${.k02.bar}
+0:Scalar but with typeset
+>the second parameter
+
+ .k02.array1=(the first array)
+ .k02.array2=(the second array)
+ print -l $.k02.array1 ${.k02.array2}
+0:Basic arrays with namespace
+>$.k02.array1
+>the
+>second
+>array
+
+ typeset -a .k02.array2=(the second array)
+ print -l ${.k02.array2}
+0:Array but with typeset
+>the
+>second
+>array
+
+ setopt ksharrays
+ print -l ${.k02.array2}
+ unsetopt ksharrays
+0:Basic ksharray with namespace
+>the
+
+ setopt shwordsplit
+ print -l ${.k02.foo} ${==.k02.bar}
+ unsetopt shwordsplit
+0:Basic shwordsplit with namespace
+>the
+>first
+>parameter
+>the second parameter
+
+ print ${+.k02.foo} ${+.k02.notappearinginthistest}
+0:$+... and namespace
+>1 0
+
+ .k02.x=()
+ print ${+.k02.x} ${+.k02.x[1]} ${+.k02.x[(r)foo]} ${+.k02.x[(r)bar]}
+ .k02.x=(foo)
+ print ${+.k02.x} ${+.k02.x[1]} ${+.k02.x[(r)foo]} ${+.k02.x[(r)bar]}
+0:$+... with arrays and namespace
+>1 0 0 0
+>1 1 1 0
+
+ # See D04 for complete explanation.
+ # For K02 we're just testing that flag syntax works.
+ .k02.foo='<five> {six} (seven) >eight< }nine{ |forty-two| $many$ )ten( more'
+ .k02.array=(${(z).k02.foo})
+ print -l ${(Q).k02.array}
+0:${(z)...} and ${(Q)...} for some hard to parse cases
+><
+>five
+>>
+>{six}
+>(
+>seven
+>)
+>>
+>eight
+><
+>}nine{
+>|
+>forty-two
+>|
+>$many$
+>)
+>ten( more
+
+ .k02.array=(characters in an array)
+ print ${(c)#.k02.array}
+0:${(c)#...}
+>22
+
+ () {
+ typeset -n .k02.ref=.k02.array
+ emulate -L ksh
+ print -l ${!.k02.ref} ${(!).k02.ref} ${.k02.ref}
+ }
+0:namerefs with namespaces
+>.k02.array
+>.k02.array
+>characters
+
+ k.2=test
+ print ${k.2}
+0:Parse without leading dot (future proofing)
+>test
reply other threads:[~2023-03-05 23:38 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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='CAH+w=7YQEUizfBBD8BJOAUqs3ecdPQh4v9Y+mvSn5XYFwEao_Q@mail.gmail.com' \
--to=schaefer@brasslantern.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).