diff options
Diffstat (limited to 'Src')
-rw-r--r-- | Src/Modules/zutil.c | 125 |
1 files changed, 84 insertions, 41 deletions
diff --git a/Src/Modules/zutil.c b/Src/Modules/zutil.c index b2eb99df2..9dae030df 100644 --- a/Src/Modules/zutil.c +++ b/Src/Modules/zutil.c @@ -48,6 +48,7 @@ struct stypat { char *pat; /* pattern string */ Patprog prog; /* compiled pattern */ int weight; /* how specific is the pattern? */ + Eprog eval; /* eval-on-retrieve? */ char **vals; }; @@ -64,6 +65,8 @@ freestypat(Stypat p) freepatprog(p->prog); if (p->vals) freearray(p->vals); + if (p->eval) + freeeprog(p->eval); zfree(p, sizeof(*p)); } @@ -101,13 +104,25 @@ getstyle(char *name) /* Store a value for a style. */ -static void -setstypat(Style s, char *pat, Patprog prog, char **vals) +static int +setstypat(Style s, char *pat, Patprog prog, char **vals, int eval) { int weight, tmp, first; char *str; Stypat p, q, qq; + Eprog eprog = NULL; + + if (eval) { + int ef = errflag; + + eprog = parse_string(zjoin(vals, ' ', 1), 0); + errflag = ef; + + if (!eprog) + return 1; + eprog = dupeprog(eprog, 0); + } for (p = s->pats; p; p = p->next) if (!strcmp(pat, p->pat)) { @@ -115,9 +130,12 @@ setstypat(Style s, char *pat, Patprog prog, char **vals) if (p->vals) freearray(p->vals); + if (p->eval) + freeeprog(p->eval); p->vals = zarrdup(vals); + p->eval = eprog; - return; + return 0; } /* New pattern. */ @@ -126,6 +144,7 @@ setstypat(Style s, char *pat, Patprog prog, char **vals) p->pat = ztrdup(pat); p->prog = prog; p->vals = zarrdup(vals); + p->eval = eprog; p->next = NULL; /* Calculate the weight. */ @@ -161,6 +180,8 @@ setstypat(Style s, char *pat, Patprog prog, char **vals) qq->next = p; else s->pats = p; + + return 0; } /* Add a new style. */ @@ -184,9 +205,34 @@ addstyle(char *name) return s; } +static char ** +evalstyle(Stypat p) +{ + int ef = errflag; + char **ret, *str; + + unsetparam("reply"); + execode(p->eval, 1, 0); + if (errflag) { + errflag = ef; + return NULL; + } + errflag = ef; + + if ((ret = getaparam("reply"))) + ret = arrdup(ret); + else if ((str = getsparam("reply"))) { + ret = (char **) hcalloc(2 * sizeof(char *)); + ret[0] = dupstring(str); + } + unsetparam("reply"); + + return ret; +} + /* Look up a style for a context pattern. This does the matching. */ -static Stypat +static char ** lookupstyle(char *ctxt, char *style) { Style s; @@ -196,7 +242,7 @@ lookupstyle(char *ctxt, char *style) if (!strcmp(s->name, style)) for (p = s->pats; p; p = p->next) if (pattry(p->prog, ctxt)) - return p; + return (p->eval ? evalstyle(p) : p->vals); return NULL; } @@ -204,7 +250,7 @@ lookupstyle(char *ctxt, char *style) static int bin_zstyle(char *nam, char **args, char *ops, int func) { - int min, max, n, add = 0, list = 0; + int min, max, n, add = 0, list = 0, eval = 0; if (!args[0]) list = 1; @@ -218,6 +264,10 @@ bin_zstyle(char *nam, char **args, char *ops, int func) } if (oc == 'L') list = 2; + else if (oc == 'e') { + eval = add = 1; + args++; + } } else { add = 1; args++; @@ -243,9 +293,7 @@ bin_zstyle(char *nam, char **args, char *ops, int func) } if (!(s = getstyle(args[1]))) s = addstyle(args[1]); - setstypat(s, args[0], prog, args + 2); - - return 0; + return setstypat(s, args[0], prog, args + 2, eval); } if (list) { Style s; @@ -259,9 +307,9 @@ bin_zstyle(char *nam, char **args, char *ops, int func) } for (p = s->pats; p; p = p->next) { if (list == 1) - printf(" %s", p->pat); + printf("%s %s", (p->eval ? "(eval)" : " "), p->pat); else { - printf("zstyle "); + printf("zstyle %s", (p->eval ? "-e " : "")); quotedzputs(p->pat, stdout); printf(" %s", s->name); } @@ -343,12 +391,11 @@ bin_zstyle(char *nam, char **args, char *ops, int func) break; case 's': { - Stypat s; - char *ret; + char **vals, *ret; int val; - if ((s = lookupstyle(args[1], args[2])) && s->vals[0]) { - ret = sepjoin(s->vals, (args[4] ? args[4] : " "), 0); + if ((vals = lookupstyle(args[1], args[2])) && vals[0]) { + ret = sepjoin(vals, (args[4] ? args[4] : " "), 0); val = 0; } else { ret = ztrdup(""); @@ -361,16 +408,15 @@ bin_zstyle(char *nam, char **args, char *ops, int func) break; case 'b': { - Stypat s; - char *ret; + char **vals, *ret; int val; - if ((s = lookupstyle(args[1], args[2])) && - s->vals[0] && !s->vals[1] && - (!strcmp(s->vals[0], "yes") || - !strcmp(s->vals[0], "true") || - !strcmp(s->vals[0], "on") || - !strcmp(s->vals[0], "1"))) { + if ((vals = lookupstyle(args[1], args[2])) && + vals[0] && !vals[1] && + (!strcmp(vals[0], "yes") || + !strcmp(vals[0], "true") || + !strcmp(vals[0], "on") || + !strcmp(vals[0], "1"))) { ret = "yes"; val = 0; } else { @@ -384,12 +430,11 @@ bin_zstyle(char *nam, char **args, char *ops, int func) break; case 'a': { - Stypat s; - char **ret; + char **vals, **ret; int val; - if ((s = lookupstyle(args[1], args[2]))) { - ret = zarrdup(s->vals); + if ((vals = lookupstyle(args[1], args[2]))) { + ret = zarrdup(vals); val = 0; } else { char *dummy = NULL; @@ -405,14 +450,14 @@ bin_zstyle(char *nam, char **args, char *ops, int func) case 't': case 'T': { - Stypat s; + char **vals; - if ((s = lookupstyle(args[1], args[2])) && s->vals[0]) { + if ((vals = lookupstyle(args[1], args[2])) && vals[0]) { if (args[3]) { char **ap = args + 3, **p; while (*ap) { - p = s->vals; + p = vals; while (*p) if (!strcmp(*ap, *p++)) return 0; @@ -420,27 +465,25 @@ bin_zstyle(char *nam, char **args, char *ops, int func) } return 1; } else - return !(!strcmp(s->vals[0], "true") || - !strcmp(s->vals[0], "yes") || - !strcmp(s->vals[0], "on") || - !strcmp(s->vals[0], "1")); + return !(!strcmp(vals[0], "true") || + !strcmp(vals[0], "yes") || + !strcmp(vals[0], "on") || + !strcmp(vals[0], "1")); } - return (args[0][1] == 't' ? (s ? 1 : 2) : 0); + return (args[0][1] == 't' ? (vals ? 1 : 2) : 0); } break; case 'm': { - Stypat s; + char **vals; Patprog prog; tokenize(args[3]); - if ((s = lookupstyle(args[1], args[2])) && + if ((vals = lookupstyle(args[1], args[2])) && (prog = patcompile(args[3], PAT_STATIC, NULL))) { - char **p = s->vals; - - while (*p) - if (pattry(prog, *p++)) + while (*vals) + if (pattry(prog, *vals++)) return 0; } return 1; |