2 # gsu -- the global subcommand utility
3 # (C) 2006-2009 Andre Noll
9 E_GSU_BAD_COMMAND invalid command
10 E_GSU_NOT_A_NUMBER not a number
11 E_GSU_SOURCE error in config file
12 E_GSU_CONFIG bad/missing config file option
13 E_GSU_BAD_CONFIG_VAR invalid config variable
14 E_GSU_NEED_VALUE value required but not given
15 E_GSU_BAD_BOOL bad value for boolian option
16 E_GSU_BAD_OPTION_TYPE invalid option type
17 E_NO_DEFAULT missing default value
33 export -f _gsu_init_errors
35 # check if $1 is a number
39 if test "$1" -eq "$1" &> /dev/null; then
42 ret=-$E_GSU_NOT_A_NUMBER
45 export -f gsu_is_a_number
51 export -f gsu_short_msg
55 gsu_short_msg "$_gsu_self: $1"
61 gsu_short_msg "$_gsu_self $(date): $1"
63 export -f gsu_date_msg
67 local txt="*** $_gsu_self --"
68 if test -z "$gsu_banner_txt"; then
69 txt="$txt set \$gsu_banner_txt to customize this message"
71 txt="$txt $gsu_banner_txt"
73 gsu_short_msg "$txt ***"
75 export -f _gsu_banner_msg
79 local txt="$result" err
81 gsu_is_a_number "$ret"
82 if test $ret -lt 0; then
83 gsu_msg "unknown error ($ret:$txt)"
86 if test $result -ge 0; then
87 gsu_msg "unknown error ($result:$txt)"
91 if test -n "$txt"; then
92 txt="$txt: ${gsu_error_txt[$err]}"
94 txt="${gsu_error_txt[$err]}"
102 gsu_short_msg "Usage: $_gsu_self command [options]"
106 _gsu_available_commands()
108 result="$( (printf "help\nman\nprefs\n"; grep "^com_[a-z_]\+()" $0) \
109 | sed -e 's/^com_//' -e 's/()//' \
114 export -f _gsu_available_commands
116 _gsu_print_available_commands()
119 gsu_short_msg "Available commands:"
120 for i in $gsu_cmds; do
122 count=$(($count + 1))
123 if test $(($count % 4)) -eq 0; then
127 if test ${#i} -lt 8; then
135 export -f _gsu_print_available_commands
137 export gsu_prefs_txt="
138 Print the current preferences.
142 Print out a list of all cmt config variables, together with their current value
143 and the default value."
148 for ((i=0; i < ${#gsu_options[@]}; i++)); do
149 local name= option_type= default_value= required=
150 local description= help_text=
151 eval "${gsu_options[$i]}"
152 eval val='"$'${gsu_name}_$name'"'
161 printf " $option_type: $description"
162 if [[ "$required" != "yes" && "$required" != "true" ]]; then
163 printf " [$default_value]"
167 [[ "$val" == "$default_value" ]] && printf " # default"
180 local equal_signs="=================================================="
181 local minus_signs="--------------------------------------------------"
184 echo "$_gsu_self (_${gsu_banner_txt}_) manual"
185 echo "${equal_signs:0:${#_gsu_self} + ${#gsu_banner_txt} + 16}"
188 sed -e '1,/^#\{70,\}/d' -e '/^#\{70,\}/,$d' $0 -e 's/^# *//'
191 echo "$_gsu_self usage"
192 echo "${minus_signs:0:${#_gsu_self} + 6}"
195 echo "Each command has its own set of options as described below."
199 echo "Available commands:"
201 _gsu_available_commands
202 for com in $result; do
204 if test $num -lt 4; then
207 echo "${minus_signs:0:$num}"
209 echo "${minus_signs:0:$num}"
217 export gsu_help_txt="
220 Usage: help [command]
222 Without arguments, print the list of available commands. Otherwise,
223 print the help text for the given command."
228 if test -z "$1"; then
232 (printf "com_help()\n$gsu_help_txt" | head -n 4; echo "--"
233 printf "com_man()\n$gsu_man_txt" | head -n 4; echo "--"
234 printf "com_prefs()\n$gsu_prefs_txt" | head -n 4; echo "--"
236 grep -A 2 "^com_\([a-zA-Z_0-9]\+\)()" $0) \
238 | sed -e '/^com_\([a-zA-Z_0-9]\+\)()/bs' \
239 -e 'H;$!d;x;s/\n//g;b' \
241 -e 'x;s/\n//g;${p;x;}' \
242 | sed -e 's/^com_\([a-zA-Z_0-9]\+\)()#*/\1\t/' \
246 if test ${#a} -lt 8; then
252 echo "Try $_gsu_self help <command> for info on <command>."
256 if test "$1" = "help"; then
261 if test "$1" = "man"; then
266 if test "$1" = "prefs"; then
267 echo "$gsu_prefs_txt"
272 if grep -q "^com_$1()" $0; then
273 sed -e "1,/com_$1()/d" -e '/^{/,$d' -e 's/^## *//' $0
276 _gsu_print_available_commands
278 ret=-$E_GSU_BAD_COMMAND
282 # internal gsu function that syntactically checks the gsu_options array
283 # for errors and parses the config file.
286 local i conf="${gsu_config_file:=$HOME/.$gsu_name.rc}"
288 [[ -r "$conf" ]] && source "$conf"
290 for ((i=0; i < ${#gsu_options[@]}; i++)); do
291 local name= option_type= default_value= required=
292 local description= help_text=
295 eval "${gsu_options[$i]}"
297 # Check name. It must be non-empty and consist of [a-zA-Z_0-9]
298 # only. Moreover it must not start with [a-zA-Z].
300 ret=-$E_GSU_BAD_CONFIG_VAR
302 # bash's =~ works only for 3.2 and newer, so use grep
303 echo "$name" | grep '^[a-zA-Z][a-zA-Z_0123456789]*$' &> /dev/null;
304 [[ $? -ne 0 ]] && return
306 eval val='"'\$$name'"'
309 ret=-$E_GSU_NEED_VALUE
311 [[ -z "$val" ]] && return
316 [[ -z "$default_value" ]] && return
320 result="required: $required, name: $name, val: $val"
324 eval ${gsu_name}_$name='"'${val:=$default_value}'"'
326 # Check option type. ATM, only num and string are supported
327 # Other types may be added without breaking compatibility
328 case "$option_type" in
332 gsu_is_a_number "$val"
333 [[ $ret -lt 0 ]] && return
336 ret=-$E_BAD_OPTION_TYPE
337 result="$name/$option_type"
343 export -f _gsu_check_options
349 _gsu_self="$(basename $0)"
352 if [[ "$ret" -lt 0 ]]; then
356 _gsu_available_commands
358 if test $# -eq 0; then
360 _gsu_print_available_commands
365 for i in $gsu_cmds; do
366 if test "$arg" = "$i"; then
368 if test $ret -lt 0; then
375 ret=-$E_GSU_BAD_COMMAND
378 _gsu_print_available_commands
383 # TODO: gsu_strerror: get error string