From 53344183e1300f3dffeaf602ac4b686ce182e884 Mon Sep 17 00:00:00 2001 From: "Barton E. Schaefer" Date: Thu, 13 Nov 2014 09:20:46 -0800 Subject: 33656: different algorithm for "whence -am" to produce results more consistent with "whence -m" This uses the scanmatchtable routine to collect the names that match the input pattern, then uses the original -a path search loop to generate the output, to avoid duplicating test conditions and output formats. --- Src/builtin.c | 74 ++++++++++++++++++++++++----------------------------------- 1 file changed, 30 insertions(+), 44 deletions(-) (limited to 'Src/builtin.c') 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; } -- cgit 1.4.1