From: Michael Hwang <nomex45@yahoo.com>
To: zsh-workers@sunsite.dk
Subject: Re: PATCH: Modifiers that implement realpath-like feature
Date: Sat, 14 Mar 2009 14:27:09 -0700 (PDT) [thread overview]
Message-ID: <664029.1117.qm@web37301.mail.mud.yahoo.com> (raw)
In-Reply-To: <20090314181458.007906bc@pws-pc>
[-- Attachment #1: Type: text/plain, Size: 980 bytes --]
Sorry, here.
----- Original Message ----
From: Peter Stephenson <p.w.stephenson@ntlworld.com>
To: Michael Hwang <nomex45@yahoo.com>
Cc: zsh-workers@sunsite.dk
Sent: Saturday, March 14, 2009 2:14:58 PM
Subject: Re: PATCH: Modifiers that implement realpath-like feature
On Thu, 12 Mar 2009 15:42:25 -0700 (PDT)
Michael Hwang <nomex45@yahoo.com> wrote:
> I'm particularly proud of this patch, as it's my first time
> contributing to an open source project. (I'm sure the novelty will wear
> off in a while.) It implements two history-style realpath-like modifiers
> for getting the absolute path of a file. I chose the letter 'a' for
> 'absolute' (r was already taken). Both 'a' and 'A' have different
> meanings. The uppercase A will resolve symbolic links.
This looks useful but your mailer's screwed it up. Could you send it as
an attachment?
Thanks
--
Peter Stephenson <p.w.stephenson@ntlworld.com>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: a_modifiers.patch --]
[-- Type: text/x-diff; name="a_modifiers.patch", Size: 4135 bytes --]
diff --git a/Src/hist.c b/Src/hist.c
index 38ceac3..0dd8c21 100644
--- a/Src/hist.c
+++ b/Src/hist.c
@@ -623,6 +623,21 @@ histsubchar(int c)
case 'p':
histdone = HISTFLAG_DONE | HISTFLAG_NOEXEC;
break;
+ case 'a':
+ if (!chabspath(&sline)) {
+ herrflush();
+ zerr("modifier failed: a");
+ return -1;
+ }
+ break;
+
+ case 'A':
+ if (!chrealpath(&sline)) {
+ herrflush();
+ zerr("modifier failed: A");
+ return -1;
+ }
+ break;
case 'h':
if (!remtpath(&sline)) {
herrflush();
@@ -1484,6 +1499,119 @@ hcomsearch(char *str)
/**/
int
+chabspath(char **junkptr)
+{
+ if (!**junkptr)
+ return 1;
+
+ if (**junkptr != '/') {
+ *junkptr = zhtricat(zgetcwd(), "/", *junkptr);
+ }
+
+ char *current = *junkptr;
+ char *dest = *junkptr;
+
+#ifdef HAVE_SUPERROOT
+ while (*current == '/' && current[1] == '.' && current[2] == '.' && (!current[3] || current[3] == '/')) {
+ *dest++ = '/';
+ *dest++ = '.';
+ *dest++ = '.';
+ current += 3;
+ }
+#endif
+
+ for (;;) {
+ if (*current == '/') {
+#ifdef __CYGWIN__
+ if (current == *junkptr && current[1] == '/')
+ *dest++ = *current++;
+#endif
+ *dest++ = *current++;
+ while (*current == '/')
+ current++;
+ } else if (!*current) {
+ while (dest > *junkptr + 1 && dest[-1] == '/')
+ dest--;
+ *dest = '\0';
+ break;
+ } else if (current[0] == '.' && current[1] == '.' && (!current[2] || current[2] == '/')) {
+ if (current == *junkptr || dest == *junkptr) {
+ *dest++ = '.';
+ *dest++ = '.';
+ current += 2;
+ } else if (dest > *junkptr + 2 && !strncmp(dest - 3, "../", 3)) {
+ *dest++ = '.';
+ *dest++ = '.';
+ current += 2;
+ } else if (dest > *junkptr + 1) {
+ *dest = '\0';
+ for (dest--; dest > *junkptr + 1 && dest[-1] != '/'; dest--);
+ if (dest[-1] != '/')
+ dest--;
+ current += 2;
+ } else if (dest == *junkptr + 1) { /* This might break with Cygwin's leading double slashes? */
+ current += 2;
+ } else {
+ return 0;
+ }
+ } else if (current[0] == '.' && (current[1] == '/' || !current[1])) {
+ while (*++current == '/');
+ } else {
+ while (*current != '/' && *current != '\0')
+ if ((*dest++ = *current++) == Meta)
+ dest[-1] = *current++ ^ 32;
+ }
+ }
+ return 1;
+}
+
+/**/
+int
+chrealpath(char **junkptr)
+{
+ if (!**junkptr)
+ return 1;
+
+ /* Notice that this means ..'s are applied before symlinks are resolved! */
+ if (!chabspath(junkptr))
+ return 0;
+
+ /* Notice that this means you cannot pass relative paths into this function! */
+ if (**junkptr != '/')
+ return 0;
+
+ char *lastpos = strend(*junkptr);
+ char *nonreal = lastpos + 1;
+ char real[PATH_MAX];
+
+ while (!realpath(*junkptr, real)) {
+ if (errno == EINVAL || errno == ELOOP || errno == ENAMETOOLONG || errno == ENOMEM)
+ return 0;
+
+ if (nonreal == *junkptr) {
+ *real = '\0';
+ break;
+ }
+
+ while (*nonreal != '/' && nonreal >= *junkptr)
+ nonreal--;
+ *nonreal = '\0';
+ }
+
+ char *str = nonreal;
+ while (str <= lastpos) {
+ if (*str == '\0')
+ *str = '/';
+ str++;
+ }
+
+ *junkptr = bicat(real, nonreal);
+
+ return 1;
+}
+
+/**/
+int
remtpath(char **junkptr)
{
char *str = strend(*junkptr);
diff --git a/Src/subst.c b/Src/subst.c
index 9e3f06f..5033dd4 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -3199,6 +3199,8 @@ modify(char **str, char **ptr)
for (; !c && **ptr;) {
switch (**ptr) {
+ case 'a':
+ case 'A':
case 'h':
case 'r':
case 'e':
@@ -3337,6 +3339,12 @@ modify(char **str, char **ptr)
copy = dupstring(tt);
*e = tc;
switch (c) {
+ case 'a':
+ chabspath(©);
+ break;
+ case 'A':
+ chrealpath(©);
+ break;
case 'h':
remtpath(©);
break;
@@ -3396,6 +3404,12 @@ modify(char **str, char **ptr)
} else {
switch (c) {
+ case 'a':
+ chabspath(str);
+ break;
+ case 'A':
+ chrealpath(str);
+ break;
case 'h':
remtpath(str);
break;
next prev parent reply other threads:[~2009-03-14 21:29 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-03-12 22:42 Michael Hwang
2009-03-14 18:14 ` Peter Stephenson
2009-03-14 21:27 ` Michael Hwang [this message]
2009-03-15 1:05 ` Peter Stephenson
2009-03-15 1:20 ` 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=664029.1117.qm@web37301.mail.mud.yahoo.com \
--to=nomex45@yahoo.com \
--cc=zsh-workers@sunsite.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).