OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
argpar.c
Go to the documentation of this file.
1 
2 #include <argpar.h>
3 
4 #include <check.h>
5 #include <errno.h>
6 #include <ftw.h>
7 #include <stdbool.h>
8 #include <stdint.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <sys/stat.h>
13 #include <unistd.h>
14 
16 const char *argpar_program_name = "argpar-test";
17 static const char doc[] = "This is an argpar test.";
18 static const char args_doc[] = "[none]";
19 static const argpar_option options[] = {
20  { "ifile", 'f', "FILE", 0, "input file" },
21  { "ofile", 'o', "FILE", 0, "output file" },
22  { 0,0,0,0, "This is a header:", 2 },
23  { 0,0,0, OPTION_DOC, "This is some docs." },
24  { 0,0,0,0, "Header #1:", 1 },
25  { 0,0,0, OPTION_DOC, "This is some docs." },
26  { "efile", 'e', "FILE", 0, "error file", 2 },
27  { "long", 'l', 0, OPTION_INT, "long, not casted" },
28  { "int", 'i', 0, OPTION_INT, "casted as int", 1 },
29  { "dbl", 'd', 0, OPTION_DBL, "casted as dbl", 1 },
30  { "double", 0, 0, OPTION_ALIAS },
31  { "p", 'p', 0, 0, "load parfile via child", 1 },
32  { "enum", 'm', 0, 0, "this option has enum values", 1 },
33  { "val1", 0, 0, OPTION_ENUM, "description of val1", 1 },
34  { "val2", 0, 0, OPTION_ENUM, "description of val2", 1 },
35  { "default", 0, 0, OPTION_ATTR, "val1" },
36  {0}
37 };
38 
39 char stdout_file[64];
40 
41 typedef struct arguments {
42  const char *argv[32];
43  int argc;
44  const char *ifile;
45  const char *ofile;
46  char *ofile_src;
47  const char *efile;
48  char *efile_src;
49  int i; bool i_error;
50  double d; bool d_error;
51  char *d_alias;
52  long l; bool l_error;
53 
54  bool ended;
55  const char *argv_unknown[32];
57 
58  int unknown;
59 
60 } arguments;
61 
62 
63 static void clean_arguments(arguments *a){
64  if (a->ofile_src){
65  free(a->ofile_src);
66  }
67  if (a->efile_src){
68  free(a->efile_src);
69  }
70  if (a->d_alias){
71  free(a->d_alias);
72  }
73 }
74 
75 static int parse_options(int key, char *argv, argpar_state *state) {
76  arguments *arguments = state->input;
77  switch (key){
78  case 'f':
79  arguments->ifile = argv;
80  break;
81  case 'o':
82  arguments->ofile = argv;
83  if (arguments->ofile_src){
84  free(arguments->ofile_src);
86  }
87  if (state->parfile){
88  arguments->ofile_src = strdup(state->parfile);
89  }
90  break;
91  case 'e':
92  arguments->efile = state->arg_value;
93  if (arguments->efile_src){
94  free(arguments->efile_src);
96  }
97  if (state->parfile){
98  arguments->efile_src = strdup(state->parfile);
99  }
100  break;
101  case 'i':
102  arguments->i = state->argv_as_int;
103  arguments->i_error = state->argv_as_int_err;
104  break;
105  case 'd':
106  arguments->d = state->argv_as_dbl;
107  arguments->d_error = state->argv_as_dbl_err;
108  if (arguments->d_alias){
109  free(arguments->d_alias);
111  }
112  if (state->arg_alias){
113  arguments->d_alias = strdup(state->arg_alias);
114  }
115  break;
116  case 'l':
117  arguments->l = state->argv_as_int;
118  arguments->l_error = state->argv_as_int_err;
119  break;
120  case 'p':
121  ck_assert_int_eq(argpar_parse_file(state->argpar, state->arg_value, 0, arguments), 0);
122  break;
123  case ARGPAR_KEY_ARG:
124  arguments->argv[arguments->argc++] = argv;
125  break;
126  case ARGPAR_KEY_UNKNOWN:
127  arguments->unknown++;
128  break;
129  case ARGPAR_KEY_END:
130  arguments->ended = true;
131  break;
132  }
133 
134  return 0;
135 }
136 
137 argpar params = { options, parse_options, args_doc, doc };
138 
139 START_TEST(no_args_usage){
141 
142  arguments arguments = {};
143  ck_assert_int_eq(argpar_parse_args(&params, 0, NULL, 0, NULL, &arguments), ARGPAR_ERR_USAGE);
144 
146  fclose(argpar_ostream);
147 }
148 END_TEST
149 
150 START_TEST(no_real_args){
152 
153  int argc = 2;
154  char *argv[] = {(char*)argpar_program_name, "--"};
155  arguments arguments = {
156  .argc = 0, .argc_unknown = 0, .i = -1, .d = -1
157  };
158  ck_assert_int_eq(argpar_parse_args(&params, argc, argv, 0, NULL, &arguments), 0);
159  ck_assert_int_eq(arguments.argc, 0);
160  ck_assert_int_eq(arguments.argc_unknown, 0);
161  ck_assert_int_eq(arguments.i, -1);
162  ck_assert(arguments.d == -1);
163 
164  clean_arguments(&arguments);
165 
167  fclose(argpar_ostream);
168 }
169 END_TEST
170 
171 START_TEST(auto_help){
173  int argc = 2;
174  char *argv_const[] = {(char*)argpar_program_name, "help=1"};
175  char *argv[argc];
176  int i;
177  for (i=0;i<argc;i++){
178  argv[i] = strdup(argv_const[i]);
179  }
180  arguments arguments = {.argc=0};
181 
182  ck_assert_int_eq(argpar_parse_args(&params, argc, argv, ARGPAR_NO_EXIT, NULL, &arguments), ARGPAR_ERR_ABORT);
183 
184  for (i=0;i<argc;i++){
185  free(argv[i]);
186  }
187 
188  clean_arguments(&arguments);
189 
191  fclose(argpar_ostream);
192 }
193 END_TEST
194 
195 START_TEST(unknown_option){
197 
198  int argc = 7;
199  char *argv_const[] = {(char*)argpar_program_name, "ifile=input", "arg1", "unknown=bad", "--", "ofile=output", "arg3"};
200  char *argv[argc];
201  int i;
202  for (i=0;i<argc;i++){
203  argv[i] = strdup(argv_const[i]);
204  }
205  arguments arguments = {
206  .argc = 0, .i = -1, .d = -1,
207  .ofile = NULL, .ended = false
208  };
209  ck_assert_int_eq(argpar_parse_args(&params, argc, argv, 0, NULL, &arguments), ARGPAR_ERR_UNKNOWN);
210 
211  for (i=0;i<argc;i++){
212  free(argv[i]);
213  }
214 
215  clean_arguments(&arguments);
216 
218  fclose(argpar_ostream);
219 }
220 END_TEST
221 
222 START_TEST(no_key_args){
224 
225  int argc = 7;
226  const char *argv_const[] = {
227  argpar_program_name, "ifile=_ifile", "ofile=_ofile", "efile=_efile",
228  "int=1", "dbl=2", "long=3"
229  };
230  char *argv[argc];
231  int i;
232  for (i=0;i<argc;i++){
233  argv[i] = strdup(argv_const[i]);
234  }
235  arguments arguments = {
236  .argc = 0, .argc_unknown = 0, .i = -1, .d = -1, .l = -1
237  };
238  ck_assert_int_eq(argpar_parse_args(&params, argc, argv, 0, NULL, &arguments), 0);
239  ck_assert_int_eq(arguments.argc, 0);
240  ck_assert_int_eq(arguments.argc_unknown, 0);
241  ck_assert_int_eq(arguments.i, 1);
242  ck_assert_int_eq(arguments.i_error, 0);
243  ck_assert_int_eq(arguments.d, 2);
244  ck_assert_int_eq(arguments.d_error, 0);
245  ck_assert_int_eq(arguments.l, 3);
246  ck_assert_int_eq(arguments.l_error, 0);
247 
248  for (i=0;i<argc;i++){
249  free(argv[i]);
250  }
251 
252  clean_arguments(&arguments);
253 
255  fclose(argpar_ostream);
256 }
257 END_TEST
258 
259 START_TEST(aliases){
261 
262  int argc = 3;
263  const char *argv_const[] = {
264  argpar_program_name, "dbl=1", "double=2"
265  };
266  char *argv[argc];
267  int i;
268  for (i=0;i<argc;i++){
269  argv[i] = strdup(argv_const[i]);
270  }
271  arguments arguments = {
272  .argc = 0, .argc_unknown = 0, .i = -1, .d = -1, .l = -1
273  };
274  ck_assert_int_eq(argpar_parse_args(&params, argc, argv, 0, NULL, &arguments), 0);
275  ck_assert_int_eq(arguments.d, 2);
276  ck_assert_int_eq(arguments.d_error, 0);
277  ck_assert_str_eq(arguments.d_alias, "double");
278 
279  for (i=0;i<argc;i++){
280  free(argv[i]);
281  }
282 
283  clean_arguments(&arguments);
284 
286  fclose(argpar_ostream);
287 }
288 END_TEST
289 
290 START_TEST(int_errors){
292 
293  int tests = 8;
294  const char *int_strs[] = { "1", "2.0", "456", "-123", "0", "-0", "q", "345a" };
295  const int ints[] = { 1, 2, 456, -123, 0, 0, 0, 345 };
296  const bool errors[] = { 0, 1, 0, 0, 0, 0, 1, 1 };
297  char *argv[2] = {(char*)argpar_program_name, malloc(0)};
298  int i;
299  for (i=0;i<tests;i++){
300  argv[1] = realloc(argv[1], sizeof(char)*(strlen(int_strs[i])+5));
301  strcpy(argv[1], "int=");
302  strcat(argv[1], int_strs[i]);
303  arguments arguments = { .i = -1 };
304 
305  ck_assert_int_eq(argpar_parse_args(&params, 2, argv, 0, NULL, &arguments), 0);
306  ck_assert_int_eq(arguments.i, ints[i]);
307  ck_assert_int_eq(arguments.i_error, errors[i]);
308 
309  clean_arguments(&arguments);
310  }
311  free(argv[1]);
312 
314  fclose(argpar_ostream);
315 }
316 END_TEST
317 
318 START_TEST(dbl_errors){
320 
321  int tests = 9;
322  const char *dbl_strs[] = { "1", "2.0", "456", "-123", "0", "-0", "q", "345a", "-2e5" };
323  const double dbls[] = { 1, 2, 456, -123, 0, 0, 0, 345, -200000 };
324  const bool errors[] = { 0, 0, 0, 0, 0, 0, 1, 1, 0 };
325  char *argv[2] = {(char*)argpar_program_name, malloc(0)};
326  int i;
327  for (i=0;i<tests;i++){
328  argv[1] = realloc(argv[1], sizeof(char)*(strlen(dbl_strs[i])+5));
329  strcpy(argv[1], "dbl=");
330  strcat(argv[1], dbl_strs[i]);
331  arguments arguments = { .i = -1 };
332 
333  ck_assert_int_eq(argpar_parse_args(&params, 2, argv, 0, NULL, &arguments), 0);
334  ck_assert(arguments.d == dbls[i]);
335  ck_assert_int_eq(arguments.d_error, errors[i]);
336 
337  clean_arguments(&arguments);
338  }
339  free(argv[1]);
340 
342  fclose(argpar_ostream);
343 }
344 END_TEST
345 
346 
347 START_TEST(parfile1){
349 
350  int argc = 5;
351  const char *argv_const[] = {
352  argpar_program_name, "parfile=parfiles/initial.par", "ofile=keyarg_ofile1", "parfile=parfiles/final.par",
353  "ofile=keyarg_ofile2"
354  };
355  char *argv[argc];
356  int i;
357  for (i=0;i<argc;i++){
358  argv[i] = strdup(argv_const[i]);
359  }
360  arguments arguments = {
361  .argc = 0, .argc_unknown = 0, .i = -1, .d = -1, .l = -1
362  };
363  ck_assert_int_eq(argpar_parse_args(&params, argc, argv, 0, NULL, &arguments), 0);
364  ck_assert_int_eq(arguments.argc, 0);
365  ck_assert_int_eq(arguments.argc_unknown, 0);
366  ck_assert_int_eq(arguments.i, -1);
367  ck_assert_int_eq(arguments.i_error, 0);
368  ck_assert_int_eq(arguments.d, 2.2);
369  ck_assert_int_eq(arguments.d_error, 0);
370  ck_assert_int_eq(arguments.l, -11);
371  ck_assert_int_eq(arguments.l_error, 0);
372  ck_assert_str_eq(arguments.ifile, "initial_input");
373  ck_assert_str_eq(arguments.ofile, "keyarg_ofile2");
374  ck_assert_ptr_eq(arguments.ofile_src, NULL);
375  ck_assert_str_eq(arguments.efile, "defaults_error");
376  ck_assert_str_eq(arguments.efile_src, "parfiles/defaults.par");
377 
378  for (i=0;i<argc;i++){
379  free(argv[i]);
380  }
381 
382  clean_arguments(&arguments);
383 
385  fclose(argpar_ostream);
386 }
387 END_TEST
388 
389 static const char doc_parent[] = "This is an argpar test.";
390 static const char args_doc_parent[] = "[none]";
391 static const argpar_option options_parent[] = {
392  { "dbl", 'd', 0, OPTION_DBL, "casted as dbl", 1 },
393  { "parg", 'p', 0, OPTION_INT, "new arg for parent", 1 },
394  {0}
395 };
396 
397 typedef struct arguments_parent {
400  int argc;
402 
403 static int parse_options_parent(int key, char *argv, argpar_state *state) {
404  arguments_parent *arguments = state->input;
405  switch (key){
406  case 'd':
407  arguments->_.d = state->argv_as_dbl * 2;
408  break;
409  case 'p':
410  arguments->parent_arg = state->argv_as_int;
411  break;
412  case ARGPAR_KEY_ARG:
413  if (arguments->argc){
414  return ARGPAR_ERR_UNKNOWN;
415  }
416  arguments->argc++;
417  break;
418  case ARGPAR_KEY_INIT:
419  state->child_inputs[0] = state->input;
420  break;
421  }
422  return 0;
423 }
425 argpar params_parent = { options_parent, parse_options_parent, args_doc_parent, doc_parent, children };
426 
427 START_TEST(children1){
429 
430  int argc = 6;
431  char *argv_const[] = {(char*)argpar_program_name, "dbl=2", "parg=5", "int=6", "arg1", "arg2"};
432  char *argv[argc];
433  int i;
434  for (i=0;i<argc;i++){
435  argv[i] = strdup(argv_const[i]);
436  }
437  arguments arguments = {
438  .argc = 0, .i = -1, .d = -1,
439  .ofile = NULL, .ended = false
440  };
442  ck_assert_int_eq(argpar_parse_args(&params_parent, argc, argv, 0, NULL, &arguments_parent), 0);
443  ck_assert(arguments_parent._.d == 4);
444  ck_assert_int_eq(arguments_parent._.i, 6);
445  ck_assert_int_eq(arguments_parent.parent_arg, 5);
446  ck_assert_int_eq(arguments_parent._.argc, 1);
447  ck_assert_int_eq(arguments_parent.argc, 1);
448 
449  for (i=0;i<argc;i++){
450  free(argv[i]);
451  }
452 
453  clean_arguments(&arguments);
454 
456  fclose(argpar_ostream);
457 }
458 END_TEST
459 
460 START_TEST(parse_parfile){
462 
463  int argc = 2;
464  char *argv_const[] = {(char*)argpar_program_name, "dbl=2"};
465  char *argv[argc];
466  int i;
467  for (i=0;i<argc;i++){
468  argv[i] = strdup(argv_const[i]);
469  }
470  arguments arguments = {
471  .argc = 0, .i = -1, .d = -1, .l = 4,
472  .ofile = NULL, .ended = false
473  };
475  ck_assert_int_eq(argpar_parse_args(&params_parent, argc, argv, 0, NULL, &arguments_parent), 0);
476  ck_assert(arguments_parent._.d == 4);
477 
478  ck_assert_int_eq(argpar_parse_file(&params_parent, "parfiles/initial.par", 0, &arguments_parent), 0);
479  ck_assert(arguments_parent._.d == 2.2);
480  ck_assert_str_eq(arguments_parent._.efile, "defaults_error");
481  ck_assert_str_eq(arguments_parent._.ofile_src, "parfiles/defaults.par");
482  ck_assert_str_eq(arguments_parent._.efile_src, "parfiles/defaults.par");
483 
484 
485  ck_assert_int_eq(arguments_parent._.l, -11);
486 
487  for (i=0;i<argc;i++){
488  free(argv[i]);
489  }
490 
491  clean_arguments(&arguments_parent._);
492 
494  fclose(argpar_ostream);
495 }
496 END_TEST
497 
498 START_TEST(parse_parfile_in_child){
500 
501  int argc = 2;
502  char *argv_const[] = {(char*)argpar_program_name, "p=parfiles/initial.par"};
503  char *argv[argc];
504  int i;
505  for (i=0;i<argc;i++){
506  argv[i] = strdup(argv_const[i]);
507  }
508  arguments arguments = {
509  .argc = 0, .i = -1, .d = -1, .l = 4,
510  .ofile = NULL, .ended = false
511  };
512 
514  ck_assert_int_eq(argpar_parse_args(&params_parent, argc, argv, 0, NULL, &arguments_parent), 0);
515 
516  ck_assert_int_eq(arguments_parent._.d, 2.2);
517  ck_assert_str_eq(arguments_parent._.efile, "defaults_error");
518  ck_assert_int_eq(arguments_parent._.l, -11);
519 
520  for (i=0;i<argc;i++){
521  free(argv[i]);
522  }
523 
524  clean_arguments(&arguments_parent._);
525 
527  fclose(argpar_ostream);
528 }
529 END_TEST
530 
531 START_TEST(skip_parfiles){
533 
534  int argc = 3;
535  char *argv_const[] = {(char*)argpar_program_name, "ofile=keyarg_ofile1", "parfile=parfiles/initial.par"};
536  char *argv[argc];
537  int i;
538  for (i=0;i<argc;i++){
539  argv[i] = strdup(argv_const[i]);
540  }
541  arguments arguments = {
542  .argc = 0, .argc_unknown = 0, .i = -1, .d = -1
543  };
544  ck_assert_int_eq(argpar_parse_args(&params, argc, argv, ARGPAR_SKIP_PARFILES, NULL, &arguments), 0);
545  ck_assert_str_eq(arguments.ofile, "keyarg_ofile1");
546 
547  for (i=0;i<argc;i++){
548  free(argv[i]);
549  }
550 
551  clean_arguments(&arguments);
552 
554  fclose(argpar_ostream);
555 }
556 END_TEST
557 
558 START_TEST(no_keyargs){
560 
561  int argc = 2;
562  char *argv_const[] = {(char*)argpar_program_name, "int"};
563  char *argv[argc];
564  int i;
565  for (i=0;i<argc;i++){
566  argv[i] = strdup(argv_const[i]);
567  }
568  arguments arguments = {
569  .argc = 0, .argc_unknown = 0, .i = -1, .d = -1
570  };
571  ck_assert_int_eq(argpar_parse_args(&params, argc, argv, ARGPAR_NO_KEYARGS, NULL, &arguments), 0);
572  ck_assert_int_eq(arguments.i, 1);
573  ck_assert_int_eq(arguments.unknown, 0);
574 
575  for (i=0;i<argc;i++){
576  free(argv[i]);
577  }
578 
579  clean_arguments(&arguments);
580 
582  fclose(argpar_ostream);
583 }
584 END_TEST
585 
586 START_TEST(no_keyargs_parfile){
588 
589  int argc = 2;
590  char *argv_const[] = {(char*)argpar_program_name, "parfile=parfiles/no_keyargs.par"};
591  char *argv[argc];
592  int i;
593  for (i=0;i<argc;i++){
594  argv[i] = strdup(argv_const[i]);
595  }
596  arguments arguments = {
597  .argc = 0, .argc_unknown = 0, .i = -1, .d = -1
598  };
599  ck_assert_int_eq(argpar_parse_args(&params, argc, argv, ARGPAR_NO_KEYARGS, NULL, &arguments), 0);
600  ck_assert_int_eq(arguments.i, 1);
601 
602  for (i=0;i<argc;i++){
603  free(argv[i]);
604  }
605 
606  clean_arguments(&arguments);
607 
609  fclose(argpar_ostream);
610 }
611 END_TEST
612 
613 START_TEST(split_strings){
614  char *str1, *str2, *str3, *str4, *str5, *str6, **ret1;
615 
616  str1 = strdup("test1,test2,test3");
617  str2 = strdup("test1 test2 test3");
618  str3 = strdup("test1, test2, test3");
619  str4 = strdup("test1");
620  str5 = strdup("test1,,test2");
621  str6 = strdup("test1,test2,test3,test4,test5,test6,test7,test8,test9,test10");
622 
623  ret1 = argpar_split_str(str1, ",");
624  ck_assert_str_eq(ret1[0], "test1");
625  ck_assert_str_eq(ret1[1], "test2");
626  ck_assert_str_eq(ret1[2], "test3");
627  ck_assert_ptr_eq(ret1[3], NULL);
628  free(ret1);
629 
630  ret1 = argpar_split_str(str2, " ");
631  ck_assert_str_eq(ret1[0], "test1");
632  ck_assert_str_eq(ret1[1], "test2");
633  ck_assert_str_eq(ret1[2], "test3");
634  ck_assert_ptr_eq(ret1[3], NULL);
635  free(ret1);
636 
637  ret1 = argpar_split_str(str3, ", ");
638  ck_assert_str_eq(ret1[0], "test1");
639  ck_assert_str_eq(ret1[1], "");
640  ck_assert_str_eq(ret1[2], "test2");
641  ck_assert_str_eq(ret1[3], "");
642  ck_assert_str_eq(ret1[4], "test3");
643  ck_assert_ptr_eq(ret1[5], NULL);
644  free(ret1);
645 
646  ret1 = argpar_split_str(str4, ",");
647  ck_assert_str_eq(ret1[0], "test1");
648  ck_assert_ptr_eq(ret1[1], NULL);
649  free(ret1);
650 
651  ret1 = argpar_split_str(str5, ",");
652  ck_assert_str_eq(ret1[0], "test1");
653  ck_assert_str_eq(ret1[1], "");
654  ck_assert_str_eq(ret1[2], "test2");
655  ck_assert_ptr_eq(ret1[3], NULL);
656  free(ret1);
657 
658  char test_str[8];
659  ret1 = argpar_split_str(str6, ",");
660  ck_assert_ptr_ne(ret1, NULL);
661  for (int i=0;i<10;i++){
662  sprintf(test_str, "test%d", i+1);
663  ck_assert_str_eq(ret1[i], test_str);
664  }
665  ck_assert_ptr_eq(ret1[10], NULL);
666  free(ret1);
667 
668  free(str1); free(str2); free(str3); free(str4); free(str5); free(str6);
669 }
670 END_TEST
671 
672 START_TEST(split_strings_trim){
673  char *str1, *str3, **ret1;
674 
675  str1 = strdup("test1,test2,test3");
676  str3 = strdup(" test1,test2 , test3 ");
677 
678  ret1 = argpar_split_trim(str1, ",");
679  ck_assert_str_eq(ret1[0], "test1");
680  ck_assert_str_eq(ret1[1], "test2");
681  ck_assert_str_eq(ret1[2], "test3");
682  ck_assert_ptr_eq(ret1[3], NULL);
683  free(ret1);
684 
685  ret1 = argpar_split_trim(str3, ",");
686  ck_assert_str_eq(ret1[0], "test1");
687  ck_assert_str_eq(ret1[1], "test2");
688  ck_assert_str_eq(ret1[2], "test3");
689  ck_assert_ptr_eq(ret1[3], NULL);
690  free(ret1);
691 
692  free(str1); free(str3);
693 }
694 END_TEST
695 
696 
697 START_TEST(split_int){
698  char *str1, *str2, *str3, *str4;
699  int *ret1;
700 
701  str1 = strdup("1, 2 , 3");
702  str2 = strdup("1");
703  str3 = strdup("asdf");
704  str4 = strdup("1,,3");
705 
706  ret1 = argpar_split_int(str1, ",");
707  ck_assert(ret1[0] == 1);
708  ck_assert(ret1[1] == 2);
709  ck_assert(ret1[2] == 3);
710  ck_assert(ret1[3] == NULL_INT);
711  free(ret1);
712 
713  ret1 = argpar_split_int(str2, ",");
714  ck_assert(ret1[0] == 1);
715  ck_assert(ret1[1] == NULL_INT);
716  free(ret1);
717 
718  ret1 = argpar_split_int(str3, ",");
719  ck_assert_ptr_eq(ret1, NULL);
720 
721  ret1 = argpar_split_int(str4, ",");
722  ck_assert(ret1[0] == 1);
723  ck_assert(ret1[1] == EMPTY_INT);
724  ck_assert(ret1[2] == 3);
725  ck_assert(ret1[3] == NULL_INT);
726  free(ret1);
727 
728  free(str1); free(str2); free(str3); free(str4);
729 }
730 END_TEST
731 
732 START_TEST(split_dbl){
733  char *str1, *str2, *str3, *str4;
734  double *ret1;
735 
736  str1 = strdup("1.1, 2.2 , 3.3");
737  str2 = strdup("1.1");
738  str3 = strdup("asdf");
739  str4 = strdup("1.1,,3.3");
740 
741  ret1 = argpar_split_dbl(str1, ",");
742  ck_assert(ret1[0] == 1.1);
743  ck_assert(ret1[1] == 2.2);
744  ck_assert(ret1[2] == 3.3);
745  ck_assert(isnan(ret1[3]));
746  free(ret1);
747 
748  ret1 = argpar_split_dbl(str2, ",");
749  ck_assert(ret1[0] == 1.1);
750  ck_assert(isnan(ret1[1]));
751  free(ret1);
752 
753  ret1 = argpar_split_dbl(str3, ",");
754  ck_assert_ptr_eq(ret1, NULL);
755 
756  ret1 = argpar_split_dbl(str4, ",");
757  ck_assert(ret1[0] == 1.1);
758  ck_assert(isinf(ret1[1]));
759  ck_assert(ret1[2] == 3.3);
760  ck_assert(isnan(ret1[3]));
761  free(ret1);
762 
763  free(str1); free(str2); free(str3); free(str4);
764 }
765 END_TEST
766 
767 START_TEST(accept_any){
769 
770  int argc = 2;
771  char *argv_const[] = {(char*)argpar_program_name, "unknown=option"};
772  char *argv[argc];
773  int i;
774  for (i=0;i<argc;i++){
775  argv[i] = strdup(argv_const[i]);
776  }
777  arguments arguments = {
778  .argc = 0, .argc_unknown = 0, .i = -1, .d = -1
779  };
780  ck_assert_int_eq(argpar_parse_args(&params, argc, argv, ARGPAR_ACCEPT_ANY, NULL, &arguments), 0);
781  ck_assert_int_eq(arguments.unknown, 1);
782 
783  for (i=0;i<argc;i++){
784  free(argv[i]);
785  }
786 
787  clean_arguments(&arguments);
788 
790  fclose(argpar_ostream);
791 }
792 END_TEST
793 
794 Suite* stub_suite(void){
795  Suite *s = suite_create("Stub");
796 
797  TCase *tc_core = tcase_create("Core");
798  tcase_add_test(tc_core, no_args_usage);
799  tcase_add_test(tc_core, no_real_args);
800  tcase_add_test(tc_core, auto_help);
801  tcase_add_test(tc_core, no_key_args);
802  tcase_add_test(tc_core, unknown_option);
803  tcase_add_test(tc_core, int_errors);
804  tcase_add_test(tc_core, dbl_errors);
805  tcase_add_test(tc_core, parfile1);
806  tcase_add_test(tc_core, children1);
807  tcase_add_test(tc_core, parse_parfile);
808  tcase_add_test(tc_core, parse_parfile_in_child);
809  tcase_add_test(tc_core, skip_parfiles);
810  tcase_add_test(tc_core, no_keyargs);
811  tcase_add_test(tc_core, no_keyargs_parfile);
812  tcase_add_test(tc_core, split_strings);
813  tcase_add_test(tc_core, split_strings_trim);
814  tcase_add_test(tc_core, split_int);
815  tcase_add_test(tc_core, split_dbl);
816  tcase_add_test(tc_core, aliases);
817  tcase_add_test(tc_core, accept_any);
818  suite_add_tcase(s, tc_core);
819 
820  return s;
821 }
822 
823 int main(int argc, char **argv){
824 
825 // int argc2 = 3;
826 // char *argv_const[] = {(char*)argpar_program_name, "help=params", "parfile=initial"};
827 // char *argv2[argc];
828 // int i;
829 // for (i=0;i<argc2;i++){
830 // argv2[i] = strdup(argv_const[i]);
831 // }
832 // arguments arguments = {0};
833 //
834 // printf("Return value: %d\n", argpar_parse_args(&params, argc2, argv2, 0, NULL, &arguments));
835 //
836 // clean_arguments(&arguments);
837 //
838 // argpar_clean(&params);
839 //
840 // for (i=0;i<argc2;i++){
841 // free(argv2[i]);
842 // }
843 //
844 // return 0;
845 
846  int number_failed;
847 
848  Suite *s = stub_suite();
849  SRunner *sr = srunner_create(s);
850 
851  srunner_run_all(sr, CK_VERBOSE);
852  number_failed = srunner_ntests_failed(sr);
853  srunner_free(sr);
854  return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
855 }
Master structure containing options, document strings, child parsers, and text filters....
Definition: argpar.h:398
#define EMPTY_INT
Definition: argpar.h:550
#define ARGPAR_KEY_END
Passed as the key to the parser callback function when there are no more arguments left to parse.
Definition: argpar.h:282
#define EXIT_SUCCESS
Definition: GEO_basic.h:72
char ** argpar_split_trim(char *str, const char *delim)
Splits a string on a delimiter, returning a NULL-terminated list of strings, trimming left and right ...
Definition: argpar.c:769
#define NULL
Definition: decode_rs.h:63
#define OPTION_INT
Cast this option as a long. The value and any error will be reflected in the argpar_state struct duri...
Definition: argpar.h:160
argpar_child children[]
Definition: argpar.c:424
int * argpar_split_int(char *str, const char *delim)
Splits a string on a delimiter, returning a NULL_INT-terminated list of ints.
Definition: argpar.c:785
long l
Definition: argpar.c:52
#define ARGPAR_ERR_USAGE
Returned from the parser callback to signal argpar to stop parsing, print a usage summary,...
Definition: argpar.h:338
#define ARGPAR_KEY_ARG
This is not an option at all, but rather a command line argument. If a parser receiving this key retu...
Definition: argpar.h:271
bool d_error
Definition: argpar.c:50
int argc_unknown
Definition: argpar.c:56
const char * ofile
Definition: argpar.c:45
arguments _
Definition: argpar.c:398
Child parser for nesting argpars.
Definition: argpar.h:377
#define ARGPAR_KEY_INIT
Passed as the key to each parser callback function before any parsing occurs. For most cases,...
Definition: argpar.h:287
#define OPTION_ATTR
This option serves to document additional attributes for an option. These are hidden from the normal ...
Definition: argpar.h:183
char * efile_src
Definition: argpar.c:48
double d
Definition: argpar.c:50
FILE * argpar_ostream
Definition: argpar.c:15
const char * efile
Definition: argpar.c:47
char stdout_file[64]
Definition: argpar.c:39
int argpar_parse_file(argpar *p, const char *path, unsigned flags, void *input)
Parse a key=value store file.
Definition: argpar.c:730
const char * argv_unknown[32]
Definition: argpar.c:55
#define ARGPAR_NO_KEYARGS
Passed to the argpar_parse_ functions, this tells the parser to accept options without equal signs,...
Definition: argpar.h:125
#define ARGPAR_ERR_UNKNOWN
What to return for unrecognized keys within an argpar_parser function.
Definition: argpar.h:341
int state(double tjdTDB, JPLIntUtilType *util, double posvel[13][6], double *pnut)
#define OPTION_ENUM
This option serves to document a valid value for an option. This is not enforced by argpar.
Definition: argpar.h:179
#define ARGPAR_NO_EXIT
Passed to the argpar_parse_ functions, this tells argpar not to call exit after printing help/usage,...
Definition: argpar.h:132
int unknown
Definition: argpar.c:58
argpar params_parent
Definition: argpar.c:425
int argpar_clean(argpar *p)
Free any space consumed by argpar for parfiles.
Definition: argpar.c:649
char * strdup(const char *)
const char * argv[32]
Definition: argpar.c:42
#define ARGPAR_ERR_ABORT
Returned from the parser callback to signal argpar to stop parsing and return to the caller.
Definition: argpar.h:334
const char * ifile
Definition: argpar.c:44
#define ARGPAR_SKIP_PARFILES
Passed to argpar_parse_args, this tells the parser to ignore parfile= arguments, useful for overwriti...
Definition: argpar.h:120
char * d_alias
Definition: argpar.c:51
bool l_error
Definition: argpar.c:52
int argpar_parse_args(argpar *p, unsigned argc, char *argv[], unsigned flags, unsigned *end_index, void *input)
Parse an array of key=value pairs and/or key arguments.
Definition: argpar.c:679
Definition: __init__.py:1
const char * argpar_program_name
Definition: argpar.c:16
bool ended
Definition: argpar.c:54
double * argpar_split_dbl(char *str, const char *delim)
Splits a string on a delimiter, returning a NAN-terminated list of doubles.
Definition: argpar.c:809
#define OPTION_ALIAS
Do not add an extra newline after this documentation string. Useful for lists and manual formatting.
Definition: argpar.h:175
#define OPTION_DOC
This option isn't actually an option, merely text for the usage summary.
Definition: argpar.h:152
State variable to be filled before each call to the parser callback.
Definition: argpar.h:196
START_TEST(no_args_usage)
Definition: argpar.c:139
Library for reading command-line arguments in the form of key=value.
char ** argpar_split_str(char *str, const char *delim)
Splits a string on a delimiter, returning a NULL-terminated list of strings.
Definition: argpar.c:744
data_t s[NROOTS]
Definition: decode_rs.h:75
END_TEST Suite * stub_suite(void)
Definition: argpar.c:794
int main(int argc, char **argv)
Definition: argpar.c:823
int argc
Definition: argpar.c:43
#define ARGPAR_ACCEPT_ANY
Passed to the argpar_parse_ functions, this tells argpar to call every parser with every option found...
Definition: argpar.h:136
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude resolving resolving GSFcd00179 Corrected handling of fill values for[Sensor|Solar][Zenith|Azimuth] resolving MODxl01751 Changed to validate LUT version against a value retrieved from the resolving MODxl02056 Changed to calculate Solar Diffuser angles without adjustment for estimated post launch changes in the MODIS orientation relative to incidentally resolving defects MODxl01766 Also resolves MODxl01947 Changed to ignore fill values in SCI_ABNORM and SCI_STATE rather than treating them as errors
Definition: HISTORY.txt:401
bool i_error
Definition: argpar.c:49
#define ARGPAR_KEY_UNKNOWN
Passed as the key to each parser callback function when an unknown option has been found....
Definition: argpar.h:307
int i
Definition: decode_rs.h:71
argpar params
Definition: argpar.c:137
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
PGE01 indicating that PGE02 PGE01 V6 for and PGE01 V2 for MOD03 were used to produce the granule By convention adopted in all MODIS Terra PGE02 code versions are The fourth digit of the PGE02 version denotes the LUT version used to produce the granule The source of the metadata environment variable ProcessingCenter was changed from a QA LUT value to the Process Configuration A sign used in error in the second order term was changed to a
Definition: HISTORY.txt:424
Stores the configuration for a par argument.
Definition: argpar.h:87
#define OPTION_DBL
Cast this option as a double. The value and any error will be reflected in the argpar_state struct du...
Definition: argpar.h:156
string tmpfile
Definition: l2mapgen.py:142
int i
Definition: argpar.c:49
char * ofile_src
Definition: argpar.c:46
#define NULL_INT
Definition: argpar.h:546