From patchwork Fri Jan 25 22:26:25 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Verma, Vishal L" X-Patchwork-Id: 10782139 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8C64A1390 for ; Fri, 25 Jan 2019 22:26:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7586B306C5 for ; Fri, 25 Jan 2019 22:26:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 657E52C879; Fri, 25 Jan 2019 22:26:30 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id EE8D32C879 for ; Fri, 25 Jan 2019 22:26:29 +0000 (UTC) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id A5B82211BA47B; Fri, 25 Jan 2019 14:26:29 -0800 (PST) X-Original-To: linux-nvdimm@lists.01.org Delivered-To: linux-nvdimm@lists.01.org Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=134.134.136.31; helo=mga06.intel.com; envelope-from=vishal.l.verma@intel.com; receiver=linux-nvdimm@lists.01.org Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 7F219203BBB80 for ; Fri, 25 Jan 2019 14:26:28 -0800 (PST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 25 Jan 2019 14:26:27 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,523,1539673200"; d="scan'208";a="133167394" Received: from vverma7-desk1.lm.intel.com ([10.232.112.170]) by orsmga001.jf.intel.com with ESMTP; 25 Jan 2019 14:26:27 -0800 From: Vishal Verma To: Subject: [ndctl PATCH] daxctl: Add bash-completion Date: Fri, 25 Jan 2019 15:26:25 -0700 Message-Id: <20190125222625.15164-1-vishal.l.verma@intel.com> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 X-BeenThere: linux-nvdimm@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Linux-nvdimm developer list." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: linux-nvdimm-bounces@lists.01.org Sender: "Linux-nvdimm" X-Virus-Scanned: ClamAV using ClamSMTP Add bash completion helpers to contrib/ndctl to also allow for daxctl completion. This makes it so we have a single bash-completion script that is installed, and it provides completions for both ndctl and daxctl. As a bonus, some of the common functions can also get reused by both. Cc: Dan Williams Signed-off-by: Vishal Verma --- contrib/ndctl | 155 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 128 insertions(+), 27 deletions(-) diff --git a/contrib/ndctl b/contrib/ndctl index 515494d..629d6a8 100755 --- a/contrib/ndctl +++ b/contrib/ndctl @@ -2,6 +2,8 @@ # Taken from perf's completion script. +### common helpers between ndctl and daxctl + __my_reassemble_comp_words_by_ref() { local exclude i j first @@ -49,7 +51,7 @@ __my_reassemble_comp_words_by_ref() } # Define preload_get_comp_words_by_ref="false", if the function -# __ndctl_get_comp_words_by_ref() is required instead. +# __nd_common_get_comp_words_by_ref() is required instead. preload_get_comp_words_by_ref="true" if [ $preload_get_comp_words_by_ref = "true" ]; then @@ -57,7 +59,7 @@ if [ $preload_get_comp_words_by_ref = "true" ]; then preload_get_comp_words_by_ref="false" fi [ $preload_get_comp_words_by_ref = "true" ] || -__ndctl_get_comp_words_by_ref() +__nd_common_get_comp_words_by_ref() { local exclude cur_ words_ cword_ if [ "$1" = "-n" ]; then @@ -85,6 +87,29 @@ __ndctl_get_comp_words_by_ref() done } +__nd_common_prev_skip_opts () +{ + local i cmd_ cmds_ + + let i=cword-1 + cmds_=$($cmd $1 --list-cmds) + prev_skip_opts=() + while [ $i -ge 0 ]; do + if [[ ${words[i]} == $1 ]]; then + return + fi + for cmd_ in $cmds_; do + if [[ ${words[i]} == $cmd_ ]]; then + prev_skip_opts=${words[i]} + return + fi + done + ((i--)) + done +} + +### ndctl + __ndctlcomp() { local i=0 @@ -351,27 +376,6 @@ __ndctl_add_special_opts() esac } -__ndctl_prev_skip_opts () -{ - local i cmd_ cmds_ - - let i=cword-1 - cmds_=$($cmd $1 --list-cmds) - prev_skip_opts=() - while [ $i -ge 0 ]; do - if [[ ${words[i]} == $1 ]]; then - return - fi - for cmd_ in $cmds_; do - if [[ ${words[i]} == $cmd_ ]]; then - prev_skip_opts=${words[i]} - return - fi - done - ((i--)) - done -} - __ndctl_init_filters() { bus_filter='' @@ -430,7 +434,7 @@ __ndctl_main() __ndctl_init_filters # Skip options backward and find the last ndctl command - __ndctl_prev_skip_opts + __nd_common_prev_skip_opts subcmd=$prev_skip_opts # List ndctl subcommands or long options if [ -z $subcmd ]; then @@ -498,9 +502,106 @@ _ndctl() if [ $preload_get_comp_words_by_ref = "true" ]; then _get_comp_words_by_ref -n =: cur words cword prev else - __ndctl_get_comp_words_by_ref -n =: cur words cword prev + __nd_common_get_comp_words_by_ref -n =: cur words cword prev fi __ndctl_main -} && +} + +### daxctl ### + +__daxctl_get_devs() +{ + local opts="--devices $*" + echo "$(daxctl list $opts | grep -E "^\s*\"chardev\":" | cut -d\" -f4)" +} + +__daxctlcomp() +{ + local i=0 + + COMPREPLY=( $( compgen -W "$1" -- "$2" ) ) + for cword in "${COMPREPLY[@]}"; do + if [[ "$cword" == @(--region|--dev) ]]; then + COMPREPLY[$i]="${cword}=" + else + COMPREPLY[$i]="${cword} " + fi + ((i++)) + done +} + +__daxctl_comp_options() +{ + + local cur=$1 + local opts + + if [[ "$cur" == *=* ]]; then + local cur_subopt=${cur%%=*} + local cur_arg=${cur##*=} + case $cur_subopt in + --region) + opts=$(__ndctl_get_regions -i) + ;; + --dev) + opts=$(__daxctl_get_devs -i) + ;; + *) + return + ;; + esac + __daxctlcomp "$opts" "$cur_arg" + fi +} + +__daxctl_comp_non_option_args() +{ + # there aren't any commands that accept non option arguments yet + return +} + +__daxctl_main() +{ + local cmd subcmd + + cmd=${words[0]} + COMPREPLY=() + + # Skip options backward and find the last daxctl command + __nd_common_prev_skip_opts + subcmd=$prev_skip_opts + # List daxctl subcommands or long options + if [ -z $subcmd ]; then + if [[ $cur == --* ]]; then + cmds="--version --help --list-cmds" + else + cmds=$($cmd --list-cmds) + fi + __daxctlcomp "$cmds" "$cur" + else + # List long option names + if [[ $cur == --* ]]; then + opts=$($cmd $subcmd --list-opts) + __daxctlcomp "$opts" "$cur" + __daxctl_comp_options "$cur" + else + [ -z "$subcmd" ] && return + __daxctl_comp_non_option_args "$subcmd" "$cur" + fi + fi +} + +type daxctl &>/dev/null && +_daxctl() +{ + local cur words cword prev + if [ $preload_get_comp_words_by_ref = "true" ]; then + _get_comp_words_by_ref -n =: cur words cword prev + else + __nd_common_get_comp_words_by_ref -n =: cur words cword prev + fi + __daxctl_main +} -complete -o nospace -F _ndctl ndctl 2>/dev/null +complete -o nospace -F _ndctl ndctl +complete -o nospace -F _daxctl daxctl