diff options
Diffstat (limited to 'Src')
-rw-r--r-- | Src/Modules/zftp.c | 10 | ||||
-rw-r--r-- | Src/Zle/compcore.c | 2 | ||||
-rw-r--r-- | Src/Zle/compctl.c | 4 | ||||
-rw-r--r-- | Src/Zle/zle_main.c | 2 | ||||
-rw-r--r-- | Src/Zle/zle_misc.c | 2 | ||||
-rw-r--r-- | Src/exec.c | 9 | ||||
-rw-r--r-- | Src/math.c | 2 | ||||
-rw-r--r-- | Src/signals.c | 2 | ||||
-rw-r--r-- | Src/subst.c | 19 | ||||
-rw-r--r-- | Src/utils.c | 49 |
10 files changed, 79 insertions, 22 deletions
diff --git a/Src/Modules/zftp.c b/Src/Modules/zftp.c index 0d5e58e56..12a9f0de2 100644 --- a/Src/Modules/zftp.c +++ b/Src/Modules/zftp.c @@ -1480,7 +1480,7 @@ zfsenddata(char *name, int recv, int progress, off_t startat) int osc = sfcontext; sfcontext = SFC_HOOK; - doshfunc(shfunc, NULL, 0, 1); + doshfunc(shfunc, NULL, 1); sfcontext = osc; /* Now add in the bit of the file we've got/sent already */ sofar = last_sofar = startat; @@ -1613,7 +1613,7 @@ zfsenddata(char *name, int recv, int progress, off_t startat) zfsetparam("ZFTP_COUNT", &sofar, ZFPM_READONLY|ZFPM_INTEGER); sfcontext = SFC_HOOK; - doshfunc(shfunc, NULL, 0, 1); + doshfunc(shfunc, NULL, 1); sfcontext = osc; last_sofar = sofar; } @@ -2395,7 +2395,7 @@ zfgetcwd(void) int osc = sfcontext; sfcontext = SFC_HOOK; - doshfunc(shfunc, NULL, 0, 1); + doshfunc(shfunc, NULL, 1); sfcontext = osc; } return 0; @@ -2615,7 +2615,7 @@ zftp_getput(char *name, char **args, int flags) zfsetparam("ZFTP_TRANSFER", ztrdup(recv ? "GF" : "PF"), ZFPM_READONLY); sfcontext = SFC_HOOK; - doshfunc(shfunc, NULL, 0, 1); + doshfunc(shfunc, NULL, 1); sfcontext = osc; } if (rest) { @@ -2770,7 +2770,7 @@ zfclose(int leaveparams) int osc = sfcontext; sfcontext = SFC_HOOK; - doshfunc(shfunc, NULL, 0, 1); + doshfunc(shfunc, NULL, 1); sfcontext = osc; } } diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c index 9f97779ff..529537d37 100644 --- a/Src/Zle/compcore.c +++ b/Src/Zle/compcore.c @@ -814,7 +814,7 @@ callcompfunc(char *s, char *fn) while (*p) addlinknode(largs, dupstring(*p++)); } - doshfunc(shfunc, largs, 0, 0); + doshfunc(shfunc, largs, 0); cfret = lastval; lastval = olv; } OLDHEAPS; diff --git a/Src/Zle/compctl.c b/Src/Zle/compctl.c index 9d03635ff..58c81c2c8 100644 --- a/Src/Zle/compctl.c +++ b/Src/Zle/compctl.c @@ -3664,7 +3664,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) incompctlfunc = 1; sfcontext = SFC_COMPLETE; /* Call the function. */ - doshfunc(shfunc, args, 0, 1); + doshfunc(shfunc, args, 1); sfcontext = osc; incompctlfunc = 0; /* And get the result from the reply parameter. */ @@ -3839,7 +3839,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) if (incompfunc != 1) incompctlfunc = 1; sfcontext = SFC_COMPLETE; - doshfunc(shfunc, args, 0, 1); + doshfunc(shfunc, args, 1); sfcontext = osc; incompctlfunc = 0; uv = "reply"; diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c index 9e2edb956..093160808 100644 --- a/Src/Zle/zle_main.c +++ b/Src/Zle/zle_main.c @@ -1330,7 +1330,7 @@ execzlefunc(Thingy func, char **args, int set_bindk) makezleparams(0); sfcontext = SFC_WIDGET; opts[XTRACE] = 0; - ret = doshfunc(shf, largs, shf->node.flags, 1); + ret = doshfunc(shf, largs, 1); opts[XTRACE] = oxt; sfcontext = osc; endparamscope(); diff --git a/Src/Zle/zle_misc.c b/Src/Zle/zle_misc.c index c34db2970..738e7b8c4 100644 --- a/Src/Zle/zle_misc.c +++ b/Src/Zle/zle_misc.c @@ -1384,7 +1384,7 @@ iremovesuffix(ZLE_INT_T c, int keep) startparamscope(); makezleparams(0); sfcontext = SFC_COMPLETE; - doshfunc(shfunc, args, 0, 1); + doshfunc(shfunc, args, 1); sfcontext = osc; endparamscope(); diff --git a/Src/exec.c b/Src/exec.c index ad6f9955d..36e381eaa 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -518,7 +518,7 @@ commandnotfound(char *arg0, LinkList args) return 127; pushnode(args, arg0); - return doshfunc(shf, args, shf->node.flags, 1); + return doshfunc(shf, args, 1); } /* execute an external command */ @@ -4064,7 +4064,7 @@ execshfunc(Shfunc shf, LinkList args) cmdsp = 0; if ((osfc = sfcontext) == SFC_NONE) sfcontext = SFC_DIRECT; - doshfunc(shf, args, shf->node.flags, 0); + doshfunc(shf, args, 0); sfcontext = osfc; free(cmdstack); cmdstack = ocs; @@ -4191,8 +4191,6 @@ loadautofn(Shfunc shf, int fksh, int autol) * in which the first element is the function name (even if * FUNCTIONARGZERO is set as this is handled inside this function). * - * flags are a set of the PM_ flags associated with the function. - * * If noreturnval is nonzero, then reset the current return * value (lastval) to its value before the shell function * was executed. However, in any case return the status value @@ -4202,13 +4200,14 @@ loadautofn(Shfunc shf, int fksh, int autol) /**/ mod_export int -doshfunc(Shfunc shfunc, LinkList doshargs, int flags, int noreturnval) +doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval) { char **tab, **x, *oargv0; int oldzoptind, oldlastval, oldoptcind, oldnumpipestats, ret; int *oldpipestats = NULL; char saveopts[OPT_SIZE], *oldscriptname = scriptname; char *name = shfunc->node.nam; + int flags = shfunc->node.flags; char *fname = dupstring(name); int obreaks, saveemulation ; Eprog prog; diff --git a/Src/math.c b/Src/math.c index 78f7572a5..241445979 100644 --- a/Src/math.c +++ b/Src/math.c @@ -872,7 +872,7 @@ callmathfunc(char *o) if (!shfunc) zerr("no such function: %s", shfnam); else { - doshfunc(shfunc, l, 0, 1); + doshfunc(shfunc, l, 1); return lastmathval; } } else { diff --git a/Src/signals.c b/Src/signals.c index ba5777524..2cedeb2b9 100644 --- a/Src/signals.c +++ b/Src/signals.c @@ -1160,7 +1160,7 @@ dotrapargs(int sig, int *sigtr, void *sigfn) trapisfunc = isfunc = 1; sfcontext = SFC_SIGNAL; - doshfunc((Shfunc)sigfn, args, 0, 1); + doshfunc((Shfunc)sigfn, args, 1); sfcontext = osc; freelinklist(args, (FreeFunc) NULL); zsfree(name); diff --git a/Src/subst.c b/Src/subst.c index 6c3487e9a..caa2ecfda 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -528,7 +528,8 @@ filesubstr(char **namptr, int assign) char *str = *namptr; if (*str == Tilde && str[1] != '=' && str[1] != Equals) { - char *ptr; + Shfunc dirfunc; + char *ptr, *tmp, *res; int val; val = zstrtol(str + 1, &ptr, 10); @@ -539,9 +540,23 @@ filesubstr(char **namptr, int assign) *namptr = dyncat(pwd, str + 2); return 1; } else if (str[1] == '-' && isend(str[2])) { /* ~- */ - char *tmp; *namptr = dyncat((tmp = oldpwd) ? tmp : pwd, str + 2); return 1; + } else if (str[1] == Inbrack && + (dirfunc = getshfunc("zsh_directory_name")) && + (ptr = strchr(str+2, Outbrack))) { + char **arr; + untokenize(tmp = dupstrpfx(str+2, ptr - (str+2))); + remnulargs(tmp); + arr = subst_string_by_func(dirfunc, "n", tmp); + res = arr ? *arr : NULL; + if (res) { + *namptr = dyncat(res, ptr+1); + return 1; + } + if (isset(NOMATCH)) + zerr("no directory expansion: ~[%s]", tmp); + return 0; } else if (!inblank(str[1]) && isend(*ptr) && (!idigit(str[1]) || (ptr - str < 4))) { char *ds; diff --git a/Src/utils.c b/Src/utils.c index 748c62920..24a643ef2 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -826,6 +826,7 @@ finddir(char *s) { static struct nameddir homenode = { {NULL, "", 0}, NULL, 0 }; static int ffsz; + Shfunc func = getshfunc("zsh_directory_name"); /* Invalidate directory cache if argument is NULL. This is called * * whenever a node is added to or removed from the hash table, and * @@ -841,7 +842,8 @@ finddir(char *s) return finddir_last = NULL; } - if(!strcmp(s, finddir_full) && *finddir_full) + /* It's not safe to use the cache while we have function transformations.*/ + if(!func && !strcmp(s, finddir_full) && *finddir_full) return finddir_last; if ((int)strlen(s) >= ffsz) { @@ -853,6 +855,21 @@ finddir(char *s) finddir_last=NULL; finddir_scan(&homenode.node, 0); scanhashtable(nameddirtab, 0, 0, 0, finddir_scan, 0); + + if (func) { + char **ares = subst_string_by_func(func, "d", finddir_full); + int len; + if (ares && arrlen(ares) >= 2 && + (len = (int)zstrtol(ares[1], NULL, 10)) > finddir_best) { + /* better duplicate this string since it's come from REPLY */ + finddir_last = (Nameddir)hcalloc(sizeof(struct nameddir)); + finddir_last->node.nam = tricat("[", dupstring(ares[0]), "]"); + finddir_last->dir = dupstrpfx(finddir_full, len); + finddir_last->diff = len - strlen(finddir_last->node.nam); + finddir_best = len; + } + } + return finddir_last; } @@ -1146,7 +1163,7 @@ callhookfunc(char *name, LinkList lnklst, int arrayp, int *retval) sfcontext = SFC_HOOK; if ((shfunc = getshfunc(name))) { - ret = doshfunc(shfunc, lnklst, 0, 1); + ret = doshfunc(shfunc, lnklst, 1); stat = 0; } @@ -1162,7 +1179,7 @@ callhookfunc(char *name, LinkList lnklst, int arrayp, int *retval) if ((arrptr = getaparam(arrnam))) { for (; *arrptr; arrptr++) { if ((shfunc = getshfunc(*arrptr))) { - int newret = doshfunc(shfunc, lnklst, 0, 1); + int newret = doshfunc(shfunc, lnklst, 1); if (!ret) ret = newret; stat = 0; @@ -2901,6 +2918,32 @@ getshfunc(char *nam) return (Shfunc) shfunctab->getnode(shfunctab, nam); } +/* + * Call the function func to substitute string orig by setting + * the parameter reply. + * Return the array from reply, or NULL if the function returned + * non-zero status. + * The returned value comes directly from the parameter and + * so should be used before there is any chance of that + * being changed or unset. + * If arg1 is not NULL, it is used as an initial argument to + * the function, with the original string as the second argument. + */ + +/**/ +char ** +subst_string_by_func(Shfunc func, char *arg1, char *orig) +{ + LinkList l = newlinklist(); + addlinknode(l, func->node.nam); + if (arg1) + addlinknode(l, arg1); + addlinknode(l, orig); + if (doshfunc(func, l, 1)) + return NULL; + return getaparam("reply"); +} + /**/ mod_export char ** mkarray(char *s) |