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