summaryrefslogtreecommitdiff
path: root/Src
diff options
context:
space:
mode:
Diffstat (limited to 'Src')
-rw-r--r--Src/Modules/zftp.c10
-rw-r--r--Src/Zle/compcore.c2
-rw-r--r--Src/Zle/compctl.c4
-rw-r--r--Src/Zle/zle_main.c2
-rw-r--r--Src/Zle/zle_misc.c2
-rw-r--r--Src/exec.c9
-rw-r--r--Src/math.c2
-rw-r--r--Src/signals.c2
-rw-r--r--Src/subst.c19
-rw-r--r--Src/utils.c49
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)