1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-07-06 03:01:26 +02:00

51431: "typeset -p" shouldn't change parameter flags

This commit is contained in:
Bart Schaefer 2023-02-20 10:32:40 -08:00
parent 76be800073
commit d2768f2f88
2 changed files with 37 additions and 13 deletions

View file

@ -1,3 +1,7 @@
2023-02-20 Bart Schaefer <schaefer@zsh.org>
* 51431: Src/builtin.c: "typeset -p" shouldn't change parameter flags
2023-02-19 Oliver Kiddle <opk@zsh.org> 2023-02-19 Oliver Kiddle <opk@zsh.org>
* 51456: Completion/Unix/Command/_git: complete only modified * 51456: Completion/Unix/Command/_git: complete only modified

View file

@ -2106,6 +2106,11 @@ typeset_single(char *cname, char *pname, Param pm, int func,
return NULL; return NULL;
} }
tc = 1; tc = 1;
if (OPT_MINUS(ops,'p'))
usepm = (on & pm->node.flags);
else if (OPT_PLUS(ops,'p'))
usepm = (off & pm->node.flags);
else
usepm = 0; usepm = 0;
} }
else if (usepm || newspecial != NS_NONE) { else if (usepm || newspecial != NS_NONE) {
@ -2113,10 +2118,17 @@ typeset_single(char *cname, char *pname, Param pm, int func,
(PM_INTEGER|PM_EFLOAT|PM_FFLOAT|PM_HASHED| (PM_INTEGER|PM_EFLOAT|PM_FFLOAT|PM_HASHED|
PM_ARRAY|PM_TIED|PM_AUTOLOAD); PM_ARRAY|PM_TIED|PM_AUTOLOAD);
/* keep the parameter if just switching between floating types */ /* keep the parameter if just switching between floating types */
if ((tc = chflags && chflags != (PM_EFLOAT|PM_FFLOAT))) if ((tc = chflags && chflags != (PM_EFLOAT|PM_FFLOAT))) {
if (OPT_MINUS(ops,'p'))
usepm = (on & pm->node.flags);
else if (OPT_PLUS(ops,'p'))
usepm = (off & pm->node.flags);
else
usepm = 0; usepm = 0;
} }
}
/* /*
* Extra checks if converting the type of a parameter, or if * Extra checks if converting the type of a parameter, or if
* trying to remove readonlyness. It's dangerous doing either * trying to remove readonlyness. It's dangerous doing either
@ -2166,11 +2178,14 @@ typeset_single(char *cname, char *pname, Param pm, int func,
} }
if (err) if (err)
{ {
zerrnam(cname, "%s: can't change type of a special parameter", if (!OPT_ISSET(ops,'p'))
zerrnam(cname,
"%s: can't change type of a special parameter",
pname); pname);
return NULL; return NULL;
} }
} else if (pm->node.flags & PM_AUTOLOAD) { } else if (pm->node.flags & PM_AUTOLOAD) {
if (!OPT_ISSET(ops,'p'))
zerrnam(cname, "%s: can't change type of autoloaded parameter", zerrnam(cname, "%s: can't change type of autoloaded parameter",
pname); pname);
return NULL; return NULL;
@ -2208,6 +2223,10 @@ typeset_single(char *cname, char *pname, Param pm, int func,
* ii. we are creating a new local parameter * ii. we are creating a new local parameter
*/ */
if (usepm) { if (usepm) {
if (OPT_MINUS(ops,'p') && on && !(on & pm->node.flags))
return NULL;
else if (OPT_PLUS(ops,'p') && off && !(off & pm->node.flags))
return NULL;
if ((asg->flags & ASG_ARRAY) ? if ((asg->flags & ASG_ARRAY) ?
!(PM_TYPE(pm->node.flags) & (PM_ARRAY|PM_HASHED)) : !(PM_TYPE(pm->node.flags) & (PM_ARRAY|PM_HASHED)) :
(asg->value.scalar && (PM_TYPE(pm->node.flags & (asg->value.scalar && (PM_TYPE(pm->node.flags &
@ -2254,6 +2273,10 @@ typeset_single(char *cname, char *pname, Param pm, int func,
arrfixenv(pm->node.nam, x); arrfixenv(pm->node.nam, x);
} }
} }
if (OPT_ISSET(ops,'p')) {
paramtab->printnode(&pm->node, PRINT_TYPESET);
return pm;
}
if (usepm == 2) /* do not change the PM_UNSET flag */ if (usepm == 2) /* do not change the PM_UNSET flag */
pm->node.flags = (pm->node.flags | (on & ~PM_READONLY)) & ~off; pm->node.flags = (pm->node.flags | (on & ~PM_READONLY)) & ~off;
else { else {
@ -2262,7 +2285,6 @@ typeset_single(char *cname, char *pname, Param pm, int func,
*/ */
if (!(on & PM_READONLY) || !isset(POSIXBUILTINS)) if (!(on & PM_READONLY) || !isset(POSIXBUILTINS))
off |= PM_UNSET; off |= PM_UNSET;
if (!OPT_ISSET(ops, 'p'))
pm->node.flags = (pm->node.flags | pm->node.flags = (pm->node.flags |
(on & ~PM_READONLY)) & ~off; (on & ~PM_READONLY)) & ~off;
} }
@ -2310,8 +2332,6 @@ typeset_single(char *cname, char *pname, Param pm, int func,
if (errflag) if (errflag)
return NULL; return NULL;
pm->node.flags |= (on & PM_READONLY); pm->node.flags |= (on & PM_READONLY);
if (OPT_ISSET(ops,'p'))
paramtab->printnode(&pm->node, PRINT_TYPESET);
return pm; return pm;
} }
@ -2328,7 +2348,7 @@ typeset_single(char *cname, char *pname, Param pm, int func,
* or we're converting the type of a parameter. In the * or we're converting the type of a parameter. In the
* last case only, we need to delete the old parameter. * last case only, we need to delete the old parameter.
*/ */
if (tc) { if (tc && !OPT_ISSET(ops,'p')) {
/* Maintain existing readonly/exported status... */ /* Maintain existing readonly/exported status... */
on |= ~off & (PM_READONLY|PM_EXPORTED) & pm->node.flags; on |= ~off & (PM_READONLY|PM_EXPORTED) & pm->node.flags;
/* ...but turn off existing readonly so we can delete it */ /* ...but turn off existing readonly so we can delete it */