diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | Src/builtin.c | 74 |
2 files changed, 35 insertions, 44 deletions
diff --git a/ChangeLog b/ChangeLog index 5609754f5..6b53b1086 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2014-11-13 Barton E. Schaefer <schaefer@zsh.org> + + * 33656: Src/builtin.c: different algorithm for "whence -am" to + produce results more consistent with "whence -m" + 2014-11-13 Oliver Kiddle <opk@zsh.org> * 33669: Src/Zle/zle_utils.c, Test/X02zlevi.ztst: allow an empty diff --git a/Src/builtin.c b/Src/builtin.c index dd22d0984..c2af51f2e 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -3154,6 +3154,15 @@ bin_unset(char *name, char **argv, Options ops, int func) /* type, whence, which, command */ +static LinkList matchednodes; + +static void +fetchcmdnamnode(HashNode hn, UNUSED(int printflags)) +{ + Cmdnam cn = (Cmdnam) hn; + addlinknode(matchednodes, cn->node.nam); +} + /**/ int bin_whence(char *nam, char **argv, Options ops, int func) @@ -3165,7 +3174,7 @@ bin_whence(char *nam, char **argv, Options ops, int func) int aliasflags; int csh, all, v, wd; int informed; - char *cnam; + char *cnam, **allmatched = 0; /* Check some option information */ csh = OPT_ISSET(ops,'c'); @@ -3198,6 +3207,10 @@ bin_whence(char *nam, char **argv, Options ops, int func) /* With -m option -- treat arguments as a glob patterns */ if (OPT_ISSET(ops,'m')) { + if (all) { + pushheap(); + matchednodes = newlinklist(); + } for (; *argv; argv++) { /* parse the pattern */ tokenize(*argv); @@ -3228,51 +3241,21 @@ bin_whence(char *nam, char **argv, Options ops, int func) scanmatchtable(builtintab, pprog, 1, 0, DISABLED, builtintab->printnode, printflags); } - if (all) { - char **pp, *buf, *fn; - DIR *od; - - pushheap(); - for (pp = path; *pp; pp++) { - if (!**pp) - continue; - od = opendir(*pp); - if (!od) - continue; - - while ((fn = zreaddir(od, 0))) { - if (!pattry(pprog, fn)) - continue; - - buf = zhtricat(*pp, "/", fn); - - if (iscom(buf)) { - if (wd) { - printf("%s: command\n", fn); - } else { - if (v && !csh) - zputs(fn, stdout), fputs(" is ", stdout); - zputs(buf, stdout); - if (OPT_ISSET(ops,'s')) - print_if_link(buf); - fputc('\n', stdout); - } - } - } - closedir(od); - } - popheap(); - } else { - /* Done search for `internal' commands, if the -p option * - * was not used. Now search the path. */ - cmdnamtab->filltable(cmdnamtab); - scanmatchtable(cmdnamtab, pprog, 1, 0, 0, - cmdnamtab->printnode, printflags); - } + /* Done search for `internal' commands, if the -p option * + * was not used. Now search the path. */ + cmdnamtab->filltable(cmdnamtab); + scanmatchtable(cmdnamtab, pprog, 1, 0, 0, + (all ? fetchcmdnamnode : cmdnamtab->printnode), + printflags); unqueue_signals(); } - return returnval; + if (all) { + allmatched = argv = zlinklist2array(matchednodes); + matchednodes = NULL; + popheap(); + } else + return returnval; } /* Take arguments literally -- do not glob */ @@ -3280,7 +3263,7 @@ bin_whence(char *nam, char **argv, Options ops, int func) for (; *argv; argv++) { informed = 0; - if (!OPT_ISSET(ops,'p')) { + if (!OPT_ISSET(ops,'p') && !allmatched) { char *suf; /* Look for alias */ @@ -3380,6 +3363,9 @@ bin_whence(char *nam, char **argv, Options ops, int func) returnval = 1; } } + if (allmatched) + freearray(allmatched); + unqueue_signals(); return returnval; } |