diff --git a/sh/argc b/sh/argc index c1e4baf..5a27626 100644 --- a/sh/argc +++ b/sh/argc @@ -9,68 +9,49 @@ argc() { ### @- ### # usage: ### ### myfunc() { - ### argc X "$0" "$@" || return; - ### # ^-- replace X with one of the following: - ### # * N to expect an *exact* (==) number of arguments, - ### # * +N to expect *at least* (>=) some number of arguments, - ### # * -N to expect *at most* (<=) some number of arguments, + ### # use one of the following: + ### argc -eq N "$0" "$@" || return + ### argc -le N "$0" "$@" || return + ### argc -ge N "$0" "$@" || return ### # where N is an integer between 0 and 9. ### } ### ``` - if [ $# -lt 2 ] || [ -z "$1" ] || [ -z "$2" ]; then - printf 'usage: %s (N|+N|-N) "$0" "$@" || return\n' "$0" >&2 +# local usage='usage: myfunc() { %s -(eq|lt|gt|le|ge) [0-9] "$0" "$@" || return; }\n' + local usage='usage: myfunc() { %s -(eq|le|ge) [0-9] "$0" "$@" || return; }\n' + + # note that $zero can be empty, but must be set. + if [ $# -lt 3 ] || [ -z "$1" ] || [ -z "$2" ] || [ "${3+x}" != x ]; then + printf "$usage" argc >&2 return 2 fi + local cond="$1"; shift local want="$1"; shift local zero="$1"; shift - local err='' - - case "$want" in - # i realize hardcoding each case like this *looks* terrible, - # but consider: there's only thirty cases we need to handle. - # plus, i can write a specific error message for each. - - 0) [ $# -eq 0 ] || err='expected no arguments, got';; - 1) [ $# -eq 1 ] || err='expected exactly one argument, got';; - 2) [ $# -eq 2 ] || err='expected exactly two arguments, got';; - 3) [ $# -eq 3 ] || err='expected exactly three arguments, got';; - 4) [ $# -eq 4 ] || err='expected exactly four arguments, got';; - 5) [ $# -eq 5 ] || err='expected exactly five arguments, got';; - 6) [ $# -eq 6 ] || err='expected exactly six arguments, got';; - 7) [ $# -eq 7 ] || err='expected exactly seven arguments, got';; - 8) [ $# -eq 8 ] || err='expected exactly eight arguments, got';; - 9) [ $# -eq 9 ] || err='expected exactly nine arguments, got';; - - +0) :;; # anything goes - +1) [ $# -ge 1 ] || err='expected at least one argument, got';; - +2) [ $# -ge 2 ] || err='expected at least two arguments, got';; - +3) [ $# -ge 3 ] || err='expected at least three arguments, got';; - +4) [ $# -ge 4 ] || err='expected at least four arguments, got';; - +5) [ $# -ge 5 ] || err='expected at least five arguments, got';; - +6) [ $# -ge 6 ] || err='expected at least six arguments, got';; - +7) [ $# -ge 7 ] || err='expected at least seven arguments, got';; - +8) [ $# -ge 8 ] || err='expected at least eight arguments, got';; - +9) [ $# -ge 9 ] || err='expected at least nine arguments, got';; - - -0) [ $# -le 0 ] || err='expected no arguments, got';; - -1) [ $# -le 1 ] || err='expected at most one argument, got';; - -2) [ $# -le 2 ] || err='expected at most two arguments, got';; - -3) [ $# -le 3 ] || err='expected at most three arguments, got';; - -4) [ $# -le 4 ] || err='expected at most four arguments, got';; - -5) [ $# -le 5 ] || err='expected at most five arguments, got';; - -6) [ $# -le 6 ] || err='expected at most six arguments, got';; - -7) [ $# -le 7 ] || err='expected at most seven arguments, got';; - -8) [ $# -le 8 ] || err='expected at most eight arguments, got';; - -9) [ $# -le 9 ] || err='expected at most nine arguments, got';; + local many='' plural='' + [ "$want" = 1 ] || plural='s' + case "$cond" in + '-eq') many='exactly';; +# '-lt') many='fewer than';; +# '-gt') many='more than';; + '-le') many='at most';; + '-ge') many='at least';; *) - printf 'usage: %s (N|+N|-N) "$0" "$@" || return\n' "$0" >&2 + printf "$usage" argc >&2 return 2;; esac - if [ -n "$err" ]; then + case "$want" in + [0-9]) :;; # no error, continue. + *) + printf "$usage" argc >&2 + return 2;; + esac + + if [ ! $# "$cond" "$want" ]; then + local err="expected $many $want argument$plural, got" printf '%s: %s %s\n' "$zero" "$err" "$#" >&2 return 1 fi diff --git a/sh/streamcrap b/sh/streamcrap index 47b6e79..7597fba 100644 --- a/sh/streamcrap +++ b/sh/streamcrap @@ -24,7 +24,7 @@ _M_LESS_INSANE="$_M_PRE_EMPH,acompressor=threshold=0.0020:ratio=1.41:attack=1000 _M_NEO="equalizer=700:o:1.3:-5,equalizer=1200:o:1.3:-3,equalizer=1090:o:0.5:-5,equalizer=970:o:1.2:-10,equalizer=4100:o:0.3:-6" getladspa() { - argc 1 "$0" "$@" || return + argc -eq 1 "$0" "$@" || return REPLY=volume if [ -e "/usr/lib/ladspa/${1}.so" ]; then REPLY="ladspa=f=${1}:p=${1}" @@ -37,7 +37,7 @@ _M_LEVEL="$REPLY" _nn="$(uname -n | tr A-Z a-z)" earphones() { - argc 0 "$0" "$@" || return + argc -eq 0 "$0" "$@" || return _M_PROCESS="lowpass=8000:p=1,$_M_KILL,alimiter=level_out=0.707" } @@ -46,7 +46,7 @@ if [ "$_nn" = spectre ]; then fi if [ "$_nn" = neobanshee ]; then speakers() { - argc 0 "$0" "$@" || return + argc -eq 0 "$0" "$@" || return _M_PROCESS="highpass=311,$_M_KILL,$_M_NEO,alimiter=level_in=2" } speakers @@ -55,7 +55,7 @@ if [ "$_nn" = banshee ]; then getladspa crap_eq_const_T420 _M_SPEAKERS="$REPLY" speakers() { - argc 0 "$0" "$@" || return + argc -eq 0 "$0" "$@" || return _M_PROCESS="$_M_LEVEL,$_M_SPEAKERS,alimiter=level_in=0.5" } speakers @@ -65,7 +65,7 @@ unset _nn mpv_watch() { ### @- ### watch something in mpv with a bunch of extra audio filtering crap. - argc +1 "$0" "$@" || return + argc -ge 1 "$0" "$@" || return pushd ~/play >/dev/null local url="$1"; shift mpv \ @@ -77,7 +77,7 @@ mpv_watch() { ### @- mpv_stream() { ### @- ### watch a stream in mpv with a bunch of extra audio filtering crap. - argc +1 "$0" "$@" || return + argc -ge 1 "$0" "$@" || return pushd ~/play >/dev/null local url="$1"; shift mpvs --af=lavfi="[$_M_PROCESS]" "$@" "$url" @@ -86,7 +86,7 @@ mpv_stream() { ### @- twitch() { ### @- ### watch a twitch stream in mpv with a bunch of extra audio filtering crap. - argc +1 "$0" "$@" || return + argc -ge 1 "$0" "$@" || return local user="$1"; shift mpv_stream "http://twitch.tv/$user" "$@" } @@ -97,7 +97,7 @@ yt() { ### @- ### remaining arguments are passed to mpv. ### ### there exist several variants for more specific use cases. - argc +1 "$0" "$@" || return + argc -ge 1 "$0" "$@" || return local vid="$1"; shift [ -e "$vid" ] || [ "$vid" != "${vid#http}" ] || vid="ytdl://$vid" mpv_watch "$vid" "$@" @@ -105,7 +105,7 @@ yt() { ### @- ytg() { ### @- ### watch a youtube video. like `yt`, but with a preference for different formats. - argc +1 "$0" "$@" || return + argc -ge 1 "$0" "$@" || return local vid="$1"; shift yt "$vid" --ytdl-format=22/95/300/best "$@" } @@ -113,26 +113,26 @@ ytg() { ### @- ytll() { ### @- ### watch a stream on youtube in mpv, etcetera etcetera. ### this is the low latency version that does not support seeking. - argc +1 "$0" "$@" || return + argc -ge 1 "$0" "$@" || return youtube-dl -q -f best "$1" -o - | mpv_stream - --no-ytdl } ytgll() { ### @- ### watch a stream on youtube in mpv. like `ytll`, but with a preference for different formats. - argc +1 "$0" "$@" || return + argc -ge 1 "$0" "$@" || return youtube-dl -q -f 22/95/300/best "$1" -o - | mpv_stream - --no-ytdl } ai() { # @- # hai domo! - argc +1 "$0" "$@" || return + argc -ge 1 "$0" "$@" || return yt "$@" --slang=en --sub-font='Tekton Pro' --sub-bold=yes \ --sub-font-size=60 --sub-border-color='#DD6180' --sub-margin-y=52 } asmr() { # @- # for your aural pleasure. - argc +1 "$0" "$@" || return + argc -ge 1 "$0" "$@" || return _M_PROCESS="acompressor=threshold=0.001:ratio=1.33:attack=900:release=6000:makeup=6:knee=8:mix=0.9,alimiter" \ yt "$@" --volume=90 --ytdl-format=251/300/best }