
  #   ˆl–ßi~”*h¥6 ¸Ø.61hßÃ„b?¿Ç ?÷     # bash completion for ethtool(8)                          -*- shell-script -*-
# shellcheck shell=bash disable=SC2207

# Complete a word representing a set of characters.
# @param $@ chars	Characters which may be present in completed set.
_ethtool_compgen_letterset()
{
	local char
	for char; do
		case "$cur" in
			*"$char"*)
				# $cur already contains $char
				;;
			*)
				COMPREPLY+=( "$cur$char" )
				;;
		esac
	done
}

# Generate completions for words matched case-insensitively
# @param $@ choices	Completion choices.
_ethtool_compgen_nocase()
{
	local reset
	reset=$( shopt -p nocasematch )
	shopt -s nocasematch

	local choice
	for choice; do
		case "$choice" in
			"$cur"*) COMPREPLY+=( "$choice" ) ;;
		esac
	done

	$reset
}

# Gets names from a section of ethtool output.
# @param $1 section_bre	POSIX BRE matching section heading (without : at end).
# @param $@		ethtool arguments
_ethtool_get_names_in_section()
{
	local section_bre="$1"
	shift

	PATH="$PATH:/sbin:/usr/sbin:/usr/local/sbin" \
		ethtool "$@" 2>/dev/null |
		command sed -n "
# Line is section heading iff it ends with :
# From requested section heading to next section heading
/^$section_bre:$/,/:$/ {
	# If line is section heading, ignore it
	/:$/d
	# Remove value and separator, if present
	s/[[:space:]]*:.*//
	# Remove leading space, if present
	s/^[[:space:]]*//
	# Print the line
	p
}"
}

# Complete an RSS Context ID
_ethtool_context()
{
	COMPREPLY=(
		$(PATH="$PATH:/sbin:/usr/sbin:/usr/local/sbin" \
			ethtool --show-nfc "${words[2]}" 2>/dev/null |
			command sed -n 's/^[[:space:]]*RSS Context ID:[[:space:]]*\([0-9]*\)$/\1/p' |
			sort -u) )
}

# Complete a network flow traffic type
# Available OPTIONS:
#	 --hash  Complete only types suitable for rx hashing
_ethtool_flow_type()
{
	local types='ah4 ah6 esp4 esp6 ether sctp4 sctp6 tcp4 tcp6 udp4 udp6'
	if [ "${1-}" != --hash ]; then
		types="$types ip4 ip6"
	else
		types="gtpc4 gtpc6 gtpc4t gtpc6t gtpu4 gtpu6 gtpu4e gtpu6e gtpu4u gtpu6u gtpu4d gtpu6d $types"
	fi
	COMPREPLY=( $( compgen -W "$types" -- "$cur" ) )
}

# Completion for ethtool --change
_ethtool_change()
{
	local -A settings=(
		[advertise]=notseen
		[autoneg]=notseen
		[duplex]=notseen
		[mdix]=notseen
		[msglvl]=notseen
		[port]=notseen
		[phyad]=notseen
		[speed]=notseen
		[wol]=notseen
		[xcvr]=notseen
		[lanes]=notseen
	)

	local -A msgtypes=(
		[drv]=notseen
		[hw]=notseen
		[ifdown]=notseen
		[ifup]=notseen
		[intr]=notseen
		[link]=notseen
		[pktdata]=notseen
		[probe]=notseen
		[rx_err]=notseen
		[rx_status]=notseen
		[timer]=notseen
		[tx_done]=notseen
		[tx_err]=notseen
		[tx_queued]=notseen
		[wol]=notseen
	)

	# Mark seen settings and msgtypes, and whether in msglvl sub-command
	local in_msglvl=
	local word
	for word in "${words[@]:3:${#words[@]}-4}"; do
		if [ "$in_msglvl" ] && [ "${msgtypes[$word]+set}" ]; then
			msgtypes[$word]=seen
		elif [ "${settings[$word]+set}" ]; then
			settings[$word]=seen
			if [ "$word" = msglvl ]; then
				in_msglvl=1
			else
				in_msglvl=
			fi
		fi
	done

	if [ "$in_msglvl" ] && [ "${msgtypes[$prev]+set}" ]; then
		# All msgtypes take an on/off argument
		COMPREPLY=( $( compgen -W 'on off' -- "$cur" ) )
		return
	fi

	case "$prev" in
		advertise)
			# Hex number
			return ;;
		autoneg)
			COMPREPLY=( $( compgen -W 'on off' -- "$cur" ) )
			return ;;
		duplex)
			COMPREPLY=( $( compgen -W 'half full' -- "$cur" ) )
			return ;;
		mdix)
			COMPREPLY=( $( compgen -W 'auto on off' -- "$cur" ) )
			return ;;
		msglvl)
			# Unsigned integer or msgtype
			COMPREPLY=( $( compgen -W "${!msgtypes[*]}" -- "$cur" ) )
			return ;;
		port)
			COMPREPLY=( $( compgen -W 'aui bnc fibre mii tp' -- "$cur" ) )
			return ;;
		phyad)
			# Integer
			return ;;
		sopass)
			_mac_addresses
			return ;;
		speed)
			# Number
			return ;;
		wol)
			# $cur is a set of wol type characters.
			_ethtool_compgen_letterset p u m b a g s f d e
			return ;;
		xcvr)
			COMPREPLY=( $( compgen -W 'internal external' -- "$cur" ) )
			return ;;
		lanes)
			# Number
			return ;;
	esac
