From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 15601 invoked by alias); 31 Dec 2015 18:49:05 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: X-Seq: 37467 Received: (qmail 10251 invoked from network); 31 Dec 2015 18:49:02 -0000 X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,T_DKIM_INVALID autolearn=ham autolearn_force=no version=3.4.0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=brasslantern-com.20150623.gappssmtp.com; s=20150623; h=from:message-id:date:in-reply-to:comments:references:to:subject :mime-version:content-type; bh=l9d23+QKZOaxzqCA38cf7zU3vSjjJQVx9uKwr+aLve0=; b=lH1cD3TTAALqDCv2Bts+c3nPDg7YwJ2RqPDlIfoZVdkDQ+h55T5AQ0vYNZYGzcEVBo 4vvewOY4I5PLxBPFhlA8g4EAfOI67E/JrALfgsvtb1YilaIDwXLjcm2B8ZDyxY5shJuH S1TCnT0uZlcy/cT4lFsAV1plyZHfR+qCorNYMgBgbEiJNtUAtZqRQiTFvmsdL7PSdC5S y+Z2ACDDnSj7WEjRBZwVSlh/BBSEkTlKSLV4Y0TVj8QzVx0fMg/n2j4IUrJggJD5phv9 3l9YKSpj8Lq8AdhqgCq82iA5NmZ6cCpcsvycPY7q7A80nvobucorx3kTPMDEqCqiW0qD 38bA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:message-id:date:in-reply-to:comments :references:to:subject:mime-version:content-type; bh=l9d23+QKZOaxzqCA38cf7zU3vSjjJQVx9uKwr+aLve0=; b=FMMWi0g8pq5exirFksFjgnvdmdFuoZt2C21RZIcjqv1W+dDgFiqPO6CpaaKwALFQwb 9SYZ2PH0kcL/Jvw5CNeVQA2Bq+l1gv3RHoENiI0j9i9dKyFLlguUv4zZgh8B1gtaNmOt J4NvQiTLSJNFVixS7RXPLDoBzae4asIUuc3KYlM61H2ppDmWOKAQE3HiDphiekcAySgz HZy3oK1bQv716QSYGphaj1DiedeDOuIgx69I+wH4QAVAORiYOuJt8HCxbSDQUTPVmOsx 6Vsxm2eruOTo0m5HjD3600+UpWUryQe4xixWQKZTbmSyBvFPhIv40OsOQgkHWjSemypO W2KA== X-Gm-Message-State: ALoCoQlE4vugURp5PMbjNouqJYQHcGvhq1TxtH67UD9sCqH38VTjJ8Md/M/uNhXOzoLBZ7zyyA0iBoiny2GK3t+6WYOvdpDriw== X-Received: by 10.66.227.1 with SMTP id rw1mr103880899pac.35.1451587738811; Thu, 31 Dec 2015 10:48:58 -0800 (PST) From: Bart Schaefer Message-Id: <151231104858.ZM24513@torch.brasslantern.com> Date: Thu, 31 Dec 2015 10:48:58 -0800 In-Reply-To: <068ca8f5-315b-444c-b281-5f183e1daa8c@email.android.com> Comments: In reply to Peter Stephenson "Re: Printf builtin missing v flag support" (Dec 31, 10:44am) References: <068ca8f5-315b-444c-b281-5f183e1daa8c@email.android.com> X-Mailer: OpenZMail Classic (0.9.2 24April2005) To: zsh-workers@zsh.org Subject: Re: Printf builtin missing v flag support MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii On Dec 31, 10:44am, Peter Stephenson wrote: } } The feature is obviously useful but the print implementation is } a nightmare of special cases making it hard to change without } considerable refactoring. That would probably be a Good Work, given } enough test cases to check it, but is going to have to wait for a } volunteer. } } I haven't checked whether -v is already in use in which case this is moot. -v is not in use, and the print implementation has already been refactored to support the -z and -s options in printf, so this is actually rather easy. I noticed that "print" uses metafy() on the aguments to -z and -s, but "printf" did not, so I added metafy() for those cases. Somebody holler if this is wrong. diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo index 120ec82..dc0b947 100644 --- a/Doc/Zsh/builtins.yo +++ b/Doc/Zsh/builtins.yo @@ -1124,7 +1124,7 @@ tt(popd) that do not change the environment seen by an interactive user. ) findex(print) 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 no flags or with the flag `tt(-)', the arguments are printed on 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))( 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))( Expand leading tabs on each line of output in the printed string 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. ) 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 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 @@ -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 required by the format than have been specified, the behaviour is as if 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) pindex(PUSHD_TO_HOME, use of) diff --git a/Src/builtin.c b/Src/builtin.c index b06bc6d..128bc36 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -99,8 +99,8 @@ static struct builtin builtins[] = #endif 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("printf", 0, bin_print, 1, -1, BIN_PRINTF, NULL, 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, "v:", 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("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; 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 (!strcmp(*args, "--") && !*++args) { zwarnnam(name, "not enough arguments"); @@ -4157,8 +4162,8 @@ bin_print(char *name, char **args, Options ops, int func) if ((OPT_HASARG(ops,'u') || OPT_ISSET(ops,'p')) && /* rule out conflicting options -- historical precedence */ ((!fmt && (OPT_ISSET(ops,'c') || OPT_ISSET(ops,'C'))) || - !(OPT_ISSET(ops, 'z') || - OPT_ISSET(ops, 's') || OPT_ISSET(ops, 'S')))) { + !(OPT_ISSET(ops, 'z') || OPT_ISSET(ops, 'v') || + OPT_ISSET(ops, 's') || OPT_ISSET(ops, 'S')))) { int fdarg, fd; if (OPT_ISSET(ops, 'p')) { @@ -4359,7 +4364,8 @@ bin_print(char *name, char **args, Options ops, int func) /* normal output */ 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. */ @@ -4367,6 +4373,13 @@ bin_print(char *name, char **args, Options ops, int func) 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 */ if (OPT_ISSET(ops,'z')) { 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. */ - 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 if ((fout = open_memstream(&buf, &mcount)) == NULL) 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 */ } 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 putc(0, fout); fclose(fout); @@ -4865,11 +4878,14 @@ bin_print(char *name, char **args, Options ops, int func) buf[count] = '\0'; #endif queue_signals(); + stringval = metafy(buf, -1, META_REALLOC); 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 { ent = prepnexthistent(); - ent->node.nam = buf; + ent->node.nam = stringval; ent->stim = ent->ftim = time(NULL); ent->node.flags = 0; ent->words = (short *)NULL; diff --git a/Test/B03print.ztst b/Test/B03print.ztst index eb79c4d..2e9bf99 100644 --- a/Test/B03print.ztst +++ b/Test/B03print.ztst @@ -301,3 +301,12 @@ >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-