about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2010-10-15 18:56:16 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2010-10-15 18:56:16 +0000
commitbdb38058e4bf67d3a473c806bbb5d7eac5187f51 (patch)
tree82039ddf7ca0e84980fb23a5816268270a21e02b
parent69134f18cb27ae6a3d8de4c45a77f6da714df3f9 (diff)
downloadzsh-bdb38058e4bf67d3a473c806bbb5d7eac5187f51.tar.gz
zsh-bdb38058e4bf67d3a473c806bbb5d7eac5187f51.tar.xz
zsh-bdb38058e4bf67d3a473c806bbb5d7eac5187f51.zip
28345: make ${(D)...} return a fully usable command line argument
-rw-r--r--ChangeLog8
-rw-r--r--Doc/Zsh/expn.yo6
-rw-r--r--Functions/Chpwd/cdr2
-rw-r--r--Src/builtin.c1
-rw-r--r--Src/utils.c29
5 files changed, 31 insertions, 15 deletions
diff --git a/ChangeLog b/ChangeLog
index 9c54b4d9c..2953f32f3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2010-10-15  Peter Stephenson  <p.w.stephenson@ntlworld.com>
+
+	* 28345: Doc/Zsh/expn.yo, Functions/Chpwd/cdr, Src/builtin.c,
+	Src/utils.c: make new ${(D)} flag return the contracted file as
+	a fully usable command line argument.
+
 2010-10-12  Barton E. Schaefer  <schaefer@zsh.org>
 
 	* unposted (users/15440): Doc/Zsh/expn.yo: fix cross-references
@@ -13749,5 +13755,5 @@
 
 *****************************************************
 * This is used by the shell to define $ZSH_PATCHLEVEL
-* $Revision: 1.5105 $
+* $Revision: 1.5106 $
 *****************************************************
diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo
index 023842a1f..64fcd74e3 100644
--- a/Doc/Zsh/expn.yo
+++ b/Doc/Zsh/expn.yo
@@ -774,8 +774,10 @@ that result from field splitting.
 )
 item(tt(D))(
 Assume the string or array elements contain directories and attempt
-to substitute the leading part of these by names.  This is the reverse
-of `tt(~)' substitution:  see
+to substitute the leading part of these by names.  The remainder of
+the path (the whole of it if the leading part was not subsituted)
+is then quoted so that the whole string can be used as a shell
+argument.  This is the reverse of `tt(~)' substitution:  see
 ifnzman(noderef(Filename Expansion))\
 ifzman(the section FILENAME EXPANSION below).
 )
diff --git a/Functions/Chpwd/cdr b/Functions/Chpwd/cdr
index 551710499..d4e6ffaaf 100644
--- a/Functions/Chpwd/cdr
+++ b/Functions/Chpwd/cdr
@@ -291,7 +291,7 @@ if (( list )); then
   dirs=($reply)
   for (( i = 1; i <= ${#dirs}; i++ )); do
     print -n ${(r.5.)i}
-    print -D ${dirs[i]}
+    print -r ${(D)dirs[i]}
   done
   return
 fi
diff --git a/Src/builtin.c b/Src/builtin.c
index f80269846..411b834e7 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -3704,6 +3704,7 @@ bin_print(char *name, char **args, Options ops, int func)
 	    Nameddir d;
 
 	    queue_signals();
+	    /* TODO: finddir takes a metafied file */
 	    d = finddir(args[n]);
 	    if(d) {
 		int dirlen = strlen(d->dir);
diff --git a/Src/utils.c b/Src/utils.c
index f311abd05..e788051cf 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -807,6 +807,8 @@ fprintdir(char *s, FILE *f)
 /*
  * Substitute a directory using a name.
  * If there is none, return the original argument.
+ *
+ * At this level all strings involved are metafied.
  */
 
 /**/
@@ -816,8 +818,9 @@ substnamedir(char *s)
     Nameddir d = finddir(s);
 
     if (!d)
-	return s;
-    return zhtricat("~", d->node.nam, s + strlen(d->dir));
+	return quotestring(s, NULL, QT_BACKSLASH);
+    return zhtricat("~", d->node.nam, quotestring(s + strlen(d->dir),
+						  NULL, QT_BACKSLASH));
 }
 
 
@@ -874,9 +877,13 @@ finddir_scan(HashNode hn, UNUSED(int flags))
     }
 }
 
-/* See if a path has a named directory as its prefix. *
- * If passed a NULL argument, it will invalidate any  *
- * cached information.                                */
+/*
+ * See if a path has a named directory as its prefix.
+ * If passed a NULL argument, it will invalidate any 
+ * cached information.
+ *
+ * s here is metafied.
+ */
 
 /**/
 Nameddir
@@ -915,9 +922,7 @@ finddir(char *s)
     scanhashtable(nameddirtab, 0, 0, 0, finddir_scan, 0);
 
     if (func) {
-	char *dir_meta = metafy(finddir_full, strlen(finddir_full),
-				META_ALLOC);
-	char **ares = subst_string_by_func(func, "d", dir_meta);
+	char **ares = subst_string_by_func(func, "d", finddir_full);
 	int len;
 	if (ares && arrlen(ares) >= 2 &&
 	    (len = (int)zstrtol(ares[1], NULL, 10)) > finddir_best) {
@@ -928,8 +933,6 @@ finddir(char *s)
 	    finddir_last->diff = len - strlen(finddir_last->node.nam);
 	    finddir_best = len;
 	}
-	if (dir_meta != finddir_full)
-	    zsfree(dir_meta);
     }
 
     return finddir_last;
@@ -1039,6 +1042,10 @@ getnameddir(char *name)
     return NULL;
 }
 
+/*
+ * Compare directories.  Both are metafied.
+ */
+
 /**/
 static int
 dircmp(char *s, char *t)
@@ -4607,7 +4614,7 @@ addunprintable(char *v, const char *u, const char *uend)
 }
 
 /*
- * Quote the string s and return the result.
+ * Quote the string s and return the result as a string from the heap.
  *
  * If e is non-zero, the
  * pointer it points to may point to a position in s and in e the position