summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--Doc/Zsh/expn.yo9
-rw-r--r--Src/hist.c7
-rw-r--r--Src/subst.c72
4 files changed, 74 insertions, 19 deletions
diff --git a/ChangeLog b/ChangeLog
index 16215ba37..d0fa9a4cc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
2009-03-23 Peter Stephenson <pws@csr.com>
+ * 26748: Doc/Zsh/expn.yo, Src/hist.c, Src/subst.c: c modifier
+ to add command path.
+
* 26767: Src/utils.c: 26763 created file descriptor leak.
2009-03-20 Peter Stephenson <p.w.stephenson@ntlworld.com>
@@ -11469,5 +11472,5 @@
*****************************************************
* This is used by the shell to define $ZSH_PATCHLEVEL
-* $Revision: 1.4631 $
+* $Revision: 1.4632 $
*****************************************************
diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo
index 74dda0977..bab12cc3f 100644
--- a/Doc/Zsh/expn.yo
+++ b/Doc/Zsh/expn.yo
@@ -219,6 +219,8 @@ startitem()
item(tt(a))(
Turn a file name into an absolute path: prepends the current directory,
if necessary, and resolves any use of `tt(..)' and `tt(.)' in the path.
+Note that the transformation takes place even if the file or any
+intervening directories do not exist.
)
item(tt(A))(
As `tt(a)', but also resolve use of symbolic links where possible.
@@ -226,6 +228,13 @@ Note that resolution of `tt(..)' occurs em(before) resolution of symbolic
links. This call is equivalent to tt(a) unless your system has the
tt(realpath) system call (modern systems do).
)
+item(tt(c))(
+Resolve a command name into an absolute path by searching the command
+path given by the tt(PATH) variable. This does not work for commands
+containing directory parts. Note also that this does not usually work as
+a glob qualifier unless a file of the same name is found in the
+current directory.
+)
item(tt(e))(
Remove all but the extension.
)
diff --git a/Src/hist.c b/Src/hist.c
index 80c5f1752..7f52ee08b 100644
--- a/Src/hist.c
+++ b/Src/hist.c
@@ -638,6 +638,13 @@ histsubchar(int c)
return -1;
}
break;
+ case 'c':
+ if (!(sline = equalsubstr(sline, 0, 0))) {
+ herrflush();
+ zerr("modifier failed: c");
+ return -1;
+ }
+ break;
case 'h':
if (!remtpath(&sline)) {
herrflush();
diff --git a/Src/subst.c b/Src/subst.c
index 5033dd492..8a695cee9 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -539,12 +539,43 @@ filesub(char **namptr, int assign)
}
}
+#define isend(c) ( !(c) || (c)=='/' || (c)==Inpar || (assign && (c)==':') )
+#define isend2(c) ( !(c) || (c)==Inpar || (assign && (c)==':') )
+
+/*
+ * do =foo substitution, or equivalent.
+ * on entry, str should point to the "foo".
+ * if assign, this is in an assignment
+ * if nomatch, report hard error on failure.
+ * if successful, returns the expansion, else NULL.
+ */
+
+/**/
+char *
+equalsubstr(char *str, int assign, int nomatch)
+{
+ char *pp, *cnam, *cmdstr, *ret;
+
+ for (pp = str; !isend2(*pp); pp++)
+ ;
+ cmdstr = dupstrpfx(str, pp-str);
+ untokenize(cmdstr);
+ remnulargs(cmdstr);
+ if (!(cnam = findcmd(cmdstr, 1))) {
+ if (nomatch)
+ zerr("%s not found", cmdstr);
+ return NULL;
+ }
+ ret = dupstring(cnam);
+ if (*pp)
+ ret = dyncat(ret, pp);
+ return ret;
+}
+
/**/
mod_export int
filesubstr(char **namptr, int assign)
{
-#define isend(c) ( !(c) || (c)=='/' || (c)==Inpar || (assign && (c)==':') )
-#define isend2(c) ( !(c) || (c)==Inpar || (assign && (c)==':') )
char *str = *namptr;
if (*str == Tilde && str[1] != '=' && str[1] != Equals) {
@@ -606,27 +637,17 @@ filesubstr(char **namptr, int assign)
return 1;
}
} else if (*str == Equals && isset(EQUALS) && str[1]) { /* =foo */
- char *pp, *cnam, *cmdstr, *str1 = str+1;
-
- for (pp = str1; !isend2(*pp); pp++)
- ;
- cmdstr = dupstrpfx(str1, pp-str1);
- untokenize(cmdstr);
- remnulargs(cmdstr);
- if (!(cnam = findcmd(cmdstr, 1))) {
- if (isset(NOMATCH))
- zerr("%s not found", cmdstr);
- return 0;
+ char *expn = equalsubstr(str+1, assign, isset(NOMATCH));
+ if (expn) {
+ *namptr = expn;
+ return 1;
}
- *namptr = dupstring(cnam);
- if (*pp)
- *namptr = dyncat(*namptr, pp);
- return 1;
}
return 0;
+}
+
#undef isend
#undef isend2
-}
/**/
static char *
@@ -3201,6 +3222,7 @@ modify(char **str, char **ptr)
switch (**ptr) {
case 'a':
case 'A':
+ case 'c':
case 'h':
case 'r':
case 'e':
@@ -3345,6 +3367,13 @@ modify(char **str, char **ptr)
case 'A':
chrealpath(&copy);
break;
+ case 'c':
+ {
+ char *copy2 = equalsubstr(copy, 0, 0);
+ if (copy2)
+ copy = copy2;
+ break;
+ }
case 'h':
remtpath(&copy);
break;
@@ -3410,6 +3439,13 @@ modify(char **str, char **ptr)
case 'A':
chrealpath(str);
break;
+ case 'c':
+ {
+ char *copy2 = equalsubstr(*str, 0, 0);
+ if (copy2)
+ *str = copy2;
+ break;
+ }
case 'h':
remtpath(str);
break;