]> git.tuebingen.mpg.de Git - gsu.git/blob - funcs/gsu
gsu: Make man a generic gsu command.
[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 tilde_signs="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
139         local com num
140
141         echo "$gsu_self (_${gsu_banner_txt}_) manual"
142         echo "${equal_signs:0:${#gsu_self} + ${#gsu_banner_txt} + 16}"
143         echo
144
145         sed -e '1,/^#\{70,\}/d' -e '/^#\{70,\}/,$d' $0 -e 's/^# *//'
146         echo "----"
147         echo
148         echo "$gsu_self usage"
149         echo "${minus_signs:0:${#gsu_self} + 6}"
150         printf "\t"
151         gsu_usage 2>&1
152         echo "Each command has its own set of options as described below."
153         echo
154         echo "----"
155         echo
156         echo "Available commands:"
157
158         gsu_available_commands
159         for com in $result; do
160                 num=${#com}
161                 if test $num -lt 4; then
162                         num=4
163                 fi
164                 echo "${minus_signs:0:$num}"
165                 echo "$com"
166                 echo "${minus_signs:0:$num}"
167                 $0 help $com
168                 echo
169         done
170         ret=$GSU_SUCCESS
171 }
172 export -f com_man
173
174 export gsu_help_txt="
175 Print online help.
176
177 Usage: help [command]
178
179 Without arguments, print the list of available commands. Otherwise,
180 print the help text for the given command."
181
182 com_help()
183 {
184         local a b
185         if test -z "$1"; then
186                 gsu_banner_msg 2>&1
187                 gsu_usage 2>&1
188                 # sed is magic, baby
189                 (printf "com_help()\n$gsu_help_txt" | head -n 4; echo "--"
190                 printf "com_man()\n$gsu_man_txt" | head -n 4; echo "--"
191
192                 grep -A 2 "^com_\([a-zA-Z_0-9]\+\)()" $0) \
193                         | grep -v -- '--' \
194                         | sed -e '/^com_\([a-zA-Z_0-9]\+\)()/bs' \
195                                 -e 'H;$!d;x;s/\n//g;b' \
196                                 -e :s \
197                                 -e 'x;s/\n//g;${p;x;}' \
198                         | sed -e 's/^com_\([a-zA-Z_0-9]\+\)()#*/\1\t/' \
199                         | sort \
200                         | while read a b; do
201                                 printf "$a\t"
202                                 if test ${#a} -lt 8; then
203                                         printf "\t"
204                                 fi
205                                 echo "$b"
206                         done
207                 echo
208                 echo "Try $gsu_self help <command> for info on <command>."
209                 ret=$GSU_SUCCESS
210                 return
211         fi
212         if test "$1" = "help"; then
213                 echo "$gsu_help_txt"
214                 ret=$GSU_SUCCESS
215                 return
216         fi
217         if test "$1" = "man"; then
218                 echo "$gsu_man_txt"
219                 ret=$GSU_SUCCESS
220                 return
221         fi
222         ret=$GSU_SUCCESS
223         if grep -q "^com_$1()" $0; then
224                 sed -e "1,/com_$1()/d" -e '/^{/,$d' -e 's/^## *//' $0
225                 return
226         fi
227         gsu_print_available_commands
228         result="$1"
229         ret=-$E_GSU_BAD_COMMAND
230 }
231 export -f com_help
232
233 gsu()
234 {
235         local i
236
237         gsu_self="$(basename $0)"
238         gsu_init_errors
239         gsu_available_commands
240         gsu_cmds="$result"
241         if test $# -eq 0; then
242                 gsu_usage
243                 gsu_print_available_commands
244                 exit 1
245         fi
246         arg="$1"
247         shift
248         for i in $gsu_cmds; do
249                 if test "$arg" = "$i"; then
250                         com_$arg "$@"
251                         if test $ret -lt 0; then
252                                 gsu_err_msg
253                                 exit 1
254                         fi
255                         exit 0
256                 fi
257         done
258         ret=-$E_GSU_BAD_COMMAND
259         result="$arg"
260         gsu_err_msg
261         gsu_print_available_commands
262         exit 1
263 }
264 # no need to export this