diff options
author | Bart Schaefer <schaefer@zsh.org> | 2023-03-05 14:03:42 -0800 |
---|---|---|
committer | Bart Schaefer <schaefer@zsh.org> | 2023-03-05 14:03:42 -0800 |
commit | a9ba1662165823a0303a03fdeddb2ce4ca3814e5 (patch) | |
tree | 4e6d63f11ccb7650bd31ff93f47354adaf446cc4 /Src | |
parent | 806d096b0e7a64bf9712be1cb8159a1ef5b4bf81 (diff) | |
download | zsh-a9ba1662165823a0303a03fdeddb2ce4ca3814e5.tar.gz zsh-a9ba1662165823a0303a03fdeddb2ce4ca3814e5.tar.xz zsh-a9ba1662165823a0303a03fdeddb2ce4ca3814e5.zip |
51483: Enable assignment and expansion of parameters with ksh-like namespace prefixes.
Diffstat (limited to 'Src')
-rw-r--r-- | Src/Zle/compcore.c | 4 | ||||
-rw-r--r-- | Src/Zle/zle_tricky.c | 6 | ||||
-rw-r--r-- | Src/lex.c | 2 | ||||
-rw-r--r-- | Src/params.c | 11 | ||||
-rw-r--r-- | Src/subst.c | 15 | ||||
-rw-r--r-- | Src/utils.c | 18 | ||||
-rw-r--r-- | Src/zsh.h | 2 | ||||
-rw-r--r-- | Src/ztype.h | 1 |
8 files changed, 40 insertions, 19 deletions
diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c index 64a860fa3..77fce66e8 100644 --- a/Src/Zle/compcore.c +++ b/Src/Zle/compcore.c @@ -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); } diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c index 07fac7144..690cf6efb 100644 --- a/Src/Zle/zle_tricky.c +++ b/Src/Zle/zle_tricky.c @@ -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); diff --git a/Src/lex.c b/Src/lex.c index 15da85a93..2f7937410 100644 --- a/Src/lex.c +++ b/Src/lex.c @@ -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 { diff --git a/Src/params.c b/Src/params.c index 90302b1b0..d3b6a7d43 100644 --- a/Src/params.c +++ b/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 == '[') { diff --git a/Src/subst.c b/Src/subst.c index 05bfcc03b..7a4b433bc 100644 --- a/Src/subst.c +++ b/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; diff --git a/Src/utils.c b/Src/utils.c index 55f2d1ab0..1393ecb13 100644 --- a/Src/utils.c +++ b/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))) { diff --git a/Src/zsh.h b/Src/zsh.h index 96b4b06bd..0de1f7afb 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -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 */ diff --git a/Src/ztype.h b/Src/ztype.h index 8757fc733..4675f73a9 100644 --- a/Src/ztype.h +++ b/Src/ztype.h @@ -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) |