summaryrefslogtreecommitdiff
path: root/Src/builtin.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/builtin.c')
-rw-r--r--Src/builtin.c74
1 files changed, 30 insertions, 44 deletions
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;
}