Skip to content

Commit a9ba166

Browse files
committed
51483: Enable assignment and expansion of parameters with ksh-like namespace prefixes.
1 parent 806d096 commit a9ba166

File tree

9 files changed

+45
-19
lines changed

9 files changed

+45
-19
lines changed

ChangeLog

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
2023-03-05 Bart Schaefer <schaefer@zsh.org>
22

3+
* 51483: Src/Zle/compcore.c, Src/Zle/zle_tricky.c, Src/lex.c,
4+
Src/params.c, Src/subst.c, Src/utils.c, Src/zsh.h, Src/ztype.h:
5+
Enable assignment and expansion of parameters with ksh-like
6+
namespace prefixes.
7+
38
* unposted: Src/Modules/param_private.c: coverity memory leak
49

510
2023-02-28 Mikael Magnusson <mikachu@gmail.com>

Src/Zle/compcore.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1230,14 +1230,14 @@ check_param(char *s, int set, int test)
12301230
else if (idigit(*e))
12311231
while (idigit(*e))
12321232
e++;
1233-
else if ((ie = itype_end(e, IIDENT, 0)) != e) {
1233+
else if ((ie = itype_end(e, INAMESPC, 0)) != e) {
12341234
do {
12351235
e = ie;
12361236
if (comppatmatch && *comppatmatch &&
12371237
(*e == Star || *e == Quest))
12381238
ie = e + 1;
12391239
else
1240-
ie = itype_end(e, IIDENT, 0);
1240+
ie = itype_end(e, INAMESPC, 0);
12411241
} while (ie != e);
12421242
}
12431243

Src/Zle/zle_tricky.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,7 @@ parambeg(char *s)
576576
while (idigit(*e))
577577
e++;
578578
else
579-
e = itype_end(e, IIDENT, 0);
579+
e = itype_end(e, INAMESPC, 0);
580580

581581
/* Now make sure that the cursor is inside the name. */
582582
if (offs <= e - s && offs >= b - s && n <= 0) {
@@ -765,7 +765,7 @@ docomplete(int lst)
765765
else if (idigit(*q))
766766
do q++; while (idigit(*q));
767767
else
768-
q = itype_end(q, IIDENT, 0);
768+
q = itype_end(q, INAMESPC, 0);
769769
sav = *q;
770770
*q = '\0';
771771
if (zlemetacs - wb == q - s &&
@@ -1497,7 +1497,7 @@ get_comp_string(void)
14971497
if (varq)
14981498
tt = clwords[clwpos];
14991499

1500-
s = itype_end(tt, IIDENT, 0);
1500+
s = itype_end(tt, INAMESPC, 0);
15011501
sav = *s;
15021502
*s = '\0';
15031503
zsfree(varname);

Src/lex.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1230,7 +1230,7 @@ gettokstr(int c, int sub)
12301230
else {
12311231
int sav = *lexbuf.ptr;
12321232
*lexbuf.ptr = '\0';
1233-
t = itype_end(t, IIDENT, 0);
1233+
t = itype_end(t, INAMESPC, 0);
12341234
if (t < lexbuf.ptr) {
12351235
skipparens(Inbrack, Outbrack, &t);
12361236
} else {

Src/params.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1223,7 +1223,7 @@ isident(char *s)
12231223
break;
12241224
} else {
12251225
/* Find the first character in `s' not in the iident type table */
1226-
ss = itype_end(s, IIDENT, 0);
1226+
ss = itype_end(s, INAMESPC, 0);
12271227
}
12281228

12291229
/* If the next character is not [, then it is *
@@ -2086,6 +2086,7 @@ fetchvalue(Value v, char **pptr, int bracks, int flags)
20862086
char *s, *t, *ie;
20872087
char sav, c;
20882088
int ppar = 0;
2089+
int itype = (flags & SCANPM_NONAMESPC) ? IIDENT : INAMESPC;
20892090

20902091
s = t = *pptr;
20912092

@@ -2095,7 +2096,7 @@ fetchvalue(Value v, char **pptr, int bracks, int flags)
20952096
else
20962097
ppar = *s++ - '0';
20972098
}
2098-
else if ((ie = itype_end(s, IIDENT, 0)) != s)
2099+
else if ((ie = itype_end(s, itype, 0)) != s)
20992100
s = ie;
21002101
else if (c == Quest)
21012102
*s++ = '?';
@@ -2183,7 +2184,7 @@ fetchvalue(Value v, char **pptr, int bracks, int flags)
21832184
return v;
21842185
}
21852186
} else if (!(flags & SCANPM_ASSIGNING) && v->isarr &&
2186-
itype_end(t, IIDENT, 1) != t && isset(KSHARRAYS))
2187+
itype_end(t, INAMESPC, 1) != t && isset(KSHARRAYS))
21872188
v->end = 1, v->isarr = 0;
21882189
}
21892190
if (!bracks && *s)
@@ -6196,7 +6197,7 @@ setscope(Param pm)
61966197
if (pm->node.flags & PM_NAMEREF) {
61976198
Param basepm;
61986199
struct asgment stop;
6199-
char *t = pm->u.str ? itype_end(pm->u.str, IIDENT, 0) : NULL;
6200+
char *t = pm->u.str ? itype_end(pm->u.str, INAMESPC, 0) : NULL;
62006201

62016202
/* Temporarily change nameref to array parameter itself */
62026203
if (t && *t == '[')
@@ -6277,7 +6278,7 @@ upscope(Param pm, int reflevel)
62776278
mod_export int
62786279
valid_refname(char *val)
62796280
{
6280-
char *t = itype_end(val, IIDENT, 0);
6281+
char *t = itype_end(val, INAMESPC, 0);
62816282

62826283
if (*t != 0) {
62836284
if (*t == '[') {

Src/subst.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1870,7 +1870,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
18701870
* these later on, too.
18711871
*/
18721872
c = *s;
1873-
if (itype_end(s, IIDENT, 1) == s && *s != '#' && c != Pound &&
1873+
if (itype_end(s, INAMESPC, 1) == s && *s != '#' && c != Pound &&
18741874
!IS_DASH(c) &&
18751875
c != '!' && c != '$' && c != String && c != Qstring &&
18761876
c != '?' && c != Quest &&
@@ -2332,7 +2332,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
23322332
}
23332333
} else if ((c == '#' || c == Pound) &&
23342334
(inbrace || !isset(POSIXIDENTIFIERS)) &&
2335-
(itype_end(s+1, IIDENT, 0) != s + 1
2335+
(itype_end(s+1, INAMESPC, 0) != s + 1
23362336
|| (cc = s[1]) == '*' || cc == Star || cc == '@'
23372337
|| cc == '?' || cc == Quest
23382338
|| cc == '$' || cc == String || cc == Qstring
@@ -2369,8 +2369,9 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
23692369
* Try to handle this when parameter is named
23702370
* by (P) (second part of test).
23712371
*/
2372-
if (itype_end(s+1, IIDENT, 0) != s+1 || (aspar && isstring(s[1]) &&
2373-
(s[2] == Inbrace || s[2] == Inpar)))
2372+
if (itype_end(s+1, INAMESPC, 0) != s+1 ||
2373+
(aspar && isstring(s[1]) &&
2374+
(s[2] == Inbrace || s[2] == Inpar)))
23742375
chkset = 1, s++;
23752376
else if (!inbrace) {
23762377
/* Special case for `$+' on its own --- leave unmodified */
@@ -2531,6 +2532,8 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
25312532
scanflags |= SCANPM_DQUOTED;
25322533
if (chkset)
25332534
scanflags |= SCANPM_CHECKING;
2535+
if (!inbrace)
2536+
scanflags |= SCANPM_NONAMESPC;
25342537
/*
25352538
* Second argument: decide whether to use the subexpression or
25362539
* the string next on the line as the parameter name.
@@ -3211,7 +3214,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
32113214
shortest = 0;
32123215
++s;
32133216
}
3214-
if (*itype_end(s, IIDENT, 0)) {
3217+
if (*itype_end(s, INAMESPC, 0)) {
32153218
untokenize(s);
32163219
zerr("not an identifier: %s", s);
32173220
return NULL;
@@ -3271,7 +3274,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
32713274
int intersect = (*s == '*' || *s == Star);
32723275
char **compare, **ap, **apsrc;
32733276
++s;
3274-
if (*itype_end(s, IIDENT, 0)) {
3277+
if (*itype_end(s, INAMESPC, 0)) {
32753278
untokenize(s);
32763279
zerr("not an identifier: %s", s);
32773280
return NULL;

Src/utils.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3123,7 +3123,7 @@ spckword(char **s, int hist, int cmd, int ask)
31233123

31243124
if (**s == String && !*t) {
31253125
guess = *s + 1;
3126-
if (itype_end(guess, IIDENT, 1) == guess)
3126+
if (itype_end(guess, INAMESPC, 1) == guess)
31273127
return;
31283128
ic = String;
31293129
d = 100;
@@ -4310,13 +4310,27 @@ wcsitype(wchar_t c, int itype)
43104310
* If "once" is set, just test the first character, i.e. (outptr !=
43114311
* inptr) tests whether the first character is valid in an identifier.
43124312
*
4313-
* Currently this is only called with itype IIDENT, IUSER or ISEP.
4313+
* Currently called only with itype INAMESPC, IIDENT, IUSER or ISEP.
43144314
*/
43154315

43164316
/**/
43174317
mod_export char *
43184318
itype_end(const char *ptr, int itype, int once)
43194319
{
4320+
if (itype == INAMESPC) {
4321+
itype = IIDENT;
4322+
if (once == 0 && !isset(POSIXIDENTIFIERS)) {
4323+
/* Special case for names containing ".", ksh93 namespaces */
4324+
char *t = itype_end(ptr + (*ptr == '.'), itype, 0);
4325+
if (t > ptr+1) {
4326+
if (*t == '.')
4327+
return itype_end(t+1, itype, 0);
4328+
else
4329+
return t;
4330+
}
4331+
}
4332+
}
4333+
43204334
#ifdef MULTIBYTE_SUPPORT
43214335
if (isset(MULTIBYTE) &&
43224336
(itype != IIDENT || !isset(POSIXIDENTIFIERS))) {

Src/zsh.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1963,6 +1963,8 @@ struct tieddata {
19631963
*/
19641964
#define SCANPM_CHECKING (1<<10) /* Check if set, no need to create */
19651965
#define SCANPM_NOEXEC (1<<11) /* No command substitutions, etc. */
1966+
#define SCANPM_NONAMESPC (1<<12) /* namespace syntax not allowed */
1967+
19661968
/* "$foo[@]"-style substitution
19671969
* Only sign bit is significant
19681970
*/

Src/ztype.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#define IWSEP (1 << 13)
4444
#define INULL (1 << 14)
4545
#define IPATTERN (1 << 15)
46+
#define INAMESPC (1 << 16)
4647
#define zistype(X,Y) (typtab[(unsigned char) (X)] & Y)
4748
#define idigit(X) zistype(X,IDIGIT)
4849
#define ialnum(X) zistype(X,IALNUM)

0 commit comments

Comments
 (0)