zsh-workers
 help / color / mirror / code / Atom feed
From: "Dian M Fay" <dian.m.fay@gmail.com>
To: <zsh-workers@zsh.org>
Subject: [PATCH] expand '..n' to equivalent number of '..' segments in fixdir
Date: Sun, 10 May 2020 00:37:32 -0400	[thread overview]
Message-ID: <C2MRS2V8S953.3DWB49ORSAIY8@lamia> (raw)

dian@lamia ~/work/zsh cd ..2
dian@lamia ~ cd ..123
dian@lamia / cd ~/..2/home/dian/work/../work/zsh
dian@lamia ~/work/zsh cd ..2/work/zsh
dian@lamia ~/work/zsh

I added a minimal test case and so far it seems to do what I expect, but I don't know if there are any side effects to worry about.

diff --git a/Src/builtin.c b/Src/builtin.c
index d5a874a95..3a13f19ee 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -1353,8 +1353,12 @@ fixdir(char *src)
 	    *dest = '\0';
 	    return chasedots;
 	}
-	if (src[0] == '.' && src[1] == '.' &&
-	    (src[2] == '\0' || src[2] == '/')) {
+	if (src[0] == '.' && src[1] == '.') {
+	    int backtracks = src[2] == '\0' || src[2] == '/' ? 1 : atoi(src + 2);
+
+	    if (backtracks < 1)
+		backtracks = 1;
+
 	    if (isset(CHASEDOTS) || chasedots > 1) {
 		chasedots = 1;
 		/* and treat as normal path segment */
@@ -1375,11 +1379,16 @@ fixdir(char *src)
 			*ptrd = '\0';
 			return 1;
 		    }
-		    for (dest--; dest > d0 + 1 && dest[-1] != '/'; dest--);
-		    if (dest[-1] != '/')
-			dest--;
+		    for (int i = 0; i < backtracks; i++) {
+			for (dest--; dest > d0 + 1 && dest[-1] != '/'; dest--);
+			if (dest[-1] != '/')
+			    dest--;
+			if (dest - 1 == d0)
+			    break;
+		    }
 		}
-		src++;
+		/* jump forward one space plus the length of any trailing digits */
+		src += backtracks == 1 ? 1 : (int) trunc(log10(backtracks)) + 2;
 		while (*++src == '/');
 		continue;
 	    }
diff --git a/Test/B01cd.ztst b/Test/B01cd.ztst
index 21e751dcb..f7f82147f 100644
--- a/Test/B01cd.ztst
+++ b/Test/B01cd.ztst
@@ -123,6 +123,14 @@ F:something is broken.  But you already knew that.
  print $PWD
 0q:Changing directory up through symbolic links without following them
 >$mydir
+>$mydir
+
+ cd $mydir/cdtst.tmp/sub/fake
+ cd ..3 &&
+ pwd &&
+ print $PWD
+0q:Changing directory up without following symlinks, shorter form
+>$mydir
 >$mydir
 
  setopt chaselinks

             reply	other threads:[~2020-05-10  4:36 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-10  4:37 Dian M Fay [this message]
2020-05-10  4:43 ` Roman Perepelitsa
2020-05-10  5:58   ` Bart Schaefer
2020-05-10  6:28     ` Bart Schaefer
2020-05-10 17:17       ` Dian M Fay
     [not found] <CAN=4vMr_8j03P2oY0+9SLgBnMWMtGtrnUag7fte =18VnvUtRKg@mail.gmail.com>
2020-05-10  5:28 ` Dian M Fay
2020-05-10  7:06   ` Eric Cook
2020-05-10  7:09     ` Eric Cook
2020-05-10 14:21       ` Daniel Shahaf

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=C2MRS2V8S953.3DWB49ORSAIY8@lamia \
    --to=dian.m.fay@gmail.com \
    --cc=zsh-workers@zsh.org \
    /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).