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

PATCH: typeset -n -H



On Sat, Feb 1, 2025 at 5:42 PM Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> wrote:
>
> On Fri, Jan 31, 2025 at 11:19 PM Oliver Kiddle <opk@xxxxxxx> wrote:
> >
> > Much as with -r, typeset -nH ref or typeset -n +H ref should apply to
> > the reference while typeset -H ref (where ref is a pre-existing
> > reference) should apply to the referant (unless that's unset).
>
> This is very easily accomplished in the code.
> [...]
> > >                 /* It's generally unwise to mass-change the types of
> > >                  * parameters, but for namerefs it would be fatal */
> >
> > If that's explicitly singled-out rather than part of a catch-all
> > condition, the error message might be clearer.
>
> I'll look at some way to change this without repeating the error for
> every parameter name that matches the pattern.
>
> Should it repeat for every option that isn't allowed if the user has
> specified a whole raft of option flags?

The attached patch adds the above, reporting each option that clashes
if there is more than one.  That's easily changed to report only the
first one found, see commented /* return 1; */ in the related hunk.

Having changed those error messages, I made the -n -m error message
correspond, and updated the test.

Doc patch includes a couple of other small clarifications.
diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo
index 7a9684ac8..69bb86a0f 100644
--- a/Doc/Zsh/builtins.yo
+++ b/Doc/Zsh/builtins.yo
@@ -2052,8 +2052,10 @@ cindex(named reference)
 cindex(reference, named)
 The flag tt(-n) creates a em(named reference) to another parameter.
 The second parameter need not exist at the time the reference is
-created.  Only tt(-g), tt(-u), and tt(-r) may be used in conjunction with
-tt(-n).  The var(name) so created may not be an array element nor use
+created.  Only the tt(-H), tt(-g), and tt(-r) flags may be used in
+conjunction with tt(-n), having their usual meanings.  The tt(-u)
+flag is special and may be applied to alter the scope of the reference.
+The var(name) so created may not be an array element nor use
 a subscript, but the var(value) assigned may be any valid parameter
 name syntax, even a subscripted array element (including an associative
 array element) or an array slice, which is evaluated when the named
@@ -2286,7 +2288,7 @@ special tt(PATH) parameter is not altered in any way.  It is also possible
 to create a local parameter using `tt(typeset +h )var(special)', where the
 local copy of var(special) will retain its special properties regardless of
 having the tt(-h) attribute.  Global special parameters loaded from shell
-modules (currently those in tt(zsh/mapfile) and tt(zsh/parameter)) are
+modules (for example, those in tt(zsh/mapfile) and tt(zsh/parameter)) are
 automatically given the tt(-h) attribute to avoid name clashes.
 )
 item(tt(-H))(
@@ -2349,7 +2351,7 @@ flag has a different meaning when used with tt(-f); see above.
 item(tt(-u))(
 Convert the result to upper case whenever the parameter is expanded.
 The value is em(not) converted when assigned.
-This flag has a different meaning when used with tt(-f); see above.
+This flag has different meanings when used with tt(-f) or tt(-n); see above.
 )
 item(tt(-x))(
 Mark for automatic export to the environment of subsequently
diff --git a/Src/builtin.c b/Src/builtin.c
index 18d74b09e..2fab73b24 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -2707,10 +2707,18 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func)
 	    on |= bit;
 	else if (OPT_PLUS(ops,optval))
 	    off |= bit;
+	else
+	    continue;
+	if (OPT_MINUS(ops,'n')) {
+	    if ((on|off) & ~(PM_READONLY|PM_UPPER|PM_HIDEVAL)) {
+		zwarnnam(name, "-%c not allowed with -n", optval);
+		/* return 1; */
+	    }
+	}
     }
     if (OPT_MINUS(ops,'n')) {
-	if ((on|off) & ~(PM_READONLY|PM_UPPER)) {
-	    zwarnnam(name, "no other attributes allowed with -n");
+	if ((on|off) & ~(PM_READONLY|PM_UPPER|PM_HIDEVAL)) {
+	    /* zwarnnam(name, "no other attributes allowed with -n"); */
 	    return 1;
 	}
 	on |= PM_NAMEREF;
@@ -3049,7 +3057,8 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func)
 		/* It's generally unwise to mass-change the types of
 		 * parameters, but for namerefs it would be fatal */
 		unqueue_signals();
-		zerrnam(name, "invalid reference");
+		zerrnam(name, "%cm not allowed with -n",
+			(OPT_PLUS(ops,'m') ? '+' : '-'));
 		return 1;
 	    }
 	    if (!(on|roff))
diff --git a/Test/K01nameref.ztst b/Test/K01nameref.ztst
index bb0d11821..bacc3ade2 100644
--- a/Test/K01nameref.ztst
+++ b/Test/K01nameref.ztst
@@ -853,7 +853,7 @@ F:previously this could create an infinite recursion and crash
 
  typeset -nm foo=bar
 1:create nameref by pattern match not allowed
-*?*typeset:1: invalid reference
+*?*typeset:1: -m not allowed with -n
 
 #
 # The following tests are run in interactive mode, using PS1 as an


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