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

Last change on this file was a163d10, checked in by Jiri Svoboda <jiri@…>, 6 years ago

Fix getopt_optional_param test failing

This is a bug in the test, getopt is working as expected. An optional
argument must be passed as part of the option, not separated by space.

  • Property mode set to 100644
File size: 11.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_optional_param)
275{
276 int argc = 4;
277 const char *argv[] = {
278 "get_opt_test",
279 "-f",
280 "-pparam"
281 };
282
283 const char *options = "f::p::";
284
285 int ret;
286 optreset = 1;
287 opterr = 0;
288
289 ret = getopt(argc, (char *const *)argv, options);
290
291 PCUT_ASSERT_INT_EQUALS('f', ret);
292 PCUT_ASSERT_INT_EQUALS(2, optind);
293 PCUT_ASSERT_NULL(optarg);
294
295 ret = getopt(argc, (char *const *)argv, options);
296
297 PCUT_ASSERT_INT_EQUALS('p', ret);
298 PCUT_ASSERT_INT_EQUALS(3, optind);
299 PCUT_ASSERT_STR_EQUALS("param", optarg);
300
301 ret = getopt(argc, (char *const *)argv, options);
302 PCUT_ASSERT_INT_EQUALS(-1, ret);
303}
304
305PCUT_TEST(getopt_special_option)
306{
307 int argc = 4;
308 const char *argv[] = {
309 "get_opt_test",
310 "-f",
311 "--",
312 "-p"
313 };
314
315 const char *options = "fp";
316
317 int ret;
318 optreset = 1;
319 opterr = 0;
320
321 ret = getopt(argc, (char *const *)argv, options);
322
323 PCUT_ASSERT_INT_EQUALS('f', ret);
324 PCUT_ASSERT_INT_EQUALS(2, optind);
325
326 ret = getopt(argc, (char *const *)argv, options);
327 PCUT_ASSERT_INT_EQUALS(-1, ret);
328}
329
330PCUT_TEST(getopt_gnu_plus)
331{
332 int argc = 4;
333 const char *argv[] = {
334 "get_opt_test",
335 "-f",
336 "break",
337 "-p"
338 };
339
340 const char *options = "+fp";
341
342 int ret;
343 optreset = 1;
344 opterr = 0;
345
346 ret = getopt(argc, (char *const *)argv, options);
347
348 PCUT_ASSERT_INT_EQUALS('f', ret);
349 PCUT_ASSERT_INT_EQUALS(2, optind);
350
351 ret = getopt(argc, (char *const *)argv, options);
352 PCUT_ASSERT_INT_EQUALS(-1, ret);
353}
354
355PCUT_TEST(getopt_gnu_minus)
356{
357 int argc = 4;
358 const char *argv[] = {
359 "get_opt_test",
360 "-f",
361 "break",
362 "-p"
363 };
364
365 const char *options = "-fp";
366
367 int ret;
368 optreset = 1;
369 opterr = 0;
370
371 ret = getopt(argc, (char *const *)argv, options);
372
373 PCUT_ASSERT_INT_EQUALS('f', ret);
374 PCUT_ASSERT_INT_EQUALS(2, optind);
375
376 ret = getopt(argc, (char *const *)argv, options);
377
378 PCUT_ASSERT_INT_EQUALS(1, ret);
379 PCUT_ASSERT_INT_EQUALS(3, optind);
380 PCUT_ASSERT_STR_EQUALS("break", optarg);
381
382 ret = getopt(argc, (char *const *)argv, options);
383
384 PCUT_ASSERT_INT_EQUALS('p', ret);
385 PCUT_ASSERT_INT_EQUALS(4, optind);
386
387 ret = getopt(argc, (char *const *)argv, options);
388 PCUT_ASSERT_INT_EQUALS(-1, ret);
389}
390
391PCUT_TEST(getopt_long_flag_param)
392{
393 int argc = 4;
394 const char *argv[] = {
395 "get_opt_test",
396 "--flag",
397 "--parameter",
398 "param"
399 };
400
401 const char *options = "fp:";
402
403 const struct option long_options[] = {
404 { "flag", no_argument, NULL, 'f' },
405 { "parameter", required_argument, NULL, 'p' },
406 };
407
408 int ret;
409 int idx;
410 optreset = 1;
411 opterr = 0;
412
413 ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
414 PCUT_ASSERT_INT_EQUALS('f', ret);
415 PCUT_ASSERT_INT_EQUALS(2, optind);
416 PCUT_ASSERT_INT_EQUALS(0, idx);
417
418 ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
419 PCUT_ASSERT_INT_EQUALS('p', ret);
420 PCUT_ASSERT_INT_EQUALS(4, optind);
421 PCUT_ASSERT_INT_EQUALS(1, idx);
422 PCUT_ASSERT_STR_EQUALS("param", optarg);
423
424 ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
425 PCUT_ASSERT_INT_EQUALS(-1, ret);
426}
427
428PCUT_TEST(getopt_long_alt_param)
429{
430 int argc = 3;
431 const char *argv[] = {
432 "get_opt_test",
433 "--flag=\"param param\"",
434 "--parameter=param",
435 };
436
437 const char *options = "f:p:";
438
439 const struct option long_options[] = {
440 { "flag", required_argument, NULL, 'f' },
441 { "parameter", required_argument, NULL, 'p' },
442 { 0, 0, 0, 0 }
443 };
444
445 int ret;
446 int idx;
447 optreset = 1;
448 opterr = 0;
449
450 ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
451 PCUT_ASSERT_INT_EQUALS('f', ret);
452 PCUT_ASSERT_INT_EQUALS(2, optind);
453 PCUT_ASSERT_INT_EQUALS(0, idx);
454 PCUT_ASSERT_STR_EQUALS("\"param param\"", optarg);
455
456 ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
457 PCUT_ASSERT_INT_EQUALS('p', ret);
458 PCUT_ASSERT_INT_EQUALS(3, optind);
459 PCUT_ASSERT_INT_EQUALS(1, idx);
460 PCUT_ASSERT_STR_EQUALS("param", optarg);
461
462 ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
463 PCUT_ASSERT_INT_EQUALS(-1, ret);
464}
465
466PCUT_TEST(getopt_long_optional_param)
467{
468 int argc = 3;
469 const char *argv[] = {
470 "get_opt_test",
471 "--flag=param",
472 "--parameter",
473 };
474
475 const char *options = "f::p::";
476
477 const struct option long_options[] = {
478 { "flag", optional_argument, NULL, 'f' },
479 { "parameter", optional_argument, NULL, 'p' },
480 { 0, 0, 0, 0 }
481 };
482
483 int ret;
484 int idx;
485 optreset = 1;
486 opterr = 0;
487
488 ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
489 PCUT_ASSERT_INT_EQUALS('f', ret);
490 PCUT_ASSERT_INT_EQUALS(2, optind);
491 PCUT_ASSERT_INT_EQUALS(0, idx);
492 PCUT_ASSERT_STR_EQUALS("param", optarg);
493
494 ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
495 PCUT_ASSERT_INT_EQUALS('p', ret);
496 PCUT_ASSERT_INT_EQUALS(3, optind);
497 PCUT_ASSERT_INT_EQUALS(1, idx);
498 PCUT_ASSERT_NULL(optarg);
499
500 ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
501 PCUT_ASSERT_INT_EQUALS(-1, ret);
502}
503
504PCUT_TEST(getopt_long_illegal_option)
505{
506 int argc = 3;
507 const char *argv[] = {
508 "get_opt_test",
509 "--param",
510 "param",
511 };
512
513 const char *options = "f::";
514
515 const struct option long_options[] = {
516 { "cflag", required_argument, NULL, 'c' },
517 { "flag", required_argument, NULL, 'f' },
518 { 0, 0, 0, 0 }
519 };
520
521 int ret;
522 int idx;
523 optreset = 1;
524 opterr = 0;
525
526 ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
527 PCUT_ASSERT_INT_EQUALS('?', ret);
528 PCUT_ASSERT_INT_EQUALS(2, optind);
529 PCUT_ASSERT_INT_EQUALS(0, idx);
530 PCUT_ASSERT_INT_EQUALS(0, optopt);
531
532 ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
533 PCUT_ASSERT_INT_EQUALS(-1, ret);
534}
535
536PCUT_TEST(getopt_long_ambiguous_param)
537{
538 int argc = 3;
539 const char *argv[] = {
540 "get_opt_test",
541 "--flag",
542 "param",
543 };
544
545 const char *options = "f::";
546
547 const struct option long_options[] = {
548 { "flag1", optional_argument, NULL, 'f' },
549 { "flag2", required_argument, NULL, 'f' },
550 { 0, 0, 0, 0 }
551 };
552
553 int ret;
554 int idx;
555 optreset = 1;
556 opterr = 0;
557
558 ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
559 PCUT_ASSERT_INT_EQUALS('?', ret);
560 PCUT_ASSERT_INT_EQUALS(2, optind);
561 PCUT_ASSERT_INT_EQUALS(0, idx);
562 PCUT_ASSERT_INT_EQUALS(0, optopt);
563
564 ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
565 PCUT_ASSERT_INT_EQUALS(-1, ret);
566}
567
568PCUT_EXPORT(getopt);
Note: See TracBrowser for help on using the repository browser.