# check for non-parametric options # returns number of params function _oscap_noarg { case "$1" in --definitions|--syschar|--results|-f|--force|-q|--quiet|--oval-results) return 0 ;; --version|--help|-V|-h) return 256 ;; # stop cmdline processing *) return 1 ;; esac } function _oscap { # commands for individual modules local -A cmds=() cmds[oscap]="oval xccdf cvss" cmds[oscap:oval]="collect eval eval-id validate-xml generate" cmds[oscap:oval:generate]="report" cmds[oscap:cvss]="base temporal environmental" cmds[oscap:xccdf]="eval validate-xml resolve generate" cmds[oscap:xccdf:generate]="report guide" # command options local -A opts=() opts[oscap]="--version --quiet --help -V -q -h" opts[oscap:oval:validate-xml]="--file-version --definitions --syschar --results" opts[oscap:oval:eval]="--result-file" opts[oscap:oval:eval-id]="--result-file --id" opts[oscap:oval:generate:report]="-o --output" opts[oscap:xccdf:eval]="--profile --result-file --report-file --oval-results" opts[oscap:xccdf:validate-xml]="--file-version" opts[oscap:xccdf:resolve]="-o --output -f --force" opts[oscap:xccdf:generate]="--profile" opts[oscap:xccdf:generate:report]="-o --output -i --result-id --show --profile" opts[oscap:xccdf:generate:guide]="-o --output --hide-profile-info --profile" opts[oscap:xccdf:generate:fix]="-o --output --template --profile --result-id" opts[oscap:cvss:base]="--AV --AC --AU --CI --II --AI" opts[oscap:cvss:temporal]="--EX --RL --RC --base" opts[oscap:cvss:environmental]="--AV --AC --AU --CI --II --AI --EX --RL --RC --CD --TD --CR --IR --AR --base" # local variables local std cmd i prev local c=1 local cur="`_get_cword`" local prog="${COMP_WORDS[0]}" local modpath='oscap' _split_longopt || prev="${COMP_WORDS[$COMP_CWORD-1]}" # get module path while [ $c -lt $COMP_CWORD ]; do i="${COMP_WORDS[c]}" case "$i" in # TODO handle generic switches -*) _oscap_noarg "$i"; c=$((c + $?)) ;; *) modpath="$modpath:$i" ;; esac c=$((c + 1)) done if [ "x${prev:0:1}" == "x-" ] && ! _oscap_noarg "$prev"; then # an option argument local cmd=${modpath##*:} case "$prev" in --AV|--AC|--AU|--CI|--II|--AI|--EX|--RL|--RC|--CD|--TD|--CR|--IR|--AR) COMPREPLY=( $(compgen -W "`$prog cvss $cmd -h | sed -r -n -e "s:^\s+$prev=\[(.+)\].+$:\1:gp" | tr '|' ' '`" -- ${cur}) ) ;; --result-file|-o|--output|--template) _filedir 'xml' ;; --report-file) _filedir 'html' ;; esac elif [ "x${cur:0:1}" == "x-" ] || [ "${modpath:0:11}" == 'oscap:cvss:' ]; then # an option COMPREPLY=( $(compgen -W "${opts[$modpath]}" -- ${cur}) ) elif [ "x${cmds[$modpath]}" != 'x' ]; then # a submodule COMPREPLY=( $(compgen -W "${cmds[$modpath]}" -- ${cur}) ) else # a positional argument case "$modpath" in oscap:cvss:*) ;; # no positional args for cvss *) _filedir 'xml' ;; esac fi } [ "${BASH_VERSINFO[0]}" -ge '4' ] && complete -F _oscap -o filenames oscap