zsh-workers
 help / color / mirror / code / Atom feed
From: Alexandre Duret-Lutz <duret_g@lrde.epita.fr>
To: "Andrej Borsenkow" <Andrej.Borsenkow@mow.siemens.ru>
Cc: <zsh-workers@sunsite.auc.dk>
Subject: PATCH: Re: :r modifier
Date: 14 Dec 2000 19:18:59 +0100	[thread overview]
Message-ID: <mvbzohy6f3g.fsf@phobos.lrde.epita.fr> (raw)
In-Reply-To: "Andrej Borsenkow"'s message of "Thu, 14 Dec 2000 17:43:11 +0300"

>>> "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


  reply	other threads:[~2000-12-14 18:16 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2000-12-12 16:57 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               ` Alexandre Duret-Lutz [this message]
2000-12-14 23:52                 ` PATCH: " 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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=mvbzohy6f3g.fsf@phobos.lrde.epita.fr \
    --to=duret_g@lrde.epita.fr \
    --cc=Andrej.Borsenkow@mow.siemens.ru \
    --cc=zsh-workers@sunsite.auc.dk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).