Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

RFC PATCH: fix lookup in $commands array when HASHLISTALL is unset



While the documentation for the zsh/parameter module does state
  The zsh/parameter module gives access to some of the internal hash tables
and
  commands
    This array gives access to the command hash table.
, the latter entry does *also* say
  values are the pathnames of the files that would be executed when
  the command would be invoked.

Change getpmcommand to always do a lookup via findcmd() if it the entry
is not found in the hash and HASHLISTALL is unset. This will indirectly
respect HASHCMDS and add the single entry if it is set, look it up in
the hash if it was added and then HASHCMDS was unset, etc.

---

It is a little messy to construct a new Cmdnam entry here but not *that*
messy.  If we explicitly call hashcmd() here ourselves, and then fall back
to findcmd(), that'll do a redundant lookup which felt even worse to me.
The function could also be changed to fill out the pm struct directly,
but I didn't want to duplicate that.

Even if you object to looking up the path via findcmd, it is very
surprising that the HASHCMDS option is also not respected. I opted to
make it return the full path even if both are unset because that's how
everyone expects it to work, and vcs_info breaks if you unset them, so
we can't claim other people are doing it wrong.

Anyway, I don't really expect anyone to object to this, but I didn't
feel 100% sure, so I marked it as RFC for now, and will hold off a bit
to give everyone a chance to bikeshed if they want.

Here's the failing case if it wasn't obvious from the above:
% setopt nohashlistall
% rehash
% echo $commands[ls] hi
hi

 Src/Modules/parameter.c | 18 ++++++++++++++----
 Src/zsh.h               |  4 ++--
 2 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/Src/Modules/parameter.c b/Src/Modules/parameter.c
index 6d1f74d226..2bcfe81a34 100644
--- a/Src/Modules/parameter.c
+++ b/Src/Modules/parameter.c
@@ -217,10 +217,20 @@ getpmcommand(UNUSED(HashTable ht), const char *name)
     Cmdnam cmd;
     Param pm = NULL;
 
-    if (!(cmd = (Cmdnam) cmdnamtab->getnode(cmdnamtab, name)) &&
-	isset(HASHLISTALL)) {
-	cmdnamtab->filltable(cmdnamtab);
-	cmd = (Cmdnam) cmdnamtab->getnode(cmdnamtab, name);
+    if (!(cmd = (Cmdnam) cmdnamtab->getnode(cmdnamtab, name))) {
+	if (isset(HASHLISTALL)) {
+	    cmdnamtab->filltable(cmdnamtab);
+	    cmd = (Cmdnam) cmdnamtab->getnode(cmdnamtab, name);
+	} else {
+	    /* this will return the path even if hashcmds is disabled,
+	     * and store it in the hash if it is enabled */
+	    char *found = findcmd((char*)name, 1, 0);
+	    if (found) {
+		cmd = (Cmdnam) hcalloc(sizeof(*cmd));
+		cmd->u.cmd = found;
+		cmd->node.flags = HASHED;
+	    }
+	}
     }
     pm = (Param) hcalloc(sizeof(struct param));
     pm->node.nam = dupstring(name);
diff --git a/Src/zsh.h b/Src/zsh.h
index dd58c08162..784f2ac8e4 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -1301,8 +1301,8 @@ enum {
 struct cmdnam {
     struct hashnode node;
     union {
-	char **name;		/* full pathname for external commands */
-	char *cmd;		/* file name for hashed commands       */
+	char **name;		/* pointer into path array for external commands */
+	char *cmd;		/* file name for hashed commands */
     }
     u;
 };
-- 
2.38.1





Messages sorted by: Reverse Date, Date, Thread, Author