time.c: Make declarations match definitions.
[paraslash.git] / command_util.sh
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 make_proto()
166 {
167         local regex='\(__noreturn \)*\(static \)*int com_'
168         local source_file match="" all_commands CR='
169 '
170         if test -n "$prototype"; then
171                 result="$prototype$CR"
172                 return
173         fi
174         all_commands="$(cat $source_files | grep "$regex")"
175         result=
176         for source_file in $source_files; do
177                 match=$(grep "$regex$name_txt(" <<< "$all_commands" | head -n 1 | sed -e 's/$/;/1')
178                 if test -n "$match"; then
179                         result="$result$match$CR"
180                         break
181                 fi
182         done
183 }
184
185 make_array_member()
186 {
187         local TAB='     ' CR='
188 '
189         local tmp
190
191         result="{.name = \"$name_txt\", .handler = com_$name_txt, "
192         if test -n "$perms_txt"; then
193                 result="$result .perms = $perms_txt,"
194         fi
195         result="$result.description = \"$desc_txt\", .usage = \"$usage_txt\", \\$CR .help = "
196         tmp="$(printf "%s\n" "$help_txt" | sed -e 's/^/\"/g' -e 's/$/\\n\"/g' \
197                 -e "s/$TAB/\\\t/g" -e's/$/\\/g')"
198         result="$result$tmp$CR}, \\$CR"
199 }
200
201 make_completion()
202 {
203         local CR='
204 '
205         result="  {.name = \"$name_txt\", .completer = ${name_txt}_completer}, \\$CR"
206 }
207
208 template_loop()
209 {
210         local loop_result=
211
212         local t_name="$name_txt"
213         local t_perms="$perms_txt"
214         local t_desc="$desc_txt"
215         local t_usage="$usage_txt"
216         local t_help="$help_txt"
217         local t_source_files="$source_files"
218         local member
219         for member in $template_members; do
220                 name_txt="${t_name//@member@/$member}"
221                 perms_txt="${t_perms//@member@/$member}"
222                 desc_txt="${t_desc//@member@/$member}"
223                 usage_txt="${t_usage//@member@/$member}"
224                 help_txt="${t_help//@member@/$member}"
225                 prototype="${template_prototype//@member@/$member}"
226                 result=
227                 $1
228                 loop_result="$loop_result$result"
229         done
230         result="$loop_result"
231         # reset global variables
232         name_txt="$t_name"
233         perms_txt="$t_perms"
234         desc_txt="$t_desc"
235         usage_txt="$t_usage"
236         help_txt="$t_help"
237         source_files="$t_source_files"
238 }
239
240 com_header()
241 {
242         local array_members CR='
243 '
244
245         while : ; do
246                 read_one_command
247                 if test $ret -lt 0; then
248                         exit 1
249                 fi
250                 if test $ret -eq 0; then
251                         break
252                 fi
253                 if test $template -eq 0; then
254                         make_proto
255                         printf "%s" "$result"
256                         make_array_member
257                         array_members="$array_members$result"
258                         continue
259                 fi
260                 template_loop make_proto
261                 printf "%s" "$result"
262                 template_loop make_array_member
263                 array_members="$array_members$result"
264         done
265         array_members="$array_members{.name = NULL} \\$CR"
266         echo "#define DEFINE_$(tr 'a-z' 'A-Z' <<< "$base_name")_CMD_ARRAY $array_members"
267 }
268
269 com_completion()
270 {
271
272         echo "#define $1 \\"
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_completion
283                         printf "%s" "$result"
284                         continue
285                 fi
286                 template_loop make_completion
287                 printf "%s" "$result"
288         done
289         echo
290 }
291
292 read_header
293 arg="$1"
294 shift
295 case "$arg" in
296         "h")
297                 com_header
298                 ;;
299         "man")
300                 com_man $*
301                 ;;
302         "compl")
303                 com_completion $*
304                 ;;
305 esac