diff options
author | Peter Stephenson <pws@users.sourceforge.net> | 2006-07-10 13:08:22 +0000 |
---|---|---|
committer | Peter Stephenson <pws@users.sourceforge.net> | 2006-07-10 13:08:22 +0000 |
commit | 4a67f2479892fda348546404216270aaaff523ea (patch) | |
tree | 3157f967e4324cdf147aa656c021e55e96f29731 /Src/Zle | |
parent | 272256f5d6f4748aed680256589a67713e517383 (diff) | |
download | zsh-4a67f2479892fda348546404216270aaaff523ea.tar.gz zsh-4a67f2479892fda348546404216270aaaff523ea.tar.xz zsh-4a67f2479892fda348546404216270aaaff523ea.zip |
22544: Improve use of ztype tests for multibyte characters. Add
POSIX_IDENTIFIERS option to control allowability of multibyte alphanumeric characters in parameter and module names.
Diffstat (limited to 'Src/Zle')
-rw-r--r-- | Src/Zle/compcore.c | 16 | ||||
-rw-r--r-- | Src/Zle/zle_tricky.c | 104 |
2 files changed, 81 insertions, 39 deletions
diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c index 008f49185..38b1934e2 100644 --- a/Src/Zle/compcore.c +++ b/Src/Zle/compcore.c @@ -1081,7 +1081,7 @@ check_param(char *s, int set, int test) } if ((*p == String || *p == Qstring) && p[1] != Inpar && p[1] != Inbrack) { /* This is really a parameter expression (not $(...) or $[...]). */ - char *b = p + 1, *e = b; + char *b = p + 1, *e = b, *ie; int n = 0, br = 1, nest = 0; if (*b == Inbrace) { @@ -1124,10 +1124,16 @@ check_param(char *s, int set, int test) else if (idigit(*e)) while (idigit(*e)) e++; - else if (iident(*e)) - while (iident(*e) || - (comppatmatch && *comppatmatch && (*e == Star || *e == Quest))) - e++; + else if ((ie = itype_end(e, IIDENT, 0)) != e) { + do { + e = ie; + if (comppatmatch && *comppatmatch && + (*e == Star || *e == Quest)) + ie = e + 1; + else + ie = itype_end(e, IIDENT, 0); + } while (ie != e); + } /* Now make sure that the cursor is inside the name. */ if (offs <= e - s && offs >= b - s && n <= 0) { diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c index 250804648..28857b03e 100644 --- a/Src/Zle/zle_tricky.c +++ b/Src/Zle/zle_tricky.c @@ -551,9 +551,8 @@ parambeg(char *s) else if (idigit(*e)) while (idigit(*e)) e++; - else if (iident(*e)) - while (iident(*e)) - e++; + else + e = itype_end(e, IIDENT, 0); /* Now make sure that the cursor is inside the name. */ if (offs <= e - s && offs >= b - s && n <= 0) { @@ -740,8 +739,7 @@ docomplete(int lst) else if (idigit(*q)) do q++; while (idigit(*q)); else - while (iident(*q)) - q++; + q = itype_end(q, IIDENT, 0); sav = *q; *q = '\0'; if (zlemetacs - wb == q - s && @@ -1293,7 +1291,7 @@ get_comp_string(void) if (varq) tt = clwords[clwpos]; - for (s = tt; iident(*s); s++); + s = itype_end(tt, IIDENT, 0); sav = *s; *s = '\0'; zsfree(varname); @@ -1360,17 +1358,29 @@ get_comp_string(void) * as being in math. */ if (inwhat != IN_MATH) { int i = 0; - char *nnb = (iident(*s) ? s : s + 1), *nb = NULL, *ne = NULL; - - for (tt = s; ++tt < s + zlemetacs - wb;) + char *nnb, *nb = NULL, *ne = NULL; + + MB_METACHARINIT(); + if (itype_end(s, IIDENT, 1) == s) + nnb = s + MB_METACHARLEN(s); + else + nnb = s; + for (tt = s; tt < s + zlemetacs - wb;) { if (*tt == Inbrack) { i++; nb = nnb; ne = tt; - } else if (i && *tt == Outbrack) + tt++; + } else if (i && *tt == Outbrack) { i--; - else if (!iident(*tt)) - nnb = tt + 1; + tt++; + } else { + int nclen = MB_METACHARLEN(tt); + if (itype_end(tt, IIDENT, 1) == tt) + nnb = tt + nclen; + tt += nclen; + } + } if (i) { inwhat = IN_MATH; insubscr = 1; @@ -1415,33 +1425,59 @@ get_comp_string(void) /* In mathematical expression, we complete parameter names * * (even if they don't have a `$' in front of them). So we * * have to find that name. */ - for (we = zlemetacs; iident(zlemetaline[we]); we++); - for (wb = zlemetacs; --wb >= 0 && iident(zlemetaline[wb]);); - wb++; + char *cspos = zlemetaline + zlemetacs, *wptr, *cptr; + we = itype_end(cspos, IIDENT, 0) - cspos; + + /* + * With multibyte characters we need to go forwards, + * so start at the beginning of the line and continue + * until cspos. + */ + wptr = cptr = zlemetaline; + for (;;) { + cptr = itype_end(wptr, IIDENT, 0); + if (cptr == wptr) { + /* not an ident character */ + wptr = (cptr += MB_METACHARLEN(cptr)); + } + if (cptr >= cspos) { + wb = wptr - zlemetaline; + break; + } + } } zsfree(s); s = zalloc(we - wb + 1); strncpy(s, zlemetaline + wb, we - wb); s[we - wb] = '\0'; - if (wb > 2 && zlemetaline[wb - 1] == '[' && - iident(zlemetaline[wb - 2])) { - int i = wb - 3; - char sav = zlemetaline[wb - 1]; - while (i >= 0 && iident(zlemetaline[i])) - i--; + if (wb > 2 && zlemetaline[wb - 1] == '[') { + char *sqbr = zlemetaline + wb - 1, *cptr, *wptr; - zlemetaline[wb - 1] = '\0'; - zsfree(varname); - varname = ztrdup(zlemetaline + i + 1); - zlemetaline[wb - 1] = sav; - if ((keypm = (Param) paramtab->getnode(paramtab, varname)) && - (keypm->node.flags & PM_HASHED)) { - if (insubscr != 3) - insubscr = 2; - } else - insubscr = 1; + /* Need to search forward for word characters */ + cptr = wptr = zlemetaline; + for (;;) { + cptr = itype_end(wptr, IIDENT, 0); + if (cptr == wptr) { + /* not an ident character */ + wptr = (cptr += MB_METACHARLEN(cptr)); + } + if (cptr >= sqbr) + break; + } + + if (wptr < sqbr) { + zsfree(varname); + varname = ztrduppfx(wptr, sqbr - wptr); + if ((keypm = (Param) paramtab->getnode(paramtab, varname)) && + (keypm->node.flags & PM_HASHED)) { + if (insubscr != 3) + insubscr = 2; + } else + insubscr = 1; + } } + parse_subst_string(s); } /* This variable will hold the current word in quoted form. */ @@ -1562,12 +1598,12 @@ get_comp_string(void) *tp == '@') p++, i++; else { + char *ie; if (idigit(*tp)) while (idigit(*tp)) tp++; - else if (iident(*tp)) - while (iident(*tp)) - tp++; + else if ((ie = itype_end(tp, IIDENT, 0)) != tp) + tp = ie; else { tt = NULL; break; |