Define XOPEN_SOURCE and __EXTENSIONS__ on Solaris.
[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"
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" "$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