Allow writers that have no pre_select functions.
[paraslash.git] / command_util.sh
1 #!/usr/bin/env bash
2
3
4 read_header()
5 {
6         local key value i
7
8         while read key value; do
9                 case "$key" in
10                 ---)
11                         break
12                         ;;
13                 HC:)
14                         header_comment="$value"
15                         ;;
16                 CC:)
17                         c_file_comment="$value"
18                         ;;
19                 OF:)
20                         output_file="$value"
21                         array_name=${value%command_list}cmds
22                         ;;
23                 SF:)
24                         source_files="$value"
25                         ;;
26                 AT:)
27                         array_type="$value"
28                         ;;
29                 IN:)
30                         for i in $value; do
31                                 includes="$includes
32 #include \"$i.h\""
33                         done
34                         includes="$includes
35 #include \"$output_file.h\""
36                         ;;
37                 SN:)
38                         section_name="$value"
39                         ;;
40                 TM:)
41                         template_members="$value"
42                 esac
43         done
44         if test -z "$header_comment" -o -z "$c_file_comment" \
45                         -o -z "$output_file"; then
46                 echo "header error" 1&>2
47                 exit 1
48         fi
49 }
50
51 read_one_command()
52 {
53         local line
54
55         name_txt=""
56         desc_txt=""
57         usage_txt=""
58         help_txt=""
59         perms_txt=""
60         line_handler=0
61         template=0
62         template_name=""
63         template_prototype=""
64         mkdir -p man/man1
65         while read key value; do
66                 case "$key" in
67                 ---)
68                         break
69                         ;;
70                 N:)
71                         name_txt="$value"
72                         ;;
73                 T:)
74                         template_name="$value"
75                         template=1
76                         ;;
77                 O:)
78                         template_prototype="$value"
79                         template=1
80                         ;;
81                 P:)
82                         perms_txt="$value"
83                         ;;
84                 D:)
85                         desc_txt="$value"
86                         ;;
87                 L:)
88                         line_handler=1
89                         ;;
90                 U:)
91                         usage_txt="$value"
92                         ;;
93                 H:)
94                         help_txt="${value}"
95                         while read line; do
96                                 if test "$line" = "---"; then
97                                         break;
98                                 fi
99                                 line=${line#H:}
100                                 help_txt="$help_txt
101 ${line# }"
102                         done
103                         break
104                         ;;
105                 esac
106         done
107         if test $template -eq 0; then
108                 if test -n "$name_txt" -a -n "$desc_txt" -a -n "$usage_txt" \
109                                 -a -n "$help_txt"; then
110                         ret=1
111                         return
112                 fi
113         else
114                 if test -n "$template_name" -a -n "$template_prototype" \
115                                 -a -n "$name_txt " -a -n "$template_members" \
116                                 -a -n "$desc_txt" -a -n "$usage_txt" \
117                                 -a -n "$help_txt"; then
118                         ret=1
119                         return
120                 fi
121         fi
122         if test -z "$name_txt" -a -z "$desc_txt" -a -z "$usage_txt" \
123                         -a -z "$help_txt"; then
124                 ret=0
125                 return
126         fi
127         ret=-1
128         #return
129         echo "!ERROR!"
130         echo "N: $name_txt"
131         echo "D: $desc_txt"
132         echo "S: $usage_txt"
133         echo "P: $perms_txt"
134         echo "H: $help_txt"
135         echo "O: $template_prototype"
136 }
137
138 dump_man()
139 {
140         if test $template -eq 0; then
141                 echo ".SS \"$name_txt\""
142                 echo "$desc_txt"
143                 echo
144                 echo "\\fBUsage: \\fP$usage_txt"
145         else
146                 for member in $template_members; do
147                         local sed_cmd="sed -e s/@member@/$member/g"
148                         local t_name_txt=$(echo $name_txt | $sed_cmd)
149                         echo ".SS \"$t_name_txt\""
150                 done
151                 echo "$desc_txt" | sed -e "s/@member@/{$(echo $template_members | sed -e 's/ / | /g')}/g"
152                 echo
153                 echo "\\fBUsage: \\fP"
154                 echo
155                 echo ".nf"
156                 for member in $template_members; do
157                         local sed_cmd="sed -e s/@member@/$member/g"
158                         local t_usage_txt=$(echo $usage_txt | $sed_cmd)
159                         printf "\t$t_usage_txt\n"
160                 done
161                 echo ".fi"
162         fi
163         echo
164         echo "$help_txt" | sed -e 's/^  //'
165         echo
166         if test -n "$perms_txt"; then
167                 echo -n "\\fBpermissions:\\fP "
168                 if test "$perms_txt" = "0"; then
169                         echo "(none)"
170                 else
171                         echo "$perms_txt"
172                 fi
173         fi
174         echo
175 }
176
177
178 com_man()
179 {
180         echo "[$section_name]"
181         echo
182         while : ; do
183                 read_one_command
184                 if test $ret -lt 0; then
185                         exit 1
186                 fi
187                 if test $ret -eq 0; then
188                         break
189                 fi
190                 dump_man
191         done
192 }
193
194 dump_proto()
195 {
196         local source_file match=""
197
198         echo '/**'
199         echo " * $desc_txt"
200         echo ' *'
201         echo ' * \param fd The file descriptor to send output to.'
202         if test $line_handler -eq 0; then
203                 echo ' * \param argc The number of arguments.'
204                 echo ' * \param argv The argument vector.'
205         else
206                 echo ' * \param cmdline The full command line.'
207         fi
208         echo ' * '
209         echo " * Usage: $usage_txt"
210         echo ' * '
211         echo "$help_txt" | sed -e 's/^/ * /g'
212         echo ' */'
213         if test -n "$prototype"; then
214                 echo "$prototype"
215                 echo
216                 return
217         fi
218         for source_file in $source_files; do
219                 match=$(grep "^\(__noreturn \)*int com_$name_txt(" $source_file | head -n 1 | sed -e 's/$/;/1')
220                 if test -n "$match"; then
221                         echo "$match"
222                         break
223                 fi
224         done
225         echo
226 }
227
228 dump_array_member()
229 {
230         echo '{'
231         echo ".name = \"$name_txt\","
232         if test $line_handler -eq 0; then
233                 echo ".handler = com_$name_txt,"
234         else
235                 echo ".handler = NULL,"
236                 echo ".line_handler = com_$name_txt,"
237         fi
238         if test -n "$perms_txt"; then
239                 echo ".perms = $perms_txt,"
240         fi
241         echo ".description = \"$desc_txt\","
242         echo ".usage = \"$usage_txt\","
243         echo ".help = "
244         printf "%s\n" "$help_txt" | sed -e 's/^/\"/g' -e 's/$/\\n\"/g'
245         echo '},'
246 }
247
248
249 template_loop()
250 {
251         local t_name="$name_txt"
252         local t_perms="$perms_txt"
253         local t_desc="$desc_txt"
254         local t_usage="$usage_txt"
255         local t_help="$help_txt"
256         local t_source_files="$source_files"
257         local member
258         for member in $template_members; do
259                 local sed_cmd="sed -e s/@member@/$member/g"
260                 #echo "sed_cmd: $sed_cmd"
261                 name_txt=$(echo $t_name | $sed_cmd)
262                 #name_txt="$tname"
263                 perms_txt=$(echo $t_perms | $sed_cmd)
264                 desc_txt=$(echo $t_desc | $sed_cmd)
265                 usage_txt=$(echo $t_usage | $sed_cmd)
266                 help_txt=$(printf "%s\n" "$t_help" | $sed_cmd)
267                 prototype=$(echo "$template_prototype" | $sed_cmd)
268                 $1
269         done
270
271 }
272
273 com_c_file()
274 {
275         echo "/** \file $output_file.c $c_file_comment */"
276         echo "$includes"
277         echo "struct $array_type $array_name[] = {"
278         while : ; do
279                 read_one_command
280                 if test $ret -lt 0; then
281                         exit 1
282                 fi
283                 if test $ret -eq 0; then
284                         break
285                 fi
286                 if test $template -eq 0; then
287                         dump_array_member
288                         continue
289                 fi
290                 template_loop dump_array_member
291         done
292         echo '{.name = NULL}};'
293 }
294
295 com_header()
296 {
297         echo "/** \file $output_file.h $header_comment */"
298         echo
299         echo "extern struct $array_type $array_name[];"
300         while : ; do
301                 read_one_command
302                 if test $ret -lt 0; then
303                         exit 1
304                 fi
305                 if test $ret -eq 0; then
306                         break
307                 fi
308                 if test $template -eq 0; then
309                         dump_proto
310                         continue
311                 fi
312                 template_loop dump_proto
313         done
314 }
315
316 read_header
317 arg="$1"
318 shift
319 case "$arg" in
320         "c")
321                 com_c_file
322                 ;;
323         "h")
324                 com_header
325                 ;;
326         "man")
327                 com_man $*
328                 ;;
329 esac