GNUnet  0.11.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 {
89  const char *name;
90  /* has_arg can't be an enum because some compilers complain about
91  * type mismatches in all the code that assumes it is an int. */
92  int has_arg;
93  int *flag;
94  int val;
95 };
96 
97 
98 /* This version of `getopt' appears to the caller like standard Unix `getopt'
99  but it behaves differently for the user, since it allows the user
100  to intersperse the options with the other arguments.
101 
102  As `getopt' works, it permutes the elements of ARGV so that,
103  when it is done, all the options precede everything else. Thus
104  all application programs are extended to handle flexible argument order.
105 
106  Setting the environment variable POSIXLY_CORRECT disables permutation.
107  Then the behavior is completely standard.
108 
109  GNU application programs can use a third alternative mode in which
110  they can distinguish the relative order of options and other arguments. */
111 
112 /* For communication from `getopt' to the caller.
113  When `getopt' finds an option that takes an argument,
114  the argument value is returned here.
115  Also, when `ordering' is RETURN_IN_ORDER,
116  each non-option ARGV-element is returned here. */
117 
118 static char *GNoptarg = NULL;
119 
120 /* Index in ARGV of the next element to be scanned.
121  This is used for communication to and from the caller
122  and for communication between successive calls to `getopt'.
123 
124  On entry to `getopt', zero means this is the first call; initialize.
125 
126  When `getopt' returns -1, this is the index of the first of the
127  non-option elements that the caller should itself scan.
128 
129  Otherwise, `GNoptind' communicates from one call to the next
130  how much of ARGV has been scanned so far. */
131 
132 /* 1003.2 says this must be 1 before any call. */
133 static int GNoptind = 1;
134 
135 /* The next char to be scanned in the option-element
136  in which the last option character we returned was found.
137  This allows us to pick up the scan where we left off.
138 
139  If this is zero, or a null string, it means resume the scan
140  by advancing to the next ARGV-element. */
141 
142 static char *nextchar;
143 
144 
145 /* Describe how to deal with options that follow non-option ARGV-elements.
146 
147  If the caller did not specify anything,
148  the default is REQUIRE_ORDER if the environment variable
149  POSIXLY_CORRECT is defined, PERMUTE otherwise.
150 
151  REQUIRE_ORDER means don't recognize them as options;
152  stop option processing when the first non-option is seen.
153  This is what Unix does.
154  This mode of operation is selected by either setting the environment
155  variable POSIXLY_CORRECT, or using `+' as the first character
156  of the list of option characters.
157 
158  PERMUTE is the default. We GNUNET_CRYPTO_random_permute the contents of ARGV as we scan,
159  so that eventually all the non-options are at the end. This allows options
160  to be given in any order, even with programs that were not written to
161  expect this.
162 
163  RETURN_IN_ORDER is an option available to programs that were written
164  to expect GNoptions and other ARGV-elements in any order and that care about
165  the ordering of the two. We describe each non-option ARGV-element
166  as if it were the argument of an option with character code 1.
167  Using `-' as the first character of the list of option characters
168  selects this mode of operation.
169 
170  The special argument `--' forces an end of option-scanning regardless
171  of the value of `ordering'. In the case of RETURN_IN_ORDER, only
172  `--' can cause `getopt' to return -1 with `GNoptind' != ARGC. */
173 
175 
176 /* Value of POSIXLY_CORRECT environment variable. */
177 static char *posixly_correct;
178 
179 #ifdef __GNU_LIBRARY__
180 /* We want to avoid inclusion of string.h with non-GNU libraries
181  because there are many ways it can cause trouble.
182  On some systems, it contains special magic macros that don't work
183  in GCC. */
184 #include <string.h>
185 #define my_index strchr
186 #else
187 
188 /* Avoid depending on library functions or files
189  whose names are inconsistent. */
190 
191 char *
192 getenv ();
193 
194 static char *
195 my_index (const char *str, int chr)
196 {
197  while (*str)
198  {
199  if (*str == chr)
200  return (char *) str;
201  str++;
202  }
203  return 0;
204 }
205 
206 
207 /* If using GCC, we can safely declare strlen this way.
208  If not using GCC, it is ok not to declare it. */
209 #ifdef __GNUC__
210 /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
211  That was relevant to code that was here before. */
212 #if ! defined(__STDC__) || ! __STDC__
213 /* gcc with -traditional declares the built-in strlen to return int,
214  and has done so at least since version 2.4.5. -- rms. */
215 extern int
216 strlen (const char *);
217 
218 #endif /* not __STDC__ */
219 #endif /* __GNUC__ */
220 
221 #endif /* not __GNU_LIBRARY__ */
222 
223 /* Handle permutation of arguments. */
224 
225 /* Describe the part of ARGV that contains non-options that have
226  been skipped. `first_nonopt' is the index in ARGV of the first of them;
227  `last_nonopt' is the index after the last of them. */
228 
229 static int first_nonopt;
230 static int last_nonopt;
231 
232 #define SWAP_FLAGS(ch1, ch2)
233 
234 /* Exchange two adjacent subsequences of ARGV.
235  One subsequence is elements [first_nonopt,last_nonopt)
236  which contains all the non-options that have been skipped so far.
237  The other is elements [last_nonopt,GNoptind), which contains all
238  the options processed since those non-options were skipped.
239 
240  `first_nonopt' and `last_nonopt' are relocated so that they describe
241  the new indices of the non-options in ARGV after they are moved. */
242 
243 #if defined(__STDC__) && __STDC__
244 static void
245 exchange (char **);
246 
247 #endif
248 
249 static void
250 exchange (char **argv)
251 {
252  int bottom = first_nonopt;
253  int middle = last_nonopt;
254  int top = GNoptind;
255  char *tem;
256 
257  /* Exchange the shorter segment with the far end of the longer segment.
258  * That puts the shorter segment into the right place.
259  * It leaves the longer segment in the right place overall,
260  * but it consists of two parts that need to be swapped next. */
261 
262  while (top > middle && middle > bottom)
263  {
264  if (top - middle > middle - bottom)
265  {
266  /* Bottom segment is the short one. */
267  int len = middle - bottom;
268  register int i;
269 
270  /* Swap it with the top part of the top segment. */
271  for (i = 0; i < len; i++)
272  {
273  tem = argv[bottom + i];
274  argv[bottom + i] = argv[top - (middle - bottom) + i];
275  argv[top - (middle - bottom) + i] = tem;
276  SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
277  }
278  /* Exclude the moved bottom segment from further swapping. */
279  top -= len;
280  }
281  else
282  {
283  /* Top segment is the short one. */
284  int len = top - middle;
285  register int i;
286 
287  /* Swap it with the bottom part of the bottom segment. */
288  for (i = 0; i < len; i++)
289  {
290  tem = argv[bottom + i];
291  argv[bottom + i] = argv[middle + i];
292  argv[middle + i] = tem;
293  SWAP_FLAGS (bottom + i, middle + i);
294  }
295  /* Exclude the moved top segment from further swapping. */
296  bottom += len;
297  }
298  }
299 
300  /* Update records for the slots the non-options now occupy. */
301 
304 }
305 
306 
307 /* Initialize the internal data when the first call is made. */
308 
309 #if defined(__STDC__) && __STDC__
310 static const char *
311 _getopt_initialize (int, char *const *, const char *);
312 
313 #endif
314 static const char *
315 _getopt_initialize (int argc, char *const *argv, const char *optstring)
316 {
317  /* Start processing options with ARGV-element 1 (since ARGV-element 0
318  * is the program name); the sequence of previously skipped
319  * non-option ARGV-elements is empty. */
320 
322 
323  nextchar = NULL;
324 
325  posixly_correct = getenv ("POSIXLY_CORRECT");
326 
327  /* Determine how to handle the ordering of options and nonoptions. */
328 
329  if (optstring[0] == '-')
330  {
332  ++optstring;
333  }
334  else if (optstring[0] == '+')
335  {
337  ++optstring;
338  }
339  else if (posixly_correct != NULL)
341  else
342  ordering = PERMUTE;
343 
344  return optstring;
345 }
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 
447  if ((first_nonopt != last_nonopt) && (last_nonopt != GNoptind) )
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. */if ((longopts != NULL) &&
521  ((argv[GNoptind][1] == '-') ||
522  (long_only &&
523  (argv[GNoptind][2] || ! my_index (optstring, argv[GNoptind][1])))))
524  {
525  char *nameend;
526  const struct GNoption *p;
527  const struct GNoption *pfound = NULL;
528  int exact = 0;
529  int ambig = 0;
530  int indfound = -1;
531  int option_index;
532 
533  for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
534  /* Do nothing. */;
535 
536  /* Test all long options for either exact match
537  * or abbreviated matches. */
538  for (p = longopts, option_index = 0; p->name; p++, option_index++)
539  if (! strncmp (p->name, nextchar, nameend - nextchar))
540  {
541  if ((unsigned int) (nameend - nextchar) ==
542  (unsigned int) strlen (p->name))
543  {
544  /* Exact match found. */
545  pfound = p;
546  indfound = option_index;
547  exact = 1;
548  break;
549  }
550  else if (pfound == NULL)
551  {
552  /* First nonexact match found. */
553  pfound = p;
554  indfound = option_index;
555  }
556  else
557  /* Second or later nonexact match found. */
558  ambig = 1;
559  }
560 
561  if (ambig && ! exact)
562  {
563  if (GNopterr)
564  fprintf (stderr,
565  _ ("%s: option `%s' is ambiguous\n"),
566  argv[0],
567  argv[GNoptind]);
568  nextchar += strlen (nextchar);
569  GNoptind++;
570  return '?';
571  }
572 
573  if (pfound != NULL)
574  {
575  option_index = indfound;
576  GNoptind++;
577  if (*nameend)
578  {
579  /* Don't test has_arg with >, because some C compilers don't
580  * allow it to be used on enums. */
581  if (pfound->has_arg)
582  GNoptarg = nameend + 1;
583  else
584  {
585  if (GNopterr)
586  {
587  if (argv[GNoptind - 1][1] == '-')
588  /* --option */
589  fprintf (stderr,
590  _ ("%s: option `--%s' does not allow an argument\n"),
591  argv[0],
592  pfound->name);
593  else
594  /* +option or -option */
595  fprintf (stderr,
596  _ ("%s: option `%c%s' does not allow an argument\n"),
597  argv[0],
598  argv[GNoptind - 1][0],
599  pfound->name);
600  }
601  nextchar += strlen (nextchar);
602  return '?';
603  }
604  }
605  else if (pfound->has_arg == 1)
606  {
607  if (GNoptind < argc)
608  {
609  GNoptarg = argv[GNoptind++];
610  }
611  else
612  {
613  if (GNopterr)
614  {
615  fprintf (stderr,
616  _ ("%s: option `%s' requires an argument\n"),
617  argv[0],
618  argv[GNoptind - 1]);
619  }
620  nextchar += strlen (nextchar);
621  return (optstring[0] == ':') ? ':' : '?';
622  }
623  }
624  nextchar += strlen (nextchar);
625  if (longind != NULL)
626  *longind = option_index;
627  if (pfound->flag)
628  {
629  *(pfound->flag) = pfound->val;
630  return 0;
631  }
632  return pfound->val;
633  }
634 
635  /* Can't find it as a long option. If this is not getopt_long_only,
636  * or the option starts with '--' or is not a valid short
637  * option, then it's an error.
638  * Otherwise interpret it as a short option. */
639  if (! long_only || (argv[GNoptind][1] == '-') ||
640  (my_index (optstring, *nextchar) == NULL) )
641  {
642  if (GNopterr)
643  {
644  if (argv[GNoptind][1] == '-')
645  /* --option */
646  fprintf (stderr,
647  _ ("%s: unrecognized option `--%s'\n"),
648  argv[0],
649  nextchar);
650  else
651  /* +option or -option */
652  fprintf (stderr,
653  _ ("%s: unrecognized option `%c%s'\n"),
654  argv[0],
655  argv[GNoptind][0],
656  nextchar);
657  }
658  nextchar = (char *) "";
659  GNoptind++;
660  return '?';
661  }
662  }
663 
664  /* Look at and handle the next short option-character. */
665 
666  {
667  char c = *nextchar++;
668  char *temp = my_index (optstring, c);
669 
670  /* Increment `GNoptind' when we start to process its last character. */
671  if (*nextchar == '\0')
672  ++GNoptind;
673 
674  if ((temp == NULL) || (c == ':'))
675  {
676  if (GNopterr)
677  {
678  if (posixly_correct)
679  /* 1003.2 specifies the format of this message. */
680  fprintf (stderr, _ ("%s: illegal option -- %c\n"), argv[0], c);
681  else
682  fprintf (stderr, _ ("%s: invalid option -- %c\n"), argv[0], c);
683  }
684  return '?';
685  }
686  /* Convenience. Treat POSIX -W foo same as long option --foo */
687  if ((temp[0] == 'W') && (temp[1] == ';'))
688  {
689  char *nameend;
690  const struct GNoption *p;
691  const struct GNoption *pfound = NULL;
692  int exact = 0;
693  int ambig = 0;
694  int indfound = 0;
695  int option_index;
696 
697  /* This is an option that requires an argument. */
698  if (*nextchar != '\0')
699  {
700  GNoptarg = nextchar;
701  /* If we end this ARGV-element by taking the rest as an arg,
702  * we must advance to the next element now. */
703  GNoptind++;
704  }
705  else if (GNoptind == argc)
706  {
707  if (GNopterr)
708  {
709  /* 1003.2 specifies the format of this message. */
710  fprintf (stderr,
711  _ ("%s: option requires an argument -- %c\n"),
712  argv[0],
713  c);
714  }
715  if (optstring[0] == ':')
716  c = ':';
717  else
718  c = '?';
719  return c;
720  }
721  else
722  /* We already incremented `GNoptind' once;
723  * increment it again when taking next ARGV-elt as argument. */
724  GNoptarg = argv[GNoptind++];
725 
726  /* GNoptarg is now the argument, see if it's in the
727  * table of longopts. */
728 
729  for (nextchar = nameend = GNoptarg; *nameend && *nameend != '=';
730  nameend++)
731  /* Do nothing. */;
732 
733  /* Test all long options for either exact match
734  * or abbreviated matches. */
735  if (longopts != NULL)
736  for (p = longopts, option_index = 0; p->name; p++, option_index++)
737  if (! strncmp (p->name, nextchar, nameend - nextchar))
738  {
739  if ((unsigned int) (nameend - nextchar) == strlen (p->name))
740  {
741  /* Exact match found. */
742  pfound = p;
743  indfound = option_index;
744  exact = 1;
745  break;
746  }
747  else if (pfound == NULL)
748  {
749  /* First nonexact match found. */
750  pfound = p;
751  indfound = option_index;
752  }
753  else
754  /* Second or later nonexact match found. */
755  ambig = 1;
756  }
757  if (ambig && ! exact)
758  {
759  if (GNopterr)
760  fprintf (stderr,
761  _ ("%s: option `-W %s' is ambiguous\n"),
762  argv[0],
763  argv[GNoptind]);
764  nextchar += strlen (nextchar);
765  GNoptind++;
766  return '?';
767  }
768  if (pfound != NULL)
769  {
770  option_index = indfound;
771  if (*nameend)
772  {
773  /* Don't test has_arg with >, because some C compilers don't
774  * allow it to be used on enums. */
775  if (pfound->has_arg)
776  GNoptarg = nameend + 1;
777  else
778  {
779  if (GNopterr)
780  fprintf (stderr,
781  _ ("%s: option `-W %s' does not allow an argument\n"),
782  argv[0],
783  pfound->name);
784 
785  nextchar += strlen (nextchar);
786  return '?';
787  }
788  }
789  else if (pfound->has_arg == 1)
790  {
791  if (GNoptind < argc)
792  GNoptarg = argv[GNoptind++];
793  else
794  {
795  if (GNopterr)
796  fprintf (stderr,
797  _ ("%s: option `%s' requires an argument\n"),
798  argv[0],
799  argv[GNoptind - 1]);
800  nextchar += strlen (nextchar);
801  return optstring[0] == ':' ? ':' : '?';
802  }
803  }
804  nextchar += strlen (nextchar);
805  if (longind != NULL)
806  *longind = option_index;
807  if (pfound->flag)
808  {
809  *(pfound->flag) = pfound->val;
810  return 0;
811  }
812  return pfound->val;
813  }
814  nextchar = NULL;
815  return 'W'; /* Let the application handle it. */
816  }
817  if (temp[1] == ':')
818  {
819  if (temp[2] == ':')
820  {
821  /* This is an option that accepts an argument optionally. */
822  if (*nextchar != '\0')
823  {
824  GNoptarg = nextchar;
825  GNoptind++;
826  }
827  else
828  GNoptarg = NULL;
829  nextchar = NULL;
830  }
831  else
832  {
833  /* This is an option that requires an argument. */
834  if (*nextchar != '\0')
835  {
836  GNoptarg = nextchar;
837  /* If we end this ARGV-element by taking the rest as an arg,
838  * we must advance to the next element now. */
839  GNoptind++;
840  }
841  else if (GNoptind == argc)
842  {
843  if (GNopterr)
844  {
845  /* 1003.2 specifies the format of this message. */
846  fprintf (stderr,
847  _ ("%s: option requires an argument -- %c\n"),
848  argv[0],
849  c);
850  }
851  if (optstring[0] == ':')
852  c = ':';
853  else
854  c = '?';
855  }
856  else
857  /* We already incremented `GNoptind' once;
858  * increment it again when taking next ARGV-elt as argument. */
859  GNoptarg = argv[GNoptind++];
860  nextchar = NULL;
861  }
862  }
863  return c;
864  }
865 }
866 
867 
868 static int
869 GNgetopt_long (int argc,
870  char *const *argv,
871  const char *options,
872  const struct GNoption *long_options,
873  int *opt_index)
874 {
875  return GN_getopt_internal (argc, argv, options, long_options, opt_index, 0);
876 }
877 
878 
879 /* ******************** now the GNUnet specific modifications... ********************* */
880 
891 int
892 GNUNET_GETOPT_run (const char *binaryOptions,
893  const struct GNUNET_GETOPT_CommandLineOption *allOptions,
894  unsigned int argc,
895  char *const *argv)
896 {
897  struct GNoption *long_options;
899  int count;
900  char *shorts;
901  int spos;
902  int cont;
903  uint8_t *seen;
904  unsigned int optmatch = 0;
905  const char *have_exclusive = NULL;
906 
907  GNUNET_assert (argc > 0);
908  GNoptind = 0;
909  clpc.binaryName = argv[0];
911  clpc.allOptions = allOptions;
912  clpc.argv = argv;
913  clpc.argc = argc;
914  for (count = 0; NULL != allOptions[count].name; count++)
915  ;
916 
917  /* transform our option representation into the format
918  used by the GNU getopt copylib */
919  long_options = GNUNET_new_array (count + 1, struct GNoption);
920  seen = GNUNET_new_array (count, uint8_t);
921  shorts = GNUNET_malloc (count * 2 + 1);
922  spos = 0;
923  for (unsigned i = 0; i < count; i++)
924  {
925  long_options[i].name = allOptions[i].name;
926  long_options[i].has_arg = allOptions[i].require_argument;
927  long_options[i].flag = NULL;
928  long_options[i].val = allOptions[i].shortName;
929  shorts[spos++] = allOptions[i].shortName;
930  if (allOptions[i].require_argument != 0)
931  shorts[spos++] = ':';
932  }
933  long_options[count].name = NULL;
934  long_options[count].has_arg = 0;
935  long_options[count].flag = NULL;
936  long_options[count].val = '\0';
937  shorts[spos] = '\0';
938  cont = GNUNET_OK;
939 
940  /* main getopt loop */
941  while (1)
942  {
943  int option_index = 0;
944  unsigned int i;
945  int c;
946 
947  c = GNgetopt_long (argc, argv, shorts, long_options, &option_index);
948  if (c == GNUNET_SYSERR)
949  break; /* No more flags to process */
950 
951  /* Check which of our program's options was given by the user */
952  for (i = 0; i < count; i++)
953  {
954  clpc.currentArgument = GNoptind - 1;
955  if ((char) c == allOptions[i].shortName)
956  {
957  optmatch++;
958  if (allOptions[i].option_exclusive)
959  have_exclusive = allOptions[i].name;
960  if (GNUNET_OK == cont)
961  {
962  /* parse the option using the option-specific processor */
963  cont = allOptions[i].processor (&clpc,
964  allOptions[i].scls,
965  allOptions[i].name,
966  GNoptarg);
967  }
968  seen[i] = 1;
969  break;
970  }
971  }
972  if (i == count)
973  {
974  fprintf (stderr, _ ("Use %s to get a list of options.\n"), "--help");
975  cont = GNUNET_SYSERR;
976  }
977  }
978  GNUNET_free (shorts);
979  GNUNET_free (long_options);
980 
981  /* check that if any option that was marked as exclusive
982  is the only option that was provided */
983  if ((NULL != have_exclusive) && (optmatch > 1))
984  {
985  fprintf (stderr,
986  _ ("Option `%s' can't be used with other options.\n"),
987  have_exclusive);
988  cont = GNUNET_SYSERR;
989  }
990  if (GNUNET_YES == cont)
991  {
992  /* check that all mandatory options are present */
993  for (count = 0; NULL != allOptions[count].name; count++)
994  {
995  if ((0 == seen[count]) && (allOptions[count].option_mandatory))
996  {
997  fprintf (stderr,
998  _ ("Missing mandatory option `%s'.\n"),
999  allOptions[count].name);
1000  cont = GNUNET_SYSERR;
1001  }
1002  }
1003  }
1004  GNUNET_free (seen);
1005 
1006  /* call cleaners, if available */
1007  for (unsigned int i = 0; NULL != allOptions[i].name; i++)
1008  if (NULL != allOptions[i].cleaner)
1009  allOptions[i].cleaner (allOptions[i].scls);
1010 
1011  if (GNUNET_OK != cont)
1012  return cont;
1013  return GNoptind;
1014 }
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:232
static int last_nonopt
Definition: getopt.c:230
int has_arg
Definition: getopt.c:92
static char * GNoptarg
Definition: getopt.c:118
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:315
struct GNUNET_ATS_TEST_Topology * top
Definition: ats-testing.c:53
const struct GNUNET_GETOPT_CommandLineOption * allOptions
Array with all command line options.
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:250
#define _(msgid)
Definition: getopt.c:62
const char * name
Definition: getopt.c:89
static char * posixly_correct
Definition: getopt.c:177
static int GNoptind
Definition: getopt.c:133
int val
Definition: getopt.c:94
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:892
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static int first_nonopt
Definition: getopt.c:229
char * getenv()
static char * nextchar
Definition: getopt.c:142
static int GNgetopt_long(int argc, char *const *argv, const char *options, const struct GNoption *long_options, int *opt_index)
Definition: getopt.c:869
const char * binaryOptions
Name of application with option summary.
static char * my_index(const char *str, int chr)
Definition: getopt.c:195
int * flag
Definition: getopt.c:93
#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.
static enum @80 ordering
#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...