@@ -422,6 +422,21 @@ _comp_compgen__error_fallback()
422
422
# The array name should not start with an underscores "_", which is
423
423
# internally used. The array name should not be either "IFS" or
424
424
# "OPT{IND,ARG,ERR}".
425
+ # -U var Unlocal VAR before performing the assignments. This option can be
426
+ # specified multiple times to register multiple variables. This
427
+ # option is supposed to be used by a parent generator (G1) when G1
428
+ # defines a local variable name that does not start with `_`. In
429
+ # such a case, when a conflicting `-v VAR` is specified to the
430
+ # generator call, the assignments to VAR fail to propagate outside
431
+ # G1. To avoid such a situation, `-U VAR` provides a mechanism to
432
+ # unlocal VAR before accessing variables specified to G1 by `-v`. If
433
+ # this is a builtin compgen call (i.e., _comp_compgen [options] --
434
+ # options), the specified variables are unlocalized after calling the
435
+ # builtin `compgen` and before assigning results to the array
436
+ # specified by `-v`. If this is a child generator call (i.e.,
437
+ # _comp_compgen [options] G2 ...), the specified variables are
438
+ # unlocalized before calling the generator function
439
+ # `_comp_compgen_G2`.
425
440
# -c cur Set a word used as a prefix to filter the completions. The default
426
441
# is ${cur-}.
427
442
# -R The same as -c ''. Use raw outputs without filtering.
@@ -512,14 +527,15 @@ _comp_compgen()
512
527
local _dir=" "
513
528
local _ifs=$' \t\n ' _has_ifs=" "
514
529
local _icmd=" " _xcmd=" "
530
+ local -a _upvars=()
515
531
516
532
local _old_nocasematch=" "
517
533
if shopt -q nocasematch; then
518
534
_old_nocasematch=set
519
535
shopt -u nocasematch
520
536
fi
521
537
local OPTIND=1 OPTARG=" " OPTERR=0 _opt
522
- while getopts ' :av:Rc:C:lF:i:x:' _opt " $@ " ; do
538
+ while getopts ' :av:U: Rc:C:lF:i:x:' _opt " $@ " ; do
523
539
case $_opt in
524
540
a) _append=set ;;
525
541
v)
@@ -529,6 +545,16 @@ _comp_compgen()
529
545
fi
530
546
_var=$OPTARG
531
547
;;
548
+ U)
549
+ if [[ $OPTARG == @ (* [^_a-zA-Z0-9]* | [0-9]* | ' ' ) ]]; then
550
+ printf ' bash_completion: %s: -U: invalid variable name `%s' \' ' \n' " $FUNCNAME " " $OPTARG " >&2
551
+ return 2
552
+ elif [[ $OPTARG == @ (_* | IFS| OPTIND| OPTARG| OPTERR) ]]; then
553
+ printf ' bash_completion: %s: -U: unnecessary to mark `%s' \' ' as upvar\n' " $FUNCNAME " " $OPTARG " >&2
554
+ return 2
555
+ fi
556
+ _upvars+=(" $OPTARG " )
557
+ ;;
532
558
c) _cur=$OPTARG ;;
533
559
R) _cur=" " ;;
534
560
C)
@@ -588,6 +614,8 @@ _comp_compgen()
588
614
return 2
589
615
fi
590
616
617
+ (( ${# _upvars[@]} )) && _comp_unlocal " ${_upvars[@]} "
618
+
591
619
if [[ $_dir ]]; then
592
620
local _original_pwd=$PWD
593
621
local PWD=${PWD-} OLDPWD=${OLDPWD-}
@@ -653,6 +681,7 @@ _comp_compgen()
653
681
return
654
682
}
655
683
684
+ (( ${# _upvars[@]} )) && _comp_unlocal " ${_upvars[@]} "
656
685
_comp_split -l ${_append: +-a} " $_var " " $_result "
657
686
}
658
687
@@ -1078,9 +1107,7 @@ _comp_compgen_filedir()
1078
1107
# Note: bash < 4.4 has a bug that all the elements are connected with
1079
1108
# ${v+"${a[@]}"} when IFS does not contain whitespace.
1080
1109
local IFS=$' \t\n '
1081
- local -a _tmp=(${toks[@]+" ${toks[@]} " } )
1082
- _comp_unlocal toks
1083
- _comp_compgen_set ${_tmp[@]+" ${_tmp[@]} " }
1110
+ _comp_compgen -U toks set ${toks[@]+" ${toks[@]} " }
1084
1111
} # _comp_compgen_filedir()
1085
1112
1086
1113
# This function splits $cur=--foo=bar into $prev=--foo, $cur=bar, making it
@@ -1535,11 +1562,8 @@ _comp_compgen_usage()
1535
1562
_comp_compgen_signals ()
1536
1563
{
1537
1564
local -a sigs
1538
- if _comp_compgen -v sigs -c " SIG${cur# " ${1-} " } " -- -P " ${1-} " -A signal; then
1539
- local -a _sigs=(" ${sigs[@]/# ${1-} SIG/ ${1-} } " )
1540
- _comp_unlocal sigs
1541
- _comp_compgen_set " ${_sigs[@]} "
1542
- fi
1565
+ _comp_compgen -v sigs -c " SIG${cur# " ${1-} " } " -- -P " ${1-} " -A signal &&
1566
+ _comp_compgen -U sigs set " ${sigs[@]/# ${1-} SIG/ ${1-} } "
1543
1567
}
1544
1568
1545
1569
# This function completes on known mac addresses
@@ -1578,9 +1602,7 @@ _comp_compgen_mac_addresses()
1578
1602
_comp_compgen -av addresses split -- " $( command sed -ne \
1579
1603
" s/^[[:space:]]*\($_re \)[[:space:]].*/\1/p" /etc/ethers 2> /dev/null) "
1580
1604
1581
- local -a _addresses=(" ${addresses[@]} " )
1582
- _comp_unlocal addresses
1583
- _comp_compgen_ltrim_colon " ${_addresses[@]} "
1605
+ _comp_compgen -U ltrim_colon " ${addresses[@]} "
1584
1606
}
1585
1607
1586
1608
# This function completes on configured network interfaces
@@ -1589,32 +1611,29 @@ _comp_compgen_mac_addresses()
1589
1611
_comp_compgen_configured_interfaces ()
1590
1612
{
1591
1613
local -a files
1592
- local _list
1593
1614
if [[ -f /etc/debian_version ]]; then
1594
1615
# Debian system
1595
1616
_comp_expand_glob files ' /etc/network/interfaces /etc/network/interfaces.d/*'
1596
1617
(( ${# files[@]} )) || return 0
1597
- _list= $( command sed -ne \
1598
- ' s|^iface \([^ ]\{1,\}\).*$|\1|p' " ${files[@]} " 2> /dev/null)
1618
+ _comp_compgen -U files split -- " $( command sed -ne \
1619
+ ' s|^iface \([^ ]\{1,\}\).*$|\1|p' " ${files[@]} " 2> /dev/null) "
1599
1620
elif [[ -f /etc/SuSE-release ]]; then
1600
1621
# SuSE system
1601
1622
_comp_expand_glob files ' /etc/sysconfig/network/ifcfg-*'
1602
1623
(( ${# files[@]} )) || return 0
1603
- _list= $( printf ' %s\n' " ${files[@]} " |
1604
- command sed -ne ' s|.*ifcfg-\([^*].*\)$|\1|p' )
1624
+ _comp_compgen -U files split -- " $( printf ' %s\n' " ${files[@]} " |
1625
+ command sed -ne ' s|.*ifcfg-\([^*].*\)$|\1|p' ) "
1605
1626
elif [[ -f /etc/pld-release ]]; then
1606
1627
# PLD Linux
1607
- _list= $( command ls -B /etc/sysconfig/interfaces |
1608
- command sed -ne ' s|.*ifcfg-\([^*].*\)$|\1|p' )
1628
+ _comp_compgen -U files split -- " $( command ls -B /etc/sysconfig/interfaces |
1629
+ command sed -ne ' s|.*ifcfg-\([^*].*\)$|\1|p' ) "
1609
1630
else
1610
1631
# Assume Red Hat
1611
1632
_comp_expand_glob files ' /etc/sysconfig/network-scripts/ifcfg-*'
1612
1633
(( ${# files[@]} )) || return 0
1613
- _list= $( printf ' %s\n' " ${files[@]} " |
1614
- command sed -ne ' s|.*ifcfg-\([^*].*\)$|\1|p' )
1634
+ _comp_compgen -U files split -- " $( printf ' %s\n' " ${files[@]} " |
1635
+ command sed -ne ' s|.*ifcfg-\([^*].*\)$|\1|p' ) "
1615
1636
fi
1616
- _comp_unlocal files
1617
- _comp_compgen_split -- " $_list "
1618
1637
}
1619
1638
1620
1639
# Local IP addresses.
@@ -1642,12 +1661,10 @@ _comp_compgen_ip_addresses()
1642
1661
" s|.*inet${_n} [[:space:]]\{1,\}\([^[:space:]/]*\).*|\1|p" ) " ||
1643
1662
return
1644
1663
1645
- local -a _addrs=(" ${addrs[@]} " )
1646
- _comp_unlocal addrs
1647
1664
if [[ ! $_n ]]; then
1648
- _comp_compgen_set " ${_addrs [@]} "
1665
+ _comp_compgen -U addrs set " ${addrs [@]} "
1649
1666
else
1650
- _comp_compgen_ltrim_colon " ${_addrs [@]} "
1667
+ _comp_compgen -U addrs ltrim_colon " ${addrs [@]} "
1651
1668
fi
1652
1669
}
1653
1670
@@ -1677,11 +1694,8 @@ _comp_compgen_available_interfaces()
1677
1694
ifconfig -a || ip -c=never link show || ip link show
1678
1695
fi
1679
1696
} 2> /dev/null | awk \
1680
- ' /^[^ \t]/ { if ($1 ~ /^[0-9]+:/) { print $2 } else { print $1 } }' ) " ||
1681
- return
1682
- local -a _generated=(" ${generated[@]/% [[:punct:]]/ } " )
1683
- _comp_unlocal generated
1684
- _comp_compgen_set " ${_generated[@]} "
1697
+ ' /^[^ \t]/ { if ($1 ~ /^[0-9]+:/) { print $2 } else { print $1 } }' ) " &&
1698
+ _comp_compgen -U set " ${generated[@]} "
1685
1699
}
1686
1700
1687
1701
# Echo number of CPUs, falling back to 1 on failure.
@@ -1845,11 +1859,8 @@ else
1845
1859
done
1846
1860
fi
1847
1861
fi
1848
- if (( ${# procs[@]} )) ; then
1849
- local -a _procs=(" ${procs[@]} " )
1850
- _comp_unlocal procs
1851
- _comp_compgen -- -X " <defunct>" -W ' "${_procs[@]}"'
1852
- fi
1862
+ (( ${# procs[@]} )) &&
1863
+ _comp_compgen -U procs -- -X " <defunct>" -W ' "${procs[@]}"'
1853
1864
}
1854
1865
fi
1855
1866
@@ -1897,9 +1908,7 @@ _comp_compgen_xinetd_services()
1897
1908
local -a svcs
1898
1909
_comp_expand_glob svcs ' $_xinetddir/!($_comp_backup_glob)'
1899
1910
if (( ${# svcs[@]} )) ; then
1900
- local _svcs=(" ${svcs[@]} " )
1901
- _comp_unlocal svcs
1902
- _comp_compgen -- -W ' "${_svcs[@]#$_xinetddir/}"'
1911
+ _comp_compgen -U svcs -- -W ' "${svcs[@]#$_xinetddir/}"'
1903
1912
fi
1904
1913
fi
1905
1914
}
0 commit comments