zsh-workers
 help / color / mirror / code / Atom feed
* Problem with an exported array
@ 2003-09-22  8:30 DervishD
  2003-09-22  9:08 ` Oliver Kiddle
  0 siblings, 1 reply; 22+ messages in thread
From: DervishD @ 2003-09-22  8:30 UTC (permalink / raw)
  To: Zsh

    Hi all :)

    Instead of turning on SHWORDSPLIT or using ${=PAGER}, I decided
to set PAGER as an array recently, with the following:

    typeset -gxa PAGER
    PAGER=(/bin/view -)

    In fact, if I do 'whatever | $PAGER' it works. The problem is
that PAGER is not exported to the environment of commands!. So, if I
do now 'man whatever', 'man' barfs saying that it cannot find
/usr/bin/pager, the default pager for man. But if I do something
like 'PAGER=$PAGER man whatever', it works perfectly. Aren't arrays
exported? If I do the following:

    typeset -gx PAGER="/bin/view -"

    then 'man' works OK. Am I doing something wrong or is just that
arrays cannot be exported? BTW I'm using zsh 4.0.7

    Thanks in advance.

    Raúl Núñez de Arenas Coronado

-- 
Linux Registered User 88736
http://www.pleyades.net & http://raul.pleyades.net/


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Problem with an exported array
  2003-09-22  8:30 Problem with an exported array DervishD
@ 2003-09-22  9:08 ` Oliver Kiddle
  2003-09-22  9:31   ` DervishD
  2003-09-22  9:48   ` Peter Stephenson
  0 siblings, 2 replies; 22+ messages in thread
From: Oliver Kiddle @ 2003-09-22  9:08 UTC (permalink / raw)
  To: Zsh

DervishD wrote:
> 
>     then 'man' works OK. Am I doing something wrong or is just that
> arrays cannot be exported? BTW I'm using zsh 4.0.7

Arrays cannot be exported.

Not so much a zsh limitation as a limitation in the way Unix stores the
environment.

There are hacks which could allow us to represent arrays in it but not
in a way programs like man could be expected to understand.

ksh (88 and 93) seem to export just the first element for an exported
array so you might argue we should do that.

Oliver


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Problem with an exported array
  2003-09-22  9:08 ` Oliver Kiddle
@ 2003-09-22  9:31   ` DervishD
  2003-09-22  9:48   ` Peter Stephenson
  1 sibling, 0 replies; 22+ messages in thread
From: DervishD @ 2003-09-22  9:31 UTC (permalink / raw)
  To: Oliver Kiddle; +Cc: Zsh

    Hi Oliver :)

 * Oliver Kiddle <okiddle@yahoo.co.uk> dixit:
> >     then 'man' works OK. Am I doing something wrong or is just that
> > arrays cannot be exported? BTW I'm using zsh 4.0.7
> Arrays cannot be exported.

    Oh :((( So I'm stuck with the ${= notation, I suppose. Or maybe I
can use two variables, one scalar for programs that want PAGER in
their environment, like man, and other for use interactively, when
manually write '|$PAGER', which will be an array. I'll try to choose
sensible names...

    BTW, is this noted in the manual? I've missed it if so.

> Not so much a zsh limitation as a limitation in the way Unix stores
> the environment.

    I was thinking about it: how the heck does zsh to store a
specially formatted variable, like an array is, in the standard
environment so the programs which use it doesn't get confused?
 
> There are hacks which could allow us to represent arrays in it but not
> in a way programs like man could be expected to understand.

    Obviously.
 
> ksh (88 and 93) seem to export just the first element for an exported
> array so you might argue we should do that.

    No, I won't ;)) I don't thing that storing just the first element
is a good idea. If you declare an array is quite possible that you
want all items ;).

    Thanks a lot for the answer :)

    Raúl Núñez de Arenas Coronado

-- 
Linux Registered User 88736
http://www.pleyades.net & http://raul.pleyades.net/


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Problem with an exported array
  2003-09-22  9:08 ` Oliver Kiddle
  2003-09-22  9:31   ` DervishD
@ 2003-09-22  9:48   ` Peter Stephenson
  2003-09-22 11:33     ` DervishD
  1 sibling, 1 reply; 22+ messages in thread
From: Peter Stephenson @ 2003-09-22  9:48 UTC (permalink / raw)
  To: Zsh

Oliver Kiddle wrote:
> There are hacks which could allow us to represent arrays in it but not
> in a way programs like man could be expected to understand.

That's not entirely true.  A brief and thorougly unscientific
investigation suggests man is doing popen() or something equivalent.
That means that if you set

typeset -ax PAGER
PAGER=(/bin/view -)

and zsh exported PAGER as the string "/bin/view -", it would work
because the shell used to invoked the pager would do the splitting.
(What I actually died was confirm that
  export PAGER="less -e"
did the right thing.)

It shouldn't be too hard to make arrays get exported joined with a
space, or maybe even a configurable string (though the param structure
isn't conveniently extensible at the moment).  I think that's far more
useful than the ksh behaviour --- probably that's just a side effect of
the fact that all variables in ksh are arrays but most just have the first
element set.  However, I haven't looked into it.

-- 
Peter Stephenson <pws@csr.com>                  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.
**********************************************************************


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Problem with an exported array
  2003-09-22  9:48   ` Peter Stephenson
@ 2003-09-22 11:33     ` DervishD
  2003-09-22 13:44       ` Peter Stephenson
  0 siblings, 1 reply; 22+ messages in thread
From: DervishD @ 2003-09-22 11:33 UTC (permalink / raw)
  To: Peter Stephenson; +Cc: Zsh

    Hi Peter :)

 * Peter Stephenson <pws@csr.com> dixit:
> > There are hacks which could allow us to represent arrays in it but not
> > in a way programs like man could be expected to understand.
> That's not entirely true.  A brief and thorougly unscientific
> investigation suggests man is doing popen() or something equivalent.
> That means that if you set
> typeset -ax PAGER
> and zsh exported PAGER as the string "/bin/view -", it would work
> because the shell used to invoked the pager would do the splitting.

    That's true (almost). In the interim I'm going to use two
variables or better I will use 'pager' instead of 'PAGER', and will
tie both values with typeset -T. That will solve my problems, won't
clutter the environment namespace and is quite easy to remember. It
will be like PATH/path, for example.

> It shouldn't be too hard to make arrays get exported joined with a
> space, or maybe even a configurable string (though the param structure
> isn't conveniently extensible at the moment).

    I think that the most used case will be joining with spaces,
maybe the colon (PATH and the like). Anyway, since the variable names
are case sensitive (what does SuSv3 says about case?) and can be tied
together, the uppercase variable can be used as scalar and the
lowercase one as an array, so it is not really needed to modify the
Zsh code in order to support this. Just a note in the manual will be
enough (methinks...). Automatically tieing PAGER and pager will be of
help, too, since is a quite common variable, but I'm not sure if it
normally has spaces in it, so I'm not sure if it worths the effort ;))

    Thanks for the answer :)))

    Raúl Núñez de Arenas Coronado

-- 
Linux Registered User 88736
http://www.pleyades.net & http://raul.pleyades.net/


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Problem with an exported array
  2003-09-22 11:33     ` DervishD
@ 2003-09-22 13:44       ` Peter Stephenson
  2003-09-22 14:04         ` DervishD
  2003-09-22 14:22         ` Bart Schaefer
  0 siblings, 2 replies; 22+ messages in thread
From: Peter Stephenson @ 2003-09-22 13:44 UTC (permalink / raw)
  To: Zsh

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@csr.com>                  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.
**********************************************************************


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Problem with an exported array
  2003-09-22 13:44       ` Peter Stephenson
@ 2003-09-22 14:04         ` DervishD
  2003-09-22 14:22         ` Bart Schaefer
  1 sibling, 0 replies; 22+ messages in thread
From: DervishD @ 2003-09-22 14:04 UTC (permalink / raw)
  To: Peter Stephenson; +Cc: Zsh

    Hi Peter :)

 * Peter Stephenson <pws@csr.com> dixit:
> >     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.

    Cool, since my idea of tieing both variables won't work because
the joining character is a colon and not an space :(((

> The only downside I can see is that you have to remember to use $pager,
> not $PAGER, when you want the array.

    Not a problem, since I already do this with PATH and path, for
example. In fact is a pro, because I do that automatically ;)

> 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.

    For me it is right, but I must confess I have interest in it ;)))
Although I cannot use that with my current zsh version, it doesn't
matter really since I don't modify the variables (on normal use, I
mean), and I can set both variables by hand in my /etc/zshenv. But
I'm ready for a new Zsh version ;))))
 
    Raúl Núñez de Arenas Coronado

-- 
Linux Registered User 88736
http://www.pleyades.net & http://raul.pleyades.net/


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Problem with an exported array
  2003-09-22 13:44       ` Peter Stephenson
  2003-09-22 14:04         ` DervishD
@ 2003-09-22 14:22         ` Bart Schaefer
  2003-09-22 14:45           ` Danek Duvall
                             ` (2 more replies)
  1 sibling, 3 replies; 22+ messages in thread
From: Bart Schaefer @ 2003-09-22 14:22 UTC (permalink / raw)
  To: Zsh

On Sep 22,  2:44pm, Peter Stephenson wrote:
}
} 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

Why not make it fully general, e.g.

	typeset -T -S ' ' PAGER pager

??


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Problem with an exported array
  2003-09-22 14:22         ` Bart Schaefer
@ 2003-09-22 14:45           ` Danek Duvall
  2003-09-22 16:30             ` DervishD
  2003-09-22 17:58             ` Bart Schaefer
  2003-09-22 15:52           ` Peter Stephenson
  2003-09-22 16:33           ` DervishD
  2 siblings, 2 replies; 22+ messages in thread
From: Danek Duvall @ 2003-09-22 14:45 UTC (permalink / raw)
  To: Zsh

On Mon, Sep 22, 2003 at 02:22:08PM +0000, Bart Schaefer wrote:

> On Sep 22,  2:44pm, Peter Stephenson wrote:
>
> } typeset -S PAGER pager
> 
> Why not make it fully general, e.g.
> 
> 	typeset -T -S ' ' PAGER pager

Or, yet more generally, specify a function to transform the array into
the scalar?  If there's a way to use the same -S option for both, then
that possibility could be left open until someone has time to implement
it, but it seems like it might be a useful thing.  Or is it just
overkill?

Danek


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Problem with an exported array
  2003-09-22 14:22         ` Bart Schaefer
  2003-09-22 14:45           ` Danek Duvall
@ 2003-09-22 15:52           ` Peter Stephenson
  2003-09-22 17:44             ` DervishD
                               ` (2 more replies)
  2003-09-22 16:33           ` DervishD
  2 siblings, 3 replies; 22+ messages in thread
From: Peter Stephenson @ 2003-09-22 15:52 UTC (permalink / raw)
  To: Zsh

Bart Schaefer wrote:
> Why not make it fully general, e.g.
> 
> 	typeset -T -S ' ' PAGER pager

As I said before, there's nowhere in struct param to store the
character; else it's not that hard.  Maybe you can see a trick.

Anything more complicated than that needs a lot more work and won't
happen unless someone volunteers to write it.

-- 
Peter Stephenson <pws@csr.com>                  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.
**********************************************************************


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Problem with an exported array
  2003-09-22 14:45           ` Danek Duvall
@ 2003-09-22 16:30             ` DervishD
  2003-09-22 17:58             ` Bart Schaefer
  1 sibling, 0 replies; 22+ messages in thread
From: DervishD @ 2003-09-22 16:30 UTC (permalink / raw)
  To: Danek Duvall, Zsh

    Hi Danek :)

 * Danek Duvall <duvall@emufarm.org> dixit:
> Or, yet more generally, specify a function to transform the array into
> the scalar?

    There are a few ways of doing that. If you have 'pager', the
array, and you want 'PAGER', the scalar, you can transform 'pager' in
'PAGER' with:

    - PAGER="$pager"
    - PAGER="${(f)pager}"
    - PAGER="${(ps:<CHAR>:)pager}"
    - Surely others...

    The first two are equivalent, and the third is useful if you want
to fold the array using <CHAR> instead of '\n'. What I want is not a
way of converting the array to an scalar, but a way of doing that
*automatically*, as is already done with PATH or any other colon
delimited variable ;))

    Raúl Núñez de Arenas Coronado

-- 
Linux Registered User 88736
http://www.pleyades.net & http://raul.pleyades.net/


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Problem with an exported array
  2003-09-22 14:22         ` Bart Schaefer
  2003-09-22 14:45           ` Danek Duvall
  2003-09-22 15:52           ` Peter Stephenson
@ 2003-09-22 16:33           ` DervishD
  2 siblings, 0 replies; 22+ messages in thread
From: DervishD @ 2003-09-22 16:33 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Zsh

    Hi Bart :)

 * Bart Schaefer <schaefer@brasslantern.com> dixit:
> } typeset -S PAGER pager
> Why not make it fully general, e.g.
> 	typeset -T -S ' ' PAGER pager

    I was going to suggest it ;)), that '-S' doesn't specify 'fold in
spaces instead of colons', but just 'fold in the following char',
while -T means, like now, 'tie both vars, folding them in the way'.
If no '-S' is specified, or if the char is missing (don't know how
zsh handles those options), then use the colon as the character.

    Nice idea ;))

    Raúl Núñez de Arenas Coronado

-- 
Linux Registered User 88736
http://www.pleyades.net & http://raul.pleyades.net/


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Problem with an exported array
  2003-09-22 15:52           ` Peter Stephenson
@ 2003-09-22 17:44             ` DervishD
  2003-09-22 18:03               ` Bart Schaefer
  2003-09-22 19:28             ` Wayne Davison
  2003-09-23  7:57             ` Oliver Kiddle
  2 siblings, 1 reply; 22+ messages in thread
From: DervishD @ 2003-09-22 17:44 UTC (permalink / raw)
  To: Peter Stephenson; +Cc: Zsh

    Hi Peter :)

 * Peter Stephenson <pws@csr.com> dixit:
> > 	typeset -T -S ' ' PAGER pager
> As I said before, there's nowhere in struct param to store the
> character; else it's not that hard.  Maybe you can see a trick.

    Surely I'm clueless, but other options in other builtins have
characters or numbers following an option: where are they stored? In
fact, the typeset builtin has '-m', where is the pattern stored?.
I've not read much of the zsh code, sorry :((

    Raúl Núñez de Arenas Coronado

-- 
Linux Registered User 88736
http://www.pleyades.net & http://raul.pleyades.net/


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Problem with an exported array
  2003-09-22 14:45           ` Danek Duvall
  2003-09-22 16:30             ` DervishD
@ 2003-09-22 17:58             ` Bart Schaefer
  2003-09-22 18:06               ` Danek Duvall
  1 sibling, 1 reply; 22+ messages in thread
From: Bart Schaefer @ 2003-09-22 17:58 UTC (permalink / raw)
  To: Zsh

On Sep 22,  7:45am, Danek Duvall wrote:
} Subject: Re: Problem with an exported array
}
} On Mon, Sep 22, 2003 at 02:22:08PM +0000, Bart Schaefer wrote:
} 
} > Why not make it fully general, e.g.
} > 
} > 	typeset -T -S ' ' PAGER pager

PWS already answered this, which I could have if I'd read the patch more
closely to begin with ...

} Or, yet more generally, specify a function to transform the array into
} the scalar?

Aside from the problem PWS explained, that's creeping into the realm
of "discipline functions" which ksh supports.  That'll probably be
added to zsh at some point in the future.


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Problem with an exported array
  2003-09-22 17:44             ` DervishD
@ 2003-09-22 18:03               ` Bart Schaefer
  2003-09-23  7:52                 ` DervishD
  0 siblings, 1 reply; 22+ messages in thread
From: Bart Schaefer @ 2003-09-22 18:03 UTC (permalink / raw)
  To: Zsh

On Sep 22,  7:44pm, DervishD wrote:
}
} > As I said before, there's nowhere in struct param to store the
} > character; else it's not that hard.  Maybe you can see a trick.
} 
}     Surely I'm clueless, but other options in other builtins have
} characters or numbers following an option: where are they stored?

By "stored" PWS here means "preserved for the entire life of the
variable, so that every time $pager is assigned we remember what to
use to transform it to $PAGER."

Other commands only have to "store" the option for the lifetime of
the command execution, not potentially forever.  There's a generic
mechanism for that, shared by all builtin commands.

If the only choices are colon or space, a one-bit boolean flag in an
existing flag word is sufficient; if it's a character (or a function)
that has to be stored in some new location that doesn't yet exist.


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Problem with an exported array
  2003-09-22 17:58             ` Bart Schaefer
@ 2003-09-22 18:06               ` Danek Duvall
  0 siblings, 0 replies; 22+ messages in thread
From: Danek Duvall @ 2003-09-22 18:06 UTC (permalink / raw)
  To: Zsh

On Mon, Sep 22, 2003 at 05:58:26PM +0000, Bart Schaefer wrote:

> } Or, yet more generally, specify a function to transform the array
> } into the scalar?
> 
> Aside from the problem PWS explained, that's creeping into the realm
> of "discipline functions" which ksh supports.  That'll probably be
> added to zsh at some point in the future.

Ah, yes.  I knew there was a todo/wishlist item for something like this,
but couldn't remember the name.  That is in fact what I was thinking of
when I made the suggestion, and am completely happy to wait for that,
whether it comes soon or not.  :)

Thanks,
Danek


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Problem with an exported array
  2003-09-22 15:52           ` Peter Stephenson
  2003-09-22 17:44             ` DervishD
@ 2003-09-22 19:28             ` Wayne Davison
  2003-09-23  9:44               ` Peter Stephenson
  2003-09-23  7:57             ` Oliver Kiddle
  2 siblings, 1 reply; 22+ messages in thread
From: Wayne Davison @ 2003-09-22 19:28 UTC (permalink / raw)
  To: Peter Stephenson; +Cc: Zsh

[-- Attachment #1: Type: text/plain, Size: 750 bytes --]

On Mon, Sep 22, 2003 at 04:52:16PM +0100, Peter Stephenson wrote:
> As I said before, there's nowhere in struct param to store the
> character; else it's not that hard.  Maybe you can see a trick.

Here's my trick: use "ct" (it's already multi-use).  A tied variable is
already excluded from being a special type of integer, so my change just
excludes the "ct" from being taken as a field width.  See if you can see
any problems with this.

I didn't document it yet, but the -S option currently takes an integer
because that was the only option-parsing currently supported.  If folks
like this kludge, that can be improved.

Example usage:

    typeset -T -S 32 PAGER pager

That would space-separate the $PAGER var from the $pager array.

..wayne..

[-- Attachment #2: tiedarray.patch --]
[-- Type: text/plain, Size: 7469 bytes --]

--- Src/builtin.c	11 Sep 2003 07:00:07 -0000	1.105
+++ Src/builtin.c	22 Sep 2003 19:21:29 -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:%S:%TUZ:%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"),
@@ -1718,7 +1718,7 @@
 	usepm = 0;
     }
 
-    /* attempting a type conversion, or making a tied colonarray? */
+    /* attempting a type conversion, or making a tied array? */
     tc = 0;
     if (usepm || newspecial != NS_NONE) {
 	int chflags = ((off & pm->flags) | (on & ~pm->flags)) &
@@ -1830,7 +1830,7 @@
 	pm->flags = (pm->flags | (on & ~PM_READONLY)) & ~(off | PM_UNSET);
 	/* This auxlen/pm->ct stuff is a nasty hack. */
 	if ((on & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z | PM_INTEGER |
-		   PM_EFLOAT | PM_FFLOAT)) &&
+		   PM_EFLOAT | PM_FFLOAT | PM_TIED)) &&
 	    auxlen)
 	    pm->ct = auxlen;
 	if (!(pm->flags & (PM_ARRAY|PM_HASHED))) {
@@ -1994,11 +1994,11 @@
     if (altpm && PM_TYPE(pm->flags) == PM_SCALAR) {
 	/*
 	 * It seems safer to set this here than in createparam(),
-	 * to make sure we only ever use the colonarr functions
+	 * to make sure we only ever use the tiedarr functions
 	 * when u.data is correctly set.
 	 */
-	pm->sets.cfn = colonarrsetfn;
-	pm->gets.cfn = colonarrgetfn;
+	pm->sets.cfn = tiedarrsetfn;
+	pm->gets.cfn = tiedarrgetfn;
 	pm->u.data = &altpm->u.arr;
     }
 
@@ -2168,6 +2168,9 @@
 	    return 1;
 	}
 
+	if (!auxlen)
+	    auxlen = ':';
+
 	if (!(asg = getasg(argv[0]))) {
 	    unqueue_signals();
 	    return 1;
@@ -2217,7 +2220,7 @@
 	    return 1;
 	}
 	/*
-	 * Create the tied colonarray.  We make it as a normal scalar
+	 * Create the tied array.  We make it as a normal scalar
 	 * and fix up the oddities later.
 	 */
 	if (!(pm=typeset_single(name, asg0.name,
--- Src/params.c	30 Aug 2003 19:00:20 -0000	1.72
+++ Src/params.c	22 Sep 2003 19:21:30 -0000
@@ -208,7 +208,7 @@
 IPDEF7("SPROMPT", &sprompt),
 IPDEF7("0", &argzero),
 
-#define IPDEF8(A,B,C,D) {NULL,A,D|PM_SCALAR|PM_SPECIAL,BR((void *)B),SFN(colonarrsetfn),GFN(colonarrgetfn),stdunsetfn,0,NULL,C,NULL,0}
+#define IPDEF8(A,B,C,D) {NULL,A,D|PM_SCALAR|PM_SPECIAL,BR((void *)B),SFN(tiedarrsetfn),GFN(tiedarrgetfn),stdunsetfn,':',NULL,C,NULL,0}
 IPDEF8("CDPATH", &cdpath, "cdpath", 0),
 IPDEF8("FIGNORE", &fignore, "fignore", 0),
 IPDEF8("FPATH", &fpath, "fpath", 0),
@@ -2584,15 +2584,15 @@
 
 /**/
 char *
-colonarrgetfn(Param pm)
+tiedarrgetfn(Param pm)
 {
     char ***dptr = (char ***)pm->u.data;
-    return *dptr ? zjoin(*dptr, ':', 1) : "";
+    return *dptr ? zjoin(*dptr, pm->ct, 1) : "";
 }
 
 /**/
 void
-colonarrsetfn(Param pm, char *x)
+tiedarrsetfn(Param pm, char *x)
 {
     char ***dptr = (char ***)pm->u.data;
 
@@ -2603,7 +2603,7 @@
      */
     if (*dptr)
 	freearray(*dptr);
-    *dptr = x ? colonsplit(x, pm->flags & PM_UNIQUE) :
+    *dptr = x ? tiedsplit(x, pm->ct, pm->flags & PM_UNIQUE) :
 	(pm->flags & PM_TIED) ? NULL : mkarray(NULL);
     if (pm->ename)
 	arrfixenv(pm->nam, *dptr);
@@ -3209,7 +3209,7 @@
      */
 
     if (pm->flags & PM_EXPORTED)
-	pm->env = addenv(s, t ? zjoin(t, ':', 1) : "", pm->flags);
+	pm->env = addenv(s, t ? zjoin(t, pm->ct, 1) : "", pm->flags);
 }
 
 
--- Src/subst.c	30 Aug 2003 19:12:18 -0000	1.36
+++ Src/subst.c	22 Sep 2003 19:21:31 -0000
@@ -1637,7 +1637,8 @@
 		 * Bet that's easier said than done.
 		 */
 		val = getstrvalue(v);
-		fwidth = v->pm->ct ? v->pm->ct : strlen(val);
+		fwidth = !(v->pm->flags & (PM_TIED|PM_SPECIAL)) && v->pm->ct?
+			 v->pm->ct : strlen(val);
 		switch (v->pm->flags & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z)) {
 		    char *t;
 		    unsigned int t0;
--- Src/utils.c	1 Aug 2003 16:29:21 -0000	1.53
+++ Src/utils.c	22 Sep 2003 19:21:32 -0000
@@ -1806,26 +1806,26 @@
     return ret;
 }
 
-/* Split a string containing a colon separated list *
+/* Split a string containing a "sep" separated list *
  * of items into an array of strings.               */
 
 /**/
 char **
-colonsplit(char *s, int uniq)
+tiedsplit(char *s, char sep, int uniq)
 {
     int ct;
     char *t, **ret, **ptr, **p;
 
-    for (t = s, ct = 0; *t; t++) /* count number of colons */
-	if (*t == ':')
+    for (t = s, ct = 0; *t; t++) /* count number of seps */
+	if (*t == sep)
 	    ct++;
     ptr = ret = (char **) zalloc(sizeof(char **) * (ct + 2));
 
     t = s;
     do {
 	s = t;
-        /* move t to point at next colon */
-	for (; *t && *t != ':'; t++);
+	/* move t to point at next sep */
+	for (; *t && *t != sep; t++);
 	if (uniq)
 	    for (p = ret; p < ptr; p++)
 		if (strlen(*p) == t - s && ! strncmp(*p, s, t - s))
--- Src/zsh.h	3 Sep 2003 10:15:36 -0000	1.49
+++ Src/zsh.h	22 Sep 2003 19:21:33 -0000
@@ -1191,24 +1191,25 @@
 #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_TIED_SEP 	(1<<17)	/* Character to use when joining array.     */
 
 /* 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"
+#define TYPESET_OPTNUM "LRZiEFS"
 
 /* Flags for extracting elements of arrays and associative arrays */
 #define SCANPM_WANTVALS   (1<<0)

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Problem with an exported array
  2003-09-22 18:03               ` Bart Schaefer
@ 2003-09-23  7:52                 ` DervishD
  0 siblings, 0 replies; 22+ messages in thread
From: DervishD @ 2003-09-23  7:52 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Zsh

    Hi Bart :)

 * Bart Schaefer <schaefer@brasslantern.com> dixit:
> } > As I said before, there's nowhere in struct param to store the
> } > character; else it's not that hard.  Maybe you can see a trick.
> }     Surely I'm clueless, but other options in other builtins have
> } characters or numbers following an option: where are they stored?
> By "stored" PWS here means "preserved for the entire life of the
> variable, so that every time $pager is assigned we remember what to
> use to transform it to $PAGER."

    OK, gotcha. I didn't think about it, although it's obvious: every
assignment must be 'synced' with the other variable, so the joining
character must be permanent stored, not only during the execution of
typeset. Thanks for the explanation :)

    Raúl Núñez de Arenas Coronado

-- 
Linux Registered User 88736
http://www.pleyades.net & http://raul.pleyades.net/


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Problem with an exported array
  2003-09-22 15:52           ` Peter Stephenson
  2003-09-22 17:44             ` DervishD
  2003-09-22 19:28             ` Wayne Davison
@ 2003-09-23  7:57             ` Oliver Kiddle
  2003-09-23 16:02               ` Peter Stephenson
  2 siblings, 1 reply; 22+ messages in thread
From: Oliver Kiddle @ 2003-09-23  7:57 UTC (permalink / raw)
  To: Zsh

Peter wrote:
> Bart Schaefer wrote:
> > Why not make it fully general, e.g.
> > 
> > 	typeset -T -S ' ' PAGER pager
> 
> As I said before, there's nowhere in struct param to store the
> character; else it's not that hard.  Maybe you can see a trick.

It would probably be better to use this syntax though even if we have to
restrict the separator to space and colon for the time being until the
parameter code is more flexible.

-d would probably be a better choice than -S though (consistent with
read and externals like cut).

As for the ct suggestion, I'm not sure which I'm less likely to need: a
separator other than space and colon or field widths on a tied array. I
think I may have wanted a semi-colon once on Cygwin but we do risk
breaking existing scripts.

Oliver


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Problem with an exported array
  2003-09-22 19:28             ` Wayne Davison
@ 2003-09-23  9:44               ` Peter Stephenson
  0 siblings, 0 replies; 22+ messages in thread
From: Peter Stephenson @ 2003-09-23  9:44 UTC (permalink / raw)
  To: Zsh

Wayne Davison wrote:
> Here's my trick: use "ct" (it's already multi-use).  A tied variable is
> already excluded from being a special type of integer, so my change just
> excludes the "ct" from being taken as a field width.  See if you can see
> any problems with this.

This does break the existing function,

% typeset -T FOO foo
% foo=(bar rod)
% typeset -R 15 FOO
% print $FOO
        bar:rod

and (unless you've taken special steps to fix it) you run the risk of
the ct element being used for both when you request `typeset -R 15 FOO'.

However, you only need eight bits (until we have wide characters, which
is another future nightmare) and ct is at least 32, so it's
tantalising...

I would be tempted to add -S as a single flag now and wait until we have
a better (virtual) interface to the parameters, then add a more
general flag.  As Oliver says, a different option letter would be more
appropriate for the general case anyway.

Eventually, I'd like struct param to become opaque to code outside
params.c and use something like a single (vtable-style) pointer for
type-specific bits.

-- 
Peter Stephenson <pws@csr.com>                  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.
**********************************************************************


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Problem with an exported array
  2003-09-23  7:57             ` Oliver Kiddle
@ 2003-09-23 16:02               ` Peter Stephenson
  2003-09-24 13:09                 ` DervishD
  0 siblings, 1 reply; 22+ messages in thread
From: Peter Stephenson @ 2003-09-23 16:02 UTC (permalink / raw)
  To: Zsh hackers list

As a consequence of a somewhat tangential discussion with Oliver, here
is a new proposal for tied arrays which should satisfy all the
requirements.

There is no new option; instead, the split/join character is given as
the third argument, which was previously an error so is entirely
backwardly compatible:

typeset -T PAGER pager ' '

Internally, instead of storing just the pointer to the array, we
allocate a new structure for both that and the join character and store
a pointer to that.  We then just have to remember to free the new
structure when we unset the parameter, so there's a new unset function.

I tried to be careful with the possibility that the join character could
be an arbitrary eight-bit character.

The second zsh hunk is now irrelevant but a bit neater than before.

I fixed the problem that setting using the scalar didn't respect -U by
brute force.

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	23 Sep 2003 15:58:33 -0000
@@ -1160,7 +1160,7 @@
 xitem(tt(typeset) [ {tt(PLUS())|tt(-)}tt(AEFHLRUZafghilprtuxm) [var(n)]] [ \
 var(name)[tt(=)var(value)] ... ])
 item(tt(typeset) -T [ {tt(PLUS()|tt(-))}tt(LRUZrux) ] \
-  var(SCALAR)[tt(=)var(value)] var(array))(
+  var(SCALAR)[tt(=)var(value)] var(array) tt([) var(sep) tt(]))(
 Set or display attributes and values for shell parameters.
 
 A parameter is created for each var(name) that does not already refer
@@ -1189,20 +1189,24 @@
 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
-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
-type of one of them with another tt(typeset) command; tt(+T) does not
-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.
+If the tt(-T) option is given, two or three arguments must be present (an
+exception is that zero arguments are allowed to show the list of parameters
+created in this fashion).  The first two are the name of a scalar and an
+array parameter (in that order) that will be tied together in the manner of
+tt($PATH) and tt($path).  The optional third argument is a single-character
+separator which will be used to join the elements of the array to form the
+scalar; if absent, a colon is used, as with tt($PATH).  Only the first
+character of the separator is significant; any remaining characters are
+ignored.  Only the scalar parameter may be assigned 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 type of one
+of them with another tt(typeset) command; tt(+T) does not 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.  Setting the value using the scalar version causes a split on all
+separators (which cannot be quoted).
 
 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	23 Sep 2003 15:58:34 -0000
@@ -1677,7 +1677,7 @@
 static Param
 typeset_single(char *cname, char *pname, Param pm, int func,
 	       int on, int off, int roff, char *value, Param altpm,
-	       Options ops, int auxlen)
+	       Options ops, int auxlen, int joinchar)
 {
     int usepm, tc, keeplocal = 0, newspecial = NS_NONE, readonly;
     char *subscript;
@@ -1997,9 +1997,17 @@
 	 * to make sure we only ever use the colonarr functions
 	 * when u.data is correctly set.
 	 */
-	pm->sets.cfn = colonarrsetfn;
-	pm->gets.cfn = colonarrgetfn;
-	pm->u.data = &altpm->u.arr;
+	struct tieddata *tdp = (struct tieddata *)
+	    zalloc(sizeof(struct tieddata));
+	if (!tdp)
+	    return NULL;
+	tdp->joinchar = joinchar;
+	tdp->arrptr = &altpm->u.arr;
+
+	pm->sets.cfn = tiedarrsetfn;
+	pm->gets.cfn = tiedarrgetfn;
+	pm->unsetfn = tiedarrunsetfn;
+	pm->u.data = tdp;
     }
 
     if (keeplocal)
@@ -2155,6 +2163,7 @@
 	Param apm;
 	struct asgment asg0;
 	char *oldval = NULL;
+	int joinchar;
 
 	if (OPT_ISSET(ops,'m')) {
 	    zwarnnam(name, "incompatible options for -T", NULL, 0);
@@ -2162,12 +2171,25 @@
 	    return 1;
 	}
 	on &= ~off;
-	if (!argv[1] || argv[2]) {
+	if (!argv[1] || argv[3]) {
 	    zwarnnam(name, "-T requires names of scalar and array", NULL, 0);
 	    unqueue_signals();
 	    return 1;
 	}
 
+	/*
+	 * Third argument, if given, is character used to join
+	 * the elements of the array in the scalar.
+	 */
+	if (!argv[2])
+	    joinchar = ':';
+	else if (!*argv[2])
+	    joinchar = 0;
+	else if (*argv[2] == Meta)
+	    joinchar = argv[2][1] ^ 32;
+	else
+	    joinchar = *argv[2];
+
 	if (!(asg = getasg(argv[0]))) {
 	    unqueue_signals();
 	    return 1;
@@ -2212,7 +2234,8 @@
 				 (Param)paramtab->getnode(paramtab,
 							  asg->name),
 				 func, (on | PM_ARRAY) & ~PM_EXPORTED,
-				 off, roff, asg->value, NULL, ops, auxlen))) {
+				 off, roff, asg->value, NULL, ops, auxlen,
+				 0))) {
 	    unqueue_signals();
 	    return 1;
 	}
@@ -2224,7 +2247,7 @@
 				(Param)paramtab->getnode(paramtab,
 							 asg0.name),
 				func, on, off, roff, asg0.value, apm,
-				ops, auxlen))) {
+				ops, auxlen, joinchar))) {
 	    if (oldval)
 		zsfree(oldval);
 	    unsetparam_pm(apm, 1, 1);
@@ -2291,7 +2314,7 @@
 	    for (pmnode = firstnode(pmlist); pmnode; incnode(pmnode)) {
 		pm = (Param) getdata(pmnode);
 		if (!typeset_single(name, pm->nam, pm, func, on, off, roff,
-				    asg->value, NULL, ops, auxlen))
+				    asg->value, NULL, ops, auxlen, 0))
 		    returnval = 1;
 	    }
 	}
@@ -2306,7 +2329,7 @@
 				     gethashnode2(paramtab, asg->name) :
 				     paramtab->getnode(paramtab, asg->name)),
 			    func, on, off, roff, asg->value, NULL,
-			    ops, auxlen))
+			    ops, auxlen, 0))
 	    returnval = 1;
     }
     unqueue_signals();
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	23 Sep 2003 15:58:34 -0000
@@ -2595,22 +2595,77 @@
 colonarrsetfn(Param pm, char *x)
 {
     char ***dptr = (char ***)pm->u.data;
-
     /*
-     * If this is tied to a parameter (rather than internal) array,
-     * the array itself may be NULL.  Otherwise, we have to make
-     * sure it doesn't ever get null.
+     * We have to make sure this is never NULL, since that
+     * can cause problems.
      */
     if (*dptr)
 	freearray(*dptr);
-    *dptr = x ? colonsplit(x, pm->flags & PM_UNIQUE) :
-	(pm->flags & PM_TIED) ? NULL : mkarray(NULL);
+    if (x)
+	*dptr = colonsplit(x, pm->flags & PM_UNIQUE);
+    else
+	*dptr = mkarray(NULL);
     if (pm->ename)
 	arrfixenv(pm->nam, *dptr);
     zsfree(x);
 }
 
 /**/
+char *
+tiedarrgetfn(Param pm)
+{
+    struct tieddata *dptr = (struct tieddata *)pm->u.data;
+    return *dptr->arrptr ? zjoin(*dptr->arrptr, dptr->joinchar, 1) : "";
+}
+
+/**/
+void
+tiedarrsetfn(Param pm, char *x)
+{
+    struct tieddata *dptr = (struct tieddata *)pm->u.data;
+
+    if (*dptr->arrptr)
+	freearray(*dptr->arrptr);
+    if (x) {
+	char sepbuf[3];
+	if (imeta(dptr->joinchar))
+	{
+	    sepbuf[0] = Meta;
+	    sepbuf[1] = dptr->joinchar;
+	    sepbuf[2] = '\0';
+	}
+	else
+	{
+	    sepbuf[0] = dptr->joinchar;
+	    sepbuf[1] = '\0';
+	}
+	*dptr->arrptr = sepsplit(x, sepbuf, 0, 0);
+	if (pm->flags & PM_UNIQUE)
+	    uniqarray(*dptr->arrptr);
+    } else
+	*dptr->arrptr = NULL;
+    if (pm->ename)
+	arrfixenv(pm->nam, *dptr->arrptr);
+    zsfree(x);
+}
+
+/**/
+void
+tiedarrunsetfn(Param pm, int exp)
+{
+    /*
+     * Special unset function because we allocated a struct tieddata
+     * in typeset_single to hold the special data which we now
+     * need to delete.
+     */
+    pm->sets.cfn(pm, NULL);
+    zfree(pm->u.data, sizeof(struct tieddata));
+    /* paranoia -- shouldn't need these, but in case we reuse the struct... */
+    pm->u.data = NULL;
+    pm->flags &= ~PM_TIED;
+}
+
+/**/
 void
 uniqarray(char **x)
 {
@@ -3187,6 +3242,7 @@
 arrfixenv(char *s, char **t)
 {
     Param pm;
+    int joinchar;
 
     if (t == path)
 	cmdnamtab->emptytable(cmdnamtab);
@@ -3208,8 +3264,15 @@
      * Do not "fix" parameters that were not exported
      */
 
-    if (pm->flags & PM_EXPORTED)
-	pm->env = addenv(s, t ? zjoin(t, ':', 1) : "", pm->flags);
+    if (!(pm->flags & PM_EXPORTED))
+	return;
+
+    if (pm->flags & PM_TIED)
+	joinchar = ((struct tieddata *)pm->u.data)->joinchar;
+    else
+	joinchar = ':';
+
+    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	23 Sep 2003 15:58:34 -0000
@@ -1793,14 +1793,20 @@
     char **s, *ret, *ptr;
 
     for (s = arr; *s; s++)
-	len += strlen(*s) + 1;
+	len += strlen(*s) + 1 + (imeta(delim) ? 1 : 0);
     if (!len)
 	return heap? "" : ztrdup("");
     ptr = ret = (heap ? (char *) hcalloc(len) : (char *) zcalloc(len));
     for (s = arr; *s; s++) {
 	strucpy(&ptr, *s);
-	if (delim)
-	    *ptr++ = delim;
+	if (delim) {
+	    if (imeta(delim)) {
+		*ptr++ = Meta;
+		*ptr++ = delim ^ 32;
+	    }
+	    else
+		*ptr++ = delim;
+	}
     }
     ptr[-1] = '\0';
     return ret;
@@ -1856,7 +1862,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	23 Sep 2003 15:58:34 -0000
@@ -1156,6 +1156,12 @@
     int level;			/* if (old != NULL), level of localness  */
 };
 
+/* structure stored in struct param's u.data by tied arrays */
+struct tieddata {
+    char ***arrptr;		/* pointer to corresponding array */
+    int joinchar;		/* character used to join arrays */
+};
+
 /* flags for parameters */
 
 /* parameter types */
@@ -1193,16 +1199,16 @@
 #define PM_TIED 	(1<<16)	/* array tied to colon-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"


-- 
Peter Stephenson <pws@csr.com>                  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.
**********************************************************************


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Problem with an exported array
  2003-09-23 16:02               ` Peter Stephenson
@ 2003-09-24 13:09                 ` DervishD
  0 siblings, 0 replies; 22+ messages in thread
From: DervishD @ 2003-09-24 13:09 UTC (permalink / raw)
  To: Peter Stephenson; +Cc: Zsh hackers list

    Hi Peter :)

 * Peter Stephenson <pws@csr.com> dixit:
> There is no new option; instead, the split/join character is given as
> the third argument, which was previously an error so is entirely
> backwardly compatible:
> typeset -T PAGER pager ' '

    Good!!! I prefer this notation. Thanks a lot for your interest
:))
 
    Raúl Núñez de Arenas Coronado

-- 
Linux Registered User 88736
http://www.pleyades.net & http://raul.pleyades.net/


^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2003-09-24 13:59 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-09-22  8:30 Problem with an exported array DervishD
2003-09-22  9:08 ` Oliver Kiddle
2003-09-22  9:31   ` DervishD
2003-09-22  9:48   ` Peter Stephenson
2003-09-22 11:33     ` DervishD
2003-09-22 13:44       ` Peter Stephenson
2003-09-22 14:04         ` DervishD
2003-09-22 14:22         ` Bart Schaefer
2003-09-22 14:45           ` Danek Duvall
2003-09-22 16:30             ` DervishD
2003-09-22 17:58             ` Bart Schaefer
2003-09-22 18:06               ` Danek Duvall
2003-09-22 15:52           ` Peter Stephenson
2003-09-22 17:44             ` DervishD
2003-09-22 18:03               ` Bart Schaefer
2003-09-23  7:52                 ` DervishD
2003-09-22 19:28             ` Wayne Davison
2003-09-23  9:44               ` Peter Stephenson
2003-09-23  7:57             ` Oliver Kiddle
2003-09-23 16:02               ` Peter Stephenson
2003-09-24 13:09                 ` DervishD
2003-09-22 16:33           ` DervishD

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).