summaryrefslogtreecommitdiff
path: root/completions/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'completions/gcc')
-rw-r--r--completions/gcc82
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 \