zsh-users
 help / color / mirror / code / Atom feed
* symlink chain.
@ 2014-12-27  4:50 Ray Andrews
  2014-12-27 23:38 ` Ray Andrews
  2015-01-02 17:03 ` Peter Stephenson
  0 siblings, 2 replies; 30+ messages in thread
From: Ray Andrews @ 2014-12-27  4:50 UTC (permalink / raw)
  To: Zsh Users

I just noticed that 'whence -s' very quietly 'finishes' a chain of 
links, and shows you the final target.  'ls' OTOH only ever shows you 
the first link in a chain. It gets me wanting some way of showing an 
entire chain of links where that applies.  Can it be done? It occurred 
to me that perhaps 'whence' should not use the standard " -> " symbol 
when showing a link, because it's not a normal display, but a jump to 
the end of the chain.  Dunno, is there a better symbol for that?  " ->> 
" or something?

BTW Peter, Oliver, finished the book, thanks again, it was very helpful, 
the only thing that defeated me was the chapter on completion.


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: symlink chain.
  2014-12-27  4:50 symlink chain Ray Andrews
@ 2014-12-27 23:38 ` Ray Andrews
  2015-01-02 17:03 ` Peter Stephenson
  1 sibling, 0 replies; 30+ messages in thread
From: Ray Andrews @ 2014-12-27 23:38 UTC (permalink / raw)
  To: zsh-users

On 12/26/2014 08:50 PM, Ray Andrews wrote:
> I just noticed that 'whence -s' very quietly 'finishes' a chain of 
> links, and shows you the final target.  'ls' OTOH only ever shows you 
> the first link in a chain. It gets me wanting some way of showing an 
> entire chain of links where that applies.  Can it be done? It occurred 
> to me that perhaps 'whence' should not use the standard " -> " symbol 
> when showing a link, because it's not a normal display, but a jump to 
> the end of the chain.  Dunno, is there a better symbol for that?  " 
> ->> " or something?
>
Well, pending a zsh internal solution, 'namei' does the trick very nicely.
Always new treasures to find.


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: symlink chain.
  2014-12-27  4:50 symlink chain Ray Andrews
  2014-12-27 23:38 ` Ray Andrews
@ 2015-01-02 17:03 ` Peter Stephenson
  2015-01-02 18:42   ` Ray Andrews
  1 sibling, 1 reply; 30+ messages in thread
From: Peter Stephenson @ 2015-01-02 17:03 UTC (permalink / raw)
  To: Zsh Users

On Fri, 26 Dec 2014 20:50:03 -0800
Ray Andrews <rayandrews@eastlink.ca> wrote:
> I just noticed that 'whence -s' very quietly 'finishes' a chain of 
> links, and shows you the final target.  'ls' OTOH only ever shows you 
> the first link in a chain. It gets me wanting some way of showing an 
> entire chain of links where that applies.  Can it be done?

showlinkchain () {
  zmodload -F zsh/stat b:zstat
  local args
  while [[ -h $1 ]]
  do
    zstat -A args +link $1
    if [[ -n $args[1] ]]
    then
      print -r - $args[1]
      set -- $args[1]
    else
      break
    fi
  done
}


pws


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: symlink chain.
  2015-01-02 17:03 ` Peter Stephenson
@ 2015-01-02 18:42   ` Ray Andrews
  2015-01-02 20:27     ` Lawrence Velázquez
  2015-01-02 21:24     ` Peter Stephenson
  0 siblings, 2 replies; 30+ messages in thread
From: Ray Andrews @ 2015-01-02 18:42 UTC (permalink / raw)
  To: zsh-users

On 01/02/2015 09:03 AM, Peter Stephenson wrote:

Thanks Peter, terse, but effective:

    $ showlinkchain /usr/bin/zsh

    /etc/alternatives/zsh-usrbin
    /usr/local/bin/zsh
    zsh-5.0.7-165-g2194da1


I'm using a cut down 'namei' to give this:

    l zsh -> /etc/alternatives/zsh-usrbin
    l   zsh-usrbin -> /usr/local/bin/zsh
    l     zsh -> zsh-5.0.7-165-g2194da1


... which is prettier.

Do you think 'whence' would benefit from showing the chain if '-s' is 
specified? Maybe it's just me, but I want no surprises when I use 
whence, I want complete information about what any typed command it 
actually going to end up executing and a roadmap of any and all links as 
to how it got there.  Again, maybe it's only me, but when I first 
started using the development builds, I was never sure what the hell was 
actually going on because I have three 'zsh' on my path, each of which 
is a chain of links going hither and yon pointing to various and sundry 
binaries all over the place.  Only once I untangled these Gordian Knots 
could I end up with this:

    $ whence -masv "zsh"
    zsh-5.0.7-165-g2194da1

    zsh is /usr/local/bin/zsh -> /usr/local/bin/zsh-5.0.7-165-g2194da1
    zsh is /usr/bin/zsh -> /usr/local/bin/zsh-5.0.7-165-g2194da1
    zsh is /bin/zsh -> /usr/local/bin/zsh-5.0.7-165-g2194da1

... so I actually know what the heck is happening. (And when Debian 
breaks it, I can fix it fast.)

BTW, how is it that both your method and 'namei' show paths except for 
the final binary target, whereas the 'whence' output just above shows 
all paths including for the final binary?  Consistency is not a zsh virtue.




^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: symlink chain.
  2015-01-02 18:42   ` Ray Andrews
@ 2015-01-02 20:27     ` Lawrence Velázquez
  2015-01-02 21:19       ` Ray Andrews
  2015-01-02 21:24     ` Peter Stephenson
  1 sibling, 1 reply; 30+ messages in thread
From: Lawrence Velázquez @ 2015-01-02 20:27 UTC (permalink / raw)
  To: Ray Andrews; +Cc: zsh-users

On Jan 2, 2015, at 1:42 PM, Ray Andrews <rayandrews@eastlink.ca> wrote:

> Do you think 'whence' would benefit from showing the chain if '-s' is specified? Maybe it's just me, but I want no surprises when I use whence, I want complete information about what any typed command it actually going to end up executing and a roadmap of any and all links as to how it got there.

I would consider this undesirable noise, and I think most users would agree. The point of `whence` is to "indicate how [the argument] would be interpreted if used as a command name". I don't care about the chain of links, I just want to know what ends up being run.

> Again, maybe it's only me, but when I first started using the development builds, I was never sure what the hell was actually going on because I have three 'zsh' on my path, each of which is a chain of links going hither and yon pointing to various and sundry binaries all over the place.  Only once I untangled these Gordian Knots could I end up with this:
> 
>   $ whence -masv "zsh"
>   zsh-5.0.7-165-g2194da1
> 
>   zsh is /usr/local/bin/zsh -> /usr/local/bin/zsh-5.0.7-165-g2194da1
>   zsh is /usr/bin/zsh -> /usr/local/bin/zsh-5.0.7-165-g2194da1
>   zsh is /bin/zsh -> /usr/local/bin/zsh-5.0.7-165-g2194da1
> 
> ... so I actually know what the heck is happening. (And when Debian breaks it, I can fix it fast.)

That's fine, but it's easy enough for you to write a script or function that accomplishes what you need. It's not worth increasing complexity for everyone else.

> BTW, how is it that both your method and 'namei' show paths except for the final binary target, whereas the 'whence' output just above shows all paths including for the final binary?  Consistency is not a zsh virtue.

It looks like `showlinkchain` and `namei` just display link targets, which are often relative paths. `whence` resolves the targets to an absolute path, as befits its purpose.

vq

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: symlink chain.
  2015-01-02 20:27     ` Lawrence Velázquez
@ 2015-01-02 21:19       ` Ray Andrews
  0 siblings, 0 replies; 30+ messages in thread
From: Ray Andrews @ 2015-01-02 21:19 UTC (permalink / raw)
  To: Lawrence Velázquez; +Cc: zsh-users

On 01/02/2015 12:27 PM, Lawrence Velázquez wrote:
> On Jan 2, 2015, at 1:42 PM, Ray Andrews <rayandrews@eastlink.ca> wrote:
>
>> Do you think 'whence' would benefit from showing the chain if '-s' is specified? Maybe it's just me, but I want no surprises when I use whence, I want complete information about what any typed command it actually going to end up executing and a roadmap of any and all links as to how it got there.
> I would consider this undesirable noise, and I think most users would agree. The point of `whence` is to "indicate how [the argument] would be interpreted if used as a command name". I don't care about the chain of links, I just want to know what ends up being run.
Yup, at the end of the day it's what people find useful.  I myself have 
had so much grief for not realizing that the way whence 'jumps' like 
that is infact a jump, that I'm biased against it.  I dunno, maybe '-S' 
could mean 'show the entire chain', but it looks like I'm the only guy 
who's worried about it and the devs have better things to think about. 
But I would change the symbol where this jumping happens "->>" or 
something like that, just so you know.


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: symlink chain.
  2015-01-02 18:42   ` Ray Andrews
  2015-01-02 20:27     ` Lawrence Velázquez
@ 2015-01-02 21:24     ` Peter Stephenson
  2015-01-02 21:36       ` Ray Andrews
  2015-01-02 21:53       ` Ray Andrews
  1 sibling, 2 replies; 30+ messages in thread
From: Peter Stephenson @ 2015-01-02 21:24 UTC (permalink / raw)
  To: zsh-users

On Fri, 02 Jan 2015 10:42:57 -0800
Ray Andrews <rayandrews@eastlink.ca> wrote:
> I'm using a cut down 'namei' to give this:
> 
>     l zsh -> /etc/alternatives/zsh-usrbin
>     l   zsh-usrbin -> /usr/local/bin/zsh
>     l     zsh -> zsh-5.0.7-165-g2194da1
> 
> 
> ... which is prettier.
> 
> Do you think 'whence' would benefit from showing the chain if '-s' is 
> specified?

Yes, I think that would be useful --- I've got confused before now about
something in /etc/alternatives appearing as an intermediate link and
started to whimper.

I've used a separate option, -S, to give you the extra detail, to avoid
confusing anyone who doesn't care or is parsing the old syntax.

java is /usr/bin/java -> /etc/alternatives/java -> /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.25-5.b18.fc21.x86_64/jre/bin/java
java is /bin/java -> /usr/bin/java -> /etc/alternatives/java -> /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.25-5.b18.fc21.x86_64/jre/bin/java

To check relative paths got expanded, I added symlinks bar1 -> foo1 and
foo1 -> /bin/java in my bin directory...

bar1 is /home/pws/bin/bar1 -> /home/pws/bin/foo1 -> /bin/java -> /usr/bin/java -> /etc/alternatives/java -> /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.25-5.b18.fc21.x86_64/jre/bin/java

pws

diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo
index 38788d3..b4f4b67 100644
--- a/Doc/Zsh/builtins.yo
+++ b/Doc/Zsh/builtins.yo
@@ -1667,7 +1667,7 @@ See also the shell variable tt(STTY) for a means of initialising
 the tty before running external commands.
 )
 findex(type)
-item(tt(type) [ tt(-wfpams) ] var(name) ...)(
+item(tt(type) [ tt(-wfpamsS) ] var(name) ...)(
 Equivalent to tt(whence -v).
 )
 findex(typeset)
@@ -2083,7 +2083,7 @@ the user is potentially interested in both, so this problem is intrinsic
 to process IDs.
 )
 findex(whence)
-item(tt(whence) [ tt(-vcwfpams) ] var(name) ...)(
+item(tt(whence) [ tt(-vcwfpamsS) ] var(name) ...)(
 For each name, indicate how it would be interpreted if used as a
 command name.
 
@@ -2126,6 +2126,11 @@ of these patterns.
 item(tt(-s))(
 If a pathname contains symlinks, print the symlink-free pathname as well.
 )
+item(tt(-S))(
+As tt(-s), but if the pathname had to be resolved by following
+multiple symlinks, the intermediate steps are printed, too.  The
+symlink resolved at each step might be anywhere in the path.
+)
 enditem()
 )
 findex(where)
diff --git a/Src/builtin.c b/Src/builtin.c
index 264169c..47d1aa0 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -119,7 +119,7 @@ static struct builtin builtins[] =
     BUILTIN("times", BINF_PSPECIAL, bin_times, 0, 0, 0, NULL, NULL),
     BUILTIN("trap", BINF_PSPECIAL | BINF_HANDLES_OPTS, bin_trap, 0, -1, 0, NULL, NULL),
     BUILTIN("true", 0, bin_true, 0, -1, 0, NULL, NULL),
-    BUILTIN("type", 0, bin_whence, 0, -1, 0, "ampfsw", "v"),
+    BUILTIN("type", 0, bin_whence, 0, -1, 0, "ampfsSw", "v"),
     BUILTIN("typeset", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%afghi:%klprtuxmz", NULL),
     BUILTIN("umask", 0, bin_umask, 0, 1, 0, "S", NULL),
     BUILTIN("unalias", 0, bin_unhash, 1, -1, 0, "ms", "a"),
@@ -128,7 +128,7 @@ static struct builtin builtins[] =
     BUILTIN("unset", BINF_PSPECIAL, bin_unset, 1, -1, 0, "fmv", NULL),
     BUILTIN("unsetopt", 0, bin_setopt, 0, -1, BIN_UNSETOPT, NULL, NULL),
     BUILTIN("wait", 0, bin_fg, 0, -1, BIN_WAIT, NULL, NULL),
-    BUILTIN("whence", 0, bin_whence, 0, -1, 0, "acmpvfsw", NULL),
+    BUILTIN("whence", 0, bin_whence, 0, -1, 0, "acmpvfsSw", NULL),
     BUILTIN("where", 0, bin_whence, 0, -1, 0, "pmsw", "ca"),
     BUILTIN("which", 0, bin_whence, 0, -1, 0, "ampsw", "c"),
     BUILTIN("zmodload", 0, bin_zmodload, 0, -1, 0, "AFRILP:abcfdilmpue", NULL),
@@ -3331,8 +3331,8 @@ bin_whence(char *nam, char **argv, Options ops, int func)
 			if (v && !csh)
 			    zputs(*argv, stdout), fputs(" is ", stdout);
 			zputs(buf, stdout);
-			if (OPT_ISSET(ops,'s'))
-			    print_if_link(buf);
+			if (OPT_ISSET(ops,'s') || OPT_ISSET(ops, 'S'))
+			    print_if_link(buf, OPT_ISSET(ops, 'S'));
 			fputc('\n', stdout);
 		    }
 		    informed = 1;
@@ -3352,8 +3352,8 @@ bin_whence(char *nam, char **argv, Options ops, int func)
 		if (v && !csh)
 		    zputs(*argv, stdout), fputs(" is ", stdout);
 		zputs(cnam, stdout);
-		if (OPT_ISSET(ops,'s'))
-		    print_if_link(cnam);
+		if (OPT_ISSET(ops,'s') || OPT_ISSET(ops,'S'))
+		    print_if_link(cnam, OPT_ISSET(ops,'S'));
 		fputc('\n', stdout);
 	    }
 	} else {
diff --git a/Src/utils.c b/Src/utils.c
index 893a8ca..2b2a815 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -719,7 +719,7 @@ slashsplit(char *s)
 
 /**/
 static int
-xsymlinks(char *s)
+xsymlinks(char *s, int full)
 {
     char **pp, **opp;
     char xbuf2[PATH_MAX*3], xbuf3[PATH_MAX*2];
@@ -758,14 +758,49 @@ xsymlinks(char *s)
 	} else {
 	    ret = 1;
 	    metafy(xbuf3, t0, META_NOALLOC);
+	    if (!full) {
+		/*
+		 * If only one expansion requested, ensure the
+		 * full path is in xbuf.
+		 */
+		zulong len = xbuflen;
+		if (*xbuf3 == '/')
+		    strcpy(xbuf, xbuf3);
+		else if ((len += strlen(xbuf3) + 1) < sizeof(xbuf)) {
+		    strcpy(xbuf + xbuflen, "/");
+		    strcpy(xbuf + xbuflen + 1, xbuf3);
+		} else {
+		    *xbuf = 0;
+		    ret = -1;
+		    break;
+		}
+
+		while (*++pp) {
+		    zulong newlen = len + strlen(*pp) + 1;
+		    if (newlen < sizeof(xbuf)) {
+			strcpy(xbuf + len, "/");
+			strcpy(xbuf + len + 1, *pp);
+			len = newlen;
+		    } else {
+			*xbuf = 01;
+			ret = -1;
+			break;
+		    }
+		}
+		/*
+		 * No need to update xbuflen, we're finished
+		 * the expansion (for now).
+		 */
+		break;
+	    }
 	    if (*xbuf3 == '/') {
 		strcpy(xbuf, "");
-		if (xsymlinks(xbuf3 + 1) < 0)
+		if (xsymlinks(xbuf3 + 1, 0) < 0)
 		    ret = -1;
 		else
 		    xbuflen = strlen(xbuf);
 	    } else
-		if (xsymlinks(xbuf3) < 0)
+		if (xsymlinks(xbuf3, 0) < 0)
 		    ret = -1;
 		else
 		    xbuflen = strlen(xbuf);
@@ -787,7 +822,7 @@ xsymlink(char *s)
     if (*s != '/')
 	return NULL;
     *xbuf = '\0';
-    if (xsymlinks(s + 1) < 0)
+    if (xsymlinks(s + 1, 1) < 0)
 	zwarn("path expansion failed, using root directory");
     if (!*xbuf)
 	return ztrdup("/");
@@ -796,12 +831,30 @@ xsymlink(char *s)
 
 /**/
 void
-print_if_link(char *s)
+print_if_link(char *s, int all)
 {
     if (*s == '/') {
 	*xbuf = '\0';
-	if (xsymlinks(s + 1) > 0)
-	    printf(" -> "), zputs(*xbuf ? xbuf : "/", stdout);
+	if (all) {
+	    char *start = s + 1;
+	    char xbuflink[PATH_MAX];
+	    for (;;) {
+		if (xsymlinks(start, 0) > 0) {
+		    printf(" -> ");
+		    zputs(*xbuf ? xbuf : "/", stdout);
+		    if (!*xbuf)
+			break;
+		    strcpy(xbuflink, xbuf);
+		    start = xbuflink + 1;
+		    *xbuf = '\0';
+		} else {
+		    break;
+		}
+	    }
+	} else {
+	    if (xsymlinks(s + 1, 1) > 0)
+		printf(" -> "), zputs(*xbuf ? xbuf : "/", stdout);
+	}
     }
 }
 


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: symlink chain.
  2015-01-02 21:24     ` Peter Stephenson
@ 2015-01-02 21:36       ` Ray Andrews
  2015-01-02 21:53       ` Ray Andrews
  1 sibling, 0 replies; 30+ messages in thread
From: Ray Andrews @ 2015-01-02 21:36 UTC (permalink / raw)
  To: zsh-users

On 01/02/2015 01:24 PM, Peter Stephenson wrote:


Would someone be so kind as to give me a command line for applying that 
patch?  I haven't done that yet:
>
>
> diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo
> index 38788d3..b4f4b67 100644
...
>


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: symlink chain.
  2015-01-02 21:24     ` Peter Stephenson
  2015-01-02 21:36       ` Ray Andrews
@ 2015-01-02 21:53       ` Ray Andrews
  2015-01-02 22:21         ` Peter Stephenson
  2015-01-02 22:22         ` Bart Schaefer
  1 sibling, 2 replies; 30+ messages in thread
From: Ray Andrews @ 2015-01-02 21:53 UTC (permalink / raw)
  To: zsh-users

Another little gotcha:

    $ whence -s /usr/bin/zsh
    /usr/bin/zsh -> /usr/local/bin/zsh-5.0.7-165-g2194da1

    $ whence -sa /usr/bin/zsh
    (nothing)


... why would the '-a' switch kill the '-s' switch?

But only sometimes:

    $ whence -as zsh

    /usr/local/bin/zsh -> /usr/local/bin/zsh-5.0.7-165-g2194da1
    /usr/bin/zsh -> /usr/local/bin/zsh-5.0.7-165-g2194da1
    /bin/zsh -> /usr/local/bin/zsh-5.0.7-165-g2194da1

... with the broader search pattern, '-as' is happy to show the symlink.


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: symlink chain.
  2015-01-02 21:53       ` Ray Andrews
@ 2015-01-02 22:21         ` Peter Stephenson
  2015-01-02 23:42           ` Ray Andrews
  2015-01-02 22:22         ` Bart Schaefer
  1 sibling, 1 reply; 30+ messages in thread
From: Peter Stephenson @ 2015-01-02 22:21 UTC (permalink / raw)
  To: zsh-users

On Fri, 02 Jan 2015 13:53:48 -0800
Ray Andrews <rayandrews@eastlink.ca> wrote:
> Another little gotcha:
> 
>     $ whence -s /usr/bin/zsh
>     /usr/bin/zsh -> /usr/local/bin/zsh-5.0.7-165-g2194da1
> 
>     $ whence -sa /usr/bin/zsh
>     (nothing)
>
> 
> ... why would the '-a' switch kill the '-s' switch?

It's nothing to do with "-s", it's the "-a".  It searches the path for
all occurrences.  It still searches even if there's already a full
path.  This isn't a hell of a lot of use.

diff --git a/Src/builtin.c b/Src/builtin.c
index 47d1aa0..ebc0654 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -3315,7 +3315,7 @@ bin_whence(char *nam, char **argv, Options ops, int func)
 
 	/* Option -a is to search the entire path, *
 	 * rather than just looking for one match. */
-	if (all) {
+	if (all && **argv != '/') {
 	    char **pp, *buf;
 
 	    pushheap();

pws


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: symlink chain.
  2015-01-02 21:53       ` Ray Andrews
  2015-01-02 22:21         ` Peter Stephenson
@ 2015-01-02 22:22         ` Bart Schaefer
  1 sibling, 0 replies; 30+ messages in thread
From: Bart Schaefer @ 2015-01-02 22:22 UTC (permalink / raw)
  To: zsh-users

On Jan 2,  1:53pm, Ray Andrews wrote:
}
} Another little gotcha:
} 
}     $ whence -s /usr/bin/zsh
}     /usr/bin/zsh -> /usr/local/bin/zsh-5.0.7-165-g2194da1
} 
}     $ whence -sa /usr/bin/zsh
}     (nothing)
} 
} ... why would the '-a' switch kill the '-s' switch?

The literal answer is because -a does a search of the command hash table
keys, and command full paths are values, not keys.

The more descriptive answer is because -a is supposed to mean a path
search for the argument, and the string "/usr/bin/zsh" is not the name
(as in, last path element) of a file found in a directory in $path.


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: symlink chain.
  2015-01-02 22:21         ` Peter Stephenson
@ 2015-01-02 23:42           ` Ray Andrews
  2015-01-03  1:08             ` Ray Andrews
  0 siblings, 1 reply; 30+ messages in thread
From: Ray Andrews @ 2015-01-02 23:42 UTC (permalink / raw)
  To: zsh-users

On 01/02/2015 02:21 PM, Peter Stephenson wrote:
>
> ... why would the '-a' switch kill the '-s' switch?
> It's nothing to do with "-s", it's the "-a". 

I put that patch in by hand and it sorts out the  -sa issue, alas:

      $ whence -asm "/usr/bin/zsh"
      (nothing)

I'm expecting -m to widen the search where wildcards are present, and to 
leave the search unchanged otherwise, but not to kill -s and/or -a. Is 
it not a general rule that switches are 'cumulative' in nature? IOW each 
switch adds something, (unless its an exclusivity thing like -v -c -w), 
such that we shouldn't have to worry about one switch screwing around 
with what the other switches do?

-a: find all matches on the path
-s: expand symlinks (if any)
-S: expand the full 'chain' of symlinks (if any).
-m: accept wildcards in the search string (if given).

... none of those things contradict each other (tho -S subsumes -s).



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: symlink chain.
  2015-01-02 23:42           ` Ray Andrews
@ 2015-01-03  1:08             ` Ray Andrews
  2015-01-03  5:03               ` Bart Schaefer
  0 siblings, 1 reply; 30+ messages in thread
From: Ray Andrews @ 2015-01-03  1:08 UTC (permalink / raw)
  To: zsh-users

On 01/02/2015 03:42 PM, Ray Andrews wrote:

>
> I put that patch in by hand and it sorts out the  -sa issue, alas:
>
>      $ whence -asm "/usr/bin/zsh"
>      (nothing)
>
Needless to say, I have no idea if this is sound, however:

     /* With -m option -- treat arguments as a glob patterns */
//    if (OPT_ISSET(ops,'m')) {
     if (OPT_ISSET(ops,'m') && **argv != '/' ) {

... seems to work.  I'm just aping what Peter did, of course.  Even when 
one has narrowed down a 'search' to a single file, the command should 
not break.  In that case the command is not so much 'finding' as it is 
informing.

     $ find /etc/fstab
     /etc/fstab

... sure, it's a bit pointless to 'find' an exactly specified file, but 
the command still works, and it confirms that the thing exists. With 
Peter's -S switch one might 'whence' a specific file just to see the 
pointer chain expand.  And the other switches should not break it, even 
if they aren't really doing anything.


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: symlink chain.
  2015-01-03  1:08             ` Ray Andrews
@ 2015-01-03  5:03               ` Bart Schaefer
  2015-01-03  5:53                 ` Ray Andrews
  0 siblings, 1 reply; 30+ messages in thread
From: Bart Schaefer @ 2015-01-03  5:03 UTC (permalink / raw)
  To: zsh-users

On Jan 2,  5:08pm, Ray Andrews wrote:
} Subject: Re: symlink chain.
}
} Needless to say, I have no idea if this is sound, however:
} 
}      /* With -m option -- treat arguments as a glob patterns */
} //    if (OPT_ISSET(ops,'m')) {
}      if (OPT_ISSET(ops,'m') && **argv != '/' ) {
} 
} ... seems to work.

I wouldn't use the word "work" exactly.  All that does is turn off the
pattern matching entirely.  You're probably next going to complain that

% whence -m /\*/bin/zsh

should return /usr/bin/zsh and /usr/local/bin/zsh, or somthing of the
kind.  This is just abusing the purpose of "whence", which is intended
to tell you what a path search would find for a simple command name.

If we *really* want this behavior -- which I submit that we don't, as
we're wandering into silly territory like whence -m '*bin*' returning
all commands in all directories named "bin", so we should stop futzing
around with "whence" -- then the correct thing is rewriting the hash
table scan to look at both the keys and the values when doing the
pattern matching.

Which has ramifications beyond "whence" because it uses the same hash
table scan routines as everything else.  I confess I'm actually a bit
surprised that PWS was willing to hack up something as deeply involved
in the internals as xsymlinks() [in which we just finished fixing other
obscure bugs] in order to implement whence -S.

Shell functions exist so that if something like whence doesn't do what
you want, you can write something else that does.


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: symlink chain.
  2015-01-03  5:03               ` Bart Schaefer
@ 2015-01-03  5:53                 ` Ray Andrews
  2015-01-03  7:17                   ` Bart Schaefer
  0 siblings, 1 reply; 30+ messages in thread
From: Ray Andrews @ 2015-01-03  5:53 UTC (permalink / raw)
  To: zsh-users

On 01/02/2015 09:03 PM, Bart Schaefer wrote:
> On Jan 2,  5:08pm, Ray Andrews wrote:
> } Subject: Re: symlink chain.
> }
> } Needless to say, I have no idea if this is sound, however:
> }
> }      /* With -m option -- treat arguments as a glob patterns */
> } //    if (OPT_ISSET(ops,'m')) {
> }      if (OPT_ISSET(ops,'m') && **argv != '/' ) {
> }
> } ... seems to work.
>
> I wouldn't use the word "work" exactly.  All that does is turn off the
> pattern matching entirely.  You're probably next going to complain that
>
> % whence -m /\*/bin/zsh

I repeat that I have no idea if that is sound, I'm just fooling with 
it.  But I haven't broken it here (yet).


    $ whence -mas "/usr/bin/zsh"
    zsh-5.0.7-165-g2194da1
    /usr/bin/zsh -> /usr/local/bin/zsh-5.0.7-165-g2194da1


    $ whence -mas "*zsh*"
    zsh-5.0.7-165-g2194da1
    /usr/local/bin/zsh -> /usr/local/bin/zsh-5.0.7-165-g2194da1
    /usr/bin/zsh -> /usr/local/bin/zsh-5.0.7-165-g2194da1
    /bin/zsh -> /usr/local/bin/zsh-5.0.7-165-g2194da1
    /usr/local/bin/zsh,3,bart-fix-TRAPDEBUG
    /usr/local/bin/zsh-2014-11-14
    /usr/local/bin/zsh-5.0.7-109-g2598010
    /usr/local/bin/zsh-5.0.7-112-g49d6aac
    /usr/local/bin/zsh-5.0.7-125-g167a15a
    /usr/local/bin/zsh-5.0.7-136-g0a07ffd
    /usr/local/bin/zsh-5.0.7-138-g247f754
    /usr/local/bin/zsh-5.0.7-159-g89c692e
    /usr/local/bin/zsh-5.0.7-161-g1cd8023
    /usr/local/bin/zsh-5.0.7-165-g2194da1
    /usr/local/bin/zsh-5.0.7-dev-0
    /usr/local/bin/zsh-RayStyle1
    /usr/local/bin/zsh.old
    /bin/zsh4
    /bin/zsh5

... so pattern matching is still working, so far.
>
> should return /usr/bin/zsh and /usr/local/bin/zsh, or somthing of the
> kind.  This is just abusing the purpose of "whence", which is intended
> to tell you what a path search would find for a simple command name.

Well, what it 'should' be used for is subjective, and of course my views on
that are very junior.  I want it to give me every command that matches the
pattern, and not to crap out if  -m is given, just because a full path is
specified.  Ditto with -a.  And I'd like being able to use it to see 
symlink chains.
I think all of that makes the command more intuitive and far more useful
even  if it is a breach of tradition.
>
> If we *really* want this behavior -- which I submit that we don't, as
> we're wandering into silly territory like whence -m '*bin*' returning
> all commands in all directories named "bin",

Speaking for myself, that's not something I'd begin to want.  I want it 
to do what
it advertises itself to do, but with no gotchas.  I'd not call that silly.
> so we should stop futzing
> around with "whence" -- then the correct thing is rewriting the hash
> table scan to look at both the keys and the values when doing the
> pattern matching.
>
> Which has ramifications beyond "whence" because it uses the same hash
> table scan routines as everything else.  I confess I'm actually a bit
> surprised that PWS was willing to hack up something as deeply involved
> in the internals as xsymlinks() [in which we just finished fixing other
> obscure bugs] in order to implement whence -S.

Of course we leave final decisions to you guys as to what can be done 
safely.
But once I lean how to preserve them, I'll be keeping both of those:

... && **argv != '/' ...
changes, cuz they sure look good to me. (And the symlink chain once I learn
how to import a patch.)  That's presuming a better method isn't forthcoming.

> Shell functions exist so that if something like whence doesn't do what
> you want, you can write something else that does.

Yup.  I had those link-chains displayed with 'namei' just fine, but I 
still think
it is a natural addition to whence.  You guys know best.


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: symlink chain.
  2015-01-03  5:53                 ` Ray Andrews
@ 2015-01-03  7:17                   ` Bart Schaefer
  2015-01-03 17:14                     ` Ray Andrews
  0 siblings, 1 reply; 30+ messages in thread
From: Bart Schaefer @ 2015-01-03  7:17 UTC (permalink / raw)
  To: zsh-users

On Jan 2,  9:53pm, Ray Andrews wrote:
} Subject: Re: symlink chain.
}
} On 01/02/2015 09:03 PM, Bart Schaefer wrote:
} > On Jan 2,  5:08pm, Ray Andrews wrote:
} > }      if (OPT_ISSET(ops,'m') && **argv != '/' ) {
} > }
} > } ... seems to work.
} >
} > I wouldn't use the word "work" exactly.  All that does is turn off the
} > pattern matching entirely.

... for strings beginning with a '/', obviously, not for all patterns.
Which is broken for aliases and shell functions:

torch% /foo() { print Look, I have a slash. }
torch% whence -v /foo
/foo is a shell function
torch% whence -mv '/fo?'	# won't work with the above change
/foo is a shell function

PWS's change for -a only works because it happens so late in the algorithm
that there is nothing left but path to search, and no patterns left to be
tried.


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: symlink chain.
  2015-01-03  7:17                   ` Bart Schaefer
@ 2015-01-03 17:14                     ` Ray Andrews
  2015-01-03 20:02                       ` Bart Schaefer
  0 siblings, 1 reply; 30+ messages in thread
From: Ray Andrews @ 2015-01-03 17:14 UTC (permalink / raw)
  To: zsh-users

On 01/02/2015 11:17 PM, Bart Schaefer wrote:
> torch% /foo() { print Look, I have a slash. }
> torch% whence -v /foo
> /foo is a shell function
> torch% whence -mv '/fo?'	# won't work with the above change
> /foo is a shell function
>
> PWS's change for -a only works because it happens so late in the algorithm
> that there is nothing left but path to search, and no patterns left to be
> tried.
>
As you say.  The test for the leading slash is obviously a bit of a 
band-aid.  I'd have expected the -m and/or -a code to be able to look at 
a full path without that being any sort of problem--it wouldn't have any 
work to do so it would get the day off, but neither would it force a 
false negative return (rather the way that -s just does nothing when it 
has nothing to do, but it doesn't break anything, either).

All I can say with conviction is that 'whence -m /usr/bin/zsh' should 
not return nothing, because the file exists on the path and is a link to 
an executable and has a legitimate search target string. It should be 
found.  It is pathetic that if I was doing a whole list of whences with 
the -m or -a switches, and then at some point I entered a canonical 
filename (whereas up to that point it was more the pattern search 
thing), I get nothing because, oops, I forgot to remove the -m and/or 
-a.  Or this alias:

     alias wenceslas='whence -mavs'

... doesn't work with a canonical filename :(

Whence is a wrench.  Wrenches should not be hard to understand and they 
shouldn't have any gotchas.  It should take two minutes to know how 
whence works and it should work every time in an intuitive way.  No 
switch should break anything.  To be theatrical, I think if zsh made 
wrenches, they would only tighten metric nuts on Tuesdays and they would 
only loosen fractional nuts on long weekends  *but* you could lay a zsh 
wrench on top of your engine and it would do a full valve job for you 
and do it right (except on Fridays).  Pardon ;-)

BTW, for what it's worth, in one of my wrappers I do this:

    find_count=`whence -ma "$1" | wc -l`

... I'm just using whence at that point to search for and count targets 
which then are given the 3d degree:

    $ i ,v zsh

    Current path:

    /aWorking/Bin
    /usr/local/bin
    /usr/sbin
    /usr/bin
    /sbin
    /bin

    Aliases, Functions, Builtins, Scripts or Binaries: Found 3 matches:

    (1)TYPE: zsh is /usr/local/bin/zsh ->
    /usr/local/bin/zsh-5.0.7-165-g2194da1:
    LISTING: lrwxrwxrwx 1 22 2014-12-30-19:59:18 /usr/local/bin/zsh ->
    zsh-5.0.7-165-g2194da1*
    LINK CHAIN:
    l zsh -> zsh-5.0.7-165-g2194da1
    CONTENT: inode/symlink; charset=binary

    (2)TYPE: zsh is /usr/bin/zsh -> /usr/local/bin/zsh-5.0.7-165-g2194da1:
    LISTING: lrwxrwxrwx 1 28 2014-02-09-19:29:52 /usr/bin/zsh ->
    /etc/alternatives/zsh-usrbin*
    LINK CHAIN:
    l zsh -> /etc/alternatives/zsh-usrbin
    l   zsh-usrbin -> /usr/local/bin/zsh
    l     zsh -> zsh-5.0.7-165-g2194da1
    CONTENT: inode/symlink; charset=binary

    (3)TYPE: zsh is /bin/zsh -> /usr/local/bin/zsh-5.0.7-165-g2194da1:
    LISTING: lrwxrwxrwx 1 21 2014-02-09-19:29:52 /bin/zsh ->
    /etc/alternatives/zsh*
    LINK CHAIN:
    l zsh -> /etc/alternatives/zsh
    l   zsh -> /usr/local/bin/zsh
    l     zsh -> zsh-5.0.7-165-g2194da1
    CONTENT: inode/symlink; charset=binary

... and sometimes I want to give the 3d degree to a single specified file:


     $ i ,v /usr/bin/zsh

... and that's when it bugs me that the 'whence -ma' test fails.  I can 
work around it, but I shouldn't hafta. -m and -a should be smart enough 
to handle a canonical filename.

(BTW The above is my idea of one-stop shopping for information about a 
command ;-)


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: symlink chain.
  2015-01-03 17:14                     ` Ray Andrews
@ 2015-01-03 20:02                       ` Bart Schaefer
  2015-01-03 21:13                         ` Ray Andrews
  0 siblings, 1 reply; 30+ messages in thread
From: Bart Schaefer @ 2015-01-03 20:02 UTC (permalink / raw)
  To: zsh-users

On Jan 3,  9:14am, Ray Andrews wrote:
}
} Whence is a wrench.  Wrenches should not be hard to understand and they 
} shouldn't have any gotchas.

Whence is a pocketknife that you seem to want to be a Leatherman tool.

If you want the wrench analogy, wrenches fit on nuts, and nuts of a
particular shape.  The shape of nut that whence fits on is a single
word that might be a key in one of the command-related hash tables.
A full file path is not that kind of nut.  YOU are making whence hard
to understand by trying to feed it things it wasn't designed to accept.


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: symlink chain.
  2015-01-03 20:02                       ` Bart Schaefer
@ 2015-01-03 21:13                         ` Ray Andrews
  2015-01-03 21:42                           ` Peter Stephenson
  2015-01-04  0:40                           ` Bart Schaefer
  0 siblings, 2 replies; 30+ messages in thread
From: Ray Andrews @ 2015-01-03 21:13 UTC (permalink / raw)
  To: zsh-users

On 01/03/2015 12:02 PM, Bart Schaefer wrote:
> On Jan 3,  9:14am, Ray Andrews wrote:
> }
> } Whence is a wrench.  Wrenches should not be hard to understand and they
> } shouldn't have any gotchas.
>
> Whence is a pocketknife that you seem to want to be a Leatherman tool.
>
> If you want the wrench analogy, wrenches fit on nuts, and nuts of a
> particular shape.  The shape of nut that whence fits on is a single
> word that might be a key in one of the command-related hash tables.
> A full file path is not that kind of nut.  YOU are making whence hard
> to understand by trying to feed it things it wasn't designed to accept.
>
Well sir, you've made up your mind on that, so I won't flog the subject 
further, but to say that if:

      $ whence /usr/bin/zsh

... did *not* work, I'd have an easier time accepting your view. But 
since it *does* work, I stick to my guns that

      $ whence -m /usr/bin/zsh

... should work as well.  IMHO the -m should just quietly undertand that 
it has nothing to do in that case and bow out gracefully.  Anyway, it's 
not going to happen.  Conversely, the man page could
explain that -m and -a are incompatible with full path filenames, but 
that's not going to happen either.



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: symlink chain.
  2015-01-03 21:13                         ` Ray Andrews
@ 2015-01-03 21:42                           ` Peter Stephenson
  2015-01-03 22:42                             ` Ray Andrews
  2015-01-04  0:40                           ` Bart Schaefer
  1 sibling, 1 reply; 30+ messages in thread
From: Peter Stephenson @ 2015-01-03 21:42 UTC (permalink / raw)
  To: zsh-users

On Sat, 03 Jan 2015 13:13:16 -0800
Ray Andrews <rayandrews@eastlink.ca> wrote:
> Conversely, the man page could
> explain that -m and -a are incompatible with full path filenames, but 
> that's not going to happen either.

There's no reason not to document what the basic intention of whence is,
to avoid people doing dodgy experiments with dodgy results.  The key
hint at the moment is where it says it indicates how the argument would
be used as a command *name*, which sort of implies full paths aren't
very useful, but it doesn't actually spell this out.

diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo
index b4f4b67..49c2c11 100644
--- a/Doc/Zsh/builtins.yo
+++ b/Doc/Zsh/builtins.yo
@@ -2087,6 +2087,11 @@ item(tt(whence) [ tt(-vcwfpamsS) ] var(name) ...)(
 For each name, indicate how it would be interpreted if used as a
 command name.
 
+tt(whence) is most useful when var(name) is only the last path component
+of a command, i.e. does not include a `tt(/)'; in particular, pattern
+matching only succeeds if just the non-directory component of the command is
+passed.
+
 startitem()
 item(tt(-v))(
 Produce a more verbose report.
@@ -2119,7 +2124,7 @@ throughout the command path.
 Normally only the first occurrence is printed.
 )
 item(tt(-m))(
-The arguments are taken as patterns (should be
+The arguments are taken as patterns (pattern characters should be
 quoted), and the information is displayed for each command matching one
 of these patterns.
 )

pws


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: symlink chain.
  2015-01-03 21:42                           ` Peter Stephenson
@ 2015-01-03 22:42                             ` Ray Andrews
  2015-01-04  0:41                               ` Bart Schaefer
  0 siblings, 1 reply; 30+ messages in thread
From: Ray Andrews @ 2015-01-03 22:42 UTC (permalink / raw)
  To: zsh-users

On 01/03/2015 01:42 PM, Peter Stephenson wrote:
> +tt(whence) is most useful when var(name) is only the last path component
> +of a command, i.e. does not include a `tt(/)'; in particular, pattern
> +matching only succeeds if just the non-directory component of the command is
> +passed.
>
Well, that's sure an improvement. If -m won't be made a bit smarter, 
then at least
the doc makes it clear what one is expected to feed the command. Anyway, 
I'll keep those **argv != '/' tests here, once I figure out how to sneak 
them past git.


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: symlink chain.
  2015-01-03 21:13                         ` Ray Andrews
  2015-01-03 21:42                           ` Peter Stephenson
@ 2015-01-04  0:40                           ` Bart Schaefer
  2015-01-04  3:35                             ` Ray Andrews
  1 sibling, 1 reply; 30+ messages in thread
From: Bart Schaefer @ 2015-01-04  0:40 UTC (permalink / raw)
  To: zsh-users

On Jan 3,  1:13pm, Ray Andrews wrote:
} Subject: Re: symlink chain.
}
} On 01/03/2015 12:02 PM, Bart Schaefer wrote:
} >
} > Whence is a pocketknife that you seem to want to be a Leatherman tool.
} >
} > If you want the wrench analogy, wrenches fit on nuts, and nuts of a
} > particular shape.
}
} Well sir, you've made up your mind on that, so I won't flog the subject 
} further, but to say that if:
} 
}       $ whence /usr/bin/zsh
} 
} ... did *not* work. I'd have an easier time accepting your view.

My actual view is closer to the pocketknife than to the wrench.  The
-w and -s options of whence can be useful with a full path.  The -m
option just isn't that sort of blade.

Don't use the knife with both ends unfolded and then complain when you
stab yourself in the thumb.

However, if you REALLY want the -m option to do something special with
arguments that start with a slash, you need this (which I won't commit):

diff --git a/Src/builtin.c b/Src/builtin.c
index ebc0654..509629f 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -3243,10 +3243,28 @@ bin_whence(char *nam, char **argv, Options ops, int func)
 	    }
 	    /* 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);
+	    if (**argv == '/') {
+		if (all)
+		    addlinknode(matchednodes, *argv);
+		else if ((cnam = findcmd(*argv, 1))) {
+		    /* Found external command. */
+		    if (wd) {
+			printf("%s: command\n", *argv);
+		    } else {
+			if (v && !csh)
+			    zputs(*argv, stdout), fputs(" is ", stdout);
+			zputs(cnam, stdout);
+			if (OPT_ISSET(ops,'s') || OPT_ISSET(ops,'S'))
+			    print_if_link(cnam, OPT_ISSET(ops,'S'));
+			fputc('\n', stdout);
+		    }
+		}
+	    } else {
+		cmdnamtab->filltable(cmdnamtab);
+		scanmatchtable(cmdnamtab, pprog, 1, 0, 0,
+			       (all ? fetchcmdnamnode : cmdnamtab->printnode),
+			       printflags);
+	    }
 
 	    unqueue_signals();
 	}


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: symlink chain.
  2015-01-03 22:42                             ` Ray Andrews
@ 2015-01-04  0:41                               ` Bart Schaefer
  2015-01-04  3:45                                 ` Ray Andrews
  0 siblings, 1 reply; 30+ messages in thread
From: Bart Schaefer @ 2015-01-04  0:41 UTC (permalink / raw)
  To: zsh-users

On Jan 3,  2:42pm, Ray Andrews wrote:
}
} I'll keep those **argv != '/' tests here, once I figure out how to sneak 
} them past git.

Peter already pushed the one for the -a option, so you should just be able
to "git pull" that one.


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: symlink chain.
  2015-01-04  0:40                           ` Bart Schaefer
@ 2015-01-04  3:35                             ` Ray Andrews
  2015-01-04  8:31                               ` Bart Schaefer
  0 siblings, 1 reply; 30+ messages in thread
From: Ray Andrews @ 2015-01-04  3:35 UTC (permalink / raw)
  To: zsh-users

On 01/03/2015 04:40 PM, Bart Schaefer wrote:
> My actual view is closer to the pocketknife than to the wrench.  The
> -w and -s options of whence can be useful with a full path.  The -m
> option just isn't that sort of blade.

I think the core of the difference between our points of view, is that 
for me, it's a simple question of trying to maximize consistency and 
minimize surprise.  For you,
knowing the guts of how these things work, it is intuitive/obvious that 
-m should do what it  does, and not work with full paths, whereas for 
me, not knowing that stuff, I take the more superficial view and don't 
want -m killing a search that would work fine without it.  I expect -m 
to *just* *add* the ability to search for patterns, not to kill 
otherwise acceptable searches. When I know how this hash table works, I 
will probably come round to your way of viewing it.
> Don't use the knife with both ends unfolded and then complain when you
> stab yourself in the thumb.
>

Well, one analogy is as good as another.  With so many of these issues, it
comes down to how you look at it.  For me, switches add features, they
don't invalidate arguments ... but is that really a rule? ...
> However, if you REALLY want the -m option to do something special with
> arguments that start with a slash, you need this (which I won't commit):
>

As we were saying it's not really about the slash, I'd say it's more a 
test for an existing, specific file, no?  FWIW, this is  how I handle it 
now:


      local ma=ma
       [ -e $1 ] && ma=
       find_count=`whence -$ma "$nnocase$1" | wc -l`

... pretty sad, IMHO, I do what whence should do for me, and cut out the 
-ma when
they are going to sabotage the output.  Anyway, it works fine, it just 
bugs me.


I hafta learn how to do this patching (I don't want to blow something up 
doing it wrong) and I have to learn how to ask git to preserve any local 
changes while still
pulling whatever needs to be pulled.  (Most cool that it can do that 
sort of thing at all.)  You can't sneak anything past git, that's for sure.


> diff --git a/Src/builtin.c b/Src/builtin.c
> index ebc0654..509629f 100644
> --- a/Src/builtin.c
> +++ b/Src/builtin.c
> @@ -3243,10 +3243,28 @@ bin_whence(char *nam, char **argv, Options ops, int func)
>   	    }
>   	    /* 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);
> +	    if (**argv == '/') {
> +		if (all)
> +		    addlinknode(matchednodes, *argv);
> +		else if ((cnam = findcmd(*argv, 1))) {
> +		    /* Found external command. */
> +		    if (wd) {
> +			printf("%s: command\n", *argv);
> +		    } else {
> +			if (v && !csh)
> +			    zputs(*argv, stdout), fputs(" is ", stdout);
> +			zputs(cnam, stdout);
> +			if (OPT_ISSET(ops,'s') || OPT_ISSET(ops,'S'))
> +			    print_if_link(cnam, OPT_ISSET(ops,'S'));
> +			fputc('\n', stdout);
> +		    }
> +		}
> +	    } else {
> +		cmdnamtab->filltable(cmdnamtab);
> +		scanmatchtable(cmdnamtab, pprog, 1, 0, 0,
> +			       (all ? fetchcmdnamnode : cmdnamtab->printnode),
> +			       printflags);
> +	    }
>   
>   	    unqueue_signals();
>   	}
>


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: symlink chain.
  2015-01-04  0:41                               ` Bart Schaefer
@ 2015-01-04  3:45                                 ` Ray Andrews
  0 siblings, 0 replies; 30+ messages in thread
From: Ray Andrews @ 2015-01-04  3:45 UTC (permalink / raw)
  To: zsh-users

On 01/03/2015 04:41 PM, Bart Schaefer wrote:
> On Jan 3,  2:42pm, Ray Andrews wrote:
> }
> } I'll keep those **argv != '/' tests here, once I figure out how to sneak
> } them past git.
>
> Peter already pushed the one for the -a option, so you should just be able
> to "git pull" that one.
>
Ah, right.  I wasn't sure that would pass muster, since you are 
skeptical of it.  But, for arguments sake, why not do for -m what
has been done for -a?  Mind ... they are rather different things;
-a is the crux of it.


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: symlink chain.
  2015-01-04  3:35                             ` Ray Andrews
@ 2015-01-04  8:31                               ` Bart Schaefer
  2015-01-04 20:49                                 ` Ray Andrews
  0 siblings, 1 reply; 30+ messages in thread
From: Bart Schaefer @ 2015-01-04  8:31 UTC (permalink / raw)
  To: zsh-users

On Jan 3,  7:35pm, Ray Andrews wrote:
}
} I take the more superficial view and don't want -m killing a search
} that would work fine without it. I expect -m to *just* *add* the
} ability to search for patterns, not to kill otherwise acceptable
} searches.

There are a couple of ways in which this is eventually going to get
you into trouble.

First, whence is not the only command where some switches are mutually
exclusive rather than cumulative, or where switches change many details
of the action performed even when they can be combined.

Second, pattern matching really isn't the same thing as simple string
comparison, and it's also not exactly the same thing as globbing even
though for the shell the same metacharacters are used.  I think we
discussed that last part in a different thread.

} Well, one analogy is as good as another. With so many of these issues,
} it comes down to how you look at it. For me, switches add features,
} they don't invalidate arguments ... but is that really a rule? ...

Switches often change the meaning of arguments.  Look at the example
we just went through with (print '\e') vs. (print -r '\e').

} As we were saying it's not really about the slash, I'd say it's more
} a test for an existing, specific file, no?

Well, no, it's not about that, actually.  It's about the difference
between a file path and a pattern.  Slashes mean something in a file
path, but in a pattern (as opposed to a glob!) they're just another
character; they might as well be dots or colons or "x" for all that
the pattern matching code cares.

Explicitly telling "whence" to interpret the arguments as patterns
ought to imply you understand what the patterns are being compared
against.  And what they're compared against is NOT the full path name
as if composed from the root of the file system.  (I explained it in
terms of hash keys because there's no more succinct way to refer to
aliases + builtins + functions + reserved-words + "only the last path
component of a command, i.e. does not include a `/';" not because I
actually think about it as hash keys when using it.)

You're expecting the -m switch to mean "try this as a pattern, but if
that doesn't seem to work, then ignore that I used -m and try it the
other way too, but only if it actually IS a file path, because file
paths work when they aren't patterns."

You think the current interpretation sabotages the output.

I think your expected interpretation sabotages the inputs.

Which is why I'm spending all this time trying to explain myself.

} I hafta learn how to do this patching (I don't want to blow something up 
} doing it wrong) and I have to learn how to ask git to preserve any local 
} changes while still pulling whatever needs to be pulled.

If you "git commit" your changes and then use "git pull --rebase" you
should have what you want most of the time, unless some of the changes
in origin/master are in direct conflict with what you committed.

You just have to be careful about "git push" in that case, if you have
permission to do so.  If you have changes you never want to be pushed
to the master, create a branch and commit them there.


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: symlink chain.
  2015-01-04  8:31                               ` Bart Schaefer
@ 2015-01-04 20:49                                 ` Ray Andrews
  2015-01-05  1:34                                   ` Bart Schaefer
  0 siblings, 1 reply; 30+ messages in thread
From: Ray Andrews @ 2015-01-04 20:49 UTC (permalink / raw)
  To: zsh-users

On 01/04/2015 12:31 AM, Bart Schaefer wrote:


Sorry for the length of this, most will not want to read it.

> On Jan 3,  7:35pm, Ray Andrews wrote:
> }
> } I take the more superficial view and don't want -m killing a search
> } that would work fine without it. I expect -m to *just* *add* the
> } ability to search for patterns, not to kill otherwise acceptable
> } searches.
>
> There are a couple of ways in which this is eventually going to get
> you into trouble.
>
> First, whence is not the only command where some switches are mutually
> exclusive rather than cumulative, or where switches change many details
> of the action performed even when they can be combined.

I'm glad you're still interested in this, because I'd like to flog it 
right to
death myself.  I'm actually trying to study the subject of switches
with rigor, and it's quite astonishing how much taxonomy and logic
can go into what might seem like a very simple subject.  It turns out
that poor old whence is a useful test case for this.

So, we
certainly have cumulative switches 'whence -v -s -S -a': show me matches
&& show verbose info && expand sysmlinks && expand full chains of
symlinks (-S subsumes -s) && (now, with Peter's change) show all
matches on the path,  not just the first (if there is only one match, then
that's just fine). Note, that none of these switches
interfere with any other, and none force any limitation on the argument--
what 'whence' can eat it can still eat with any and/or all of those 
switches.
(But that was not the case with -a previously).

IMHO, this is 'good'.
We have minimal gotchas, minimal exceptions and maximum utility.  In
short, the man page is shorter, our wrench works on Tuesdays too! There
is, at one and the same time, more power *and*  less to learn.

And we certainly have mutually exclusive switches 'whence -v -c -w':
Only one can be true at any given time, but that's the nature of the
thing, I'd say that this is intuitively acceptable, and not limiting in
any way, dinner is served on silver, or on china, it can't be both.

And yes, we have naturally limiting switches: 'ls -B': ignore backups.
But, would we not agree that it is the natural thing to prefer
cumulative switches over limiting switches?  Is it not intuitive that as
you 'add' switches you 'add' features?  No rule there, just a preference.
(BTW, you convinced me of that yourself not too long ago, I was wanting
something to come with all bells and whistles blowing by default, and
that was a juvenile mistake, as you showed me.)

And then we have the question of the 'smartness' of switches.  'ls -g':
group directories first.  Imagine if the output was nothing if it
turned out that there *were* no directories to sort first.  IOW, 'ls -g'
returns nothing even tho there are lots of  files because there are no
directories to sort.  Not very friendly eh?  As I put it, when -g has
nothing to do it just does nothing (and it certainly does not sabotage
the output).

I'm wanting 'whence -m' to be smart the same way as 'ls -g' is smart.
I'm wanting it to 'add' functionality without constraining the
arguments.  My thinking being that that maximizes utility without
breaking anything because -m will just 'step aside' when the
argument is not valid for it's intended use.  IOW just as 'ls -g' says:
"Sort directories first (if there *are* any)" but it does *not* say: "Sort
directories first and don't show *anything* if there are no directories",
so 'whence -m' should say: "Expand the search to use pattern matching
*IF* a pattern is  supplied, and if there is no valid pattern supplied 
then just
do nothing. i.e. if a full  path is given, then -m just does nothing at all
in the same way that 'ls -g' does nothing at all when there are no
directories to sort.

In practical terms this lets me bury 'whence -mavs $1' inside a wrapper
or alias and know that it will work no matter what I throw at it (needless
to say, what I throw at it must be legal for bare 'whence'.)

The counter argument is to explore what my smart -m would break.
What would it break?  Now, there is no logical reason why -m should
*not* be exclusionary--to abort the search if a valid pattern is not given
(as it is now) but is that the most desirable thing? I say that 99% of the
time, it is not.

But maybe what really defeats me is that I can handle it more or less like
this:

   local ma=ma
   # Anything with a path in it can't be used with -m or -a!
   [[ $1 =~ / ]] && ma=
   find_count=`whence -$ma "$nnocase$1" | wc -l`

< micro-rant>
I myself will never, ever use a slash for anything but what God meant it
to be used for and I think it is monstrous that anyone would think of
doing otherwise, nor should zsh even permit such blasphemy.
</>

... That more or less does what Peter's modification does.  So all I really
have 'left' to argue is that I think it would be polite of whence to handle
it for me.  I'd like a kinder, gentler zsh. Fat chance ;-)
> Second, pattern matching really isn't the same thing as simple string
> comparison, and it's also not exactly the same thing as globbing even
> though for the shell the same metacharacters are used.  I think we
> discussed that last part in a different thread.

True, as you've explained.  But I'm not asking -m to process a full 
path, I'm
asking it to just 'step aside' and do nothing and let whence revert to 
the 'normal' search, 'intelligently'.

(Which BTW, demolishes my 'wrench' analogy ... wrenches have no brains.
If I apply a crescent wrench to a pipe, it will not tell me: "Pardon 
Ray, you need a
pipe wrench for this, and I'm an adjustable spanner.")
> } Well, one analogy is as good as another. With so many of these issues,
> } it comes down to how you look at it. For me, switches add features,
> } they don't invalidate arguments ... but is that really a rule? ...
>
> Switches often change the meaning of arguments.  Look at the example
> we just went through with (print '\e') vs. (print -r '\e').

Good example.  Still -r never 'invalidates' an argument.  Imagine if -r
forced print to print nothing if there were no escapes for it to handle--
is that not the symmetric comparison with -m? -r is smart, if it has
nothing to do, it does nothing. -m should be smart, if it has nothing to
do, it does nothing. This is imperfect reasoning, but not without
some force.
>
> } As we were saying it's not really about the slash, I'd say it's more
> } a test for an existing, specific file, no?
>
> Well, no, it's not about that, actually.  It's about the difference
> between a file path and a pattern.  Slashes mean something in a file
> path, but in a pattern (as opposed to a glob!) they're just another
> character; they might as well be dots or colons or "x" for all that
> the pattern matching code cares.

Yes, quite right, I figured that out myself last night.  It may indeed be
that what I want can not be done robustly.  If so it must of course be
omitted.  No matter how friendly it might seem, if it introduces any
'maybes' then it's poison.  I probably 'loose' this discussion based on
that.  And fairly beaten.


> ... You're expecting the -m switch to mean "try this as a pattern, but if
that doesn't seem to work, then ignore that I used -m and try it the
other way too, but only if it actually IS a file path, because file
paths work when they aren't patterns."


Well, yes, that's exactly it.

whence: trynormalstearch || error

whence -m: trypatternsearch || trynormalsearch || error

Not to strange, is it?  Just for arguments sake we could:

whence -m: trypatternsearch || error

whence -M: trypatternsearch || trynormalsearch || error

... so -m would remain unchanged, and -M would give me what I want.
In code terms, it would introduce a 'goto' (try again as a normal search).

As -S expands on -s, so -M would expand on -m.

In the manual:  " -M will attempt a pattern match, (as -m), but will
then attempt a normal match if the pattern match fails. This can be
useful where whence is used in, say, an alias that might receive
either a normal argument, or a pattern argument."

We'd have it both ways.

So IMHO the question becomes, would that
add utility?  I say it would.  Do I need it, strictly speaking? No.  Could
it be coded robustly, without breaking anything?  That's for you guys
to decide.  (But Peter likes it for -a at least even if not for -m, but 
I think
the implementation is more of a 'try again' at failure than a filtering out
of the slash up front).
> You think the current interpretation sabotages the output.

It does!
> I think your expected interpretation sabotages the inputs.

Maybe :(
> Which is why I'm spending all this time trying to explain myself.

It will be worth it in the long run.  I think my 'challenge' is valid,
but it is not certain that it should triumph.  But if it fails, then
(given it's obvious superficial utility) the reasons should be
very clear.  These conclusions will apply widely.
> } I hafta learn how to do this patching (I don't want to blow something up
> } doing it wrong) and I have to learn how to ask git to preserve any local
> } changes while still pulling whatever needs to be pulled.
>
> If you "git commit" your changes and then use "git pull --rebase" you
> should have what you want most of the time, unless some of the changes
> in origin/master are in direct conflict with what you committed.

Many thanks.  I've stopped reading the manual, hafta get back to it.
> You just have to be careful about "git push" in that case, if you have
> permission to do so.

Maybe five years from now.
> If you have changes you never want to be pushed
> to the master, create a branch and commit them there.
>
Arigato sensei


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: symlink chain.
  2015-01-04 20:49                                 ` Ray Andrews
@ 2015-01-05  1:34                                   ` Bart Schaefer
  2015-01-05  2:28                                     ` Lawrence Velázquez
  0 siblings, 1 reply; 30+ messages in thread
From: Bart Schaefer @ 2015-01-05  1:34 UTC (permalink / raw)
  To: zsh-users

On Jan 4, 12:49pm, Ray Andrews wrote:
}
} But, would we not agree that it is the natural thing to prefer
} cumulative switches over limiting switches?  Is it not intuitive that
} as you 'add' switches you 'add' features?

There's no answer for this that fits all cases.  In an ideal world,
one would always think of the minimal action and then build on it,
but the world is rarely ideal.  More often there exists something
that has a purpose or mechanism very similar to a new idea, and so
that something is altered to support the new idea.  A lot of times,
that isn't an additive process.

} And then we have the question of the 'smartness' of switches.  'ls -g':
} group directories first.  Imagine if the output was nothing if it
} turned out that there *were* no directories to sort first.

This is not a good example, because "ls -g" refers to sorting, whereas
"whence -m" refers to searching.  A better example would be "grep -f".
Consider
	ls -l /usr/local/bin | grep '.*zsh.*'
vs.
	ls -l /usr/local/bin | grep -f '.*zsh.*'

Should the latter grep revert to pattern matching because the literal
string failed to match anything?  Did -f add a feature to grep?  Did I
sabotage the output when the second grep found nothing?

(I'm going to return to this in a moment.)

} < micro-rant>
} I myself will never, ever use a slash for anything but what God meant it
} to be used for and I think it is monstrous that anyone would think of
} doing otherwise, nor should zsh even permit such blasphemy.
} </>

Apparently that means you're going to use a slash only to close your
HTML tags ...?

} > Switches often change the meaning of arguments.  Look at the example
} > we just went through with (print '\e') vs. (print -r '\e').
} 
} Good example.  Still -r never 'invalidates' an argument.  Imagine if -r
} forced print to print nothing if there were no escapes for it to handle--
} is that not the symmetric comparison with -m?

No, it's not symmetric, because print doesn't have any other job to do
with the arguments, whereas whence does have another job (compare them
to something).  If you want symmetry, try "print %G" vs. "print -P %G".

} whence: trynormalstearch || error
} 
} whence -m: trypatternsearch || trynormalsearch || error
} 
} Not to strange, is it?

OK, now you've hit on something that actually might be a problem.  To
return to

	ls -l /usr/local/bin | grep -f '.*zsh.*'

That would typically return nonzero because the grep failed to match
anything.  The trouble this illustrates is that

	whence -m /this/is/a/file/path
and
	whence -a this_is_not_a_command

both return zero.  Other cases in which whence does not find anything
return nonzero.  So you can't successfully write

	whence -m $1 || whence -a $1 || whence $1

which would be the "normal" way to do what you want.  I think whence
should return a detectable failure when the pattern doesn't match,
rather than just output nothing.

} In the manual:  " -M will attempt a pattern match, (as -m), but will
} then attempt a normal match if the pattern match fails. This can be
} either a normal argument, or a pattern argument."
} 
} So IMHO the question becomes, would that add utility?  I say it would.

I could be convinced to agree with you except for two things:

(1) A pattern like [a-z] or using # or ## with extendeglob matches a
very different set of strings than does the literal '[a-z]' etc.  You
have to consider the case of a pattern getting a false hit when taken
as a plain string, as well as the case of a plain string getting a
"false" miss when taken as a pattern.

(2) The set of things searched by whence is not limited to files, and
this adds utility only for the case where the search is meant (by the
user) to be restricted to files.  This compounds the effects of (1).

} (But Peter likes it for -a at least even if not for -m, [...])

The -a case avoids (1) entirely and does not affect the behavior of (2)
for the non-file searches performed by whence.


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: symlink chain.
  2015-01-05  1:34                                   ` Bart Schaefer
@ 2015-01-05  2:28                                     ` Lawrence Velázquez
  2015-01-05  4:24                                       ` Ray Andrews
  0 siblings, 1 reply; 30+ messages in thread
From: Lawrence Velázquez @ 2015-01-05  2:28 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: zsh-users

On Jan 4, 2015, at 8:34 PM, Bart Schaefer <schaefer@brasslantern.com> wrote:

> On Jan 4, 12:49pm, Ray Andrews wrote:
> }
> } But, would we not agree that it is the natural thing to prefer
> } cumulative switches over limiting switches?  Is it not intuitive that
> } as you 'add' switches you 'add' features?
> 
> There's no answer for this that fits all cases.  In an ideal world,
> one would always think of the minimal action and then build on it,
> but the world is rarely ideal.  More often there exists something
> that has a purpose or mechanism very similar to a new idea, and so
> that something is altered to support the new idea.  A lot of times,
> that isn't an additive process.

Also consider an alternate (and equally valid) point of view in which
commands should be a sort of variable-length encoding. That is, the
shortest commands (the ones without switches) would ideally represent
*common* actions, not necessarily *minimal* actions.

vq


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: symlink chain.
  2015-01-05  2:28                                     ` Lawrence Velázquez
@ 2015-01-05  4:24                                       ` Ray Andrews
  0 siblings, 0 replies; 30+ messages in thread
From: Ray Andrews @ 2015-01-05  4:24 UTC (permalink / raw)
  To: zsh-users

On 01/04/2015 06:28 PM, Lawrence Velázquez wrote:
> On Jan 4, 2015, at 8:34 PM, Bart Schaefer <schaefer@brasslantern.com> wrote:
>
>> On Jan 4, 12:49pm, Ray Andrews wrote:
>> }
>> } But, would we not agree that it is the natural thing to prefer
>> } cumulative switches over limiting switches?  Is it not intuitive that
>> } as you 'add' switches you 'add' features?
>>
>> There's no answer for this that fits all cases.  In an ideal world,
>> one would always think of the minimal action and then build on it,
>> but the world is rarely ideal.  More often there exists something
>> that has a purpose or mechanism very similar to a new idea, and so
>> that something is altered to support the new idea.  A lot of times,
>> that isn't an additive process.
> Also consider an alternate (and equally valid) point of view in which
> commands should be a sort of variable-length encoding. That is, the
> shortest commands (the ones without switches) would ideally represent
> *common* actions, not necessarily *minimal* actions.
>
> vq
Yes.  We always are stuck with the limits of language there, but there's 
no doubt that the 'nix world has attempted to do just that. The common 
commands are normally, what? four letters or fewer.
>


^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2015-01-05  4:24 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-12-27  4:50 symlink chain Ray Andrews
2014-12-27 23:38 ` Ray Andrews
2015-01-02 17:03 ` Peter Stephenson
2015-01-02 18:42   ` Ray Andrews
2015-01-02 20:27     ` Lawrence Velázquez
2015-01-02 21:19       ` Ray Andrews
2015-01-02 21:24     ` Peter Stephenson
2015-01-02 21:36       ` Ray Andrews
2015-01-02 21:53       ` Ray Andrews
2015-01-02 22:21         ` Peter Stephenson
2015-01-02 23:42           ` Ray Andrews
2015-01-03  1:08             ` Ray Andrews
2015-01-03  5:03               ` Bart Schaefer
2015-01-03  5:53                 ` Ray Andrews
2015-01-03  7:17                   ` Bart Schaefer
2015-01-03 17:14                     ` Ray Andrews
2015-01-03 20:02                       ` Bart Schaefer
2015-01-03 21:13                         ` Ray Andrews
2015-01-03 21:42                           ` Peter Stephenson
2015-01-03 22:42                             ` Ray Andrews
2015-01-04  0:41                               ` Bart Schaefer
2015-01-04  3:45                                 ` Ray Andrews
2015-01-04  0:40                           ` Bart Schaefer
2015-01-04  3:35                             ` Ray Andrews
2015-01-04  8:31                               ` Bart Schaefer
2015-01-04 20:49                                 ` Ray Andrews
2015-01-05  1:34                                   ` Bart Schaefer
2015-01-05  2:28                                     ` Lawrence Velázquez
2015-01-05  4:24                                       ` Ray Andrews
2015-01-02 22:22         ` Bart Schaefer

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).