testfunc() {
printf -v args_str '%q ' "$@"
while (( $# )) && [[ $1 = -* ]]; do
  arg=${1#-}; shift
  while [[ $arg ]]; do
    case $arg in
      l*) flag_l=1; arg=${arg#l};;
      u*) flag_u=1; arg=${arg#u};;
      w*)
        flag_w=1
        rest=${arg#w}
        if [[ -z $rest ]]; then
          arg=$1; shift; rest=$arg
        fi
        if [[ $rest =~ ^([[:digit:]]+)(.*) ]]; then
          w_value=${BASH_REMATCH[1]}
          arg=${BASH_REMATCH[2]}
        else
          echo "ERROR: -w not followed with a number" >&2
          exit 1
        fi
        ;;
      *) echo "Unrecognized flag: $arg" >&2; exit 1;;
    esac
  done
done

echo "After parsing $args_str"
echo "flag_w = ${flag_w:-0}"
echo "flag_l = ${flag_l:-0}"
echo "flag_u = ${flag_u:-0}"
echo "w_value = ${w_value:-0}"
}

testfunc -w42l
testfunc -w 42 -l