From 3e1e46e9d2aa8ce2889682894d3de8998f5bcee9 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Mon, 23 Mar 2009 12:17:32 +0000 Subject: 26748: c modifier to add command path --- ChangeLog | 5 +++- Doc/Zsh/expn.yo | 9 ++++++++ Src/hist.c | 7 ++++++ Src/subst.c | 72 ++++++++++++++++++++++++++++++++++++++++++--------------- 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 + * 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 @@ -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(©); break; + case 'c': + { + char *copy2 = equalsubstr(copy, 0, 0); + if (copy2) + copy = copy2; + break; + } case 'h': remtpath(©); 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; -- cgit 1.4.1