12c593315Sopenharmony_ci#!/usr/bin/env python3
22c593315Sopenharmony_ci# -*- coding: utf-8 -*-
32c593315Sopenharmony_ci
42c593315Sopenharmony_ciimport subprocess
52c593315Sopenharmony_ciimport io
62c593315Sopenharmony_ciimport re
72c593315Sopenharmony_ciimport sys
82c593315Sopenharmony_ciimport os.path
92c593315Sopenharmony_ci
102c593315Sopenharmony_ciclass Option:
112c593315Sopenharmony_ci    def __init__(self, long_opt, short_opt):
122c593315Sopenharmony_ci        self.long_opt = long_opt
132c593315Sopenharmony_ci        self.short_opt = short_opt
142c593315Sopenharmony_ci
152c593315Sopenharmony_cidef get_all_options(cmd):
162c593315Sopenharmony_ci    opt_pattern = re.compile(r'  (?:(-.), )?(--[^\s\[=]+)(\[)?')
172c593315Sopenharmony_ci    proc = subprocess.Popen([cmd, "--help"], stdout=subprocess.PIPE)
182c593315Sopenharmony_ci    stdoutdata, _ = proc.communicate()
192c593315Sopenharmony_ci    cur_option = None
202c593315Sopenharmony_ci    opts = {}
212c593315Sopenharmony_ci    for line in io.StringIO(stdoutdata.decode('utf-8')):
222c593315Sopenharmony_ci        match = opt_pattern.match(line)
232c593315Sopenharmony_ci        if not match:
242c593315Sopenharmony_ci            continue
252c593315Sopenharmony_ci        long_opt = match.group(2)
262c593315Sopenharmony_ci        short_opt = match.group(1)
272c593315Sopenharmony_ci        opts[long_opt] = Option(long_opt, short_opt)
282c593315Sopenharmony_ci
292c593315Sopenharmony_ci    return opts
302c593315Sopenharmony_ci
312c593315Sopenharmony_cidef output_case(out, name, opts):
322c593315Sopenharmony_ci    out.write('''\
332c593315Sopenharmony_ci_{name}()
342c593315Sopenharmony_ci{{
352c593315Sopenharmony_ci    local cur prev split=false
362c593315Sopenharmony_ci    COMPREPLY=()
372c593315Sopenharmony_ci    COMP_WORDBREAKS=${{COMP_WORDBREAKS//=}}
382c593315Sopenharmony_ci
392c593315Sopenharmony_ci    cmd=${{COMP_WORDS[0]}}
402c593315Sopenharmony_ci    _get_comp_words_by_ref cur prev
412c593315Sopenharmony_ci'''.format(name=name))
422c593315Sopenharmony_ci
432c593315Sopenharmony_ci    # Complete option name.
442c593315Sopenharmony_ci    out.write('''\
452c593315Sopenharmony_ci    case $cur in
462c593315Sopenharmony_ci        -*)
472c593315Sopenharmony_ci            COMPREPLY=( $( compgen -W '\
482c593315Sopenharmony_ci''')
492c593315Sopenharmony_ci    for opt in opts.values():
502c593315Sopenharmony_ci        out.write(opt.long_opt)
512c593315Sopenharmony_ci        out.write(' ')
522c593315Sopenharmony_ci
532c593315Sopenharmony_ci    out.write('''\
542c593315Sopenharmony_ci' -- "$cur" ) )
552c593315Sopenharmony_ci            ;;
562c593315Sopenharmony_ci''')
572c593315Sopenharmony_ci    # If no option found for completion then complete with files.
582c593315Sopenharmony_ci    out.write('''\
592c593315Sopenharmony_ci        *)
602c593315Sopenharmony_ci            _filedir
612c593315Sopenharmony_ci            return 0
622c593315Sopenharmony_ci    esac
632c593315Sopenharmony_ci    return 0
642c593315Sopenharmony_ci}}
652c593315Sopenharmony_cicomplete -F _{name} {name}
662c593315Sopenharmony_ci'''.format(name=name))
672c593315Sopenharmony_ci
682c593315Sopenharmony_ciif __name__ == '__main__':
692c593315Sopenharmony_ci    if len(sys.argv) < 2:
702c593315Sopenharmony_ci        print("Generates bash_completion using `/path/to/cmd --help'")
712c593315Sopenharmony_ci        print("Usage: make_bash_completion.py /path/to/cmd")
722c593315Sopenharmony_ci        exit(1)
732c593315Sopenharmony_ci    name = os.path.basename(sys.argv[1])
742c593315Sopenharmony_ci    opts = get_all_options(sys.argv[1])
752c593315Sopenharmony_ci    output_case(sys.stdout, name, opts)
76