Merge branch 'refs/heads/t/tarball-build-fix'
[paraslash.git] / command_util.bash
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