about summary refs log tree commit diff
path: root/Src/subst.c
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2009-03-23 12:17:32 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2009-03-23 12:17:32 +0000
commit3e1e46e9d2aa8ce2889682894d3de8998f5bcee9 (patch)
tree1485aa93fe72ca2565cd1c2714525f70033799da /Src/subst.c
parent4b2ad07d39a3def549a3382eeec36dc1b222ff03 (diff)
downloadzsh-3e1e46e9d2aa8ce2889682894d3de8998f5bcee9.tar.gz
zsh-3e1e46e9d2aa8ce2889682894d3de8998f5bcee9.tar.xz
zsh-3e1e46e9d2aa8ce2889682894d3de8998f5bcee9.zip
26748: c modifier to add command path
Diffstat (limited to 'Src/subst.c')
-rw-r--r--Src/subst.c72
1 files changed, 54 insertions, 18 deletions
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;