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

37467: add "print -v var" / "printf -v var"

This commit is contained in:
Barton E. Schaefer 2015-12-31 12:38:10 -08:00
parent 4f5d7b7b37
commit 15b73ea99b
4 changed files with 47 additions and 11 deletions

View file

@ -1,3 +1,8 @@
2015-12-31 Barton E. Schaefer <schaefer@zsh.org>
* 37467: Doc/Zsh/builtins.yo, Src/builtin.c, Test/B03print.ztst:
add "print -v var" / "printf -v var"
2015-12-31 Oliver Kiddle <opk@zsh.org> 2015-12-31 Oliver Kiddle <opk@zsh.org>
* 37453 (with Bart, started by Baptiste Daroussin, 37315) * 37453 (with Bart, started by Baptiste Daroussin, 37315)

View file

@ -1124,7 +1124,7 @@ tt(popd) that do not change the environment seen by an interactive user.
) )
findex(print) findex(print)
xitem(tt(print )[ tt(-abcDilmnNoOpPrsSz) ] [ tt(-u) var(n) ] [ tt(-f) var(format) ] [ tt(-C) var(cols) ]) xitem(tt(print )[ tt(-abcDilmnNoOpPrsSz) ] [ tt(-u) var(n) ] [ tt(-f) var(format) ] [ tt(-C) var(cols) ])
item(SPACES()[ tt(-xX) var(tab-stop) ] [ tt(-R) [ tt(-en) ]] [ var(arg) ... ])( item(SPACES()[ tt(-v) var(name) ] [ tt(-xX) var(tabstop) ] [ tt(-R) [ tt(-en) ]] [ var(arg) ... ])(
With the `tt(-f)' option the arguments are printed as described by tt(printf). With the `tt(-f)' option the arguments are printed as described by tt(printf).
With no flags or with the flag `tt(-)', the arguments are printed on With no flags or with the flag `tt(-)', the arguments are printed on
the standard output as described by tt(echo), with the following differences: the standard output as described by tt(echo), with the following differences:
@ -1219,6 +1219,9 @@ tt(HIST_LEX_WORDS) option active.
item(tt(-u) var(n))( item(tt(-u) var(n))(
Print the arguments to file descriptor var(n). Print the arguments to file descriptor var(n).
) )
item(tt(-v) var(name))(
Store the printed arguments as the value of the parameter var(name).
)
item(tt(-x) var(tab-stop))( item(tt(-x) var(tab-stop))(
Expand leading tabs on each line of output in the printed string Expand leading tabs on each line of output in the printed string
assuming a tab stop every var(tab-stop) characters. This is appropriate assuming a tab stop every var(tab-stop) characters. This is appropriate
@ -1250,7 +1253,7 @@ If any of `tt(-m)', `tt(-o)' or `tt(-O)' are used in combination with
case of `tt(-m)') then nothing is printed. case of `tt(-m)') then nothing is printed.
) )
findex(printf) findex(printf)
item(tt(printf) var(format) [ var(arg) ... ])( item(tt(printf) [ -v var(name) ] var(format) [ var(arg) ... ])(
Print the arguments according to the format specification. Formatting Print the arguments according to the format specification. Formatting
rules are the same as used in C. The same escape sequences as for tt(echo) rules are the same as used in C. The same escape sequences as for tt(echo)
are recognised in the format. All C conversion specifications ending in are recognised in the format. All C conversion specifications ending in
@ -1279,6 +1282,9 @@ until all arguments have been consumed. With the tt(print) builtin, this
can be suppressed by using the tt(-r) option. If more arguments are can be suppressed by using the tt(-r) option. If more arguments are
required by the format than have been specified, the behaviour is as if required by the format than have been specified, the behaviour is as if
zero or an empty string had been specified as the argument. zero or an empty string had been specified as the argument.
The tt(-v) option causes the output to be stored as the value of the
parameter var(name), instead of printed.
) )
findex(pushd) findex(pushd)
pindex(PUSHD_TO_HOME, use of) pindex(PUSHD_TO_HOME, use of)

View file

@ -99,8 +99,8 @@ static struct builtin builtins[] =
#endif #endif
BUILTIN("popd", BINF_SKIPINVALID | BINF_SKIPDASH | BINF_DASHDASHVALID, bin_cd, 0, 1, BIN_POPD, "q", NULL), BUILTIN("popd", BINF_SKIPINVALID | BINF_SKIPDASH | BINF_DASHDASHVALID, bin_cd, 0, 1, BIN_POPD, "q", NULL),
BUILTIN("print", BINF_PRINTOPTS, bin_print, 0, -1, BIN_PRINT, "abcC:Df:ilmnNoOpPrRsSu:x:X:z-", NULL), BUILTIN("print", BINF_PRINTOPTS, bin_print, 0, -1, BIN_PRINT, "abcC:Df:ilmnNoOpPrRsSu:v:x:X:z-", NULL),
BUILTIN("printf", 0, bin_print, 1, -1, BIN_PRINTF, NULL, NULL), BUILTIN("printf", 0, bin_print, 1, -1, BIN_PRINTF, "v:", NULL),
BUILTIN("pushd", BINF_SKIPINVALID | BINF_SKIPDASH | BINF_DASHDASHVALID, bin_cd, 0, 2, BIN_PUSHD, "qsPL", NULL), BUILTIN("pushd", BINF_SKIPINVALID | BINF_SKIPDASH | BINF_DASHDASHVALID, bin_cd, 0, 2, BIN_PUSHD, "qsPL", NULL),
BUILTIN("pushln", 0, bin_print, 0, -1, BIN_PRINT, NULL, "-nz"), BUILTIN("pushln", 0, bin_print, 0, -1, BIN_PRINT, NULL, "-nz"),
BUILTIN("pwd", 0, bin_pwd, 0, 0, 0, "rLP", NULL), BUILTIN("pwd", 0, bin_pwd, 0, 0, 0, "rLP", NULL),
@ -4032,6 +4032,11 @@ bin_print(char *name, char **args, Options ops, int func)
zulong zulongval; zulong zulongval;
char *stringval; char *stringval;
if (OPT_ISSET(ops, 'z') + OPT_ISSET(ops, 's') + OPT_ISSET(ops, 'v') > 1) {
zwarnnam(name, "only one of -z, -s, or -v allowed");
return 1;
}
if (func == BIN_PRINTF) { if (func == BIN_PRINTF) {
if (!strcmp(*args, "--") && !*++args) { if (!strcmp(*args, "--") && !*++args) {
zwarnnam(name, "not enough arguments"); zwarnnam(name, "not enough arguments");
@ -4157,7 +4162,7 @@ bin_print(char *name, char **args, Options ops, int func)
if ((OPT_HASARG(ops,'u') || OPT_ISSET(ops,'p')) && if ((OPT_HASARG(ops,'u') || OPT_ISSET(ops,'p')) &&
/* rule out conflicting options -- historical precedence */ /* rule out conflicting options -- historical precedence */
((!fmt && (OPT_ISSET(ops,'c') || OPT_ISSET(ops,'C'))) || ((!fmt && (OPT_ISSET(ops,'c') || OPT_ISSET(ops,'C'))) ||
!(OPT_ISSET(ops, 'z') || !(OPT_ISSET(ops, 'z') || OPT_ISSET(ops, 'v') ||
OPT_ISSET(ops, 's') || OPT_ISSET(ops, 'S')))) { OPT_ISSET(ops, 's') || OPT_ISSET(ops, 'S')))) {
int fdarg, fd; int fdarg, fd;
@ -4359,7 +4364,8 @@ bin_print(char *name, char **args, Options ops, int func)
/* normal output */ /* normal output */
if (!fmt) { if (!fmt) {
if (OPT_ISSET(ops, 'z') || OPT_ISSET(ops, 's')) { if (OPT_ISSET(ops, 'z') || OPT_ISSET(ops, 's') ||
OPT_ISSET(ops, 'v')) {
/* /*
* We don't want the arguments unmetafied after all. * We don't want the arguments unmetafied after all.
*/ */
@ -4367,6 +4373,13 @@ bin_print(char *name, char **args, Options ops, int func)
metafy(args[n], len[n], META_NOALLOC); metafy(args[n], len[n], META_NOALLOC);
} }
/* -v option -- store the arguments in the named parameter */
if (OPT_ISSET(ops,'v')) {
queue_signals();
assignsparam(OPT_ARG(ops, 'v'), sepjoin(args, NULL, 0), 0);
unqueue_signals();
return 0;
}
/* -z option -- push the arguments onto the editing buffer stack */ /* -z option -- push the arguments onto the editing buffer stack */
if (OPT_ISSET(ops,'z')) { if (OPT_ISSET(ops,'z')) {
queue_signals(); queue_signals();
@ -4474,7 +4487,7 @@ bin_print(char *name, char **args, Options ops, int func)
* special cases of printing to a ZLE buffer or the history, however. * special cases of printing to a ZLE buffer or the history, however.
*/ */
if (OPT_ISSET(ops,'z') || OPT_ISSET(ops,'s')) { if (OPT_ISSET(ops,'z') || OPT_ISSET(ops,'s') || OPT_ISSET(ops, 'v')) {
#ifdef HAVE_OPEN_MEMSTREAM #ifdef HAVE_OPEN_MEMSTREAM
if ((fout = open_memstream(&buf, &mcount)) == NULL) if ((fout = open_memstream(&buf, &mcount)) == NULL)
zwarnnam(name, "open_memstream failed"); zwarnnam(name, "open_memstream failed");
@ -4853,7 +4866,7 @@ bin_print(char *name, char **args, Options ops, int func)
/* if there are remaining args, reuse format string */ /* if there are remaining args, reuse format string */
} while (*argp && argp != first && !fmttrunc && !OPT_ISSET(ops,'r')); } while (*argp && argp != first && !fmttrunc && !OPT_ISSET(ops,'r'));
if (OPT_ISSET(ops,'z') || OPT_ISSET(ops,'s')) { if (OPT_ISSET(ops,'z') || OPT_ISSET(ops,'s') || OPT_ISSET(ops,'v')) {
#ifdef HAVE_OPEN_MEMSTREAM #ifdef HAVE_OPEN_MEMSTREAM
putc(0, fout); putc(0, fout);
fclose(fout); fclose(fout);
@ -4865,11 +4878,14 @@ bin_print(char *name, char **args, Options ops, int func)
buf[count] = '\0'; buf[count] = '\0';
#endif #endif
queue_signals(); queue_signals();
stringval = metafy(buf, -1, META_REALLOC);
if (OPT_ISSET(ops,'z')) { if (OPT_ISSET(ops,'z')) {
zpushnode(bufstack, buf); zpushnode(bufstack, stringval);
} else if (OPT_ISSET(ops,'v')) {
assignsparam(OPT_ARG(ops, 'v'), stringval, 0);
} else { } else {
ent = prepnexthistent(); ent = prepnexthistent();
ent->node.nam = buf; ent->node.nam = stringval;
ent->stim = ent->ftim = time(NULL); ent->stim = ent->ftim = time(NULL);
ent->node.flags = 0; ent->node.flags = 0;
ent->words = (short *)NULL; ent->words = (short *)NULL;

View file

@ -301,3 +301,12 @@
>one two three four >one two three four
> one two three four > one two three four
> one two three four > one two three four
unset foo
print -v foo once more
print -r -- $foo
printf -v foo "%s-" into the breach
print -r -- $foo
0:print and printf into a variable
>once more
>into-the-breach-