mirror of
git://git.code.sf.net/p/zsh/code
synced 2024-12-29 16:25:35 +01:00
users/18298 (tidied up): add {<char>..<char>} expansion
This commit is contained in:
parent
a34754e962
commit
d26461a3c6
4 changed files with 128 additions and 3 deletions
|
@ -1,3 +1,8 @@
|
|||
2014-01-09 Peter Stephenson <p.stephenson@samsung.com>
|
||||
|
||||
* users/18298 (tidied up): Doc/Zsh/expn.yo, Src/glob.c,
|
||||
Test/D09brace.ztst: add {<char>..<char>} expansion.
|
||||
|
||||
2014-01-07 Peter Stephenson <p.w.stephenson@ntlworld.com>
|
||||
|
||||
* Mark Oteiza: 32238: suppress error output completing after ip.
|
||||
|
|
|
@ -1539,6 +1539,16 @@ specified in any of the three numbers, specifying it in the third can be useful
|
|||
to pad for example `tt({-99..100..01})' which is not possible to specify by putting a
|
||||
0 on either of the first two numbers (i.e. pad to two characters).
|
||||
|
||||
An expression of the form `tt({)var(c1)tt(..)var(c2)tt(})', where
|
||||
var(c1) and var(c2) are single characters (which may be multibyte
|
||||
characters), is expanded to every character in the range from var(c1) to
|
||||
var(c2) in whatever character sequence is used internally. For
|
||||
characters with code points below 128 this is US ASCII (this is the only
|
||||
case most users will need). If any intervening character is not
|
||||
printable, appropriate quotation is used to render it printable.
|
||||
If the character sequence is reversed, the output is in reverse
|
||||
order, e.g. `tt({d..a})' is substituted as `tt(d c b a)'.
|
||||
|
||||
If a brace expression matches none of the above forms, it is left
|
||||
unchanged, unless the option tt(BRACE_CCL) (an abbreviation for `brace
|
||||
character class') is set.
|
||||
|
|
101
Src/glob.c
101
Src/glob.c
|
@ -1895,6 +1895,8 @@ hasbraces(char *str)
|
|||
switch (*str++) {
|
||||
case Inbrace:
|
||||
if (!lbr) {
|
||||
if (bracechardots(str-1, NULL, NULL))
|
||||
return 1;
|
||||
lbr = str - 1;
|
||||
if (*str == '-')
|
||||
str++;
|
||||
|
@ -2027,6 +2029,52 @@ xpandredir(struct redir *fn, LinkList redirtab)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for a brace expansion of the form {<char>..<char>}.
|
||||
* On input str must be positioned at an Inbrace, but the sequence
|
||||
* of characters beyond that has not necessarily been checked.
|
||||
* Return 1 if found else 0.
|
||||
*
|
||||
* The other parameters are optionaland if the function returns 1 are
|
||||
* used to return:
|
||||
* - *c1p: the first character in the expansion.
|
||||
* - *c2p: the final character in the expansion.
|
||||
*/
|
||||
|
||||
/**/
|
||||
static int
|
||||
bracechardots(char *str, convchar_t *c1p, convchar_t *c2p)
|
||||
{
|
||||
convchar_t cstart, cend;
|
||||
char *pnext = str + 1, *pconv, convstr[2];
|
||||
if (itok(*pnext)) {
|
||||
convstr[0] = ztokens[*pnext - Pound];
|
||||
convstr[1] = '\0';
|
||||
pconv = convstr;
|
||||
} else
|
||||
pconv = pnext;
|
||||
MB_METACHARINIT();
|
||||
pnext += MB_METACHARLENCONV(pconv, &cstart);
|
||||
if (cstart == WEOF || pnext[0] != '.' || pnext[1] != '.')
|
||||
return 0;
|
||||
pnext += 2;
|
||||
if (itok(*pnext)) {
|
||||
convstr[0] = ztokens[*pnext - Pound];
|
||||
convstr[1] = '\0';
|
||||
pconv = convstr;
|
||||
} else
|
||||
pconv = pnext;
|
||||
MB_METACHARINIT();
|
||||
pnext += MB_METACHARLENCONV(pconv, &cend);
|
||||
if (cend == WEOF || *pnext != Outbrace)
|
||||
return 0;
|
||||
if (c1p)
|
||||
*c1p = cstart;
|
||||
if (c2p)
|
||||
*c2p = cend;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* brace expansion */
|
||||
|
||||
/**/
|
||||
|
@ -2060,10 +2108,57 @@ xpandbraces(LinkList list, LinkNode *np)
|
|||
char *dots, *p, *dots2 = NULL;
|
||||
LinkNode olast = last;
|
||||
/* Get the first number of the range */
|
||||
zlong rstart = zstrtol(str+1,&dots,10), rend = 0;
|
||||
zlong rstart, rend;
|
||||
int err = 0, rev = 0, rincr = 1;
|
||||
int wid1 = (dots - str) - 1, wid2 = (str2 - dots) - 2, wid3 = 0;
|
||||
int strp = str - str3;
|
||||
int wid1, wid2, wid3, strp;
|
||||
convchar_t cstart, cend;
|
||||
|
||||
if (bracechardots(str, &cstart, &cend)) {
|
||||
int lenalloc;
|
||||
/*
|
||||
* This is a character range.
|
||||
*/
|
||||
if (cend < cstart) {
|
||||
convchar_t ctmp = cend;
|
||||
cend = cstart;
|
||||
cstart = ctmp;
|
||||
rev = 1;
|
||||
}
|
||||
uremnode(list, node);
|
||||
strp = str - str3;
|
||||
lenalloc = strp + strlen(str2+1) + 1;
|
||||
for (; cend >= cstart; cend--) {
|
||||
#ifdef MULTIBYTE_SUPPORT
|
||||
char *ncptr;
|
||||
int nclen;
|
||||
mb_metacharinit();
|
||||
ncptr = wcs_nicechar(cend, NULL, NULL);
|
||||
nclen = strlen(ncptr);
|
||||
p = zhalloc(lenalloc + nclen);
|
||||
memcpy(p, str3, strp);
|
||||
memcpy(p + strp, ncptr, nclen);
|
||||
strcpy(p + strp + nclen, str2 + 1);
|
||||
#else
|
||||
p = zhalloc(lenalloc + 1);
|
||||
memcpy(p, str3, strp);
|
||||
sprintf(p + strp, "%c", cend);
|
||||
strcat(p + strp, str2 + 1);
|
||||
#endif
|
||||
insertlinknode(list, last, p);
|
||||
if (rev) /* decreasing: add in reverse order. */
|
||||
last = nextnode(last);
|
||||
}
|
||||
*np = nextnode(olast);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the first number of the range */
|
||||
rstart = zstrtol(str+1,&dots,10);
|
||||
rend = 0;
|
||||
wid1 = (dots - str) - 1;
|
||||
wid2 = (str2 - dots) - 2;
|
||||
wid3 = 0;
|
||||
strp = str - str3;
|
||||
|
||||
if (dots == str + 1 || *dots != '.' || dots[1] != '.')
|
||||
err++;
|
||||
|
|
|
@ -97,3 +97,18 @@
|
|||
0:BRACE_CCL off
|
||||
>X{za-q521}Y
|
||||
|
||||
print -r hey{a..j}there
|
||||
0:{char..char} ranges, simple case
|
||||
>heyathere heybthere heycthere heydthere heyethere heyfthere heygthere heyhthere heyithere heyjthere
|
||||
|
||||
print -r gosh{1,{Z..a},2}cripes
|
||||
0:{char..char} ranges, ASCII ordering
|
||||
>gosh1cripes goshZcripes gosh[cripes gosh\cripes gosh]cripes gosh^cripes gosh_cripes gosh`cripes goshacripes gosh2cripes
|
||||
|
||||
print -r crumbs{y..p}ooh
|
||||
0:{char..char} ranges, reverse
|
||||
>crumbsyooh crumbsxooh crumbswooh crumbsvooh crumbsuooh crumbstooh crumbssooh crumbsrooh crumbsqooh crumbspooh
|
||||
|
||||
print -r left{[..]}right
|
||||
0:{char..char} ranges with tokenized characters
|
||||
>left[right left\right left]right
|
||||
|
|
Loading…
Reference in a new issue