* Fw: PATCH: typeset -P @ 2017-09-29 19:50 Peter Stephenson 2017-09-29 22:55 ` Bart Schaefer 0 siblings, 1 reply; 7+ messages in thread From: Peter Stephenson @ 2017-09-29 19:50 UTC (permalink / raw) To: Zsh hackers list Sent this yesterday but it's disappeared... pws Begin forwarded message: Date: Thu, 28 Sep 2017 21:12:30 +0100 From: Peter Stephenson <p.w.stephenson@ntlworld.com> To: Zsh hackers list <zsh-workers@zsh.org> Subject: PATCH: typeset -P I'd quite like to have a variant of "typeset -p" that prints array elements one per line for readability --- this is entirely cosmetic as the syntax can still be read in. This uses -P, but if there are suggestions for something less likely to clash with an option in another shell let me know. I think it would be too fraught to make this the default for -p as it might be assumed there is one line per variable. pws diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo index d6aa078..d644d0b 100644 --- a/Doc/Zsh/builtins.yo +++ b/Doc/Zsh/builtins.yo @@ -1817,7 +1817,7 @@ findex(typeset) cindex(parameters, setting) cindex(parameters, declaring) redef(SPACES)(0)(tt(ifztexi(NOTRANS(@ @ @ @ @ @ @ @ ))ifnztexi( ))) -xitem(tt(typeset )[ {tt(PLUS())|tt(-)}tt(AHUaghlmprtux) ] \ +xitem(tt(typeset )[ {tt(PLUS())|tt(-)}tt(AHPUaghlmprtux) ] \ [ {tt(PLUS())|tt(-)}tt(EFLRZi) [ var(n) ] ]) xitem(SPACES()[ tt(+) ] [ var(name)[tt(=)var(value)] ... ]) xitem(tt(typeset )tt(-T) [ {tt(PLUS())|tt(-)}tt(Uglprux) ] [ {tt(PLUS())|tt(-)}tt(LRZ) [ var(n) ] ]) @@ -1986,6 +1986,10 @@ form of a typeset command with an assignment, regardless of other flags and options. Note that the tt(-H) flag on parameters is respected; no value will be shown for these parameters. ) +item(tt(-P))( +Identical to tt(-P), except that arrays and associative arrays are +printed with newlines beteween elements for readability. +) item(tt(-T) [ var(scalar)[tt(=)var(value)] var(array)[tt(=LPAR())var(value) ...tt(RPAR())] [ var(sep) ] ])( This flag has a different meaning when used with tt(-f); see below. Otherwise the tt(-T) option requires zero, two, or three arguments to be diff --git a/Src/builtin.c b/Src/builtin.c index f5ccf52..ad0fa93 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -53,7 +53,7 @@ static struct builtin builtins[] = BUILTIN("cd", BINF_SKIPINVALID | BINF_SKIPDASH | BINF_DASHDASHVALID, bin_cd, 0, 2, BIN_CD, "qsPL", NULL), BUILTIN("chdir", BINF_SKIPINVALID | BINF_SKIPDASH | BINF_DASHDASHVALID, bin_cd, 0, 2, BIN_CD, "qsPL", NULL), BUILTIN("continue", BINF_PSPECIAL, bin_break, 0, 1, BIN_CONTINUE, NULL, NULL), - BUILTIN("declare", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%afghi:%klmprtuxz", NULL), + BUILTIN("declare", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "AE:%F:%HL:%PR:%TUZ:%afghi:%klmprtuxz", NULL), BUILTIN("dirs", 0, bin_dirs, 0, -1, 0, "clpv", NULL), BUILTIN("disable", 0, bin_enable, 0, -1, BIN_DISABLE, "afmprs", NULL), BUILTIN("disown", 0, bin_fg, 0, -1, BIN_DISOWN, NULL, NULL), @@ -62,7 +62,7 @@ static struct builtin builtins[] = BUILTIN("enable", 0, bin_enable, 0, -1, BIN_ENABLE, "afmprs", NULL), BUILTIN("eval", BINF_PSPECIAL, bin_eval, 0, -1, BIN_EVAL, NULL, NULL), BUILTIN("exit", BINF_PSPECIAL, bin_break, 0, 1, BIN_EXIT, NULL, NULL), - BUILTIN("export", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "E:%F:%HL:%R:%TUZ:%afhi:%lprtu", "xg"), + BUILTIN("export", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "E:%F:%HL:%PR:%TUZ:%afhi:%lprtu", "xg"), BUILTIN("false", 0, bin_false, 0, -1, 0, NULL, NULL), /* * We used to behave as if the argument to -e was optional. @@ -71,7 +71,7 @@ static struct builtin builtins[] = */ BUILTIN("fc", 0, bin_fc, 0, -1, BIN_FC, "aAdDe:EfiIlLmnpPrRt:W", NULL), BUILTIN("fg", 0, bin_fg, 0, -1, BIN_FG, NULL, NULL), - BUILTIN("float", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "E:%F:%HL:%R:%Z:%ghlprtux", "E"), + BUILTIN("float", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "E:%F:%HL:%PR:%Z:%ghlprtux", "E"), BUILTIN("functions", BINF_PLUSOPTS, bin_functions, 0, -1, 0, "kmMstTuUWx:z", NULL), BUILTIN("getln", 0, bin_read, 0, -1, 0, "ecnAlE", "zr"), BUILTIN("getopts", 0, bin_getopts, 2, -1, 0, NULL, NULL), @@ -82,11 +82,11 @@ static struct builtin builtins[] = #endif BUILTIN("history", 0, bin_fc, 0, -1, BIN_FC, "adDEfiLmnpPrt:", "l"), - BUILTIN("integer", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "HL:%R:%Z:%ghi:%lprtux", "i"), + BUILTIN("integer", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "HL:%PR:%Z:%ghi:%lprtux", "i"), BUILTIN("jobs", 0, bin_fg, 0, -1, BIN_JOBS, "dlpZrs", NULL), BUILTIN("kill", BINF_HANDLES_OPTS, bin_kill, 0, -1, 0, NULL, NULL), BUILTIN("let", 0, bin_let, 1, -1, 0, NULL, NULL), - BUILTIN("local", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%ahi:%lprtux", NULL), + BUILTIN("local", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "AE:%F:%HL:%PR:%TUZ:%ahi:%lprtux", NULL), BUILTIN("log", 0, bin_log, 0, 0, 0, NULL, NULL), BUILTIN("logout", 0, bin_break, 0, 1, BIN_LOGOUT, NULL, NULL), @@ -120,7 +120,7 @@ static struct builtin builtins[] = BUILTIN("trap", BINF_PSPECIAL | BINF_HANDLES_OPTS, bin_trap, 0, -1, 0, NULL, NULL), BUILTIN("true", 0, bin_true, 0, -1, 0, NULL, NULL), BUILTIN("type", 0, bin_whence, 0, -1, 0, "ampfsSw", "v"), - BUILTIN("typeset", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%afghi:%klprtuxmz", NULL), + BUILTIN("typeset", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "AE:%F:%HL:%PR:%TUZ:%afghi:%klprtuxmz", NULL), BUILTIN("umask", 0, bin_umask, 0, 1, 0, "S", NULL), BUILTIN("unalias", 0, bin_unhash, 0, -1, BIN_UNALIAS, "ams", NULL), BUILTIN("unfunction", 0, bin_unhash, 1, -1, BIN_UNFUNCTION, "m", "f"), @@ -2647,6 +2647,10 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func) /* Given no arguments, list whatever the options specify. */ if (OPT_ISSET(ops,'p')) printflags |= PRINT_TYPESET; + if (OPT_ISSET(ops,'P')) { + printflags |= PRINT_TYPESET|PRINT_LINE; + ops->ind['p'] = 1; + } hasargs = *argv != NULL || (assigns && firstnode(assigns)); if (!hasargs) { if (!OPT_ISSET(ops,'p')) { diff --git a/Src/params.c b/Src/params.c index 3236f71..0d0c0f0 100644 --- a/Src/params.c +++ b/Src/params.c @@ -5682,18 +5682,18 @@ printparamvalue(Param p, int printflags) /* array */ if (!(printflags & PRINT_KV_PAIR)) { putchar('('); - putchar(' '); + putchar((printflags & PRINT_LINE) ? '\n' : ' '); } u = p->gsu.a->getfn(p); if(*u) { quotedzputs(*u++, stdout); while (*u) { - putchar(' '); + putchar((printflags & PRINT_LINE) ? '\n' : ' '); quotedzputs(*u++, stdout); } } if (!(printflags & PRINT_KV_PAIR)) { - putchar(' '); + putchar((printflags & PRINT_LINE) ? '\n' : ' '); putchar(')'); } break; @@ -5701,19 +5701,20 @@ printparamvalue(Param p, int printflags) /* association */ if (!(printflags & PRINT_KV_PAIR)) { putchar('('); - putchar(' '); + putchar((printflags & PRINT_LINE) ? '\n' : ' '); } { HashTable ht = p->gsu.h->getfn(p); if (ht) scanhashtable(ht, 1, 0, PM_UNSET, - ht->printnode, PRINT_KV_PAIR); + ht->printnode, PRINT_KV_PAIR | + (printflags & PRINT_LINE)); } if (!(printflags & PRINT_KV_PAIR)) putchar(')'); break; } - if (printflags & PRINT_KV_PAIR) + if ((printflags & (PRINT_KV_PAIR|PRINT_LINE)) == PRINT_KV_PAIR) putchar(' '); else putchar('\n'); diff --git a/Src/zsh.h b/Src/zsh.h index c1138bf..24d06ba 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -2128,13 +2128,14 @@ typedef groupset *Groupset; #define PRINT_KV_PAIR (1<<3) #define PRINT_INCLUDEVALUE (1<<4) #define PRINT_TYPESET (1<<5) +#define PRINT_LINE (1<<6) /* flags for printing for the whence builtin */ -#define PRINT_WHENCE_CSH (1<<6) -#define PRINT_WHENCE_VERBOSE (1<<7) -#define PRINT_WHENCE_SIMPLE (1<<8) -#define PRINT_WHENCE_FUNCDEF (1<<9) -#define PRINT_WHENCE_WORD (1<<10) +#define PRINT_WHENCE_CSH (1<<7) +#define PRINT_WHENCE_VERBOSE (1<<8) +#define PRINT_WHENCE_SIMPLE (1<<9) +#define PRINT_WHENCE_FUNCDEF (1<<10) +#define PRINT_WHENCE_WORD (1<<11) /* Return values from loop() */ ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Fw: PATCH: typeset -P 2017-09-29 19:50 Fw: PATCH: typeset -P Peter Stephenson @ 2017-09-29 22:55 ` Bart Schaefer 2017-09-30 12:48 ` Peter Stephenson 0 siblings, 1 reply; 7+ messages in thread From: Bart Schaefer @ 2017-09-29 22:55 UTC (permalink / raw) To: Zsh hackers list On Sep 29, 8:50pm, Peter Stephenson wrote: } } +item(tt(-P))( } +Identical to tt(-P), except that arrays and associative arrays are Need to lower-case that second -P. I'm ambivalent about this choice of option letter, though. What about something entirely unlikely to conflict, like -1 (ala "ls -1")? Then e.g. one could use the idiom "typeset -p1" to make it obvious. We could also have "typeset -2" to output associative arrays in the old (k1 v1 k2 v2 ...) format (I suppose "typeset -12" would then print a newline after each value but not after each key). I have two requests with respect to the rest of this patch: (1) Don't print the blank line for arrays with no elements, e.g. NOT typeset -a cdpath=( ) Ideally this would just be cdpath=() as before, but I could live with one line break in the parens. (2) Indent each element by a couple of spaces. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: PATCH: typeset -P 2017-09-29 22:55 ` Bart Schaefer @ 2017-09-30 12:48 ` Peter Stephenson 2017-09-30 19:46 ` Peter Stephenson 0 siblings, 1 reply; 7+ messages in thread From: Peter Stephenson @ 2017-09-30 12:48 UTC (permalink / raw) To: Zsh hackers list On Fri, 29 Sep 2017 15:55:33 -0700 Bart Schaefer <schaefer@brasslantern.com> wrote: > I'm ambivalent about this choice of option letter, though. What about > something entirely unlikely to conflict, like -1 (ala "ls -1")? Then > e.g. one could use the idiom "typeset -p1" to make it obvious. Handling integer options is difficult as the option parser has special arrangements. Optional integer arguments are possible, so we could enforce this as -p1, i.e. your idiom becomes the required syntax. I think I've got this working; I'll send it later with documentation and tests. pws ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: PATCH: typeset -P 2017-09-30 12:48 ` Peter Stephenson @ 2017-09-30 19:46 ` Peter Stephenson 2017-10-01 0:11 ` Bart Schaefer 0 siblings, 1 reply; 7+ messages in thread From: Peter Stephenson @ 2017-09-30 19:46 UTC (permalink / raw) To: Zsh hackers list On Sat, 30 Sep 2017 13:48:51 +0100 Peter Stephenson <p.w.stephenson@ntlworld.com> wrote: > On Fri, 29 Sep 2017 15:55:33 -0700 > Bart Schaefer <schaefer@brasslantern.com> wrote: > > I'm ambivalent about this choice of option letter, though. What about > > something entirely unlikely to conflict, like -1 (ala "ls -1")? Then > > e.g. one could use the idiom "typeset -p1" to make it obvious. > > Handling integer options is difficult as the option parser has special > arrangements. Optional integer arguments are possible, so we could > enforce this as -p1, i.e. your idiom becomes the required syntax. I > think I've got this working; I'll send it later with documentation and > tests. This message never arrived, but it's been overtaken by events. The chunk in Src/subst.c is unrelated apart from being required by a test I've just added. It ensures we don't elide empty nodes from the list when using key / value pairs. Slight hack here to avoid doing too much extra processing: it'll keep empty nodes in the old-fashioned part of mixed array assignments (forbidden for associative arrays). Do you know, I don't really care? Shocking. One other minor compatibility note: the existing typeset -p prints a space between the parentheses of an empty array. This may have been required for parsing in the past, or may have simply been to avoid special cases, I don't know. I've removed this space for typeset -p1. pws diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo index d6aa078..b4a7272 100644 --- a/Doc/Zsh/builtins.yo +++ b/Doc/Zsh/builtins.yo @@ -1817,10 +1817,10 @@ findex(typeset) cindex(parameters, setting) cindex(parameters, declaring) redef(SPACES)(0)(tt(ifztexi(NOTRANS(@ @ @ @ @ @ @ @ ))ifnztexi( ))) -xitem(tt(typeset )[ {tt(PLUS())|tt(-)}tt(AHUaghlmprtux) ] \ -[ {tt(PLUS())|tt(-)}tt(EFLRZi) [ var(n) ] ]) +xitem(tt(typeset )[ {tt(PLUS())|tt(-)}tt(AHUaghlmrtux) ] \ +[ {tt(PLUS())|tt(-)}tt(EFLRZip) [ var(n) ] ]) xitem(SPACES()[ tt(+) ] [ var(name)[tt(=)var(value)] ... ]) -xitem(tt(typeset )tt(-T) [ {tt(PLUS())|tt(-)}tt(Uglprux) ] [ {tt(PLUS())|tt(-)}tt(LRZ) [ var(n) ] ]) +xitem(tt(typeset )tt(-T) [ {tt(PLUS())|tt(-)}tt(Uglrux) ] [ {tt(PLUS())|tt(-)}tt(LRZp) [ var(n) ] ]) xitem(SPACES()[ tt(+) | var(SCALAR)[tt(=)var(value)] var(array)[tt(=LPAR())var(value) ...tt(RPAR())] [ var(sep) ] ]) item(tt(typeset) tt(-f) [ {tt(PLUS())|tt(-)}tt(TUkmtuz) ] [ tt(+) ] [ var(name) ... ])( Set or display attributes and values for shell parameters. @@ -1985,6 +1985,11 @@ If the tt(-p) option is given, parameters and values are printed in the form of a typeset command with an assignment, regardless of other flags and options. Note that the tt(-H) flag on parameters is respected; no value will be shown for these parameters. + +tt(-p) may be followed by an optional integer argument. Currently +only the value 1 is supported. In this case arrays and associative +arrays are printed with newlines beteween indented elements for +readability. ) item(tt(-T) [ var(scalar)[tt(=)var(value)] var(array)[tt(=LPAR())var(value) ...tt(RPAR())] [ var(sep) ] ])( This flag has a different meaning when used with tt(-f); see below. diff --git a/Src/builtin.c b/Src/builtin.c index f5ccf52..d39bb96 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -53,7 +53,7 @@ static struct builtin builtins[] = BUILTIN("cd", BINF_SKIPINVALID | BINF_SKIPDASH | BINF_DASHDASHVALID, bin_cd, 0, 2, BIN_CD, "qsPL", NULL), BUILTIN("chdir", BINF_SKIPINVALID | BINF_SKIPDASH | BINF_DASHDASHVALID, bin_cd, 0, 2, BIN_CD, "qsPL", NULL), BUILTIN("continue", BINF_PSPECIAL, bin_break, 0, 1, BIN_CONTINUE, NULL, NULL), - BUILTIN("declare", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%afghi:%klmprtuxz", NULL), + BUILTIN("declare", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%afghi:%klmp:%rtuxz", NULL), BUILTIN("dirs", 0, bin_dirs, 0, -1, 0, "clpv", NULL), BUILTIN("disable", 0, bin_enable, 0, -1, BIN_DISABLE, "afmprs", NULL), BUILTIN("disown", 0, bin_fg, 0, -1, BIN_DISOWN, NULL, NULL), @@ -62,7 +62,7 @@ static struct builtin builtins[] = BUILTIN("enable", 0, bin_enable, 0, -1, BIN_ENABLE, "afmprs", NULL), BUILTIN("eval", BINF_PSPECIAL, bin_eval, 0, -1, BIN_EVAL, NULL, NULL), BUILTIN("exit", BINF_PSPECIAL, bin_break, 0, 1, BIN_EXIT, NULL, NULL), - BUILTIN("export", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "E:%F:%HL:%R:%TUZ:%afhi:%lprtu", "xg"), + BUILTIN("export", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "E:%F:%HL:%R:%TUZ:%afhi:%lp:%rtu", "xg"), BUILTIN("false", 0, bin_false, 0, -1, 0, NULL, NULL), /* * We used to behave as if the argument to -e was optional. @@ -71,7 +71,7 @@ static struct builtin builtins[] = */ BUILTIN("fc", 0, bin_fc, 0, -1, BIN_FC, "aAdDe:EfiIlLmnpPrRt:W", NULL), BUILTIN("fg", 0, bin_fg, 0, -1, BIN_FG, NULL, NULL), - BUILTIN("float", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "E:%F:%HL:%R:%Z:%ghlprtux", "E"), + BUILTIN("float", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "E:%F:%HL:%R:%Z:%ghlp:%rtux", "E"), BUILTIN("functions", BINF_PLUSOPTS, bin_functions, 0, -1, 0, "kmMstTuUWx:z", NULL), BUILTIN("getln", 0, bin_read, 0, -1, 0, "ecnAlE", "zr"), BUILTIN("getopts", 0, bin_getopts, 2, -1, 0, NULL, NULL), @@ -82,11 +82,11 @@ static struct builtin builtins[] = #endif BUILTIN("history", 0, bin_fc, 0, -1, BIN_FC, "adDEfiLmnpPrt:", "l"), - BUILTIN("integer", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "HL:%R:%Z:%ghi:%lprtux", "i"), + BUILTIN("integer", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "HL:%R:%Z:%ghi:%lp:%rtux", "i"), BUILTIN("jobs", 0, bin_fg, 0, -1, BIN_JOBS, "dlpZrs", NULL), BUILTIN("kill", BINF_HANDLES_OPTS, bin_kill, 0, -1, 0, NULL, NULL), BUILTIN("let", 0, bin_let, 1, -1, 0, NULL, NULL), - BUILTIN("local", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%ahi:%lprtux", NULL), + BUILTIN("local", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%ahi:%lp:%rtux", NULL), BUILTIN("log", 0, bin_log, 0, 0, 0, NULL, NULL), BUILTIN("logout", 0, bin_break, 0, 1, BIN_LOGOUT, NULL, NULL), @@ -120,7 +120,7 @@ static struct builtin builtins[] = BUILTIN("trap", BINF_PSPECIAL | BINF_HANDLES_OPTS, bin_trap, 0, -1, 0, NULL, NULL), BUILTIN("true", 0, bin_true, 0, -1, 0, NULL, NULL), BUILTIN("type", 0, bin_whence, 0, -1, 0, "ampfsSw", "v"), - BUILTIN("typeset", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%afghi:%klprtuxmz", NULL), + BUILTIN("typeset", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%afghi:%klp:%rtuxmz", NULL), BUILTIN("umask", 0, bin_umask, 0, 1, 0, "S", NULL), BUILTIN("unalias", 0, bin_unhash, 0, -1, BIN_UNALIAS, "ams", NULL), BUILTIN("unfunction", 0, bin_unhash, 1, -1, BIN_UNFUNCTION, "m", "f"), @@ -2645,8 +2645,20 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func) queue_signals(); /* Given no arguments, list whatever the options specify. */ - if (OPT_ISSET(ops,'p')) + if (OPT_ISSET(ops,'p')) { printflags |= PRINT_TYPESET; + if (OPT_HASARG(ops,'p')) { + char *eptr; + int pflag = (int)zstrtol(OPT_ARG(ops,'p'), &eptr, 10); + if (pflag == 1 && !*eptr) + printflags |= PRINT_LINE; + else { + zwarnnam(name, "bad argument to -p: %s", OPT_ARG(ops,'p')); + unqueue_signals(); + return 1; + } + } + } hasargs = *argv != NULL || (assigns && firstnode(assigns)); if (!hasargs) { if (!OPT_ISSET(ops,'p')) { diff --git a/Src/params.c b/Src/params.c index 3236f71..ddf3ce1 100644 --- a/Src/params.c +++ b/Src/params.c @@ -5682,40 +5682,60 @@ printparamvalue(Param p, int printflags) /* array */ if (!(printflags & PRINT_KV_PAIR)) { putchar('('); - putchar(' '); + if (!(printflags & PRINT_LINE)) + putchar(' '); } u = p->gsu.a->getfn(p); if(*u) { + if (printflags & PRINT_LINE) { + if (printflags & PRINT_KV_PAIR) + printf(" "); + else + printf("\n "); + } quotedzputs(*u++, stdout); while (*u) { - putchar(' '); + if (printflags & PRINT_LINE) + printf("\n "); + else + putchar(' '); quotedzputs(*u++, stdout); } + if ((printflags & (PRINT_LINE|PRINT_KV_PAIR)) == PRINT_LINE) + putchar('\n'); } if (!(printflags & PRINT_KV_PAIR)) { - putchar(' '); + if (!(printflags & PRINT_LINE)) + putchar(' '); putchar(')'); } break; case PM_HASHED: /* association */ - if (!(printflags & PRINT_KV_PAIR)) { - putchar('('); - putchar(' '); - } { - HashTable ht = p->gsu.h->getfn(p); + HashTable ht; + int found = 0; + if (!(printflags & PRINT_KV_PAIR)) { + putchar('('); + if (!(printflags & PRINT_LINE)) + putchar(' '); + } + ht = p->gsu.h->getfn(p); if (ht) - scanhashtable(ht, 1, 0, PM_UNSET, - ht->printnode, PRINT_KV_PAIR); + found = scanhashtable(ht, 1, 0, PM_UNSET, + ht->printnode, PRINT_KV_PAIR | + (printflags & PRINT_LINE)); + if (!(printflags & PRINT_KV_PAIR)) { + if (found && (printflags & PRINT_LINE)) + putchar('\n'); + putchar(')'); + } } - if (!(printflags & PRINT_KV_PAIR)) - putchar(')'); break; } - if (printflags & PRINT_KV_PAIR) + if ((printflags & (PRINT_KV_PAIR|PRINT_LINE)) == PRINT_KV_PAIR) putchar(' '); - else + else if (!(printflags & PRINT_KV_PAIR)) putchar('\n'); } @@ -5809,8 +5829,11 @@ printparamnode(HashNode hn, int printflags) zputs(p->node.nam, stdout); putchar('\n'); } else { - if (printflags & PRINT_KV_PAIR) + if (printflags & PRINT_KV_PAIR) { + if (printflags & PRINT_LINE) + printf("\n "); putchar('['); + } quotedzputs(p->node.nam, stdout); if (printflags & PRINT_KV_PAIR) printf("]="); diff --git a/Src/subst.c b/Src/subst.c index eef0dc7..2d3eeb2 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -158,7 +158,9 @@ prefork(LinkList list, int flags, int *ret_flags) filesub(&cptr, flags & (PREFORK_TYPESET|PREFORK_ASSIGN)); setdata(node, cptr); } - } else if (!(flags & PREFORK_SINGLE) && !keep) + } else if (!(flags & PREFORK_SINGLE) && + !(*ret_flags & PREFORK_KEY_VALUE) && + !keep) uremnode(list, node); if (errflag) { unqueue_signals(); diff --git a/Src/zsh.h b/Src/zsh.h index c1138bf..24d06ba 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -2128,13 +2128,14 @@ typedef groupset *Groupset; #define PRINT_KV_PAIR (1<<3) #define PRINT_INCLUDEVALUE (1<<4) #define PRINT_TYPESET (1<<5) +#define PRINT_LINE (1<<6) /* flags for printing for the whence builtin */ -#define PRINT_WHENCE_CSH (1<<6) -#define PRINT_WHENCE_VERBOSE (1<<7) -#define PRINT_WHENCE_SIMPLE (1<<8) -#define PRINT_WHENCE_FUNCDEF (1<<9) -#define PRINT_WHENCE_WORD (1<<10) +#define PRINT_WHENCE_CSH (1<<7) +#define PRINT_WHENCE_VERBOSE (1<<8) +#define PRINT_WHENCE_SIMPLE (1<<9) +#define PRINT_WHENCE_FUNCDEF (1<<10) +#define PRINT_WHENCE_WORD (1<<11) /* Return values from loop() */ diff --git a/Test/B02typeset.ztst b/Test/B02typeset.ztst index 13f0d5e..996af06 100644 --- a/Test/B02typeset.ztst +++ b/Test/B02typeset.ztst @@ -793,3 +793,29 @@ local -A keyvalhash=(1 one [2]=two 3 three) 1:Mixed syntax with [key]=val not allowed for hash. ?(eval):1: bad [key]=value syntax for associative array + + local -a myarray + typeset -p1 myarray + myarray=("&" sand '""' "" plugh) + typeset -p1 myarray +0:typeset -p1 output for array +>typeset -a myarray=() +>typeset -a myarray=( +> '&' +> sand +> '""' +> '' +> plugh +>) + + local -A myhash + typeset -p1 myhash + myhash=([one]=two [three]= [four]="[]") + typeset -p1 myhash +0:typeset -p1 output for associative array +>typeset -A myhash=() +>typeset -A myhash=( +> [four]='[]' +> [one]=two +> [three]='' +>) ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: PATCH: typeset -P 2017-09-30 19:46 ` Peter Stephenson @ 2017-10-01 0:11 ` Bart Schaefer 2017-10-01 16:48 ` Peter Stephenson 0 siblings, 1 reply; 7+ messages in thread From: Bart Schaefer @ 2017-10-01 0:11 UTC (permalink / raw) To: Zsh hackers list On Sep 30, 8:46pm, Peter Stephenson wrote: } } The chunk in Src/subst.c is unrelated apart from being required by a } test I've just added. It ensures we don't elide empty nodes from the } list when using key / value pairs. Hrm, this makes me notice that there's a useful case for typeset -p to output the [k]=v syntax even for traditional arrays. Consider: % typeset -a onek=([1024]=something) % typeset -p 1 onek We could skip the initial 1023 lines of '' if we used the new syntax. On the other hand, we'd waste a bunch of bytes on [N]=... if the array was *not* mostly empty, so most of the time the old syntax is likely more compact. } One other minor compatibility note: the existing typeset -p } prints a space between the parentheses of an empty array. [...] } I've removed this space for typeset -p1. Interesting: torch% typeset -p x typeset -a x=( ) torch% typeset -p 1 x typeset -a x=() (I don't really care either, but somebody is probably going to notice and file a bug report.) Aside -- *prior to* this patch: torch% () { typeset -p 1 } foo (anon):typeset: no such variable: 1 torch% () { typeset -p @ } foo torch% () { typeset -p \* } foo torch% () { typeset -p # } foo torch% () { typeset -p ARGC } foo torch% () { typeset -p argv } foo typeset -g -a argv=( foo ) So individual positional parameters are "no such variable" which nicely makes this new syntax usable, yet the argv variants are recognized but not always printable. (Also not clear that the -g is correct for argv, but I think it's merely extraneous rather than wrong.) ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: PATCH: typeset -P 2017-10-01 0:11 ` Bart Schaefer @ 2017-10-01 16:48 ` Peter Stephenson 2017-10-01 17:06 ` Bart Schaefer 0 siblings, 1 reply; 7+ messages in thread From: Peter Stephenson @ 2017-10-01 16:48 UTC (permalink / raw) To: Zsh hackers list On Sat, 30 Sep 2017 17:11:54 -0700 Bart Schaefer <schaefer@brasslantern.com> wrote: > Hrm, this makes me notice that there's a useful case for typeset -p to > output the [k]=v syntax even for traditional arrays. Consider: > > % typeset -a onek=([1024]=something) > % typeset -p 1 onek > > We could skip the initial 1023 lines of '' if we used the new syntax. > On the other hand, we'd waste a bunch of bytes on [N]=... if the array > was *not* mostly empty, so most of the time the old syntax is likely > more compact. Unfortunately, unlike bash, arrays aren't sparse. So the intervening elements that haven't been set are identical to any that have been set explicitly to any empty string. Of course, that could be adopted as a convention --- on re-input the effect is the same, which is ultimately the key point. > } One other minor compatibility note: the existing typeset -p > } prints a space between the parentheses of an empty array. [...] > } I've removed this space for typeset -p1. > > Interesting: > > torch% typeset -p x > typeset -a x=( ) > torch% typeset -p 1 x > typeset -a x=() > > (I don't really care either, but somebody is probably going to notice > and file a bug report.) I only changed it because I was asked. Cosmetic differences between -p and -p1 are quite explicitly not a bug. I'll commit it as it stands (with a correction from Daniel). Hmm, maybe I'll make typeset -p0 the same as -p for consistency. pws ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: PATCH: typeset -P 2017-10-01 16:48 ` Peter Stephenson @ 2017-10-01 17:06 ` Bart Schaefer 0 siblings, 0 replies; 7+ messages in thread From: Bart Schaefer @ 2017-10-01 17:06 UTC (permalink / raw) To: Zsh hackers list On Oct 1, 5:48pm, Peter Stephenson wrote: } } > } One other minor compatibility note: the existing typeset -p } > } prints a space between the parentheses of an empty array. [...] } > } I've removed this space for typeset -p1. } } I only changed it because I was asked. Sadly, I only asked because I forgot there was a space there in the first place. I was more concerned with the newlines. ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2017-10-01 17:06 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2017-09-29 19:50 Fw: PATCH: typeset -P Peter Stephenson 2017-09-29 22:55 ` Bart Schaefer 2017-09-30 12:48 ` Peter Stephenson 2017-09-30 19:46 ` Peter Stephenson 2017-10-01 0:11 ` Bart Schaefer 2017-10-01 16:48 ` Peter Stephenson 2017-10-01 17:06 ` Bart Schaefer
Code repositories for project(s) associated with this public inbox https://git.vuxu.org/mirror/zsh/ This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).