X-Git-Url: http://git.tuebingen.mpg.de/?p=gsu.git;a=blobdiff_plain;f=funcs%2Fgsu;h=9ee2d72442d4b0694f4c151559c2b383cdf860e0;hp=37092a3985ee835768dbfc5ec7d4fd2fcd68f572;hb=7cc3cdb5fc9245ea8654411098c859b6d928be42;hpb=8cc5100ff6c21522e400e5d9ab6317829382add0 diff --git a/funcs/gsu b/funcs/gsu index 37092a3..9ee2d72 100644 --- a/funcs/gsu +++ b/funcs/gsu @@ -1,12 +1,20 @@ +#!/bin/sh # gsu -- the global subcommand utility -# (C) 2006-2007 Andre Noll +# (C) 2006-2009 Andre Noll -gsu_init_errors() +_gsu_init_errors() { gsu_errors=" GSU_SUCCESS success E_GSU_BAD_COMMAND invalid command E_GSU_NOT_A_NUMBER not a number +E_GSU_SOURCE error in config file +E_GSU_CONFIG bad/missing config file option +E_GSU_BAD_CONFIG_VAR invalid config variable +E_GSU_NEED_VALUE value required but not given +E_GSU_BAD_BOOL bad value for boolian option +E_GSU_BAD_OPTION_TYPE invalid option type +E_NO_DEFAULT missing default value $gsu_errors " local a b i=0 @@ -22,7 +30,7 @@ $gsu_errors $gsu_errors EOF } -export -f gsu_init_errors +export -f _gsu_init_errors # check if $1 is a number gsu_is_a_number() @@ -44,19 +52,19 @@ export -f gsu_short_msg gsu_msg() { - gsu_short_msg "$gsu_self: $1" + gsu_short_msg "$_gsu_self: $1" } export -f gsu_msg gsu_date_msg() { - gsu_short_msg "$gsu_self $(date): $1" + gsu_short_msg "$_gsu_self $(date): $1" } export -f gsu_date_msg -gsu_banner_msg() +_gsu_banner_msg() { - local txt="*** $gsu_self --" + local txt="*** $_gsu_self --" if test -z "$gsu_banner_txt"; then txt="$txt set \$gsu_banner_txt to customize this message" else @@ -64,7 +72,7 @@ gsu_banner_msg() fi gsu_short_msg "$txt ***" } -export -f gsu_banner_msg +export -f _gsu_banner_msg gsu_err_msg() { @@ -89,23 +97,23 @@ gsu_err_msg() } export -f gsu_err_msg -gsu_usage() +_gsu_usage() { - gsu_short_msg "Usage: $gsu_self command [options]" + gsu_short_msg "Usage: $_gsu_self command [options]" } -export -f gsu_usage +export -f _gsu_usage -gsu_available_commands() +_gsu_available_commands() { - result="$( (printf "help\nman\n"; grep "^com_[a-z_]\+()" $0) \ + result="$( (printf "help\nman\nprefs\n"; grep "^com_[a-z_]\+()" $0) \ | sed -e 's/^com_//' -e 's/()//' \ | sort \ | tr '\n' ' ')" ret=$GSU_SUCCESS } -export -f gsu_available_commands +export -f _gsu_available_commands -gsu_print_available_commands() +_gsu_print_available_commands() {( local i count gsu_short_msg "Available commands:" @@ -124,7 +132,43 @@ gsu_print_available_commands() echo ) 2>&1 } -export -f gsu_print_available_commands +export -f _gsu_print_available_commands + +export gsu_prefs_txt=" +Print the current preferences. + +Usage: prefs + +Print out a list of all cmt config variables, together with their current value +and the default value." +com_prefs() +{ + local i + + for ((i=0; i < ${#gsu_options[@]}; i++)); do + local name= option_type= default_value= required= + local description= help_text= + eval "${gsu_options[$i]}" + eval val='"$'${gsu_config_var_prefix}_$name'"' + case "$required" in + true|yes) + printf "# required" + ;; + *) + printf "# optional" + ;; + esac + printf " $option_type: $description" + if [[ "$required" != "yes" && "$required" != "true" ]]; then + printf " [$default_value]" + fi + echo + printf "$name=$val" + [[ "$val" == "$default_value" ]] && printf " # default" + echo + done +} +export -f com_prefs export gsu_man_txt=" Print the manual. @@ -137,24 +181,24 @@ com_man() local minus_signs="--------------------------------------------------" local com num - echo "$gsu_self (_${gsu_banner_txt}_) manual" - echo "${equal_signs:0:${#gsu_self} + ${#gsu_banner_txt} + 16}" + echo "$_gsu_self (_${gsu_banner_txt}_) manual" + echo "${equal_signs:0:${#_gsu_self} + ${#gsu_banner_txt} + 16}" echo sed -e '1,/^#\{70,\}/d' -e '/^#\{70,\}/,$d' $0 -e 's/^# *//' echo "----" echo - echo "$gsu_self usage" - echo "${minus_signs:0:${#gsu_self} + 6}" + echo "$_gsu_self usage" + echo "${minus_signs:0:${#_gsu_self} + 6}" printf "\t" - gsu_usage 2>&1 + _gsu_usage 2>&1 echo "Each command has its own set of options as described below." echo echo "----" echo echo "Available commands:" - gsu_available_commands + _gsu_available_commands for com in $result; do num=${#com} if test $num -lt 4; then @@ -182,11 +226,12 @@ com_help() { local a b if test -z "$1"; then - gsu_banner_msg 2>&1 - gsu_usage 2>&1 + _gsu_banner_msg 2>&1 + _gsu_usage 2>&1 # sed is magic, baby (printf "com_help()\n$gsu_help_txt" | head -n 4; echo "--" printf "com_man()\n$gsu_man_txt" | head -n 4; echo "--" + printf "com_prefs()\n$gsu_prefs_txt" | head -n 4; echo "--" grep -A 2 "^com_\([a-zA-Z_0-9]\+\)()" $0) \ | grep -v -- '--' \ @@ -204,7 +249,7 @@ com_help() echo "$b" done echo - echo "Try $gsu_self help for info on ." + echo "Try $_gsu_self help for info on ." ret=$GSU_SUCCESS return fi @@ -218,28 +263,103 @@ com_help() ret=$GSU_SUCCESS return fi + if test "$1" = "prefs"; then + echo "$gsu_prefs_txt" + ret=$GSU_SUCCESS + return + fi ret=$GSU_SUCCESS if grep -q "^com_$1()" $0; then sed -e "1,/com_$1()/d" -e '/^{/,$d' -e 's/^## *//' $0 return fi - gsu_print_available_commands + _gsu_print_available_commands result="$1" ret=-$E_GSU_BAD_COMMAND } export -f com_help +# internal gsu function that syntactically checks the gsu_options array +# for errors and parses the config file. +_gsu_check_options() +{ + local i conf="${gsu_config_file:=$HOME/.$gsu_name.rc}" + + [[ -r "$conf" ]] && source "$conf" + + for ((i=0; i < ${#gsu_options[@]}; i++)); do + local name= option_type= default_value= required= + local description= help_text= + local val + + eval "${gsu_options[$i]}" + + + # Check name. It must be non-empty and consist of [a-zA-Z_0-9] + # only. Moreover it must not start with [a-zA-Z]. + + ret=-$E_GSU_BAD_CONFIG_VAR + result="$name" + # bash's =~ works only for 3.2 and newer, so use grep + echo "$name" | grep '^[a-zA-Z][a-zA-Z_0123456789]*$' &> /dev/null; + [[ $? -ne 0 ]] && return + + eval val='"'\$$name'"' + case "$required" in + true|yes) + ret=-$E_GSU_NEED_VALUE + result="$name" + [[ -z "$val" ]] && return + ;; + false|no) + ;; + *) + ret=-$E_GSU_BAD_BOOL + result="required: $required, name: $name, val: $val" + return + esac + + eval ${gsu_config_var_prefix}_$name='"'${val:=$default_value}'"' + + # Check option type. ATM, only num and string are supported + # Other types may be added without breaking compatibility + case "$option_type" in + string) + ;; + num) + gsu_is_a_number "$val" + [[ $ret -lt 0 ]] && return + ;; + *) + ret=-$E_GSU_BAD_OPTION_TYPE + result="$name/$option_type" + return + esac + done + ret=$GSU_SUCCESS +} +export -f _gsu_check_options + gsu() { local i - gsu_self="$(basename $0)" - gsu_init_errors - gsu_available_commands + _gsu_self="$(basename $0)" + gsu_name="${gsu_name:=$_gsu_self}" + gsu_config_var_prefix="${gsu_config_var_prefix:=$gsu_name}" + _gsu_init_errors + _gsu_check_options + if [[ "$ret" -lt 0 ]]; then + if [[ "$1" != "help" && "$1" != "man" && "$1" != "prefs" ]]; then + gsu_err_msg + exit 1 + fi + fi + _gsu_available_commands gsu_cmds="$result" if test $# -eq 0; then - gsu_usage - gsu_print_available_commands + _gsu_usage + _gsu_print_available_commands exit 1 fi arg="$1" @@ -257,7 +377,9 @@ gsu() ret=-$E_GSU_BAD_COMMAND result="$arg" gsu_err_msg - gsu_print_available_commands + _gsu_print_available_commands exit 1 } -# no need to export this +export -f gsu + +# TODO: gsu_strerror: get error string