gsu: print $(basename $0) instead of $0 on help output.
[gsu.git] / funcs / gsu
1 #!/bin/bash
2 # gsu -- the global subcommand utility
3 # (C) 2006-2007 Andre Noll
4
5 gsu_init_errors()
6 {
7 gsu_errors="
8 GSU_SUCCESS success
9 E_GSU_BAD_COMMAND invalid command
10 E_GSU_NOT_A_NUMBER not a number
11 $gsu_errors
12 "
13 local a b i
14 local i=0
15 while read a b; do
16 if test -z "$a"; then
17 continue
18 fi
19 #echo "a:$a, b: $b"
20 gsu_error_txt[i]="$b"
21 eval $a=$i
22 i=$((i + 1))
23 done << EOF
24 $gsu_errors
25 EOF
26 }
27 export -f gsu_init_errors
28
29 # check if $1 is a number
30 gsu_is_a_number()
31 {
32 result="$1"
33 if test "$1" -eq "$1" &> /dev/null; then
34 ret=$GSU_SUCCESS
35 else
36 ret=-$E_GSU_NOT_A_NUMBER
37 fi
38 }
39 export -f gsu_is_a_number
40
41 gsu_short_msg()
42 {
43 echo "$1" 1>&2
44 }
45 export -f gsu_short_msg
46
47 gsu_msg()
48 {
49 gsu_short_msg "$gsu_self: $1"
50 }
51 export -f gsu_msg
52
53 gsu_date_msg()
54 {
55 gsu_short_msg "$gsu_self $(date): $1"
56 }
57 export -f gsu_date_msg
58
59 gsu_banner_msg()
60 {
61 local txt="*** $gsu_self --"
62 if test -z "$gsu_banner_txt"; then
63 txt="$txt set \$gsu_banner_txt to customize this message"
64 else
65 txt="$txt $gsu_banner_txt"
66 fi
67 gsu_short_msg "$txt ***"
68 }
69 export -f gsu_banner_msg
70
71 gsu_err_msg()
72 {
73 local txt="$result" err
74
75 gsu_is_a_number "$ret"
76 if test $ret -lt 0; then
77 gsu_msg "unknown error ($ret:$txt)"
78 exit 1
79 fi
80 if test $result -ge 0; then
81 gsu_msg "unknown error ($result:$txt)"
82 exit 1
83 fi
84 err=$((0 - $result))
85 if test -n "$txt"; then
86 txt="$txt: ${gsu_error_txt[$err]}"
87 else
88 txt="${gsu_error_txt[$err]}"
89 fi
90 echo "$gsu_self: $txt" 1>&2
91 }
92 export -f gsu_err_msg
93
94 gsu_usage()
95 {
96 gsu_short_msg "Usage: $gsu_self command [options]"
97 }
98 export -f gsu_usage
99
100 export gsu_help_txt="
101 Print online help.
102
103 Usage: help [command]
104
105 Without arguments, print the list of available commands. Otherwise,
106 print the help text for the given command."
107 com_help()
108 {
109 local a b
110 if test -z "$1"; then
111 gsu_banner_msg
112 gsu_usage
113 # sed is magic, baby
114 grep -A 2 "^com_\([a-zA-Z_0-9]\+\)()" $0 \
115 | grep -v -- '--' \
116 | sed -e '/^com_\([a-zA-Z_0-9]\+\)()/bs' \
117 -e 'H;$!d;x;s/\n//g;b' \
118 -e :s \
119 -e 'x;s/\n//g;${p;x;}' \
120 | sed -e 's/^com_\([a-zA-Z_0-9]\+\)()#*/\1\t/' \
121 | sort \
122 | while read a b; do
123 echo -en "$a\t"
124 if test ${#a} -lt 8; then
125 echo -en "\t"
126 fi
127 echo "$b"
128 done
129 echo
130 gsu_msg "Try $gsu_self help <command> for info on <command>."
131 ret=$GSU_SUCCESS
132 return
133 fi
134 if test "$1" = "help"; then
135 gsu_short_msg "$gsu_help_txt"
136 ret=$GSU_SUCCESS
137 return
138 fi
139 ret=$GSU_SUCCESS
140 if grep -q "^com_$1()" $0; then
141 sed -e "1,/com_$1()/d" -e '/^{/,$d' -e 's/^## *//' $0
142 return
143 fi
144 gsu_print_available_commands
145 result="$1"
146 ret=-$E_GSU_BAD_COMMAND
147 }
148 export -f com_help
149
150 gsu_available_commands()
151 {
152 result="$( (echo help; grep "^com_[a-z_]\+()" $0) \
153 | sed -e 's/^com_//' -e 's/()//' \
154 | sort \
155 | tr '\n' ' ')"
156 ret=$SUCCESS
157 }
158 export -f gsu_available_commands
159
160 gsu_print_available_commands()
161 {(
162 local i count
163 gsu_short_msg "Available commands:"
164 for i in $gsu_cmds; do
165 printf "$i"
166 count=$((count + 1))
167 if test $((count % 4)) -eq 0; then
168 echo
169 else
170 printf "\t"
171 if test ${#i} -lt 8; then
172 printf "\t"
173 fi
174 fi
175 done
176 echo
177 ) 2>&1
178 }
179 export -f gsu_print_available_commands
180
181 gsu()
182 {
183 gsu_self="$(basename $0)"
184 gsu_init_errors
185 gsu_available_commands
186 gsu_cmds="$result"
187 if test $# -eq 0; then
188 gsu_usage
189 gsu_print_available_commands
190 exit 1
191 fi
192 arg="$1"
193 shift
194 for i in $gsu_cmds; do
195 if test "$arg" = "$i"; then
196 com_$arg $*
197 if test $ret -lt 0; then
198 gsu_err_msg
199 exit 1
200 fi
201 exit 0
202 fi
203 done
204 ret=-$E_GSU_BAD_COMMAND
205 result="$arg"
206 gsu_err_msg
207 gsu_print_available_commands
208 exit 1
209 }
210 # no need to export this