mirror of
git://git.code.sf.net/p/zsh/code
synced 2024-12-29 16:25:35 +01:00
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.
This commit is contained in:
parent
e9dbfa8046
commit
921b39ac6b
4 changed files with 59 additions and 39 deletions
|
@ -1,5 +1,9 @@
|
|||
2016-11-15 Peter Stephenson <p.stephenson@samsung.com>
|
||||
|
||||
* 39949: Src/subst.c, Src/utils.c, Test/B09hash.ztst: "-" is
|
||||
allowed in named directories, so needs a special case when
|
||||
sh-tokenized for possible ranges.
|
||||
|
||||
* 39947: Test/D04parameter.ztst: Test out-of-rantge multiple
|
||||
array subscripts with and without (@).
|
||||
|
||||
|
|
16
Src/subst.c
16
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;
|
||||
}
|
||||
|
|
70
Src/utils.c
70
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;
|
||||
wint_t wc;
|
||||
len = mb_metacharlenconv(ptr, &wc);
|
||||
|
||||
if (!len)
|
||||
break;
|
||||
|
||||
case ISEP:
|
||||
if (!wmemchr(ifs_wide.chars, wc, ifs_wide.len))
|
||||
return (char *)ptr;
|
||||
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 */
|
||||
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;
|
||||
|
||||
default:
|
||||
if (!iswalnum(wc))
|
||||
return (char *)ptr;
|
||||
case ISEP:
|
||||
if (!wmemchr(ifs_wide.chars, wc, ifs_wide.len))
|
||||
return (char *)ptr;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!iswalnum(wc))
|
||||
return (char *)ptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
ptr += len;
|
||||
|
|
|
@ -69,3 +69,11 @@
|
|||
>one=/first/directory
|
||||
>two=/directory/the/second
|
||||
>three=/noch/ein/verzeichnis
|
||||
|
||||
hash -d t-t=/foo
|
||||
i="~t-t"
|
||||
print ~t-t/bar
|
||||
print ${~i}/rab
|
||||
0:Dashes are untokenized in directory hash names
|
||||
>/foo/bar
|
||||
>/foo/rab
|
||||
|
|
Loading…
Reference in a new issue