run indent twice, it alternates between two 'canonical' forms, also run whitespace...
[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 *
198 getenv ();
199
200 static char *
201 my_index (str, chr)
202   const char *str;
203   int chr;
204 {
205   while (*str)
206   {
207     if (*str == chr)
208       return (char *) str;
209     str++;
210   }
211   return 0;
212 }
213
214 /* If using GCC, we can safely declare strlen this way.
215    If not using GCC, it is ok not to declare it.  */
216 #ifdef __GNUC__
217 /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
218    That was relevant to code that was here before.  */
219 #if !defined (__STDC__) || !__STDC__
220 /* gcc with -traditional declares the built-in strlen to return int,
221    and has done so at least since version 2.4.5. -- rms.  */
222 extern int
223 strlen (const char *);
224 #endif /* not __STDC__ */
225 #endif /* __GNUC__ */
226
227 #endif /* not __GNU_LIBRARY__ */
228
229 /* Handle permutation of arguments.  */
230
231 /* Describe the part of ARGV that contains non-options that have
232    been skipped.  `first_nonopt' is the index in ARGV of the first of them;
233    `last_nonopt' is the index after the last of them.  */
234
235 static int first_nonopt;
236 static int last_nonopt;
237
238 #ifdef _LIBC
239 /* Bash 2.0 gives us an environment variable containing flags
240    indicating ARGV elements that should not be considered arguments.  */
241
242 /* Defined in getopt_init.c  */
243 extern char *__getopt_nonoption_flags;
244
245 static int nonoption_flags_max_len;
246 static int nonoption_flags_len;
247
248 static int original_argc;
249 static char *const *original_argv;
250
251 extern pid_t __libc_pid;
252
253 /* Make sure the environment variable bash 2.0 puts in the environment
254    is valid for the getopt call we must make sure that the ARGV passed
255    to getopt is that one passed to the process.  */
256 static void
257     __attribute__ ((unused)) store_args_and_env (int argc, char *const *argv)
258 {
259   /* XXX This is no good solution.  We should rather copy the args so
260    * that we can compare them later.  But we must not use malloc(3).  */
261   original_argc = argc;
262   original_argv = argv;
263 }
264
265 text_set_element (__libc_subinit, store_args_and_env);
266
267 #define SWAP_FLAGS(ch1, ch2) \
268   if (nonoption_flags_len > 0)                                                \
269     {                                                                 \
270       char __tmp = __getopt_nonoption_flags[ch1];                     \
271       __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2];        \
272       __getopt_nonoption_flags[ch2] = __tmp;                          \
273     }
274 #else /* !_LIBC */
275 #define SWAP_FLAGS(ch1, ch2)
276 #endif /* _LIBC */
277
278 /* Exchange two adjacent subsequences of ARGV.
279    One subsequence is elements [first_nonopt,last_nonopt)
280    which contains all the non-options that have been skipped so far.
281    The other is elements [last_nonopt,GNoptind), which contains all
282    the options processed since those non-options were skipped.
283
284    `first_nonopt' and `last_nonopt' are relocated so that they describe
285    the new indices of the non-options in ARGV after they are moved.  */
286
287 #if defined (__STDC__) && __STDC__
288 static void
289 exchange (char **);
290 #endif
291
292 static void
293 exchange (argv)
294   char **argv;
295 {
296   int bottom = first_nonopt;
297   int middle = last_nonopt;
298   int top = GNoptind;
299   char *tem;
300
301   /* Exchange the shorter segment with the far end of the longer segment.
302    * That puts the shorter segment into the right place.
303    * It leaves the longer segment in the right place overall,
304    * but it consists of two parts that need to be swapped next.  */
305
306 #ifdef _LIBC
307   /* First make sure the handling of the `__getopt_nonoption_flags'
308    * string can work normally.  Our top argument must be in the range
309    * of the string.  */
310   if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
311   {
312     /* We must extend the array.  The user plays games with us and
313      * presents new arguments.  */
314     char *new_str = malloc (top + 1);
315
316     if (new_str == NULL)
317       nonoption_flags_len = nonoption_flags_max_len = 0;
318     else
319     {
320       memcpy (new_str, __getopt_nonoption_flags, nonoption_flags_max_len);
321       memset (&new_str[nonoption_flags_max_len], '\0',
322               top + 1 - nonoption_flags_max_len);
323       nonoption_flags_max_len = top + 1;
324       __getopt_nonoption_flags = new_str;
325     }
326   }
327 #endif
328
329   while (top > middle && middle > bottom)
330   {
331     if (top - middle > middle - bottom)
332     {
333       /* Bottom segment is the short one.  */
334       int len = middle - bottom;
335       register int i;
336
337       /* Swap it with the top part of the top segment.  */
338       for (i = 0; i < len; i++)
339       {
340         tem = argv[bottom + i];
341         argv[bottom + i] = argv[top - (middle - bottom) + i];
342         argv[top - (middle - bottom) + i] = tem;
343         SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
344       }
345       /* Exclude the moved bottom segment from further swapping.  */
346       top -= len;
347     }
348     else
349     {
350       /* Top segment is the short one.  */
351       int len = top - middle;
352       register int i;
353
354       /* Swap it with the bottom part of the bottom segment.  */
355       for (i = 0; i < len; i++)
356       {
357         tem = argv[bottom + i];
358         argv[bottom + i] = argv[middle + i];
359         argv[middle + i] = tem;
360         SWAP_FLAGS (bottom + i, middle + i);
361       }
362       /* Exclude the moved top segment from further swapping.  */
363       bottom += len;
364     }
365   }
366
367   /* Update records for the slots the non-options now occupy.  */
368
369   first_nonopt += (GNoptind - last_nonopt);
370   last_nonopt = GNoptind;
371 }
372
373 /* Initialize the internal data when the first call is made.  */
374
375 #if defined (__STDC__) && __STDC__
376 static const char *
377 _getopt_initialize (int, char *const *, const char *);
378 #endif
379 static const char *
380 _getopt_initialize (argc, argv, optstring)
381   int argc;
382   char *const *argv;
383   const char *optstring;
384 {
385   /* Start processing options with ARGV-element 1 (since ARGV-element 0
386    * is the program name); the sequence of previously skipped
387    * non-option ARGV-elements is empty.  */
388
389   first_nonopt = last_nonopt = GNoptind;
390
391   nextchar = NULL;
392
393   posixly_correct = getenv ("POSIXLY_CORRECT");
394
395   /* Determine how to handle the ordering of options and nonoptions.  */
396
397   if (optstring[0] == '-')
398   {
399     ordering = RETURN_IN_ORDER;
400     ++optstring;
401   }
402   else if (optstring[0] == '+')
403   {
404     ordering = REQUIRE_ORDER;
405     ++optstring;
406   }
407   else if (posixly_correct != NULL)
408     ordering = REQUIRE_ORDER;
409   else
410     ordering = PERMUTE;
411
412 #ifdef _LIBC
413   if (posixly_correct == NULL && argc == original_argc && argv == original_argv)
414   {
415     if (nonoption_flags_max_len == 0)
416     {
417       if (__getopt_nonoption_flags == NULL ||
418           __getopt_nonoption_flags[0] == '\0')
419         nonoption_flags_max_len = -1;
420       else
421       {
422         const char *orig_str = __getopt_nonoption_flags;
423         int len = nonoption_flags_max_len = strlen (orig_str);
424
425         if (nonoption_flags_max_len < argc)
426           nonoption_flags_max_len = argc;
427         __getopt_nonoption_flags = (char *) malloc (nonoption_flags_max_len);
428         if (__getopt_nonoption_flags == NULL)
429           nonoption_flags_max_len = -1;
430         else
431         {
432           memcpy (__getopt_nonoption_flags, orig_str, len);
433           memset (&__getopt_nonoption_flags[len], '\0',
434                   nonoption_flags_max_len - len);
435         }
436       }
437     }
438     nonoption_flags_len = nonoption_flags_max_len;
439   }
440   else
441     nonoption_flags_len = 0;
442 #endif
443
444   return optstring;
445 }
446 \f
447 /* Scan elements of ARGV (whose length is ARGC) for option characters
448    given in OPTSTRING.
449
450    If an element of ARGV starts with '-', and is not exactly "-" or "--",
451    then it is an option element.  The characters of this element
452    (aside from the initial '-') are option characters.  If `getopt'
453    is called repeatedly, it returns successively each of the option characters
454    from each of the option elements.
455
456    If `getopt' finds another option character, it returns that character,
457    updating `GNoptind' and `nextchar' so that the next call to `getopt' can
458    resume the scan with the following option character or ARGV-element.
459
460    If there are no more option characters, `getopt' returns -1.
461    Then `GNoptind' is the index in ARGV of the first ARGV-element
462    that is not an option.  (The ARGV-elements have been permuted
463    so that those that are not options now come last.)
464
465    OPTSTRING is a string containing the legitimate option characters.
466    If an option character is seen that is not listed in OPTSTRING,
467    return '?' after printing an error message.  If you set `GNopterr' to
468    zero, the error message is suppressed but we still return '?'.
469
470    If a char in OPTSTRING is followed by a colon, that means it wants an arg,
471    so the following text in the same ARGV-element, or the text of the following
472    ARGV-element, is returned in `GNoptarg'.  Two colons mean an option that
473    wants an optional arg; if there is text in the current ARGV-element,
474    it is returned in `GNoptarg', otherwise `GNoptarg' is set to zero.
475
476    If OPTSTRING starts with `-' or `+', it requests different methods of
477    handling the non-option ARGV-elements.
478    See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
479
480    Long-named options begin with `--' instead of `-'.
481    Their names may be abbreviated as long as the abbreviation is unique
482    or is an exact match for some defined option.  If they have an
483    argument, it follows the option name in the same ARGV-element, separated
484    from the option name by a `=', or else the in next ARGV-element.
485    When `getopt' finds a long-named option, it returns 0 if that option's
486    `flag' field is nonzero, the value of the option's `val' field
487    if the `flag' field is zero.
488
489    The elements of ARGV aren't really const, because we GNUNET_CRYPTO_random_permute them.
490    But we pretend they're const in the prototype to be compatible
491    with other systems.
492
493    LONGOPTS is a vector of `struct GNoption' terminated by an
494    element containing a name which is zero.
495
496    LONGIND returns the index in LONGOPT of the long-named option found.
497    It is only valid when a long-named option has been found by the most
498    recent call.
499
500    If LONG_ONLY is nonzero, '-' as well as '--' can introduce
501    long-named options.  */
502
503 static int
504 GN_getopt_internal (int argc, char *const *argv, const char *optstring,
505                     const struct GNoption *longopts, int *longind,
506                     int long_only)
507 {
508   static int __getopt_initialized = 0;
509   static int GNopterr = 1;
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 =
606         (argv[GNoptind] + 1 + (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] || !my_index (optstring, argv[GNoptind][1])))))
628   {
629     char *nameend;
630     const struct GNoption *p;
631     const struct GNoption *pfound = NULL;
632     int exact = 0;
633     int ambig = 0;
634     int indfound = -1;
635     int option_index;
636
637     for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
638       /* Do nothing.  */ ;
639
640     /* Test all long options for either exact match
641      * or abbreviated matches.  */
642     for (p = longopts, option_index = 0; p->name; p++, option_index++)
643       if (!strncmp (p->name, nextchar, nameend - nextchar))
644       {
645         if ((unsigned int) (nameend - nextchar) ==
646             (unsigned int) strlen (p->name))
647         {
648           /* Exact match found.  */
649           pfound = p;
650           indfound = option_index;
651           exact = 1;
652           break;
653         }
654         else if (pfound == NULL)
655         {
656           /* First nonexact match found.  */
657           pfound = p;
658           indfound = option_index;
659         }
660         else
661           /* Second or later nonexact match found.  */
662           ambig = 1;
663       }
664
665     if (ambig && !exact)
666     {
667       if (GNopterr)
668         fprintf (stderr, _("%s: option `%s' is ambiguous\n"), argv[0],
669                  argv[GNoptind]);
670       nextchar += strlen (nextchar);
671       GNoptind++;
672       return '?';
673     }
674
675     if (pfound != NULL)
676     {
677       option_index = indfound;
678       GNoptind++;
679       if (*nameend)
680       {
681         /* Don't test has_arg with >, because some C compilers don't
682          * allow it to be used on enums.  */
683         if (pfound->has_arg)
684           GNoptarg = nameend + 1;
685         else
686         {
687           if (GNopterr)
688           {
689             if (argv[GNoptind - 1][1] == '-')
690               /* --option */
691               fprintf (stderr,
692                        _("%s: option `--%s' does not allow an argument\n"),
693                        argv[0], pfound->name);
694             else
695               /* +option or -option */
696               fprintf (stderr,
697                        _("%s: option `%c%s' does not allow an argument\n"),
698                        argv[0], argv[GNoptind - 1][0], pfound->name);
699           }
700           nextchar += strlen (nextchar);
701           return '?';
702         }
703       }
704       else if (pfound->has_arg == 1)
705       {
706         if (GNoptind < argc)
707         {
708           GNoptarg = argv[GNoptind++];
709         }
710         else
711         {
712           if (GNopterr)
713           {
714             fprintf (stderr, _("%s: option `%s' requires an argument\n"),
715                      argv[0], argv[GNoptind - 1]);
716           }
717           nextchar += strlen (nextchar);
718           return (optstring[0] == ':') ? ':' : '?';
719         }
720       }
721       nextchar += strlen (nextchar);
722       if (longind != NULL)
723         *longind = option_index;
724       if (pfound->flag)
725       {
726         *(pfound->flag) = pfound->val;
727         return 0;
728       }
729       return pfound->val;
730     }
731
732     /* Can't find it as a long option.  If this is not getopt_long_only,
733      * or the option starts with '--' or is not a valid short
734      * option, then it's an error.
735      * Otherwise interpret it as a short option.  */
736     if (!long_only || argv[GNoptind][1] == '-' ||
737         my_index (optstring, *nextchar) == NULL)
738     {
739       if (GNopterr)
740       {
741         if (argv[GNoptind][1] == '-')
742           /* --option */
743           fprintf (stderr, _("%s: unrecognized option `--%s'\n"), argv[0],
744                    nextchar);
745         else
746           /* +option or -option */
747           fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), argv[0],
748                    argv[GNoptind][0], nextchar);
749       }
750       nextchar = (char *) "";
751       GNoptind++;
752       return '?';
753     }
754   }
755
756   /* Look at and handle the next short option-character.  */
757
758   {
759     char c = *nextchar++;
760     char *temp = my_index (optstring, c);
761
762     /* Increment `GNoptind' when we start to process its last character.  */
763     if (*nextchar == '\0')
764       ++GNoptind;
765
766     if (temp == NULL || c == ':')
767     {
768       if (GNopterr)
769       {
770         if (posixly_correct)
771           /* 1003.2 specifies the format of this message.  */
772           fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c);
773         else
774           fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c);
775       }
776       return '?';
777     }
778     /* Convenience. Treat POSIX -W foo same as long option --foo */
779     if (temp[0] == 'W' && temp[1] == ';')
780     {
781       char *nameend;
782       const struct GNoption *p;
783       const struct GNoption *pfound = NULL;
784       int exact = 0;
785       int ambig = 0;
786       int indfound = 0;
787       int option_index;
788
789       /* This is an option that requires an argument.  */
790       if (*nextchar != '\0')
791       {
792         GNoptarg = nextchar;
793         /* If we end this ARGV-element by taking the rest as an arg,
794          * we must advance to the next element now.  */
795         GNoptind++;
796       }
797       else if (GNoptind == argc)
798       {
799         if (GNopterr)
800         {
801           /* 1003.2 specifies the format of this message.  */
802           fprintf (stderr, _("%s: option requires an argument -- %c\n"),
803                    argv[0], c);
804         }
805         if (optstring[0] == ':')
806           c = ':';
807         else
808           c = '?';
809         return c;
810       }
811       else
812         /* We already incremented `GNoptind' once;
813          * increment it again when taking next ARGV-elt as argument.  */
814         GNoptarg = argv[GNoptind++];
815
816       /* GNoptarg is now the argument, see if it's in the
817        * table of longopts.  */
818
819       for (nextchar = nameend = GNoptarg; *nameend && *nameend != '=';
820            nameend++)
821         /* Do nothing.  */ ;
822
823       /* Test all long options for either exact match
824        * or abbreviated matches.  */
825       if (longopts != NULL)
826         for (p = longopts, option_index = 0; p->name; p++, option_index++)
827           if (!strncmp (p->name, nextchar, nameend - nextchar))
828           {
829             if ((unsigned int) (nameend - nextchar) == strlen (p->name))
830             {
831               /* Exact match found.  */
832               pfound = p;
833               indfound = option_index;
834               exact = 1;
835               break;
836             }
837             else if (pfound == NULL)
838             {
839               /* First nonexact match found.  */
840               pfound = p;
841               indfound = option_index;
842             }
843             else
844               /* Second or later nonexact match found.  */
845               ambig = 1;
846           }
847       if (ambig && !exact)
848       {
849         if (GNopterr)
850           fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), argv[0],
851                    argv[GNoptind]);
852         nextchar += strlen (nextchar);
853         GNoptind++;
854         return '?';
855       }
856       if (pfound != NULL)
857       {
858         option_index = indfound;
859         if (*nameend)
860         {
861           /* Don't test has_arg with >, because some C compilers don't
862            * allow it to be used on enums.  */
863           if (pfound->has_arg)
864             GNoptarg = nameend + 1;
865           else
866           {
867             if (GNopterr)
868               fprintf (stderr, _("\
869 %s: option `-W %s' does not allow an argument\n"), argv[0], pfound->name);
870
871             nextchar += strlen (nextchar);
872             return '?';
873           }
874         }
875         else if (pfound->has_arg == 1)
876         {
877           if (GNoptind < argc)
878             GNoptarg = argv[GNoptind++];
879           else
880           {
881             if (GNopterr)
882               fprintf (stderr, _("%s: option `%s' requires an argument\n"),
883                        argv[0], argv[GNoptind - 1]);
884             nextchar += strlen (nextchar);
885             return optstring[0] == ':' ? ':' : '?';
886           }
887         }
888         nextchar += strlen (nextchar);
889         if (longind != NULL)
890           *longind = option_index;
891         if (pfound->flag)
892         {
893           *(pfound->flag) = pfound->val;
894           return 0;
895         }
896         return pfound->val;
897       }
898       nextchar = NULL;
899       return 'W';               /* Let the application handle it.   */
900     }
901     if (temp[1] == ':')
902     {
903       if (temp[2] == ':')
904       {
905         /* This is an option that accepts an argument optionally.  */
906         if (*nextchar != '\0')
907         {
908           GNoptarg = nextchar;
909           GNoptind++;
910         }
911         else
912           GNoptarg = NULL;
913         nextchar = NULL;
914       }
915       else
916       {
917         /* This is an option that requires an argument.  */
918         if (*nextchar != '\0')
919         {
920           GNoptarg = nextchar;
921           /* If we end this ARGV-element by taking the rest as an arg,
922            * we must advance to the next element now.  */
923           GNoptind++;
924         }
925         else if (GNoptind == argc)
926         {
927           if (GNopterr)
928           {
929             /* 1003.2 specifies the format of this message.  */
930             fprintf (stderr, _("%s: option requires an argument -- %c\n"),
931                      argv[0], c);
932           }
933           if (optstring[0] == ':')
934             c = ':';
935           else
936             c = '?';
937         }
938         else
939           /* We already incremented `GNoptind' once;
940            * increment it again when taking next ARGV-elt as argument.  */
941           GNoptarg = argv[GNoptind++];
942         nextchar = NULL;
943       }
944     }
945     return c;
946   }
947 }
948
949 static int
950 GNgetopt_long (int argc, char *const *argv, const char *options,
951                const struct GNoption *long_options, int *opt_index)
952 {
953   return GN_getopt_internal (argc, argv, options, long_options, opt_index, 0);
954 }
955
956 /* ******************** now the GNUnet specific modifications... ********************* */
957
958 /**
959  * Parse the command line.
960  *
961  * @param binaryOptions Name of application with option summary
962  * @param allOptions defined options and handlers
963  * @param argc number of arguments
964  * @param argv actual arguments
965  * @return index into argv with first non-option
966  *   argument, or -1 on error
967  */
968 int
969 GNUNET_GETOPT_run (const char *binaryOptions,
970                    const struct GNUNET_GETOPT_CommandLineOption *allOptions,
971                    unsigned int argc, char *const *argv)
972 {
973   struct GNoption *long_options;
974   struct GNUNET_GETOPT_CommandLineProcessorContext clpc;
975   int count;
976   int i;
977   char *shorts;
978   int spos;
979   int cont;
980   int c;
981
982   GNUNET_assert (argc > 0);
983   GNoptind = 0;
984   clpc.binaryName = argv[0];
985   clpc.binaryOptions = binaryOptions;
986   clpc.allOptions = allOptions;
987   clpc.argv = argv;
988   clpc.argc = argc;
989   count = 0;
990   while (allOptions[count].name != NULL)
991     count++;
992   long_options = GNUNET_malloc (sizeof (struct GNoption) * (count + 1));
993   shorts = GNUNET_malloc (count * 2 + 1);
994   spos = 0;
995   for (i = 0; i < count; i++)
996   {
997     long_options[i].name = allOptions[i].name;
998     long_options[i].has_arg = allOptions[i].require_argument;
999     long_options[i].flag = NULL;
1000     long_options[i].val = allOptions[i].shortName;
1001     shorts[spos++] = allOptions[i].shortName;
1002     if (allOptions[i].require_argument != 0)
1003       shorts[spos++] = ':';
1004   }
1005   long_options[count].name = NULL;
1006   long_options[count].has_arg = 0;
1007   long_options[count].flag = NULL;
1008   long_options[count].val = '\0';
1009   shorts[spos] = '\0';
1010   cont = GNUNET_OK;
1011   /* main getopt loop */
1012   while (cont == GNUNET_OK)
1013   {
1014     int option_index = 0;
1015
1016     c = GNgetopt_long (argc, argv, shorts, long_options, &option_index);
1017
1018     if (c == GNUNET_SYSERR)
1019       break;                    /* No more flags to process */
1020
1021     for (i = 0; i < count; i++)
1022     {
1023       clpc.currentArgument = GNoptind - 1;
1024       if ((char) c == allOptions[i].shortName)
1025       {
1026         cont =
1027             allOptions[i].processor (&clpc, allOptions[i].scls,
1028                                      allOptions[i].name, GNoptarg);
1029         break;
1030       }
1031     }
1032     if (i == count)
1033     {
1034       fprintf (stderr, _("Use --help to get a list of options.\n"));
1035       cont = GNUNET_SYSERR;
1036     }
1037   }
1038
1039   GNUNET_free (shorts);
1040   GNUNET_free (long_options);
1041   if (cont == GNUNET_SYSERR)
1042     return GNUNET_SYSERR;
1043   return GNoptind;
1044 }
1045
1046 /* end of getopt.c */