zsh-workers
 help / color / mirror / code / Atom feed
* PATCH: print -v with an array
@ 2016-09-19 16:50 Oliver Kiddle
  2016-09-19 20:30 ` Bart Schaefer
  0 siblings, 1 reply; 6+ messages in thread
From: Oliver Kiddle @ 2016-09-19 16:50 UTC (permalink / raw)
  To: Zsh workers

A feature of the shell printf implementations is that the format
string will be reused if additional arguments remain. So you can
do things like print out an associative array:
  printf '%s - %s\n' ${(kv)_comps}

This patch makes print -v check if the variable is an array and if
so, each reuse of the format string will correspond to a separate
array element. So you can combine or skip elements: perhaps matches
and descriptions in a completion function. In general, I find any
case where I can apply an operation to all elements of an array to
be very useful.

This is also something that can't be done directly with command
substitution. Ksh93 has the right basic idea in not forking for
builtins and -v otherwise feels somehow not right.

This is not fully bash compatible. Neither actually was our previous
implementation because bash assigns to the first element of the
array leaving subsequent elements unchanged. printf -v was added
after zsh 5.2 was released so we've no compatibility concern there.
Alternatives to checking if the variable is an array first would
be a -A option or perhaps making the feature specific to print
(which bash lacks) and not to printf.

With a bit of rearrangment of bin_print it would now be possible
to use this to allow more mixing of print options: -f with -c, for
example.

Back in January, when I wasn't paying attention, Bart wrote:
> - Should "print -v foo bar" write the trailing newline into $foo ?  In the
>   patch below I've chosen to make -n implicit with -v.  This does not
>   involve "printf" which always needs an explicit newline.

I'd suggest we include the trailing newline if the -l option was
specified. Seems it does get included with -c.

With print -v the open_memstream stuff might see more usage. Should
we be concerned with more efficient alternatives to the temporary
file fallback?

It appears to work to use shm_open followed by fdopen, do the writes,
a final fflush and then mmap the file descriptor to get at what was
written. That's fairly guaranteed to be in memory and shared memory
limits shouldn't be a problem. pipe() also works but it tends to have
a limited buffer size in the region of 16-64K.

A memfd_create system call was recently added to Linux. Combined
with fdopen, that would provide an alternative on Linux where libc
is something other than glibc. FreeBSD appears to have open_memstream.
On Solaris a tmpfs /tmp has been standard for a very long time so
the temporary file is unlikely to ever touch a disc anyway.

Oliver

diff --git a/Completion/Zsh/Command/_print b/Completion/Zsh/Command/_print
index 38f17ab..8df0941 100644
--- a/Completion/Zsh/Command/_print
+++ b/Completion/Zsh/Command/_print
@@ -1,15 +1,18 @@
 #compdef print printf
 
-local state expl line eflag pflag rest ret=1
+local state expl line eflag pflag rflag rest ret=1
 
 if [[ $service = print ]]; then
   # -e flag available only after -R 
   eflag="${words[1,CURRENT-1][(r)-*R*]:+-e[enable escapes]}"
+  rflag='-r[ignore escape conventions of echo]'
 
   # -p flag only relevant if we have a coprocess
   (:>&p) 2>/dev/null &&
     pflag='(-s -u -z)-p[print arguments to input of coprocess]'
 
+  [[ -n ${words[(r)-*f]} ]] && rflag='-r[disable reuse of format string]'
+
   if [[ -n ${words[1,CURRENT][(r)-*P*]} ]]; then
     rest='*: :->prompt'
   else
@@ -17,11 +20,11 @@ if [[ $service = print ]]; then
   fi
 
   _arguments -C -s -A "-*" -S \
-    '(-f)-r[ignore escape conventions of echo]' \
+    '-r[ignore escape conventions of echo]' \
     '(-r -b -f -m -s -l -N -o -O -i -c -u -p -z -D -P)-R[emulate BSD echo (no escapes, -n & -e flags only)]' \
     '-b[recognise bindkey escape sequences]' \
-    '-m[remove arguments matching specified pattern]' \
-    '(-r -n -R -l -N -c)-f+[print arguments as for the printf builtin]:format:->printfformat' \
+    '-m[remove arguments not matching specified pattern]:pattern' \
+    '(-n -R -l -N -c)-f+[print arguments as for the printf builtin]:format:->printfformat' \
     '(-u -p -z)-s[place results in the history list]' \
     '(-c -f)-n[do not add a newline to the result]' \
     '(-N -c -f)-l[print arguments separated by newlines]' \
@@ -33,11 +36,13 @@ if [[ $service = print ]]; then
     '(-n -l -N -f -C -s -z)-c[print arguments in columns]' \
     '(-n -l -N -f -c -s -z)-C+[print arguments in specified number of columns]:columns' \
     '(-s -p -z)-u+[specify file descriptor to print arguments to]:file descriptor:_file_descriptors' \
-    '-v[store output in named parameter]:parameter:_parameters' \
+    '(-s -z -p -u)-v[store output in named parameter]:parameter:_parameters' \
     '(-s -p -u)-z[push arguments onto editing buffer stack]' \
     '-D[substitute any arguments which are named directories using ~ notation]' \
     '-P[perform prompt expansion]' \
-    $pflag $eflag $rest && ret=0
+    '(-X -f -a -C -c -z)-x+[expand leading tabs]:tab width' \
+    '(-x -f -a -C -c -z)-X+[expand all tabs]:tab width' \
+    $pflag $eflag $rflag $rest && ret=0
 elif [[ $service = printf ]]; then
   state=printf
 fi
diff --git a/Completion/Zsh/Type/_globquals b/Completion/Zsh/Type/_globquals
index 6eef168..a904bdf 100644
--- a/Completion/Zsh/Type/_globquals
+++ b/Completion/Zsh/Type/_globquals
@@ -121,8 +121,7 @@ while [[ -n $PREFIX ]]; do
 	tmatch=( s m h d w M )
 	if zstyle -t ":completion:${curcontext}:time-specifiers" verbose; then
 	  zstyle -s ":completion:${curcontext}:time-specifiers" list-separator sep || sep=--
-          print -v tdisp -f "%s ${sep//(#m)[%\\]/$MATCH$MATCH} %s\0" ${tmatch:^^tdisp}
-	  tdisp=( ${(0)tdisp} )
+          print -v tdisp -f "%s ${sep//(#m)[%\\]/$MATCH$MATCH} %s" ${tmatch:^^tdisp}
 	fi
 	alts+=( "time-specifiers:time specifier:compadd -E 0 -d tdisp -S '' -a tmatch" )
       fi
diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo
index ac4441c..1676c25 100644
--- a/Doc/Zsh/builtins.yo
+++ b/Doc/Zsh/builtins.yo
@@ -1289,7 +1289,9 @@ 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.
+parameter var(name), instead of printed. If var(name) is an array and
+the format string is reused when consuming arguments then one
+array element will be used for each use of the format string.
 )
 findex(pushd)
 pindex(PUSHD_TO_HOME, use of)
diff --git a/Src/builtin.c b/Src/builtin.c
index 248f929..47dcc4c 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -4051,10 +4051,11 @@ bin_print(char *name, char **args, Options ops, int func)
 {
     int flen, width, prec, type, argc, n, narg, curlen = 0;
     int nnl = 0, fmttrunc = 0, ret = 0, maxarg = 0, nc = 0;
-    int flags[6], *len;
+    int flags[6], *len, visarr = 0;
     char *start, *endptr, *c, *d, *flag, *buf = NULL, spec[14], *fmt = NULL;
     char **first, **argp, *curarg, *flagch = "'0+- #", save = '\0', nullstr = '\0';
     size_t rcount = 0, count = 0;
+    size_t *cursplit, *splits = 0;
     FILE *fout = stdout;
 #ifdef HAVE_OPEN_MEMSTREAM
     size_t mcount;
@@ -4086,7 +4087,7 @@ bin_print(char *name, char **args, Options ops, int func)
             return 1; \
         } \
         unlink(tmpf); \
-        if ((fout = fdopen(tempfd, "w+")) == NULL) { \
+        if ((FOUT = fdopen(tempfd, "w+")) == NULL) { \
             close(tempfd); \
             zwarnnam(name, "can't open temp file: %e", errno); \
             return 1; \
@@ -4611,11 +4612,23 @@ 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,'v')) {
+	struct value vbuf;
+	char* s = OPT_ARG(ops,'v');
+	Value v = getvalue(&vbuf, &s, 0);
+	visarr = v && PM_TYPE(v->pm->node.flags) == PM_ARRAY;
+    }
     /* printf style output */
     *spec = '%';
     argp = args;
     do {
     	rcount = count;
+	if (argp > args && visarr) { /* reusing format string */
+	    if (!splits)
+		cursplit = splits = (size_t *)zhalloc(sizeof(size_t) *
+			(arrlen(args) / (argp - args) + 1));
+	    *cursplit++ = count;
+	}
     	if (maxarg) {
 	    first += maxarg;
 	    argc -= maxarg;
@@ -4982,18 +4995,30 @@ bin_print(char *name, char **args, Options ops, int func)
 	    if (buf)
 		free(buf);
 	} else {
-	    stringval = metafy(buf, rcount, META_REALLOC);
-	    if (OPT_ISSET(ops,'z')) {
-		zpushnode(bufstack, stringval);
-	    } else if (OPT_ISSET(ops,'v')) {
-		setsparam(OPT_ARG(ops, 'v'), stringval);
+	    if (visarr) {
+		char **arrayval = zshcalloc((cursplit - splits + 2) * sizeof(char *));
+		for (;cursplit >= splits; cursplit--) {
+		    int start = cursplit == splits ? 0 : cursplit[-1];
+		    arrayval[cursplit - splits] =
+			    metafy(buf + start, count - start, META_DUP);
+		    count = start;
+		}
+		setaparam(OPT_ARG(ops, 'v'), arrayval);
+		free(buf);
 	    } else {
-		ent = prepnexthistent();
-		ent->node.nam = stringval;
-		ent->stim = ent->ftim = time(NULL);
-		ent->node.flags = 0;
-		ent->words = (short *)NULL;
-		addhistnode(histtab, ent->node.nam, ent);
+		stringval = metafy(buf, rcount, META_REALLOC);
+		if (OPT_ISSET(ops,'z')) {
+		    zpushnode(bufstack, stringval);
+		} else if (OPT_ISSET(ops,'v')) {
+		    setsparam(OPT_ARG(ops, 'v'), stringval);
+		} else {
+		    ent = prepnexthistent();
+		    ent->node.nam = stringval;
+		    ent->stim = ent->ftim = time(NULL);
+		    ent->node.flags = 0;
+		    ent->words = (short *)NULL;
+		    addhistnode(histtab, ent->node.nam, ent);
+		}
 	    }
 	}
 	unqueue_signals();
diff --git a/Test/B03print.ztst b/Test/B03print.ztst
index befe2f2..74e34f3 100644
--- a/Test/B03print.ztst
+++ b/Test/B03print.ztst
@@ -310,3 +310,9 @@
 0:print and printf into a variable
 >typeset foo='once more'
 >typeset foo=$'into\C-@the-breach\C-@-'
+
+ foo=()
+ print -f '%2$d %4s' -v foo one 1 two 2 three 3
+ typeset -p foo
+0:printf into an array variable
+>typeset -a foo=( '1  one' '2  two' '3 three' )


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PATCH: print -v with an array
  2016-09-19 16:50 PATCH: print -v with an array Oliver Kiddle
@ 2016-09-19 20:30 ` Bart Schaefer
  2016-09-21 19:51   ` Oliver Kiddle
  0 siblings, 1 reply; 6+ messages in thread
From: Bart Schaefer @ 2016-09-19 20:30 UTC (permalink / raw)
  To: Zsh workers

On Sep 19,  6:50pm, Oliver Kiddle wrote:
}
} This patch makes print -v check if the variable is an array and if
} so, each reuse of the format string will correspond to a separate
} array element.  [...]  printf -v was added
} after zsh 5.2 was released so we've no compatibility concern there.
} [...]
} With a bit of rearrangment of bin_print it would now be possible
} to use this to allow more mixing of print options: -f with -c, for
} example.

When did we get the ability to do "print -z -f ..."  It might be
useful to have every reuse of the format add a separate entry to
the buffer stack.  Similarly for "print -s -f" and the history.
(Currently -S is silently ignored if -f is given.  Hmm.  Not sure
how that ought to work anyway.)

} Alternatives to checking if the variable is an array first would
} be a -A option or perhaps making the feature specific to print
} (which bash lacks) and not to printf.

I'd lean toward the -A option (especially if we alter -z / -s as I
just mentioned above).  Right now print -v / printf -v can create a
variable (for which BTW we are lacking a WARN_CREATE_GLOBAL warning),
it'd be nice to create it as an array.

I see you've implemented it by building up the array and then doing
the assignment all at once, rather than appending one element at a
time.  This makes it possible to use it for associative arrays, even
though it'd be a bit unusual to have the same format for both keys
and values.

} Back in January, when I wasn't paying attention, Bart wrote:
} > - Should "print -v foo bar" write the trailing newline into $foo ?  In the
} >   patch below I've chosen to make -n implicit with -v.  This does not
} >   involve "printf" which always needs an explicit newline.
} 
} I'd suggest we include the trailing newline if the -l option was
} specified. Seems it does get included with -c.

It's probably a mistake/oversight with -c.  The *embedded* newlines
always get included.  The question is whether

    print -l one two three four
and
    print -l -v stuff one two three four
    print "$stuff"

should produce identical output, rather than the latter having two
consecutive newlines at the end.  Whichever way we decide, the same
really should also apply to -c.

} With print -v the open_memstream stuff might see more usage. Should
} we be concerned with more efficient alternatives to the temporary
} file fallback?

I have no opinion here, except to grumble about ending up with three
or four #ifdef'd implementations of the same thing.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PATCH: print -v with an array
  2016-09-19 20:30 ` Bart Schaefer
@ 2016-09-21 19:51   ` Oliver Kiddle
  2016-09-21 21:24     ` Bart Schaefer
  0 siblings, 1 reply; 6+ messages in thread
From: Oliver Kiddle @ 2016-09-21 19:51 UTC (permalink / raw)
  To: Zsh workers

Bart wrote:
> When did we get the ability to do "print -z -f ..."  It might be

Not long after printf itself was added.

> useful to have every reuse of the format add a separate entry to
> the buffer stack.  Similarly for "print -s -f" and the history.

I doubt that anyone would notice a change of behaviour. Is multiple
entries definitely more useful?

> (Currently -S is silently ignored if -f is given.  Hmm.  Not sure
> how that ought to work anyway.)

-S is also missing from the completion function so I've missed that.
The only way it could work is for the parsing and splitting to be done
last. It doesn't even take more than one argument at the moment.

> I'd lean toward the -A option (especially if we alter -z / -s as I

Being able to create the array direct is nice and it is more
consistent with read and set. My concern was that adding ever more
options causes the most commonly used ones to get buried in
documentation and completion listings.

> just mentioned above).  Right now print -v / printf -v can create a
> variable (for which BTW we are lacking a WARN_CREATE_GLOBAL warning),

WARN_CREATE_GLOBAL is handled internally to setsparam so that's covered.

> I see you've implemented it by building up the array and then doing
> the assignment all at once, rather than appending one element at a
> time.  This makes it possible to use it for associative arrays, even
> though it'd be a bit unusual to have the same format for both keys
> and values.

While it's only five lines of code to check for a hash and use
sethparam, it just doesn't seem useful enough to do that.

> } > - Should "print -v foo bar" write the trailing newline into $foo ?  In the
> } I'd suggest we include the trailing newline if the -l option was
> } specified. Seems it does get included with -c.
>
> It's probably a mistake/oversight with -c.  The *embedded* newlines
> always get included.  The question is whether
>
>     print -l one two three four
> and
>     print -l -v stuff one two three four
>     print "$stuff"
>
> should produce identical output, rather than the latter having two
> consecutive newlines at the end.  Whichever way we decide, the same
> really should also apply to -c.

I'd vote for the two consecutive newlines in the case of both -l and -c.

Oliver


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PATCH: print -v with an array
  2016-09-21 19:51   ` Oliver Kiddle
@ 2016-09-21 21:24     ` Bart Schaefer
  2016-11-04 16:37       ` Oliver Kiddle
  0 siblings, 1 reply; 6+ messages in thread
From: Bart Schaefer @ 2016-09-21 21:24 UTC (permalink / raw)
  To: Zsh workers

On Sep 21,  9:51pm, Oliver Kiddle wrote:
} Subject: Re: PATCH: print -v with an array
}
} Bart wrote:
} > useful to have every reuse of the format add a separate entry to
} > the buffer stack.  Similarly for "print -s -f" and the history.
} 
} I doubt that anyone would notice a change of behaviour. Is multiple
} entries definitely more useful?

I don't know of a specific use-case.  It just seemed to make sense
that if you deliberately designed the format to consume only part
of the input on each pass, you might be expecting it to make separate
entries for each chunk so consumed.

Multiple buffer-stack entries might be less useful than multiple history
entries just because the buffer stack is LIFO.

} > (Currently -S is silently ignored if -f is given.  Hmm.  Not sure
} > how that ought to work anyway.)
} 
} -S is also missing from the completion function so I've missed that.
} The only way it could work is for the parsing and splitting to be done
} last. It doesn't even take more than one argument at the moment.

Yes, I'm wondering if print -S -f ... should just be an error.

} > It's probably a mistake/oversight with -c.  The *embedded* newlines
} > always get included.  The question is whether
} >
} >     print -l one two three four
} > and
} >     print -l -v stuff one two three four
} >     print "$stuff"
} >
} > should produce identical output, rather than the latter having two
} > consecutive newlines at the end.  Whichever way we decide, the same
} > really should also apply to -c.
} 
} I'd vote for the two consecutive newlines in the case of both -l and -c.

Feel free to fix this when you make whatever other tweaks emerge from
the foregoing conversation.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PATCH: print -v with an array
  2016-09-21 21:24     ` Bart Schaefer
@ 2016-11-04 16:37       ` Oliver Kiddle
  2016-11-05  4:03         ` Bart Schaefer
  0 siblings, 1 reply; 6+ messages in thread
From: Oliver Kiddle @ 2016-11-04 16:37 UTC (permalink / raw)
  To: Zsh workers

On 21 Sep, Bart wrote:
> Yes, I'm wondering if print -S -f ... should just be an error.

Combining print -S with multiple arguments with a zsh debug build is printing:
 exec.c:3837: BUG: q = 3 != queue_in = 4

> } I'd vote for the two consecutive newlines in the case of both -l and -c.
>
> Feel free to fix this when you make whatever other tweaks emerge from
> the foregoing conversation.

The patch below does that. It also adds -S to _print which ends up
looking like a big change because -S gets added to the exclusion list of
most other options. There's probably further exclusions that could be
added there.

I've also updated two further uses of printf in completion functions to
make use of the new feature - in _fc and _ps1234.

The most notable thing about this patch is what it does not do. I've
not moved the array behaviour to a -A option. That's not something I'm
especially bothered about and if someone is keen to change it then I
don't especially care.

-A would have been more consistent with read/set and avoids any
need to declare the array. But I don't like needlessly cluttering
builtins with ever more options, -A would not have worked with any
other print option besides -f and I like the fact that this change
gives -v a use that isn't covered by process substitution. Finally,
as I couldn't decide, sticking with what I have is the least effort.

Oliver

diff --git a/Completion/Zsh/Command/_fc b/Completion/Zsh/Command/_fc
index b90436a..6cc01f3 100644
--- a/Completion/Zsh/Command/_fc
+++ b/Completion/Zsh/Command/_fc
@@ -1,7 +1,8 @@
 #compdef fc history r
 
 local curcontext="$curcontext" state state_descr line ret=1
-local events num cmd sep
+local num cmd sep
+local -a events
 typeset -A opt_args
 local fc_common fc_hist fc_r
 
@@ -71,7 +72,7 @@ if [[ -n $state ]]; then
   if [[ -z ${line:#*=*} ]] && compset -P 1 '*='; then
     _message -e replacements 'replacement'
   elif [[ -prefix [0-9] ]]; then
-    events=( ${(0)"$(printf "%-${#HISTNO}.${#HISTNO}s $sep %s\0" "${(kv)history[@]}")"} )
+    print -v events -f "%-${#HISTNO}.${#HISTNO}s $sep %s" "${(kv)history[@]}"
     _wanted -2V events expl "$state_descr" compadd -M "B:0=" -ld events - \
         "${events[@]%% *}"
   elif [[ -prefix - ]]; then
diff --git a/Completion/Zsh/Command/_print b/Completion/Zsh/Command/_print
index 8df0941..0610cd4 100644
--- a/Completion/Zsh/Command/_print
+++ b/Completion/Zsh/Command/_print
@@ -21,27 +21,28 @@ if [[ $service = print ]]; then
 
   _arguments -C -s -A "-*" -S \
     '-r[ignore escape conventions of echo]' \
-    '(-r -b -f -m -s -l -N -o -O -i -c -u -p -z -D -P)-R[emulate BSD echo (no escapes, -n & -e flags only)]' \
+    '(-r -b -f -m -s -S -l -N -o -O -i -c -u -p -z -D -P)-R[emulate BSD echo (no escapes, -n & -e flags only)]' \
     '-b[recognise bindkey escape sequences]' \
     '-m[remove arguments not matching specified pattern]:pattern' \
-    '(-n -R -l -N -c)-f+[print arguments as for the printf builtin]:format:->printfformat' \
-    '(-u -p -z)-s[place results in the history list]' \
+    '(-n -R -l -N -c -S)-f+[print arguments as for the printf builtin]:format:->printfformat' \
+    '(-u -p -z -S)-s[place results in the history list]' \
+    '(-a -f -c -C -i -l -o -O -N -u -p -v -z -s -x -X)-S[place results in the history list, after splitting argument into words]' \
     '(-c -f)-n[do not add a newline to the result]' \
-    '(-N -c -f)-l[print arguments separated by newlines]' \
-    '(-n -l -c -f)-N[print arguments separated and terminated by nulls]' \
-    '(-O)-o[sort arguments in ascending order]' \
-    '(-o)-O[sort arguments in descending order]' \
-    '-i[case-insensitive sorting]' \
-    '(-n -l -N -f -s -z)-a[with -c/-C, print arguments across before down]' \
-    '(-n -l -N -f -C -s -z)-c[print arguments in columns]' \
-    '(-n -l -N -f -c -s -z)-C+[print arguments in specified number of columns]:columns' \
-    '(-s -p -z)-u+[specify file descriptor to print arguments to]:file descriptor:_file_descriptors' \
-    '(-s -z -p -u)-v[store output in named parameter]:parameter:_parameters' \
-    '(-s -p -u)-z[push arguments onto editing buffer stack]' \
+    '(-N -c -f -S)-l[print arguments separated by newlines]' \
+    '(-n -l -c -f -S)-N[print arguments separated and terminated by nulls]' \
+    '(-O -S)-o[sort arguments in ascending order]' \
+    '(-o -S)-O[sort arguments in descending order]' \
+    '(-S)-i[case-insensitive sorting]' \
+    '(-n -l -N -f -s -S -z)-a[with -c/-C, print arguments across before down]' \
+    '(-n -l -N -f -C -s -S -z)-c[print arguments in columns]' \
+    '(-n -l -N -f -c -s -S -z)-C+[print arguments in specified number of columns]:columns' \
+    '(-s -S -p -z)-u+[specify file descriptor to print arguments to]:file descriptor:_file_descriptors' \
+    '(-s -S -z -p -u)-v[store output in named parameter]:parameter:_parameters' \
+    '(-s -S -p -u)-z[push arguments onto editing buffer stack]' \
     '-D[substitute any arguments which are named directories using ~ notation]' \
     '-P[perform prompt expansion]' \
-    '(-X -f -a -C -c -z)-x+[expand leading tabs]:tab width' \
-    '(-x -f -a -C -c -z)-X+[expand all tabs]:tab width' \
+    '(-X -f -a -C -c -s -S -z)-x+[expand leading tabs]:tab width' \
+    '(-x -f -a -C -c -s -S -z)-X+[expand all tabs]:tab width' \
     $pflag $eflag $rflag $rest && ret=0
 elif [[ $service = printf ]]; then
   state=printf
diff --git a/Completion/Zsh/Type/_ps1234 b/Completion/Zsh/Type/_ps1234
index 0671ceb..cf19822 100644
--- a/Completion/Zsh/Type/_ps1234
+++ b/Completion/Zsh/Type/_ps1234
@@ -1,6 +1,6 @@
 #compdef -value-,PROMPT,-default- -value-,PROMPT2,-default- -value-,PROMPT3,-default- -value-,PROMPT4,-default- -value-,RPROMPT,-default- -value-,RPROMPT2,-default- -value-,PS1,-default- -value-,PS2,-default- -value-,PS3,-default- -value-,PS4,-default- -value-,RPS1,-default- -value-,RPS2,-default- -value-,SPROMPT,-default-
 
-local -a specs
+local -a specs ccol
 local expl grp cols bs suf pre changed=1 ret=1
 local -A ansi
 
@@ -39,7 +39,8 @@ if compset -P '%[FK]'; then
 
   _description -V ansi-colors expl 'ansi color'
   grp="$expl[expl[(i)-V]+1]"
-  _comp_colors+=( ${(ps.\0.)"$(printf "($grp)=%s=%s\0" ${(kv)ansi})"} )
+  print -v ccol -f "($grp)=%s=%s" ${(kv)ansi}
+  _comp_colors+=( $ccol )
   compadd "$expl[@]" $suf $pre -k ansi && ret=0
   if (( $#suf )) && compset -P "(<->|%v)"; then
     _wanted ansi-colors expl 'closing brace' compadd -S '' \} && ret=0
diff --git a/Src/builtin.c b/Src/builtin.c
index 083a3ae..b7b7bdf 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -4621,7 +4621,8 @@ bin_print(char *name, char **args, Options ops, int func)
 			  OPT_ISSET(ops,'N') ? '\0' : ' ', fout);
 	    }
 	}
-	if (!(OPT_ISSET(ops,'n') || OPT_ISSET(ops, 'v') || nnl))
+	if (!(OPT_ISSET(ops,'n') || nnl ||
+	    (OPT_ISSET(ops, 'v') && !OPT_ISSET(ops, 'l'))))
 	    fputc(OPT_ISSET(ops,'N') ? '\0' : '\n', fout);
 	if (IS_MSTREAM(fout) && (rcount = READ_MSTREAM(buf,fout)) == -1)
 	    ret = 1;


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PATCH: print -v with an array
  2016-11-04 16:37       ` Oliver Kiddle
@ 2016-11-05  4:03         ` Bart Schaefer
  0 siblings, 0 replies; 6+ messages in thread
From: Bart Schaefer @ 2016-11-05  4:03 UTC (permalink / raw)
  To: Zsh workers

On Nov 4,  5:37pm, Oliver Kiddle wrote:
} Subject: Re: PATCH: print -v with an array
}
} On 21 Sep, Bart wrote:
} > Yes, I'm wondering if print -S -f ... should just be an error.
} 
} Combining print -S with multiple arguments with a zsh debug build is printing:
}  exec.c:3837: BUG: q = 3 != queue_in = 4

Thanks for spotting that.  Patch below.

Doesn't answer the question of whether -S -f should be an error.  At the
moment -S and -C and -c are all ignored if -f is with them.  There is
code commented out to make an error of this.

} The most notable thing about this patch is what it does not do. I've
} not moved the array behaviour to a -A option. That's not something
} I'm especially bothered about and if someone is keen to change it
} then I don't especially care.

It has occurred to me that zsh doesn't really need print -v, except
for compatibility.  Other bourne-ish shells fork the right side of
pipes, so piping to read -A won't capture anything in the parent,
but zsh forks to the left.  I suppose print -v does avoid that fork.


diff --git a/Src/builtin.c b/Src/builtin.c
index b7b7bdf..6c9d058 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -4552,6 +4552,7 @@ bin_print(char *name, char **args, Options ops, int func)
 		    short *words;
 		    if (nwords > 1) {
 			zwarnnam(name, "option -S takes a single argument");
+			unqueue_signals();
 			return 1;
 		    }
 		    words = NULL;


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2016-11-05  6:13 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-19 16:50 PATCH: print -v with an array Oliver Kiddle
2016-09-19 20:30 ` Bart Schaefer
2016-09-21 19:51   ` Oliver Kiddle
2016-09-21 21:24     ` Bart Schaefer
2016-11-04 16:37       ` Oliver Kiddle
2016-11-05  4:03         ` 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).