Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Problem with an exported array



DervishD wrote:
>     I think that the most used case will be joining with spaces,
> maybe the colon (PATH and the like).

This gives me an idea... it looks like a minimal modification to the
user version of the PATH stuff can give you a combination where pager is
an array and PAGER is a scalar with the elements joined by spaces.  You
do this with:

typeset -S PAGER pager

The only downside I can see is that you have to remember to use $pager,
not $PAGER, when you want the array.  I don't think that's much of a
downside since I expect most zsh users who use arrays are conditioned to
think of them as being in lower case.

Note the restrictions when setting the scalar version --- no use of -U
(which doesn't make that much sense here, typically) and splitting on
*all* spaces.  Could be improved but I suggest setting via the array in
any case.

I moved up the non-option parameter flags so that they don't have to be
renumbered every time we add an option-related one.  New non-option
flags need to be added at the bottom of the list.  I would have made
flags unsigned (which is more natural) but it would have needed a host
of related changes.

If this isn't going to be good enough, or someone can see a problem, say
now, since I don't want to clutter the parameter code more than is
necessary.  However, if it's useful it seems a relatively clean change
compared with most of the typeset flummery.

Index: Doc/Zsh/builtins.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/builtins.yo,v
retrieving revision 1.64
diff -u -r1.64 builtins.yo
--- Doc/Zsh/builtins.yo	11 Sep 2003 07:00:07 -0000	1.64
+++ Doc/Zsh/builtins.yo	22 Sep 2003 13:32:28 -0000
@@ -1159,7 +1159,7 @@
 cindex(parameters, declaring)
 xitem(tt(typeset) [ {tt(PLUS())|tt(-)}tt(AEFHLRUZafghilprtuxm) [var(n)]] [ \
 var(name)[tt(=)var(value)] ... ])
-item(tt(typeset) -T [ {tt(PLUS()|tt(-))}tt(LRUZrux) ] \
+item(tt(typeset) [ -T | -S ] [ {tt(PLUS()|tt(-))}tt(LRUZrux) ] \
   var(SCALAR)[tt(=)var(value)] var(array))(
 Set or display attributes and values for shell parameters.
 
@@ -1189,12 +1189,13 @@
 and options.  Note that the tt(-h) flag on parameters is respected; no
 value will be shown for these parameters.
 
-If the tt(-T) option is given, exactly two (or zero) var(name)
-arguments must be present.  They represent a scalar and an array (in
-that order) that will be tied together in the manner of tt($PATH) and
-tt($path).  In other words, an array present in the latter variable
-appears as a scalar with the elements of the array joined by colons in
-the former.  Only the scalar may have an initial value.  Both the
+If one of the tt(-T) or tt(-S) options is given, exactly two (or zero)
+var(name) arguments must be present.  They represent a scalar and an array
+(in that order) that will be tied together in the manner of tt($PATH) and
+tt($path).  With the option tt(-T), the scalar contains of the array
+elements joined by colons, as with tt($PATH), and with the option tt(-S),
+the scalar consists of the array elements joined by spaces.
+Only the scalar may have an initial value.  Both the
 scalar and the array may otherwise be manipulated as normal.  If one
 is unset, the other will automatically be unset too.  There is no way
 of untying the variables without unsetting them, or converting the
@@ -1202,7 +1203,10 @@
 work, assigning an array to var(SCALAR) is an error, and assigning a
 scalar to var(array) sets it to be a single-element array.  Note that
 both `tt(typeset -xT ...)' and `tt(export -T ...)' work, but only the
-scalar will be marked for export.
+scalar will be marked for export.  With tt(-S), setting the value using the
+scalar version causes a split on all spaces (which cannot be quoted) and
+the option tt(-U) is not respected, hence it is recommended that the array
+version be used to set the value.
 
 The tt(-g) (global) flag is treated specially: it means that any
 resulting parameter will not be restricted to local scope.  Note that this
Index: Src/builtin.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/builtin.c,v
retrieving revision 1.105
diff -u -r1.105 builtin.c
--- Src/builtin.c	11 Sep 2003 07:00:07 -0000	1.105
+++ Src/builtin.c	22 Sep 2003 13:32:28 -0000
@@ -121,7 +121,7 @@
     BUILTIN("trap", BINF_PSPECIAL, bin_trap, 0, -1, 0, NULL, NULL),
     BUILTIN("true", 0, bin_true, 0, -1, 0, NULL, NULL),
     BUILTIN("type", 0, bin_whence, 0, -1, 0, "ampfsw", "v"),
-    BUILTIN("typeset", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%afghi:%lprtuxm", NULL),
+    BUILTIN("typeset", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%STUZ:%afghi:%lprtuxm", NULL),
     BUILTIN("umask", 0, bin_umask, 0, 1, 0, "S", NULL),
     BUILTIN("unalias", 0, bin_unhash, 1, -1, 0, "ms", "a"),
     BUILTIN("unfunction", 0, bin_unhash, 1, -1, 0, "m", "f"),
@@ -1817,14 +1817,14 @@
 		x = (*pm->gets.afn)(pm);
 		uniqarray(x);
 		if (pm->ename && x)
-		    arrfixenv(pm->ename, x);
+		    arrfixenv(pm->ename, x, pm->flags);
 	    } else if (PM_TYPE(pm->flags) == PM_SCALAR && pm->ename &&
 		       (apm =
 			(Param) paramtab->getnode(paramtab, pm->ename))) {
 		x = (*apm->gets.afn)(apm);
 		uniqarray(x);
 		if (x)
-		    arrfixenv(pm->nam, x);
+		    arrfixenv(pm->nam, x, pm->flags);
 	    }
 	}
 	pm->flags = (pm->flags | (on & ~PM_READONLY)) & ~(off | PM_UNSET);
@@ -2124,8 +2124,10 @@
 	off |= PM_UPPER;
     if (on & PM_HASHED)
 	off |= PM_ARRAY;
-    if (on & PM_TIED)
+    if (on & (PM_TIED|PM_SPACEJOIN)) {
+	on |= PM_TIED;
 	off |= PM_INTEGER | PM_EFLOAT | PM_FFLOAT | PM_ARRAY | PM_HASHED;
+    }
 
     on &= ~off;
 
Index: Src/params.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/params.c,v
retrieving revision 1.72
diff -u -r1.72 params.c
--- Src/params.c	30 Aug 2003 19:00:20 -0000	1.72
+++ Src/params.c	22 Sep 2003 13:32:29 -0000
@@ -2399,7 +2399,7 @@
     pm->u.arr = x;
     /* Arrays tied to colon-arrays may need to fix the environment */
     if (pm->ename && x)
-	arrfixenv(pm->ename, x);
+	arrfixenv(pm->ename, x, pm->flags);
 }
 
 /* Function to get value of an association parameter */
@@ -2579,7 +2579,7 @@
 	uniqarray(x);
     *dptr = x ? x : mkarray(NULL);
     if (pm->ename && x)
-	arrfixenv(pm->ename, x);
+	arrfixenv(pm->ename, x, pm->flags);
 }
 
 /**/
@@ -2587,7 +2587,8 @@
 colonarrgetfn(Param pm)
 {
     char ***dptr = (char ***)pm->u.data;
-    return *dptr ? zjoin(*dptr, ':', 1) : "";
+    return *dptr ? zjoin(*dptr, (pm->flags & PM_SPACEJOIN) ? ' ' : ':', 1)
+	: "";
 }
 
 /**/
@@ -2595,6 +2596,7 @@
 colonarrsetfn(Param pm, char *x)
 {
     char ***dptr = (char ***)pm->u.data;
+    int flags = pm->flags;
 
     /*
      * If this is tied to a parameter (rather than internal) array,
@@ -2603,10 +2605,17 @@
      */
     if (*dptr)
 	freearray(*dptr);
-    *dptr = x ? colonsplit(x, pm->flags & PM_UNIQUE) :
-	(pm->flags & PM_TIED) ? NULL : mkarray(NULL);
+    if (x) {
+	if (flags & PM_SPACEJOIN)
+	    *dptr = spacesplit(x, 0, 0, 0);
+	else
+	    *dptr = colonsplit(x, flags & PM_UNIQUE);
+    } else if (flags & PM_TIED)
+	*dptr = NULL;
+    else
+	*dptr = mkarray(NULL);
     if (pm->ename)
-	arrfixenv(pm->nam, *dptr);
+	arrfixenv(pm->nam, *dptr, pm->flags);
     zsfree(x);
 }
 
@@ -3184,9 +3193,10 @@
 
 /**/
 void
-arrfixenv(char *s, char **t)
+arrfixenv(char *s, char **t, int flags)
 {
     Param pm;
+    int joinchar = (flags & PM_SPACEJOIN) ? ' ' : ':';
 
     if (t == path)
 	cmdnamtab->emptytable(cmdnamtab);
@@ -3209,7 +3219,7 @@
      */
 
     if (pm->flags & PM_EXPORTED)
-	pm->env = addenv(s, t ? zjoin(t, ':', 1) : "", pm->flags);
+	pm->env = addenv(s, t ? zjoin(t, joinchar, 1) : "", pm->flags);
 }
 
 
Index: Src/utils.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/utils.c,v
retrieving revision 1.53
diff -u -r1.53 utils.c
--- Src/utils.c	1 Aug 2003 16:29:21 -0000	1.53
+++ Src/utils.c	22 Sep 2003 13:32:29 -0000
@@ -1856,7 +1856,15 @@
     return i;
 }
 
-/* see findsep() below for handling of `quote' argument */
+/*
+ * haven't worked out what allownull does; it's passed down from
+ *   sepsplit but all the cases it's used are either 0 or 1 without
+ *   a comment.  it seems to be something to do with the `nulstring'
+ *   which i think is some kind of a metafication thing, so probably
+ *   allownull's value is associated with whether we are using
+ *   metafied strings.
+ * see findsep() below for handling of `quote' argument
+ */
 
 /**/
 mod_export char **
Index: Src/zsh.h
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/zsh.h,v
retrieving revision 1.49
diff -u -r1.49 zsh.h
--- Src/zsh.h	3 Sep 2003 10:15:36 -0000	1.49
+++ Src/zsh.h	22 Sep 2003 13:32:29 -0000
@@ -1191,21 +1191,22 @@
 #define PM_HIDE		(1<<14)	/* Special behaviour hidden by local        */
 #define PM_HIDEVAL	(1<<15)	/* Value not shown in `typeset' commands    */
 #define PM_TIED 	(1<<16)	/* array tied to colon-path or v.v.         */
+#define PM_SPACEJOIN	(1<<17) /* array tied to space-path or v.v.	    */
 
 /* Remaining flags do not correspond directly to command line arguments */
-#define PM_LOCAL	(1<<17) /* this parameter will be made local        */
-#define PM_SPECIAL	(1<<18) /* special builtin parameter                */
-#define PM_DONTIMPORT	(1<<19)	/* do not import this variable              */
-#define PM_RESTRICTED	(1<<20) /* cannot be changed in restricted mode     */
-#define PM_UNSET	(1<<21)	/* has null value                           */
-#define PM_REMOVABLE	(1<<22)	/* special can be removed from paramtab     */
-#define PM_AUTOLOAD	(1<<23) /* autoloaded from module                   */
-#define PM_NORESTORE	(1<<24)	/* do not restore value of local special    */
-#define PM_HASHELEM     (1<<25) /* is a hash-element */
-#define PM_NAMEDDIR     (1<<26) /* has a corresponding nameddirtab entry    */
+#define PM_LOCAL	(1<<21) /* this parameter will be made local        */
+#define PM_SPECIAL	(1<<22) /* special builtin parameter                */
+#define PM_DONTIMPORT	(1<<23)	/* do not import this variable              */
+#define PM_RESTRICTED	(1<<24) /* cannot be changed in restricted mode     */
+#define PM_UNSET	(1<<25)	/* has null value                           */
+#define PM_REMOVABLE	(1<<26)	/* special can be removed from paramtab     */
+#define PM_AUTOLOAD	(1<<27) /* autoloaded from module                   */
+#define PM_NORESTORE	(1<<28)	/* do not restore value of local special    */
+#define PM_HASHELEM     (1<<29) /* is a hash-element */
+#define PM_NAMEDDIR     (1<<30) /* has a corresponding nameddirtab entry    */
 
 /* The option string corresponds to the first of the variables above */
-#define TYPESET_OPTSTR "aiEFALRZlurtxUhHT"
+#define TYPESET_OPTSTR "aiEFALRZlurtxUhHTS"
 
 /* These typeset options take an optional numeric argument */
 #define TYPESET_OPTNUM "LRZiEF"

-- 
Peter Stephenson <pws@xxxxxxx>                  Software Engineer
CSR Ltd., Science Park, Milton Road,
Cambridge, CB4 0WH, UK                          Tel: +44 (0)1223 692070


**********************************************************************
The information transmitted is intended only for the person or
entity to which it is addressed and may contain confidential 
and/or privileged material. 
Any review, retransmission, dissemination or other use of, or
taking of any action in reliance upon, this information by 
persons or entities other than the intended recipient is 
prohibited.  
If you received this in error, please contact the sender and 
delete the material from any computer.
**********************************************************************



Messages sorted by: Reverse Date, Date, Thread, Author