From ee39f37ff22194ed45ec5d470f36b52f316d98d9 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Wed, 10 Jun 2009 16:48:47 +0200 Subject: [PATCH] Priliminary version of gsu2. Backwards compatible, new features are only used by dpch yet. --- funcs/gsu | 154 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 112 insertions(+), 42 deletions(-) diff --git a/funcs/gsu b/funcs/gsu index 9611b30..81066f7 100644 --- a/funcs/gsu +++ b/funcs/gsu @@ -10,6 +10,11 @@ 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 @@ -100,7 +105,7 @@ export -f _gsu_usage _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' ' ')" @@ -129,6 +134,42 @@ _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_name}_$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. @@ -190,6 +231,7 @@ com_help() # 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 -- '--' \ @@ -221,6 +263,11 @@ 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 @@ -232,51 +279,68 @@ com_help() } export -f com_help -_gsu_init_config() +# internal gsu function that syntactically checks the gsu_options array +# for errors and parses the config file. +_gsu_check_options() { - local name val default_val required ty comment + local i conf="${gsu_config_file:=$HOME/.$gsu_name.rc}" - # set default values - while read name default_val required ty comment; do - if test -z "$name"; then - continue - fi - eval ${gsu_self}_$name="$default_val" - done << EOF - $gsu_config_vars -EOF - result="$HOME/.${gsu_self}rc" - # overwrite by custom configuration - if [ -r "$result" ]; then - ret=-$E_GSU_SOURCE - if ! . "$result"; then - gsu_err_msg - exit 1 - fi - fi - while read name default_val required ty comment; do - [ -z "$name" ] && continue - eval val="\$$name" - # abort if any required config var remains unset - ret=-$_E_GSU_CONFIG - if [ "$val" = "-" -a "$required" = "required" ]; then + [[ -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" - gsu_err_msg - exit 1 - fi - if [ $ty == "number" ]; then + [[ -z "$val" ]] && return + ;; + false|no) + ret=-$E_NO_DEFAULT + result="$name" + [[ -z "$default_value" ]] && return + ;; + *) + ret=-$E_GSU_BAD_BOOL + result="required: $required, name: $name, val: $val" + return + esac + + eval ${gsu_name}_$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" - if [ $ret -lt 0]; then - gsu_err_msg - exit 1 - fi - fi - eval export ${gsu_self}_$name - done << EOF - $config_vars -EOF + [[ $ret -lt 0 ]] && return + ;; + *) + ret=-$E_BAD_OPTION_TYPE + result="$name/$option_type" + return + esac + done + ret=$GSU_SUCCESS } -export -f _gsu_init_config +export -f _gsu_check_options gsu() { @@ -284,7 +348,11 @@ gsu() _gsu_self="$(basename $0)" _gsu_init_errors - _gsu_init_config + _gsu_check_options + if [[ "$ret" -lt 0 ]]; then + gsu_err_msg + exit 1 + fi _gsu_available_commands gsu_cmds="$result" if test $# -eq 0; then @@ -311,3 +379,5 @@ gsu() exit 1 } export -f gsu + +# TODO: gsu_strerror: get error string -- 2.30.2