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