Fix issues detected by static analysis tool
[platform/upstream/libxkbcommon.git] / tools / xkbcli-bash-completion.sh
1 # bash completion support for xkbcli.
2
3 # See completion API documentation: https://github.com/scop/bash-completion
4 # NOTE: The script parses the commands help messages to provide the completions,
5 #       thus any new subcommand or option will be supported, as long as it has its
6 #       entry in the help messages. This should result in low maintenancei effort.
7
8 ___xkbcli_main()
9 {
10     # Initialization: https://github.com/scop/bash-completion/blob/fdf4456186eb4548ef628e65fb1be73d8e4695e9/bash_completion.d/000_bash_completion_compat.bash#L205
11     local cur prev words cword cmd
12     _init_completion -s || return
13
14     # Find subcommand
15     local i=1
16     while [[ "$i" -lt "$COMP_CWORD" ]]; do
17         local s="${COMP_WORDS[i]}"
18         case "$s" in
19             -*) ;;
20             *)
21             cmd="$s"
22             break
23             ;;
24         esac
25         (( i++ ))
26     done
27
28     # Parse available subcommands
29     local line
30     local is_command_list=false
31     local subcommands=()
32     while IFS='' read -r line; do
33         # Traverse subcommand list
34         if [[ "$is_command_list" == true ]]; then
35             # Check for subcommand based on the indentation
36             if [[ "$line" =~ ^[[:blank:]]{2}([[:alpha:]]([[:alnum:]]|-)+)$ ]]; then
37                 subcommands+=("${BASH_REMATCH[1]}")
38             # Detect end of subcommand list based on indentation
39             elif [[ "$line" =~ ^[[:graph:]] ]]; then
40                 is_command_list=false
41             fi
42         # Detect start of subcommand list
43         elif [[ "$line" == "Commands:" ]]; then
44             is_command_list=true
45         fi
46     # NOTE: <( COMMAND ) Bash construct is “process substitution”.
47     done < <(xkbcli --help)
48
49     # No previous subcommand or incomplete: completion for root xkbcli command
50     if [[ "$i" -eq "$COMP_CWORD" ]]; then
51         local opts
52         # Doc for _parse_help: https://github.com/scop/bash-completion/blob/fdf4456186eb4548ef628e65fb1be73d8e4695e9/bash_completion.d/000_bash_completion_compat.bash#L311
53         opts=$(_parse_help xkbcli)
54         local cur="${COMP_WORDS[COMP_CWORD]}"
55         COMPREPLY=($(compgen -W "${subcommands[*]} $opts" -- "$cur"))
56         return
57     fi
58
59     # Found a supported subcommand: proceed to completion
60     if [[ "${subcommands[*]}" =~ (^| )$cmd( |$) ]]; then
61         ___xkbcli_subcommand "$cmd"
62     fi
63 }
64
65 ___xkbcli_subcommand()
66 {
67     # Some special cases
68     case $1 in
69         compile-keymap | interactive-evdev)
70             case ${COMP_WORDS[COMP_CWORD-1]} in
71                 --include | --keymap)
72                     _filedir
73                     return;;
74             esac
75             ;;
76         list)
77             if [[ ${COMP_WORDS[COMP_CWORD]} != -* ]]; then
78                 _filedir
79                 return
80             fi
81             ;;
82     esac
83
84     # Parse help to get command options
85     local opts
86     # Doc for _parse_usage and _parse_help:
87     # • https://github.com/scop/bash-completion/blob/fdf4456186eb4548ef628e65fb1be73d8e4695e9/bash_completion.d/000_bash_completion_compat.bash#L335
88     # • https://github.com/scop/bash-completion/blob/fdf4456186eb4548ef628e65fb1be73d8e4695e9/bash_completion.d/000_bash_completion_compat.bash#L311
89     # We need both as the current help messages adopt both GNU and BSD styles.
90     opts=$(_parse_usage xkbcli "$1 --help")
91     opts+=$(_parse_help xkbcli "$1 --help")
92     local cur="${COMP_WORDS[COMP_CWORD]}"
93     COMPREPLY=($(compgen -W "$opts" -- "$cur"))
94 }
95
96 complete -F ___xkbcli_main xkbcli