1 /*
2 File autogenerated by gengetopt version 2.23
3 generated with the following command:
4 /usr/bin/gengetopt -N --no-version --input=/home/andriish/Projects/HepMC3/examples/ConvertExample/cmdline.ggo --file-name cmdline --output-dir=/home/andriish/Projects/HepMC3/examples/ConvertExample --include-getopt --show-required --unnamed-opts=inputfile outputfile
5
6 The developers of gengetopt consider the fixed text that goes in all
7 gengetopt output files to be in the public domain:
8 we make no copyright claims on it.
9 */
10
11 /* If we use autoconf. */
12 #ifdef HAVE_CONFIG_H
13 #include "config.h"
14 #endif
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19
20 #ifndef FIX_UNUSED
21 #define FIX_UNUSED(X) (void) (X) /* avoid warnings for unused params */
22 #endif
23
24
25 #include "cmdline.h"
26
27 const char *gengetopt_args_info_purpose = "Convert between different file formats of Monte Carlo event record.\nExample:\n convert_example -i hepmc2 -o treeroot input.hepmc output.root\n";
28
29 const char *gengetopt_args_info_usage = "Usage: convert_example [OPTION]... [inputfile outputfile]...";
30
31 const char *gengetopt_args_info_versiontext = "";
32
33 const char *gengetopt_args_info_description = "";
34
35 const char *gengetopt_args_info_help[] = {
36 " -h, --help Print help and exit",
37 " -i, --input-format=STRING Input format (possible values=\"hepmc2\",\n \"auto\", \"hepmc3\", \"hpe\", \"root\",\n \"treeroot\", \"lhef\", \"gz\", \"uproot\", \"plugin\")\n (mandatory)",
38 " -o, --output-format=STRING Output format (possible values=\"hepmc2\",\n \"hepmc3\", \"hpe\", \"root\", \"treeroot\",\n \"treerootopal\", \"hpezeus\", \"dump\",\n \"plugin\", \"dot\", \"none\") (mandatory)",
39 " -e, --extensions=STRING Extensions, in a form extension=value, could be\n passed to readers/writers",
40 " --events-limit=LONG Limit of events to read from input\n (default=`100000000')",
41 " --first-event-number=LONG Lowest allowed event number\n (default=`-100000000')",
42 " --last-event-number=LONG Highest allowed event number\n (default=`100000000')",
43 " --print-every-events-parsed=LONG\n Frequency of parsing information printouts\n (default=`100')",
44 0
45 };
46
47 typedef enum {ARG_NO
48 , ARG_STRING
49 , ARG_LONG
50 } cmdline_parser_arg_type;
51
52 static
53 void clear_given (struct gengetopt_args_info *args_info);
54 static
55 void clear_args (struct gengetopt_args_info *args_info);
56
57 static int
58 cmdline_parser_internal (int argc, char **argv, struct gengetopt_args_info *args_info,
59 struct cmdline_parser_params *params, const char *additional_error);
60
61 static int
62 cmdline_parser_required2 (struct gengetopt_args_info *args_info, const char *prog_name, const char *additional_error);
63
64 const char *cmdline_parser_input_format_values[] = {"hepmc2", "auto", "hepmc3", "hpe", "root", "treeroot", "lhef", "gz","uproot", "plugin", 0}; /*< Possible values for input-format. */
65 const char *cmdline_parser_output_format_values[] = {"hepmc2", "hepmc3", "hpe", "root", "treeroot", "treerootopal", "hpezeus", "dump", "plugin", "dot", "none", 0}; /*< Possible values for output-format. */
66
67 static char *
68 gengetopt_strdup (const char *s);
69
70 static
clear_given(struct gengetopt_args_info * args_info)71 void clear_given (struct gengetopt_args_info *args_info)
72 {
73 args_info->help_given = 0 ;
74 args_info->input_format_given = 0 ;
75 args_info->output_format_given = 0 ;
76 args_info->extensions_given = 0 ;
77 args_info->events_limit_given = 0 ;
78 args_info->first_event_number_given = 0 ;
79 args_info->last_event_number_given = 0 ;
80 args_info->print_every_events_parsed_given = 0 ;
81 }
82
83 static
clear_args(struct gengetopt_args_info * args_info)84 void clear_args (struct gengetopt_args_info *args_info)
85 {
86 FIX_UNUSED (args_info);
87 args_info->input_format_arg = NULL;
88 args_info->input_format_orig = NULL;
89 args_info->output_format_arg = NULL;
90 args_info->output_format_orig = NULL;
91 args_info->extensions_arg = NULL;
92 args_info->extensions_orig = NULL;
93 args_info->events_limit_arg = 100000000;
94 args_info->events_limit_orig = NULL;
95 args_info->first_event_number_arg = -100000000;
96 args_info->first_event_number_orig = NULL;
97 args_info->last_event_number_arg = 100000000;
98 args_info->last_event_number_orig = NULL;
99 args_info->print_every_events_parsed_arg = 100;
100 args_info->print_every_events_parsed_orig = NULL;
101
102 }
103
104 static
init_args_info(struct gengetopt_args_info * args_info)105 void init_args_info(struct gengetopt_args_info *args_info)
106 {
107
108
109 args_info->help_help = gengetopt_args_info_help[0] ;
110 args_info->input_format_help = gengetopt_args_info_help[1] ;
111 args_info->output_format_help = gengetopt_args_info_help[2] ;
112 args_info->extensions_help = gengetopt_args_info_help[3] ;
113 args_info->extensions_min = 0;
114 args_info->extensions_max = 0;
115 args_info->events_limit_help = gengetopt_args_info_help[4] ;
116 args_info->first_event_number_help = gengetopt_args_info_help[5] ;
117 args_info->last_event_number_help = gengetopt_args_info_help[6] ;
118 args_info->print_every_events_parsed_help = gengetopt_args_info_help[7] ;
119
120 }
121
122 void
cmdline_parser_print_version(void)123 cmdline_parser_print_version (void)
124 {
125 printf ("%s %s\n",
126 (strlen(CMDLINE_PARSER_PACKAGE_NAME) ? CMDLINE_PARSER_PACKAGE_NAME : CMDLINE_PARSER_PACKAGE),
127 CMDLINE_PARSER_VERSION);
128
129 if (strlen(gengetopt_args_info_versiontext) > 0)
130 printf("\n%s\n", gengetopt_args_info_versiontext);
131 }
132
print_help_common(void)133 static void print_help_common(void)
134 {
135 size_t len_purpose = strlen(gengetopt_args_info_purpose);
136 size_t len_usage = strlen(gengetopt_args_info_usage);
137
138 if (len_usage > 0) {
139 printf("%s\n", gengetopt_args_info_usage);
140 }
141 if (len_purpose > 0) {
142 printf("%s\n", gengetopt_args_info_purpose);
143 }
144
145 if (len_usage || len_purpose) {
146 printf("\n");
147 }
148
149 if (strlen(gengetopt_args_info_description) > 0) {
150 printf("%s\n\n", gengetopt_args_info_description);
151 }
152 }
153
154 void
cmdline_parser_print_help(void)155 cmdline_parser_print_help (void)
156 {
157 int i = 0;
158 print_help_common();
159 while (gengetopt_args_info_help[i])
160 printf("%s\n", gengetopt_args_info_help[i++]);
161 }
162
163 void
cmdline_parser_init(struct gengetopt_args_info * args_info)164 cmdline_parser_init (struct gengetopt_args_info *args_info)
165 {
166 clear_given (args_info);
167 clear_args (args_info);
168 init_args_info (args_info);
169
170 args_info->inputs = 0;
171 args_info->inputs_num = 0;
172 }
173
174 void
cmdline_parser_params_init(struct cmdline_parser_params * params)175 cmdline_parser_params_init(struct cmdline_parser_params *params)
176 {
177 if (params)
178 {
179 params->override = 0;
180 params->initialize = 1;
181 params->check_required = 1;
182 params->check_ambiguity = 0;
183 params->print_errors = 1;
184 }
185 }
186
187 struct cmdline_parser_params *
cmdline_parser_params_create(void)188 cmdline_parser_params_create(void)
189 {
190 struct cmdline_parser_params *params =
191 (struct cmdline_parser_params *)malloc(sizeof(struct cmdline_parser_params));
192 cmdline_parser_params_init(params);
193 return params;
194 }
195
196 static void
free_string_field(char ** s)197 free_string_field (char **s)
198 {
199 if (*s)
200 {
201 free (*s);
202 *s = 0;
203 }
204 }
205
206 /** @brief generic value variable */
207 union generic_value {
208 long long_arg;
209 char *string_arg;
210 const char *default_string_arg;
211 };
212
213 /** @brief holds temporary values for multiple options */
214 struct generic_list
215 {
216 union generic_value arg;
217 char *orig;
218 struct generic_list *next;
219 };
220
221 /**
222 * @brief add a node at the head of the list
223 */
add_node(struct generic_list ** list)224 static void add_node(struct generic_list **list) {
225 struct generic_list *new_node = (struct generic_list *) malloc (sizeof (struct generic_list));
226 new_node->next = *list;
227 *list = new_node;
228 new_node->arg.string_arg = 0;
229 new_node->orig = 0;
230 }
231
232
233 static void
free_multiple_string_field(unsigned int len,char *** arg,char *** orig)234 free_multiple_string_field(unsigned int len, char ***arg, char ***orig)
235 {
236 unsigned int i;
237 if (*arg) {
238 for (i = 0; i < len; ++i)
239 {
240 free_string_field(&((*arg)[i]));
241 free_string_field(&((*orig)[i]));
242 }
243 free_string_field(&((*arg)[0])); /* free default string */
244
245 free (*arg);
246 *arg = 0;
247 free (*orig);
248 *orig = 0;
249 }
250 }
251
252 static void
cmdline_parser_release(struct gengetopt_args_info * args_info)253 cmdline_parser_release (struct gengetopt_args_info *args_info)
254 {
255 unsigned int i;
256 free_string_field (&(args_info->input_format_arg));
257 free_string_field (&(args_info->input_format_orig));
258 free_string_field (&(args_info->output_format_arg));
259 free_string_field (&(args_info->output_format_orig));
260 free_multiple_string_field (args_info->extensions_given, &(args_info->extensions_arg), &(args_info->extensions_orig));
261 free_string_field (&(args_info->events_limit_orig));
262 free_string_field (&(args_info->first_event_number_orig));
263 free_string_field (&(args_info->last_event_number_orig));
264 free_string_field (&(args_info->print_every_events_parsed_orig));
265
266
267 for (i = 0; i < args_info->inputs_num; ++i)
268 free (args_info->inputs [i]);
269
270 if (args_info->inputs_num)
271 free (args_info->inputs);
272
273 clear_given (args_info);
274 }
275
276 /**
277 * @param val the value to check
278 * @param values the possible values
279 * @return the index of the matched value:
280 * -1 if no value matched,
281 * -2 if more than one value has matched
282 */
283 static int
check_possible_values(const char * val,const char * values[])284 check_possible_values(const char *val, const char *values[])
285 {
286 int i, found, last;
287 size_t len;
288
289 if (!val) /* otherwise strlen() crashes below */
290 return -1; /* -1 means no argument for the option */
291
292 found = last = 0;
293
294 for (i = 0, len = strlen(val); values[i]; ++i)
295 {
296 if (strncmp(val, values[i], len) == 0)
297 {
298 ++found;
299 last = i;
300 if (strlen(values[i]) == len)
301 return i; /* exact macth no need to check more */
302 }
303 }
304
305 if (found == 1) /* one match: OK */
306 return last;
307
308 return (found ? -2 : -1); /* return many values or none matched */
309 }
310
311
312 static void
write_into_file(FILE * outfile,const char * opt,const char * arg,const char * values[])313 write_into_file(FILE *outfile, const char *opt, const char *arg, const char *values[])
314 {
315 int found = -1;
316 if (arg) {
317 if (values) {
318 found = check_possible_values(arg, values);
319 }
320 if (found >= 0)
321 fprintf(outfile, "%s=\"%s\" # %s\n", opt, arg, values[found]);
322 else
323 fprintf(outfile, "%s=\"%s\"\n", opt, arg);
324 } else {
325 fprintf(outfile, "%s\n", opt);
326 }
327 }
328
329 static void
write_multiple_into_file(FILE * outfile,int len,const char * opt,char ** arg,const char * values[])330 write_multiple_into_file(FILE *outfile, int len, const char *opt, char **arg, const char *values[])
331 {
332 int i;
333
334 for (i = 0; i < len; ++i)
335 write_into_file(outfile, opt, (arg ? arg[i] : 0), values);
336 }
337
338 int
cmdline_parser_dump(FILE * outfile,struct gengetopt_args_info * args_info)339 cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info)
340 {
341 int i = 0;
342
343 if (!outfile)
344 {
345 fprintf (stderr, "%s: cannot dump options to stream\n", CMDLINE_PARSER_PACKAGE);
346 return EXIT_FAILURE;
347 }
348
349 if (args_info->help_given)
350 write_into_file(outfile, "help", 0, 0 );
351 if (args_info->input_format_given)
352 write_into_file(outfile, "input-format", args_info->input_format_orig, cmdline_parser_input_format_values);
353 if (args_info->output_format_given)
354 write_into_file(outfile, "output-format", args_info->output_format_orig, cmdline_parser_output_format_values);
355 write_multiple_into_file(outfile, args_info->extensions_given, "extensions", args_info->extensions_orig, 0);
356 if (args_info->events_limit_given)
357 write_into_file(outfile, "events-limit", args_info->events_limit_orig, 0);
358 if (args_info->first_event_number_given)
359 write_into_file(outfile, "first-event-number", args_info->first_event_number_orig, 0);
360 if (args_info->last_event_number_given)
361 write_into_file(outfile, "last-event-number", args_info->last_event_number_orig, 0);
362 if (args_info->print_every_events_parsed_given)
363 write_into_file(outfile, "print-every-events-parsed", args_info->print_every_events_parsed_orig, 0);
364
365
366 i = EXIT_SUCCESS;
367 return i;
368 }
369
370 int
cmdline_parser_file_save(const char * filename,struct gengetopt_args_info * args_info)371 cmdline_parser_file_save(const char *filename, struct gengetopt_args_info *args_info)
372 {
373 FILE *outfile;
374 int i = 0;
375
376 outfile = fopen(filename, "w");
377
378 if (!outfile)
379 {
380 fprintf (stderr, "%s: cannot open file for writing: %s\n", CMDLINE_PARSER_PACKAGE, filename);
381 return EXIT_FAILURE;
382 }
383
384 i = cmdline_parser_dump(outfile, args_info);
385 fclose (outfile);
386
387 return i;
388 }
389
390 void
cmdline_parser_free(struct gengetopt_args_info * args_info)391 cmdline_parser_free (struct gengetopt_args_info *args_info)
392 {
393 cmdline_parser_release (args_info);
394 }
395
396 /** @brief replacement of strdup, which is not standard */
397 char *
gengetopt_strdup(const char * s)398 gengetopt_strdup (const char *s)
399 {
400 char *result = 0;
401 if (!s)
402 return result;
403
404 result = (char*)malloc(strlen(s) + 1);
405 if (result == (char*)0)
406 return (char*)0;
407 strcpy(result, s);
408 return result;
409 }
410
411 static char *
get_multiple_arg_token(const char * arg)412 get_multiple_arg_token(const char *arg)
413 {
414 const char *tok;
415 char *ret;
416 size_t len, num_of_escape, i, j;
417
418 if (!arg)
419 return 0;
420
421 tok = strchr (arg, ',');
422 num_of_escape = 0;
423
424 /* make sure it is not escaped */
425 while (tok)
426 {
427 if (*(tok-1) == '\\')
428 {
429 /* find the next one */
430 tok = strchr (tok+1, ',');
431 ++num_of_escape;
432 }
433 else
434 break;
435 }
436
437 if (tok)
438 len = (size_t)(tok - arg + 1);
439 else
440 len = strlen (arg) + 1;
441
442 len -= num_of_escape;
443
444 ret = (char *) malloc (len);
445
446 i = 0;
447 j = 0;
448 while (arg[i] && (j < len-1))
449 {
450 if (arg[i] == '\\' &&
451 arg[ i + 1 ] &&
452 arg[ i + 1 ] == ',')
453 ++i;
454
455 ret[j++] = arg[i++];
456 }
457
458 ret[len-1] = '\0';
459
460 return ret;
461 }
462
463 static const char *
get_multiple_arg_token_next(const char * arg)464 get_multiple_arg_token_next(const char *arg)
465 {
466 const char *tok;
467
468 if (!arg)
469 return 0;
470
471 tok = strchr (arg, ',');
472
473 /* make sure it is not escaped */
474 while (tok)
475 {
476 if (*(tok-1) == '\\')
477 {
478 /* find the next one */
479 tok = strchr (tok+1, ',');
480 }
481 else
482 break;
483 }
484
485 if (! tok || strlen(tok) == 1)
486 return 0;
487
488 return tok+1;
489 }
490
491 static int
492 check_multiple_option_occurrences(const char *prog_name, unsigned int option_given, unsigned int min, unsigned int max, const char *option_desc);
493
494 int
check_multiple_option_occurrences(const char * prog_name,unsigned int option_given,unsigned int min,unsigned int max,const char * option_desc)495 check_multiple_option_occurrences(const char *prog_name, unsigned int option_given, unsigned int min, unsigned int max, const char *option_desc)
496 {
497 int error_occurred = 0;
498
499 if (option_given && (min > 0 || max > 0))
500 {
501 if (min > 0 && max > 0)
502 {
503 if (min == max)
504 {
505 /* specific occurrences */
506 if (option_given != (unsigned int) min)
507 {
508 fprintf (stderr, "%s: %s option occurrences must be %d\n",
509 prog_name, option_desc, min);
510 error_occurred = 1;
511 }
512 }
513 else if (option_given < (unsigned int) min
514 || option_given > (unsigned int) max)
515 {
516 /* range occurrences */
517 fprintf (stderr, "%s: %s option occurrences must be between %d and %d\n",
518 prog_name, option_desc, min, max);
519 error_occurred = 1;
520 }
521 }
522 else if (min > 0)
523 {
524 /* at least check */
525 if (option_given < min)
526 {
527 fprintf (stderr, "%s: %s option occurrences must be at least %d\n",
528 prog_name, option_desc, min);
529 error_occurred = 1;
530 }
531 }
532 else if (max > 0)
533 {
534 /* at most check */
535 if (option_given > max)
536 {
537 fprintf (stderr, "%s: %s option occurrences must be at most %d\n",
538 prog_name, option_desc, max);
539 error_occurred = 1;
540 }
541 }
542 }
543
544 return error_occurred;
545 }
546 int
cmdline_parser(int argc,char ** argv,struct gengetopt_args_info * args_info)547 cmdline_parser (int argc, char **argv, struct gengetopt_args_info *args_info)
548 {
549 return cmdline_parser2 (argc, argv, args_info, 0, 1, 1);
550 }
551
552 int
cmdline_parser_ext(int argc,char ** argv,struct gengetopt_args_info * args_info,struct cmdline_parser_params * params)553 cmdline_parser_ext (int argc, char **argv, struct gengetopt_args_info *args_info,
554 struct cmdline_parser_params *params)
555 {
556 int result;
557 result = cmdline_parser_internal (argc, argv, args_info, params, 0);
558
559 if (result == EXIT_FAILURE)
560 {
561 cmdline_parser_free (args_info);
562 exit (EXIT_FAILURE);
563 }
564
565 return result;
566 }
567
568 int
cmdline_parser2(int argc,char ** argv,struct gengetopt_args_info * args_info,int override,int initialize,int check_required)569 cmdline_parser2 (int argc, char **argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required)
570 {
571 int result;
572 struct cmdline_parser_params params;
573
574 params.override = override;
575 params.initialize = initialize;
576 params.check_required = check_required;
577 params.check_ambiguity = 0;
578 params.print_errors = 1;
579
580 result = cmdline_parser_internal (argc, argv, args_info, ¶ms, 0);
581
582 if (result == EXIT_FAILURE)
583 {
584 cmdline_parser_free (args_info);
585 exit (EXIT_FAILURE);
586 }
587
588 return result;
589 }
590
591 int
cmdline_parser_required(struct gengetopt_args_info * args_info,const char * prog_name)592 cmdline_parser_required (struct gengetopt_args_info *args_info, const char *prog_name)
593 {
594 int result = EXIT_SUCCESS;
595
596 if (cmdline_parser_required2(args_info, prog_name, 0) > 0)
597 result = EXIT_FAILURE;
598
599 if (result == EXIT_FAILURE)
600 {
601 cmdline_parser_free (args_info);
602 exit (EXIT_FAILURE);
603 }
604
605 return result;
606 }
607
608 int
cmdline_parser_required2(struct gengetopt_args_info * args_info,const char * prog_name,const char * additional_error)609 cmdline_parser_required2 (struct gengetopt_args_info *args_info, const char *prog_name, const char *additional_error)
610 {
611 int error_occurred = 0;
612 FIX_UNUSED (additional_error);
613
614 /* checks for required options */
615 if (! args_info->input_format_given)
616 {
617 fprintf (stderr, "%s: '--input-format' ('-i') option required%s\n", prog_name, (additional_error ? additional_error : ""));
618 error_occurred = 1;
619 }
620
621 if (! args_info->output_format_given)
622 {
623 fprintf (stderr, "%s: '--output-format' ('-o') option required%s\n", prog_name, (additional_error ? additional_error : ""));
624 error_occurred = 1;
625 }
626
627 if (check_multiple_option_occurrences(prog_name, args_info->extensions_given, args_info->extensions_min, args_info->extensions_max, "'--extensions' ('-e')"))
628 error_occurred = 1;
629
630
631 /* checks for dependences among options */
632
633 return error_occurred;
634 }
635
636 /*
637 * Extracted from the glibc source tree, version 2.3.6
638 *
639 * Licensed under the GPL as per the whole glibc source tree.
640 *
641 * This file was modified so that getopt_long can be called
642 * many times without risking previous memory to be spoiled.
643 *
644 * Modified by Andre Noll and Lorenzo Bettini for use in
645 * GNU gengetopt generated files.
646 *
647 */
648
649 /*
650 * we must include anything we need since this file is not thought to be
651 * inserted in a file already using getopt.h
652 *
653 * Lorenzo
654 */
655
656 struct option
657 {
658 const char *name;
659 /* has_arg can't be an enum because some compilers complain about
660 type mismatches in all the code that assumes it is an int. */
661 int has_arg;
662 int *flag;
663 int val;
664 };
665
666 /* This version of `getopt' appears to the caller like standard Unix `getopt'
667 but it behaves differently for the user, since it allows the user
668 to intersperse the options with the other arguments.
669
670 As `getopt' works, it permutes the elements of ARGV so that,
671 when it is done, all the options precede everything else. Thus
672 all application programs are extended to handle flexible argument order.
673 */
674 /*
675 If the field `flag' is not NULL, it points to a variable that is set
676 to the value given in the field `val' when the option is found, but
677 left unchanged if the option is not found.
678
679 To have a long-named option do something other than set an `int' to
680 a compiled-in constant, such as set a value from `custom_optarg', set the
681 option's `flag' field to zero and its `val' field to a nonzero
682 value (the equivalent single-letter option character, if there is
683 one). For long options that have a zero `flag' field, `getopt'
684 returns the contents of the `val' field. */
685
686 /* Names for the values of the `has_arg' field of `struct option'. */
687 #ifndef no_argument
688 #define no_argument 0
689 #endif
690
691 #ifndef required_argument
692 #define required_argument 1
693 #endif
694
695 #ifndef optional_argument
696 #define optional_argument 2
697 #endif
698
699 struct custom_getopt_data {
700 /*
701 * These have exactly the same meaning as the corresponding global variables,
702 * except that they are used for the reentrant versions of getopt.
703 */
704 int custom_optind;
705 int custom_opterr;
706 int custom_optopt;
707 char *custom_optarg;
708
709 /* True if the internal members have been initialized. */
710 int initialized;
711
712 /*
713 * The next char to be scanned in the option-element in which the last option
714 * character we returned was found. This allows us to pick up the scan where
715 * we left off. If this is zero, or a null string, it means resume the scan by
716 * advancing to the next ARGV-element.
717 */
718 char *nextchar;
719
720 /*
721 * Describe the part of ARGV that contains non-options that have been skipped.
722 * `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is
723 * the index after the last of them.
724 */
725 int first_nonopt;
726 int last_nonopt;
727 };
728
729 /*
730 * the variables optarg, optind, opterr and optopt are renamed with
731 * the custom_ prefix so that they don't interfere with getopt ones.
732 *
733 * Moreover they're static so they are visible only from within the
734 * file where this very file will be included.
735 */
736
737 /*
738 * For communication from `custom_getopt' to the caller. When `custom_getopt' finds an
739 * option that takes an argument, the argument value is returned here.
740 */
741 static char *custom_optarg;
742
743 /*
744 * Index in ARGV of the next element to be scanned. This is used for
745 * communication to and from the caller and for communication between
746 * successive calls to `custom_getopt'.
747 *
748 * On entry to `custom_getopt', 1 means this is the first call; initialize.
749 *
750 * When `custom_getopt' returns -1, this is the index of the first of the non-option
751 * elements that the caller should itself scan.
752 *
753 * Otherwise, `custom_optind' communicates from one call to the next how much of ARGV
754 * has been scanned so far.
755 *
756 * 1003.2 says this must be 1 before any call.
757 */
758 static int custom_optind = 1;
759
760 /*
761 * Callers store zero here to inhibit the error message for unrecognized
762 * options.
763 */
764 static int custom_opterr = 1;
765
766 /*
767 * Set to an option character which was unrecognized. This must be initialized
768 * on some systems to avoid linking in the system's own getopt implementation.
769 */
770 static int custom_optopt = '?';
771
772 /*
773 * Exchange two adjacent subsequences of ARGV. One subsequence is elements
774 * [first_nonopt,last_nonopt) which contains all the non-options that have been
775 * skipped so far. The other is elements [last_nonopt,custom_optind), which contains
776 * all the options processed since those non-options were skipped.
777 * `first_nonopt' and `last_nonopt' are relocated so that they describe the new
778 * indices of the non-options in ARGV after they are moved.
779 */
exchange(char ** argv,struct custom_getopt_data * d)780 static void exchange(char **argv, struct custom_getopt_data *d)
781 {
782 int bottom = d->first_nonopt;
783 int middle = d->last_nonopt;
784 int top = d->custom_optind;
785 char *tem;
786
787 /*
788 * Exchange the shorter segment with the far end of the longer segment.
789 * That puts the shorter segment into the right place. It leaves the
790 * longer segment in the right place overall, but it consists of two
791 * parts that need to be swapped next.
792 */
793 while (top > middle && middle > bottom) {
794 if (top - middle > middle - bottom) {
795 /* Bottom segment is the short one. */
796 int len = middle - bottom;
797 int i;
798
799 /* Swap it with the top part of the top segment. */
800 for (i = 0; i < len; i++) {
801 tem = argv[bottom + i];
802 argv[bottom + i] =
803 argv[top - (middle - bottom) + i];
804 argv[top - (middle - bottom) + i] = tem;
805 }
806 /* Exclude the moved bottom segment from further swapping. */
807 top -= len;
808 } else {
809 /* Top segment is the short one. */
810 int len = top - middle;
811 int i;
812
813 /* Swap it with the bottom part of the bottom segment. */
814 for (i = 0; i < len; i++) {
815 tem = argv[bottom + i];
816 argv[bottom + i] = argv[middle + i];
817 argv[middle + i] = tem;
818 }
819 /* Exclude the moved top segment from further swapping. */
820 bottom += len;
821 }
822 }
823 /* Update records for the slots the non-options now occupy. */
824 d->first_nonopt += (d->custom_optind - d->last_nonopt);
825 d->last_nonopt = d->custom_optind;
826 }
827
828 /* Initialize the internal data when the first call is made. */
custom_getopt_initialize(struct custom_getopt_data * d)829 static void custom_getopt_initialize(struct custom_getopt_data *d)
830 {
831 /*
832 * Start processing options with ARGV-element 1 (since ARGV-element 0
833 * is the program name); the sequence of previously skipped non-option
834 * ARGV-elements is empty.
835 */
836 d->first_nonopt = d->last_nonopt = d->custom_optind;
837 d->nextchar = NULL;
838 d->initialized = 1;
839 }
840
841 #define NONOPTION_P (argv[d->custom_optind][0] != '-' || argv[d->custom_optind][1] == '\0')
842
843 /* return: zero: continue, nonzero: return given value to user */
shuffle_argv(int argc,char * const * argv,const struct option * longopts,struct custom_getopt_data * d)844 static int shuffle_argv(int argc, char *const *argv,const struct option *longopts,
845 struct custom_getopt_data *d)
846 {
847 /*
848 * Give FIRST_NONOPT & LAST_NONOPT rational values if CUSTOM_OPTIND has been
849 * moved back by the user (who may also have changed the arguments).
850 */
851 if (d->last_nonopt > d->custom_optind)
852 d->last_nonopt = d->custom_optind;
853 if (d->first_nonopt > d->custom_optind)
854 d->first_nonopt = d->custom_optind;
855 /*
856 * If we have just processed some options following some
857 * non-options, exchange them so that the options come first.
858 */
859 if (d->first_nonopt != d->last_nonopt &&
860 d->last_nonopt != d->custom_optind)
861 exchange((char **) argv, d);
862 else if (d->last_nonopt != d->custom_optind)
863 d->first_nonopt = d->custom_optind;
864 /*
865 * Skip any additional non-options and extend the range of
866 * non-options previously skipped.
867 */
868 while (d->custom_optind < argc && NONOPTION_P)
869 d->custom_optind++;
870 d->last_nonopt = d->custom_optind;
871 /*
872 * The special ARGV-element `--' means premature end of options. Skip
873 * it like a null option, then exchange with previous non-options as if
874 * it were an option, then skip everything else like a non-option.
875 */
876 if (d->custom_optind != argc && !strcmp(argv[d->custom_optind], "--")) {
877 d->custom_optind++;
878 if (d->first_nonopt != d->last_nonopt
879 && d->last_nonopt != d->custom_optind)
880 exchange((char **) argv, d);
881 else if (d->first_nonopt == d->last_nonopt)
882 d->first_nonopt = d->custom_optind;
883 d->last_nonopt = argc;
884 d->custom_optind = argc;
885 }
886 /*
887 * If we have done all the ARGV-elements, stop the scan and back over
888 * any non-options that we skipped and permuted.
889 */
890 if (d->custom_optind == argc) {
891 /*
892 * Set the next-arg-index to point at the non-options that we
893 * previously skipped, so the caller will digest them.
894 */
895 if (d->first_nonopt != d->last_nonopt)
896 d->custom_optind = d->first_nonopt;
897 return -1;
898 }
899 /*
900 * If we have come to a non-option and did not permute it, either stop
901 * the scan or describe it to the caller and pass it by.
902 */
903 if (NONOPTION_P) {
904 d->custom_optarg = argv[d->custom_optind++];
905 return 1;
906 }
907 /*
908 * We have found another option-ARGV-element. Skip the initial
909 * punctuation.
910 */
911 d->nextchar = (argv[d->custom_optind] + 1 + (longopts != NULL && argv[d->custom_optind][1] == '-'));
912 return 0;
913 }
914
915 /*
916 * Check whether the ARGV-element is a long option.
917 *
918 * If there's a long option "fubar" and the ARGV-element is "-fu", consider
919 * that an abbreviation of the long option, just like "--fu", and not "-f" with
920 * arg "u".
921 *
922 * This distinction seems to be the most useful approach.
923 *
924 */
check_long_opt(int argc,char * const * argv,const char * optstring,const struct option * longopts,int * longind,int print_errors,struct custom_getopt_data * d)925 static int check_long_opt(int argc, char *const *argv, const char *optstring,
926 const struct option *longopts, int *longind,
927 int print_errors, struct custom_getopt_data *d)
928 {
929 char *nameend;
930 const struct option *p;
931 const struct option *pfound = NULL;
932 int exact = 0;
933 int ambig = 0;
934 int indfound = -1;
935 int option_index;
936
937 for (nameend = d->nextchar; *nameend && *nameend != '='; nameend++)
938 /* Do nothing. */ ;
939
940 /* Test all long options for either exact match or abbreviated matches */
941 for (p = longopts, option_index = 0; p->name; p++, option_index++)
942 if (!strncmp(p->name, d->nextchar, nameend - d->nextchar)) {
943 if ((unsigned int) (nameend - d->nextchar)
944 == (unsigned int) strlen(p->name)) {
945 /* Exact match found. */
946 pfound = p;
947 indfound = option_index;
948 exact = 1;
949 break;
950 } else if (pfound == NULL) {
951 /* First nonexact match found. */
952 pfound = p;
953 indfound = option_index;
954 } else if (pfound->has_arg != p->has_arg
955 || pfound->flag != p->flag
956 || pfound->val != p->val)
957 /* Second or later nonexact match found. */
958 ambig = 1;
959 }
960 if (ambig && !exact) {
961 if (print_errors) {
962 fprintf(stderr,
963 "%s: option `%s' is ambiguous\n",
964 argv[0], argv[d->custom_optind]);
965 }
966 d->nextchar += strlen(d->nextchar);
967 d->custom_optind++;
968 d->custom_optopt = 0;
969 return '?';
970 }
971 if (pfound) {
972 option_index = indfound;
973 d->custom_optind++;
974 if (*nameend) {
975 if (pfound->has_arg != no_argument)
976 d->custom_optarg = nameend + 1;
977 else {
978 if (print_errors) {
979 if (argv[d->custom_optind - 1][1] == '-') {
980 /* --option */
981 fprintf(stderr, "%s: option `--%s' doesn't allow an argument\n",
982 argv[0], pfound->name);
983 } else {
984 /* +option or -option */
985 fprintf(stderr, "%s: option `%c%s' doesn't allow an argument\n",
986 argv[0], argv[d->custom_optind - 1][0], pfound->name);
987 }
988
989 }
990 d->nextchar += strlen(d->nextchar);
991 d->custom_optopt = pfound->val;
992 return '?';
993 }
994 } else if (pfound->has_arg == required_argument) {
995 if (d->custom_optind < argc)
996 d->custom_optarg = argv[d->custom_optind++];
997 else {
998 if (print_errors) {
999 fprintf(stderr,
1000 "%s: option `%s' requires an argument\n",
1001 argv[0],
1002 argv[d->custom_optind - 1]);
1003 }
1004 d->nextchar += strlen(d->nextchar);
1005 d->custom_optopt = pfound->val;
1006 return optstring[0] == ':' ? ':' : '?';
1007 }
1008 }
1009 d->nextchar += strlen(d->nextchar);
1010 if (longind != NULL)
1011 *longind = option_index;
1012 if (pfound->flag) {
1013 *(pfound->flag) = pfound->val;
1014 return 0;
1015 }
1016 return pfound->val;
1017 }
1018 /*
1019 * Can't find it as a long option. If this is not getopt_long_only, or
1020 * the option starts with '--' or is not a valid short option, then
1021 * it's an error. Otherwise interpret it as a short option.
1022 */
1023 if (print_errors) {
1024 if (argv[d->custom_optind][1] == '-') {
1025 /* --option */
1026 fprintf(stderr,
1027 "%s: unrecognized option `--%s'\n",
1028 argv[0], d->nextchar);
1029 } else {
1030 /* +option or -option */
1031 fprintf(stderr,
1032 "%s: unrecognized option `%c%s'\n",
1033 argv[0], argv[d->custom_optind][0],
1034 d->nextchar);
1035 }
1036 }
1037 d->nextchar = (char *) "";
1038 d->custom_optind++;
1039 d->custom_optopt = 0;
1040 return '?';
1041 }
1042
check_short_opt(int argc,char * const * argv,const char * optstring,int print_errors,struct custom_getopt_data * d)1043 static int check_short_opt(int argc, char *const *argv, const char *optstring,
1044 int print_errors, struct custom_getopt_data *d)
1045 {
1046 char c = *d->nextchar++;
1047 const char *temp = strchr(optstring, c);
1048
1049 /* Increment `custom_optind' when we start to process its last character. */
1050 if (*d->nextchar == '\0')
1051 ++d->custom_optind;
1052 if (!temp || c == ':') {
1053 if (print_errors)
1054 fprintf(stderr, "%s: invalid option -- %c\n", argv[0], c);
1055
1056 d->custom_optopt = c;
1057 return '?';
1058 }
1059 if (temp[1] == ':') {
1060 if (temp[2] == ':') {
1061 /* This is an option that accepts an argument optionally. */
1062 if (*d->nextchar != '\0') {
1063 d->custom_optarg = d->nextchar;
1064 d->custom_optind++;
1065 } else
1066 d->custom_optarg = NULL;
1067 d->nextchar = NULL;
1068 } else {
1069 /* This is an option that requires an argument. */
1070 if (*d->nextchar != '\0') {
1071 d->custom_optarg = d->nextchar;
1072 /*
1073 * If we end this ARGV-element by taking the
1074 * rest as an arg, we must advance to the next
1075 * element now.
1076 */
1077 d->custom_optind++;
1078 } else if (d->custom_optind == argc) {
1079 if (print_errors) {
1080 fprintf(stderr,
1081 "%s: option requires an argument -- %c\n",
1082 argv[0], c);
1083 }
1084 d->custom_optopt = c;
1085 if (optstring[0] == ':')
1086 c = ':';
1087 else
1088 c = '?';
1089 } else
1090 /*
1091 * We already incremented `custom_optind' once;
1092 * increment it again when taking next ARGV-elt
1093 * as argument.
1094 */
1095 d->custom_optarg = argv[d->custom_optind++];
1096 d->nextchar = NULL;
1097 }
1098 }
1099 return c;
1100 }
1101
1102 /*
1103 * Scan elements of ARGV for option characters given in OPTSTRING.
1104 *
1105 * If an element of ARGV starts with '-', and is not exactly "-" or "--",
1106 * then it is an option element. The characters of this element
1107 * (aside from the initial '-') are option characters. If `getopt'
1108 * is called repeatedly, it returns successively each of the option characters
1109 * from each of the option elements.
1110 *
1111 * If `getopt' finds another option character, it returns that character,
1112 * updating `custom_optind' and `nextchar' so that the next call to `getopt' can
1113 * resume the scan with the following option character or ARGV-element.
1114 *
1115 * If there are no more option characters, `getopt' returns -1.
1116 * Then `custom_optind' is the index in ARGV of the first ARGV-element
1117 * that is not an option. (The ARGV-elements have been permuted
1118 * so that those that are not options now come last.)
1119 *
1120 * OPTSTRING is a string containing the legitimate option characters.
1121 * If an option character is seen that is not listed in OPTSTRING,
1122 * return '?' after printing an error message. If you set `custom_opterr' to
1123 * zero, the error message is suppressed but we still return '?'.
1124 *
1125 * If a char in OPTSTRING is followed by a colon, that means it wants an arg,
1126 * so the following text in the same ARGV-element, or the text of the following
1127 * ARGV-element, is returned in `custom_optarg'. Two colons mean an option that
1128 * wants an optional arg; if there is text in the current ARGV-element,
1129 * it is returned in `custom_optarg', otherwise `custom_optarg' is set to zero.
1130 *
1131 * If OPTSTRING starts with `-' or `+', it requests different methods of
1132 * handling the non-option ARGV-elements.
1133 * See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
1134 *
1135 * Long-named options begin with `--' instead of `-'.
1136 * Their names may be abbreviated as long as the abbreviation is unique
1137 * or is an exact match for some defined option. If they have an
1138 * argument, it follows the option name in the same ARGV-element, separated
1139 * from the option name by a `=', or else the in next ARGV-element.
1140 * When `getopt' finds a long-named option, it returns 0 if that option's
1141 * `flag' field is nonzero, the value of the option's `val' field
1142 * if the `flag' field is zero.
1143 *
1144 * The elements of ARGV aren't really const, because we permute them.
1145 * But we pretend they're const in the prototype to be compatible
1146 * with other systems.
1147 *
1148 * LONGOPTS is a vector of `struct option' terminated by an
1149 * element containing a name which is zero.
1150 *
1151 * LONGIND returns the index in LONGOPT of the long-named option found.
1152 * It is only valid when a long-named option has been found by the most
1153 * recent call.
1154 *
1155 * Return the option character from OPTS just read. Return -1 when there are
1156 * no more options. For unrecognized options, or options missing arguments,
1157 * `custom_optopt' is set to the option letter, and '?' is returned.
1158 *
1159 * The OPTS string is a list of characters which are recognized option letters,
1160 * optionally followed by colons, specifying that that letter takes an
1161 * argument, to be placed in `custom_optarg'.
1162 *
1163 * If a letter in OPTS is followed by two colons, its argument is optional.
1164 * This behavior is specific to the GNU `getopt'.
1165 *
1166 * The argument `--' causes premature termination of argument scanning,
1167 * explicitly telling `getopt' that there are no more options. If OPTS begins
1168 * with `--', then non-option arguments are treated as arguments to the option
1169 * '\0'. This behavior is specific to the GNU `getopt'.
1170 */
1171
getopt_internal_r(int argc,char * const * argv,const char * optstring,const struct option * longopts,int * longind,struct custom_getopt_data * d)1172 static int getopt_internal_r(int argc, char *const *argv, const char *optstring,
1173 const struct option *longopts, int *longind,
1174 struct custom_getopt_data *d)
1175 {
1176 int ret, print_errors = d->custom_opterr;
1177
1178 if (optstring[0] == ':')
1179 print_errors = 0;
1180 if (argc < 1)
1181 return -1;
1182 d->custom_optarg = NULL;
1183
1184 /*
1185 * This is a big difference with GNU getopt, since optind == 0
1186 * means initialization while here 1 means first call.
1187 */
1188 if (d->custom_optind == 0 || !d->initialized) {
1189 if (d->custom_optind == 0)
1190 d->custom_optind = 1; /* Don't scan ARGV[0], the program name. */
1191 custom_getopt_initialize(d);
1192 }
1193 if (d->nextchar == NULL || *d->nextchar == '\0') {
1194 ret = shuffle_argv(argc, argv, longopts, d);
1195 if (ret)
1196 return ret;
1197 }
1198 if (longopts && (argv[d->custom_optind][1] == '-' ))
1199 return check_long_opt(argc, argv, optstring, longopts,
1200 longind, print_errors, d);
1201 return check_short_opt(argc, argv, optstring, print_errors, d);
1202 }
1203
custom_getopt_internal(int argc,char * const * argv,const char * optstring,const struct option * longopts,int * longind)1204 static int custom_getopt_internal(int argc, char *const *argv, const char *optstring,
1205 const struct option *longopts, int *longind)
1206 {
1207 int result;
1208 /* Keep a global copy of all internal members of d */
1209 static struct custom_getopt_data d;
1210
1211 d.custom_optind = custom_optind;
1212 d.custom_opterr = custom_opterr;
1213 result = getopt_internal_r(argc, argv, optstring, longopts,
1214 longind, &d);
1215 custom_optind = d.custom_optind;
1216 custom_optarg = d.custom_optarg;
1217 custom_optopt = d.custom_optopt;
1218 return result;
1219 }
1220
custom_getopt_long(int argc,char * const * argv,const char * options,const struct option * long_options,int * opt_index)1221 static int custom_getopt_long (int argc, char *const *argv, const char *options,
1222 const struct option *long_options, int *opt_index)
1223 {
1224 return custom_getopt_internal(argc, argv, options, long_options,
1225 opt_index);
1226 }
1227
1228
1229 static char *package_name = 0;
1230
1231 /**
1232 * @brief updates an option
1233 * @param field the generic pointer to the field to update
1234 * @param orig_field the pointer to the orig field
1235 * @param field_given the pointer to the number of occurrence of this option
1236 * @param prev_given the pointer to the number of occurrence already seen
1237 * @param value the argument for this option (if null no arg was specified)
1238 * @param possible_values the possible values for this option (if specified)
1239 * @param default_value the default value (in case the option only accepts fixed values)
1240 * @param arg_type the type of this option
1241 * @param check_ambiguity @see cmdline_parser_params.check_ambiguity
1242 * @param override @see cmdline_parser_params.override
1243 * @param no_free whether to free a possible previous value
1244 * @param multiple_option whether this is a multiple option
1245 * @param long_opt the corresponding long option
1246 * @param short_opt the corresponding short option (or '-' if none)
1247 * @param additional_error possible further error specification
1248 */
1249 static
update_arg(void * field,char ** orig_field,unsigned int * field_given,unsigned int * prev_given,char * value,const char * possible_values[],const char * default_value,cmdline_parser_arg_type arg_type,int check_ambiguity,int override,int no_free,int multiple_option,const char * long_opt,char short_opt,const char * additional_error)1250 int update_arg(void *field, char **orig_field,
1251 unsigned int *field_given, unsigned int *prev_given,
1252 char *value, const char *possible_values[],
1253 const char *default_value,
1254 cmdline_parser_arg_type arg_type,
1255 int check_ambiguity, int override,
1256 int no_free, int multiple_option,
1257 const char *long_opt, char short_opt,
1258 const char *additional_error)
1259 {
1260 char *stop_char = 0;
1261 const char *val = value;
1262 int found;
1263 char **string_field;
1264 FIX_UNUSED (field);
1265
1266 stop_char = 0;
1267 found = 0;
1268
1269 if (!multiple_option && prev_given && (*prev_given || (check_ambiguity && *field_given)))
1270 {
1271 if (short_opt != '-')
1272 fprintf (stderr, "%s: `--%s' (`-%c') option given more than once%s\n",
1273 package_name, long_opt, short_opt,
1274 (additional_error ? additional_error : ""));
1275 else
1276 fprintf (stderr, "%s: `--%s' option given more than once%s\n",
1277 package_name, long_opt,
1278 (additional_error ? additional_error : ""));
1279 return 1; /* failure */
1280 }
1281
1282 if (possible_values && (found = check_possible_values((value ? value : default_value), possible_values)) < 0)
1283 {
1284 if (short_opt != '-')
1285 fprintf (stderr, "%s: %s argument, \"%s\", for option `--%s' (`-%c')%s\n",
1286 package_name, (found == -2) ? "ambiguous" : "invalid", value, long_opt, short_opt,
1287 (additional_error ? additional_error : ""));
1288 else
1289 fprintf (stderr, "%s: %s argument, \"%s\", for option `--%s'%s\n",
1290 package_name, (found == -2) ? "ambiguous" : "invalid", value, long_opt,
1291 (additional_error ? additional_error : ""));
1292 return 1; /* failure */
1293 }
1294
1295 if (field_given && *field_given && ! override)
1296 return 0;
1297 if (prev_given)
1298 (*prev_given)++;
1299 if (field_given)
1300 (*field_given)++;
1301 if (possible_values)
1302 val = possible_values[found];
1303
1304 switch(arg_type) {
1305 case ARG_LONG:
1306 if (val) *((long *)field) = (long)strtol (val, &stop_char, 0);
1307 break;
1308 case ARG_STRING:
1309 if (val) {
1310 string_field = (char **)field;
1311 if (!no_free && *string_field)
1312 free (*string_field); /* free previous string */
1313 *string_field = gengetopt_strdup (val);
1314 }
1315 break;
1316 default:
1317 break;
1318 };
1319
1320 /* check numeric conversion */
1321 switch(arg_type) {
1322 case ARG_LONG:
1323 if (val && !(stop_char && *stop_char == '\0')) {
1324 fprintf(stderr, "%s: invalid numeric value: %s\n", package_name, val);
1325 return 1; /* failure */
1326 }
1327 break;
1328 default:
1329 ;
1330 };
1331
1332 /* store the original value */
1333 switch(arg_type) {
1334 case ARG_NO:
1335 break;
1336 default:
1337 if (value && orig_field) {
1338 if (no_free) {
1339 *orig_field = value;
1340 } else {
1341 if (*orig_field)
1342 free (*orig_field); /* free previous string */
1343 *orig_field = gengetopt_strdup (value);
1344 }
1345 }
1346 };
1347
1348 return 0; /* OK */
1349 }
1350
1351 /**
1352 * @brief store information about a multiple option in a temporary list
1353 * @param list where to (temporarily) store multiple options
1354 */
1355 static
update_multiple_arg_temp(struct generic_list ** list,unsigned int * prev_given,const char * val,const char * possible_values[],const char * default_value,cmdline_parser_arg_type arg_type,const char * long_opt,char short_opt,const char * additional_error)1356 int update_multiple_arg_temp(struct generic_list **list,
1357 unsigned int *prev_given, const char *val,
1358 const char *possible_values[], const char *default_value,
1359 cmdline_parser_arg_type arg_type,
1360 const char *long_opt, char short_opt,
1361 const char *additional_error)
1362 {
1363 /* store single arguments */
1364 char *multi_token;
1365 const char *multi_next;
1366
1367 if (arg_type == ARG_NO) {
1368 (*prev_given)++;
1369 return 0; /* OK */
1370 }
1371
1372 multi_token = get_multiple_arg_token(val);
1373 multi_next = get_multiple_arg_token_next (val);
1374
1375 while (1)
1376 {
1377 add_node (list);
1378 if (update_arg((void *)&((*list)->arg), &((*list)->orig), 0,
1379 prev_given, multi_token, possible_values, default_value,
1380 arg_type, 0, 1, 1, 1, long_opt, short_opt, additional_error)) {
1381 if (multi_token) free(multi_token);
1382 return 1; /* failure */
1383 }
1384
1385 if (multi_next)
1386 {
1387 multi_token = get_multiple_arg_token(multi_next);
1388 multi_next = get_multiple_arg_token_next (multi_next);
1389 }
1390 else
1391 break;
1392 }
1393
1394 return 0; /* OK */
1395 }
1396
1397 /**
1398 * @brief free the passed list (including possible string argument)
1399 */
1400 static
free_list(struct generic_list * list,short string_arg)1401 void free_list(struct generic_list *list, short string_arg)
1402 {
1403 if (list) {
1404 struct generic_list *tmp;
1405 while (list)
1406 {
1407 tmp = list;
1408 if (string_arg && list->arg.string_arg)
1409 free (list->arg.string_arg);
1410 if (list->orig)
1411 free (list->orig);
1412 list = list->next;
1413 free (tmp);
1414 }
1415 }
1416 }
1417
1418 /**
1419 * @brief updates a multiple option starting from the passed list
1420 */
1421 static
update_multiple_arg(void * field,char *** orig_field,unsigned int field_given,unsigned int prev_given,union generic_value * default_value,cmdline_parser_arg_type arg_type,struct generic_list * list)1422 void update_multiple_arg(void *field, char ***orig_field,
1423 unsigned int field_given, unsigned int prev_given, union generic_value *default_value,
1424 cmdline_parser_arg_type arg_type,
1425 struct generic_list *list)
1426 {
1427 int i;
1428 struct generic_list *tmp;
1429
1430 if (prev_given && list) {
1431 *orig_field = (char **) realloc (*orig_field, (field_given + prev_given) * sizeof (char *));
1432
1433 switch(arg_type) {
1434 case ARG_LONG:
1435 *((long **)field) = (long *)realloc (*((long **)field), (field_given + prev_given) * sizeof (long)); break;
1436 case ARG_STRING:
1437 *((char ***)field) = (char **)realloc (*((char ***)field), (field_given + prev_given) * sizeof (char *)); break;
1438 default:
1439 break;
1440 };
1441
1442 for (i = (prev_given - 1); i >= 0; --i)
1443 {
1444 tmp = list;
1445
1446 switch(arg_type) {
1447 case ARG_LONG:
1448 (*((long **)field))[i + field_given] = tmp->arg.long_arg; break;
1449 case ARG_STRING:
1450 (*((char ***)field))[i + field_given] = tmp->arg.string_arg; break;
1451 default:
1452 break;
1453 }
1454 (*orig_field) [i + field_given] = list->orig;
1455 list = list->next;
1456 free (tmp);
1457 }
1458 } else { /* set the default value */
1459 if (default_value && ! field_given) {
1460 switch(arg_type) {
1461 case ARG_LONG:
1462 if (! *((long **)field)) {
1463 *((long **)field) = (long *)malloc (sizeof (long));
1464 (*((long **)field))[0] = default_value->long_arg;
1465 }
1466 break;
1467 case ARG_STRING:
1468 if (! *((char ***)field)) {
1469 *((char ***)field) = (char **)malloc (sizeof (char *));
1470 (*((char ***)field))[0] = gengetopt_strdup(default_value->string_arg);
1471 }
1472 break;
1473 default: break;
1474 }
1475 if (!(*orig_field)) {
1476 *orig_field = (char **) malloc (sizeof (char *));
1477 (*orig_field)[0] = 0;
1478 }
1479 }
1480 }
1481 }
1482
1483 int
cmdline_parser_internal(int argc,char ** argv,struct gengetopt_args_info * args_info,struct cmdline_parser_params * params,const char * additional_error)1484 cmdline_parser_internal (
1485 int argc, char **argv, struct gengetopt_args_info *args_info,
1486 struct cmdline_parser_params *params, const char *additional_error)
1487 {
1488 int c; /* Character of the parsed option. */
1489
1490 struct generic_list * extensions_list = NULL;
1491 int error_occurred = 0;
1492 struct gengetopt_args_info local_args_info;
1493
1494 int override;
1495 int initialize;
1496 int check_required;
1497 int check_ambiguity;
1498
1499 char *optarg;
1500 int optind;
1501 int opterr;
1502 int optopt;
1503
1504 package_name = argv[0];
1505
1506 /* TODO: Why is this here? It is not used anywhere. */
1507 override = params->override;
1508 FIX_UNUSED(override);
1509
1510 initialize = params->initialize;
1511 check_required = params->check_required;
1512
1513 /* TODO: Why is this here? It is not used anywhere. */
1514 check_ambiguity = params->check_ambiguity;
1515 FIX_UNUSED(check_ambiguity);
1516
1517 if (initialize)
1518 cmdline_parser_init (args_info);
1519
1520 cmdline_parser_init (&local_args_info);
1521
1522 optarg = 0;
1523 optind = 0;
1524 opterr = params->print_errors;
1525 optopt = '?';
1526
1527 while (1)
1528 {
1529 int option_index = 0;
1530
1531 static struct option long_options[] = {
1532 { "help", 0, NULL, 'h' },
1533 { "input-format", 1, NULL, 'i' },
1534 { "output-format", 1, NULL, 'o' },
1535 { "extensions", 1, NULL, 'e' },
1536 { "events-limit", 1, NULL, 0 },
1537 { "first-event-number", 1, NULL, 0 },
1538 { "last-event-number", 1, NULL, 0 },
1539 { "print-every-events-parsed", 1, NULL, 0 },
1540 { 0, 0, 0, 0 }
1541 };
1542
1543 custom_optarg = optarg;
1544 custom_optind = optind;
1545 custom_opterr = opterr;
1546 custom_optopt = optopt;
1547
1548 c = custom_getopt_long (argc, argv, "hi:o:e:", long_options, &option_index);
1549
1550 optarg = custom_optarg;
1551 optind = custom_optind;
1552 opterr = custom_opterr;
1553 optopt = custom_optopt;
1554
1555 if (c == -1) break; /* Exit from `while (1)' loop. */
1556
1557 switch (c)
1558 {
1559 case 'h': /* Print help and exit. */
1560 cmdline_parser_print_help ();
1561 cmdline_parser_free (&local_args_info);
1562 exit (EXIT_SUCCESS);
1563
1564 case 'i': /* Input format. */
1565
1566
1567 if (update_arg( (void *)&(args_info->input_format_arg),
1568 &(args_info->input_format_orig), &(args_info->input_format_given),
1569 &(local_args_info.input_format_given), optarg, cmdline_parser_input_format_values, 0, ARG_STRING,
1570 check_ambiguity, override, 0, 0,
1571 "input-format", 'i',
1572 additional_error))
1573 goto failure;
1574
1575 break;
1576 case 'o': /* Output format. */
1577
1578
1579 if (update_arg( (void *)&(args_info->output_format_arg),
1580 &(args_info->output_format_orig), &(args_info->output_format_given),
1581 &(local_args_info.output_format_given), optarg, cmdline_parser_output_format_values, 0, ARG_STRING,
1582 check_ambiguity, override, 0, 0,
1583 "output-format", 'o',
1584 additional_error))
1585 goto failure;
1586
1587 break;
1588 case 'e': /* Extensions, in a form extension=value, could be passed to readers/writers. */
1589
1590 if (update_multiple_arg_temp(&extensions_list,
1591 &(local_args_info.extensions_given), optarg, 0, 0, ARG_STRING,
1592 "extensions", 'e',
1593 additional_error))
1594 goto failure;
1595
1596 break;
1597
1598 case 0: /* Long option with no short option */
1599 /* Limit of events to read from input. */
1600 if (strcmp (long_options[option_index].name, "events-limit") == 0)
1601 {
1602
1603
1604 if (update_arg( (void *)&(args_info->events_limit_arg),
1605 &(args_info->events_limit_orig), &(args_info->events_limit_given),
1606 &(local_args_info.events_limit_given), optarg, 0, "100000000", ARG_LONG,
1607 check_ambiguity, override, 0, 0,
1608 "events-limit", '-',
1609 additional_error))
1610 goto failure;
1611
1612 }
1613 /* Lowest allowed event number. */
1614 else if (strcmp (long_options[option_index].name, "first-event-number") == 0)
1615 {
1616
1617
1618 if (update_arg( (void *)&(args_info->first_event_number_arg),
1619 &(args_info->first_event_number_orig), &(args_info->first_event_number_given),
1620 &(local_args_info.first_event_number_given), optarg, 0, "-100000000", ARG_LONG,
1621 check_ambiguity, override, 0, 0,
1622 "first-event-number", '-',
1623 additional_error))
1624 goto failure;
1625
1626 }
1627 /* Highest allowed event number. */
1628 else if (strcmp (long_options[option_index].name, "last-event-number") == 0)
1629 {
1630
1631
1632 if (update_arg( (void *)&(args_info->last_event_number_arg),
1633 &(args_info->last_event_number_orig), &(args_info->last_event_number_given),
1634 &(local_args_info.last_event_number_given), optarg, 0, "100000000", ARG_LONG,
1635 check_ambiguity, override, 0, 0,
1636 "last-event-number", '-',
1637 additional_error))
1638 goto failure;
1639
1640 }
1641 /* Frequency of parsing information printouts. */
1642 else if (strcmp (long_options[option_index].name, "print-every-events-parsed") == 0)
1643 {
1644
1645
1646 if (update_arg( (void *)&(args_info->print_every_events_parsed_arg),
1647 &(args_info->print_every_events_parsed_orig), &(args_info->print_every_events_parsed_given),
1648 &(local_args_info.print_every_events_parsed_given), optarg, 0, "100", ARG_LONG,
1649 check_ambiguity, override, 0, 0,
1650 "print-every-events-parsed", '-',
1651 additional_error))
1652 goto failure;
1653
1654 }
1655
1656 break;
1657 case '?': /* Invalid option. */
1658 /* `getopt_long' already printed an error message. */
1659 goto failure;
1660
1661 default: /* bug: option not considered. */
1662 fprintf (stderr, "%s: option unknown: %c%s\n", CMDLINE_PARSER_PACKAGE, c, (additional_error ? additional_error : ""));
1663 abort ();
1664 } /* switch */
1665 } /* while */
1666
1667
1668 update_multiple_arg((void *)&(args_info->extensions_arg),
1669 &(args_info->extensions_orig), args_info->extensions_given,
1670 local_args_info.extensions_given, 0,
1671 ARG_STRING, extensions_list);
1672
1673 args_info->extensions_given += local_args_info.extensions_given;
1674 local_args_info.extensions_given = 0;
1675
1676 if (check_required)
1677 {
1678 error_occurred += cmdline_parser_required2 (args_info, argv[0], additional_error);
1679 }
1680
1681 cmdline_parser_release (&local_args_info);
1682
1683 if ( error_occurred )
1684 return (EXIT_FAILURE);
1685
1686 if (optind < argc)
1687 {
1688 int i = 0 ;
1689 int found_prog_name = 0;
1690 /* whether program name, i.e., argv[0], is in the remaining args
1691 (this may happen with some implementations of getopt,
1692 but surely not with the one included by gengetopt) */
1693
1694
1695 args_info->inputs_num = argc - optind - found_prog_name;
1696 args_info->inputs =
1697 (char **)(malloc ((args_info->inputs_num)*sizeof(char *))) ;
1698 while (optind < argc)
1699 args_info->inputs[ i++ ] = gengetopt_strdup (argv[optind++]) ;
1700 }
1701
1702 return 0;
1703
1704 failure:
1705 free_list (extensions_list, 1 );
1706
1707 cmdline_parser_release (&local_args_info);
1708 return (EXIT_FAILURE);
1709 }
1710 /* vim: set ft=c noet ts=8 sts=8 sw=8 tw=80 nojs spell : */
1711