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