bind -X shows inactive bindings (bindings removed using bind -r)

2019-12-12 Thread Šimon Let
Hi,

according to `bind --help`, `bind -X` should "List key sequences bound with
-x and associated commands in a form that can be reused as input.".

However, when I remove a binding using `bind -r` it still shows up in the
list.

Reproduce:
1) Bind command using: `bind -x "\"\C-r\":\"echo I just pressed C-R\""`
Everything works as expected.
Pressing `\C-r` runs `echo I just pressed C-R`.
Running `bind -X` shows the following list of bound commands: `"\C-r":
"echo I just pressed C-R"`

2) Unbind command using `bind -r "\C-r"`
Pressing `\C-r` does nothing as expected.
Running `bind -X` still shows the same list of bound commands: `"\C-r":
"echo I just pressed C-R"`

This behavior seems very weird to me. I would expect the binding list to
match actual active bindings.

Affected bash versions: 4.3 - 5.0.11


Best regards,

Simon Let


Re: bind -X shows inactive bindings (bindings removed using bind -r)

2019-12-12 Thread Koichi Murase
> according to `bind --help`, `bind -X` should "List key sequences bound with
> -x and associated commands in a form that can be reused as input.".
>
> However, when I remove a binding using `bind -r` it still shows up in the
> list.
>
> Simon Let

I also would like to see this problem fixed.  In this February, I
actually posted to this mailing list a patch fixing this problem (with
another patch):

https://lists.gnu.org/archive/html/bug-bash/2019-02/msg00038.html

Although the first patch was applied to the devel branch, the second
one which fixes this problem seems not to have been reviewed yet.  I
updated the patch to fit the current devel branch.  I attach the
updated patch.  Here is the description quoted from the mail:

> In the second patch
> `0002-do-not-print-unbound-bindings-in-bind-X.patch', to correctly
> dump `bind -x' bindings, I created a new function
> `_print_unix_command_map_internal' by modifying
> `_rl_macro_dumper_internal' (lib/readline/bind.c).  However, the
> implementation of `_print_unix_command_map_internal' uses private
> readline functions `_rl_get_keyname' and
> `_rl_untranslate_macro_value', so the implementation should be
> modified somehow or maybe these private functions can be made
> public.

Note that in the attached patch the functions in Readline library,
`_rl_get_keyname' and `_rl_untranslate_macro_value', were made public
and used from Bash codes.  I think it is worth to make them a part of
public interface of Readline library.

Even if Chet does not use my patch and instead write a new code with
another approach for this, I am anyway happy as far as the problem is
fixed.

Best regards,
Koichi
From 9eddd581f385712238bdbd146eeca261960592a2 Mon Sep 17 00:00:00 2001
From: Koichi Murase 
Date: Mon, 11 Feb 2019 19:23:09 +0900
Subject: [PATCH] do not print unbound bindings in "bind -X"

---
 bashline.c  | 73 +
 lib/readline/bind.c |  2 +-
 2 files changed, 68 insertions(+), 7 deletions(-)

diff --git a/bashline.c b/bashline.c
index e992c64b..040946e2 100644
--- a/bashline.c
+++ b/bashline.c
@@ -4368,16 +4368,77 @@ bash_execute_unix_command (count, key)
   return 0;
 }
 
+static void
+_print_unix_command_map_internal (Keymap map, Keymap xmap, char *prefix)
+{
+  register int key;
+  char *keyname, *out;
+  int prefix_len;
+
+  /* XXX - They are private readline functions... */
+  extern char *_rl_get_keyname (int key);
+  extern char *_rl_untranslate_macro_value (char *seq, int use_escapes);
+
+  for (key = 0; key < KEYMAP_SIZE; key++)
+{
+  switch (map[key].type)
+	{
+	case ISMACR:
+	  break;
+	case ISFUNC:
+	  if (map[key].function != bash_execute_unix_command || xmap[key].type != ISMACR)
+	continue;
+
+	  keyname = _rl_get_keyname (key);
+	  out = _rl_untranslate_macro_value ((char *)xmap[key].function, 0);
+	  fprintf (rl_outstream, "\"%s%s\": \"%s\"\n", prefix ? prefix : "",
+		   keyname,
+		   out ? out : "");
+	  xfree (keyname);
+	  xfree (out);
+	  break;
+	case ISKMAP:
+	  if (xmap[key].type != ISKMAP)
+	continue;
+
+	  prefix_len = prefix ? strlen (prefix) : 0;
+	  if (key == ESC)
+	{
+	  keyname = (char *)xmalloc (3 + prefix_len);
+	  if (prefix)
+		strcpy (keyname, prefix);
+	  keyname[prefix_len] = '\\';
+	  keyname[prefix_len + 1] = 'e';
+	  keyname[prefix_len + 2] = '\0';
+	}
+	  else
+	{
+	  keyname = _rl_get_keyname (key);
+	  if (prefix)
+		{
+		  out = (char *)xmalloc (strlen (keyname) + prefix_len + 1);
+		  strcpy (out, prefix);
+		  strcpy (out + prefix_len, keyname);
+		  xfree (keyname);
+		  keyname = out;
+		}
+	}
+
+	  _print_unix_command_map_internal (FUNCTION_TO_KEYMAP (map, key), FUNCTION_TO_KEYMAP (xmap, key), keyname);
+	  xfree (keyname);
+	  break;
+	}
+}
+}
+
 int
 print_unix_command_map ()
 {
-  Keymap save, cmd_xmap;
+  Keymap kmap, cmd_xmap;
 
-  save = rl_get_keymap ();
-  cmd_xmap = get_cmd_xmap_from_keymap (save);
-  rl_set_keymap (cmd_xmap);
-  rl_macro_dumper (1);
-  rl_set_keymap (save);
+  kmap = rl_get_keymap ();
+  cmd_xmap = get_cmd_xmap_from_keymap (kmap);
+  _print_unix_command_map_internal (kmap, cmd_xmap, (char *)NULL);
   return 0;
 }
 
diff --git a/lib/readline/bind.c b/lib/readline/bind.c
index b6970df6..87b0a31a 100644
--- a/lib/readline/bind.c
+++ b/lib/readline/bind.c
@@ -2483,7 +2483,7 @@ rl_list_funmap_names (void)
   xfree (funmap_names);
 }
 
-static char *
+char *
 _rl_get_keyname (int key)
 {
   char *keyname;
-- 
2.21.0



parser perversities (was Re: make install failed; dump core in mkdir)

2019-12-12 Thread L A Walsh

On 2019/12/02 07:04, pepa65 wrote:

it would be nice to be able to omit 'do'.
  

like:


 set -- 1 2 3
 for i
 { echo $i
 }

1
2
3

or:


 for i;{ echo $i;}

1
2
3




Two states of empty arryays

2019-12-12 Thread Léa Gris
Hello,

Depending on how an empty array is declared, it is not stored with the
same state.

# Empty array declared without parenthesis
unset myArr
declare -a myArr
typeset -p myArr
echo "${#myArr[@]}"

output:
declare -a myArr
0

# Empty array declared without parenthesis
unset myArr
declare -a myArr=()
typeset -p myArr
echo "${#myArr[@]}"

output:
declare -a myArr=()
0

What is the reason for having different states for empty arrays?

-- 
Lea Gris



Two states of empty arrays

2019-12-12 Thread Léa Gris
Hello,

Depending on how an empty array is declared, it is not stored with the
same state.

# Empty array declared without parenthesis
unset myArr
declare -a myArr
typeset -p myArr
echo "${#myArr[@]}"

output:
declare -a myArr
0

# Empty array declared without parenthesis
unset myArr
declare -a myArr=()
typeset -p myArr
echo "${#myArr[@]}"

output:
declare -a myArr=()
0

What is the reason for having different states for empty arrays?

-- 
Lea Gris

-- 
Léa Gris



signature.asc
Description: OpenPGP digital signature


Re: Two states of empty arrays

2019-12-12 Thread Clint Hepner
On Thu, Dec 12, 2019 at 1:10 PM Léa Gris  wrote:

> Hello,
>
> Depending on how an empty array is declared, it is not stored with the
> same state.
>
> # Empty array declared without parenthesis
> unset myArr
> declare -a myArr
> typeset -p myArr
> echo "${#myArr[@]}"
>
> output:
> declare -a myArr
> 0
>

Here, you haven't yet defined a parameter named myArr; you have only set
the array
attribute on the name myArr. You can see something similar with other
attributes:

$ declare -i x
$ [[ -v x ]] || echo "x not defined"
x not defined
$ declare -p x
declare -i x


>
> # Empty array declared without parenthesis
> unset myArr
> declare -a myArr=()
> typeset -p myArr
> echo "${#myArr[@]}"
>
> output:
> declare -a myArr=()
> 0
>
>
With the assignment, you have an actual parameter named myArr. Continuing
the integer attribute
example from above,

$ x=3
$ declare -p x
declare -i x="3"
$ [[ -v x ]] || echo "x not defined"   # No output


--
Clint


Re: Two states of empty arrays

2019-12-12 Thread Chet Ramey

On 12/12/19 12:08 PM, Léa Gris wrote:

Hello,

Depending on how an empty array is declared, it is not stored with the
same state.

# Empty array declared without parenthesis
unset myArr
declare -a myArr
typeset -p myArr
echo "${#myArr[@]}"


This is an unset variable with the array attribute; you have not assigned a
value.



# Empty array declared without parenthesis
unset myArr
declare -a myArr=()


This is an empty array variable; you have assigned a value.


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



Not missing, but very hard to see (was Re: Backslash missing in brace expansion)

2019-12-12 Thread L A Walsh

On 2019/12/06 14:14, Chet Ramey wrote:

Seems very hard to print out that backquote though.  Closest I got
was bash converting it to "''":


 read -r -a a< <(printf "%q " {Z..a})
 my -p a
declare -a a=([0]="Z" [1]="\\[" [2]="''" [3]="\\]" [4]="\\^" [5]="_" 
[6]="\\\`" [7]="a")


#2 is where backslash would be and has been transliterated to the pair
of single quotes.  Guess "" was too messy looking?





Re: Not missing, but very hard to see (was Re: Backslash missing in brace expansion)

2019-12-12 Thread Greg Wooledge
On Thu, Dec 12, 2019 at 11:43:58AM -0800, L A Walsh wrote:
> >  read -r -a a< <(printf "%q " {Z..a})
> >  my -p a
> declare -a a=([0]="Z" [1]="\\[" [2]="''" [3]="\\]" [4]="\\^" [5]="_"
> [6]="\\\`" [7]="a")

Nice try.  I guess the takeaway from this thread is: "You cannot mix
capital and lowercase letters in brace expansion.  If you try, you
get garbage out."



Re: Binding Containing Escape Key Fails to Escape History Search

2019-12-12 Thread Chet Ramey

On 12/8/19 7:15 PM, sunnycemet...@gmail.com wrote:

On 2019-11-04 14:41, Chet Ramey wrote:
If \ef and Alt+f generate distinct character sequences, you can bind them 
separately. If they don't, you can't. This has nothing to do with whether 
or not incremental searching expands keyboard macros.


In that case, how would one go about binding æ such that it both exits an 
incremental search and executes forward-word?


There isn't, really. Any character that doesn't end the search or map to
one of a few editing functions that the isearch code uses to modify the
search string is added to the search string.

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



Re: Not missing, but very hard to see (was Re: Backslash missing in brace expansion)

2019-12-12 Thread Ilkka Virta

On 12.12. 21:43, L A Walsh wrote:

On 2019/12/06 14:14, Chet Ramey wrote:

Seems very hard to print out that backquote though.  Closest I got
was bash converting it to "''":


The backquote is in [6], and the backslash disappears, you just get the 
pair of quotes in [2] because that's how printf %q outputs an empty string.



 read -r -a a< <(printf "%q " {Z..a})
 my -p a
declare -a a=([0]="Z" [1]="\\[" [2]="''" [3]="\\]" [4]="\\^" [5]="_" 
[6]="\\\`" [7]="a")



--
Ilkka Virta / itvi...@iki.fi



Re: Two states of empty arrays

2019-12-12 Thread Léa Gris
Le 12/12/2019 à 20:13, Chet Ramey écrivait :

>> # Empty array declared without parenthesis
>> unset myArr
>> declare -a myArr
>> typeset -p myArr
>> echo "${#myArr[@]}"
> 
> This is an unset variable with the array attribute; you have not assigned a
> value.
>> # Empty array declared without parenthesis
>> unset myArr
>> declare -a myArr=()
> 
> This is an empty array variable; you have assigned a value.

Thank you and Clint, it makes sense now.

I was trying to play the the -v test to detect when an array or
associative array has been declared, not necessarily assigned entries
key, values, to not error when Bash runs with -o nounset

Like here:
#!/usr/bin/bash
set -o nounset
myArr+=(["key"]="value")

ERR: line 3: key: unbound variable

I can test the type of myArr this way:
if [[ "$(typeset -p myArr 2>&1)" =~ ^declare\ -A ]]; then
  myArr+=(["key"]="value")
fi

But it looks sub-optimal to test the type and declaration of a variable.
The -v test flag cannot be used because it requires the associative
array to contain at least a [key]=value entry as mentioned in the man
bash.1:

>-v varname
>   True if the shell variable varname is set (has been assigned a 
> value).

_has been assigned a value_

-- 
Lea Gris




Re: Two states of empty arrays

2019-12-12 Thread Martin Schulte
Hello Léa!

Léa Gris  wrote:
> I was trying to play the the -v test to detect when an array or
> associative array has been declared, not necessarily assigned entries
> key, values, to not error when Bash runs with -o nounset

Just for the curious: What is your attention here?

I think that most useful questions (Is there an element in the array? Is
there a value for a given key?) can be answered in a simpler way:

#!/bin/bash

set -o nounset

# From what I learned today it seems to be good practice to always
# assign and empty array to when declaring an associative array:
declare -A assoc=()

echo ${#assoc[@]} # Are there elements in it?

assoc[key1]=val1
assoc[key2]=

for key in key1 key2 key3; do
  if [[ -n ${assoc[$key]+isset} ]]; then
echo "Element for $key is set"
  else
echo "No Element for $key"
  fi
done

Best regards,

Martin



Re: Not missing, but very hard to see (was Re: Backslash missing in brace expansion)

2019-12-12 Thread L A Walsh




On 2019/12/12 13:01, Ilkka Virta wrote:

On 12.12. 21:43, L A Walsh wrote:
  

On 2019/12/06 14:14, Chet Ramey wrote:

Seems very hard to print out that backquote though.  Closest I got
was bash converting it to "''":



The backquote is in [6], and the backslash disappears, you just get the 
pair of quotes in [2] because that's how printf %q outputs an empty string.
  

-

   I'm sorry, but you are mistaken.

   The characters from 'Z' (0x5A) through 'z' (0x61) are:

0x5A 0x5B 0x5C 0x5D 0x5E 0x5F 0x60 0x61
Z[\] ^   _ `a

the backslash comes between the two square brackets.

Position [6] is the "Grave Accent" (or backquote).

It is quoted properly.

As for %q printing an empty string for 0x5C

"%q" causes  printf to output the corresponding argument in a
format that can be reused as shell input.

   For that string to be empty would mean there is no character at hex
value 0x5C (unicode U+005C), which isn't so.

  

 read -r -a a< <(printf "%q " {Z..a})
 my -p a
  
declare -a a=([0]="Z" [1]="\\[" [2]="''" [3]="\\]" [4]="\\^" [5]="_" 
[6]="\\\`" [7]="a")




  





Re: Not missing, but very hard to see (was Re: Backslash missing in brace expansion)

2019-12-12 Thread Eli Schwartz
On 12/12/19 9:57 PM, L A Walsh wrote:
> 
> 
> On 2019/12/12 13:01, Ilkka Virta wrote:
>> On 12.12. 21:43, L A Walsh wrote:
>>  
>>> On 2019/12/06 14:14, Chet Ramey wrote:
>>>
>>> Seems very hard to print out that backquote though.  Closest I got
>>> was bash converting it to "''":
>>>     
>>
>> The backquote is in [6], and the backslash disappears, you just get
>> the pair of quotes in [2] because that's how printf %q outputs an
>> empty string.
>>   
> -
> 
>    I'm sorry, but you are mistaken.

How so?

>    The characters from 'Z' (0x5A) through 'z' (0x61) are:
> 
> 0x5A 0x5B 0x5C 0x5D 0x5E 0x5F 0x60 0x61
> Z    [    \    ] ^   _ `    a
> 
> the backslash comes between the two square brackets.
> 
> Position [6] is the "Grave Accent" (or backquote).
> 
> It is quoted properly.

But... that's exactly what was said.

> As for %q printing an empty string for 0x5C
> 
>     "%q" causes  printf to output the corresponding argument in a
>     format that can be reused as shell input.
> 
>    For that string to be empty would mean there is no character at hex
> value 0x5C (unicode U+005C), which isn't so.

But there isn't. An empty string was passed as an argument to printf,
because the backslash was *converted* via escaping, into an empty
string, *before* it was passed on the command line as an argv element to
the printf builtin.

Do you think that because printf is a builtin, and you didn't use
/bin/printf, that somehow means it is exempt from the usual rule of how
shells work, and gets to see its own argv before the parser reinterprets it?

>>  
  read -r -a a< <(printf "%q " {Z..a})
  my -p a
   
>>> declare -a a=([0]="Z" [1]="\\[" [2]="''" [3]="\\]" [4]="\\^" [5]="_"
>>> [6]="\\\`" [7]="a")
>>>     
>>
>>
>>   


-- 
Eli Schwartz
Bug Wrangler and Trusted User



signature.asc
Description: OpenPGP digital signature