# (C) 2010 magicant

# Completion script for the "od" command.
# Supports POSIX 2008, GNU coreutils 8.4, FreeBSD 8.1, OpenBSD 4.8, NetBSD 5.0,
# Mac OS X 10.6.4, SunOS 5.10, HP-UX 11i v3.

function completion/od {

	case $("${WORDS[1]}" --version 2>/dev/null) in
		(*'coreutils'*) typeset type=GNU ;;
		(*)             typeset type="$(uname 2>/dev/null)" ;;
	esac
	case $type in
		(GNU) typeset long=true ;;
		(*)   typeset long= ;;
	esac
	case $type in
		(GNU|*BSD|Darwin) typeset bsd=true ;;
		(*)               typeset bsd= ;;
	esac

	typeset OPTIONS POSIXOPTIONS ADDOPTIONS ARGOPT PREFIX
	POSIXOPTIONS=( #>#
	"A: ${long:+--address-radix:}; specify the radix of addresses printed at the beginning of lines"
	"b; like -t o1: interpret bytes in octal"
	"c; interpret bytes as characters"
	"d; like -t u2: interpret 2-byte words in unsigned decimal"
	"j: ${long:+--skip-bytes:}; specify the number of bytes to skip first"
	"N: ${long:+--read-bytes:}; specify the number of bytes to dump at most"
	"o ${bsd:+B}; like -t o2: interpret 2-byte words in octal"
	"s; like -t d2: interpret 2-byte words in signed decimal"
	"t: ${long:+--format:}; specify output format"
	"v ${long:+--output-duplicates}; don't omit lines containing the same data as the previous line"
	"x ${bsd:+h}; like -t x2: interpret 2-byte words in hexadecimal"
	) #<#

	ADDOPTIONS=()
	case $type in (GNU|*BSD|Darwin|SunOS)
		ADDOPTIONS=("$ADDOPTIONS" #>#
		"F ${bsd:+e}; like -t fD: interpret double-precision floating point numbers"
		"f; like -t fF: interpret single-precision floating point numbers"
		"O; like -t o4: interpret 4-byte words in octal"
		"X ${bsd:+H}; like -t x4: interpret 4-byte words in hexadecimal"
		) #<#
		case $type in (GNU|*BSD|Darwin)
			ADDOPTIONS=("$ADDOPTIONS" #>#
			"a; like -t a: interpret named characters"
			"l L I; like -t dL: interpret signed long values in decimal"
			"i; like -t dI: interpret singed int values in decimal"
			) #<#
		esac
		case $type in (GNU|FreeBSD|Darwin|SunOS)
			ADDOPTIONS=("$ADDOPTIONS" #>#
			"D; like -t u4: interpret 4-byte words in unsigned decimal"
			) #<#
		esac
		case $type in
		(GNU)
			ADDOPTIONS=("$ADDOPTIONS" #>#
			"S: --strings::; output strings of at least n-byte long"
			"w:: --width::; specify the number of input bytes per output line"
			"--traditional; use the traditional syntax"
			"--help"
			"--version"
			) #<#
			;;
		(SunOS)
			ADDOPTIONS=("$ADDOPTIONS" #>#
			"C; interpret bytes as characters"
			"S; like -t d4: interpret 4-byte words in signed decimal"
			) #<#
			;;
		esac
	esac

	OPTIONS=("$POSIXOPTIONS" "$ADDOPTIONS")
	unset POSIXOPTIONS ADDOPTIONS

	command -f completion//parseoptions ${long:+-es}
	case $ARGOPT in
	(-)
		command -f completion//completeoptions
		;;
	(A|--address-radix) #>>#
		complete -P "$PREFIX" -D "decimal" d
		complete -P "$PREFIX" -D "octal" o
		complete -P "$PREFIX" -D "hexadecimal" x
		complete -P "$PREFIX" -D "none" n
		;; #<<#
	(j|--skip-bytes)
		typeset word hex
		command -f completion/od::size && {
			if command -vf completion//completesizesuffix >/dev/null 2>&1 ||
					. -AL completion/_blocksize; then
				command -f completion//completesizesuffix k m ${hex:-b}
			fi
		}
		;;
	([NS]|--read-bytes|--strings)
		typeset word hex
		command -f completion/od::size
		;;
	(w|--width)
		;;
	(t|--format) #>>#
		complete -P "$TARGETWORD" -D "named character" a
		complete -P "$TARGETWORD" -D "character" c
		complete -P "$TARGETWORD" -D "signed decimal" d
		complete -P "$TARGETWORD" -D "floating point number" f
		complete -P "$TARGETWORD" -D "octal" o
		complete -P "$TARGETWORD" -D "unsigned decimal" u
		complete -P "$TARGETWORD" -D "hexadecimal" x
		#<<#
		case ${TARGETWORD#"$PREFIX"} in
		(*[doux]) #>>#
			complete -P "$TARGETWORD" -D "char" C
			complete -P "$TARGETWORD" -D "short" S
			complete -P "$TARGETWORD" -D "int" I
			complete -P "$TARGETWORD" -D "long" L
			;; #<<#
		(*f) #>>#
			complete -P "$TARGETWORD" -D "float" F
			complete -P "$TARGETWORD" -D "double" D
			complete -P "$TARGETWORD" -D "long double" L
			;; #<<#
		esac
		case $type in (GNU)
			case ${TARGETWORD#"$PREFIX"} in (*[acdfouxCDFSIL[:digit:]]) #>>#
				complete -P "$TARGETWORD" -D "also print characters directly" z
			esac #<<#
		esac
		;;
	(*)
		complete -f
		;;
	esac

}

# This function sets the word, hex, PREFIX variables.
function completion/od::size {
	word="${TARGETWORD#"$PREFIX"}"
	case $word in
		(0[Xx]*) hex=true ;;
		(*)      hex= ;;
	esac
	case $word in ([[:digit:]]*)
		while [ "${word#[[:digit:]AaBbCcDdEeFfXx]}" != "$word" ]; do
			word=${word#[[:digit:]AaBbCcDdEeFfXx]}
		done
		PREFIX=${TARGETWORD%"$word"}
		case $type in (GNU)
			if command -vf completion//completesizesuffix >/dev/null 2>&1 ||
					. -AL completion/_blocksize; then
				command -f completion//completesizesuffix GNU${hex:+-E}
			fi
		esac
		return 0
	esac
	return 1
}


# vim: set ft=sh ts=8 sts=8 sw=8 noet:
