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

[PATCH] More "typeset -p" and GLOBAL_EXPORT



On Tue, Mar 12, 2024 at 1:38 PM Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> wrote:
>
> On Tue, Mar 12, 2024 at 1:26 PM Stephane Chazelas <stephane@xxxxxxxxxxxx> wrote:
> >
> > $ zsh -c 'a() { export a; a=3; typeset -p a; }; b() { local a=2; a; typeset -p a; }; a=1; b; typeset -p a'
> > export -x a=3
> > typeset -x a=3
> > typeset a=1
> >
> > That export -x seems bogus BTW as export doesn't accept the -x
> > option.
>
> Indeed, that's a bug in the printparamnode() routine.

That's not the only bug.  As demonstrated by B02typeset.ztst in the test
  no array/hash in POSIX export/readonly -p
with a declaration in a function of
   local -rx zsh_exported_readonly_scalar=1
the output of "export -p" is
  typeset -rx zsh_exported_readonly_scalar=1

However, "local" is supposed to supersede the GLOBAL_EXPORT option, so
that should have output one of
  typeset +g -rx zsh_exported_readonly_scalar=1
or
  local -rx zsh_exported_readonly_scalar=1

The attached patch changes this (using "local").  The POSIX mode output --
  export zsh_exported_readonly_scalar=1
-- is explained by a comment:
         * The zsh variants of export -p/readonly -p also report other
         * flags to indicate other attributes or scope. The POSIX variants
         * don't.

There is also an AFAICT insurmountable problem:
  innie() { typeset -p $1 }
  outie() { local -x $1; innie $1 }
  outie var
displays
  export var=''

That is "correct" in that var is not local to outie, but that
statement cannot be evaluated to restore the state of $var anywhere
other than from functions called by innie.  Conversely:
  innie() { print ${(tP)1} }
  outie var
displays
  scalar-local-export

Which is also "correct" but fibs about $var being local to innie.
Finally we have
  innie() { typeset +m $1 }
  outie var
which agrees with the (t) flag by reporting
  local exported var

And
  innie() { typeset -m $1 }
  outie var
yielding
  var=''

No mention of export at all.

These are all long-standing behaviors and haven't caused anyone a
problem yet that I know of, so I'm not suggesting anything change,
just pointing out that this patch doesn't address them.
diff --git a/Src/params.c b/Src/params.c
index 973df3fe5..f65aa1e80 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -6044,6 +6044,7 @@ printparamnode(HashNode hn, int printflags)
 {
     Param p = (Param) hn;
     Param peer = NULL;
+    int altname = 0;
 
     if (!(p->node.flags & PM_HASHELEM) &&
 	!(printflags & PRINT_WITH_NAMESPACE) && *(p->node.nam) == '.')
@@ -6089,16 +6090,26 @@ printparamnode(HashNode hn, int printflags)
 	if (printflags & PRINT_POSIX_EXPORT) {
 	    if (!(p->node.flags & PM_EXPORTED))
 		return;
+	    altname = 'x';
 	    printf("export ");
 	} else if (printflags & PRINT_POSIX_READONLY) {
 	    if (!(p->node.flags & PM_READONLY))
 		return;
+	    altname = 'r';
 	    printf("readonly ");
-	} else if (locallevel && p->level >= locallevel) {
-	    printf("typeset ");	    /* printf("local "); */
 	} else if ((p->node.flags & PM_EXPORTED) &&
 		   !(p->node.flags & (PM_ARRAY|PM_HASHED))) {
-	    printf("export ");
+	  if (p->level && p->level >= locallevel)
+		printf("local ");
+	    else {
+		altname = 'x';
+		printf("export ");
+	    }
+	} else if (locallevel && p->level >= locallevel) {
+	    if (p->node.flags & PM_EXPORTED)
+		printf("local ");
+	    else
+		printf("typeset ");	    /* printf("local "); */
 	} else if (locallevel) {
 	    printf("typeset -g ");
 	} else
@@ -6112,6 +6123,10 @@ printparamnode(HashNode hn, int printflags)
 
 	for (pmptr = pmtypes, i = 0; i < PMTYPES_SIZE; i++, pmptr++) {
 	    int doprint = 0;
+
+	    if (altname && altname == pmptr->typeflag)
+		continue;
+
 	    if (pmptr->flags & PMTF_TEST_LEVEL) {
 		if (p->level) {
 		    /*
diff --git a/Test/B02typeset.ztst b/Test/B02typeset.ztst
index d90f17d13..914eea92b 100644
--- a/Test/B02typeset.ztst
+++ b/Test/B02typeset.ztst
@@ -311,7 +311,7 @@
  print $OUTER
 0:Export of tied parameters
 >i:n:n:e:r
->typeset -xT OUTER outer=( i n n e r )
+>local -xT OUTER outer=( i n n e r )
 >typeset -aT OUTER outer=( i n n e r )
 >OUTER=i:n:n:e:r
 >outer=( i n n e r )
@@ -1099,12 +1099,12 @@
  }
 0: no array/hash in POSIX export/readonly -p
 >zsh:
->typeset -arx zsh_exported_readonly_array=( 2 )
->typeset -Arx zsh_exported_readonly_hash=( [3]=3 )
->typeset -rx zsh_exported_readonly_scalar=1
->typeset -arx zsh_exported_readonly_array=( 2 )
->typeset -Arx zsh_exported_readonly_hash=( [3]=3 )
->typeset -rx zsh_exported_readonly_scalar=1
+>local -arx zsh_exported_readonly_array=( 2 )
+>local -Arx zsh_exported_readonly_hash=( [3]=3 )
+>local -rx zsh_exported_readonly_scalar=1
+>local -arx zsh_exported_readonly_array=( 2 )
+>local -Arx zsh_exported_readonly_hash=( [3]=3 )
+>local -rx zsh_exported_readonly_scalar=1
 >sh:
 >export zsh_exported_readonly_scalar=1
 >readonly zsh_exported_readonly_scalar=1


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