mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-28 16:09:51 +02:00
new "@k" parameter transformation; minor completion fix for uncommon case
This commit is contained in:
@@ -1746,4 +1746,33 @@ bashline.c
|
||||
- orig_rl_completer_word_break_characters: now const char * like
|
||||
rl_completer_word_break_characters
|
||||
|
||||
8/20
|
||||
----
|
||||
bashline.c
|
||||
- bash_directory_completion_hook: if direxpand and dirspell are both
|
||||
set while trying to complete an absolute pathname as a command, don't
|
||||
take a spell-corrected directory name that is shorter than the
|
||||
original hint. https://bugzilla.redhat.com/show_bug.cgi?id=1782809
|
||||
|
||||
builtins/common.[ch]
|
||||
- sh_noassign: convenience function to print an error message when a
|
||||
user attempts an assignment to a "noassign" variable. Not used yet
|
||||
|
||||
assoc.[ch]
|
||||
- assoc_to_kvpair_list: new function, returns a WORD_LIST containing
|
||||
key-value pairs as separate words
|
||||
|
||||
array.[ch]
|
||||
- array_to_kvpair_list: new function, returns a WORD_LIST containing
|
||||
index-value pairs as separate words
|
||||
|
||||
subst.c
|
||||
- string_transform: handle '@k' transform like '@K'
|
||||
- valid_parameter_transform: 'k' is a valid transform operator
|
||||
- array_transform: handle '@k' transformation by calling one of
|
||||
array_to_kvpair_list or assoc_to_kvpair_list and treating the
|
||||
result as if expanding the array depending on whether the index is
|
||||
`@' or `*' with the usual meanings
|
||||
|
||||
doc/{bash.1,bashref.texi}
|
||||
- document new '@k' parameter transformation operator
|
||||
|
||||
@@ -949,6 +949,7 @@ tests/assoc10.sub f
|
||||
tests/assoc11.sub f
|
||||
tests/assoc12.sub f
|
||||
tests/assoc13.sub f
|
||||
tests/assoc14.sub f
|
||||
tests/attr.tests f
|
||||
tests/attr.right f
|
||||
tests/attr1.sub f
|
||||
|
||||
@@ -793,6 +793,27 @@ ARRAY *a;
|
||||
return (REVERSE_LIST(list, WORD_LIST *));
|
||||
}
|
||||
|
||||
WORD_LIST *
|
||||
array_to_kvpair_list(a)
|
||||
ARRAY *a;
|
||||
{
|
||||
WORD_LIST *list;
|
||||
ARRAY_ELEMENT *ae;
|
||||
char *k, *v;
|
||||
|
||||
if (a == 0 || array_empty(a))
|
||||
return((WORD_LIST *)NULL);
|
||||
list = (WORD_LIST *)NULL;
|
||||
for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae)) {
|
||||
k = itos(element_index(ae));
|
||||
v = element_value(ae);
|
||||
list = make_word_list (make_bare_word(k), list);
|
||||
list = make_word_list (make_bare_word(v), list);
|
||||
free(k);
|
||||
}
|
||||
return (REVERSE_LIST(list, WORD_LIST *));
|
||||
}
|
||||
|
||||
ARRAY *
|
||||
array_assign_list (array, list)
|
||||
ARRAY *array;
|
||||
|
||||
@@ -80,6 +80,7 @@ extern char *array_reference PARAMS((ARRAY *, arrayind_t));
|
||||
extern WORD_LIST *array_to_word_list PARAMS((ARRAY *));
|
||||
extern ARRAY *array_from_word_list PARAMS((WORD_LIST *));
|
||||
extern WORD_LIST *array_keys_to_word_list PARAMS((ARRAY *));
|
||||
extern WORD_LIST *array_to_kvpair_list PARAMS((ARRAY *));
|
||||
|
||||
extern ARRAY *array_assign_list PARAMS((ARRAY *, WORD_LIST *));
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* chet@ins.cwru.edu
|
||||
*/
|
||||
|
||||
/* Copyright (C) 2008,2009,2011-2020 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2008,2009,2011-2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -544,6 +544,30 @@ assoc_keys_to_word_list (h)
|
||||
return (assoc_to_word_list_internal (h, 1));
|
||||
}
|
||||
|
||||
WORD_LIST *
|
||||
assoc_to_kvpair_list (h)
|
||||
HASH_TABLE *h;
|
||||
{
|
||||
WORD_LIST *list;
|
||||
int i;
|
||||
BUCKET_CONTENTS *tlist;
|
||||
char *k, *v;
|
||||
|
||||
if (h == 0 || assoc_empty (h))
|
||||
return((WORD_LIST *)NULL);
|
||||
list = (WORD_LIST *)NULL;
|
||||
|
||||
for (i = 0; i < h->nbuckets; i++)
|
||||
for (tlist = hash_items (i, h); tlist; tlist = tlist->next)
|
||||
{
|
||||
k = (char *)tlist->key;
|
||||
v = (char *)tlist->data;
|
||||
list = make_word_list (make_bare_word (k), list);
|
||||
list = make_word_list (make_bare_word (v), list);
|
||||
}
|
||||
return (REVERSE_LIST(list, WORD_LIST *));
|
||||
}
|
||||
|
||||
char *
|
||||
assoc_to_string (h, sep, quoted)
|
||||
HASH_TABLE *h;
|
||||
|
||||
@@ -60,6 +60,7 @@ extern char *assoc_to_assign PARAMS((HASH_TABLE *, int));
|
||||
|
||||
extern WORD_LIST *assoc_to_word_list PARAMS((HASH_TABLE *));
|
||||
extern WORD_LIST *assoc_keys_to_word_list PARAMS((HASH_TABLE *));
|
||||
extern WORD_LIST *assoc_to_kvpair_list PARAMS((HASH_TABLE *));
|
||||
|
||||
extern char *assoc_to_string PARAMS((HASH_TABLE *, char *, int));
|
||||
#endif /* _ASSOC_H_ */
|
||||
|
||||
@@ -3580,7 +3580,16 @@ bash_directory_completion_hook (dirname)
|
||||
subsequent directory checks don't fail. */
|
||||
if (temp2 == 0 && dircomplete_spelling && dircomplete_expand)
|
||||
{
|
||||
size_t l1, l2;
|
||||
|
||||
temp2 = dirspell (temp1);
|
||||
l2 = STRLEN (temp2);
|
||||
/* Don't take matches if they are shorter than the original path */
|
||||
if (temp2 && l2 < strlen (temp1) && STREQN (temp1, temp2, l2))
|
||||
{
|
||||
free (temp2);
|
||||
temp2 = 0;
|
||||
}
|
||||
if (temp2)
|
||||
{
|
||||
free (temp1);
|
||||
|
||||
@@ -266,6 +266,13 @@ sh_readonly (s)
|
||||
builtin_error (_("%s: readonly variable"), s);
|
||||
}
|
||||
|
||||
void
|
||||
sh_noassign (s)
|
||||
const char *s;
|
||||
{
|
||||
internal_error (_("%s: cannot assign"), s); /* XXX */
|
||||
}
|
||||
|
||||
void
|
||||
sh_erange (s, desc)
|
||||
char *s, *desc;
|
||||
|
||||
+2
-1
@@ -95,10 +95,11 @@ extern void sh_invalidoptname PARAMS((char *));
|
||||
extern void sh_invalidid PARAMS((char *));
|
||||
extern void sh_invalidnum PARAMS((char *));
|
||||
extern void sh_invalidsig PARAMS((char *));
|
||||
extern void sh_readonly PARAMS((const char *));
|
||||
extern void sh_noassign PARAMS((const char *));
|
||||
extern void sh_erange PARAMS((char *, char *));
|
||||
extern void sh_badpid PARAMS((char *));
|
||||
extern void sh_badjob PARAMS((char *));
|
||||
extern void sh_readonly PARAMS((const char *));
|
||||
extern void sh_nojobs PARAMS((char *));
|
||||
extern void sh_restricted PARAMS((char *));
|
||||
extern void sh_notbuiltin PARAMS((char *));
|
||||
|
||||
+6
-2
@@ -5,12 +5,12 @@
|
||||
.\" Case Western Reserve University
|
||||
.\" chet.ramey@case.edu
|
||||
.\"
|
||||
.\" Last Change: Tue Aug 10 11:06:20 EDT 2021
|
||||
.\" Last Change: Mon Aug 23 10:08:28 EDT 2021
|
||||
.\"
|
||||
.\" bash_builtins, strip all but Built-Ins section
|
||||
.if \n(zZ=1 .ig zZ
|
||||
.if \n(zY=1 .ig zY
|
||||
.TH BASH 1 "2021 August 10" "GNU Bash 5.1"
|
||||
.TH BASH 1 "2021 August 23" "GNU Bash 5.1"
|
||||
.\"
|
||||
.\" There's some problem with having a `@'
|
||||
.\" in a tagged paragraph with the BSD man macros.
|
||||
@@ -3461,6 +3461,10 @@ indexed and associative arrays as a sequence of quoted key-value pairs
|
||||
.B a
|
||||
The expansion is a string consisting of flag values representing
|
||||
\fIparameter\fP's attributes.
|
||||
.TP
|
||||
.B k
|
||||
Like the K transformation, but expands the keys and values of
|
||||
indexed and associative arrays to separate words after word splitting.
|
||||
.PD
|
||||
.PP
|
||||
If
|
||||
|
||||
@@ -2478,6 +2478,9 @@ indexed and associative arrays as a sequence of quoted key-value pairs
|
||||
@item a
|
||||
The expansion is a string consisting of flag values representing
|
||||
@var{parameter}'s attributes.
|
||||
@item k
|
||||
Like the @samp{K} transformation, but expands the keys and values of
|
||||
indexed and associative arrays to separate words after word splitting.
|
||||
@end table
|
||||
|
||||
If @var{parameter} is @samp{@@} or @samp{*},
|
||||
|
||||
+2
-2
@@ -2,10 +2,10 @@
|
||||
Copyright (C) 1988-2021 Free Software Foundation, Inc.
|
||||
@end ignore
|
||||
|
||||
@set LASTCHANGE Tue Aug 10 11:06:03 EDT 2021
|
||||
@set LASTCHANGE Mon Aug 23 10:07:59 EDT 2021
|
||||
|
||||
@set EDITION 5.1
|
||||
@set VERSION 5.1
|
||||
|
||||
@set UPDATED 10 August 2021
|
||||
@set UPDATED 23 August 2021
|
||||
@set UPDATED-MONTH August 2021
|
||||
|
||||
@@ -7915,6 +7915,7 @@ string_transform (xc, v, s)
|
||||
ret = string_var_assignment (v, s);
|
||||
break;
|
||||
case 'K':
|
||||
case 'k':
|
||||
ret = sh_quote_reusable (s, 0);
|
||||
break;
|
||||
/* Transformations that modify the variable's value */
|
||||
@@ -8008,7 +8009,7 @@ array_transform (xc, var, starsub, quoted)
|
||||
{
|
||||
ARRAY *a;
|
||||
HASH_TABLE *h;
|
||||
int itype;
|
||||
int itype, qflags;
|
||||
char *ret;
|
||||
WORD_LIST *list;
|
||||
SHELL_VAR *v;
|
||||
@@ -8035,6 +8036,23 @@ array_transform (xc, var, starsub, quoted)
|
||||
a = (v && array_p (v)) ? array_cell (v) : 0;
|
||||
h = (v && assoc_p (v)) ? assoc_cell (v) : 0;
|
||||
|
||||
/* XXX - for now */
|
||||
if (xc == 'k')
|
||||
{
|
||||
if (v == 0)
|
||||
return ((char *)NULL);
|
||||
list = array_p (v) ? array_to_kvpair_list (a) : assoc_to_kvpair_list (h);
|
||||
qflags = quoted;
|
||||
/* If we are expanding in a context where word splitting will not be
|
||||
performed, treat as quoted. This changes how $* will be expanded. */
|
||||
if (itype == '*' && expand_no_split_dollar_star && ifs_is_null)
|
||||
qflags |= Q_DOUBLE_QUOTES; /* Posix interp 888 */
|
||||
|
||||
ret = string_list_pos_params (itype, list, qflags, 0);
|
||||
dispose_words (list);
|
||||
return ret;
|
||||
}
|
||||
|
||||
list = a ? array_to_word_list (a) : (h ? assoc_to_word_list (h) : 0);
|
||||
if (list == 0)
|
||||
return ((char *)NULL);
|
||||
@@ -8058,6 +8076,7 @@ valid_parameter_transform (xform)
|
||||
case 'a': /* expand to a string with just attributes */
|
||||
case 'A': /* expand as an assignment statement with attributes */
|
||||
case 'K': /* expand assoc array to list of key/value pairs */
|
||||
case 'k': /* XXX - for now */
|
||||
case 'E': /* expand like $'...' */
|
||||
case 'P': /* expand like prompt string */
|
||||
case 'Q': /* quote reusably */
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
BUILD_DIR=/usr/local/build/chet/bash/bash-current
|
||||
BUILD_DIR=/usr/local/build/bash/bash-current
|
||||
THIS_SH=$BUILD_DIR/bash
|
||||
PATH=$PATH:$BUILD_DIR
|
||||
|
||||
|
||||
@@ -288,3 +288,44 @@ declare -a ia
|
||||
declare -A a=(["@"]="at2" )
|
||||
declare -A a=(["@"]=" string" )
|
||||
declare -A a=(["*"]="star2" ["@"]="at" )
|
||||
declare -A assoc=([hello]="world" ["key with spaces"]="value with spaces" [foo]="bar" [one]="1" )
|
||||
argv[1] = <world>
|
||||
argv[2] = <value with spaces>
|
||||
argv[3] = <bar>
|
||||
argv[4] = <1>
|
||||
argv[1] = <hello>
|
||||
argv[2] = <world>
|
||||
argv[3] = <key with spaces>
|
||||
argv[4] = <value with spaces>
|
||||
argv[5] = <foo>
|
||||
argv[6] = <bar>
|
||||
argv[7] = <one>
|
||||
argv[8] = <1>
|
||||
argv[1] = <world value with spaces bar 1>
|
||||
argv[1] = <hello world key with spaces value with spaces foo bar one 1>
|
||||
argv[1] = <hello>
|
||||
argv[2] = <world>
|
||||
argv[3] = <key with spaces>
|
||||
argv[4] = <value with spaces>
|
||||
argv[5] = <one>
|
||||
argv[6] = <1>
|
||||
argv[7] = <foo>
|
||||
argv[8] = <bar>
|
||||
argv[1] = <'hello'>
|
||||
argv[2] = <'world'>
|
||||
argv[3] = <'key with spaces'>
|
||||
argv[4] = <'value with spaces'>
|
||||
argv[5] = <'one'>
|
||||
argv[6] = <'1'>
|
||||
argv[7] = <'foo'>
|
||||
argv[8] = <'bar'>
|
||||
argv[1] = <'hello'>
|
||||
argv[2] = <'world'>
|
||||
argv[3] = <'key with spaces'>
|
||||
argv[4] = <'value with spaces'>
|
||||
argv[5] = <'one'>
|
||||
argv[6] = <'1'>
|
||||
argv[7] = <'foo'>
|
||||
argv[8] = <'bar'>
|
||||
declare -A clone=([hello]="world" ["key with spaces"]="value with spaces" [foo]="bar" [one]="1" )
|
||||
declare -A posparams=([hello]="world" ["key with spaces"]="value with spaces" [foo]="bar" [one]="1" )
|
||||
|
||||
@@ -250,3 +250,6 @@ ${THIS_SH} ./assoc12.sub
|
||||
|
||||
# assignment to @ and *
|
||||
${THIS_SH} ./assoc13.sub
|
||||
|
||||
# tests of the @k transformation on associative arrays
|
||||
${THIS_SH} ./assoc14.sub
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
declare -A assoc=(hello world "key with spaces" "value with spaces" one 1 foo bar)
|
||||
declare -p assoc
|
||||
|
||||
recho "${assoc[@]}"
|
||||
recho "${assoc[@]@k}"
|
||||
|
||||
recho "${assoc[*]}"
|
||||
recho "${assoc[*]@k}"
|
||||
|
||||
set -- hello world "key with spaces" "value with spaces" one 1 foo bar
|
||||
recho "${@}"
|
||||
recho "${@@K}"
|
||||
recho "${@@k}"
|
||||
|
||||
declare -A clone
|
||||
eval clone=\( "${assoc[@]@K}" \)
|
||||
declare -p clone
|
||||
|
||||
declare -A posparams
|
||||
eval posparams=\( "${@@K}" \)
|
||||
declare -p posparams
|
||||
@@ -703,11 +703,21 @@ aaa bbb
|
||||
a bbb
|
||||
aaa bb
|
||||
'string'
|
||||
'string'
|
||||
'value with spaces'
|
||||
'value with spaces'
|
||||
'a b' 'c d' 'e f'
|
||||
'a b' 'c d' 'e f'
|
||||
0 "zero" 1 "one" 2 "two" 3 "three"
|
||||
0 "zero z" 1 "one o" 2 "two t" 3 "three t"
|
||||
argv[1] = <0>
|
||||
argv[2] = <zero z>
|
||||
argv[3] = <1>
|
||||
argv[4] = <one o>
|
||||
argv[5] = <2>
|
||||
argv[6] = <two t>
|
||||
argv[7] = <3>
|
||||
argv[8] = <three t>
|
||||
declare -a foo=()
|
||||
ai
|
||||
declare -ai foo
|
||||
|
||||
+18
-1
@@ -1,4 +1,18 @@
|
||||
# test the other uses of the 'K' tranform operator
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
# test the other uses of the 'K' tranform operator and its sibling 'k'
|
||||
# the associative array tests are performed separately, since that was the
|
||||
# original motivation for this feature
|
||||
foo=string
|
||||
@@ -7,7 +21,9 @@ bar='value with spaces'
|
||||
set -- 'a b' 'c d' 'e f'
|
||||
|
||||
echo ${foo@K}
|
||||
echo ${foo@k}
|
||||
echo ${bar@K}
|
||||
echo ${bar@k}
|
||||
|
||||
echo ${@@K}
|
||||
echo "${@@K}"
|
||||
@@ -17,3 +33,4 @@ echo ${foo[@]@K}
|
||||
|
||||
foo=( 'zero z' 'one o' 'two t' 'three t' )
|
||||
echo ${foo[@]@K}
|
||||
recho "${foo[@]@k}"
|
||||
|
||||
Reference in New Issue
Block a user