1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-09-03 10:21:46 +02:00

zsh-workers/8319

This commit is contained in:
Tanaka Akira 1999-10-18 09:57:00 +00:00
parent 2246999a84
commit 910dc80a58
6 changed files with 155 additions and 39 deletions

View file

@ -107,16 +107,15 @@ evalcond(Cond c)
left = dupstring((char *) c->left);
singsub(&left);
untokenize(left);
if (c->right) {
if (c->right && c->type != COND_STREQ && c->type != COND_STRNEQ) {
right = dupstring((char *) c->right);
singsub(&right);
if (c->type != COND_STREQ && c->type != COND_STRNEQ)
untokenize(right);
untokenize(right);
}
if (tracingcond) {
if (c->type < COND_MOD) {
char *rt = (char *)right;
char *rt = (char *) right;
if (c->type == COND_STREQ || c->type == COND_STRNEQ) {
rt = dupstring(rt);
untokenize(rt);
@ -168,9 +167,29 @@ evalcond(Cond c)
switch (c->type) {
case COND_STREQ:
return matchpat(left, right);
case COND_STRNEQ:
return !matchpat(left, right);
{
Patprog pprog = c->prog;
int test;
if (pprog == dummy_patprog1 || pprog == dummy_patprog2) {
char *opat;
int save;
right = opat = dupstring((char *) c->right);
singsub(&right);
save = (!strcmp(opat, right) && pprog != dummy_patprog2);
if (!(pprog = patcompile(right, (save ? PAT_ZDUP : PAT_STATIC),
NULL)))
zerr("bad pattern: %s", right, 0);
else if (save)
c->prog = pprog;
}
test = (pprog && pattry(pprog, left));
return (c->type == COND_STREQ ? test : !test);
}
case COND_STRLT:
return strcmp(left, right) < 0;
case COND_STRGTR:

View file

@ -422,10 +422,13 @@ execcase(Cmd cmd, LinkList args, int flags)
char *word;
List *l;
char **p;
Patprog *pp, pprog;
int save;
node = cmd->u.casecmd;
l = node->lists;
p = node->pats;
pp = node->progs;
word = dupstring(*p++);
singsub(&word);
@ -435,22 +438,47 @@ execcase(Cmd cmd, LinkList args, int flags)
if (node) {
cmdpush(CS_CASE);
while (*p) {
char *pat = dupstring(*p + 1);
singsub(&pat);
char *pat = NULL, *opat;
pprog = NULL;
save = 0;
if (isset(XTRACE)) {
char *pat2 = dupstring(pat);
char *pat2;
opat = pat = dupstring(*p + 1);
singsub(&pat);
save = (!strcmp(pat, opat) && *pp != dummy_patprog2);
pat2 = dupstring(pat);
untokenize(pat2);
printprompt4();
fprintf(stderr, "case %s (%s)\n", word, pat2);
fflush(stderr);
}
if (matchpat(word, pat)) {
if (*pp != dummy_patprog1 && *pp != dummy_patprog2)
pprog = *pp;
if (!pprog) {
if (!pat) {
opat = pat = dupstring(*p + 1);
singsub(&pat);
save = (!strcmp(pat, opat) && *pp != dummy_patprog2);
}
if (!(pprog = patcompile(pat, (save ? PAT_ZDUP : PAT_STATIC),
NULL)))
zerr("bad pattern: %s", pat, 0);
else if (save)
*pp = pprog;
}
if (pprog && pattry(pprog, word)) {
do {
execlist(*l++, 1, **p == ';' && (flags & CFLAG_EXEC));
} while(**p++ == '&' && *p);
break;
}
p++;
pp++;
l++;
}
cmdpop();

View file

@ -539,6 +539,7 @@ par_case(Cmd c)
LinkList pats, lists;
int n = 1;
char **pp;
Patprog *ppp;
List *ll;
LinkNode no;
struct casecmd *cc;
@ -659,11 +660,17 @@ par_case(Cmd c)
incmdpos = 1;
yylex();
cc->pats = (char **)alloc((n + 1) * sizeof(char *));
cc->pats = (char **) alloc((n + 1) * sizeof(char *));
cc->progs = (Patprog *) alloc((n + 1) * sizeof(Patprog));
for (pp = cc->pats, no = firstnode(pats); no; incnode(no))
for (pp = cc->pats, ppp = cc->progs, no = firstnode(pats);
no; incnode(no)) {
*pp++ = (char *)getdata(no);
*ppp++ = dummy_patprog1;
}
*pp = NULL;
*ppp = NULL;
cc->lists = (List *) alloc((n + 1) * sizeof(List));
for (ll = cc->lists, no = firstnode(lists); no; incnode(no), ll++)
if (!(*ll = (List) getdata(no)))
@ -1438,18 +1445,21 @@ par_cond_triple(char *a, char *b, char *c)
Cond n = (Cond) make_cond();
int t0;
n->ntype = NT_SET(N_COND, NT_STR, NT_STR, 0, 0);
n->left = (void *) a;
n->right = (void *) c;
n->prog = dummy_patprog1;
if ((b[0] == Equals || b[0] == '=') &&
(!b[1] || ((b[1] == Equals || b[1] == '=') && !b[2])))
(!b[1] || ((b[1] == Equals || b[1] == '=') && !b[2]))) {
n->ntype = NT_SET(N_COND, NT_STR, NT_STR, NT_PAT, 0);
n->type = COND_STREQ;
else if (b[0] == '!' && (b[1] == Equals || b[1] == '=') && !b[2])
} else if (b[0] == '!' && (b[1] == Equals || b[1] == '=') && !b[2]) {
n->ntype = NT_SET(N_COND, NT_STR, NT_STR, NT_PAT, 0);
n->type = COND_STRNEQ;
else if (b[0] == '-') {
if ((t0 = get_cond_num(b + 1)) > -1)
} else if (b[0] == '-') {
if ((t0 = get_cond_num(b + 1)) > -1) {
n->ntype = NT_SET(N_COND, NT_STR, NT_STR, 0, 0);
n->type = t0 + COND_NT;
else {
} else {
char *d[3];
n->ntype = NT_SET(N_COND, NT_STR, NT_STR | NT_ARR, 0, 0);

View file

@ -427,8 +427,13 @@ patcompile(char *exp, int inflags, char **endexp)
* The pattern was compiled in a fixed buffer: unless told otherwise,
* we stick the compiled pattern on the heap. This is necessary
* for files where we will often be compiling multiple segments at once.
* But if we get the ZDUP flag w always put it in zalloc()ed memory.
*/
if (!(patflags & PAT_STATIC)) {
if (patflags & PAT_ZDUP) {
Patprog newp = (Patprog)zalloc(patsize);
memcpy((char *)newp, (char *)p, patsize);
p = newp;
} else if (!(patflags & PAT_STATIC)) {
Patprog newp = (Patprog)zhalloc(patsize);
memcpy((char *)newp, (char *)p, patsize);
p = newp;
@ -2188,6 +2193,32 @@ static int patrepeat(Upat p)
return count;
}
/* Duplicate a patprog. */
/**/
Patprog
duppatprog(Patprog prog)
{
if (prog && prog != dummy_patprog1 && prog != dummy_patprog2) {
Patprog ret = (Patprog) alloc(prog->size);
memcpy(ret, prog, prog->size);
return ret;
}
return prog;
}
/* Free a patprog. */
/**/
void
freepatprog(Patprog prog)
{
if (prog && prog != dummy_patprog1 && prog != dummy_patprog2)
zfree(prog, prog->size);
}
/**/
#ifdef ZSH_PAT_DEBUG

View file

@ -1933,9 +1933,9 @@ static int flagtab[N_COUNT] = {
NT_SET(N_PLINE, NT_NODE, NT_NODE, 0, 0),
NT_SET(N_CMD, NT_NODE, NT_STR | NT_LIST, NT_NODE | NT_LIST, NT_NODE | NT_LIST),
NT_SET(N_REDIR, NT_STR, 0, 0, 0),
NT_SET(N_COND, NT_NODE, NT_NODE, 0, 0),
NT_SET(N_COND, NT_NODE, NT_NODE, NT_PAT, 0),
NT_SET(N_FOR, NT_STR, NT_STR, NT_STR, NT_NODE),
NT_SET(N_CASE, NT_STR | NT_ARR, NT_NODE | NT_ARR, 0, 0),
NT_SET(N_CASE, NT_STR | NT_ARR, NT_PAT | NT_ARR, NT_NODE | NT_ARR, 0),
NT_SET(N_IF, NT_NODE | NT_ARR, NT_NODE | NT_ARR, 0, 0),
NT_SET(N_WHILE, NT_NODE, NT_NODE, 0, 0),
NT_SET(N_VARASG, NT_STR, NT_STR, NT_STR | NT_LIST, 0),
@ -1983,18 +1983,27 @@ dupstruct(void *a)
case NT_STR:
n = dupstring(on);
break;
case NT_PAT:
n = duppatprog(on);
break;
case NT_LIST | NT_NODE:
n = duplist(on, (VFunc) dupstruct);
break;
case NT_LIST | NT_STR:
n = duplist(on, (VFunc) (useheap ? dupstring : ztrdup));
break;
case NT_LIST | NT_PAT:
n = duplist(on, (VFunc) duppatprog);
break;
case NT_NODE | NT_ARR:
n = duparray(on, (VFunc) dupstruct);
break;
case NT_STR | NT_ARR:
n = duparray(on, (VFunc) (useheap ? dupstring : ztrdup));
break;
case NT_PAT | NT_ARR:
n = duparray(on, (VFunc) duppatprog);
break;
default:
DPUTS(1, "BUG: bad node type in dupstruct()");
abort();
@ -2055,32 +2064,49 @@ ifreestruct(void *a)
case NT_STR:
zsfree((char *) n);
break;
case NT_PAT:
freepatprog((Patprog) n);
break;
case NT_LIST | NT_NODE:
freelinklist((LinkList) n, (FreeFunc) freestruct);
break;
case NT_NODE | NT_ARR:
{
void **p = (void **) n;
while (*p)
freestruct(*p++);
zfree(n, sizeof(void *) * (p + 1 - (void **) n));
break;
}
case NT_LIST | NT_STR:
freelinklist((LinkList) n, (FreeFunc) zsfree);
break;
case NT_LIST | NT_PAT:
freelinklist((LinkList) n, (FreeFunc) freepatprog);
break;
case NT_NODE | NT_ARR:
{
void **p = (void **) n;
while (*p)
freestruct(*p++);
zfree(n, sizeof(void *) * (p + 1 - (void **) n));
break;
}
case NT_STR | NT_ARR:
freearray((char **) n);
break;
case NT_PAT | NT_ARR:
{
Patprog *p = (Patprog *) n;
while (*p)
freepatprog(*p++);
zfree(n, sizeof(void *) * ((void **) p + 1 - (void **) n));
break;
}
default:
DPUTS(1, "BUG: bad node type in freenode()");
abort();
}
}
}
#if 0
DPUTS(size != ((char *) nodes) - ((char *) a),
"BUG: size wrong in freenode()");
#endif
zfree(a, size);
}

View file

@ -392,6 +392,7 @@ struct node {
#define NT_EMPTY 0
#define NT_NODE 1
#define NT_STR 2
#define NT_PAT 3
#define NT_LIST 4
#define NT_ARR 8
@ -502,6 +503,7 @@ struct cond {
int type; /* can be cond_type, or a single */
/* letter (-a, -b, ...) */
void *left, *right;
Patprog prog; /* compiled pattern for `==' and `!=' */
};
#define COND_NOT 0
@ -555,18 +557,11 @@ struct forcmd { /* for/select */
struct casecmd {
/* Cmd->args contains word to test */
int ntype; /* node type */
char **pats;
char **pats; /* pattern strings */
Patprog *progs; /* compiled patterns (on demand) */
List *lists; /* list to execute */
};
/* A command like "if foo then bar elif baz then fubar else fooble" */
/* generates a tree like: */
/* */
/* struct ifcmd a = { next = &b, ifl = "foo", thenl = "bar" } */
/* struct ifcmd b = { next = &c, ifl = "baz", thenl = "fubar" } */
/* struct ifcmd c = { next = NULL, ifl = NULL, thenl = "fooble" } */
struct ifcmd {
int ntype; /* node type */
List *ifls;
@ -974,6 +969,7 @@ struct patprog {
#define PAT_PURES 0x0020 /* Pattern is a pure string: set internally */
#define PAT_STATIC 0x0040 /* Don't copy pattern to heap as per default */
#define PAT_SCAN 0x0080 /* Scanning, so don't try must-match test */
#define PAT_ZDUP 0x0100 /* Copy pattern in real memory */
/* Globbing flags: lower 8 bits gives approx count */
#define GF_LCMATCHUC 0x0100
@ -981,6 +977,12 @@ struct patprog {
#define GF_BACKREF 0x0400
#define GF_MATCHREF 0x0800
/* Dummy Patprog pointers. Used mainly in executions trees, but the
* pattern code needs to knwo about it, too. */
#define dummy_patprog1 ((Patprog) 1)
#define dummy_patprog2 ((Patprog) 2)
/* node used in parameter hash table (paramtab) */
struct param {