Although this question was posted over 2 years ago, I found myself needing support for XFree86-style long options too; and I also wanted to take what I could from getopts. Consider the GCC switch -rdynamic. I mark r as the flag letter, and expect dynamic within $OPTARG...but, I want to reject -r dynamic, while accepting other options following r.
The idea I've put below builds on the observation that $OPTIND will be one larger than otherwise if space (a gap) follows the flag. So, I define a bash variable to hold the previous value of $OPTIND, called $PREVOPTIND, and update it at the end of the while loop. If $OPTIND is 1 greater than $PREVOPTIND, we have no gap (i.e. -rdynamic); and $GAP is set to false. If instead $OPTIND is 2 greater than $PREVOPTIND, we do have a gap (e.g. -r dynamic), and $GAP is set to true.
usage() { echo usage: error from $1; exit -1; }
OPTIND=1
PREVOPTIND=$OPTIND
while getopts "t:s:o:" option; do
GAP=$((OPTIND-(PREVOPTIND+1)))
case $option in
t) case "${OPTARG}" in
emp) # i.e. -temp
((GAP)) && usage "-${option} and ${OPTARG}"
TMPDIR="$OPTARG"
;;
*)
true
;;
esac
;;
s) case "${OPTARG}" in
hots) # i.e. -shots
((GAP)) && usage
NUMSHOTS="$OPTARG"
;;
*) usage "-${option} and ${OPTARG}" ;;
esac
;;
o) OUTFILE="$OPTARG" ;;
*) usage "-${option} and ${OPTARG}" ;;
esac
PREVOPTIND=$OPTIND
done
shift $(($OPTIND - 1))