command_util: Fix make dependencies for *_command_list.h.
[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         mkdir -p man/man1
40         while read key value; do
41                 case "$key" in
42                 ---)
43                         break
44                         ;;
45                 N:)
46                         name_txt="$value"
47                         ;;
48                 T:)
49                         template_name="$value"
50                         template=1
51                         ;;
52                 O:)
53                         template_prototype="$value"
54                         template=1
55                         ;;
56                 P:)
57                         perms_txt="$value"
58                         ;;
59                 D:)
60                         desc_txt="$value"
61                         ;;
62                 U:)
63                         usage_txt="$value"
64                         ;;
65                 H:)
66                         help_txt="${value}"
67                         while read line; do
68                                 if test "$line" = "---"; then
69                                         break;
70                                 fi
71                                 line=${line#H:}
72                                 help_txt="$help_txt
73 ${line# }"
74                         done
75                         break
76                         ;;
77                 esac
78         done
79         if test $template -eq 0; then
80                 if test -n "$name_txt" -a -n "$desc_txt" -a -n "$usage_txt" \
81                                 -a -n "$help_txt"; then
82                         ret=1
83                         return
84                 fi
85         else
86                 if test -n "$template_name" -a -n "$template_prototype" \
87                                 -a -n "$name_txt " -a -n "$template_members" \
88                                 -a -n "$desc_txt" -a -n "$usage_txt" \
89                                 -a -n "$help_txt"; then
90                         ret=1
91                         return
92                 fi
93         fi
94         if test -z "$name_txt" -a -z "$desc_txt" -a -z "$usage_txt" \
95                         -a -z "$help_txt"; then
96                 ret=0
97                 return
98         fi
99         ret=-1
100         #return
101         echo "!ERROR!"
102         echo "N: $name_txt"
103         echo "D: $desc_txt"
104         echo "S: $usage_txt"
105         echo "P: $perms_txt"
106         echo "H: $help_txt"
107         echo "O: $template_prototype"
108 }
109
110 dump_man()
111 {
112         if test $template -eq 0; then
113                 echo ".SS \"$name_txt\""
114                 echo "$desc_txt"
115                 echo
116                 echo "\\fBUsage: \\fP$usage_txt"
117         else
118                 for member in $template_members; do
119                         local sed_cmd="sed -e s/@member@/$member/g"
120                         local t_name_txt=$(echo $name_txt | $sed_cmd)
121                         echo ".SS \"$t_name_txt\""
122                 done
123                 echo "$desc_txt" | sed -e "s/@member@/{$(echo $template_members | sed -e 's/ / | /g')}/g"
124                 echo
125                 echo "\\fBUsage: \\fP"
126                 echo
127                 echo ".nf"
128                 for member in $template_members; do
129                         local sed_cmd="sed -e s/@member@/$member/g"
130                         local t_usage_txt=$(echo $usage_txt | $sed_cmd)
131                         printf "\t$t_usage_txt\n"
132                 done
133                 echo ".fi"
134         fi
135         echo
136         echo "$help_txt" | sed -e 's/^  //'
137         echo
138         if test -n "$perms_txt"; then
139                 echo -n "\\fBpermissions:\\fP "
140                 if test "$perms_txt" = "0"; then
141                         echo "(none)"
142                 else
143                         echo "$perms_txt"
144                 fi
145         fi
146         echo
147 }
148
149
150 com_man()
151 {
152         echo "[$section_name]"
153         echo
154         while : ; do
155                 read_one_command
156                 if test $ret -lt 0; then
157                         exit 1
158                 fi
159                 if test $ret -eq 0; then
160                         break
161                 fi
162                 dump_man
163         done
164 }
165
166 make_proto()
167 {
168         local source_file match="" CR='
169 '
170         if test -n "$prototype"; then
171                 result="$prototype$CR"
172                 return
173         fi
174         result=
175         for source_file in $source_files; do
176                 match=$(grep "^\(__noreturn \)*\(static \)*int com_$name_txt(" $source_file | head -n 1 | sed -e 's/$/;/1')
177                 if test -n "$match"; then
178                         result="$result$match$CR"
179                         break
180                 fi
181         done
182 }
183
184 make_array_member()
185 {
186         local TAB='     ' CR='
187 '
188         local tmp
189
190         result="{.name = \"$name_txt\", .handler = com_$name_txt, "
191         if test -n "$perms_txt"; then
192                 result="$result .perms = $perms_txt,"
193         fi
194         result="$result.description = \"$desc_txt\", .usage = \"$usage_txt\", \\$CR .help = "
195         tmp="$(printf "%s\n" "$help_txt" | sed -e 's/^/\"/g' -e 's/$/\\n\"/g' \
196                 -e "s/$TAB/\\\t/g" -e's/$/\\/g')"
197         result="$result$tmp$CR}, \\$CR"
198 }
199
200 make_completion()
201 {
202         local CR='
203 '
204         result="  {.name = \"$name_txt\", .completer = ${name_txt}_completer}, \\$CR"
205 }
206
207 template_loop()
208 {
209         local loop_result=
210
211         local t_name="$name_txt"
212         local t_perms="$perms_txt"
213         local t_desc="$desc_txt"
214         local t_usage="$usage_txt"
215         local t_help="$help_txt"
216         local t_source_files="$source_files"
217         local member
218         for member in $template_members; do
219                 local sed_cmd="sed -e s/@member@/$member/g"
220                 #echo "sed_cmd: $sed_cmd"
221                 name_txt=$(echo "$t_name" | $sed_cmd)
222                 #name_txt="$tname"
223                 perms_txt=$(echo "$t_perms" | $sed_cmd)
224                 desc_txt=$(echo "$t_desc" | $sed_cmd)
225                 usage_txt=$(echo "$t_usage" | $sed_cmd)
226                 help_txt=$(printf "%s\n" "$t_help" | $sed_cmd)
227                 prototype=$(echo "$template_prototype" | $sed_cmd)
228                 result=
229                 $1
230                 loop_result="$loop_result$result"
231         done
232         result="$loop_result"
233         # reset global variables
234         name_txt="$t_name"
235         perms_txt="$t_perms"
236         desc_txt="$t_desc"
237         usage_txt="$t_usage"
238         help_txt="$t_help"
239         source_files="$t_source_files"
240 }
241
242 com_header()
243 {
244         local array_members CR='
245 '
246
247         while : ; do
248                 read_one_command
249                 if test $ret -lt 0; then
250                         exit 1
251                 fi
252                 if test $ret -eq 0; then
253                         break
254                 fi
255                 if test $template -eq 0; then
256                         make_proto
257                         printf "%s" "$result"
258                         make_array_member
259                         array_members="$array_members$result"
260                         continue
261                 fi
262                 template_loop make_proto
263                 printf "%s" "$result"
264                 template_loop make_array_member
265                 array_members="$array_members$result"
266         done
267         array_members="$array_members{.name = NULL} \\$CR"
268         echo "#define DEFINE_$(tr 'a-z' 'A-Z' <<< "$base_name")_CMD_ARRAY $array_members"
269 }
270
271 com_completion()
272 {
273
274         echo "#define $1 \\"
275         while : ; do
276                 read_one_command
277                 if test $ret -lt 0; then
278                         exit 1
279                 fi
280                 if test $ret -eq 0; then
281                         break
282                 fi
283                 if test $template -eq 0; then
284                         make_completion
285                         printf "%s" "$result"
286                         continue
287                 fi
288                 template_loop make_completion
289                 printf "%s" "$result"
290         done
291         echo
292 }
293
294 read_header
295 arg="$1"
296 shift
297 case "$arg" in
298         "h")
299                 com_header
300                 ;;
301         "man")
302                 com_man $*
303                 ;;
304         "compl")
305                 com_completion $*
306                 ;;
307 esac