1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-10-17 00:31:09 +02:00

35059: fix, document, test readonly -p.

Don't output specials as can't be reconstructed.

Output arrays in a useful order.
This commit is contained in:
Peter Stephenson 2015-05-08 12:53:18 +01:00
parent 39aeeedb19
commit f855801fb9
4 changed files with 138 additions and 70 deletions

View file

@ -1,5 +1,9 @@
2015-05-08 Peter Stephenson <p.stephenson@samsung.com>
* 35059: Doc/Zsh/builtins.yo, Src/params.c,
Test/B02typeset.ztst: fix, document and test "readonly -p"
output for arrays and specials.
* 35056: Test/A02alias.ztst: turn off PROMPT_SP for interactive
test.

View file

@ -1785,6 +1785,11 @@ form of a typeset command and an assignment (which will be printed
separately for arrays and associative arrays), regardless of other flags
and options. Note that the tt(-H) flag on parameters is respected; no
value will be shown for these parameters.
As the intention of this option is to produce output that can restore
the current state, readonly specials (whose values cannot be
changed) are not shown and assignments to arrays are shown before
the tt(typeset) rendering the array readonly.
)
item(tt(-T) [ var(scalar)[tt(=)var(value)] var(array) [ var(sep) ] ])(
This flag has a different meaning when used with tt(-f); see below.

View file

@ -5032,78 +5032,11 @@ static const struct paramtypes pmtypes[] = {
#define PMTYPES_SIZE ((int)(sizeof(pmtypes)/sizeof(struct paramtypes)))
/**/
mod_export void
printparamnode(HashNode hn, int printflags)
static void
printparamvalue(Param p, int printflags)
{
Param p = (Param) hn;
char *t, **u;
if (p->node.flags & PM_UNSET) {
if (isset(POSIXBUILTINS) && (p->node.flags & PM_READONLY) &&
(printflags & PRINT_TYPESET))
{
/*
* Special POSIX rules: show the parameter as readonly
* even though it's unset, but with no value.
*/
printflags |= PRINT_NAMEONLY;
}
else
return;
}
if (printflags & PRINT_TYPESET)
printf("typeset ");
/* Print the attributes of the parameter */
if (printflags & (PRINT_TYPE|PRINT_TYPESET)) {
int doneminus = 0, i;
const struct paramtypes *pmptr;
for (pmptr = pmtypes, i = 0; i < PMTYPES_SIZE; i++, pmptr++) {
int doprint = 0;
if (pmptr->flags & PMTF_TEST_LEVEL) {
if (p->level)
doprint = 1;
} else if (p->node.flags & pmptr->binflag)
doprint = 1;
if (doprint) {
if (printflags & PRINT_TYPESET) {
if (pmptr->typeflag) {
if (!doneminus) {
putchar('-');
doneminus = 1;
}
putchar(pmptr->typeflag);
}
} else {
printf("%s ", pmptr->string);
}
if ((pmptr->flags & PMTF_USE_BASE) && p->base) {
printf("%d ", p->base);
doneminus = 0;
}
if ((pmptr->flags & PMTF_USE_WIDTH) && p->width) {
printf("%d ", p->width);
doneminus = 0;
}
}
}
if (doneminus)
putchar(' ');
}
if ((printflags & PRINT_NAMEONLY) ||
((p->node.flags & PM_HIDEVAL) && !(printflags & PRINT_INCLUDEVALUE))) {
zputs(p->node.nam, stdout);
putchar('\n');
return;
}
quotedzputs(p->node.nam, stdout);
if (p->node.flags & PM_AUTOLOAD) {
putchar('\n');
return;
@ -5112,7 +5045,7 @@ printparamnode(HashNode hn, int printflags)
putchar(' ');
else if ((printflags & PRINT_TYPESET) &&
(PM_TYPE(p->node.flags) == PM_ARRAY || PM_TYPE(p->node.flags) == PM_HASHED))
printf("\n%s=", p->node.nam);
printf("%s=", p->node.nam);
else
putchar('=');
@ -5171,3 +5104,108 @@ printparamnode(HashNode hn, int printflags)
else
putchar('\n');
}
/**/
mod_export void
printparamnode(HashNode hn, int printflags)
{
Param p = (Param) hn;
int array_typeset;
if (p->node.flags & PM_UNSET) {
if (isset(POSIXBUILTINS) && (p->node.flags & PM_READONLY) &&
(printflags & PRINT_TYPESET))
{
/*
* Special POSIX rules: show the parameter as readonly
* even though it's unset, but with no value.
*/
printflags |= PRINT_NAMEONLY;
}
else
return;
}
if (printflags & PRINT_TYPESET) {
if ((p->node.flags & (PM_READONLY|PM_SPECIAL)) ==
(PM_READONLY|PM_SPECIAL)) {
/*
* It's not possible to restore the state of
* these, so don't output.
*/
return;
}
/*
* Printing the value of array: this needs to be on
* a separate line so more care is required.
*/
array_typeset = (PM_TYPE(p->node.flags) == PM_ARRAY ||
PM_TYPE(p->node.flags) == PM_HASHED) &&
!(printflags & PRINT_NAMEONLY);
if (array_typeset && (p->node.flags & PM_READONLY)) {
/*
* We need to create the array before making it
* readonly.
*/
printf("typeset -a ");
zputs(p->node.nam, stdout);
putchar('\n');
printparamvalue(p, printflags);
printflags |= PRINT_NAMEONLY;
}
printf("typeset ");
}
else
array_typeset = 0;
/* Print the attributes of the parameter */
if (printflags & (PRINT_TYPE|PRINT_TYPESET)) {
int doneminus = 0, i;
const struct paramtypes *pmptr;
for (pmptr = pmtypes, i = 0; i < PMTYPES_SIZE; i++, pmptr++) {
int doprint = 0;
if (pmptr->flags & PMTF_TEST_LEVEL) {
if (p->level)
doprint = 1;
} else if (p->node.flags & pmptr->binflag)
doprint = 1;
if (doprint) {
if (printflags & PRINT_TYPESET) {
if (pmptr->typeflag) {
if (!doneminus) {
putchar('-');
doneminus = 1;
}
putchar(pmptr->typeflag);
}
} else {
printf("%s ", pmptr->string);
}
if ((pmptr->flags & PMTF_USE_BASE) && p->base) {
printf("%d ", p->base);
doneminus = 0;
}
if ((pmptr->flags & PMTF_USE_WIDTH) && p->width) {
printf("%d ", p->width);
doneminus = 0;
}
}
}
if (doneminus)
putchar(' ');
}
if ((printflags & PRINT_NAMEONLY) ||
((p->node.flags & PM_HIDEVAL) && !(printflags & PRINT_INCLUDEVALUE))) {
zputs(p->node.nam, stdout);
putchar('\n');
} else {
quotedzputs(p->node.nam, stdout);
if (array_typeset)
putchar('\n');
printparamvalue(p, printflags);
}
}

View file

@ -487,3 +487,24 @@
?typeset -r pbro
?0
?(eval):10: read-only variable: pbro
readonly foo=bar novalue
readonly -p
0:readonly -p output (no readonly specials)
>typeset -r foo=bar
>typeset -r novalue=''
local -a a1 a2
local -r r1=yes r2=no
a1=(one two) a2=(three four)
readonly a1
typeset -pm 'a[12]'
typeset -pm 'r[12]'
0:readonly -p output
>typeset -a a1
>a1=(one two)
>typeset -ar a1
>typeset -a a2
>a2=(three four)
>typeset -r r1=yes
>typeset -r r2=no