audiod: Force status dump on slot changes.
[paraslash.git] / command_util.bash
1 #!/usr/bin/env bash
2
3 read_header()
4 {
5         local key value i
6
7         while read key value; do
8                 case "$key" in
9                 ---)
10                         break
11                         ;;
12                 BN:)
13                         base_name="$value"
14                         ;;
15                 SF:)
16                         source_files="$value"
17                         ;;
18                 SN:)
19                         section_name="$value"
20                         ;;
21                 TM:)
22                         template_members="$value"
23                 esac
24         done
25 }
26
27 read_one_command()
28 {
29         local line
30
31         name_txt=""
32         desc_txt=""
33         usage_txt=""
34         help_txt=""
35         perms_txt=""
36         template=0
37         template_name=""
38         template_prototype=""
39         while read key value; do
40                 case "$key" in
41                 ---)
42                         break
43                         ;;
44                 N:)
45                         name_txt="$value"
46                         ;;
47                 T:)
48                         template_name="$value"
49                         template=1
50                         ;;
51                 O:)
52                         template_prototype="$value"
53                         template=1
54                         ;;
55                 P:)
56                         perms_txt="$value"
57                         ;;
58                 D:)
59                         desc_txt="$value"
60                         ;;
61                 U:)
62                         usage_txt="$value"
63                         ;;
64                 H:)
65                         help_txt="${value}"
66                         while read line; do
67                                 if test "$line" = "---"; then
68                                         break;
69                                 fi
70                                 line=${line#H:}
71                                 help_txt="$help_txt
72 ${line# }"
73                         done
74                         break
75                         ;;
76                 esac
77         done
78         if test $template -eq 0; then
79                 if test -n "$name_txt" -a -n "$desc_txt" -a -n "$usage_txt" \
80                                 -a -n "$help_txt"; then
81                         ret=1
82                         return
83                 fi
84         else
85                 if test -n "$template_name" -a -n "$template_prototype" \
86                                 -a -n "$name_txt " -a -n "$template_members" \
87                                 -a -n "$desc_txt" -a -n "$usage_txt" \
88                                 -a -n "$help_txt"; then
89                         ret=1
90                         return
91                 fi
92         fi
93         if test -z "$name_txt" -a -z "$desc_txt" -a -z "$usage_txt" \
94                         -a -z "$help_txt"; then
95                 ret=0
96                 return
97         fi
98         ret=-1
99         #return
100         echo "!ERROR!"
101         echo "N: $name_txt"
102         echo "D: $desc_txt"
103         echo "S: $usage_txt"
104         echo "P: $perms_txt"
105         echo "H: $help_txt"
106         echo "O: $template_prototype"
107 }
108
109 dump_man()
110 {
111         if test $template -eq 0; then
112                 echo ".SS \"$name_txt\""
113                 echo "$desc_txt"
114                 echo
115                 echo "\\fBUsage: \\fP$usage_txt"
116         else
117                 for member in $template_members; do
118                         local sed_cmd="sed -e s/@member@/$member/g"
119                         local t_name_txt=$(echo $name_txt | $sed_cmd)
120                         echo ".SS \"$t_name_txt\""
121                 done
122                 echo "$desc_txt" | sed -e "s/@member@/{$(echo $template_members | sed -e 's/ / | /g')}/g"
123                 echo
124                 echo "\\fBUsage: \\fP"
125                 echo
126                 echo ".nf"
127                 for member in $template_members; do
128                         local sed_cmd="sed -e s/@member@/$member/g"
129                         local t_usage_txt=$(echo $usage_txt | $sed_cmd)
130                         printf "\t$t_usage_txt\n"
131                 done
132                 echo ".fi"
133         fi
134         echo
135         echo "$help_txt" | sed -e 's/^  //'
136         echo
137         if test -n "$perms_txt"; then
138                 echo -n "\\fBpermissions:\\fP "
139                 if test "$perms_txt" = "0"; then
140                         echo "(none)"
141                 else
142                         echo "$perms_txt"
143                 fi
144         fi
145         echo
146 }
147
148
149 com_man()
150 {
151         echo "[$section_name]"
152         echo
153         while : ; do
154                 read_one_command
155                 if test $ret -lt 0; then
156                         exit 1
157                 fi
158                 if test $ret -eq 0; then
159                         break
160                 fi
161                 dump_man
162         done
163 }
164
165 cmd_handler_name()
166 {
167         result="com_$name_txt,"
168 }
169
170 make_array_member()
171 {
172         local TAB='     ' CR='
173 '
174         local tmp
175
176         result="{.name = \"$name_txt\", .handler = com_$name_txt, "
177         if test -n "$perms_txt"; then
178                 result="$result .perms = $perms_txt,"
179         fi
180         result="$result.description = \"$desc_txt\", .usage = \"$usage_txt\", \\$CR .help = "
181         tmp="$(printf "%s\n" "$help_txt" | sed -e 's/^/\"/g' -e 's/$/\\n\"/g' \
182                 -e "s/$TAB/\\\t/g" -e's/$/\\/g')"
183         result="$result$tmp$CR}, \\$CR"
184 }
185
186 make_completion()
187 {
188         local CR='
189 '
190         result="  {.name = \"$name_txt\", .completer = ${name_txt}_completer}, \\$CR"
191 }
192
193 template_loop()
194 {
195         local loop_result=
196
197         local t_name="$name_txt"
198         local t_perms="$perms_txt"
199         local t_desc="$desc_txt"
200         local t_usage="$usage_txt"
201         local t_help="$help_txt"
202         local t_source_files="$source_files"
203         local member
204         for member in $template_members; do
205                 name_txt="${t_name//@member@/$member}"
206                 perms_txt="${t_perms//@member@/$member}"
207                 desc_txt="${t_desc//@member@/$member}"
208                 usage_txt="${t_usage//@member@/$member}"
209                 help_txt="${t_help//@member@/$member}"
210                 prototype="${template_prototype//@member@/$member}"
211                 result=
212                 $1
213                 loop_result="$loop_result$result"
214         done
215         result="$loop_result"
216         # reset global variables
217         name_txt="$t_name"
218         perms_txt="$t_perms"
219         desc_txt="$t_desc"
220         usage_txt="$t_usage"
221         help_txt="$t_help"
222         source_files="$t_source_files"
223 }
224
225 com_header()
226 {
227         local array_members handlers= CR='
228 '
229
230         while : ; do
231                 read_one_command
232                 if test $ret -lt 0; then
233                         exit 1
234                 fi
235                 if test $ret -eq 0; then
236                         break
237                 fi
238                 if test $template -eq 0; then
239                         cmd_handler_name
240                         handlers+="$result"
241                         make_array_member
242                         array_members="$array_members$result"
243                         continue
244                 fi
245                 template_loop cmd_handler_name
246                 handlers+="$result"
247                 template_loop make_array_member
248                 array_members="$array_members$result"
249         done
250         array_members="$array_members{.name = NULL} \\$CR"
251         echo "#define DEFINE_${base_name^^}_CMD_ARRAY $array_members"
252         echo "#define ${base_name^^}_COMMAND_HANDLERS ${handlers%,}"
253 }
254
255 com_completion()
256 {
257
258         echo "#define $1 \\"
259         while : ; do
260                 read_one_command
261                 if test $ret -lt 0; then
262                         exit 1
263                 fi
264                 if test $ret -eq 0; then
265                         break
266                 fi
267                 if test $template -eq 0; then
268                         make_completion
269                         printf "%s" "$result"
270                         continue
271                 fi
272                 template_loop make_completion
273                 printf "%s" "$result"
274         done
275         echo
276 }
277
278 read_header
279 arg="$1"
280 shift
281 case "$arg" in
282         "h")
283                 com_header
284                 ;;
285         "man")
286                 com_man $*
287                 ;;
288         "compl")
289                 com_completion $*
290                 ;;
291 esac