It's okay.
I would place the
shift before the
done so it's immediately visible that the loop won't run forever.
And shift out all -* args.
Code:
while (( $# > 0 )); do
case $1 in
##------------------------------------------------
(-p+([[:digit:]]))
val="${1:2}" ;;
(-p*)
printf '%s\n' "${1:2} malformed number" ;;
(--)
shift; break ;;
(-*)
printf '%s\n' "$1 Unrecognised Predicate"
shift; break ;;
(*)
break ;;
esac
shift
done