Re: process substitution not correctly parsed inside variable expansion

2017-03-18 Thread Chet Ramey
On 3/17/17 11:30 AM, D630 wrote:
> There is a parse error in B:

Thanks for the report.  I'll take a look.

Chet

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/



[PATCH] Fix types in complete.c

2017-03-18 Thread Eduardo Bustamante
---
 lib/readline/complete.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/readline/complete.c b/lib/readline/complete.c
index 13241d13..726d51fb 100644
--- a/lib/readline/complete.c
+++ b/lib/readline/complete.c
@@ -2644,7 +2644,7 @@ rl_filename_completion_function (const char
*text, int state)
hit the end of the match list, we restore the original unmatched text,
ring the bell, and reset the counter to zero. */
 int
-rl_old_menu_complete (int count, invoking_key)
+rl_old_menu_complete (int count, int invoking_key)
 {
   rl_compentry_func_t *our_func;
   int matching_filenames, found_quote;
@@ -2947,7 +2947,7 @@ rl_menu_complete (int count, int ignore)
 }

 int
-rl_backward_menu_complete (int count, key)
+rl_backward_menu_complete (int count, int key)
 {
   /* Positive arguments to backward-menu-complete translate into negative
  arguments for menu-complete, and vice versa. */
-- 
2.11.0



Re: \! and \# in PS1 vs PS2 vs PS4, PS0 and ${var@P}

2017-03-18 Thread Chet Ramey
On 3/17/17 5:43 PM, Grisha Levit wrote:

> Fair enough; sorry for the vague report.  I thought it was surprising that:
> 
> 1. \! and \# increment at different times during command entry

OK, I see what you mean.  They are incremented at different times, and by
different "agents". The command number (\#) is incremented after the shell
parses a complete command and before it is executed.  The history number
(\!) increments when the first line of the command is read and returned and
bash calls add_history.  It's the result of the division of responsibility
between bash and readline.  The shell is the one responsible for adding
subsequent lines to the first history entry (`command-oriented history'),
so the history library has done it's job: it's incremented the history
number and is waiting for the next call to add_history().

Maybe the shell could special-case \! for the second and subsequent lines
of a multi-line command, but that seems tricky to get right.

How would you suggest capturing this in the documentation in a way that
would be clearer?  The text from your previous message or something else?

Chet
-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/



Re: \! and \# in PS1 vs PS2 vs PS4, PS0 and ${var@P}

2017-03-18 Thread Chet Ramey
On 3/17/17 5:43 PM, Grisha Levit wrote:
> On Tue, Mar 14, 2017 at 9:07 PM, Chet Ramey  wrote:
>> when PS1 is expanded the first time, the "current" history entry is the
>> one corresponding to the last command entered
> 
>> PS2 looks at the current history entry, which is 530 since we've
>> started on it.
> 
> I think I'm missing something. It seems that when PS1 is expanded \! *does*
> match what will eventually become the history number of the command-to-be-
> -entered, while PS2 does not. i.e. I can't see how we've started on the second
> line of history if the current input will still be stored in the first.

OK, let me take a look.

> 
> $ PS1='\!  $ ' PS2=${PS1/$/>}; history -c
> 1  $ : 1.1 \
> 2  > : 1.2
> 2  $ fc -l -1
> 1: 1.1 : 1.2
> 
>> When the first line is entered, the history number and command numbers
>> get incremented
> 
> There seems to be a mismatch: the history number is incremented and the
> command number is not:

This is true; the command number is incremented only when the complete
command is parsed and before it's executed, before PS0 is displayed.

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/



Re: "unset var" pops var off variable stack instead of unsetting it

2017-03-18 Thread Chet Ramey
On 3/17/17 8:21 PM, Stephane Chazelas wrote:

> I don't expect the need to have to add "local var" in
> 
> (
>unset -v var
>echo "${var-OK}"
> )
> 
> would be obvious to many people beside you though.

Try the following:

function foo
{
(
unset -v IFS
recho "${IFS-unset}"

foo='a:b:c:d'
recho $foo
)
}

IFS=':|'
foo
echo after IFS = "$IFS"

Bash and ksh93 echo '', '', and ':|'.


> People writing function libraries meant to be used by several
> POSIX-like shells need to change their code to:
> 
> split() (
>   [ -z "$BASH_VERSION" ] || local IFS # WA for bash bug^Wmisfeature
>   unset -v IFS
>   set -f 
>   split+glob $1
> )
> 
> if they want them to be reliable in bash.

Well, there's the fact that you've left the realm of standardization when
you start talking about local variables, so "Posix-like" doesn't have
much meaning.

> 
>> The problem is the non-obvious nature of unset's interaction with scope,
> 
> the main problem to me is an unset command that doesn't unset.

So you don't like dynamic scoping.  This is not new.

> As shown in my original post, there's also a POSIX conformance
> issue.

Yeah, it looks like there is differing behavior that has to do with the
"special builtin" nature of eval and unset.  In Posix, these two statements
are essentially equivalent:

a=1 eval unset a
a=1; eval unset a

I am not a fan of the special builtin behavior rules.

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/



Re: "unset var" pops var off variable stack instead of unsetting it

2017-03-18 Thread Chet Ramey
On 3/17/17 6:35 PM, Dan Douglas wrote:

> The problem is the non-obvious nature of unset's interaction with scope,
> (and the lack of documentation). Not much can be done about the former,
> as it is with so many things.

How would you suggest improving the documentation? I can see highlighting
the fact that unset applied to a local variable at the same scope
preserves the local attribute. What else?


-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/



Re: "unset var" pops var off variable stack instead of unsetting it

2017-03-18 Thread Chet Ramey
On 3/17/17 5:51 PM, Stephane Chazelas wrote:

> Now, if that "split" functions is called from within a function
> that declares $IFS local like:
[...]
> because after the "unset IFS", $IFS is not unset (which would
> result in the default splitting behaviour) but set to ":" as it
> was before "bar" ran "local IFS=."

This is how local variables work.  Setting a local variable shadows
any global with the same name; unsetting a local variable reveals the
global variable (or really, because bash has dynamic scoping, the value
at a previous scope) since there is no longer a local variable to shadow
it.

> 
> A simpler reproducer:
> 
> $ bash -c 'f()(unset a; echo "$a"); g(){ local a=1; f;}; a=0; g'
> 0
> 
> Or even with POSIX syntax:
> 
> $ bash -c 'f()(unset a; echo "$a"); a=0; a=1 eval f'
> 0

In this case, the unset unsets the variable provided in the builtin's
`environment'.  It's essentially the same thing.

> 
> A work around is to change the "split" function to:
> 
> split() (
>   local IFS
>   unset -v IFS  # default splitting
>   set -o noglob # disable glob
> 
>   set -- $1 # split+(no)glob
>   [ "$#" -eq 0 ] || printf '<%s>\n' "$@"
> )
> 
> For some reason, in that case (when "local" and "unset" are
> called in the same function context), unset does unset the
> variable.

There's special code in bash to preserve the locally-declared nature of
a variable if you use local and unset in the same function scope.  That's
been in bash forever (at least as far back as bash-2.0, which is when I
quit looking), for compatibility -- that's how ksh93 behaves -- and user
expectations.

Chet
-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/



Re: [BUG] With null IFS, ${1+$*}, ${var-$*}, etc. don't generate fields

2017-03-18 Thread Martijn Dekker
Op 27-02-17 om 21:03 schreef Chet Ramey:
> If you think you have a winning argument, initiate a new discussion with
> the Austin Group.  You might want to dig up the mail archives from
> October, 2014 and look at the discussion that preceded interpretation 888.

Thanks for the heads-up. I'm finding some time to do that now.

> You might also prepare a counter to the argument that at the time the
> $* on the right side of the parameter expansion is expanded, the rules
> in force are detailed in 2.6.2 ("word shall be subjected to tilde
> expansion, parameter expansion, command substitution, and arithmetic
> expansion"), and word splitting isn't listed. I think that came up before.

I've got three counterpoints to that:

1. This is irrelevant, because the bug does not concern splitting
fields, but instead failure to generate fields as specified.

2. Even if it were relevant, in the case under discussion, IFS is null,
so field splitting is a no-op anyway.

3. In the general case, field splitting not being listed there simply
means that field splitting is not performed for the word on the right
side /within/ an expansion such as ${var-$*} (in this case, that word
being $*). If the ${var-$*} expansion as a whole is not quoted, then
field splitting is performed as normal for the expansion as a whole (as
is pathname expansion/globbing), as detailed in 2.6.

- M.