Commit f855801f authored by Peter Stephenson's avatar Peter Stephenson

35059: fix, document, test readonly -p.

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

Output arrays in a useful order.
parent 39aeeedb
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.
......
......@@ -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.
......
......@@ -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);
}
}
......@@ -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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment