2 # (C) 2006-2011 Andre Noll
4 if [[ "$(type -t _gsu_setup)" != "function" ]]; then
5 gsu_dir=${gsu_dir:-${BASH_SOURCE[0]%/*}}
6 . $gsu_dir/common || exit 1
12 gsu_short_msg "# Usage: $_gsu_self command [options]"
15 # Return an extended regular expression to match against $0.
17 # When called without argument, the expression matches all lines which define a
20 # If an argument is given, the returned expression matches only the subcommand
21 # passed as $1. This is useful to tell if a string is a valid subcommand.
23 # Regardless of whether an argument is given, the returned expression contains
24 # exactly one parenthesized subexpression for matching the command name.
25 _gsu_get_command_regex()
27 local cmd="${1:-[-a-zA-Z_0-9]+}"
28 result="^com_($cmd)\(\)"
31 _gsu_available_commands()
35 _gsu_get_command_regex
38 printf "help\nman\nprefs\ncomplete\n"
40 # if line matches, isolate command name
43 # if there is a match, (print it and) start next cycle
49 } | sort | tr '\n' ' ')"
52 _gsu_print_available_commands()
55 gsu_short_msg "Available commands:"
56 for i in $gsu_cmds; do
59 if test $(($count % 4)) -eq 0; then
63 if test ${#i} -lt 8; then
72 gsu_complete_options()
74 local opts="$1" cword="$2" cur opt
79 cur="${words[$cword]}"
81 [[ ! "$cur" == -* ]] && return
84 for ((i=0; i < ${#opts}; i++)); do
86 [[ "$opt" == ":" ]] && continue
92 export gsu_prefs_txt="
93 Print the current preferences.
97 If -e is given, the config file is opened with the default editor. Without
98 options, the command prints out a list of all cmt config variables, together
99 with their current value and the default value."
102 local i conf="${gsu_config_file:=${HOME:-}/.$gsu_name.rc}"
106 (($ret < 0)) && return
107 gsu_check_arg_count $# 0 0
108 (($ret < 0)) && return
110 if [[ "$o_e" == "true" ]]; then
114 [[ $? -ne 0 ]] && return
116 result="${EDITOR:-vi}"
118 [[ $? -ne 0 ]] && return
123 for ((i=0; i < ${#gsu_options[@]}; i++)); do
124 local name= option_type= default_value= required=
125 local description= help_text=
126 eval "${gsu_options[$i]}"
127 eval val='"${'${gsu_config_var_prefix}_$name:-'}"'
136 printf " $option_type: $description"
137 if [[ "$required" != "yes" && "$required" != "true" ]]; then
138 printf " [$default_value]"
141 [[ -n "$help_text" ]] && sed -e '/^[ ]*$/d; s/^[ ]*/# /g' <<< "$help_text"
143 [[ "$val" == "$default_value" ]] && printf " # default"
150 gsu_complete_options "e" "$@"
160 local equal_signs="=================================================="
161 local minus_signs="--------------------------------------------------"
164 echo "$_gsu_self (_${gsu_banner_txt}_) manual"
165 echo "${equal_signs:0:${#_gsu_self} + ${#gsu_banner_txt} + 16}"
168 sed -e '1,/^#\{70,\}/d' -e '/^#\{70,\}/,$d' $0 -e 's/^# *//'
171 echo "$_gsu_self usage"
172 echo "${minus_signs:0:${#_gsu_self} + 6}"
175 echo "Each command has its own set of options as described below."
179 echo "Available commands:"
181 _gsu_available_commands
182 for com in $result; do
184 if test $num -lt 4; then
187 echo "${minus_signs:0:$num}"
189 echo "${minus_signs:0:$num}"
198 gsu_short_msg "### $_gsu_self -- ###"
201 export gsu_help_txt="
204 Usage: help [command]
206 Without arguments, print the list of available commands. Otherwise,
207 print the help text for the given command."
209 export gsu_complete_txt="
210 Command line completion.
212 Usage: complete [<cword> <word>...]
214 When executed without argument the command writes bash code to
215 stdout. This code is suitable to be evaled from .bashrc to enable
218 If at least one argument is given, all possible completions are
219 written to stdout. This can be used from the completion function of
225 local a b ere tab=' '
227 _gsu_get_command_regex
234 printf "com_help()\n$gsu_help_txt" | head -n 4; echo "--"
235 printf "com_man()\n$gsu_man_txt" | head -n 4; echo "--"
236 printf "com_prefs()\n$gsu_prefs_txt" | head -n 4; echo "--"
237 printf "com_complete()\n$gsu_complete_txt" | head -n 4; echo "--"
239 } | grep -v -- '--' \
240 | sed -En "/$ere/"'!d
241 # remove everything but the command name
242 s/^com_(.*)\(\).*/\1/
244 # append tab after short commands (less than 8 chars)
245 s/^(.{1,7})$/\1'"$tab"'/g
247 # remove next line (should contain only ## anyway)
251 # append next line, removing leading ##
255 # replace newline by tab
258 # and print the sucker
261 echo "# Try $_gsu_self help <command> for info on <command>."
265 if test "$1" = "help"; then
270 if test "$1" = "man"; then
275 if test "$1" = "prefs"; then
276 echo "$gsu_prefs_txt"
280 if test "$1" = "complete"; then
281 echo "$gsu_complete_txt"
286 _gsu_get_command_regex "$1"
288 if ! grep -Eq "$ere" $0; then
289 _gsu_print_available_commands
291 ret=-$E_GSU_BAD_COMMAND
295 # only consider lines in the comment of the function
301 # if it did start with ##, jump to label p and print it
304 # otherwise, move on to next line
316 _gsu_available_commands
320 # Wrapper for the bash getopts builtin.
322 # Aborts on programming errors such as missing or invalid option string. On
323 # success $result contains shell code that can be eval'ed. For each defined
324 # option x, the local variable o_x will be created when calling eval "$result".
325 # o_x contains true/false for options without argument and either the emtpy
326 # string or the given argument for options that take an argument.
329 # gsu_getopts abc:x:y
331 # (($ret < 0)) && return
333 # [[ "$o_a" = 'true' ]] && echo 'The -a flag was given'
334 # [[ -n "$o_c" ]] && echo "The -c option was given with arg $o_c"
337 local i c tab=' ' cr='
340 gsu_check_arg_count $# 1 1
341 if [[ $ret -lt 0 ]]; then
347 result="invalid optstring $1"
348 if [[ -z "$1" ]] || grep -q '::' <<< "$1" ; then
353 for ((i=0; i < ${#1}; i++)); do
359 result="invalid character $c in optstring"
364 result="local _gsu_getopts_opt"
365 for ((i=0; i < ${#1}; i++)); do
367 c2=${1:$(($i + 1)):1}
369 if [[ "$c2" = ":" ]]; then
377 while getopts $1 _gsu_getopts_opt \"\$@\"; do
378 case \"\$_gsu_getopts_opt\" in
380 for ((i=0; i < ${#1}; i++)); do
382 c2=${1:$(($i + 1)):1}
383 result+="$tab$tab$c1) o_$c1="
384 if [[ "$c2" = ":" ]]; then
385 result+="\"\$OPTARG\""
395 result=\"invalid option given\"
400 shift \$((\$OPTIND - 1))
412 local cur="\${COMP_WORDS[\$COMP_CWORD]}";
415 candidates=(\$($0 complete "\$COMP_CWORD" "\${COMP_WORDS[@]}"));
416 COMPREPLY=(\$(compgen -W "\${candidates[*]}" -- "\$cur"));
423 gsu_is_a_number "$cword"
424 (($ret < 0)) && return
425 if (($cword <= 1)); then
426 _gsu_available_commands
434 ret=$GSU_SUCCESS # It's not an error if no completer was defined
435 [[ "$(type -t complete_$cmd)" != "function" ]] && return
436 complete_$cmd "$cword" "${words[@]}"
437 # ignore errors, they would only clutter the completion output
441 # Find out if the current word is a parameter for an option.
443 # $1: usual getopts option string.
444 # $2: The current word number.
445 # $3..: All words of the current command line.
447 # return: If yes, $result contains the letter of the option for which the
448 # current word is a parameter. Otherwise, $result is empty.
450 gsu_cword_is_option_parameter()
452 local opts="$1" cword="$2" prev i n
456 (($cword == 0)) && return
457 ((${#opts} < 2)) && return
461 prev="${words[$(($cword - 1))]}"
462 [[ ! "$prev" == -* ]] && return
465 for ((i=0; i <= $n; i++)); do
467 [[ "${opts:$(($i + 1)):1}" != ":" ]] && continue
469 [[ "$prev" != "-$opt" ]] && continue
476 # Get the word number on which the cursor is, not counting options.
478 # This is useful for completing commands whose possible completions depend
479 # on the word number, for example mount.
481 # $1: Getopt option string.
482 # $2: The current word number.
483 # $3..: All words of the current command line.
485 # return: If the current word is an option, or a parameter to an option,
486 # this function sets $result to -1. Otherwise, the number of the non-option
487 # is returned in $result.
489 gsu_get_unnamed_arg_num()
491 local opts="$1" cword="$2" prev cur
497 cur="${words[$cword]}"
498 prev="${words[$(($cword - 1))]}"
500 [[ "$cur" == -* ]] && return
501 [[ "$prev" == -* ]] && [[ "$opts" == *${prev#-}:* ]] && return
503 for ((i=1; i <= $cword; i++)); do
504 prev="${words[$(($i - 1))]}"
506 [[ "$cur" == -* ]] && continue
507 if [[ "$prev" == -* ]]; then
509 [[ "$opts" != *$opt:* ]] && let n++
517 # Entry point for all gsu-based scripts.
519 # The startup part of the application script should source this file to load
520 # the functions defined here, and then call gsu(). Functions starting with com_
521 # are automatically recognized as subcommands.
529 # gsu_dir=${gsu_dir:-/system/location/where/gsu/is/installed}
530 # . $gsu_dir/subcommand || exit 1
535 _gsu_available_commands
537 if test $# -eq 0; then
539 _gsu_print_available_commands
544 # check internal commands
545 if [[ "$arg" = "help" || "$arg" = "man" || "$arg" = "prefs" || "$arg" = "complete" ]]; then
547 if [[ "$ret" -lt 0 ]]; then
555 for i in $gsu_cmds; do
556 if test "$arg" = "$i"; then
558 if [[ "$ret" -lt 0 ]]; then
566 ret=-$E_GSU_BAD_COMMAND
569 _gsu_print_available_commands
573 # Check number of arguments.
575 # Usage: gsu_check_arg_count <num_given> <num1> [<num2>]
577 # Check that <num_given> is between <num1> and <num2> inclusively.
578 # If only <num1> ist given, num2 is assumed to be infinity.
581 # 0 0 no argument allowed
582 # 1 1 exactly one argument required
583 # 0 2 at most two arguments admissible
584 # 2 at least two arguments reqired
586 gsu_check_arg_count()
588 ret=-$E_GSU_BAD_ARG_COUNT
589 if [[ $# -eq 2 ]]; then # only num1 is given
590 result="at least $2 args required, $1 given"
591 [[ $1 -lt $2 ]] && return
595 # num1 and num2 given
596 result="need at least $2 args, $1 given"
597 [[ $1 -lt $2 ]] && return
598 result="need at most $3 args, $1 given"
599 [[ $1 -gt $3 ]] && return