diff options
author | Peter Stephenson <pws@zsh.org> | 2016-11-15 18:01:32 +0000 |
---|---|---|
committer | Peter Stephenson <pws@zsh.org> | 2016-11-15 18:01:32 +0000 |
commit | 921b39ac6b25dbfcc477fc7db4ed1c5c3ffb778c (patch) | |
tree | 47a0b6481316082d3899ad190e444db0d89e698d /Src | |
parent | e9dbfa8046e0da6dbb37340df9d3c95f410a713b (diff) | |
download | zsh-921b39ac6b25dbfcc477fc7db4ed1c5c3ffb778c.tar.gz zsh-921b39ac6b25dbfcc477fc7db4ed1c5c3ffb778c.tar.xz zsh-921b39ac6b25dbfcc477fc7db4ed1c5c3ffb778c.zip |
39949: Special case for "-" in directory names.
It can be sh-tokenized to Dash to allow for appearing in ranges after substitution, so needs to be turned back to "-" in that case.
Diffstat (limited to 'Src')
-rw-r--r-- | Src/subst.c | 16 | ||||
-rw-r--r-- | Src/utils.c | 70 |
2 files changed, 47 insertions, 39 deletions
diff --git a/Src/subst.c b/Src/subst.c index 447177409..c7c552257 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -684,19 +684,19 @@ filesubstr(char **namptr, int assign) *namptr = dyncat(ds, ptr); return 1; } else if ((ptr = itype_end(str+1, IUSER, 0)) != str+1) { /* ~foo */ - char *hom, save; + char *untok, *hom; - save = *ptr; - if (!isend(save)) + if (!isend(*ptr)) return 0; - *ptr = 0; - if (!(hom = getnameddir(++str))) { + untok = dupstring(++str); + untok[ptr-str] = 0; + untokenize(untok); + + if (!(hom = getnameddir(untok))) { if (isset(NOMATCH) && isset(EXECOPT)) - zerr("no such user or named directory: %s", str); - *ptr = save; + zerr("no such user or named directory: %s", untok); return 0; } - *ptr = save; *namptr = dyncat(hom, ptr); return 1; } diff --git a/Src/utils.c b/Src/utils.c index cceaf4c57..92d831172 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -3959,7 +3959,7 @@ inittyptab(void) #endif /* typtab['.'] |= IIDENT; */ /* Allow '.' in variable names - broken */ typtab['_'] = IIDENT | IUSER; - typtab['-'] = typtab['.'] = IUSER; + typtab['-'] = typtab['.'] = typtab[STOUC(Dash)] = IUSER; typtab[' '] |= IBLANK | INBLANK; typtab['\t'] |= IBLANK | INBLANK; typtab['\n'] |= INBLANK; @@ -4157,42 +4157,50 @@ itype_end(const char *ptr, int itype, int once) (itype != IIDENT || !isset(POSIXIDENTIFIERS))) { mb_charinit(); while (*ptr) { - wint_t wc; - int len = mb_metacharlenconv(ptr, &wc); - - if (!len) - break; - - if (wc == WEOF) { - /* invalid, treat as single character */ - int chr = STOUC(*ptr == Meta ? ptr[1] ^ 32 : *ptr); - /* in this case non-ASCII characters can't match */ - if (chr > 127 || !zistype(chr,itype)) - break; - } else if (len == 1 && isascii(*ptr)) { - /* ASCII: can't be metafied, use standard test */ + int len; + if (itok(*ptr)) { + /* Not untokenised yet --- can happen in raw command line */ + len = 1; if (!zistype(*ptr,itype)) break; } else { - /* - * Valid non-ASCII character. - */ - switch (itype) { - case IWORD: - if (!iswalnum(wc) && - !wmemchr(wordchars_wide.chars, wc, - wordchars_wide.len)) - return (char *)ptr; - break; + wint_t wc; + len = mb_metacharlenconv(ptr, &wc); - case ISEP: - if (!wmemchr(ifs_wide.chars, wc, ifs_wide.len)) - return (char *)ptr; + if (!len) break; - default: - if (!iswalnum(wc)) - return (char *)ptr; + if (wc == WEOF) { + /* invalid, treat as single character */ + int chr = STOUC(*ptr == Meta ? ptr[1] ^ 32 : *ptr); + /* in this case non-ASCII characters can't match */ + if (chr > 127 || !zistype(chr,itype)) + break; + } else if (len == 1 && isascii(*ptr)) { + /* ASCII: can't be metafied, use standard test */ + if (!zistype(*ptr,itype)) + break; + } else { + /* + * Valid non-ASCII character. + */ + switch (itype) { + case IWORD: + if (!iswalnum(wc) && + !wmemchr(wordchars_wide.chars, wc, + wordchars_wide.len)) + return (char *)ptr; + break; + + case ISEP: + if (!wmemchr(ifs_wide.chars, wc, ifs_wide.len)) + return (char *)ptr; + break; + + default: + if (!iswalnum(wc)) + return (char *)ptr; + } } } ptr += len; |