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