mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-05-20 23:41:27 +02:00
51483: Enable assignment and expansion of parameters with ksh-like namespace prefixes.
This commit is contained in:
parent
806d096b0e
commit
a9ba166216
9 changed files with 45 additions and 19 deletions
|
@ -1,5 +1,10 @@
|
|||
2023-03-05 Bart Schaefer <schaefer@zsh.org>
|
||||
|
||||
* 51483: Src/Zle/compcore.c, Src/Zle/zle_tricky.c, Src/lex.c,
|
||||
Src/params.c, Src/subst.c, Src/utils.c, Src/zsh.h, Src/ztype.h:
|
||||
Enable assignment and expansion of parameters with ksh-like
|
||||
namespace prefixes.
|
||||
|
||||
* unposted: Src/Modules/param_private.c: coverity memory leak
|
||||
|
||||
2023-02-28 Mikael Magnusson <mikachu@gmail.com>
|
||||
|
|
|
@ -1230,14 +1230,14 @@ check_param(char *s, int set, int test)
|
|||
else if (idigit(*e))
|
||||
while (idigit(*e))
|
||||
e++;
|
||||
else if ((ie = itype_end(e, IIDENT, 0)) != e) {
|
||||
else if ((ie = itype_end(e, INAMESPC, 0)) != e) {
|
||||
do {
|
||||
e = ie;
|
||||
if (comppatmatch && *comppatmatch &&
|
||||
(*e == Star || *e == Quest))
|
||||
ie = e + 1;
|
||||
else
|
||||
ie = itype_end(e, IIDENT, 0);
|
||||
ie = itype_end(e, INAMESPC, 0);
|
||||
} while (ie != e);
|
||||
}
|
||||
|
||||
|
|
|
@ -576,7 +576,7 @@ parambeg(char *s)
|
|||
while (idigit(*e))
|
||||
e++;
|
||||
else
|
||||
e = itype_end(e, IIDENT, 0);
|
||||
e = itype_end(e, INAMESPC, 0);
|
||||
|
||||
/* Now make sure that the cursor is inside the name. */
|
||||
if (offs <= e - s && offs >= b - s && n <= 0) {
|
||||
|
@ -765,7 +765,7 @@ docomplete(int lst)
|
|||
else if (idigit(*q))
|
||||
do q++; while (idigit(*q));
|
||||
else
|
||||
q = itype_end(q, IIDENT, 0);
|
||||
q = itype_end(q, INAMESPC, 0);
|
||||
sav = *q;
|
||||
*q = '\0';
|
||||
if (zlemetacs - wb == q - s &&
|
||||
|
@ -1497,7 +1497,7 @@ get_comp_string(void)
|
|||
if (varq)
|
||||
tt = clwords[clwpos];
|
||||
|
||||
s = itype_end(tt, IIDENT, 0);
|
||||
s = itype_end(tt, INAMESPC, 0);
|
||||
sav = *s;
|
||||
*s = '\0';
|
||||
zsfree(varname);
|
||||
|
|
|
@ -1230,7 +1230,7 @@ gettokstr(int c, int sub)
|
|||
else {
|
||||
int sav = *lexbuf.ptr;
|
||||
*lexbuf.ptr = '\0';
|
||||
t = itype_end(t, IIDENT, 0);
|
||||
t = itype_end(t, INAMESPC, 0);
|
||||
if (t < lexbuf.ptr) {
|
||||
skipparens(Inbrack, Outbrack, &t);
|
||||
} else {
|
||||
|
|
11
Src/params.c
11
Src/params.c
|
@ -1223,7 +1223,7 @@ isident(char *s)
|
|||
break;
|
||||
} else {
|
||||
/* Find the first character in `s' not in the iident type table */
|
||||
ss = itype_end(s, IIDENT, 0);
|
||||
ss = itype_end(s, INAMESPC, 0);
|
||||
}
|
||||
|
||||
/* If the next character is not [, then it is *
|
||||
|
@ -2086,6 +2086,7 @@ fetchvalue(Value v, char **pptr, int bracks, int flags)
|
|||
char *s, *t, *ie;
|
||||
char sav, c;
|
||||
int ppar = 0;
|
||||
int itype = (flags & SCANPM_NONAMESPC) ? IIDENT : INAMESPC;
|
||||
|
||||
s = t = *pptr;
|
||||
|
||||
|
@ -2095,7 +2096,7 @@ fetchvalue(Value v, char **pptr, int bracks, int flags)
|
|||
else
|
||||
ppar = *s++ - '0';
|
||||
}
|
||||
else if ((ie = itype_end(s, IIDENT, 0)) != s)
|
||||
else if ((ie = itype_end(s, itype, 0)) != s)
|
||||
s = ie;
|
||||
else if (c == Quest)
|
||||
*s++ = '?';
|
||||
|
@ -2183,7 +2184,7 @@ fetchvalue(Value v, char **pptr, int bracks, int flags)
|
|||
return v;
|
||||
}
|
||||
} else if (!(flags & SCANPM_ASSIGNING) && v->isarr &&
|
||||
itype_end(t, IIDENT, 1) != t && isset(KSHARRAYS))
|
||||
itype_end(t, INAMESPC, 1) != t && isset(KSHARRAYS))
|
||||
v->end = 1, v->isarr = 0;
|
||||
}
|
||||
if (!bracks && *s)
|
||||
|
@ -6196,7 +6197,7 @@ setscope(Param pm)
|
|||
if (pm->node.flags & PM_NAMEREF) {
|
||||
Param basepm;
|
||||
struct asgment stop;
|
||||
char *t = pm->u.str ? itype_end(pm->u.str, IIDENT, 0) : NULL;
|
||||
char *t = pm->u.str ? itype_end(pm->u.str, INAMESPC, 0) : NULL;
|
||||
|
||||
/* Temporarily change nameref to array parameter itself */
|
||||
if (t && *t == '[')
|
||||
|
@ -6277,7 +6278,7 @@ upscope(Param pm, int reflevel)
|
|||
mod_export int
|
||||
valid_refname(char *val)
|
||||
{
|
||||
char *t = itype_end(val, IIDENT, 0);
|
||||
char *t = itype_end(val, INAMESPC, 0);
|
||||
|
||||
if (*t != 0) {
|
||||
if (*t == '[') {
|
||||
|
|
15
Src/subst.c
15
Src/subst.c
|
@ -1870,7 +1870,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
|
|||
* these later on, too.
|
||||
*/
|
||||
c = *s;
|
||||
if (itype_end(s, IIDENT, 1) == s && *s != '#' && c != Pound &&
|
||||
if (itype_end(s, INAMESPC, 1) == s && *s != '#' && c != Pound &&
|
||||
!IS_DASH(c) &&
|
||||
c != '!' && c != '$' && c != String && c != Qstring &&
|
||||
c != '?' && c != Quest &&
|
||||
|
@ -2332,7 +2332,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
|
|||
}
|
||||
} else if ((c == '#' || c == Pound) &&
|
||||
(inbrace || !isset(POSIXIDENTIFIERS)) &&
|
||||
(itype_end(s+1, IIDENT, 0) != s + 1
|
||||
(itype_end(s+1, INAMESPC, 0) != s + 1
|
||||
|| (cc = s[1]) == '*' || cc == Star || cc == '@'
|
||||
|| cc == '?' || cc == Quest
|
||||
|| cc == '$' || cc == String || cc == Qstring
|
||||
|
@ -2369,8 +2369,9 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
|
|||
* Try to handle this when parameter is named
|
||||
* by (P) (second part of test).
|
||||
*/
|
||||
if (itype_end(s+1, IIDENT, 0) != s+1 || (aspar && isstring(s[1]) &&
|
||||
(s[2] == Inbrace || s[2] == Inpar)))
|
||||
if (itype_end(s+1, INAMESPC, 0) != s+1 ||
|
||||
(aspar && isstring(s[1]) &&
|
||||
(s[2] == Inbrace || s[2] == Inpar)))
|
||||
chkset = 1, s++;
|
||||
else if (!inbrace) {
|
||||
/* Special case for `$+' on its own --- leave unmodified */
|
||||
|
@ -2531,6 +2532,8 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
|
|||
scanflags |= SCANPM_DQUOTED;
|
||||
if (chkset)
|
||||
scanflags |= SCANPM_CHECKING;
|
||||
if (!inbrace)
|
||||
scanflags |= SCANPM_NONAMESPC;
|
||||
/*
|
||||
* Second argument: decide whether to use the subexpression or
|
||||
* 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,
|
|||
shortest = 0;
|
||||
++s;
|
||||
}
|
||||
if (*itype_end(s, IIDENT, 0)) {
|
||||
if (*itype_end(s, INAMESPC, 0)) {
|
||||
untokenize(s);
|
||||
zerr("not an identifier: %s", s);
|
||||
return NULL;
|
||||
|
@ -3271,7 +3274,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
|
|||
int intersect = (*s == '*' || *s == Star);
|
||||
char **compare, **ap, **apsrc;
|
||||
++s;
|
||||
if (*itype_end(s, IIDENT, 0)) {
|
||||
if (*itype_end(s, INAMESPC, 0)) {
|
||||
untokenize(s);
|
||||
zerr("not an identifier: %s", s);
|
||||
return NULL;
|
||||
|
|
18
Src/utils.c
18
Src/utils.c
|
@ -3123,7 +3123,7 @@ spckword(char **s, int hist, int cmd, int ask)
|
|||
|
||||
if (**s == String && !*t) {
|
||||
guess = *s + 1;
|
||||
if (itype_end(guess, IIDENT, 1) == guess)
|
||||
if (itype_end(guess, INAMESPC, 1) == guess)
|
||||
return;
|
||||
ic = String;
|
||||
d = 100;
|
||||
|
@ -4310,13 +4310,27 @@ wcsitype(wchar_t c, int itype)
|
|||
* If "once" is set, just test the first character, i.e. (outptr !=
|
||||
* inptr) tests whether the first character is valid in an identifier.
|
||||
*
|
||||
* Currently this is only called with itype IIDENT, IUSER or ISEP.
|
||||
* Currently called only with itype INAMESPC, IIDENT, IUSER or ISEP.
|
||||
*/
|
||||
|
||||
/**/
|
||||
mod_export char *
|
||||
itype_end(const char *ptr, int itype, int once)
|
||||
{
|
||||
if (itype == INAMESPC) {
|
||||
itype = IIDENT;
|
||||
if (once == 0 && !isset(POSIXIDENTIFIERS)) {
|
||||
/* Special case for names containing ".", ksh93 namespaces */
|
||||
char *t = itype_end(ptr + (*ptr == '.'), itype, 0);
|
||||
if (t > ptr+1) {
|
||||
if (*t == '.')
|
||||
return itype_end(t+1, itype, 0);
|
||||
else
|
||||
return t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MULTIBYTE_SUPPORT
|
||||
if (isset(MULTIBYTE) &&
|
||||
(itype != IIDENT || !isset(POSIXIDENTIFIERS))) {
|
||||
|
|
|
@ -1963,6 +1963,8 @@ struct tieddata {
|
|||
*/
|
||||
#define SCANPM_CHECKING (1<<10) /* Check if set, no need to create */
|
||||
#define SCANPM_NOEXEC (1<<11) /* No command substitutions, etc. */
|
||||
#define SCANPM_NONAMESPC (1<<12) /* namespace syntax not allowed */
|
||||
|
||||
/* "$foo[@]"-style substitution
|
||||
* Only sign bit is significant
|
||||
*/
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#define IWSEP (1 << 13)
|
||||
#define INULL (1 << 14)
|
||||
#define IPATTERN (1 << 15)
|
||||
#define INAMESPC (1 << 16)
|
||||
#define zistype(X,Y) (typtab[(unsigned char) (X)] & Y)
|
||||
#define idigit(X) zistype(X,IDIGIT)
|
||||
#define ialnum(X) zistype(X,IALNUM)
|
||||
|
|
Loading…
Reference in a new issue