zsh-workers
 help / color / mirror / code / Atom feed
* :r modifier
@ 2000-12-12 16:57 Alexandre Duret-Lutz
  2000-12-13  4:15 ` Bart Schaefer
  0 siblings, 1 reply; 20+ messages in thread
From: Alexandre Duret-Lutz @ 2000-12-12 16:57 UTC (permalink / raw)
  To: zsh-workers

Hi people!

Is the following behaviour correct?

  ~ % echo $MAIL
  /home/adl/.procmail/spool/Inbox
  ~ % echo $MAIL:r $MAIL:e
  /home/adl/ procmail/spool/Inbox

I was expecting to get $MAIL:r equal to $MAIL and $MAIL:e empty.

The corresponding documentation reads as follow.

  r
       Remove a trailing suffix of the form `.XXX', leaving the basename.

  e
       Remove all but the suffix.

  t    
       Remove all leading pathname components, leaving the tail.

I find it quite confusing: I don't think :r leaves the basename,
but this is what :t does!

Ciao,
-- 
Alexandre Duret-Lutz


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

* Re: :r modifier
  2000-12-12 16:57 :r modifier Alexandre Duret-Lutz
@ 2000-12-13  4:15 ` Bart Schaefer
  2000-12-13 13:03   ` Alexandre Duret-Lutz
  0 siblings, 1 reply; 20+ messages in thread
From: Bart Schaefer @ 2000-12-13  4:15 UTC (permalink / raw)
  To: Alexandre Duret-Lutz, zsh-workers

On Dec 12,  5:57pm, Alexandre Duret-Lutz wrote:
} Subject: :r modifier
}
}   ~ % echo $MAIL
}   /home/adl/.procmail/spool/Inbox
}   ~ % echo $MAIL:r $MAIL:e
}   /home/adl/ procmail/spool/Inbox
} 
} I was expecting to get $MAIL:r equal to $MAIL and $MAIL:e empty.

Hrm.  Well, it's correct in so far as it goes; the :r and :e modifiers
appear to assume that they're already working on the result of :t, and
pay no attention at all to slash characters; they just find the rightmost
'.' and split on it.  They've worked this way for as long as zsh has
existed, AFAICT.

Tcsh behaves the same, so I don't expect we'll be changing it any time
soon.

-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com

Zsh: http://www.zsh.org | PHPerl Project: http://phperl.sourceforge.net   


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

* Re: :r modifier
  2000-12-13  4:15 ` Bart Schaefer
@ 2000-12-13 13:03   ` Alexandre Duret-Lutz
  2000-12-13 17:21     ` Bart Schaefer
  0 siblings, 1 reply; 20+ messages in thread
From: Alexandre Duret-Lutz @ 2000-12-13 13:03 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: zsh-workers

>>> "Bart" == Bart Schaefer <schaefer@candle.brasslantern.com> writes:

[...]

 Bart> Hrm.  Well, it's correct in so far as it goes; the :r and
 Bart> :e modifiers appear to assume that they're already
 Bart> working on the result of :t, and pay no attention at all
 Bart> to slash characters; they just find the rightmost '.' and
 Bart> split on it.  They've worked this way for as long as zsh
 Bart> has existed, AFAICT.

I believe this weakness makes :r error-prone (who *needs* to
ignore slashes?).  Now, if I want the slash-aware equivalant for
$MAIL:r, I have to write something like:

echo $MAIL:h/$MAIL:t:r
(this assumes that the dirname is non-empty).

 Bart> Tcsh behaves the same, so I don't expect we'll be
 Bart> changing it any time soon.

Oh, I didn't know this was a tcsh heritage (this can explain
lots of things :o)).  Anyway, my copy of tcsh does behave as *I*
expect on these modifiers (i.e. unlike Zsh). See:

% tcsh -f
> echo $MAIL
/home/adl/.procmail/spool/Inbox
> echo $MAIL:r $MAIL:e
/home/adl/.procmail/spool/Inbox
> echo $version
tcsh 6.09.03 (Astron) 2000-07-15 (i386-intel-linux) options 8b,nls,bye,al,ng,rh,nd,color

-- 
Alexandre Duret-Lutz


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

* Re: :r modifier
  2000-12-13 13:03   ` Alexandre Duret-Lutz
@ 2000-12-13 17:21     ` Bart Schaefer
  2000-12-13 19:21       ` Alexandre Duret-Lutz
  0 siblings, 1 reply; 20+ messages in thread
From: Bart Schaefer @ 2000-12-13 17:21 UTC (permalink / raw)
  To: zsh-workers

On Dec 13,  2:03pm, Alexandre Duret-Lutz wrote:
} Subject: Re: :r modifier
}
} >>> "Bart" == Bart Schaefer <schaefer@candle.brasslantern.com> writes:
} 
}  Bart> Tcsh behaves the same, so I don't expect we'll be
}  Bart> changing it any time soon.
} 
} Oh, I didn't know this was a tcsh heritage (this can explain
} lots of things :o)).

Actually, it's likely straight 4.[23] BSD csh heritage, not via tcsh, but
I don't have a copy of 4.x BSD sitting around to confirm that.

} I believe this weakness makes :r error-prone (who *needs* to
} ignore slashes?).

You're assuming that :r is used exclusively on unix file-paths and should
employ unix file-path semantics, but parameter values are just strings.

Suppose we change it to pay attention to slashes.  Does that mean that on
cygwin it should also pay attention to backslashes?  Do we need to teach
:h/:t about the leading-double-slash convention for some networked file
systems?

} [To get] $MAIL:r, I have to write something like:
} 
} echo $MAIL:h/$MAIL:t:r
} (this assumes that the dirname is non-empty).

There's always ${MAIL%.[^/]#} ...

-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com

Zsh: http://www.zsh.org | PHPerl Project: http://phperl.sourceforge.net   


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

* Re: :r modifier
  2000-12-13 17:21     ` Bart Schaefer
@ 2000-12-13 19:21       ` Alexandre Duret-Lutz
  2000-12-13 23:10         ` Thomas Köhler
  2000-12-14 13:00         ` Andrej Borsenkow
  0 siblings, 2 replies; 20+ messages in thread
From: Alexandre Duret-Lutz @ 2000-12-13 19:21 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: zsh-workers

>>> "Bart" == Bart Schaefer <schaefer@candle.brasslantern.com> writes:

[...]

 Bart> You're assuming that :r is used exclusively on unix
 Bart> file-paths and should employ unix file-path semantics,

Right, I'm shortsighted (didn't think at all about the 
non-unix world -- does it *really* exist? :o)).

 Bart> but parameter values are just strings.

But these modifers are somewhat useless on strings which are not
filenames, aren't they?  :h and :t are documented to works on
`pathnames'; my wish is to document :e and :r as working on
`filename extesions'.

 Bart> Suppose we change it to pay attention to slashes.  Does
 Bart> that mean that on cygwin it should also pay attention to
 Bart> backslashes?

I'd say yes: stick to the filename definition used on the host
whenever possible. (Here I'm feeling that I ask too much!)

 Bart> :Do we need to teach :h/:t about the leading-double-slash
 Bart> convention for some networked file systems?

I don't know, I never seen such file systems.  But I'm already 
confused by the current behiavor of :h on repeated slashes:

  % x=abc///def
  % echo $x:h
  abc//
  % echo $x:h:h
  abc/

(My dream is that repeated slashes would be treated as a single
slash; but I'm probably again assuming filesystem specific convention)

[...]

-- 
Alexandre Duret-Lutz


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

* Re: :r modifier
  2000-12-13 19:21       ` Alexandre Duret-Lutz
@ 2000-12-13 23:10         ` Thomas Köhler
  2000-12-14 13:00         ` Andrej Borsenkow
  1 sibling, 0 replies; 20+ messages in thread
From: Thomas Köhler @ 2000-12-13 23:10 UTC (permalink / raw)
  To: zsh-workers

[-- Attachment #1: Type: text/plain, Size: 1033 bytes --]

On Wed, Dec 13, 2000 at 08:21:17PM +0100,
Alexandre Duret-Lutz <duret_g@lrde.epita.fr> wrote:
> 
> >>> "Bart" == Bart Schaefer <schaefer@candle.brasslantern.com> writes:
> 
> [...]
>  Bart> You're assuming that :r is used exclusively on unix
>  Bart> file-paths and should employ unix file-path semantics,
> 
> Right, I'm shortsighted (didn't think at all about the 
> non-unix world -- does it *really* exist? :o)).

Well, yes. But I haven't seen a port of zsh to MVS or OS/390 so far ;)

[...]
> (My dream is that repeated slashes would be treated as a single
> slash; but I'm probably again assuming filesystem specific convention)

No, it's not filesystem specific. It might be Unix specific, though. ;)

Ciao,
Thomas

-- 
 Thomas Köhler Email:   jean-luc@picard.franken.de     | LCARS - Linux
     <><        WWW:     http://jeanluc-picard.de      | for Computers
                IRC:             jeanluc               | on All Real
               PGP public key available from Homepage! | Starships

[-- Attachment #2: Type: application/pgp-signature, Size: 232 bytes --]

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

* RE: :r modifier
  2000-12-13 19:21       ` Alexandre Duret-Lutz
  2000-12-13 23:10         ` Thomas Köhler
@ 2000-12-14 13:00         ` Andrej Borsenkow
  2000-12-14 14:14           ` Alexandre Duret-Lutz
  1 sibling, 1 reply; 20+ messages in thread
From: Andrej Borsenkow @ 2000-12-14 13:00 UTC (permalink / raw)
  To: Alexandre Duret-Lutz; +Cc: zsh-workers


>
>  Bart> :Do we need to teach :h/:t about the leading-double-slash
>  Bart> convention for some networked file systems?
>
> I don't know, I never seen such file systems.

May be, you have heard about one. It is called Windows and (sometimes) runs on
x86 PC-compatible systems :-)

I checked bash and it behaves the same as zsh. On Cygwin bash is just as
ignorant about special Win32 names as zsh is. It does not mean we should
follow the suite - but, at least, we are in good company as it stand now :))

-andrej


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

* Re: :r modifier
  2000-12-14 13:00         ` Andrej Borsenkow
@ 2000-12-14 14:14           ` Alexandre Duret-Lutz
  2000-12-14 14:43             ` Andrej Borsenkow
  0 siblings, 1 reply; 20+ messages in thread
From: Alexandre Duret-Lutz @ 2000-12-14 14:14 UTC (permalink / raw)
  To: Andrej Borsenkow; +Cc: zsh-workers

>>> "Andrej" == Andrej Borsenkow <Andrej.Borsenkow@mow.siemens.ru> writes:

 >> 
 Bart> :Do we need to teach :h/:t about the leading-double-slash
 Bart> convention for some networked file systems?
 >> 
 >> I don't know, I never seen such file systems.

 Andrej> May be, you have heard about one. It is called Windows
 Andrej> and (sometimes) runs on x86 PC-compatible systems :-)

:o)

By the meantime I have been pointed to the Texinfo documentation
of Autoconf (>=2.49a) which reads as follow.

`dirname'
     Not all hosts have `dirname', but it is reasonably easy to
     emulate, e.g.:
          
          dir=`expr "x$file" : 'x\(.*\)/[^/]*' \|
                    '.'      : '.'

     But there are a few subtilities, e.g., under UN*X, should `//1'
     give `/'?  Paul Eggert answers:
          
          No, under some older flavors of Unix, leading `//' is a
          special path name: it refers to a "super-root" and is used to
          access other machines' files.  Leading `///', `////', etc.
          are equivalent to `/'; but leading `//' is special.  I think
          this tradition started with Apollo Domain/OS, an OS that is
          still in use on some older hosts.
          
          POSIX.2 allows but does not require the special treatment for
          `//'.  It says that the behavior of dirname on path names of
          the form `//([^/]+/*)?'  is implementation defined.  In these
          cases, GNU `dirname' returns `/', but it's more portable to
          return `//' as this works even on those older flavors of Unix.
          
          I have heard rumors that this special treatment of `//' may be
          dropped in future versions of POSIX, but for now it's still
          the standard.

 Andrej> I checked bash and it behaves the same as zsh. 

Huh?  You aren't speaking about :h here, are you?

 Andrej> On Cygwin bash is just as ignorant about special Win32
 Andrej> names as zsh is. It does not mean we should follow the
 Andrej> suite - but, at least, we are in good company as it
 Andrej> stand now :))
-- 
Alexandre Duret-Lutz


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

* RE: :r modifier
  2000-12-14 14:14           ` Alexandre Duret-Lutz
@ 2000-12-14 14:43             ` Andrej Borsenkow
  2000-12-14 18:18               ` PATCH: " Alexandre Duret-Lutz
  0 siblings, 1 reply; 20+ messages in thread
From: Andrej Borsenkow @ 2000-12-14 14:43 UTC (permalink / raw)
  To: Alexandre Duret-Lutz; +Cc: zsh-workers

>
>           No, under some older flavors of Unix, leading `//' is a
>           special path name: it refers to a "super-root" and is used to
>           access other machines' files.  Leading `///', `////', etc.
>           are equivalent to `/'; but leading `//' is special.  I think
>           this tradition started with Apollo Domain/OS, an OS that is
>           still in use on some older hosts.
>

I really liked Apollo Domain/OS. It was nice system, with transparent
networking, remote execution and file system. You could start program on a
second system with input from local (your own) and let output be created on a
third.

>           POSIX.2 allows but does not require the special treatment for
>           `//'.  It says that the behavior of dirname on path names of
>           the form `//([^/]+/*)?'  is implementation defined.  In these
>           cases, GNU `dirname' returns `/', but it's more portable to
>           return `//' as this works even on those older flavors of Unix.
>

Yep, POSIX is very careful to not require changing of existing behaviour. It
prefers to leave most things as implementation defined.

>
>  Andrej> I checked bash and it behaves the same as zsh.
>
> Huh?  You aren't speaking about :h here, are you?
>

I am speaking about :r and :e. What so special about :h? Here is bash:

mw1g017@MW1G17C ~
$ ls  /bar/bar.baz/baz
ls: /bar/bar.baz/baz: No such file or directory

mw1g017@MW1G17C ~
$ ls !!:1:r
ls /bar/bar
ls: /bar/bar: No such file or directory

mw1g017@MW1G17C ~
$ ls  /bar/bar.baz/baz
ls: /bar/bar.baz/baz: No such file or directory

mw1g017@MW1G17C ~
$ ls !!:1:e
ls .baz/baz
ls: .baz/baz: No such file or directory

Hmm ... with :e modifier bash preserves dot and zsh not. csh here behaves as
zsh. Incidentally, csh here does treat strings like Alexander would like it:

itsrm2% !21
echo /bar/bar.baz/baz
/bar/bar.baz/baz
itsrm2% echo !!:1:r
echo /bar/bar.baz/baz
/bar/bar.baz/baz
itsrm2% echo !!:1:e
echo

-andrej


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

* PATCH: Re: :r modifier
  2000-12-14 14:43             ` Andrej Borsenkow
@ 2000-12-14 18:18               ` Alexandre Duret-Lutz
  2000-12-14 23:52                 ` Geoff Wing
                                   ` (2 more replies)
  0 siblings, 3 replies; 20+ messages in thread
From: Alexandre Duret-Lutz @ 2000-12-14 18:18 UTC (permalink / raw)
  To: Andrej Borsenkow; +Cc: zsh-workers

>>> "Andrej" == Andrej Borsenkow <Andrej.Borsenkow@mow.siemens.ru> writes:

[...]

 Andrej> I checked bash and it behaves the same as zsh.
 >> 
 >> Huh?  You aren't speaking about :h here, are you?
 >> 

 Andrej> I am speaking about :r and :e. What so special about
 Andrej> :h? 

Nothing, please dismiss my question...

[...]

Here is my proposal.  The following patch modifies :r, :e, :h, 
and :t to behave as I expect them to.  My point for doing so is that
  1) this seems natural and more useful (from the user point of 
     view) 
  2) that should not break anything because these modifiers are 
     usually used in places where you won't have any surprise
     with the old behavior  (e.g. you use :r when you *know* 
     that there is an extenstion to delete) and the behavior 
     is not changed in those places.

I don't know if you consider the compatibility with other shells
important on this point. I must confess I don't really do :),
the overall semantic is still the same, but at least there is no 
surprises in the results.

Leading double-slashes are handled, and backslashes too (under
Cygwin only).   remtpath() is also assuming that leading `//', 
`/\\', `\\/', and `\\\\' are equivalent under Cygwin, is this true?


Index: Doc/Zsh/expn.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/expn.yo,v
retrieving revision 1.24
diff -u -r1.24 expn.yo
--- Doc/Zsh/expn.yo	2000/10/05 08:41:37	1.24
+++ Doc/Zsh/expn.yo	2000/12/14 17:38:40
@@ -202,13 +202,15 @@
 
 startitem()
 item(tt(h))(
-Remove a trailing pathname component, leaving the head.
+Remove a trailing pathname component, leaving the head.  This works
+like `tt(dirname)'.
 )
 item(tt(r))(
-Remove a trailing suffix of the form `tt(.)var(xxx)', leaving the basename.
+Remove a filename extension of the form `tt(.)var(xxx)', leaving
+the root name.
 )
 item(tt(e))(
-Remove all but the suffix.
+Remove all but the extension.
 )
 item(tt(t))(
 Remove all leading pathname components, leaving the tail.
Index: Src/hist.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/hist.c,v
retrieving revision 1.20
diff -u -r1.20 hist.c
--- Src/hist.c	2000/10/21 03:15:36	1.20
+++ Src/hist.c	2000/12/14 17:38:40
@@ -1334,28 +1334,43 @@
 int
 remtpath(char **junkptr)
 {
-    char *str = *junkptr, *remcut;
+    char *str = strend(*junkptr);
 
-    if ((remcut = strrchr(str, '/'))) {
-	if (str != remcut)
-	    *remcut = '\0';
-	else
-	    str[1] = '\0';
-	return 1;
+    /* ignore trailing slashes */
+    while (str >= *junkptr && IS_DIRSEP(*str))
+	--str;
+    /* skip filename */
+    while (str >= *junkptr && !IS_DIRSEP(*str))
+	--str;
+    if (str < *junkptr)
+	return 0;
+    /* repeated slashes are considered like a single slash */
+    while (str > *junkptr && IS_DIRSEP(str[-1]))
+	--str;
+    /* never erase the root slash */
+    if (str == *junkptr) {
+	++str;
+	/* Leading doubled slashes (`//') have a special meaning on cygwin
+	   and some old flavor of UNIX, so we do not assimilate them to
+	   a single slashes.  However a greater number is ok to squeeze. */
+	if (IS_DIRSEP(*str) && !IS_DIRSEP(str[1]))
+	    ++str;
     }
-    return 0;
+    *str = '\0';
+    return 1;
 }
 
 /**/
 int
 remtext(char **junkptr)
 {
-    char *str = *junkptr, *remcut;
+    char *str;
 
-    if ((remcut = strrchr(str, '.')) && remcut != str) {
-	*remcut = '\0';
-	return 1;
-    }
+    for (str = strend(*junkptr); str >= *junkptr && !IS_DIRSEP(*str); --str)
+	if (*str == '.') {
+	    *str = '\0';
+	    return 1;
+	}
     return 0;
 }
 
@@ -1363,12 +1378,13 @@
 int
 rembutext(char **junkptr)
 {
-    char *str = *junkptr, *remcut;
+    char *str;
 
-    if ((remcut = strrchr(str, '.')) && remcut != str) {
-	*junkptr = dupstring(remcut + 1);	/* .xx or xx? */
-	return 1;
-    }
+    for (str = strend(*junkptr); str >= *junkptr && !IS_DIRSEP(*str); --str)
+	if (*str == '.') {
+	    *junkptr = dupstring(str + 1); /* .xx or xx? */
+	    return 1;
+	}
     return 0;
 }
 
@@ -1376,13 +1392,14 @@
 mod_export int
 remlpaths(char **junkptr)
 {
-    char *str = *junkptr, *remcut;
+    char *str = *junkptr + strlen (*junkptr) - 1;
 
-    if ((remcut = strrchr(str, '/'))) {
-	*remcut = '\0';
-	*junkptr = dupstring(remcut + 1);
-	return 1;
-    }
+    for (str = strend(*junkptr); str >= *junkptr; --str)
+	if (IS_DIRSEP(*str)) {
+	    *str = '\0';
+	    *junkptr = dupstring(str + 1);
+	    return 1;
+	}
     return 0;
 }
 
Index: Src/string.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/string.c,v
retrieving revision 1.3
diff -u -r1.3 string.c
--- Src/string.c	2000/09/27 19:31:48	1.3
+++ Src/string.c	2000/12/14 17:38:40
@@ -79,7 +79,7 @@
     char *ptr;
     size_t l1 = strlen(s1);
     size_t l2 = strlen(s2);
-    
+
     ptr = (char *)zhalloc(l1 + l2 + strlen(s3) + 1);
     strcpy(ptr, s1);
     strcpy(ptr + l1, s2);
@@ -132,4 +132,16 @@
 appstr(char *base, char const *append)
 {
     return strcat(realloc(base, strlen(base) + strlen(append) + 1), append);
+}
+
+/* Return a pointer to the last character of a string,
+   unless the string is empty. */
+
+/**/
+mod_export char *
+strend(char *str)
+{
+    if (*str == '\0')
+	return str;
+    return str + strlen (str) - 1;
 }
Index: Src/system.h
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/system.h,v
retrieving revision 1.11
diff -u -r1.11 system.h
--- Src/system.h	2000/09/18 14:22:48	1.11
+++ Src/system.h	2000/12/14 17:38:41
@@ -657,3 +657,9 @@
 #ifndef MAILDIR_SUPPORT
 #define mailstat(X,Y) stat(X,Y)
 #endif
+
+#ifdef __CYGWIN__
+# define IS_DIRSEP(c) ((c) == '/' || (c) == '\\')
+#else
+# define IS_DIRSEP(c) ((c) == '/')
+#endif

-- 
Alexandre Duret-Lutz


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

* Re: PATCH: Re: :r modifier
  2000-12-14 18:18               ` PATCH: " Alexandre Duret-Lutz
@ 2000-12-14 23:52                 ` Geoff Wing
  2000-12-15 10:22                   ` Alexandre Duret-Lutz
  2000-12-15 10:27                 ` Peter Stephenson
  2000-12-15 11:53                 ` Alexandre Duret-Lutz
  2 siblings, 1 reply; 20+ messages in thread
From: Geoff Wing @ 2000-12-14 23:52 UTC (permalink / raw)
  To: zsh-workers

Alexandre Duret-Lutz <duret_g@lrde.epita.fr> typed:
:>>> "Andrej" == Andrej Borsenkow <Andrej.Borsenkow@mow.siemens.ru> writes:
:Here is my proposal.  The following patch modifies :r, :e, :h, 
:and :t to behave as I expect them to.  My point for doing so is that
:  1) this seems natural and more useful (from the user point of 
:     view) 

?  I don't expect :r to behave that way but I don't really use it
much these days so maybe my objections have little weight.

: item(tt(r))(
:-Remove a trailing suffix of the form `tt(.)var(xxx)', leaving the basename.
:+Remove a filename extension of the form `tt(.)var(xxx)', leaving
:+the root name.
: )

I'm not sure the wording has cleared it up.  The previous wording of
"trailing suffix" [what's a non-trailing suffix? :-)] wasn't that
good but what's the "root name"?  (Can't think of anything better
at the moment, sorry).

Regards,
-- 
Geoff Wing : <gcw@pobox.com>
Rxvt Stuff : <gcw@rxvt.org>
Zsh Stuff  : <gcw@zsh.org>


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

* Re: PATCH: Re: :r modifier
  2000-12-14 23:52                 ` Geoff Wing
@ 2000-12-15 10:22                   ` Alexandre Duret-Lutz
  2000-12-15 10:58                     ` Geoff Wing
  0 siblings, 1 reply; 20+ messages in thread
From: Alexandre Duret-Lutz @ 2000-12-15 10:22 UTC (permalink / raw)
  To: mason; +Cc: zsh-workers

>>> "Geoff" == Geoff Wing <mason@primenet.com.au> writes:

[...]

 Geoff> ?  I don't expect :r to behave that way but I don't really use it
 Geoff> much these days so maybe my objections have little weight.

Do you mean you prefer the current behavior or would like another?

: item(tt(r))(
:-Remove a trailing suffix of the form `tt(.)var(xxx)', leaving the basename.
:+Remove a filename extension of the form `tt(.)var(xxx)', leaving
:+the root name.
: )

 Geoff> I'm not sure the wording has cleared it up.  The previous wording of
 Geoff> "trailing suffix" [what's a non-trailing suffix? :-)] 

:o)

 Geoff> wasn't that good but what's the "root name"?  (Can't
 Geoff> think of anything better at the moment, sorry).

I can't think of anything better either.  This is the
description used in the tcsh manual.  The original `basename' is
clearly misleading; `root name' may require a definition, or
else the `leaving the root name' part can be removed.  But at
least `root name' offers a mnemonic mean to remember what
thoses modifiers do (r-root e-extension h-head t-tail).

-- 
Alexandre Duret-Lutz


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

* Re: PATCH: Re: :r modifier
  2000-12-14 18:18               ` PATCH: " Alexandre Duret-Lutz
  2000-12-14 23:52                 ` Geoff Wing
@ 2000-12-15 10:27                 ` Peter Stephenson
  2000-12-15 21:30                   ` Thomas Köhler
  2000-12-15 11:53                 ` Alexandre Duret-Lutz
  2 siblings, 1 reply; 20+ messages in thread
From: Peter Stephenson @ 2000-12-15 10:27 UTC (permalink / raw)
  To: Zsh hackers list

Alexandre Duret-Lutz <duret_g@lrde.epita.fr> wrote:
> Here is my proposal.  The following patch modifies :r, :e, :h, 
> and :t to behave as I expect them to.

I've got no objection to this (assuming, of course, it actually does what I
think, I haven't actually tried ity et).  It's a little foolerproof than
the previous version.... while we're waiting for the back port to VMS.  As
Alexandre says, I don't think you had any business assuming it *would*
ignore slashes with the old version; I certainly never knew.

(Maybe we could even make a version for VM/CMS where the string `191' is
special...)

-- 
Peter Stephenson <pws@csr.com>                  Software Engineer
Cambridge Silicon Radio, Unit 300, Science Park, Milton Road,
Cambridge, CB4 0XL, UK                          Tel: +44 (0)1223 392070


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

* Re: PATCH: Re: :r modifier
  2000-12-15 10:22                   ` Alexandre Duret-Lutz
@ 2000-12-15 10:58                     ` Geoff Wing
  0 siblings, 0 replies; 20+ messages in thread
From: Geoff Wing @ 2000-12-15 10:58 UTC (permalink / raw)
  To: Alexandre Duret-Lutz; +Cc: Zsh Hackers

Alexandre Duret-Lutz wrote about Re: PATCH: Re: :r modifier:
:>>> "Geoff" == Geoff Wing <mason@primenet.com.au> writes:
:Do you mean you prefer the current behavior or would like another?

I'm used to the current behaviour but don't take my objections too
seriously.  I'm now leaning heavily towards your version's behaviour.
I guess I can learn some new skills :-)

% export FOO='foo.bar/baz'
% tcsh -fc 'echo $FOO:r'
foo.bar/baz
% csh -fc 'echo $FOO:r'
foo.bar/baz
% bash -fc 'echo $FOO:r ${FOO:r}'
foo.bar/baz:r foo.bar/baz
% zsh -fc 'echo $FOO:r'
foo
% zsh-alexandre-patch -fc 'echo $FOO:r'
foo.bar/baz

:: item(tt(r))(
::-Remove a trailing suffix of the form `tt(.)var(xxx)', leaving the basename.
::+Remove a filename extension of the form `tt(.)var(xxx)', leaving
::+the root name.
:: )
: Geoff> wasn't that good but what's the "root name"?  (Can't
: Geoff> think of anything better at the moment, sorry).

My csh manual says:
 "Remove a trailing `.xxx' component, leaving the root name."
so I guess it has precedent.

:But at
:least `root name' offers a mnemonic mean to remember what
:thoses modifiers do (r-root e-extension h-head t-tail).

Yes, I suppose "root name" should be sufficient and I don't really
think we need to explain what it means (nobody else does).

Regards,
-- 
Geoff Wing : <gcw@pobox.com>
Rxvt Stuff : <gcw@rxvt.org>
Zsh Stuff  : <gcw@zsh.org>


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

* Re: PATCH: Re: :r modifier
  2000-12-14 18:18               ` PATCH: " Alexandre Duret-Lutz
  2000-12-14 23:52                 ` Geoff Wing
  2000-12-15 10:27                 ` Peter Stephenson
@ 2000-12-15 11:53                 ` Alexandre Duret-Lutz
  2001-02-14 18:34                   ` Alexandre Duret-Lutz
  2001-02-19 10:32                   ` Peter Stephenson
  2 siblings, 2 replies; 20+ messages in thread
From: Alexandre Duret-Lutz @ 2000-12-15 11:53 UTC (permalink / raw)
  To: zsh-workers

>>> "adl" == Alexandre Duret-Lutz <duret_g@lrde.epita.fr> writes:

[...]

 adl> Here is my proposal.  

It was broken (since :h ignore trailing slashes, :t should to
likewise).  I have also modified :h to works on filenames without
pathname: `dirname a.b' return `.', so :h does that too, the
point is that $x:h/$x:t should designate the same file as
$x (as `dirname $x`/`basename $x` would), and $x:r.$x:e likewise.

Here are the results on some error-prone inputs:

% for x in a.b//c //e ///g.h /i/j/k/ l.m ..
for> print "$x\t root=$x:r\text=$x:e,\thead=$x:h,\ttail=$x:t"
a.b//c   root=a.b//c    ext=,   head=a.b,       tail=c
//e      root=//e       ext=,   head=//,        tail=e
///g.h   root=///g      ext=h,  head=/, tail=g.h
/i/j/k/  root=/i/j/k/   ext=,   head=/i/j,      tail=k
l.m      root=l ext=m,  head=., tail=l.m
..       root=. ext=,   head=., tail=..

For comparison, here is tcsh:

12> foreach x ( a.b//c //e ///g.h /i/j/k/ l.m )
foreach? echo "$x\t root=$x:r\text=$x:e,\thead=$x:h,\ttail=$x:t"
foreach? end
a.b//c   root=a.b//c    ext=,   head=a.b/,      tail=c
//e      root=//e       ext=,   head=/, tail=e
///g.h   root=///g      ext=h,  head=//,        tail=g.h
/i/j/k/  root=/i/j/k/   ext=,   head=/i/j/k,    tail=
l.m      root=l ext=m,  head=l.m,       tail=l.m

and unpatched zsh:
% for x in a.b//c //e ///g.h /i/j/k/ l.m ..
for> print "$x\t root=$x:r\text=$x:e,\thead=$x:h,\ttail=$x:t"
a.b//c   root=a ext=b//c,       head=a.b/,      tail=c
//e      root=//e       ext=//e,        head=/, tail=e
///g.h   root=///g      ext=h,  head=//,        tail=g.h
/i/j/k/  root=/i/j/k/   ext=/i/j/k/,    head=/i/j/k,    tail=
l.m      root=l ext=m,  head=l.m,       tail=l.m
..       root=. ext=,   head=..,        tail=..


Index: Doc/Zsh/expn.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/expn.yo,v
retrieving revision 1.24
diff -u -r1.24 expn.yo
--- Doc/Zsh/expn.yo	2000/10/05 08:41:37	1.24
+++ Doc/Zsh/expn.yo	2000/12/15 11:30:35
@@ -202,16 +202,19 @@
 
 startitem()
 item(tt(h))(
-Remove a trailing pathname component, leaving the head.
+Remove a trailing pathname component, leaving the head.  This works
+like `tt(dirname)'.
 )
 item(tt(r))(
-Remove a trailing suffix of the form `tt(.)var(xxx)', leaving the basename.
+Remove a filename extension of the form `tt(.)var(xxx)', leaving
+the root name.
 )
 item(tt(e))(
-Remove all but the suffix.
+Remove all but the extension.
 )
 item(tt(t))(
-Remove all leading pathname components, leaving the tail.
+Remove all leading pathname components, leaving the tail.  This works
+like `tt(basename)'.
 )
 item(tt(p))(
 Print the new command but do not execute it.  Only works with history
Index: Src/hist.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/hist.c,v
retrieving revision 1.20
diff -u -r1.20 hist.c
--- Src/hist.c	2000/10/21 03:15:36	1.20
+++ Src/hist.c	2000/12/15 11:30:36
@@ -1334,28 +1334,45 @@
 int
 remtpath(char **junkptr)
 {
-    char *str = *junkptr, *remcut;
+    char *str = strend(*junkptr);
 
-    if ((remcut = strrchr(str, '/'))) {
-	if (str != remcut)
-	    *remcut = '\0';
-	else
-	    str[1] = '\0';
-	return 1;
+    /* ignore trailing slashes */
+    while (str >= *junkptr && IS_DIRSEP(*str))
+	--str;
+    /* skip filename */
+    while (str >= *junkptr && !IS_DIRSEP(*str))
+	--str;
+    if (str < *junkptr) {
+	*junkptr = dupstring (".");
+	return 0;
     }
-    return 0;
+    /* repeated slashes are considered like a single slash */
+    while (str > *junkptr && IS_DIRSEP(str[-1]))
+	--str;
+    /* never erase the root slash */
+    if (str == *junkptr) {
+	++str;
+	/* Leading doubled slashes (`//') have a special meaning on cygwin
+	   and some old flavor of UNIX, so we do not assimilate them to
+	   a single slash.  However a greater number is ok to squeeze. */
+	if (IS_DIRSEP(*str) && !IS_DIRSEP(str[1]))
+	    ++str;
+    }
+    *str = '\0';
+    return 1;
 }
 
 /**/
 int
 remtext(char **junkptr)
 {
-    char *str = *junkptr, *remcut;
+    char *str;
 
-    if ((remcut = strrchr(str, '.')) && remcut != str) {
-	*remcut = '\0';
-	return 1;
-    }
+    for (str = strend(*junkptr); str >= *junkptr && !IS_DIRSEP(*str); --str)
+	if (*str == '.') {
+	    *str = '\0';
+	    return 1;
+	}
     return 0;
 }
 
@@ -1363,12 +1380,15 @@
 int
 rembutext(char **junkptr)
 {
-    char *str = *junkptr, *remcut;
+    char *str;
 
-    if ((remcut = strrchr(str, '.')) && remcut != str) {
-	*junkptr = dupstring(remcut + 1);	/* .xx or xx? */
-	return 1;
-    }
+    for (str = strend(*junkptr); str >= *junkptr && !IS_DIRSEP(*str); --str)
+	if (*str == '.') {
+	    *junkptr = dupstring(str + 1); /* .xx or xx? */
+	    return 1;
+	}
+    /* no extension */
+    *junkptr = dupstring ("");
     return 0;
 }
 
@@ -1376,13 +1396,20 @@
 mod_export int
 remlpaths(char **junkptr)
 {
-    char *str = *junkptr, *remcut;
+    char *str = strend(*junkptr);
 
-    if ((remcut = strrchr(str, '/'))) {
-	*remcut = '\0';
-	*junkptr = dupstring(remcut + 1);
-	return 1;
-    }
+    if (IS_DIRSEP(*str)) {
+	/* remove trailing slashes */
+	while (str >= *junkptr && IS_DIRSEP(*str))
+	    --str;
+	str[1] = '\0';
+    }
+    for (; str >= *junkptr; --str)
+	if (IS_DIRSEP(*str)) {
+	    *str = '\0';
+	    *junkptr = dupstring(str + 1);
+	    return 1;
+	}
     return 0;
 }
 
Index: Src/string.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/string.c,v
retrieving revision 1.3
diff -u -r1.3 string.c
--- Src/string.c	2000/09/27 19:31:48	1.3
+++ Src/string.c	2000/12/15 11:30:36
@@ -79,7 +79,7 @@
     char *ptr;
     size_t l1 = strlen(s1);
     size_t l2 = strlen(s2);
-    
+
     ptr = (char *)zhalloc(l1 + l2 + strlen(s3) + 1);
     strcpy(ptr, s1);
     strcpy(ptr + l1, s2);
@@ -132,4 +132,16 @@
 appstr(char *base, char const *append)
 {
     return strcat(realloc(base, strlen(base) + strlen(append) + 1), append);
+}
+
+/* Return a pointer to the last character of a string,
+   unless the string is empty. */
+
+/**/
+mod_export char *
+strend(char *str)
+{
+    if (*str == '\0')
+	return str;
+    return str + strlen (str) - 1;
 }
Index: Src/system.h
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/system.h,v
retrieving revision 1.11
diff -u -r1.11 system.h
--- Src/system.h	2000/09/18 14:22:48	1.11
+++ Src/system.h	2000/12/15 11:30:37
@@ -657,3 +657,9 @@
 #ifndef MAILDIR_SUPPORT
 #define mailstat(X,Y) stat(X,Y)
 #endif
+
+#ifdef __CYGWIN__
+# define IS_DIRSEP(c) ((c) == '/' || (c) == '\\')
+#else
+# define IS_DIRSEP(c) ((c) == '/')
+#endif

-- 
Alexandre Duret-Lutz


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

* Re: PATCH: Re: :r modifier
  2000-12-15 10:27                 ` Peter Stephenson
@ 2000-12-15 21:30                   ` Thomas Köhler
  0 siblings, 0 replies; 20+ messages in thread
From: Thomas Köhler @ 2000-12-15 21:30 UTC (permalink / raw)
  To: Zsh hackers list

[-- Attachment #1: Type: text/plain, Size: 1127 bytes --]

On Fri, Dec 15, 2000 at 10:27:38AM +0000,
Peter Stephenson <pws@csr.com> wrote:
> 
> Alexandre Duret-Lutz <duret_g@lrde.epita.fr> wrote:
> > Here is my proposal.  The following patch modifies :r, :e, :h, 
> > and :t to behave as I expect them to.
> 
> I've got no objection to this (assuming, of course, it actually does what I
> think, I haven't actually tried ity et).  It's a little foolerproof than
> the previous version.... while we're waiting for the back port to VMS.  As
> Alexandre says, I don't think you had any business assuming it *would*
> ignore slashes with the old version; I certainly never knew.
> 
> (Maybe we could even make a version for VM/CMS where the string `191' is
> special...)

Now, that one would be cool :-)

And, btw, ... Tab-completion for 3270 terminals anyone? :-)

Ciao,
Thomas

-- 
 Thomas Köhler Email:   jean-luc@picard.franken.de     | LCARS - Linux
     <><        WWW:     http://jeanluc-picard.de      | for Computers
                IRC:             jeanluc               | on All Real
               PGP public key available from Homepage! | Starships

[-- Attachment #2: Type: application/pgp-signature, Size: 232 bytes --]

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

* Re: PATCH: Re: :r modifier
  2000-12-15 11:53                 ` Alexandre Duret-Lutz
@ 2001-02-14 18:34                   ` Alexandre Duret-Lutz
  2001-02-14 18:40                     ` Peter Stephenson
  2001-02-19 10:32                   ` Peter Stephenson
  1 sibling, 1 reply; 20+ messages in thread
From: Alexandre Duret-Lutz @ 2001-02-14 18:34 UTC (permalink / raw)
  To: zsh-workers

Hi

I'd hate to beat a dead horse, but it's not clear to me 
whether 13280 has been rejected or just forgotten.

Thanks!
-- 
Alexandre Duret-Lutz


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

* Re: PATCH: Re: :r modifier
  2001-02-14 18:34                   ` Alexandre Duret-Lutz
@ 2001-02-14 18:40                     ` Peter Stephenson
  2001-02-14 19:44                       ` Bart Schaefer
  0 siblings, 1 reply; 20+ messages in thread
From: Peter Stephenson @ 2001-02-14 18:40 UTC (permalink / raw)
  To: Zsh hackers list

Alexandre Duret-Lutz wrote:
> I'd hate to beat a dead horse, but it's not clear to me 
> whether 13280 has been rejected or just forgotten.

That's because it's not clear to anyone.  I don't have any objections, does
anyone know if they are relying on the old (somewhat unexpected) behaviour?

-- 
Peter Stephenson <pws@csr.com>                  Software Engineer
Cambridge Silicon Radio, Unit 300, Science Park, Milton Road,
Cambridge, CB4 0XL, UK                          Tel: +44 (0)1223 392070


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

* Re: PATCH: Re: :r modifier
  2001-02-14 18:40                     ` Peter Stephenson
@ 2001-02-14 19:44                       ` Bart Schaefer
  0 siblings, 0 replies; 20+ messages in thread
From: Bart Schaefer @ 2001-02-14 19:44 UTC (permalink / raw)
  To: Zsh hackers list

On Feb 14,  6:40pm, Peter Stephenson wrote:
> Subject: Re: PATCH: Re: :r modifier
> Alexandre Duret-Lutz wrote:
> > I'd hate to beat a dead horse, but it's not clear to me 
> > whether 13280 has been rejected or just forgotten.
> 
> That's because it's not clear to anyone. I don't have any objections,
> does anyone know if they are relying on the old (somewhat unexpected)
> behaviour?

I don't believe I'm relying on the old behavior; I have a certain sort
of nostalgia for it because that's how the original csh behaves, but I
suppose we're long beyond worrying about compatibility with *that*.


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

* Re: PATCH: Re: :r modifier
  2000-12-15 11:53                 ` Alexandre Duret-Lutz
  2001-02-14 18:34                   ` Alexandre Duret-Lutz
@ 2001-02-19 10:32                   ` Peter Stephenson
  1 sibling, 0 replies; 20+ messages in thread
From: Peter Stephenson @ 2001-02-19 10:32 UTC (permalink / raw)
  To: Zsh hackers list

> >>> "adl" == Alexandre Duret-Lutz <duret_g@lrde.epita.fr> writes:
>
> Here are the results on some error-prone inputs:
> 
> % for x in a.b//c //e ///g.h /i/j/k/ l.m ..
> for> print "$x\t root=$x:r\text=$x:e,\thead=$x:h,\ttail=$x:t"
> a.b//c   root=a.b//c    ext=,   head=a.b,       tail=c
> //e      root=//e       ext=,   head=//,        tail=e
> ///g.h   root=///g      ext=h,  head=/, tail=g.h
> /i/j/k/  root=/i/j/k/   ext=,   head=/i/j,      tail=k
> l.m      root=l ext=m,  head=., tail=l.m
> ..       root=. ext=,   head=., tail=..
>
> and unpatched zsh:
>
> % for x in a.b//c //e ///g.h /i/j/k/ l.m ..
> for> print "$x\t root=$x:r\text=$x:e,\thead=$x:h,\ttail=$x:t"
> a.b//c   root=a ext=b//c,       head=a.b/,      tail=c
> //e      root=//e       ext=//e,        head=/, tail=e
> ///g.h   root=///g      ext=h,  head=//,        tail=g.h
> /i/j/k/  root=/i/j/k/   ext=/i/j/k/,    head=/i/j/k,    tail=
> l.m      root=l ext=m,  head=l.m,       tail=l.m
> ..       root=. ext=,   head=..,        tail=..

I've just committed Alexandre's patch, with the effects shown.  Watch out
for unexpected results from colon modifiers.  With a bit of luck, in most
places where they are used the new behaviour should actually reduce
unexpected results.  Andrej:  note that this uses `\\' as well as `/' for
paths in Cygwin.

-- 
Peter Stephenson <pws@csr.com>                  Software Engineer
Cambridge Silicon Radio, Unit 300, Science Park, Milton Road,
Cambridge, CB4 0XL, UK                          Tel: +44 (0)1223 392070


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

end of thread, other threads:[~2001-02-19 10:32 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-12-12 16:57 :r modifier Alexandre Duret-Lutz
2000-12-13  4:15 ` Bart Schaefer
2000-12-13 13:03   ` Alexandre Duret-Lutz
2000-12-13 17:21     ` Bart Schaefer
2000-12-13 19:21       ` Alexandre Duret-Lutz
2000-12-13 23:10         ` Thomas Köhler
2000-12-14 13:00         ` Andrej Borsenkow
2000-12-14 14:14           ` Alexandre Duret-Lutz
2000-12-14 14:43             ` Andrej Borsenkow
2000-12-14 18:18               ` PATCH: " Alexandre Duret-Lutz
2000-12-14 23:52                 ` Geoff Wing
2000-12-15 10:22                   ` Alexandre Duret-Lutz
2000-12-15 10:58                     ` Geoff Wing
2000-12-15 10:27                 ` Peter Stephenson
2000-12-15 21:30                   ` Thomas Köhler
2000-12-15 11:53                 ` Alexandre Duret-Lutz
2001-02-14 18:34                   ` Alexandre Duret-Lutz
2001-02-14 18:40                     ` Peter Stephenson
2001-02-14 19:44                       ` Bart Schaefer
2001-02-19 10:32                   ` Peter Stephenson

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).