getopt.c
Go to the documentation of this file.
1 /*************************************************************************/
34 /*************************************************************************/
35 
36 
37 #include <GKlib.h>
38 
39 /*************************************************************************/
40 /* Local function prototypes */
41 /*************************************************************************/
42 static void exchange (char **);
43 static char *gk_getopt_initialize (int, char **, char *);
44 static int gk_getopt_internal(int argc, char **argv, char *optstring,
45  struct gk_option *longopts, int *longind, int long_only);
46 
47 
48 
49 /*************************************************************************/
55 /*************************************************************************/
56 char *gk_optarg;
57 
58 
59 /*************************************************************************/
67 /*************************************************************************/
68 int gk_optind = 1;
69 
70 
71 /*************************************************************************/
80 /*************************************************************************/
81 int gk_opterr = 1;
82 
83 
84 /*************************************************************************/
91 /*************************************************************************/
92 int gk_optopt = '?';
93 
94 
95 /*************************************************************************/
96 /*
97 Records that the getopt facility has been initialized.
98 */
99 /*************************************************************************/
101 
102 
103 /*************************************************************************/
104 /*
105 The next char to be scanned in the option-element in which the last option
106 character we returned was found. This allows us to pick up the scan where
107 we left off.
108 
109 If this is zero, or a null string, it means resume the scan by advancing
110 to the next ARGV-element.
111 */
112 /*************************************************************************/
113 static char *nextchar;
114 
115 
116 /*************************************************************************/
117 /*
118 Value of POSIXLY_CORRECT environment variable.
119 */
120 /*************************************************************************/
121 static char *posixly_correct;
122 
123 
124 /*************************************************************************/
125 /*
126 Describe how to deal with options that follow non-option ARGV-elements.
127 
128 If the caller did not specify anything, the default is REQUIRE_ORDER if
129 the environment variable POSIXLY_CORRECT is defined, PERMUTE otherwise.
130 
131 REQUIRE_ORDER means don't recognize them as options; stop option processing
132 when the first non-option is seen. This is what Unix does. This mode of
133 operation is selected by either setting the environment variable
134 POSIXLY_CORRECT, or using `+' as the first character of the list of
135 option characters.
136 
137 PERMUTE is the default. We permute the contents of ARGV as we scan, so
138 that eventually all the non-options are at the end. This allows options
139 to be given in any order, even with programs that were not written to
140 expect this.
141 
142 RETURN_IN_ORDER is an option available to programs that were written
143 to expect options and other ARGV-elements in any order and that care
144 about the ordering of the two. We describe each non-option ARGV-element
145 as if it were the argument of an option with character code 1.
146 Using `-' as the first character of the list of option characters
147 selects this mode of operation.
148 
149 The special argument `--' forces an end of option-scanning regardless
150 of the value of `ordering'. In the case of RETURN_IN_ORDER, only
151 `--' can cause `getopt' to return -1 with `gk_optind' != ARGC.
152 */
153 /*************************************************************************/
154 static enum
155 {
157 } ordering;
158 
159 
160 
161 /*************************************************************************/
162 /*
163 Describe the part of ARGV that contains non-options that have
164 been skipped. `first_nonopt' is the index in ARGV of the first of them;
165 `last_nonopt' is the index after the last of them.
166 */
167 /*************************************************************************/
168 static int first_nonopt;
169 static int last_nonopt;
170 
171 
172 
173 
174 
175 /*************************************************************************/
176 /*
177 Handle permutation of arguments.
178 
179 Exchange two adjacent subsequences of ARGV.
180 One subsequence is elements [first_nonopt,last_nonopt)
181 which contains all the non-options that have been skipped so far.
182 The other is elements [last_nonopt,gk_optind), which contains all
183 the options processed since those non-options were skipped.
184 
185 `first_nonopt' and `last_nonopt' are relocated so that they describe
186 the new indices of the non-options in ARGV after they are moved.
187 */
188 /*************************************************************************/
189 static void exchange (char **argv)
190 {
191  int bottom = first_nonopt;
192  int middle = last_nonopt;
193  int top = gk_optind;
194  char *tem;
195 
196  /* Exchange the shorter segment with the far end of the longer segment.
197  That puts the shorter segment into the right place.
198  It leaves the longer segment in the right place overall,
199  but it consists of two parts that need to be swapped next. */
200 
201  while (top > middle && middle > bottom) {
202  if (top - middle > middle - bottom) {
203  /* Bottom segment is the short one. */
204  int len = middle - bottom;
205  register int i;
206 
207  /* Swap it with the top part of the top segment. */
208  for (i = 0; i < len; i++) {
209  tem = argv[bottom + i];
210  argv[bottom + i] = argv[top - (middle - bottom) + i];
211  argv[top - (middle - bottom) + i] = tem;
212  }
213  /* Exclude the moved bottom segment from further swapping. */
214  top -= len;
215  }
216  else {
217  /* Top segment is the short one. */
218  int len = top - middle;
219  register int i;
220 
221  /* Swap it with the bottom part of the bottom segment. */
222  for (i = 0; i < len; i++) {
223  tem = argv[bottom + i];
224  argv[bottom + i] = argv[middle + i];
225  argv[middle + i] = tem;
226  }
227  /* Exclude the moved top segment from further swapping. */
228  bottom += len;
229  }
230  }
231 
232  /* Update records for the slots the non-options now occupy. */
233 
236 }
237 
238 
239 
240 /*************************************************************************/
241 /*
242 Initialize the internal data when the first call is made.
243 */
244 /*************************************************************************/
245 static char *gk_getopt_initialize (int argc, char **argv, char *optstring)
246 {
247  /* Start processing options with ARGV-element 1 (since ARGV-element 0
248  is the program name); the sequence of previously skipped
249  non-option ARGV-elements is empty. */
250 
252 
253  nextchar = NULL;
254 
255  posixly_correct = getenv("POSIXLY_CORRECT");
256 
257  /* Determine how to handle the ordering of options and nonoptions. */
258  if (optstring[0] == '-') {
260  ++optstring;
261  }
262  else if (optstring[0] == '+') {
264  ++optstring;
265  }
266  else if (posixly_correct != NULL)
268  else
269  ordering = PERMUTE;
270 
271  return optstring;
272 }
273 
274 
275 /*************************************************************************/
276 /*
277  Scan elements of ARGV (whose length is ARGC) for option characters
278  given in OPTSTRING.
279 
280  If an element of ARGV starts with '-', and is not exactly "-" or "--",
281  then it is an option element. The characters of this element
282  (aside from the initial '-') are option characters. If `getopt'
283  is called repeatedly, it returns successively each of the option characters
284  from each of the option elements.
285 
286  If `getopt' finds another option character, it returns that character,
287  updating `gk_optind' and `nextchar' so that the next call to `getopt' can
288  resume the scan with the following option character or ARGV-element.
289 
290  If there are no more option characters, `getopt' returns -1.
291  Then `gk_optind' is the index in ARGV of the first ARGV-element
292  that is not an option. (The ARGV-elements have been permuted
293  so that those that are not options now come last.)
294 
295  OPTSTRING is a string containing the legitimate option characters.
296  If an option character is seen that is not listed in OPTSTRING,
297  return '?' after printing an error message. If you set `gk_opterr' to
298  zero, the error message is suppressed but we still return '?'.
299 
300  If a char in OPTSTRING is followed by a colon, that means it wants an arg,
301  so the following text in the same ARGV-element, or the text of the following
302  ARGV-element, is returned in `gk_optarg'. Two colons mean an option that
303  wants an optional arg; if there is text in the current ARGV-element,
304  it is returned in `gk_optarg', otherwise `gk_optarg' is set to zero.
305 
306  If OPTSTRING starts with `-' or `+', it requests different methods of
307  handling the non-option ARGV-elements.
308  See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
309 
310  Long-named options begin with `--' instead of `-'.
311  Their names may be abbreviated as long as the abbreviation is unique
312  or is an exact match for some defined option. If they have an
313  argument, it follows the option name in the same ARGV-element, separated
314  from the option name by a `=', or else the in next ARGV-element.
315  When `getopt' finds a long-named option, it returns 0 if that option's
316  `flag' field is nonzero, the value of the option's `val' field
317  if the `flag' field is zero.
318 
319  LONGOPTS is a vector of `struct gk_option' terminated by an
320  element containing a name which is zero.
321 
322  LONGIND returns the index in LONGOPT of the long-named option found.
323  It is only valid when a long-named option has been found by the most
324  recent call.
325 
326  If LONG_ONLY is nonzero, '-' as well as '--' can introduce
327  long-named options.
328 */
329 /*************************************************************************/
330 static int gk_getopt_internal(int argc, char **argv, char *optstring,
331  struct gk_option *longopts, int *longind, int long_only)
332 {
333  int print_errors = gk_opterr;
334  if (optstring[0] == ':')
335  print_errors = 0;
336 
337  if (argc < 1)
338  return -1;
339 
340  gk_optarg = NULL;
341 
342  if (gk_optind == 0 || !gk_getopt_initialized) {
343  if (gk_optind == 0)
344  gk_optind = 1; /* Don't scan ARGV[0], the program name. */
345  optstring = gk_getopt_initialize(argc, argv, optstring);
347  }
348 
349  /* Test whether ARGV[gk_optind] points to a non-option argument.
350  Either it does not have option syntax, or there is an environment flag
351  from the shell indicating it is not an option. The later information
352  is only used when the used in the GNU libc. */
353 # define NONOPTION_P (argv[gk_optind][0] != '-' || argv[gk_optind][1] == '\0')
354 
355  if (nextchar == NULL || *nextchar == '\0') {
356  /* Advance to the next ARGV-element. */
357 
358  /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
359  moved back by the user (who may also have changed the arguments). */
360  if (last_nonopt > gk_optind)
362  if (first_nonopt > gk_optind)
364 
365  if (ordering == PERMUTE) {
366  /* If we have just processed some options following some non-options,
367  exchange them so that the options come first. */
368 
370  exchange ((char **) argv);
371  else if (last_nonopt != gk_optind)
373 
374  /* Skip any additional non-options
375  and extend the range of non-options previously skipped. */
376 
377  while (gk_optind < argc && NONOPTION_P)
378  gk_optind++;
379 
381  }
382 
383  /* The special ARGV-element `--' means premature end of options.
384  Skip it like a null option,
385  then exchange with previous non-options as if it were an option,
386  then skip everything else like a non-option. */
387 
388  if (gk_optind != argc && !strcmp (argv[gk_optind], "--")) {
389  gk_optind++;
390 
391  if (first_nonopt != last_nonopt && last_nonopt != gk_optind)
392  exchange ((char **) argv);
393  else if (first_nonopt == last_nonopt)
395  last_nonopt = argc;
396 
397  gk_optind = argc;
398  }
399 
400  /* If we have done all the ARGV-elements, stop the scan
401  and back over any non-options that we skipped and permuted. */
402 
403  if (gk_optind == argc) {
404  /* Set the next-arg-index to point at the non-options
405  that we previously skipped, so the caller will digest them. */
406  if (first_nonopt != last_nonopt)
407  gk_optind = first_nonopt;
408  return -1;
409  }
410 
411  /* If we have come to a non-option and did not permute it,
412  either stop the scan or describe it to the caller and pass it by. */
413 
414  if (NONOPTION_P) {
415  if (ordering == REQUIRE_ORDER)
416  return -1;
417  gk_optarg = argv[gk_optind++];
418  return 1;
419  }
420 
421  /* We have found another option-ARGV-element.
422  Skip the initial punctuation. */
423 
424  nextchar = (argv[gk_optind] + 1 + (longopts != NULL && argv[gk_optind][1] == '-'));
425  }
426 
427  /* Decode the current option-ARGV-element. */
428 
429  /* Check whether the ARGV-element is a long option.
430 
431  If long_only and the ARGV-element has the form "-f", where f is
432  a valid short option, don't consider it an abbreviated form of
433  a long option that starts with f. Otherwise there would be no
434  way to give the -f short option.
435 
436  On the other hand, if there's a long option "fubar" and
437  the ARGV-element is "-fu", do consider that an abbreviation of
438  the long option, just like "--fu", and not "-f" with arg "u".
439 
440  This distinction seems to be the most useful approach. */
441 
442  if (longopts != NULL && (argv[gk_optind][1] == '-' || (long_only && (argv[gk_optind][2] || !strchr(optstring, argv[gk_optind][1]))))) {
443  char *nameend;
444  struct gk_option *p;
445  struct gk_option *pfound = NULL;
446  int exact = 0;
447  int ambig = 0;
448  int indfound = -1;
449  int option_index;
450 
451  for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
452  /* Do nothing. */ ;
453 
454  /* Test all long options for either exact match or abbreviated matches. */
455  for (p = longopts, option_index = 0; p->name; p++, option_index++) {
456  if (!strncmp (p->name, nextchar, nameend - nextchar)) {
457  if ((unsigned int) (nameend - nextchar) == (unsigned int) strlen (p->name)) {
458  /* Exact match found. */
459  pfound = p;
460  indfound = option_index;
461  exact = 1;
462  break;
463  }
464  else if (pfound == NULL) {
465  /* First nonexact match found. */
466  pfound = p;
467  indfound = option_index;
468  }
469  else if (long_only || pfound->has_arg != p->has_arg || pfound->flag != p->flag || pfound->val != p->val)
470  /* Second or later nonexact match found. */
471  ambig = 1;
472  }
473  }
474 
475  if (ambig && !exact) {
476  if (print_errors)
477  fprintf(stderr, "%s: option `%s' is ambiguous\n", argv[0], argv[gk_optind]);
478 
479  nextchar += strlen (nextchar);
480  gk_optind++;
481  gk_optopt = 0;
482  return '?';
483  }
484 
485  if (pfound != NULL) {
486  option_index = indfound;
487  gk_optind++;
488  if (*nameend) {
489  /* Don't test has_arg with >, because some C compilers don't allow it to be used on enums. */
490  if (pfound->has_arg)
491  gk_optarg = nameend + 1;
492  else {
493  if (print_errors) {
494  if (argv[gk_optind - 1][1] == '-')
495  /* --option */
496  fprintf(stderr, "%s: option `--%s' doesn't allow an argument\n", argv[0], pfound->name);
497  else
498  /* +option or -option */
499  fprintf(stderr, "%s: option `%c%s' doesn't allow an argument\n", argv[0], argv[gk_optind - 1][0], pfound->name);
500  }
501 
502  nextchar += strlen (nextchar);
503 
504  gk_optopt = pfound->val;
505  return '?';
506  }
507  }
508  else if (pfound->has_arg == 1) {
509  if (gk_optind < argc)
510  gk_optarg = argv[gk_optind++];
511  else {
512  if (print_errors)
513  fprintf(stderr, "%s: option `%s' requires an argument\n", argv[0], argv[gk_optind - 1]);
514  nextchar += strlen (nextchar);
515  gk_optopt = pfound->val;
516  return optstring[0] == ':' ? ':' : '?';
517  }
518  }
519  nextchar += strlen (nextchar);
520  if (longind != NULL)
521  *longind = option_index;
522  if (pfound->flag) {
523  *(pfound->flag) = pfound->val;
524  return 0;
525  }
526  return pfound->val;
527  }
528 
529  /* Can't find it as a long option. If this is not getopt_long_only,
530  or the option starts with '--' or is not a valid short
531  option, then it's an error. Otherwise interpret it as a short option. */
532  if (!long_only || argv[gk_optind][1] == '-' || strchr(optstring, *nextchar) == NULL) {
533  if (print_errors) {
534  if (argv[gk_optind][1] == '-')
535  /* --option */
536  fprintf(stderr, "%s: unrecognized option `--%s'\n", argv[0], nextchar);
537  else
538  /* +option or -option */
539  fprintf(stderr, "%s: unrecognized option `%c%s'\n", argv[0], argv[gk_optind][0], nextchar);
540  }
541  nextchar = (char *) "";
542  gk_optind++;
543  gk_optopt = 0;
544  return '?';
545  }
546  }
547 
548  /* Look at and handle the next short option-character. */
549  {
550  char c = *nextchar++;
551  char *temp = strchr(optstring, c);
552 
553  /* Increment `gk_optind' when we start to process its last character. */
554  if (*nextchar == '\0')
555  ++gk_optind;
556 
557  if (temp == NULL || c == ':') {
558  if (print_errors) {
559  if (posixly_correct)
560  /* 1003.2 specifies the format of this message. */
561  fprintf(stderr, "%s: illegal option -- %c\n", argv[0], c);
562  else
563  fprintf(stderr, "%s: invalid option -- %c\n", argv[0], c);
564  }
565  gk_optopt = c;
566  return '?';
567  }
568 
569  /* Convenience. Treat POSIX -W foo same as long option --foo */
570  if (temp[0] == 'W' && temp[1] == ';') {
571  char *nameend;
572  struct gk_option *p;
573  struct gk_option *pfound = NULL;
574  int exact = 0;
575  int ambig = 0;
576  int indfound = 0;
577  int option_index;
578 
579  /* This is an option that requires an argument. */
580  if (*nextchar != '\0') {
582  /* If we end this ARGV-element by taking the rest as an arg,
583  we must advance to the next element now. */
584  gk_optind++;
585  }
586  else if (gk_optind == argc) {
587  if (print_errors) {
588  /* 1003.2 specifies the format of this message. */
589  fprintf(stderr, "%s: option requires an argument -- %c\n", argv[0], c);
590  }
591  gk_optopt = c;
592  if (optstring[0] == ':')
593  c = ':';
594  else
595  c = '?';
596  return c;
597  }
598  else
599  /* We already incremented `gk_optind' once; increment it again when taking next ARGV-elt as argument. */
600  gk_optarg = argv[gk_optind++];
601 
602  /* gk_optarg is now the argument, see if it's in the table of longopts. */
603 
604  for (nextchar = nameend = gk_optarg; *nameend && *nameend != '='; nameend++)
605  /* Do nothing. */ ;
606 
607  /* Test all long options for either exact match or abbreviated matches. */
608  for (p = longopts, option_index = 0; p->name; p++, option_index++) {
609  if (!strncmp (p->name, nextchar, nameend - nextchar)) {
610  if ((unsigned int) (nameend - nextchar) == strlen (p->name)) {
611  /* Exact match found. */
612  pfound = p;
613  indfound = option_index;
614  exact = 1;
615  break;
616  }
617  else if (pfound == NULL) {
618  /* First nonexact match found. */
619  pfound = p;
620  indfound = option_index;
621  }
622  else
623  /* Second or later nonexact match found. */
624  ambig = 1;
625  }
626  }
627  if (ambig && !exact) {
628  if (print_errors)
629  fprintf(stderr, "%s: option `-W %s' is ambiguous\n", argv[0], argv[gk_optind]);
630  nextchar += strlen (nextchar);
631  gk_optind++;
632  return '?';
633  }
634  if (pfound != NULL) {
635  option_index = indfound;
636  if (*nameend) {
637  /* Don't test has_arg with >, because some C compilers don't allow it to be used on enums. */
638  if (pfound->has_arg)
639  gk_optarg = nameend + 1;
640  else {
641  if (print_errors)
642  fprintf(stderr, "%s: option `-W %s' doesn't allow an argument\n", argv[0], pfound->name);
643 
644  nextchar += strlen (nextchar);
645  return '?';
646  }
647  }
648  else if (pfound->has_arg == 1) {
649  if (gk_optind < argc)
650  gk_optarg = argv[gk_optind++];
651  else {
652  if (print_errors)
653  fprintf(stderr, "%s: option `%s' requires an argument\n", argv[0], argv[gk_optind - 1]);
654  nextchar += strlen (nextchar);
655  return optstring[0] == ':' ? ':' : '?';
656  }
657  }
658  nextchar += strlen (nextchar);
659  if (longind != NULL)
660  *longind = option_index;
661  if (pfound->flag) {
662  *(pfound->flag) = pfound->val;
663  return 0;
664  }
665  return pfound->val;
666  }
667  nextchar = NULL;
668  return 'W'; /* Let the application handle it. */
669  }
670 
671  if (temp[1] == ':') {
672  if (temp[2] == ':') {
673  /* This is an option that accepts an argument optionally. */
674  if (*nextchar != '\0') {
676  gk_optind++;
677  } else {
678  gk_optarg = NULL;
679  }
680  nextchar = NULL;
681  } else {
682  /* This is an option that requires an argument. */
683  if (*nextchar != '\0') {
685  /* If we end this ARGV-element by taking the rest as an arg, we must
686  * advance to the next element now. */
687  gk_optind++;
688  } else if (gk_optind == argc) {
689  if (print_errors) {
690  /* 1003.2 specifies the format of this message. */
691  fprintf(stderr, "%s: option requires an argument -- %c\n", argv[0],
692  c);
693  }
694  gk_optopt = c;
695  if (optstring[0] == ':')
696  c = ':';
697  else
698  c = '?';
699  } else {
700  /* We already incremented `gk_optind' once; increment it again when
701  * taking next ARGV-elt as argument. */
702  gk_optarg = argv[gk_optind++];
703  }
704  nextchar = NULL;
705  }
706  }
707  return c;
708  }
709 }
710 
711 
712 
713 /*************************************************************************/
769 /*************************************************************************/
770 int gk_getopt(int argc, char **argv, char *options)
771 {
772  return gk_getopt_internal(argc, argv, options, NULL, NULL, 0);
773 }
774 
775 
776 /*************************************************************************/
833 /*************************************************************************/
834 int gk_getopt_long( int argc, char **argv, char *options,
835  struct gk_option *long_options, int *opt_index)
836 {
837  return gk_getopt_internal (argc, argv, options, long_options, opt_index, 0);
838 }
839 
840 
841 
842 /*************************************************************************/
849 /*************************************************************************/
850 int gk_getopt_long_only(int argc, char **argv, char *options,
851  struct gk_option *long_options, int *opt_index)
852 {
853  return gk_getopt_internal(argc, argv, options, long_options, opt_index, 1);
854 }
855 
The structure that stores the information about the command-line options.
Definition: gk_getopt.h:28
static int gk_getopt_internal(int argc, char **argv, char *optstring, struct gk_option *longopts, int *longind, int long_only)
Definition: getopt.c:330
static char * gk_getopt_initialize(int, char **, char *)
Definition: getopt.c:245
char * name
Definition: gk_getopt.h:29
int gk_getopt(int argc, char **argv, char *options)
Parse command-line arguments.
Definition: getopt.c:770
int gk_optind
Index in ARGV of the next element to be scanned.
Definition: getopt.c:68
static int last_nonopt
Definition: getopt.c:169
int gk_optopt
Stores unknown option characters.
Definition: getopt.c:92
static struct gk_option long_options[]
Definition: fis.c:40
int gk_getopt_long(int argc, char **argv, char *options, struct gk_option *long_options, int *opt_index)
Parse command-line arguments with long options.
Definition: getopt.c:834
Scalar Scalar * c
Definition: benchVecAdd.cpp:17
static void exchange(char **)
Definition: getopt.c:189
static enum @1107 ordering
int has_arg
Definition: gk_getopt.h:30
int gk_getopt_initialized
Definition: getopt.c:100
int * flag
Definition: gk_getopt.h:34
static char * posixly_correct
Definition: getopt.c:121
int gk_opterr
Controls error reporting for unrecognized options.
Definition: getopt.c:81
#define NULL
Definition: ccolamd.c:609
static int first_nonopt
Definition: getopt.c:168
char * gk_optarg
For communication arguments to the caller.
Definition: getopt.c:56
static char * nextchar
Definition: getopt.c:113
int val
Definition: gk_getopt.h:35
float * p
#define NONOPTION_P
size_t len(handle h)
Get the length of a Python object.
Definition: pytypes.h:2244
int gk_getopt_long_only(int argc, char **argv, char *options, struct gk_option *long_options, int *opt_index)
Parse command-line arguments with only long options.
Definition: getopt.c:850


gtsam
Author(s):
autogenerated on Tue Jul 4 2023 02:34:18