GNUnet  0.10.x
getopt.c
Go to the documentation of this file.
1 /* Getopt for GNU.
2  NOTE: getopt is now part of the C library, so if you don't know what
3  "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
4  before changing it!
5 
6  Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97
7  Free Software Foundation, Inc.
8 
9  NOTE: The canonical source of this file is maintained with the GNU C Library.
10  Bugs can be reported to bug-glibc@prep.ai.mit.edu.
11 
12  This program is free software; you can redistribute it and/or modify it
13  under the terms of the GNU General Public License as published by the
14  Free Software Foundation; either version 3, or (at your option) any
15  later version.
16 
17  This program is distributed in the hope that it will be useful,
18  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  GNU General Public License for more details.
21 
22  You should have received a copy of the GNU General Public License
23  along with this program; if not, write to the Free Software
24  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
25  USA.
26 
27 
28  This code was heavily modified for GNUnet.
29  Copyright (C) 2006, 2017 Christian Grothoff
30  */
31 
40 #include "platform.h"
41 #include "gnunet_util_lib.h"
42 
43 #ifdef VMS
44 #include <unixlib.h>
45 #if HAVE_STRING_H - 0
46 #include <string.h>
47 #endif
48 #endif
49 
50 #define LOG(kind, ...) GNUNET_log_from(kind, "util-getopt", __VA_ARGS__)
51 
52 #define LOG_STRERROR(kind, syscall) \
53  GNUNET_log_from_strerror(kind, "util-getopt", syscall)
54 
55 #ifndef _
56 /* This is for other GNU distributions with internationalized messages.
57  When compiling libc, the _ macro is predefined. */
58 #ifdef HAVE_LIBINTL_H
59 #include <libintl.h>
60 #define _(msgid) gettext(msgid)
61 #else
62 #define _(msgid) (msgid)
63 #endif
64 #endif
65 
66 /* Describe the long-named options requested by the application.
67  The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
68  of `struct GNoption' terminated by an element containing a name which is
69  zero.
70 
71  The field `has_arg' is:
72  no_argument (or 0) if the option does not take an argument,
73  required_argument (or 1) if the option requires an argument,
74  optional_argument (or 2) if the option takes an optional argument.
75 
76  If the field `flag' is not NULL, it points to a variable that is set
77  to the value given in the field `val' when the option is found, but
78  left unchanged if the option is not found.
79 
80  To have a long-named option do something other than set an `int' to
81  a compiled-in constant, such as set a value from `GNoptarg', set the
82  option's `flag' field to zero and its `val' field to a nonzero
83  value (the equivalent single-letter option character, if there is
84  one). For long options that have a zero `flag' field, `getopt'
85  returns the contents of the `val' field. */
86 
87 struct GNoption {
88  const char *name;
89  /* has_arg can't be an enum because some compilers complain about
90  * type mismatches in all the code that assumes it is an int. */
91  int has_arg;
92  int *flag;
93  int val;
94 };
95 
96 
97 /* This version of `getopt' appears to the caller like standard Unix `getopt'
98  but it behaves differently for the user, since it allows the user
99  to intersperse the options with the other arguments.
100 
101  As `getopt' works, it permutes the elements of ARGV so that,
102  when it is done, all the options precede everything else. Thus
103  all application programs are extended to handle flexible argument order.
104 
105  Setting the environment variable POSIXLY_CORRECT disables permutation.
106  Then the behavior is completely standard.
107 
108  GNU application programs can use a third alternative mode in which
109  they can distinguish the relative order of options and other arguments. */
110 
111 /* For communication from `getopt' to the caller.
112  When `getopt' finds an option that takes an argument,
113  the argument value is returned here.
114  Also, when `ordering' is RETURN_IN_ORDER,
115  each non-option ARGV-element is returned here. */
116 
117 static char *GNoptarg = NULL;
118 
119 /* Index in ARGV of the next element to be scanned.
120  This is used for communication to and from the caller
121  and for communication between successive calls to `getopt'.
122 
123  On entry to `getopt', zero means this is the first call; initialize.
124 
125  When `getopt' returns -1, this is the index of the first of the
126  non-option elements that the caller should itself scan.
127 
128  Otherwise, `GNoptind' communicates from one call to the next
129  how much of ARGV has been scanned so far. */
130 
131 /* 1003.2 says this must be 1 before any call. */
132 static int GNoptind = 1;
133 
134 /* The next char to be scanned in the option-element
135  in which the last option character we returned was found.
136  This allows us to pick up the scan where we left off.
137 
138  If this is zero, or a null string, it means resume the scan
139  by advancing to the next ARGV-element. */
140 
141 static char *nextchar;
142 
143 
144 /* Describe how to deal with options that follow non-option ARGV-elements.
145 
146  If the caller did not specify anything,
147  the default is REQUIRE_ORDER if the environment variable
148  POSIXLY_CORRECT is defined, PERMUTE otherwise.
149 
150  REQUIRE_ORDER means don't recognize them as options;
151  stop option processing when the first non-option is seen.
152  This is what Unix does.
153  This mode of operation is selected by either setting the environment
154  variable POSIXLY_CORRECT, or using `+' as the first character
155  of the list of option characters.
156 
157  PERMUTE is the default. We GNUNET_CRYPTO_random_permute the contents of ARGV as we scan,
158  so that eventually all the non-options are at the end. This allows options
159  to be given in any order, even with programs that were not written to
160  expect this.
161 
162  RETURN_IN_ORDER is an option available to programs that were written
163  to expect GNoptions and other ARGV-elements in any order and that care about
164  the ordering of the two. We describe each non-option ARGV-element
165  as if it were the argument of an option with character code 1.
166  Using `-' as the first character of the list of option characters
167  selects this mode of operation.
168 
169  The special argument `--' forces an end of option-scanning regardless
170  of the value of `ordering'. In the case of RETURN_IN_ORDER, only
171  `--' can cause `getopt' to return -1 with `GNoptind' != ARGC. */
172 
174 
175 /* Value of POSIXLY_CORRECT environment variable. */
176 static char *posixly_correct;
177 
178 #ifdef __GNU_LIBRARY__
179 /* We want to avoid inclusion of string.h with non-GNU libraries
180  because there are many ways it can cause trouble.
181  On some systems, it contains special magic macros that don't work
182  in GCC. */
183 #include <string.h>
184 #define my_index strchr
185 #else
186 
187 /* Avoid depending on library functions or files
188  whose names are inconsistent. */
189 
190 char *
191 getenv();
192 
193 static char *
194 my_index(const char *str, int chr)
195 {
196  while (*str)
197  {
198  if (*str == chr)
199  return (char *)str;
200  str++;
201  }
202  return 0;
203 }
204 
205 /* If using GCC, we can safely declare strlen this way.
206  If not using GCC, it is ok not to declare it. */
207 #ifdef __GNUC__
208 /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
209  That was relevant to code that was here before. */
210 #if !defined(__STDC__) || !__STDC__
211 /* gcc with -traditional declares the built-in strlen to return int,
212  and has done so at least since version 2.4.5. -- rms. */
213 extern int
214 strlen(const char *);
215 #endif /* not __STDC__ */
216 #endif /* __GNUC__ */
217 
218 #endif /* not __GNU_LIBRARY__ */
219 
220 /* Handle permutation of arguments. */
221 
222 /* Describe the part of ARGV that contains non-options that have
223  been skipped. `first_nonopt' is the index in ARGV of the first of them;
224  `last_nonopt' is the index after the last of them. */
225 
226 static int first_nonopt;
227 static int last_nonopt;
228 
229 #define SWAP_FLAGS(ch1, ch2)
230 
231 /* Exchange two adjacent subsequences of ARGV.
232  One subsequence is elements [first_nonopt,last_nonopt)
233  which contains all the non-options that have been skipped so far.
234  The other is elements [last_nonopt,GNoptind), which contains all
235  the options processed since those non-options were skipped.
236 
237  `first_nonopt' and `last_nonopt' are relocated so that they describe
238  the new indices of the non-options in ARGV after they are moved. */
239 
240 #if defined(__STDC__) && __STDC__
241 static void
242 exchange(char **);
243 #endif
244 
245 static void
246 exchange(char **argv)
247 {
248  int bottom = first_nonopt;
249  int middle = last_nonopt;
250  int top = GNoptind;
251  char *tem;
252 
253  /* Exchange the shorter segment with the far end of the longer segment.
254  * That puts the shorter segment into the right place.
255  * It leaves the longer segment in the right place overall,
256  * but it consists of two parts that need to be swapped next. */
257 
258  while (top > middle && middle > bottom)
259  {
260  if (top - middle > middle - bottom)
261  {
262  /* Bottom segment is the short one. */
263  int len = middle - bottom;
264  register int i;
265 
266  /* Swap it with the top part of the top segment. */
267  for (i = 0; i < len; i++)
268  {
269  tem = argv[bottom + i];
270  argv[bottom + i] = argv[top - (middle - bottom) + i];
271  argv[top - (middle - bottom) + i] = tem;
272  SWAP_FLAGS(bottom + i, top - (middle - bottom) + i);
273  }
274  /* Exclude the moved bottom segment from further swapping. */
275  top -= len;
276  }
277  else
278  {
279  /* Top segment is the short one. */
280  int len = top - middle;
281  register int i;
282 
283  /* Swap it with the bottom part of the bottom segment. */
284  for (i = 0; i < len; i++)
285  {
286  tem = argv[bottom + i];
287  argv[bottom + i] = argv[middle + i];
288  argv[middle + i] = tem;
289  SWAP_FLAGS(bottom + i, middle + i);
290  }
291  /* Exclude the moved top segment from further swapping. */
292  bottom += len;
293  }
294  }
295 
296  /* Update records for the slots the non-options now occupy. */
297 
300 }
301 
302 /* Initialize the internal data when the first call is made. */
303 
304 #if defined(__STDC__) && __STDC__
305 static const char *
306 _getopt_initialize(int, char *const *, const char *);
307 #endif
308 static const char *
309 _getopt_initialize(int argc, char *const *argv, const char *optstring)
310 {
311  /* Start processing options with ARGV-element 1 (since ARGV-element 0
312  * is the program name); the sequence of previously skipped
313  * non-option ARGV-elements is empty. */
314 
316 
317  nextchar = NULL;
318 
319  posixly_correct = getenv("POSIXLY_CORRECT");
320 
321  /* Determine how to handle the ordering of options and nonoptions. */
322 
323  if (optstring[0] == '-')
324  {
326  ++optstring;
327  }
328  else if (optstring[0] == '+')
329  {
331  ++optstring;
332  }
333  else if (posixly_correct != NULL)
335  else
336  ordering = PERMUTE;
337 
338  return optstring;
339 }
340 
341 /* Scan elements of ARGV (whose length is ARGC) for option characters
342  given in OPTSTRING.
343 
344  If an element of ARGV starts with '-', and is not exactly "-" or "--",
345  then it is an option element. The characters of this element
346  (aside from the initial '-') are option characters. If `getopt'
347  is called repeatedly, it returns successively each of the option characters
348  from each of the option elements.
349 
350  If `getopt' finds another option character, it returns that character,
351  updating `GNoptind' and `nextchar' so that the next call to `getopt' can
352  resume the scan with the following option character or ARGV-element.
353 
354  If there are no more option characters, `getopt' returns -1.
355  Then `GNoptind' is the index in ARGV of the first ARGV-element
356  that is not an option. (The ARGV-elements have been permuted
357  so that those that are not options now come last.)
358 
359  OPTSTRING is a string containing the legitimate option characters.
360  If an option character is seen that is not listed in OPTSTRING,
361  return '?' after printing an error message. If you set `GNopterr' to
362  zero, the error message is suppressed but we still return '?'.
363 
364  If a char in OPTSTRING is followed by a colon, that means it wants an arg,
365  so the following text in the same ARGV-element, or the text of the following
366  ARGV-element, is returned in `GNoptarg'. Two colons mean an option that
367  wants an optional arg; if there is text in the current ARGV-element,
368  it is returned in `GNoptarg', otherwise `GNoptarg' is set to zero.
369 
370  If OPTSTRING starts with `-' or `+', it requests different methods of
371  handling the non-option ARGV-elements.
372  See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
373 
374  Long-named options begin with `--' instead of `-'.
375  Their names may be abbreviated as long as the abbreviation is unique
376  or is an exact match for some defined option. If they have an
377  argument, it follows the option name in the same ARGV-element, separated
378  from the option name by a `=', or else the in next ARGV-element.
379  When `getopt' finds a long-named option, it returns 0 if that option's
380  `flag' field is nonzero, the value of the option's `val' field
381  if the `flag' field is zero.
382 
383  The elements of ARGV aren't really const, because we GNUNET_CRYPTO_random_permute them.
384  But we pretend they're const in the prototype to be compatible
385  with other systems.
386 
387  LONGOPTS is a vector of `struct GNoption' terminated by an
388  element containing a name which is zero.
389 
390  LONGIND returns the index in LONGOPT of the long-named option found.
391  It is only valid when a long-named option has been found by the most
392  recent call.
393 
394  If LONG_ONLY is nonzero, '-' as well as '--' can introduce
395  long-named options. */
396 
397 static int
399  char *const *argv,
400  const char *optstring,
401  const struct GNoption *longopts,
402  int *longind,
403  int long_only)
404 {
405  static int __getopt_initialized = 0;
406  static int GNopterr = 1;
407 
408  GNoptarg = NULL;
409 
410  if (GNoptind == 0 || !__getopt_initialized)
411  {
412  if (GNoptind == 0)
413  GNoptind = 1; /* Don't scan ARGV[0], the program name. */
414  optstring = _getopt_initialize(argc, argv, optstring);
415  __getopt_initialized = 1;
416  }
417 
418  /* Test whether ARGV[GNoptind] points to a non-option argument.
419  * Either it does not have option syntax, or there is an environment flag
420  * from the shell indicating it is not an option. The later information
421  * is only used when the used in the GNU libc. */
422 #define NONOPTION_P (argv[GNoptind][0] != '-' || argv[GNoptind][1] == '\0')
423 
424  if (nextchar == NULL || *nextchar == '\0')
425  {
426  /* Advance to the next ARGV-element. */
427 
428  /* Give FIRST_NONOPT & LAST_NONOPT rational values if GNoptind has been
429  * moved back by the user (who may also have changed the arguments). */
430  if (last_nonopt > GNoptind)
432  if (first_nonopt > GNoptind)
434 
435  if (ordering == PERMUTE)
436  {
437  /* If we have just processed some options following some non-options,
438  * exchange them so that the options come first. */
439 
441  exchange((char **)argv);
442  else if (last_nonopt != GNoptind)
444 
445  /* Skip any additional non-options
446  * and extend the range of non-options previously skipped. */
447 
448  while (GNoptind < argc && NONOPTION_P)
449  GNoptind++;
451  }
452 
453  /* The special ARGV-element `--' means premature end of options.
454  * Skip it like a null option,
455  * then exchange with previous non-options as if it were an option,
456  * then skip everything else like a non-option. */
457  if (GNoptind != argc && !strcmp(argv[GNoptind], "--"))
458  {
459  GNoptind++;
460 
461  if (first_nonopt != last_nonopt && last_nonopt != GNoptind)
462  exchange((char **)argv);
463  else if (first_nonopt == last_nonopt)
465  last_nonopt = argc;
466 
467  GNoptind = argc;
468  }
469 
470  /* If we have done all the ARGV-elements, stop the scan
471  * and back over any non-options that we skipped and permuted. */
472 
473  if (GNoptind == argc)
474  {
475  /* Set the next-arg-index to point at the non-options
476  * that we previously skipped, so the caller will digest them. */
477  if (first_nonopt != last_nonopt)
478  GNoptind = first_nonopt;
479  return -1;
480  }
481 
482  /* If we have come to a non-option and did not permute it,
483  * either stop the scan or describe it to the caller and pass it by. */
484 
485  if (NONOPTION_P)
486  {
487  if (ordering == REQUIRE_ORDER)
488  return -1;
489  GNoptarg = argv[GNoptind++];
490  return 1;
491  }
492 
493  /* We have found another option-ARGV-element.
494  * Skip the initial punctuation. */
495 
496  nextchar =
497  (argv[GNoptind] + 1 + (longopts != NULL && argv[GNoptind][1] == '-'));
498  }
499 
500  /* Decode the current option-ARGV-element. */
501 
502  /* Check whether the ARGV-element is a long option.
503  *
504  * If long_only and the ARGV-element has the form "-f", where f is
505  * a valid short option, don't consider it an abbreviated form of
506  * a long option that starts with f. Otherwise there would be no
507  * way to give the -f short option.
508  *
509  * On the other hand, if there's a long option "fubar" and
510  * the ARGV-element is "-fu", do consider that an abbreviation of
511  * the long option, just like "--fu", and not "-f" with arg "u".
512  *
513  * This distinction seems to be the most useful approach. */
514 
515  if (longopts != NULL &&
516  (argv[GNoptind][1] == '-' ||
517  (long_only &&
518  (argv[GNoptind][2] || !my_index(optstring, argv[GNoptind][1])))))
519  {
520  char *nameend;
521  const struct GNoption *p;
522  const struct GNoption *pfound = NULL;
523  int exact = 0;
524  int ambig = 0;
525  int indfound = -1;
526  int option_index;
527 
528  for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
529  /* Do nothing. */;
530 
531  /* Test all long options for either exact match
532  * or abbreviated matches. */
533  for (p = longopts, option_index = 0; p->name; p++, option_index++)
534  if (!strncmp(p->name, nextchar, nameend - nextchar))
535  {
536  if ((unsigned int)(nameend - nextchar) ==
537  (unsigned int)strlen(p->name))
538  {
539  /* Exact match found. */
540  pfound = p;
541  indfound = option_index;
542  exact = 1;
543  break;
544  }
545  else if (pfound == NULL)
546  {
547  /* First nonexact match found. */
548  pfound = p;
549  indfound = option_index;
550  }
551  else
552  /* Second or later nonexact match found. */
553  ambig = 1;
554  }
555 
556  if (ambig && !exact)
557  {
558  if (GNopterr)
559  fprintf(stderr,
560  _("%s: option `%s' is ambiguous\n"),
561  argv[0],
562  argv[GNoptind]);
563  nextchar += strlen(nextchar);
564  GNoptind++;
565  return '?';
566  }
567 
568  if (pfound != NULL)
569  {
570  option_index = indfound;
571  GNoptind++;
572  if (*nameend)
573  {
574  /* Don't test has_arg with >, because some C compilers don't
575  * allow it to be used on enums. */
576  if (pfound->has_arg)
577  GNoptarg = nameend + 1;
578  else
579  {
580  if (GNopterr)
581  {
582  if (argv[GNoptind - 1][1] == '-')
583  /* --option */
584  fprintf(stderr,
585  _("%s: option `--%s' does not allow an argument\n"),
586  argv[0],
587  pfound->name);
588  else
589  /* +option or -option */
590  fprintf(stderr,
591  _("%s: option `%c%s' does not allow an argument\n"),
592  argv[0],
593  argv[GNoptind - 1][0],
594  pfound->name);
595  }
596  nextchar += strlen(nextchar);
597  return '?';
598  }
599  }
600  else if (pfound->has_arg == 1)
601  {
602  if (GNoptind < argc)
603  {
604  GNoptarg = argv[GNoptind++];
605  }
606  else
607  {
608  if (GNopterr)
609  {
610  fprintf(stderr,
611  _("%s: option `%s' requires an argument\n"),
612  argv[0],
613  argv[GNoptind - 1]);
614  }
615  nextchar += strlen(nextchar);
616  return (optstring[0] == ':') ? ':' : '?';
617  }
618  }
619  nextchar += strlen(nextchar);
620  if (longind != NULL)
621  *longind = option_index;
622  if (pfound->flag)
623  {
624  *(pfound->flag) = pfound->val;
625  return 0;
626  }
627  return pfound->val;
628  }
629 
630  /* Can't find it as a long option. If this is not getopt_long_only,
631  * or the option starts with '--' or is not a valid short
632  * option, then it's an error.
633  * Otherwise interpret it as a short option. */
634  if (!long_only || argv[GNoptind][1] == '-' ||
635  my_index(optstring, *nextchar) == NULL)
636  {
637  if (GNopterr)
638  {
639  if (argv[GNoptind][1] == '-')
640  /* --option */
641  fprintf(stderr,
642  _("%s: unrecognized option `--%s'\n"),
643  argv[0],
644  nextchar);
645  else
646  /* +option or -option */
647  fprintf(stderr,
648  _("%s: unrecognized option `%c%s'\n"),
649  argv[0],
650  argv[GNoptind][0],
651  nextchar);
652  }
653  nextchar = (char *)"";
654  GNoptind++;
655  return '?';
656  }
657  }
658 
659  /* Look at and handle the next short option-character. */
660 
661  {
662  char c = *nextchar++;
663  char *temp = my_index(optstring, c);
664 
665  /* Increment `GNoptind' when we start to process its last character. */
666  if (*nextchar == '\0')
667  ++GNoptind;
668 
669  if (temp == NULL || c == ':')
670  {
671  if (GNopterr)
672  {
673  if (posixly_correct)
674  /* 1003.2 specifies the format of this message. */
675  fprintf(stderr, _("%s: illegal option -- %c\n"), argv[0], c);
676  else
677  fprintf(stderr, _("%s: invalid option -- %c\n"), argv[0], c);
678  }
679  return '?';
680  }
681  /* Convenience. Treat POSIX -W foo same as long option --foo */
682  if (temp[0] == 'W' && temp[1] == ';')
683  {
684  char *nameend;
685  const struct GNoption *p;
686  const struct GNoption *pfound = NULL;
687  int exact = 0;
688  int ambig = 0;
689  int indfound = 0;
690  int option_index;
691 
692  /* This is an option that requires an argument. */
693  if (*nextchar != '\0')
694  {
695  GNoptarg = nextchar;
696  /* If we end this ARGV-element by taking the rest as an arg,
697  * we must advance to the next element now. */
698  GNoptind++;
699  }
700  else if (GNoptind == argc)
701  {
702  if (GNopterr)
703  {
704  /* 1003.2 specifies the format of this message. */
705  fprintf(stderr,
706  _("%s: option requires an argument -- %c\n"),
707  argv[0],
708  c);
709  }
710  if (optstring[0] == ':')
711  c = ':';
712  else
713  c = '?';
714  return c;
715  }
716  else
717  /* We already incremented `GNoptind' once;
718  * increment it again when taking next ARGV-elt as argument. */
719  GNoptarg = argv[GNoptind++];
720 
721  /* GNoptarg is now the argument, see if it's in the
722  * table of longopts. */
723 
724  for (nextchar = nameend = GNoptarg; *nameend && *nameend != '=';
725  nameend++)
726  /* Do nothing. */;
727 
728  /* Test all long options for either exact match
729  * or abbreviated matches. */
730  if (longopts != NULL)
731  for (p = longopts, option_index = 0; p->name; p++, option_index++)
732  if (!strncmp(p->name, nextchar, nameend - nextchar))
733  {
734  if ((unsigned int)(nameend - nextchar) == strlen(p->name))
735  {
736  /* Exact match found. */
737  pfound = p;
738  indfound = option_index;
739  exact = 1;
740  break;
741  }
742  else if (pfound == NULL)
743  {
744  /* First nonexact match found. */
745  pfound = p;
746  indfound = option_index;
747  }
748  else
749  /* Second or later nonexact match found. */
750  ambig = 1;
751  }
752  if (ambig && !exact)
753  {
754  if (GNopterr)
755  fprintf(stderr,
756  _("%s: option `-W %s' is ambiguous\n"),
757  argv[0],
758  argv[GNoptind]);
759  nextchar += strlen(nextchar);
760  GNoptind++;
761  return '?';
762  }
763  if (pfound != NULL)
764  {
765  option_index = indfound;
766  if (*nameend)
767  {
768  /* Don't test has_arg with >, because some C compilers don't
769  * allow it to be used on enums. */
770  if (pfound->has_arg)
771  GNoptarg = nameend + 1;
772  else
773  {
774  if (GNopterr)
775  fprintf(stderr,
776  _("%s: option `-W %s' does not allow an argument\n"),
777  argv[0],
778  pfound->name);
779 
780  nextchar += strlen(nextchar);
781  return '?';
782  }
783  }
784  else if (pfound->has_arg == 1)
785  {
786  if (GNoptind < argc)
787  GNoptarg = argv[GNoptind++];
788  else
789  {
790  if (GNopterr)
791  fprintf(stderr,
792  _("%s: option `%s' requires an argument\n"),
793  argv[0],
794  argv[GNoptind - 1]);
795  nextchar += strlen(nextchar);
796  return optstring[0] == ':' ? ':' : '?';
797  }
798  }
799  nextchar += strlen(nextchar);
800  if (longind != NULL)
801  *longind = option_index;
802  if (pfound->flag)
803  {
804  *(pfound->flag) = pfound->val;
805  return 0;
806  }
807  return pfound->val;
808  }
809  nextchar = NULL;
810  return 'W'; /* Let the application handle it. */
811  }
812  if (temp[1] == ':')
813  {
814  if (temp[2] == ':')
815  {
816  /* This is an option that accepts an argument optionally. */
817  if (*nextchar != '\0')
818  {
819  GNoptarg = nextchar;
820  GNoptind++;
821  }
822  else
823  GNoptarg = NULL;
824  nextchar = NULL;
825  }
826  else
827  {
828  /* This is an option that requires an argument. */
829  if (*nextchar != '\0')
830  {
831  GNoptarg = nextchar;
832  /* If we end this ARGV-element by taking the rest as an arg,
833  * we must advance to the next element now. */
834  GNoptind++;
835  }
836  else if (GNoptind == argc)
837  {
838  if (GNopterr)
839  {
840  /* 1003.2 specifies the format of this message. */
841  fprintf(stderr,
842  _("%s: option requires an argument -- %c\n"),
843  argv[0],
844  c);
845  }
846  if (optstring[0] == ':')
847  c = ':';
848  else
849  c = '?';
850  }
851  else
852  /* We already incremented `GNoptind' once;
853  * increment it again when taking next ARGV-elt as argument. */
854  GNoptarg = argv[GNoptind++];
855  nextchar = NULL;
856  }
857  }
858  return c;
859  }
860 }
861 
862 
863 static int
864 GNgetopt_long(int argc,
865  char *const *argv,
866  const char *options,
867  const struct GNoption *long_options,
868  int *opt_index)
869 {
870  return GN_getopt_internal(argc, argv, options, long_options, opt_index, 0);
871 }
872 
873 /* ******************** now the GNUnet specific modifications... ********************* */
874 
885 int
886 GNUNET_GETOPT_run(const char *binaryOptions,
887  const struct GNUNET_GETOPT_CommandLineOption *allOptions,
888  unsigned int argc,
889  char *const *argv)
890 {
891  struct GNoption *long_options;
893  int count;
894  char *shorts;
895  int spos;
896  int cont;
897  uint8_t *seen;
898  unsigned int optmatch = 0;
899  const char *have_exclusive = NULL;
900 
901  GNUNET_assert(argc > 0);
902  GNoptind = 0;
903  clpc.binaryName = argv[0];
905  clpc.allOptions = allOptions;
906  clpc.argv = argv;
907  clpc.argc = argc;
908  for (count = 0; NULL != allOptions[count].name; count++)
909  ;
910 
911  /* transform our option representation into the format
912  used by the GNU getopt copylib */
913  long_options = GNUNET_new_array(count + 1, struct GNoption);
914  seen = GNUNET_new_array(count, uint8_t);
915  shorts = GNUNET_malloc(count * 2 + 1);
916  spos = 0;
917  for (unsigned i = 0; i < count; i++)
918  {
919  long_options[i].name = allOptions[i].name;
920  long_options[i].has_arg = allOptions[i].require_argument;
921  long_options[i].flag = NULL;
922  long_options[i].val = allOptions[i].shortName;
923  shorts[spos++] = allOptions[i].shortName;
924  if (allOptions[i].require_argument != 0)
925  shorts[spos++] = ':';
926  }
927  long_options[count].name = NULL;
928  long_options[count].has_arg = 0;
929  long_options[count].flag = NULL;
930  long_options[count].val = '\0';
931  shorts[spos] = '\0';
932  cont = GNUNET_OK;
933 
934  /* main getopt loop */
935  while (1)
936  {
937  int option_index = 0;
938  unsigned int i;
939  int c;
940 
941  c = GNgetopt_long(argc, argv, shorts, long_options, &option_index);
942  if (c == GNUNET_SYSERR)
943  break; /* No more flags to process */
944 
945  /* Check which of our program's options was given by the user */
946  for (i = 0; i < count; i++)
947  {
948  clpc.currentArgument = GNoptind - 1;
949  if ((char)c == allOptions[i].shortName)
950  {
951  optmatch++;
952  if (allOptions[i].option_exclusive)
953  have_exclusive = allOptions[i].name;
954  if (GNUNET_OK == cont)
955  {
956  /* parse the option using the option-specific processor */
957  cont = allOptions[i].processor(&clpc,
958  allOptions[i].scls,
959  allOptions[i].name,
960  GNoptarg);
961  }
962  seen[i] = 1;
963  break;
964  }
965  }
966  if (i == count)
967  {
968  fprintf(stderr, _("Use %s to get a list of options.\n"), "--help");
969  cont = GNUNET_SYSERR;
970  }
971  }
972  GNUNET_free(shorts);
973  GNUNET_free(long_options);
974 
975  /* check that if any option that was marked as exclusive
976  is the only option that was provided */
977  if ((NULL != have_exclusive) && (optmatch > 1))
978  {
979  fprintf(stderr,
980  _("Option `%s' can't be used with other options.\n"),
981  have_exclusive);
982  cont = GNUNET_SYSERR;
983  }
984  if (GNUNET_YES == cont)
985  {
986  /* check that all mandatory options are present */
987  for (count = 0; NULL != allOptions[count].name; count++)
988  {
989  if ((0 == seen[count]) && (allOptions[count].option_mandatory))
990  {
991  fprintf(stderr,
992  _("Missing mandatory option `%s'.\n"),
993  allOptions[count].name);
994  cont = GNUNET_SYSERR;
995  }
996  }
997  }
998  GNUNET_free(seen);
999 
1000  /* call cleaners, if available */
1001  for (unsigned int i = 0; NULL != allOptions[i].name; i++)
1002  if (NULL != allOptions[i].cleaner)
1003  allOptions[i].cleaner(allOptions[i].scls);
1004 
1005  if (GNUNET_OK != cont)
1006  return cont;
1007  return GNoptind;
1008 }
1009 
1010 /* end of getopt.c */
General context for command line processors.
unsigned int argc
Total number of argv&#39;s.
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
#define SWAP_FLAGS(ch1, ch2)
Definition: getopt.c:229
static int last_nonopt
Definition: getopt.c:227
int has_arg
Definition: getopt.c:91
static char * GNoptarg
Definition: getopt.c:117
const char * binaryName
Name of the application.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
char *const * argv
Original command line.
static const char * _getopt_initialize(int argc, char *const *argv, const char *optstring)
Definition: getopt.c:309
struct GNUNET_ATS_TEST_Topology * top
Definition: ats-testing.c:52
const struct GNUNET_GETOPT_CommandLineOption * allOptions
Array with all command line options.
static enum @83 ordering
GNUNET_GETOPT_CommandLineOptionProcessor processor
Handler for the option.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
Definition of a command line option.
const char shortName
Short name of the option.
static void exchange(char **argv)
Definition: getopt.c:246
#define _(msgid)
Definition: getopt.c:62
const char * name
Definition: getopt.c:88
static char * posixly_correct
Definition: getopt.c:176
static int GNoptind
Definition: getopt.c:132
int val
Definition: getopt.c:93
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-qr.c:59
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
int require_argument
Is an argument required? GNUNET_NO (includes optional) or GNUNET_YES (required)
void(* cleaner)(void *cls)
Function to call on scls to clean up after processing all the arguments.
static int GN_getopt_internal(int argc, char *const *argv, const char *optstring, const struct GNoption *longopts, int *longind, int long_only)
Definition: getopt.c:398
unsigned int currentArgument
Current argument.
int GNUNET_GETOPT_run(const char *binaryOptions, const struct GNUNET_GETOPT_CommandLineOption *allOptions, unsigned int argc, char *const *argv)
Parse the command line.
Definition: getopt.c:886
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static int first_nonopt
Definition: getopt.c:226
char * getenv()
static char * nextchar
Definition: getopt.c:141
static int GNgetopt_long(int argc, char *const *argv, const char *options, const struct GNoption *long_options, int *opt_index)
Definition: getopt.c:864
const char * binaryOptions
Name of application with option summary.
static char * my_index(const char *str, int chr)
Definition: getopt.c:194
int * flag
Definition: getopt.c:92
#define GNUNET_YES
Definition: gnunet_common.h:77
#define NONOPTION_P
const char * name
Long name of the option (may not be NULL)
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...