command_util: Write array definition in header mode.
[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 BN:)
14 base_name="$value"
15 ;;
16 OF:)
17 output_file="$value"
18 array_name=${value%command_list}cmds
19 ;;
20 SF:)
21 source_files="$value"
22 ;;
23 AT:)
24 array_type="$value"
25 ;;
26 SI:)
27 for i in $value; do
28 system_includes="$system_includes
29 #include <$i.h>"
30 done
31 ;;
32 IN:)
33 for i in $value; do
34 includes="$includes
35 #include \"$i.h\""
36 done
37 includes="$includes
38 #include \"$output_file.h\""
39 ;;
40 SN:)
41 section_name="$value"
42 ;;
43 TM:)
44 template_members="$value"
45 esac
46 done
47 if test -z "$output_file"; then
48 echo "header error" 1&>2
49 exit 1
50 fi
51 }
52
53 read_one_command()
54 {
55 local line
56
57 name_txt=""
58 desc_txt=""
59 usage_txt=""
60 help_txt=""
61 perms_txt=""
62 template=0
63 template_name=""
64 template_prototype=""
65 mkdir -p man/man1
66 while read key value; do
67 case "$key" in
68 ---)
69 break
70 ;;
71 N:)
72 name_txt="$value"
73 ;;
74 T:)
75 template_name="$value"
76 template=1
77 ;;
78 O:)
79 template_prototype="$value"
80 template=1
81 ;;
82 P:)
83 perms_txt="$value"
84 ;;
85 D:)
86 desc_txt="$value"
87 ;;
88 U:)
89 usage_txt="$value"
90 ;;
91 H:)
92 help_txt="${value}"
93 while read line; do
94 if test "$line" = "---"; then
95 break;
96 fi
97 line=${line#H:}
98 help_txt="$help_txt
99 ${line# }"
100 done
101 break
102 ;;
103 esac
104 done
105 if test $template -eq 0; then
106 if test -n "$name_txt" -a -n "$desc_txt" -a -n "$usage_txt" \
107 -a -n "$help_txt"; then
108 ret=1
109 return
110 fi
111 else
112 if test -n "$template_name" -a -n "$template_prototype" \
113 -a -n "$name_txt " -a -n "$template_members" \
114 -a -n "$desc_txt" -a -n "$usage_txt" \
115 -a -n "$help_txt"; then
116 ret=1
117 return
118 fi
119 fi
120 if test -z "$name_txt" -a -z "$desc_txt" -a -z "$usage_txt" \
121 -a -z "$help_txt"; then
122 ret=0
123 return
124 fi
125 ret=-1
126 #return
127 echo "!ERROR!"
128 echo "N: $name_txt"
129 echo "D: $desc_txt"
130 echo "S: $usage_txt"
131 echo "P: $perms_txt"
132 echo "H: $help_txt"
133 echo "O: $template_prototype"
134 }
135
136 dump_man()
137 {
138 if test $template -eq 0; then
139 echo ".SS \"$name_txt\""
140 echo "$desc_txt"
141 echo
142 echo "\\fBUsage: \\fP$usage_txt"
143 else
144 for member in $template_members; do
145 local sed_cmd="sed -e s/@member@/$member/g"
146 local t_name_txt=$(echo $name_txt | $sed_cmd)
147 echo ".SS \"$t_name_txt\""
148 done
149 echo "$desc_txt" | sed -e "s/@member@/{$(echo $template_members | sed -e 's/ / | /g')}/g"
150 echo
151 echo "\\fBUsage: \\fP"
152 echo
153 echo ".nf"
154 for member in $template_members; do
155 local sed_cmd="sed -e s/@member@/$member/g"
156 local t_usage_txt=$(echo $usage_txt | $sed_cmd)
157 printf "\t$t_usage_txt\n"
158 done
159 echo ".fi"
160 fi
161 echo
162 echo "$help_txt" | sed -e 's/^ //'
163 echo
164 if test -n "$perms_txt"; then
165 echo -n "\\fBpermissions:\\fP "
166 if test "$perms_txt" = "0"; then
167 echo "(none)"
168 else
169 echo "$perms_txt"
170 fi
171 fi
172 echo
173 }
174
175
176 com_man()
177 {
178 echo "[$section_name]"
179 echo
180 while : ; do
181 read_one_command
182 if test $ret -lt 0; then
183 exit 1
184 fi
185 if test $ret -eq 0; then
186 break
187 fi
188 dump_man
189 done
190 }
191
192 make_proto()
193 {
194 local source_file match="" CR='
195 '
196 if test -n "$prototype"; then
197 result="$prototype$CR"
198 return
199 fi
200 result=
201 for source_file in $source_files; do
202 match=$(grep "^\(__noreturn \)*int com_$name_txt(" $source_file | head -n 1 | sed -e 's/$/;/1')
203 if test -n "$match"; then
204 result="$result$match$CR"
205 break
206 fi
207 done
208 }
209
210 make_array_member()
211 {
212 local TAB=' ' CR='
213 '
214 local tmp
215
216 result="{.name = \"$name_txt\", .handler = com_$name_txt, "
217 if test -n "$perms_txt"; then
218 result="$result .perms = $perms_txt,"
219 fi
220 result="$result.description = \"$desc_txt\", .usage = \"$usage_txt\", \\$CR .help = "
221 tmp="$(printf "%s\n" "$help_txt" | sed -e 's/^/\"/g' -e 's/$/\\n\"/g' \
222 -e "s/$TAB/\\\t/g" -e's/$/\\/g')"
223 result="$result$tmp$CR}, \\$CR"
224 }
225
226 make_completion()
227 {
228 local CR='
229 '
230 result=" {.name = \"$name_txt\", .completer = ${name_txt}_completer}, \\$CR"
231 }
232
233 template_loop()
234 {
235 local loop_result=
236
237 local t_name="$name_txt"
238 local t_perms="$perms_txt"
239 local t_desc="$desc_txt"
240 local t_usage="$usage_txt"
241 local t_help="$help_txt"
242 local t_source_files="$source_files"
243 local member
244 for member in $template_members; do
245 local sed_cmd="sed -e s/@member@/$member/g"
246 #echo "sed_cmd: $sed_cmd"
247 name_txt=$(echo "$t_name" | $sed_cmd)
248 #name_txt="$tname"
249 perms_txt=$(echo "$t_perms" | $sed_cmd)
250 desc_txt=$(echo "$t_desc" | $sed_cmd)
251 usage_txt=$(echo "$t_usage" | $sed_cmd)
252 help_txt=$(printf "%s\n" "$t_help" | $sed_cmd)
253 prototype=$(echo "$template_prototype" | $sed_cmd)
254 result=
255 $1
256 loop_result="$loop_result$result"
257 done
258 result="$loop_result"
259 # reset global variables
260 name_txt="$t_name"
261 perms_txt="$t_perms"
262 desc_txt="$t_desc"
263 usage_txt="$t_usage"
264 help_txt="$t_help"
265 source_files="$t_source_files"
266 }
267
268 com_c_file()
269 {
270 echo "$system_includes"
271 echo "$includes"
272 echo "struct $array_type $array_name[] = {"
273 while : ; do
274 read_one_command
275 if test $ret -lt 0; then
276 exit 1
277 fi
278 if test $ret -eq 0; then
279 break
280 fi
281 if test $template -eq 0; then
282 make_array_member
283 printf "%s" "$result"
284 continue
285 fi
286 template_loop make_array_member
287 printf "%s" "$result"
288 done
289 echo '{.name = NULL}};'
290 }
291
292 com_header()
293 {
294 local array_members CR='
295 '
296
297 echo "extern struct $array_type $array_name[];"
298 while : ; do
299 read_one_command
300 if test $ret -lt 0; then
301 exit 1
302 fi
303 if test $ret -eq 0; then
304 break
305 fi
306 if test $template -eq 0; then
307 make_proto
308 printf "%s" "$result"
309 make_array_member
310 array_members="$array_members$result"
311 continue
312 fi
313 template_loop make_proto
314 printf "%s" "$result"
315 template_loop make_array_member
316 array_members="$array_members$result"
317 done
318 array_members="$array_members{.name = NULL} \\$CR"
319 echo "#define DEFINE_$(tr 'a-z' 'A-Z' <<< "$base_name")_CMD_ARRAY $array_members"
320 }
321
322 com_completion()
323 {
324
325 echo "#define $1 \\"
326 while : ; do
327 read_one_command
328 if test $ret -lt 0; then
329 exit 1
330 fi
331 if test $ret -eq 0; then
332 break
333 fi
334 if test $template -eq 0; then
335 make_completion
336 printf "%s" "$result"
337 continue
338 fi
339 template_loop make_completion
340 printf "%s" "$result"
341 done
342 echo
343 }
344
345 read_header
346 arg="$1"
347 shift
348 case "$arg" in
349 "c")
350 com_c_file
351 ;;
352 "h")
353 com_header
354 ;;
355 "man")
356 com_man $*
357 ;;
358 "compl")
359 com_completion $*
360 ;;
361 esac