source: mainline/uspace/lib/c/test/getopt.c@ a508e82

Last change on this file since a508e82 was 2c7ef07, checked in by Matthieu Riolo <matthieu.riolo@…>, 6 years ago

adding test cases for getopt

  • Property mode set to 100644
File size: 12.9 KB
Line 
1/*
2 * Copyright (c) 2019 Matthieu Riolo
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <pcut/pcut.h>
30#include <getopt.h>
31#include <stdio.h>
32
33PCUT_INIT;
34
35PCUT_TEST_SUITE(getopt);
36
37PCUT_TEST(getopt_param_flag)
38{
39 int argc = 4;
40 const char *argv[] = {
41 "get_opt_test",
42 "-f",
43 "-p",
44 "param",
45 };
46
47 const char *options = "fp:";
48
49 int ret;
50 optreset = 1;
51 opterr = 0;
52
53 ret = getopt(argc, (char *const *)argv, options);
54
55 PCUT_ASSERT_INT_EQUALS('f', ret);
56 PCUT_ASSERT_INT_EQUALS(2, optind);
57
58 ret = getopt(argc, (char *const *)argv, options);
59
60 PCUT_ASSERT_INT_EQUALS('p', ret);
61 PCUT_ASSERT_INT_EQUALS(4, optind);
62 PCUT_ASSERT_STR_EQUALS("param", optarg);
63
64 ret = getopt(argc, (char *const *)argv, options);
65 PCUT_ASSERT_INT_EQUALS(-1, ret);
66}
67
68PCUT_TEST(getopt_concat_flags)
69{
70 int argc = 2;
71 const char *argv[] = {
72 "get_opt_test",
73 "-fda",
74 };
75
76 const char *options = "afd";
77
78 int ret;
79 optreset = 1;
80 opterr = 0;
81
82 ret = getopt(argc, (char *const *)argv, options);
83
84 PCUT_ASSERT_INT_EQUALS('f', ret);
85 PCUT_ASSERT_INT_EQUALS(1, optind);
86
87 ret = getopt(argc, (char *const *)argv, options);
88
89 PCUT_ASSERT_INT_EQUALS('d', ret);
90 PCUT_ASSERT_INT_EQUALS(1, optind);
91
92 ret = getopt(argc, (char *const *)argv, options);
93
94 PCUT_ASSERT_INT_EQUALS('a', ret);
95 PCUT_ASSERT_INT_EQUALS(2, optind);
96
97 ret = getopt(argc, (char *const *)argv, options);
98 PCUT_ASSERT_INT_EQUALS(-1, ret);
99}
100
101PCUT_TEST(getopt_concat_flag_param)
102{
103 int argc = 3;
104 const char *argv[] = {
105 "get_opt_test",
106 "-fp",
107 "param"
108 };
109
110 const char *options = "fp:";
111
112 int ret;
113 optreset = 1;
114 opterr = 0;
115
116 ret = getopt(argc, (char *const *)argv, options);
117
118 PCUT_ASSERT_INT_EQUALS('f', ret);
119 PCUT_ASSERT_INT_EQUALS(1, optind);
120
121 ret = getopt(argc, (char *const *)argv, options);
122
123 PCUT_ASSERT_INT_EQUALS('p', ret);
124 PCUT_ASSERT_INT_EQUALS(3, optind);
125 PCUT_ASSERT_STR_EQUALS("param", optarg);
126
127 ret = getopt(argc, (char *const *)argv, options);
128 PCUT_ASSERT_INT_EQUALS(-1, ret);
129}
130
131PCUT_TEST(getopt_missing_param1)
132{
133 int argc = 2;
134 const char *argv[] = {
135 "get_opt_test",
136 "-p",
137 };
138
139 const char *options = "p:";
140
141 int ret;
142 optreset = 1;
143 opterr = 0;
144
145 ret = getopt(argc, (char *const *)argv, options);
146
147 PCUT_ASSERT_INT_EQUALS('?', ret);
148 PCUT_ASSERT_INT_EQUALS('p', optopt);
149 PCUT_ASSERT_INT_EQUALS(2, optind);
150
151 ret = getopt(argc, (char *const *)argv, options);
152 PCUT_ASSERT_INT_EQUALS(-1, ret);
153}
154
155PCUT_TEST(getopt_missing_param2)
156{
157 int argc = 2;
158 const char *argv[] = {
159 "get_opt_test",
160 "-p",
161 };
162
163 const char *options = ":p:";
164
165 int ret;
166 optreset = 1;
167 opterr = 0;
168
169 ret = getopt(argc, (char *const *)argv, options);
170
171 PCUT_ASSERT_INT_EQUALS(':', ret);
172 PCUT_ASSERT_INT_EQUALS('p', optopt);
173 PCUT_ASSERT_INT_EQUALS(2, optind);
174
175 ret = getopt(argc, (char *const *)argv, options);
176 PCUT_ASSERT_INT_EQUALS(-1, ret);
177}
178
179PCUT_TEST(getopt_illegal_option)
180{
181 int argc = 2;
182 const char *argv[] = {
183 "get_opt_test",
184 "-p",
185 };
186
187 const char *options = "a";
188
189 int ret;
190 optreset = 1;
191 opterr = 0;
192
193 ret = getopt(argc, (char *const *)argv, options);
194
195 PCUT_ASSERT_INT_EQUALS('?', ret);
196 PCUT_ASSERT_INT_EQUALS('p', optopt);
197 PCUT_ASSERT_INT_EQUALS(2, optind);
198
199 ret = getopt(argc, (char *const *)argv, options);
200 PCUT_ASSERT_INT_EQUALS(-1, ret);
201
202 options = ":a";
203 optreset = 1;
204 ret = getopt(argc, (char *const *)argv, options);
205
206 PCUT_ASSERT_INT_EQUALS(-1, ret);
207 PCUT_ASSERT_INT_EQUALS('p', optopt);
208 PCUT_ASSERT_INT_EQUALS(2, optind);
209
210 ret = getopt(argc, (char *const *)argv, options);
211 PCUT_ASSERT_INT_EQUALS(-1, ret);
212}
213
214PCUT_TEST(getopt_flag_with_param)
215{
216 int argc = 4;
217 const char *argv[] = {
218 "get_opt_test",
219 "-f",
220 "param",
221 "-d"
222 };
223
224 const char *options = "fd";
225
226 int ret;
227 optreset = 1;
228 opterr = 0;
229
230 ret = getopt(argc, (char *const *)argv, options);
231
232 /* getopt() would print a error message but thx to opterror=0 it doesnt */
233 PCUT_ASSERT_INT_EQUALS('f', ret);
234 PCUT_ASSERT_INT_EQUALS(2, optind);
235
236 ret = getopt(argc, (char *const *)argv, options);
237
238 PCUT_ASSERT_INT_EQUALS('d', ret);
239 PCUT_ASSERT_INT_EQUALS(4, optind);
240
241 ret = getopt(argc, (char *const *)argv, options);
242 PCUT_ASSERT_INT_EQUALS(-1, ret);
243}
244
245PCUT_TEST(getopt_case_sensitive)
246{
247 int argc = 3;
248 const char *argv[] = {
249 "get_opt_test",
250 "-F",
251 "-f"
252 };
253
254 const char *options = "fF";
255
256 int ret;
257 optreset = 1;
258 opterr = 0;
259
260 ret = getopt(argc, (char *const *)argv, options);
261
262 PCUT_ASSERT_INT_EQUALS('F', ret);
263 PCUT_ASSERT_INT_EQUALS(2, optind);
264
265 ret = getopt(argc, (char *const *)argv, options);
266
267 PCUT_ASSERT_INT_EQUALS('f', ret);
268 PCUT_ASSERT_INT_EQUALS(3, optind);
269
270 ret = getopt(argc, (char *const *)argv, options);
271 PCUT_ASSERT_INT_EQUALS(-1, ret);
272}
273
274PCUT_TEST(getopt_flag_whitespace)
275{
276 int argc = 2;
277 const char *argv[] = {
278 "get_opt_test",
279 "-p -f",
280 };
281
282 const char *options = "pf";
283
284 int ret;
285 optreset = 1;
286 opterr = 0;
287
288 ret = getopt(argc, (char *const *)argv, options);
289
290 PCUT_ASSERT_INT_EQUALS('p', ret);
291 PCUT_ASSERT_INT_EQUALS(1, optind);
292
293 ret = getopt(argc, (char *const *)argv, options);
294
295 PCUT_ASSERT_INT_EQUALS('f', ret);
296 PCUT_ASSERT_INT_EQUALS(1, optind);
297
298 ret = getopt(argc, (char *const *)argv, options);
299 PCUT_ASSERT_INT_EQUALS(-1, ret);
300}
301
302PCUT_TEST(getopt_param_whitespace)
303{
304 int argc = 2;
305 const char *argv[] = {
306 "get_opt_test",
307 "-p param",
308 };
309
310 const char *options = "p:";
311
312 int ret;
313 optreset = 1;
314 opterr = 0;
315
316 ret = getopt(argc, (char *const *)argv, options);
317
318 PCUT_ASSERT_INT_EQUALS('p', ret);
319 PCUT_ASSERT_INT_EQUALS(2, optind);
320 PCUT_ASSERT_STR_EQUALS(" param", optarg);
321
322 ret = getopt(argc, (char *const *)argv, options);
323 PCUT_ASSERT_INT_EQUALS(-1, ret);
324}
325
326PCUT_TEST(getopt_optional_param)
327{
328 int argc = 4;
329 const char *argv[] = {
330 "get_opt_test",
331 "-f",
332 "-p",
333 "param"
334 };
335
336 const char *options = "f::p::";
337
338 int ret;
339 optreset = 1;
340 opterr = 0;
341
342 ret = getopt(argc, (char *const *)argv, options);
343
344 PCUT_ASSERT_INT_EQUALS('f', ret);
345 PCUT_ASSERT_INT_EQUALS(2, optind);
346 PCUT_ASSERT_NULL(optarg);
347
348 ret = getopt(argc, (char *const *)argv, options);
349
350 PCUT_ASSERT_INT_EQUALS('p', ret);
351 PCUT_ASSERT_INT_EQUALS(3, optind);
352 PCUT_ASSERT_STR_EQUALS("param", optarg);
353
354 ret = getopt(argc, (char *const *)argv, options);
355 PCUT_ASSERT_INT_EQUALS(-1, ret);
356}
357
358PCUT_TEST(getopt_special_option)
359{
360 int argc = 4;
361 const char *argv[] = {
362 "get_opt_test",
363 "-f",
364 "--",
365 "-p"
366 };
367
368 const char *options = "fp";
369
370 int ret;
371 optreset = 1;
372 opterr = 0;
373
374 ret = getopt(argc, (char *const *)argv, options);
375
376 PCUT_ASSERT_INT_EQUALS('f', ret);
377 PCUT_ASSERT_INT_EQUALS(2, optind);
378
379 ret = getopt(argc, (char *const *)argv, options);
380 PCUT_ASSERT_INT_EQUALS(-1, ret);
381}
382
383PCUT_TEST(getopt_gnu_plus)
384{
385 int argc = 4;
386 const char *argv[] = {
387 "get_opt_test",
388 "-f",
389 "break",
390 "-p"
391 };
392
393 const char *options = "+fp";
394
395 int ret;
396 optreset = 1;
397 opterr = 0;
398
399 ret = getopt(argc, (char *const *)argv, options);
400
401 PCUT_ASSERT_INT_EQUALS('f', ret);
402 PCUT_ASSERT_INT_EQUALS(2, optind);
403
404 ret = getopt(argc, (char *const *)argv, options);
405 PCUT_ASSERT_INT_EQUALS(-1, ret);
406}
407
408PCUT_TEST(getopt_gnu_minus)
409{
410 int argc = 4;
411 const char *argv[] = {
412 "get_opt_test",
413 "-f",
414 "break",
415 "-p"
416 };
417
418 const char *options = "-fp";
419
420 int ret;
421 optreset = 1;
422 opterr = 0;
423
424 ret = getopt(argc, (char *const *)argv, options);
425
426 PCUT_ASSERT_INT_EQUALS('f', ret);
427 PCUT_ASSERT_INT_EQUALS(2, optind);
428
429 ret = getopt(argc, (char *const *)argv, options);
430
431 PCUT_ASSERT_INT_EQUALS(1, ret);
432 PCUT_ASSERT_INT_EQUALS(3, optind);
433 PCUT_ASSERT_STR_EQUALS("break", optarg);
434
435 ret = getopt(argc, (char *const *)argv, options);
436
437 PCUT_ASSERT_INT_EQUALS('p', ret);
438 PCUT_ASSERT_INT_EQUALS(4, optind);
439
440 ret = getopt(argc, (char *const *)argv, options);
441 PCUT_ASSERT_INT_EQUALS(-1, ret);
442}
443
444PCUT_TEST(getopt_long_flag_param)
445{
446 int argc = 4;
447 const char *argv[] = {
448 "get_opt_test",
449 "--flag",
450 "--parameter",
451 "param"
452 };
453
454 const char *options = "fp:";
455
456 const struct option long_options[] = {
457 { "flag", no_argument, NULL, 'f' },
458 { "parameter", required_argument, NULL, 'p' },
459 };
460
461 int ret;
462 int idx;
463 optreset = 1;
464 opterr = 0;
465
466 ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
467 PCUT_ASSERT_INT_EQUALS('f', ret);
468 PCUT_ASSERT_INT_EQUALS(2, optind);
469 PCUT_ASSERT_INT_EQUALS(0, idx);
470
471 ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
472 PCUT_ASSERT_INT_EQUALS('p', ret);
473 PCUT_ASSERT_INT_EQUALS(4, optind);
474 PCUT_ASSERT_INT_EQUALS(1, idx);
475 PCUT_ASSERT_STR_EQUALS("param", optarg);
476
477 ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
478 PCUT_ASSERT_INT_EQUALS(-1, ret);
479}
480
481PCUT_TEST(getopt_long_alt_param)
482{
483 int argc = 3;
484 const char *argv[] = {
485 "get_opt_test",
486 "--flag=\"param param\"",
487 "--parameter=param",
488 };
489
490 const char *options = "f:p:";
491
492 const struct option long_options[] = {
493 { "flag", required_argument, NULL, 'f' },
494 { "parameter", required_argument, NULL, 'p' },
495 { 0, 0, 0, 0 }
496 };
497
498 int ret;
499 int idx;
500 optreset = 1;
501 opterr = 0;
502
503 ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
504 PCUT_ASSERT_INT_EQUALS('f', ret);
505 PCUT_ASSERT_INT_EQUALS(2, optind);
506 PCUT_ASSERT_INT_EQUALS(0, idx);
507 PCUT_ASSERT_STR_EQUALS("\"param param\"", optarg);
508
509 ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
510 PCUT_ASSERT_INT_EQUALS('p', ret);
511 PCUT_ASSERT_INT_EQUALS(3, optind);
512 PCUT_ASSERT_INT_EQUALS(1, idx);
513 PCUT_ASSERT_STR_EQUALS("param", optarg);
514
515 ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
516 PCUT_ASSERT_INT_EQUALS(-1, ret);
517}
518
519PCUT_TEST(getopt_long_optional_param)
520{
521 int argc = 3;
522 const char *argv[] = {
523 "get_opt_test",
524 "--flag=param",
525 "--parameter",
526 };
527
528 const char *options = "f::p::";
529
530 const struct option long_options[] = {
531 { "flag", optional_argument, NULL, 'f' },
532 { "parameter", optional_argument, NULL, 'p' },
533 { 0, 0, 0, 0 }
534 };
535
536 int ret;
537 int idx;
538 optreset = 1;
539 opterr = 0;
540
541 ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
542 PCUT_ASSERT_INT_EQUALS('f', ret);
543 PCUT_ASSERT_INT_EQUALS(2, optind);
544 PCUT_ASSERT_INT_EQUALS(0, idx);
545 PCUT_ASSERT_STR_EQUALS("param", optarg);
546
547 ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
548 PCUT_ASSERT_INT_EQUALS('p', ret);
549 PCUT_ASSERT_INT_EQUALS(3, optind);
550 PCUT_ASSERT_INT_EQUALS(1, idx);
551 PCUT_ASSERT_NULL(optarg);
552
553 ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
554 PCUT_ASSERT_INT_EQUALS(-1, ret);
555}
556
557PCUT_TEST(getopt_long_illegal_option)
558{
559 int argc = 3;
560 const char *argv[] = {
561 "get_opt_test",
562 "--param",
563 "param",
564 };
565
566 const char *options = "f::";
567
568 const struct option long_options[] = {
569 { "cflag", required_argument, NULL, 'c' },
570 { "flag", required_argument, NULL, 'f' },
571 { 0, 0, 0, 0 }
572 };
573
574 int ret;
575 int idx;
576 optreset = 1;
577 opterr = 0;
578
579 ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
580 PCUT_ASSERT_INT_EQUALS('?', ret);
581 PCUT_ASSERT_INT_EQUALS(2, optind);
582 PCUT_ASSERT_INT_EQUALS(0, idx);
583 PCUT_ASSERT_INT_EQUALS(0, optopt);
584
585 ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
586 PCUT_ASSERT_INT_EQUALS(-1, ret);
587}
588
589PCUT_TEST(getopt_long_ambiguous_param)
590{
591 int argc = 3;
592 const char *argv[] = {
593 "get_opt_test",
594 "--flag",
595 "param",
596 };
597
598 const char *options = "f::";
599
600 const struct option long_options[] = {
601 { "flag1", optional_argument, NULL, 'f' },
602 { "flag2", required_argument, NULL, 'f' },
603 { 0, 0, 0, 0 }
604 };
605
606 int ret;
607 int idx;
608 optreset = 1;
609 opterr = 0;
610
611 ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
612 PCUT_ASSERT_INT_EQUALS('?', ret);
613 PCUT_ASSERT_INT_EQUALS(2, optind);
614 PCUT_ASSERT_INT_EQUALS(0, idx);
615 PCUT_ASSERT_INT_EQUALS(0, optopt);
616
617 ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
618 PCUT_ASSERT_INT_EQUALS(-1, ret);
619}
620
621PCUT_EXPORT(getopt);
Note: See TracBrowser for help on using the repository browser.