cli/bash-completion: simplify code by passing arrays by indirection to functions

Signed-off-by: Thomas Haller <thaller@redhat.com>
This commit is contained in:
Thomas Haller 2014-03-01 00:35:15 +01:00
parent 74809e64cc
commit 39dc39ec0a

View file

@ -29,9 +29,12 @@ _nmcli_dev_status()
} }
_nmcli_array_has_value() { _nmcli_array_has_value() {
# expects an array variable ARRAY defined and returns true # expects the name of an array as first parameter and
# if one of the arguments $@ is contained in ${ARRAY[@]} # returns true if if one of the remaining arguments is
# contained in the array ${$1[@]}
eval "local ARRAY=(\"\${$1[@]}\")"
local arg a local arg a
shift
for arg; do for arg; do
for a in "${ARRAY[@]}"; do for a in "${ARRAY[@]}"; do
if [[ "$a" = "$arg" ]]; then if [[ "$a" = "$arg" ]]; then
@ -42,6 +45,31 @@ _nmcli_array_has_value() {
return 1 return 1
} }
_nmcli_array_delete_at()
{
eval "local ARRAY=(\"\${$1[@]}\")"
local i
local tmp=()
local lower=$2
local upper=${3:-$lower}
# for some reason the following fails. So this clumsy workaround...
# A=(a "")
# echo " >> ${#A[@]}"
# >> 2
# A=("${A[@]:1}")
# echo " >> ${#A[@]}"
# >> 0
# ... seriously???
for i in "${!ARRAY[@]}"; do
if [[ "$i" -lt "$2" || "$i" -gt "${3-$2}" ]]; then
tmp=("${tmp[@]}" "${ARRAY[$i]}")
fi
done
eval "$1=(\"\${tmp[@]}\")"
}
_nmcli_compl_match_option() _nmcli_compl_match_option()
{ {
local S="$1" local S="$1"
@ -84,32 +112,32 @@ _nmcli_compl_OPTIONS()
REMOVE_LONG_OPTION="$W" REMOVE_LONG_OPTION="$W"
case "$W" in case "$W" in
terse) terse)
words=("${words[@]:1}") _nmcli_array_delete_at words 0
;; ;;
pretty) pretty)
words=("${words[@]:1}") _nmcli_array_delete_at words 0
;; ;;
nocheck) nocheck)
words=("${words[@]:1}") _nmcli_array_delete_at words 0
;; ;;
ask) ask)
words=("${words[@]:1}") _nmcli_array_delete_at words 0
;; ;;
version) version)
words=("${words[@]:1}") _nmcli_array_delete_at words 0
;; ;;
help) help)
words=("${words[@]:1}") _nmcli_array_delete_at words 0
;; ;;
temporary) temporary)
words=("${words[@]:1}") _nmcli_array_delete_at words 0
;; ;;
mode) mode)
if [[ "${#words[@]}" -eq 2 ]]; then if [[ "${#words[@]}" -eq 2 ]]; then
_nmcli_list "tabular multiline" _nmcli_list "tabular multiline"
return 0 return 0
fi fi
words=("${words[@]:2}") _nmcli_array_delete_at words 0 1
;; ;;
fields) fields)
if [[ "${#words[@]}" -eq 2 ]]; then if [[ "${#words[@]}" -eq 2 ]]; then
@ -120,21 +148,21 @@ _nmcli_compl_OPTIONS()
profile active" profile active"
return 0 return 0
fi fi
words=("${words[@]:2}") _nmcli_array_delete_at words 0 1
;; ;;
escape) escape)
if [[ "${#words[@]}" -eq 2 ]]; then if [[ "${#words[@]}" -eq 2 ]]; then
_nmcli_list "no yes" _nmcli_list "no yes"
return 0 return 0
fi fi
words=("${words[@]:2}") _nmcli_array_delete_at words 0 1
;; ;;
wait) wait)
if [[ "${#words[@]}" -eq 2 ]]; then if [[ "${#words[@]}" -eq 2 ]]; then
_nmcli_list "" _nmcli_list ""
return 0 return 0
fi fi
words=("${words[@]:2}") _nmcli_array_delete_at words 0 1
;; ;;
*) *)
# something unexpected. We are finished with parsing the OPTIONS. # something unexpected. We are finished with parsing the OPTIONS.
@ -179,8 +207,7 @@ _nmcli_compl_ARGS()
COMMAND_ARGS_WAIT_OPTIONS=0 COMMAND_ARGS_WAIT_OPTIONS=0
return 1 return 1
fi fi
ARRAY=("${OPTIONS_ALL[@]}") if ! _nmcli_array_has_value OPTIONS_ALL "${words[0]}"; then
if ! _nmcli_array_has_value "${words[0]}"; then
# This is an entirely unknown option. # This is an entirely unknown option.
OPTIONS_UNKNOWN_OPTION="?${words[0]}" OPTIONS_UNKNOWN_OPTION="?${words[0]}"
return 1 return 1
@ -441,15 +468,14 @@ _nmcli_compl_ARGS()
if [[ "${#OPTIONS_NEXT_GROUP[@]}" -gt 0 ]]; then if [[ "${#OPTIONS_NEXT_GROUP[@]}" -gt 0 ]]; then
ARRAY=("${OPTIONS_NEXT_GROUP[@]}") if _nmcli_array_has_value OPTIONS_NEXT_GROUP "${words[0]}"; then
if _nmcli_array_has_value "${words[0]}"; then
# the current value is from the next group... # the current value is from the next group...
# We back off, because the current group is complete. # We back off, because the current group is complete.
return 1 return 1
fi fi
fi fi
words=("${words[@]:$N_REMOVE_WORDS}") _nmcli_array_delete_at words 0 $((N_REMOVE_WORDS-1))
# remove the options already seen. # remove the options already seen.
for i in ${!OPTIONS[*]}; do for i in ${!OPTIONS[*]}; do
if [[ "${OPTIONS[$i]}" = "${REMOVE_OPTIONS[0]}" || "${OPTIONS[$i]}" = "${REMOVE_OPTIONS[1]}" ]]; then if [[ "${OPTIONS[$i]}" = "${REMOVE_OPTIONS[0]}" || "${OPTIONS[$i]}" = "${REMOVE_OPTIONS[1]}" ]]; then
@ -468,11 +494,10 @@ _nmcli_compl_ARGS()
# as id|uuid|path|apath. Parse that connection parameter. # as id|uuid|path|apath. Parse that connection parameter.
_nmcli_compl_ARGS_CONNECTION() _nmcli_compl_ARGS_CONNECTION()
{ {
ARRAY=("${OPTIONS[@]}") if ! _nmcli_array_has_value OPTIONS "${words[0]}"; then
if ! _nmcli_array_has_value "${words[0]}"; then
COMMAND_CONNECTION_TYPE= COMMAND_CONNECTION_TYPE=
COMMAND_CONNECTION_ID="${words[0]}" COMMAND_CONNECTION_ID="${words[0]}"
words=("${words[@]:1}") _nmcli_array_delete_at words 0
return 1 return 1
fi fi
COMMAND_CONNECTION_TYPE="${words[0]}" COMMAND_CONNECTION_TYPE="${words[0]}"
@ -487,40 +512,40 @@ _nmcli_compl_ARGS_CONNECTION()
_nmcli_list_nl "$(_nmcli_con_show NAME $CON_TYPE)" _nmcli_list_nl "$(_nmcli_con_show NAME $CON_TYPE)"
return 0 return 0
fi fi
words=("${words[@]:2}") _nmcli_array_delete_at words 0 1
;; ;;
uuid) uuid)
if [[ ${#words[@]} -le 2 ]]; then if [[ ${#words[@]} -le 2 ]]; then
_nmcli_list_nl "$(_nmcli_con_show UUID $CON_TYPE)" _nmcli_list_nl "$(_nmcli_con_show UUID $CON_TYPE)"
return 0 return 0
fi fi
words=("${words[@]:2}") _nmcli_array_delete_at words 0 1
;; ;;
path) path)
if [[ ${#words[@]} -le 2 ]]; then if [[ ${#words[@]} -le 2 ]]; then
_nmcli_list_nl "$(_nmcli_con_show DBUS-PATH $CON_TYPE)" _nmcli_list_nl "$(_nmcli_con_show DBUS-PATH $CON_TYPE)"
return 0 return 0
fi fi
words=("${words[@]:2}") _nmcli_array_delete_at words 0 1
;; ;;
apath) apath)
if [[ ${#words[@]} -le 2 ]]; then if [[ ${#words[@]} -le 2 ]]; then
_nmcli_list_nl "$(_nmcli_con_show ACTIVE-PATH --active)" _nmcli_list_nl "$(_nmcli_con_show ACTIVE-PATH --active)"
return 0 return 0
fi fi
words=("${words[@]:2}") _nmcli_array_delete_at words 0 1
;; ;;
ifname) ifname)
if [[ ${#words[@]} -le 2 ]]; then if [[ ${#words[@]} -le 2 ]]; then
_nmcli_list_nl "$(_nmcli_dev_status DEVICE)" _nmcli_list_nl "$(_nmcli_dev_status DEVICE)"
return 0 return 0
fi fi
words=("${words[@]:2}") _nmcli_array_delete_at words 0 1
;; ;;
*) *)
COMMAND_CONNECTION_TYPE= COMMAND_CONNECTION_TYPE=
COMMAND_CONNECTION_ID="${words[0]}" COMMAND_CONNECTION_ID="${words[0]}"
words=("${words[@]:1}") _nmcli_array_delete_at words 0
;; ;;
esac esac
return 1 return 1
@ -562,7 +587,8 @@ _nmcli()
# we don't care about any arguments after the current cursor position # we don't care about any arguments after the current cursor position
# because we only parse from left to right. So, if there are some arguments # because we only parse from left to right. So, if there are some arguments
# right of the cursor, just ignore them. Also don't care about ${words[0]}. # right of the cursor, just ignore them. Also don't care about ${words[0]}.
words=("${words[@]:1:$cword}") _nmcli_array_delete_at words $((cword+1)) ${#words[@]}
_nmcli_array_delete_at words 0
# _init_completion returns the words with all the quotes and escaping # _init_completion returns the words with all the quotes and escaping
# characters. We don't care about them, drop them at first. # characters. We don't care about them, drop them at first.
@ -577,7 +603,7 @@ _nmcli()
cur='' cur=''
fi fi
local OPTIONS_UNKNOWN_OPTION OPTIONS_TYPE OPTIONS_TYPED OPTIONS OPTIONS_MANDATORY COMMAND_ARGS_WAIT_OPTIONS ARRAY OPTIONS_IP OPTIONS_MANDATORY OPTIONS_NEXT_GROUP local OPTIONS_UNKNOWN_OPTION OPTIONS_TYPE OPTIONS_TYPED OPTIONS OPTIONS_MANDATORY COMMAND_ARGS_WAIT_OPTIONS OPTIONS_IP OPTIONS_MANDATORY OPTIONS_NEXT_GROUP
local COMMAND_CONNECTION_TYPE COMMAND_CONNECTION_ID OPTIONS_MANDATORY_IFNAME local COMMAND_CONNECTION_TYPE COMMAND_CONNECTION_ID OPTIONS_MANDATORY_IFNAME
local COMMAND_CONNECTION_ACTIVE="" local COMMAND_CONNECTION_ACTIVE=""
@ -626,7 +652,7 @@ _nmcli()
if [[ ${#words[@]} -eq 3 ]]; then if [[ ${#words[@]} -eq 3 ]]; then
_nmcli_compl_COMMAND "${words[2]}" level domains _nmcli_compl_COMMAND "${words[2]}" level domains
else else
words=("${words[@]:2}") _nmcli_array_delete_at words 0 1
OPTIONS=(level domains) OPTIONS=(level domains)
_nmcli_compl_ARGS _nmcli_compl_ARGS
fi fi
@ -666,11 +692,11 @@ _nmcli()
_nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "id\nuuid\npath\napath\n%s" "$(_nmcli_con_show NAME)")" active _nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "id\nuuid\npath\napath\n%s" "$(_nmcli_con_show NAME)")" active
elif [[ ${#words[@]} -gt 3 ]]; then elif [[ ${#words[@]} -gt 3 ]]; then
OPTIONS=(id uuid path apath) OPTIONS=(id uuid path apath)
words=("${words[@]:2}") _nmcli_array_delete_at words 0 1
case "${words[0]}" in case "${words[0]}" in
--a|--ac|--act|--acti|--activ|--active) --a|--ac|--act|--acti|--activ|--active)
COMMAND_CONNECTION_ACTIVE=1 COMMAND_CONNECTION_ACTIVE=1
words=("${words[@]:1}") _nmcli_array_delete_at words 0
;; ;;
esac esac
while [[ ${#words[@]} -gt 0 ]]; do while [[ ${#words[@]} -gt 0 ]]; do
@ -688,7 +714,7 @@ _nmcli()
_nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "ifname\nid\nuuid\npath\n%s" "$(_nmcli_con_show NAME)")" _nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "ifname\nid\nuuid\npath\n%s" "$(_nmcli_con_show NAME)")"
elif [[ ${#words[@]} -gt 3 ]]; then elif [[ ${#words[@]} -gt 3 ]]; then
local COMMAND_CONNECTION_TYPE='' local COMMAND_CONNECTION_TYPE=''
words=("${words[@]:2}") _nmcli_array_delete_at words 0 1
OPTIONS=(ifname id uuid path) OPTIONS=(ifname id uuid path)
_nmcli_compl_ARGS_CONNECTION && return 0 _nmcli_compl_ARGS_CONNECTION && return 0
@ -704,7 +730,7 @@ _nmcli()
if [[ ${#words[@]} -eq 3 ]]; then if [[ ${#words[@]} -eq 3 ]]; then
_nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "id\nuuid\npath\napath\n%s" "$(_nmcli_con_show NAME --active)")" _nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "id\nuuid\npath\napath\n%s" "$(_nmcli_con_show NAME --active)")"
elif [[ ${#words[@]} -gt 3 ]]; then elif [[ ${#words[@]} -gt 3 ]]; then
words=("${words[@]:2}") _nmcli_array_delete_at words 0 1
OPTIONS=(id uuid path apath) OPTIONS=(id uuid path apath)
COMMAND_CONNECTION_ACTIVE=1 COMMAND_CONNECTION_ACTIVE=1
_nmcli_compl_ARGS_CONNECTION _nmcli_compl_ARGS_CONNECTION
@ -714,7 +740,7 @@ _nmcli()
if [[ ${#words[@]} -eq 3 ]]; then if [[ ${#words[@]} -eq 3 ]]; then
_nmcli_compl_COMMAND "${words[2]}" type ifname con-name autoconnect _nmcli_compl_COMMAND "${words[2]}" type ifname con-name autoconnect
elif [[ ${#words[@]} -gt 3 ]]; then elif [[ ${#words[@]} -gt 3 ]]; then
words=("${words[@]:2}") _nmcli_array_delete_at words 0 1
OPTIONS_TYPE= OPTIONS_TYPE=
OPTIONS=(type ifname con-name autoconnect save) OPTIONS=(type ifname con-name autoconnect save)
OPTIONS_MANDATORY=(type ifname) OPTIONS_MANDATORY=(type ifname)
@ -723,12 +749,10 @@ _nmcli()
_nmcli_compl_ARGS && return 0 _nmcli_compl_ARGS && return 0
OPTIONS_MANDATORY_IFNAME= OPTIONS_MANDATORY_IFNAME=
ARRAY=("${OPTIONS[@]}") if _nmcli_array_has_value OPTIONS "${OPTIONS_MANDATORY[@]}"; then
if _nmcli_array_has_value "${OPTIONS_MANDATORY[@]}"; then
# we still have some missing mandatory options... # we still have some missing mandatory options...
if [[ "$OPTIONS_UNKNOWN_OPTION" != '' ]]; then if [[ "$OPTIONS_UNKNOWN_OPTION" != '' ]]; then
ARRAY="${OPTIONS[@]}" if ! _nmcli_array_has_value OPTIONS "${OPTIONS_UNKNOWN_OPTION:1}"; then
if ! _nmcli_array_has_value "${OPTIONS_UNKNOWN_OPTION:1}"; then
# if we encountered an unknown option while having mandatory # if we encountered an unknown option while having mandatory
# options, just return. # options, just return.
return 0 return 0
@ -846,8 +870,7 @@ _nmcli()
# we have an unknown option, but still mandatory ones that must be fullfiled first. # we have an unknown option, but still mandatory ones that must be fullfiled first.
return 0 return 0
fi fi
ARRAY=("${OPTIONS_IP[@]}") if ! _nmcli_array_has_value OPTIONS_IP "${OPTIONS_UNKNOWN_OPTION:1}"; then
if ! _nmcli_array_has_value "${OPTIONS_UNKNOWN_OPTION:1}"; then
# the unknown option is NOT an IP option. # the unknown option is NOT an IP option.
return 0 return 0
fi fi
@ -862,15 +885,13 @@ _nmcli()
# we have some mandatory options... don't check for IP options yet... # we have some mandatory options... don't check for IP options yet...
_nmcli_compl_ARGS && return 0 _nmcli_compl_ARGS && return 0
ARRAY=("${OPTIONS[@]}") if _nmcli_array_has_value OPTIONS "${OPTIONS_MANDATORY[@]}"; then
if _nmcli_array_has_value "${OPTIONS_MANDATORY[@]}"; then
_nmcli_list "$(echo "${OPTIONS[@]}")" _nmcli_list "$(echo "${OPTIONS[@]}")"
return 0 return 0
fi fi
if [[ "$OPTIONS_UNKNOWN_OPTION" != "" ]]; then if [[ "$OPTIONS_UNKNOWN_OPTION" != "" ]]; then
ARRAY=("${OPTIONS_IP[@]}") if ! _nmcli_array_has_value OPTIONS_IP "${OPTIONS_UNKNOWN_OPTION:1}"; then
if ! _nmcli_array_has_value "${OPTIONS_UNKNOWN_OPTION:1}"; then
# the unknown option is NOT an IP option. # the unknown option is NOT an IP option.
return 0 return 0
fi fi
@ -905,7 +926,7 @@ _nmcli()
if [[ ${#words[@]} -eq 3 ]]; then if [[ ${#words[@]} -eq 3 ]]; then
_nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "id\nuuid\npath\ntype\ncon-name\n%s" "$(_nmcli_con_show NAME)")" _nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "id\nuuid\npath\ntype\ncon-name\n%s" "$(_nmcli_con_show NAME)")"
elif [[ ${#words[@]} -gt 3 ]]; then elif [[ ${#words[@]} -gt 3 ]]; then
words=("${words[@]:2}") _nmcli_array_delete_at words 0 1
if [[ "${words[0]}" = 'type' || "${words[0]}" = 'con-name' ]]; then if [[ "${words[0]}" = 'type' || "${words[0]}" = 'con-name' ]]; then
OPTIONS=(type con-name) OPTIONS=(type con-name)
_nmcli_compl_ARGS _nmcli_compl_ARGS
@ -919,7 +940,7 @@ _nmcli()
if [[ ${#words[@]} -eq 3 ]]; then if [[ ${#words[@]} -eq 3 ]]; then
_nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "id\nuuid\npath\n%s" "$(_nmcli_con_show NAME)")" temporary _nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "id\nuuid\npath\n%s" "$(_nmcli_con_show NAME)")" temporary
elif [[ ${#words[@]} -gt 3 ]]; then elif [[ ${#words[@]} -gt 3 ]]; then
words=("${words[@]:2}") _nmcli_array_delete_at words 0 1
LONG_OPTIONS=(help temporary) LONG_OPTIONS=(help temporary)
_nmcli_compl_OPTIONS _nmcli_compl_OPTIONS
@ -928,8 +949,7 @@ _nmcli()
return 0 return 0
;; ;;
1) 1)
ARRAY="${LONG_OPTIONS[@]}" if _nmcli_array_has_value LONG_OPTIONS "help"; then
if _nmcli_array_has_value "help"; then
_nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "id\nuuid\npath\n%s" "$(_nmcli_con_show NAME)")" "${LONG_OPTIONS[@]}" _nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "id\nuuid\npath\n%s" "$(_nmcli_con_show NAME)")" "${LONG_OPTIONS[@]}"
fi fi
return 0 return 0
@ -945,7 +965,7 @@ _nmcli()
elif [[ ${#words[@]} -le 2 ]]; then elif [[ ${#words[@]} -le 2 ]]; then
return 0 return 0
fi fi
words=("${words[@]:2}") _nmcli_array_delete_at words 0 1
done done
_nmcli_list_nl "$(nmcli --fields profile connection show "${COMMAND_CONNECTION_TYPE:-id}" "$COMMAND_CONNECTION_ID" 2>/dev/null | sed -n 's/^\([^:]\+\):.*/\1/p')" _nmcli_list_nl "$(nmcli --fields profile connection show "${COMMAND_CONNECTION_TYPE:-id}" "$COMMAND_CONNECTION_ID" 2>/dev/null | sed -n 's/^\([^:]\+\):.*/\1/p')"
return 0 return 0
@ -955,7 +975,7 @@ _nmcli()
if [[ ${#words[@]} -eq 3 ]]; then if [[ ${#words[@]} -eq 3 ]]; then
_nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "id\nuuid\npath\n%s" "$(_nmcli_con_show NAME)")" _nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "id\nuuid\npath\n%s" "$(_nmcli_con_show NAME)")"
elif [[ ${#words[@]} -gt 3 ]]; then elif [[ ${#words[@]} -gt 3 ]]; then
words=("${words[@]:2}") _nmcli_array_delete_at words 0 1
LONG_OPTIONS=(help) LONG_OPTIONS=(help)
_nmcli_compl_OPTIONS _nmcli_compl_OPTIONS
@ -964,8 +984,7 @@ _nmcli()
return 0 return 0
;; ;;
1) 1)
ARRAY="${LONG_OPTIONS[@]}" if ! _nmcli_array_has_value LONG_OPTIONS "help"; then
if ! _nmcli_array_has_value "help"; then
return 0 return 0
fi fi
;; ;;
@ -1012,7 +1031,7 @@ _nmcli()
else else
case "${words[2]}" in case "${words[2]}" in
l|li|lis|list) l|li|lis|list)
words=("${words[@]:3}") _nmcli_array_delete_at words 0 2
OPTIONS=(ifname bssid) OPTIONS=(ifname bssid)
_nmcli_compl_ARGS _nmcli_compl_ARGS
;; ;;
@ -1024,13 +1043,13 @@ _nmcli()
_nmcli_list_nl "$(printf "%s\n%s" "$(_nmcli_wifi_list SSID)" "$(_nmcli_wifi_list BSSID)")" _nmcli_list_nl "$(printf "%s\n%s" "$(_nmcli_wifi_list SSID)" "$(_nmcli_wifi_list BSSID)")"
fi fi
else else
words=("${words[@]:4}") _nmcli_array_delete_at words 0 3
local OPTIONS=(password wep-key-type ifname bssid name private) local OPTIONS=(password wep-key-type ifname bssid name private)
_nmcli_compl_ARGS _nmcli_compl_ARGS
fi fi
;; ;;
r|re|res|resc|resca|rescan) r|re|res|resc|resca|rescan)
words=("${words[@]:3}") _nmcli_array_delete_at words 0 2
OPTIONS=(ifname) OPTIONS=(ifname)
_nmcli_compl_ARGS _nmcli_compl_ARGS
;; ;;
@ -1043,7 +1062,7 @@ _nmcli()
else else
case "${words[2]}" in case "${words[2]}" in
l|li|lis|list) l|li|lis|list)
words=("${words[@]:3}") _nmcli_array_delete_at words 0 2
OPTIONS=(ifname nsp) OPTIONS=(ifname nsp)
_nmcli_compl_ARGS _nmcli_compl_ARGS
;; ;;