mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-01-01 05:16:05 +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>
|
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
|
* 39947: Test/D04parameter.ztst: Test out-of-rantge multiple
|
||||||
array subscripts with and without (@).
|
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);
|
*namptr = dyncat(ds, ptr);
|
||||||
return 1;
|
return 1;
|
||||||
} else if ((ptr = itype_end(str+1, IUSER, 0)) != str+1) { /* ~foo */
|
} else if ((ptr = itype_end(str+1, IUSER, 0)) != str+1) { /* ~foo */
|
||||||
char *hom, save;
|
char *untok, *hom;
|
||||||
|
|
||||||
save = *ptr;
|
if (!isend(*ptr))
|
||||||
if (!isend(save))
|
|
||||||
return 0;
|
return 0;
|
||||||
*ptr = 0;
|
untok = dupstring(++str);
|
||||||
if (!(hom = getnameddir(++str))) {
|
untok[ptr-str] = 0;
|
||||||
|
untokenize(untok);
|
||||||
|
|
||||||
|
if (!(hom = getnameddir(untok))) {
|
||||||
if (isset(NOMATCH) && isset(EXECOPT))
|
if (isset(NOMATCH) && isset(EXECOPT))
|
||||||
zerr("no such user or named directory: %s", str);
|
zerr("no such user or named directory: %s", untok);
|
||||||
*ptr = save;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
*ptr = save;
|
|
||||||
*namptr = dyncat(hom, ptr);
|
*namptr = dyncat(hom, ptr);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
70
Src/utils.c
70
Src/utils.c
|
@ -3959,7 +3959,7 @@ inittyptab(void)
|
||||||
#endif
|
#endif
|
||||||
/* typtab['.'] |= IIDENT; */ /* Allow '.' in variable names - broken */
|
/* typtab['.'] |= IIDENT; */ /* Allow '.' in variable names - broken */
|
||||||
typtab['_'] = IIDENT | IUSER;
|
typtab['_'] = IIDENT | IUSER;
|
||||||
typtab['-'] = typtab['.'] = IUSER;
|
typtab['-'] = typtab['.'] = typtab[STOUC(Dash)] = IUSER;
|
||||||
typtab[' '] |= IBLANK | INBLANK;
|
typtab[' '] |= IBLANK | INBLANK;
|
||||||
typtab['\t'] |= IBLANK | INBLANK;
|
typtab['\t'] |= IBLANK | INBLANK;
|
||||||
typtab['\n'] |= INBLANK;
|
typtab['\n'] |= INBLANK;
|
||||||
|
@ -4157,42 +4157,50 @@ itype_end(const char *ptr, int itype, int once)
|
||||||
(itype != IIDENT || !isset(POSIXIDENTIFIERS))) {
|
(itype != IIDENT || !isset(POSIXIDENTIFIERS))) {
|
||||||
mb_charinit();
|
mb_charinit();
|
||||||
while (*ptr) {
|
while (*ptr) {
|
||||||
wint_t wc;
|
int len;
|
||||||
int len = mb_metacharlenconv(ptr, &wc);
|
if (itok(*ptr)) {
|
||||||
|
/* Not untokenised yet --- can happen in raw command line */
|
||||||
if (!len)
|
len = 1;
|
||||||
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))
|
if (!zistype(*ptr,itype))
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
/*
|
wint_t wc;
|
||||||
* Valid non-ASCII character.
|
len = mb_metacharlenconv(ptr, &wc);
|
||||||
*/
|
|
||||||
switch (itype) {
|
if (!len)
|
||||||
case IWORD:
|
|
||||||
if (!iswalnum(wc) &&
|
|
||||||
!wmemchr(wordchars_wide.chars, wc,
|
|
||||||
wordchars_wide.len))
|
|
||||||
return (char *)ptr;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ISEP:
|
if (wc == WEOF) {
|
||||||
if (!wmemchr(ifs_wide.chars, wc, ifs_wide.len))
|
/* invalid, treat as single character */
|
||||||
return (char *)ptr;
|
int chr = STOUC(*ptr == Meta ? ptr[1] ^ 32 : *ptr);
|
||||||
break;
|
/* 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:
|
case ISEP:
|
||||||
if (!iswalnum(wc))
|
if (!wmemchr(ifs_wide.chars, wc, ifs_wide.len))
|
||||||
return (char *)ptr;
|
return (char *)ptr;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (!iswalnum(wc))
|
||||||
|
return (char *)ptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ptr += len;
|
ptr += len;
|
||||||
|
|
|
@ -69,3 +69,11 @@
|
||||||
>one=/first/directory
|
>one=/first/directory
|
||||||
>two=/directory/the/second
|
>two=/directory/the/second
|
||||||
>three=/noch/ein/verzeichnis
|
>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