X-Git-Url: http://git.tuebingen.mpg.de/?a=blobdiff_plain;f=funcs%2Fgsu;fp=funcs%2Fgsu;h=0000000000000000000000000000000000000000;hb=d84fb61667757b1e62b915781357e10693ce8a9e;hp=1a35fca523b5084455e2a25c24e87fcbe0e08d97;hpb=279c1ab1336b67b144d39f1d0bbd256cd4510b20;p=gsu.git diff --git a/funcs/gsu b/funcs/gsu deleted file mode 100644 index 1a35fca..0000000 --- a/funcs/gsu +++ /dev/null @@ -1,544 +0,0 @@ -#!/bin/bash -# gsu -- the global subcommand utility -# (C) 2006-2011 Andre Noll - -_gsu_init_errors() -{ - gsu_errors=" -GSU_SUCCESS success -E_GSU_BAD_COMMAND invalid command -E_GSU_NOT_A_NUMBER not a number -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_GSU_EDITOR failed to execute editor -E_GSU_MKDIR failed to create directory -E_GSU_GETOPTS getopts error -$gsu_errors -" - local a b i=0 - while read a b; do - if test -z "$a"; then - continue - fi - #echo "a:$a, b: $b" - gsu_error_txt[i]="$b" - eval $a=$i - i=$(($i + 1)) - done << EOF - $gsu_errors -EOF -} -export -f _gsu_init_errors - -# check if $1 is a number -gsu_is_a_number() -{ - result="$1" - if test "$1" -eq "$1" &> /dev/null; then - ret=$GSU_SUCCESS - else - ret=-$E_GSU_NOT_A_NUMBER - fi -} -export -f gsu_is_a_number - -# Check number of arguments. -# -# Usage: gsu_check_arg_count [] -# -# Check that is between and inclusively. -# If only 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 -} -export -f gsu_short_msg - -gsu_msg() -{ - gsu_short_msg "$_gsu_self: $1" -} -export -f gsu_msg - -gsu_date_msg() -{ - gsu_short_msg "$_gsu_self $(date): $1" -} -export -f gsu_date_msg - - - -_gsu_banner_msg() -{ - local txt="### $_gsu_self --" - if test -z "$gsu_banner_txt"; then - txt="$txt set \$gsu_banner_txt to customize this message" - else - txt="$txt $gsu_banner_txt" - fi - gsu_short_msg "$txt ###" -} -export -f _gsu_banner_msg - -gsu_err_msg() -{ - local txt="$result" err - - gsu_is_a_number "$ret" - if test $ret -lt 0; then - gsu_msg "unknown error ($ret:$txt)" - exit 1 - fi - if test $result -ge 0; then - gsu_msg "unknown error ($result:$txt)" - exit 1 - fi - err=$((0 - $result)) - if test -n "$txt"; then - txt="$txt: ${gsu_error_txt[$err]}" - else - txt="${gsu_error_txt[$err]}" - fi - gsu_msg "$txt" -} -export -f gsu_err_msg - -_gsu_usage() -{ - gsu_short_msg "# Usage: $_gsu_self command [options]" -} -export -f _gsu_usage - -# Each line matching this is recognized as a subcommand. The name -# of the subcommand is the first subexpression. -export gsu_command_regex='^com_\([-a-zA-Z_0-9]\+\)()' - -_gsu_available_commands() -{ - result="$({ - printf "help\nman\nprefs\n" - sed -ne "s/$gsu_command_regex/\1/g;T;p" $0 - } | sort | tr '\n' ' ')" -} -export -f _gsu_available_commands - -_gsu_print_available_commands() -{( - local i count - gsu_short_msg "Available commands:" - for i in $gsu_cmds; do - printf "$i" - count=$(($count + 1)) - if test $(($count % 4)) -eq 0; then - echo - else - printf "\t" - if test ${#i} -lt 8; then - printf "\t" - fi - fi - done - echo -) 2>&1 -} -export -f _gsu_print_available_commands - -export gsu_prefs_txt=" -Print the current preferences. - -Usage: prefs [-e] - -If -e is given, the config file is opened with the default editor. Without -options, the command prints out a list of all cmt config variables, together -with their current value and the default value." -_com_prefs() -{ - local i conf="${gsu_config_file:=$HOME/.$gsu_name.rc}" - - if [[ "$1" = "-e" ]]; then - ret=-$E_GSU_MKDIR - result="${conf%/*}" - mkdir -p "$result" - [[ $? -ne 0 ]] && return - ret=-$E_GSU_EDITOR - result="${EDITOR:-vi}" - "$result" "$conf" - [[ $? -ne 0 ]] && return - ret=$GSU_SUCCESS - return - fi - - 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 - [[ -n "$help_text" ]] && sed -e '/^[ ]*$/d; s/^[ ]*/# /g' <<< "$help_text" - printf "$name=$val" - [[ "$val" == "$default_value" ]] && printf " # default" - echo - done -} -export -f _com_prefs - -export gsu_man_txt=" -Print the manual. - -Usage: man" - -_com_man() -{ - local equal_signs="==================================================" - local minus_signs="--------------------------------------------------" - local com num - - 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}" - printf "\t" - _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 - for com in $result; do - num=${#com} - if test $num -lt 4; then - num=4 - fi - echo "${minus_signs:0:$num}" - echo "$com" - echo "${minus_signs:0:$num}" - $0 help $com - echo - done - ret=$GSU_SUCCESS -} -export -f _com_man - -export gsu_help_txt=" -Print online help. - -Usage: help [command] - -Without arguments, print the list of available commands. Otherwise, -print the help text for the given command." - -_com_help() -{ - local a b - if test -z "$1"; then - _gsu_banner_msg 2>&1 - _gsu_usage 2>&1 - { - 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 "$gsu_command_regex" $0 - } | grep -v -- '--' \ - | sed -e "/$gsu_command_regex/bs" \ - -e 'H;$!d;x;s/\n//g;b' \ - -e :s \ - -e 'x;s/\n//g;${p;x;}' \ - | sed -e "s/${gsu_command_regex}#*/\1\t/" \ - | sort \ - | while read a b; do - printf "$a\t" - if test ${#a} -lt 8; then - printf "\t" - fi - echo "$b" - done - echo - echo "# Try $_gsu_self help for info on ." - ret=$GSU_SUCCESS - return - fi - if test "$1" = "help"; then - echo "$gsu_help_txt" - ret=$GSU_SUCCESS - return - fi - if test "$1" = "man"; then - echo "$gsu_man_txt" - 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 - 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}" 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 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: '$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 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 - 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 - -# Wrapper for bash's getopts. -# -# Aborts on programming errors such as missing or invalid option string. On -# success $result contains shell code that can be eval'ed. For each defined -# option x, the local variable o_x will be created when calling eval "$result". -# o_x contains true/false for options without an argument or the emtpy string/the -# given argument, depending on whether this option was contained in the "$@" -# array. -# -# Example: -# gsu_getopts abc:x:y -# eval "$result" -# [[ $ret -lt 0 ]] && return -# -# [[ "$o_a" = "true ]] && echo "The -a flag was given" -# [[ -n "$o_c" ]] && echo "The -c option was given with arg $o_c" -gsu_getopts() -{ - local i c tab=' ' cr=' -' - - gsu_check_arg_count $# 1 1 - if [[ $ret -lt 0 ]]; then - gsu_err_msg - exit 1 - fi - - ret=-$E_GSU_GETOPTS - result="invalid optstring $1" - if [[ -z "$1" ]] || grep -q '::' <<< "$1" ; then - gsu_err_msg - exit 1 - fi - - for ((i=0; i < ${#1}; i++)); do - c=${1:$i:1} - case "$c" in - [a-zA-Z:]);; - *) - ret=-$E_GSU_GETOPTS - result="invalid character $c in optstring" - gsu_err_msg - exit 1 - esac - done - result="local opt" - for ((i=0; i < ${#1}; i++)); do - c1=${1:$i:1} - c2=${1:$(($i + 1)):1} - result+=" o_$c1" - if [[ "$c2" = ":" ]]; then - let i++ - else - result+="=false" - fi - done - result+=" - OPTIND=1 - while getopts $1 opt \"\$@\"; do - case \"\$opt\" in -" - for ((i=0; i < ${#1}; i++)); do - c1=${1:$i:1} - c2=${1:$(($i + 1)):1} - result+="$tab$tab$c1) o_$c1=" - if [[ "$c2" = ":" ]]; then - result+="\"\$OPTARG\"" - let i++ - else - result+="true" - fi - result+=";;$cr" - done - result+=" - *) - ret=-\$E_GSU_GETOPTS - result=\"invalid option given\" - return - ;; - esac - done - shift \$((\$OPTIND - 1)) -" - ret=$GSU_SUCCESS -} -export -f gsu_getopts - -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 - if [[ "$1" != "help" && "$1" != "man" ]]; 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 - exit 1 - fi - arg="$1" - shift - # check internal commands - if [[ "$arg" = "help" || "$arg" = "man" || "$arg" = "prefs" ]]; then - _com_$arg "$@" - if [[ "$ret" -lt 0 ]]; then - gsu_err_msg - exit 1 - fi - exit 0 - fi - - # external commands - for i in $gsu_cmds; do - if test "$arg" = "$i"; then - com_$arg "$@" - if [[ "$ret" -lt 0 ]]; then - gsu_err_msg - exit 1 - fi - exit 0 - fi - done - - ret=-$E_GSU_BAD_COMMAND - result="$arg" - gsu_err_msg - _gsu_print_available_commands - exit 1 -} -export -f gsu - -# TODO: gsu_strerror: get error string