zsh-workers
 help / color / mirror / code / Atom feed
From: Alexandre Duret-Lutz <duret_g@lrde.epita.fr>
To: <zsh-workers@sunsite.auc.dk>
Subject: Re: PATCH: Re: :r modifier
Date: 15 Dec 2000 12:53:30 +0100	[thread overview]
Message-ID: <mvbelz96gud.fsf@phobos.lrde.epita.fr> (raw)
In-Reply-To: Alexandre Duret-Lutz's message of "14 Dec 2000 19:18:59 +0100"

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


  parent reply	other threads:[~2000-12-15 11:46 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               ` 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 [this message]
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=mvbelz96gud.fsf@phobos.lrde.epita.fr \
    --to=duret_g@lrde.epita.fr \
    --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).