diff options
Diffstat (limited to 'completions/gcc')
-rw-r--r-- | completions/gcc | 82 |
1 files changed, 45 insertions, 37 deletions
diff --git a/completions/gcc b/completions/gcc index b72bf972..86d0d095 100644 --- a/completions/gcc +++ b/completions/gcc @@ -1,50 +1,58 @@ # gcc(1) completion -*- shell-script -*- -# -# The only unusual feature is that we don't parse "gcc --help -v" output -# directly, because that would include the options of all the other backend -# tools (linker, assembler, preprocessor, etc) without any indication that -# you cannot feed such options to the gcc driver directly. (For example, the -# linker takes a -z option, but you must type -Wl,-z for gcc.) Instead, we -# ask the driver ("g++") for the name of the compiler ("cc1"), and parse the -# --help output of the compiler. _gcc() { - local cur prev words cword + local cur prev prev2 words cword argument prefix prefix_length _init_completion || return - local cc backend + # Test that GCC is recent enough and if not fallback to + # parsing of --completion option. + if ! $1 --completion=" " 2>/dev/null; then + if [[ "$cur" == -* ]]; then + local cc=$($1 -print-prog-name=cc1 2>/dev/null) + [[ $cc ]] || return + COMPREPLY=($( compgen -W "$($cc --help 2>/dev/null | tr '\t' ' ' |\ + command sed -e '/^ *-/!d' -e 's/ *-\([^][ <>]*\).*/-\1/')" \ + -- "$cur" )) + [[ $COMPREPLY == *= ]] && compopt -o nospace + else + _filedir + fi + return + fi - case $1 in - gcj) - backend=jc1 - ;; - gpc) - backend=gpc1 - ;; - *77) - backend=f771 - ;; - *95) - backend=f951 - ;; - *) - backend=cc1 # (near-)universal backend - ;; - esac + # extract also for situations like: -fsanitize=add + if [[ $cword -gt 2 ]]; then + prev2="${COMP_WORDS[$cword - 2]}" + fi + # sample: -fsan if [[ "$cur" == -* ]]; then - cc=$($1 -print-prog-name=$backend 2>/dev/null) - [[ $cc ]] || return - # sink stderr: - # for C/C++/ObjectiveC it's useless - # for FORTRAN/Java it's an error - COMPREPLY=( $(compgen -W "$($cc --help 2>/dev/null | tr '\t' ' ' |\ - command sed -e '/^ *-/!d' -e 's/ *-\([^][ <>]*\).*/-\1/')" \ - -- "$cur") ) - [[ $COMPREPLY == *= ]] && compopt -o nospace - else + argument=$cur + prefix="" + # sample: -fsanitize= + elif [[ "$cur" == "=" && $prev == -* ]]; then + argument=$prev$cur + prefix=$prev$cur + # sample: -fsanitize=add + elif [[ "$prev" == "=" && $prev2 == -* ]]; then + argument=$prev2$prev$cur + prefix=$prev2$prev + # sample: --param lto- + elif [[ "$prev" == --param ]]; then + argument="$prev $cur" + prefix="$prev " + fi + + if [[ -z $argument ]]; then _filedir + else + # In situation like '-fsanitize=add' $cur is equal to last token. + # Thus we need to strip the beginning of suggested option. + prefix_length=$((${#prefix}+1)) + local flags=$($1 --completion="$argument" | cut -c $prefix_length-) + [[ "${flags}" == "=*" ]] && compopt -o nospace 2>/dev/null + COMPREPLY=( $(compgen -W "$flags" -- "") ) fi } && complete -F _gcc gcc{,-5,-6,-7,-8} g++{,-5,-6,-7,-8} g77 g95 \ |