server: Convert com_addatt() to lopsub.
[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 cmd_handler_name()
166 {
167 result="com_$name_txt,"
168 }
169
170 make_array_member()
171 {
172 local TAB=' ' CR='
173 '
174 local tmp
175
176 result="{.name = \"$name_txt\", .handler = com_$name_txt, "
177 if test -n "$perms_txt"; then
178 result="$result .perms = $perms_txt,"
179 fi
180 result="$result.description = \"$desc_txt\", .usage = \"$usage_txt\", \\$CR .help = "
181 tmp="$(printf "%s\n" "$help_txt" | sed -e 's/^/\"/g' -e 's/$/\\n\"/g' \
182 -e "s/$TAB/\\\t/g" -e's/$/\\/g')"
183 result="$result$tmp$CR}, \\$CR"
184 }
185
186 make_completion()
187 {
188 local CR='
189 '
190 result=" {.name = \"$name_txt\", .completer = ${name_txt}_completer}, \\$CR"
191 }
192
193 template_loop()
194 {
195 local loop_result=
196
197 local t_name="$name_txt"
198 local t_perms="$perms_txt"
199 local t_desc="$desc_txt"
200 local t_usage="$usage_txt"
201 local t_help="$help_txt"
202 local t_source_files="$source_files"
203 local member
204 for member in $template_members; do
205 name_txt="${t_name//@member@/$member}"
206 perms_txt="${t_perms//@member@/$member}"
207 desc_txt="${t_desc//@member@/$member}"
208 usage_txt="${t_usage//@member@/$member}"
209 help_txt="${t_help//@member@/$member}"
210 prototype="${template_prototype//@member@/$member}"
211 result=
212 $1
213 loop_result="$loop_result$result"
214 done
215 result="$loop_result"
216 # reset global variables
217 name_txt="$t_name"
218 perms_txt="$t_perms"
219 desc_txt="$t_desc"
220 usage_txt="$t_usage"
221 help_txt="$t_help"
222 source_files="$t_source_files"
223 }
224
225 com_header()
226 {
227 local array_members handlers= CR='
228 '
229
230 while : ; do
231 read_one_command
232 if test $ret -lt 0; then
233 exit 1
234 fi
235 if test $ret -eq 0; then
236 break
237 fi
238 if test $template -eq 0; then
239 cmd_handler_name
240 handlers+="$result"
241 make_array_member
242 array_members="$array_members$result"
243 continue
244 fi
245 template_loop cmd_handler_name
246 handlers+="$result"
247 template_loop make_array_member
248 array_members="$array_members$result"
249 done
250 array_members="$array_members{.name = NULL} \\$CR"
251 echo "#define DEFINE_${base_name^^}_CMD_ARRAY $array_members"
252 echo "#define ${base_name^^}_COMMAND_HANDLERS ${handlers%,}"
253 }
254
255 com_completion()
256 {
257
258 echo "#define $1 \\"
259 while : ; do
260 read_one_command
261 if test $ret -lt 0; then
262 exit 1
263 fi
264 if test $ret -eq 0; then
265 break
266 fi
267 if test $template -eq 0; then
268 make_completion
269 printf "%s" "$result"
270 continue
271 fi
272 template_loop make_completion
273 printf "%s" "$result"
274 done
275 echo
276 }
277
278 read_header
279 arg="$1"
280 shift
281 case "$arg" in
282 "h")
283 com_header
284 ;;
285 "man")
286 com_man $*
287 ;;
288 "compl")
289 com_completion $*
290 ;;
291 esac