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