1 /*
2 Command line processing tests
3
4 Copyright (C) Amitay Isaacs 2018
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "replace.h"
21
22 #include <popt.h>
23 #include <talloc.h>
24
25 #include <assert.h>
26
27 #include "common/cmdline.c"
28
dummy_func(TALLOC_CTX * mem_ctx,int argc,const char ** argv,void * private_data)29 static int dummy_func(TALLOC_CTX *mem_ctx,
30 int argc,
31 const char **argv,
32 void *private_data)
33 {
34 return 0;
35 }
36
37 static struct poptOption dummy_options[] = {
38 POPT_TABLEEND
39 };
40
41 static struct cmdline_command dummy_commands[] = {
42 CMDLINE_TABLEEND
43 };
44
test1(void)45 static void test1(void)
46 {
47 TALLOC_CTX *mem_ctx;
48 struct cmdline_context *cmdline;
49 int ret;
50
51 mem_ctx = talloc_new(NULL);
52 assert(mem_ctx != NULL);
53
54 ret = cmdline_init(mem_ctx, NULL, NULL, NULL, NULL, &cmdline);
55 assert(ret == EINVAL);
56
57 ret = cmdline_init(mem_ctx, "test1", NULL, NULL, NULL, &cmdline);
58 assert(ret == EINVAL);
59
60 ret = cmdline_init(mem_ctx,
61 "test1",
62 dummy_options,
63 NULL,
64 NULL,
65 &cmdline);
66 assert(ret == EINVAL);
67
68 talloc_free(mem_ctx);
69 }
70
71 static struct cmdline_command test2_nofunc[] = {
72 { "nofunc", NULL, NULL, NULL },
73 CMDLINE_TABLEEND
74 };
75
76 static struct cmdline_command test2_nohelp[] = {
77 { "nohelp", dummy_func, NULL, NULL },
78 CMDLINE_TABLEEND
79 };
80
81 static struct cmdline_command test2_long[] = {
82 { "really really long command with lots of words",
83 dummy_func, "long command help",
84 "<and lots of really long long arguments>" },
85 CMDLINE_TABLEEND
86 };
87
88 static struct cmdline_command test2_longhelp[] = {
89 { "longhelp", dummy_func,
90 "this is a really really really long help message" \
91 "with lots of words and lots of description",
92 NULL },
93 CMDLINE_TABLEEND
94 };
95
96 static struct cmdline_command test2_twowords[] = {
97 { "multiple words", dummy_func, "multiple words help", NULL },
98 CMDLINE_TABLEEND
99 };
100
test2(void)101 static void test2(void)
102 {
103 TALLOC_CTX *mem_ctx;
104 struct cmdline_context *cmdline;
105 int ret;
106
107 mem_ctx = talloc_new(NULL);
108 assert(mem_ctx != NULL);
109
110 ret = cmdline_init(mem_ctx,
111 "test2",
112 NULL,
113 NULL,
114 test2_nofunc,
115 &cmdline);
116 assert(ret == EINVAL);
117
118 ret = cmdline_init(mem_ctx,
119 "test2",
120 NULL,
121 NULL,
122 test2_nohelp,
123 &cmdline);
124 assert(ret == EINVAL);
125
126 ret = cmdline_init(mem_ctx,
127 "test2",
128 NULL,
129 NULL,
130 test2_long,
131 &cmdline);
132 assert(ret == EINVAL);
133
134 ret = cmdline_init(mem_ctx,
135 "test2",
136 NULL,
137 NULL,
138 test2_longhelp,
139 &cmdline);
140 assert(ret == EINVAL);
141
142 ret = cmdline_init(mem_ctx,
143 "test2",
144 NULL,
145 NULL,
146 test2_twowords,
147 &cmdline);
148 assert(ret == 0);
149
150 talloc_free(mem_ctx);
151 }
152
153 struct {
154 const char *str;
155 } test3_data;
156
157 static struct poptOption test3_noname[] = {
158 { NULL, 'o', POPT_ARG_STRING, &test3_data.str, 0,
159 "Noname option", NULL },
160 POPT_TABLEEND
161 };
162
163 static struct poptOption test3_notype[] = {
164 { "debug", 'd', POPT_ARG_NONE, NULL, 0,
165 "No argument option", NULL },
166 POPT_TABLEEND
167 };
168
169 static struct poptOption test3_noarg[] = {
170 { "debug", 'd', POPT_ARG_STRING, NULL, 0,
171 "No argument option", NULL },
172 POPT_TABLEEND
173 };
174
test3(void)175 static void test3(void)
176 {
177 TALLOC_CTX *mem_ctx;
178 struct cmdline_context *cmdline;
179 int ret;
180
181 mem_ctx = talloc_new(NULL);
182 assert(mem_ctx != NULL);
183
184 ret = cmdline_init(mem_ctx,
185 "test3",
186 test3_noname,
187 NULL,
188 dummy_commands,
189 &cmdline);
190 assert(ret == EINVAL);
191
192 ret = cmdline_init(mem_ctx,
193 "test3",
194 test3_notype,
195 NULL,
196 dummy_commands,
197 &cmdline);
198 assert(ret == EINVAL);
199
200 ret = cmdline_init(mem_ctx,
201 "test3",
202 test3_noarg,
203 NULL,
204 dummy_commands,
205 &cmdline);
206 assert(ret == EINVAL);
207
208 talloc_free(mem_ctx);
209 }
210
211 static int test4_count;
212 static int test4_value;
213
214 static struct poptOption test4_options[] = {
215 { "count", 'c', POPT_ARG_INT, &test4_count, 0,
216 "Option help of length thirty.", NULL },
217 { "value", 'v', POPT_ARG_INT, &test4_value, 0,
218 "Short description", "Value help of length 23" },
219 POPT_TABLEEND
220 };
221
222 static struct cmdline_command test4_commands[] = {
223 { "A really really long command", dummy_func,
224 "This is a really long help message",
225 "<a long arguments message>" },
226 { "short command", dummy_func,
227 "short msg for short command", "<short arg msg>" },
228 CMDLINE_TABLEEND
229 };
230
test4(void)231 static void test4(void)
232 {
233 TALLOC_CTX *mem_ctx;
234 struct cmdline_context *cmdline;
235 int ret;
236
237 mem_ctx = talloc_new(NULL);
238 assert(mem_ctx != NULL);
239
240 ret = cmdline_init(mem_ctx,
241 "test4",
242 test4_options,
243 NULL,
244 test4_commands,
245 &cmdline);
246 assert(ret == 0);
247
248 cmdline_usage(cmdline, NULL);
249 cmdline_usage(cmdline, "short command");
250
251 talloc_free(mem_ctx);
252 }
253
action_func(TALLOC_CTX * mem_ctx,int argc,const char ** argv,void * private_data)254 static int action_func(TALLOC_CTX *mem_ctx,
255 int argc,
256 const char **argv,
257 void *private_data)
258 {
259 if (argc != 1) {
260 return 100;
261 }
262
263 printf("%s\n", argv[0]);
264 return 200;
265 }
266
267 static struct cmdline_command action_commands[] = {
268 { "action one", dummy_func, "action one help", NULL },
269 { "action two", action_func, "action two help", NULL },
270 CMDLINE_TABLEEND
271 };
272
test5(void)273 static void test5(void)
274 {
275 TALLOC_CTX *mem_ctx;
276 struct cmdline_context *cmdline;
277 const char *argv1[] = { "test5", "--help" };
278 const char *argv2[] = { "test5", "action" };
279 const char *argv3[] = { "test5", "action", "--help" };
280 const char *argv4[] = { "test5", "action", "one" };
281 int ret;
282
283 mem_ctx = talloc_new(NULL);
284 assert(mem_ctx != NULL);
285
286 ret = cmdline_init(mem_ctx,
287 "test5",
288 NULL,
289 "Action",
290 action_commands,
291 &cmdline);
292 assert(ret == 0);
293
294 ret = cmdline_parse(cmdline, 2, argv1, true);
295 assert(ret == EAGAIN);
296
297 ret = cmdline_parse(cmdline, 2, argv2, true);
298 assert(ret == ENOENT);
299
300 ret = cmdline_parse(cmdline, 3, argv3, true);
301 assert(ret == EAGAIN);
302
303 ret = cmdline_parse(cmdline, 3, argv4, true);
304 assert(ret == 0);
305
306 talloc_free(mem_ctx);
307 }
308
test6(void)309 static void test6(void)
310 {
311 TALLOC_CTX *mem_ctx;
312 struct cmdline_context *cmdline;
313 const char *argv1[] = { "action", "two" };
314 const char *argv2[] = { "action", "two", "arg1" };
315 const char *argv3[] = { "action", "two", "arg1", "arg2" };
316 int ret, result;
317
318 mem_ctx = talloc_new(NULL);
319 assert(mem_ctx != NULL);
320
321 ret = cmdline_init(mem_ctx,
322 "test6",
323 NULL,
324 NULL,
325 action_commands,
326 &cmdline);
327 assert(ret == 0);
328
329 ret = cmdline_parse(cmdline, 2, argv1, false);
330 assert(ret == 0);
331
332 ret = cmdline_run(cmdline, NULL, &result);
333 assert(ret == 0);
334 assert(result == 100);
335
336 ret = cmdline_parse(cmdline, 3, argv2, false);
337 assert(ret == 0);
338
339 ret = cmdline_run(cmdline, NULL, &result);
340 assert(ret == 0);
341 assert(result == 200);
342
343 ret = cmdline_parse(cmdline, 4, argv3, false);
344 assert(ret == 0);
345
346 ret = cmdline_run(cmdline, NULL, &result);
347 assert(ret == 0);
348 assert(result == 100);
349
350 talloc_free(mem_ctx);
351 }
352
test7_func(TALLOC_CTX * mem_ctx,int argc,const char ** argv,void * private_data)353 static int test7_func(TALLOC_CTX *mem_ctx,
354 int argc,
355 const char **argv,
356 void *private_data)
357 {
358 assert(argc == 1);
359
360 printf("%s\n", argv[0]);
361
362 return 0;
363 }
364
365 static struct cmdline_command test7_basic_commands[] = {
366 { "cmd1", test7_func, "command one help", NULL },
367 { "cmd2", test7_func, "command two help", NULL },
368 CMDLINE_TABLEEND
369 };
370
371 static struct cmdline_command test7_advanced_commands[] = {
372 { "cmd3", test7_func, "command three help", NULL },
373 { "cmd4", test7_func, "command four help", NULL },
374 CMDLINE_TABLEEND
375 };
376
377 static struct cmdline_command test7_ultimate_commands[] = {
378 { "cmd5", test7_func, "command five help", NULL },
379 { "cmd6", test7_func, "command six help", NULL },
380 CMDLINE_TABLEEND
381 };
382
test7(void)383 static void test7(void)
384 {
385 TALLOC_CTX *mem_ctx;
386 struct cmdline_context *cmdline;
387 const char *argv1[] = { "cmd1", "one" };
388 const char *argv2[] = { "cmd3", "three" };
389 const char *argv3[] = { "cmd6", "six" };
390 int ret, result;
391
392 mem_ctx = talloc_new(NULL);
393 assert(mem_ctx != NULL);
394
395 ret = cmdline_init(mem_ctx,
396 "test7",
397 NULL,
398 "Basic",
399 test7_basic_commands,
400 &cmdline);
401 assert(ret == 0);
402
403 ret = cmdline_add(cmdline, "Advanced", test7_advanced_commands);
404 assert(ret == 0);
405
406 ret = cmdline_add(cmdline, "Ultimate", test7_ultimate_commands);
407 assert(ret == 0);
408
409 cmdline_usage(cmdline, NULL);
410
411 printf("\n");
412
413 ret = cmdline_parse(cmdline, 2, argv1, false);
414 assert(ret == 0);
415
416 ret = cmdline_run(cmdline, NULL, &result);
417 assert(ret == 0);
418 assert(result == 0);
419
420 ret = cmdline_parse(cmdline, 2, argv2, false);
421 assert(ret == 0);
422
423 ret = cmdline_run(cmdline, NULL, &result);
424 assert(ret == 0);
425 assert(result == 0);
426
427 ret = cmdline_parse(cmdline, 2, argv3, false);
428 assert(ret == 0);
429
430 ret = cmdline_run(cmdline, NULL, &result);
431 assert(ret == 0);
432 assert(result == 0);
433
434 talloc_free(mem_ctx);
435 }
436
437
main(int argc,const char ** argv)438 int main(int argc, const char **argv)
439 {
440 int num;
441
442 if (argc < 2) {
443 fprintf(stderr, "Usage %s <testnum>\n", argv[0]);
444 exit(1);
445 }
446
447 num = atoi(argv[1]);
448
449 switch (num) {
450 case 1:
451 test1();
452 break;
453
454 case 2:
455 test2();
456 break;
457
458 case 3:
459 test3();
460 break;
461
462 case 4:
463 test4();
464 break;
465
466 case 5:
467 test5();
468 break;
469
470 case 6:
471 test6();
472 break;
473
474 case 7:
475 test7();
476 break;
477 }
478
479 return 0;
480 }
481