gsu: Change semantics of gsu_check_arg_count().
[gsu.git] / funcs / gsu
index 18b7c13e0774cd62c6d52e2c07670f0fd6709615..b409bc50bc75d50969d60a800c0710358c34c2d9 100644 (file)
--- a/funcs/gsu
+++ b/funcs/gsu
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 # gsu -- the global subcommand utility
 # (C) 2006-2009 Andre Noll
 
@@ -14,6 +14,7 @@ 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_GSU_BAD_ARG_COUNT            invalid number of arguments
 E_NO_DEFAULT                   missing default value
 $gsu_errors
 "
@@ -44,6 +45,37 @@ gsu_is_a_number()
 }
 export -f gsu_is_a_number
 
+# Check number of arguments.
+#
+# Usage: gsu_check_arg_count <num_given> <num1> [<num2>]
+#
+# Check that <num_given> is between <num1> and <num2> inclusively.
+# If only <num1> ist given, num2 is assumed to be infinity.
+#
+# Examples:
+#      0 0 no argument allowed
+#      1 1 exactly one argument required
+#      0 2 at most two arguments admissible
+#      2   at least two arguments reqired
+#
+gsu_check_arg_count()
+{
+       ret=-$E_GSU_BAD_ARG_COUNT
+       if [[ $# -eq 2 ]]; then # only num1 is given
+               result="at least $2 args required, $1 given"
+               [[ $1 -lt $2 ]] && return
+               ret=$GSU_SUCCESS
+               return
+       fi
+       # num1 and num2 given
+       result="need at least $2 args, $1 given"
+       [[ $1 -lt $2 ]] && return
+       result="need at most $3 args, $1 given"
+       [[ $1 -gt $3 ]] && return
+       ret=$GSU_SUCCESS
+}
+export -f gsu_check_arg_count
+
 gsu_short_msg()
 {
        echo "$1" 1>&2
@@ -62,6 +94,8 @@ gsu_date_msg()
 }
 export -f gsu_date_msg
 
+
+
 _gsu_banner_msg()
 {
        local txt="*** $_gsu_self --"
@@ -149,7 +183,7 @@ com_prefs()
                local name= option_type= default_value= required=
                local description= help_text=
                eval "${gsu_options[$i]}"
-               eval val='"$'${gsu_name}_$name'"'
+               eval val='"$'${gsu_config_var_prefix}_$name'"'
                case "$required" in
                true|yes)
                        printf "# required"
@@ -163,6 +197,7 @@ com_prefs()
                        printf " [$default_value]"
                fi
                echo
+               [[ -n "$help_text" ]] && sed -e '/^[    ]*$/d; s/^[     ]*/#    /g' <<< "$help_text"
                printf "$name=$val"
                [[ "$val" == "$default_value" ]] && printf " # default"
                echo
@@ -283,27 +318,39 @@ export -f com_help
 # for errors and parses the config file.
 _gsu_check_options()
 {
-       local i conf="${gsu_config_file:=$HOME/.$gsu_name.rc}"
+       local i conf="${gsu_config_file:=$HOME/.$gsu_name.rc}" val
+
+       for ((i=0; i < ${#gsu_options[@]}; i++)); do
+               eval "${gsu_options[$i]}"
+               eval val='"'\$$name'"'
+               eval orig_${gsu_config_var_prefix}_$name='"'${val}'"'
+       done
 
        [[ -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
+               local val orig_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"
+               result="name: '$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'"'
+               eval orig_val='"'\$orig_${gsu_config_var_prefix}_$name'"'
+               if [[ -z "$orig_val" ]]; then
+                       eval val='"'\$$name'"'
+               else
+                       val="$orig_val"
+               fi
                case "$required" in
                true|yes)
                        ret=-$E_GSU_NEED_VALUE
@@ -318,8 +365,7 @@ _gsu_check_options()
                        return
                esac
 
-               eval ${gsu_name}_$name='"'${val:=$default_value}'"'
-
+               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
@@ -330,7 +376,7 @@ _gsu_check_options()
                        [[ $ret -lt 0 ]] && return
                        ;;
                *)
-                       ret=-$E_BAD_OPTION_TYPE
+                       ret=-$E_GSU_BAD_OPTION_TYPE
                        result="$name/$option_type"
                        return
                esac
@@ -344,11 +390,15 @@ gsu()
        local i
 
        _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
-               gsu_err_msg
-               exit 1
+               if [[ "$1" != "help" && "$1" != "man" ]]; then
+                       gsu_err_msg
+                       exit 1
+               fi
        fi
        _gsu_available_commands
        gsu_cmds="$result"