1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2026-01-06 09:41:07 +01:00

zsh-workers/8254

This commit is contained in:
Tanaka Akira 1999-10-14 15:01:13 +00:00
parent 537091ddf2
commit 356af07859
3 changed files with 51 additions and 13 deletions

View file

@ -139,6 +139,17 @@ item(tt(R))(
Like `tt(r)', but gives the last match. For associative arrays, gives
all possible matches.
)
item(tt(k))(
If used in a subscript on a parameter that is not an associative
array, this behaves like `tt(r)', but if used on an association, it
makes the keys be interpreted as patterns and returns the first value
whose key matches the var(exp).
)
item(tt(K))(
On an associtation this is like `tt(k)' but returns all values whose
keys match the var(exp). On other types of parameters this has the
same effect as `tt(R)'.
)
item(tt(i))(
like `tt(r)', but gives the index of the match instead; this may not
be combined with a second argument. For associative arrays, the key

View file

@ -359,6 +359,7 @@ scancountparams(HashNode hn, int flags)
}
static Patprog scanprog;
static char *scanstr;
static char **paramvals;
/**/
@ -366,12 +367,20 @@ void
scanparamvals(HashNode hn, int flags)
{
struct value v;
if (numparamvals && (flags & (SCANPM_MATCHVAL|SCANPM_MATCHKEY)) &&
!(flags & SCANPM_MATCHMANY))
Patprog prog;
if (numparamvals && !(flags & SCANPM_MATCHMANY) &&
(flags & (SCANPM_MATCHVAL|SCANPM_MATCHKEY|SCANPM_KEYMATCH)))
return;
v.pm = (Param)hn;
if ((flags & SCANPM_MATCHKEY) &&
!pattry(scanprog, v.pm->nam)) {
if ((flags & SCANPM_KEYMATCH)) {
char *tmp = dupstring(v.pm->nam);
tokenize(tmp);
if (!(prog = patcompile(tmp, 0, NULL)) || !pattry(prog, scanstr))
return;
} else if ((flags & SCANPM_MATCHKEY) && !pattry(scanprog, v.pm->nam)) {
return;
}
if (flags & SCANPM_WANTKEYS) {
@ -736,9 +745,10 @@ static zlong
getarg(char **str, int *inv, Value v, int a2, zlong *w)
{
int hasbeg = 0, word = 0, rev = 0, ind = 0, down = 0, l, i, ishash;
int keymatch = 0;
char *s = *str, *sep = NULL, *t, sav, *d, **ta, **p, *tt;
zlong num = 1, beg = 0, r = 0;
Patprog pprog;
Patprog pprog = NULL;
ishash = (v->pm && PM_TYPE(v->pm->flags) == PM_HASHED);
@ -750,18 +760,29 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w)
switch (*s) {
case 'r':
rev = 1;
down = ind = 0;
keymatch = down = ind = 0;
break;
case 'R':
rev = down = 1;
keymatch = ind = 0;
break;
case 'k':
keymatch = ishash;
rev = 1;
down = ind = 0;
break;
case 'K':
keymatch = ishash;
rev = down = 1;
ind = 0;
break;
case 'i':
rev = ind = 1;
down = 0;
down = keymatch = 0;
break;
case 'I':
rev = ind = down = 1;
keymatch = 0;
break;
case 'w':
/* If the parameter is a scalar, then make subscription *
@ -818,7 +839,7 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w)
default:
flagerr:
num = 1;
word = rev = ind = down = 0;
word = rev = ind = down = keymatch = 0;
sep = NULL;
s = *str - 1;
}
@ -841,7 +862,7 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w)
v->isarr &= ~SCANPM_WANTVALS;
} else if (rev)
v->isarr |= SCANPM_WANTVALS;
if (!down && ishash)
if (!down && !keymatch && ishash)
v->isarr &= ~SCANPM_MATCHMANY;
}
*inv = ind;
@ -938,13 +959,16 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w)
}
tokenize(s);
if ((pprog = patcompile(s, 0, NULL))) {
if (keymatch || (pprog = patcompile(s, 0, NULL))) {
int len;
if (v->isarr) {
if (ishash) {
scanprog = pprog;
if (ind)
scanstr = s;
if (keymatch)
v->isarr |= SCANPM_KEYMATCH;
else if (ind)
v->isarr |= SCANPM_MATCHKEY;
else
v->isarr |= SCANPM_MATCHVAL;
@ -952,7 +976,8 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w)
v->isarr |= SCANPM_MATCHMANY;
if ((ta = getvaluearr(v)) &&
(*ta || ((v->isarr & SCANPM_MATCHMANY) &&
(v->isarr & (SCANPM_MATCHKEY | SCANPM_MATCHVAL))))) {
(v->isarr & (SCANPM_MATCHKEY | SCANPM_MATCHVAL |
SCANPM_KEYMATCH))))) {
*inv = v->inv;
*w = v->b;
return 1;
@ -1131,7 +1156,8 @@ getindex(char **pptr, Value v)
s++;
if (v->isarr && a == b &&
(!(v->isarr & SCANPM_MATCHMANY) ||
!(v->isarr & (SCANPM_MATCHKEY | SCANPM_MATCHVAL))))
!(v->isarr & (SCANPM_MATCHKEY | SCANPM_MATCHVAL |
SCANPM_KEYMATCH))))
v->isarr = 0;
v->a = a;
v->b = b;

View file

@ -1086,6 +1086,7 @@ struct param {
#define SCANPM_MATCHVAL (1<<4)
#define SCANPM_MATCHMANY (1<<5)
#define SCANPM_ASSIGNING (1<<6)
#define SCANPM_KEYMATCH (1<<7)
#define SCANPM_ISVAR_AT ((-1)<<15) /* Only sign bit is significant */
/*