~ubuntu-branches/ubuntu/maverick/hello/maverick

« back to all changes in this revision

Viewing changes to getopt.c

  • Committer: Bazaar Package Importer
  • Author(s): Santiago Vila
  • Date: 2004-01-05 16:42:30 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20040105164230-ze0yqbimyx4sx1gs
Tags: 2.1.1-4
Updated config.guess and config.sub for GNU/K*BSD.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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, 1993
7
 
        Free Software Foundation, Inc.
8
 
 
9
 
   This program is free software; you can redistribute it and/or modify it
10
 
   under the terms of the GNU General Public License as published by the
11
 
   Free Software Foundation; either version 2, or (at your option) any
12
 
   later version.
13
 
 
14
 
   This program is distributed in the hope that it will be useful,
15
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 
   GNU General Public License for more details.
18
 
 
19
 
   You should have received a copy of the GNU General Public License
20
 
   along with this program; if not, write to the Free Software
21
 
   Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
22
 
 
23
 
/* NOTE!!!  AIX requires this to be the first thing in the file.
24
 
   Do not put ANYTHING before it!  */
25
 
#if !defined (__GNUC__) && defined (_AIX)
26
 
 #pragma alloca
27
 
#endif
28
 
 
29
 
#ifdef HAVE_CONFIG_H
30
 
#include "config.h"
31
 
#endif
32
 
 
33
 
#ifdef __GNUC__
34
 
#define alloca __builtin_alloca
35
 
#else /* not __GNUC__ */
36
 
#if defined (HAVE_ALLOCA_H) || (defined(sparc) && (defined(sun) || (!defined(USG) && !defined(SVR4) && !defined(__svr4__))))
37
 
#include <alloca.h>
38
 
#else
39
 
#ifndef _AIX
40
 
char *alloca ();
41
 
#endif
42
 
#endif /* alloca.h */
43
 
#endif /* not __GNUC__ */
44
 
 
45
 
#if !__STDC__ && !defined(const) && IN_GCC
46
 
#define const
47
 
#endif
48
 
 
49
 
/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.  */
50
 
#ifndef _NO_PROTO
51
 
#define _NO_PROTO
52
 
#endif
53
 
 
54
 
#include <stdio.h>
55
 
 
56
 
/* Comment out all this code if we are using the GNU C Library, and are not
57
 
   actually compiling the library itself.  This code is part of the GNU C
58
 
   Library, but also included in many other GNU distributions.  Compiling
59
 
   and linking in this code is a waste when using the GNU C library
60
 
   (especially if it is a shared library).  Rather than having every GNU
61
 
   program understand `configure --with-gnu-libc' and omit the object files,
62
 
   it is simpler to just do this in the source for each such file.  */
63
 
 
64
 
#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
65
 
 
66
 
 
67
 
/* This needs to come after some library #include
68
 
   to get __GNU_LIBRARY__ defined.  */
69
 
#ifdef  __GNU_LIBRARY__
70
 
#undef  alloca
71
 
/* Don't include stdlib.h for non-GNU C libraries because some of them
72
 
   contain conflicting prototypes for getopt.  */
73
 
#include <stdlib.h>
74
 
#else   /* Not GNU C library.  */
75
 
#define __alloca        alloca
76
 
#endif  /* GNU C library.  */
77
 
 
78
 
/* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a
79
 
   long-named option.  Because this is not POSIX.2 compliant, it is
80
 
   being phased out.  */
81
 
/* #define GETOPT_COMPAT */
82
 
 
83
 
/* This version of `getopt' appears to the caller like standard Unix `getopt'
84
 
   but it behaves differently for the user, since it allows the user
85
 
   to intersperse the options with the other arguments.
86
 
 
87
 
   As `getopt' works, it permutes the elements of ARGV so that,
88
 
   when it is done, all the options precede everything else.  Thus
89
 
   all application programs are extended to handle flexible argument order.
90
 
 
91
 
   Setting the environment variable POSIXLY_CORRECT disables permutation.
92
 
   Then the behavior is completely standard.
93
 
 
94
 
   GNU application programs can use a third alternative mode in which
95
 
   they can distinguish the relative order of options and other arguments.  */
96
 
 
97
 
#include "getopt.h"
98
 
 
99
 
/* For communication from `getopt' to the caller.
100
 
   When `getopt' finds an option that takes an argument,
101
 
   the argument value is returned here.
102
 
   Also, when `ordering' is RETURN_IN_ORDER,
103
 
   each non-option ARGV-element is returned here.  */
104
 
 
105
 
char *optarg = 0;
106
 
 
107
 
/* Index in ARGV of the next element to be scanned.
108
 
   This is used for communication to and from the caller
109
 
   and for communication between successive calls to `getopt'.
110
 
 
111
 
   On entry to `getopt', zero means this is the first call; initialize.
112
 
 
113
 
   When `getopt' returns EOF, this is the index of the first of the
114
 
   non-option elements that the caller should itself scan.
115
 
 
116
 
   Otherwise, `optind' communicates from one call to the next
117
 
   how much of ARGV has been scanned so far.  */
118
 
 
119
 
/* XXX 1003.2 says this must be 1 before any call.  */
120
 
int optind = 0;
121
 
 
122
 
/* The next char to be scanned in the option-element
123
 
   in which the last option character we returned was found.
124
 
   This allows us to pick up the scan where we left off.
125
 
 
126
 
   If this is zero, or a null string, it means resume the scan
127
 
   by advancing to the next ARGV-element.  */
128
 
 
129
 
static char *nextchar;
130
 
 
131
 
/* Callers store zero here to inhibit the error message
132
 
   for unrecognized options.  */
133
 
 
134
 
int opterr = 1;
135
 
 
136
 
/* Set to an option character which was unrecognized.
137
 
   This must be initialized on some systems to avoid linking in the
138
 
   system's own getopt implementation.  */
139
 
 
140
 
int optopt = '?';
141
 
 
142
 
/* Describe how to deal with options that follow non-option ARGV-elements.
143
 
 
144
 
   If the caller did not specify anything,
145
 
   the default is REQUIRE_ORDER if the environment variable
146
 
   POSIXLY_CORRECT is defined, PERMUTE otherwise.
147
 
 
148
 
   REQUIRE_ORDER means don't recognize them as options;
149
 
   stop option processing when the first non-option is seen.
150
 
   This is what Unix does.
151
 
   This mode of operation is selected by either setting the environment
152
 
   variable POSIXLY_CORRECT, or using `+' as the first character
153
 
   of the list of option characters.
154
 
 
155
 
   PERMUTE is the default.  We permute the contents of ARGV as we scan,
156
 
   so that eventually all the non-options are at the end.  This allows options
157
 
   to be given in any order, even with programs that were not written to
158
 
   expect this.
159
 
 
160
 
   RETURN_IN_ORDER is an option available to programs that were written
161
 
   to expect options and other ARGV-elements in any order and that care about
162
 
   the ordering of the two.  We describe each non-option ARGV-element
163
 
   as if it were the argument of an option with character code 1.
164
 
   Using `-' as the first character of the list of option characters
165
 
   selects this mode of operation.
166
 
 
167
 
   The special argument `--' forces an end of option-scanning regardless
168
 
   of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
169
 
   `--' can cause `getopt' to return EOF with `optind' != ARGC.  */
170
 
 
171
 
static enum
172
 
{
173
 
  REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
174
 
} ordering;
175
 
 
176
 
#ifdef  __GNU_LIBRARY__
177
 
/* We want to avoid inclusion of string.h with non-GNU libraries
178
 
   because there are many ways it can cause trouble.
179
 
   On some systems, it contains special magic macros that don't work
180
 
   in GCC.  */
181
 
#include <string.h>
182
 
#define my_index        strchr
183
 
#define my_bcopy(src, dst, n)   memcpy ((dst), (src), (n))
184
 
#else
185
 
 
186
 
/* Avoid depending on library functions or files
187
 
   whose names are inconsistent.  */
188
 
 
189
 
char *getenv ();
190
 
 
191
 
static char *
192
 
my_index (str, chr)
193
 
     const char *str;
194
 
     int chr;
195
 
{
196
 
  while (*str)
197
 
    {
198
 
      if (*str == chr)
199
 
        return (char *) str;
200
 
      str++;
201
 
    }
202
 
  return 0;
203
 
}
204
 
 
205
 
static void
206
 
my_bcopy (from, to, size)
207
 
     const char *from;
208
 
     char *to;
209
 
     int size;
210
 
{
211
 
  int i;
212
 
  for (i = 0; i < size; i++)
213
 
    to[i] = from[i];
214
 
}
215
 
#endif                          /* GNU C library.  */
216
 
 
217
 
/* Handle permutation of arguments.  */
218
 
 
219
 
/* Describe the part of ARGV that contains non-options that have
220
 
   been skipped.  `first_nonopt' is the index in ARGV of the first of them;
221
 
   `last_nonopt' is the index after the last of them.  */
222
 
 
223
 
static int first_nonopt;
224
 
static int last_nonopt;
225
 
 
226
 
/* Exchange two adjacent subsequences of ARGV.
227
 
   One subsequence is elements [first_nonopt,last_nonopt)
228
 
   which contains all the non-options that have been skipped so far.
229
 
   The other is elements [last_nonopt,optind), which contains all
230
 
   the options processed since those non-options were skipped.
231
 
 
232
 
   `first_nonopt' and `last_nonopt' are relocated so that they describe
233
 
   the new indices of the non-options in ARGV after they are moved.  */
234
 
 
235
 
static void
236
 
exchange (argv)
237
 
     char **argv;
238
 
{
239
 
  int nonopts_size = (last_nonopt - first_nonopt) * sizeof (char *);
240
 
  char **temp = (char **) __alloca (nonopts_size);
241
 
 
242
 
  /* Interchange the two blocks of data in ARGV.  */
243
 
 
244
 
  my_bcopy ((char *) &argv[first_nonopt], (char *) temp, nonopts_size);
245
 
  my_bcopy ((char *) &argv[last_nonopt], (char *) &argv[first_nonopt],
246
 
            (optind - last_nonopt) * sizeof (char *));
247
 
  my_bcopy ((char *) temp,
248
 
            (char *) &argv[first_nonopt + optind - last_nonopt],
249
 
            nonopts_size);
250
 
 
251
 
  /* Update records for the slots the non-options now occupy.  */
252
 
 
253
 
  first_nonopt += (optind - last_nonopt);
254
 
  last_nonopt = optind;
255
 
}
256
 
 
257
 
/* Scan elements of ARGV (whose length is ARGC) for option characters
258
 
   given in OPTSTRING.
259
 
 
260
 
   If an element of ARGV starts with '-', and is not exactly "-" or "--",
261
 
   then it is an option element.  The characters of this element
262
 
   (aside from the initial '-') are option characters.  If `getopt'
263
 
   is called repeatedly, it returns successively each of the option characters
264
 
   from each of the option elements.
265
 
 
266
 
   If `getopt' finds another option character, it returns that character,
267
 
   updating `optind' and `nextchar' so that the next call to `getopt' can
268
 
   resume the scan with the following option character or ARGV-element.
269
 
 
270
 
   If there are no more option characters, `getopt' returns `EOF'.
271
 
   Then `optind' is the index in ARGV of the first ARGV-element
272
 
   that is not an option.  (The ARGV-elements have been permuted
273
 
   so that those that are not options now come last.)
274
 
 
275
 
   OPTSTRING is a string containing the legitimate option characters.
276
 
   If an option character is seen that is not listed in OPTSTRING,
277
 
   return '?' after printing an error message.  If you set `opterr' to
278
 
   zero, the error message is suppressed but we still return '?'.
279
 
 
280
 
   If a char in OPTSTRING is followed by a colon, that means it wants an arg,
281
 
   so the following text in the same ARGV-element, or the text of the following
282
 
   ARGV-element, is returned in `optarg'.  Two colons mean an option that
283
 
   wants an optional arg; if there is text in the current ARGV-element,
284
 
   it is returned in `optarg', otherwise `optarg' is set to zero.
285
 
 
286
 
   If OPTSTRING starts with `-' or `+', it requests different methods of
287
 
   handling the non-option ARGV-elements.
288
 
   See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
289
 
 
290
 
   Long-named options begin with `--' instead of `-'.
291
 
   Their names may be abbreviated as long as the abbreviation is unique
292
 
   or is an exact match for some defined option.  If they have an
293
 
   argument, it follows the option name in the same ARGV-element, separated
294
 
   from the option name by a `=', or else the in next ARGV-element.
295
 
   When `getopt' finds a long-named option, it returns 0 if that option's
296
 
   `flag' field is nonzero, the value of the option's `val' field
297
 
   if the `flag' field is zero.
298
 
 
299
 
   The elements of ARGV aren't really const, because we permute them.
300
 
   But we pretend they're const in the prototype to be compatible
301
 
   with other systems.
302
 
 
303
 
   LONGOPTS is a vector of `struct option' terminated by an
304
 
   element containing a name which is zero.
305
 
 
306
 
   LONGIND returns the index in LONGOPT of the long-named option found.
307
 
   It is only valid when a long-named option has been found by the most
308
 
   recent call.
309
 
 
310
 
   If LONG_ONLY is nonzero, '-' as well as '--' can introduce
311
 
   long-named options.  */
312
 
 
313
 
int
314
 
_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
315
 
     int argc;
316
 
     char *const *argv;
317
 
     const char *optstring;
318
 
     const struct option *longopts;
319
 
     int *longind;
320
 
     int long_only;
321
 
{
322
 
  int option_index;
323
 
 
324
 
  optarg = 0;
325
 
 
326
 
  /* Initialize the internal data when the first call is made.
327
 
     Start processing options with ARGV-element 1 (since ARGV-element 0
328
 
     is the program name); the sequence of previously skipped
329
 
     non-option ARGV-elements is empty.  */
330
 
 
331
 
  if (optind == 0)
332
 
    {
333
 
      first_nonopt = last_nonopt = optind = 1;
334
 
 
335
 
      nextchar = NULL;
336
 
 
337
 
      /* Determine how to handle the ordering of options and nonoptions.  */
338
 
 
339
 
      if (optstring[0] == '-')
340
 
        {
341
 
          ordering = RETURN_IN_ORDER;
342
 
          ++optstring;
343
 
        }
344
 
      else if (optstring[0] == '+')
345
 
        {
346
 
          ordering = REQUIRE_ORDER;
347
 
          ++optstring;
348
 
        }
349
 
      else if (getenv ("POSIXLY_CORRECT") != NULL)
350
 
        ordering = REQUIRE_ORDER;
351
 
      else
352
 
        ordering = PERMUTE;
353
 
    }
354
 
 
355
 
  if (nextchar == NULL || *nextchar == '\0')
356
 
    {
357
 
      if (ordering == PERMUTE)
358
 
        {
359
 
          /* If we have just processed some options following some non-options,
360
 
             exchange them so that the options come first.  */
361
 
 
362
 
          if (first_nonopt != last_nonopt && last_nonopt != optind)
363
 
            exchange ((char **) argv);
364
 
          else if (last_nonopt != optind)
365
 
            first_nonopt = optind;
366
 
 
367
 
          /* Now skip any additional non-options
368
 
             and extend the range of non-options previously skipped.  */
369
 
 
370
 
          while (optind < argc
371
 
                 && (argv[optind][0] != '-' || argv[optind][1] == '\0')
372
 
#ifdef GETOPT_COMPAT
373
 
                 && (longopts == NULL
374
 
                     || argv[optind][0] != '+' || argv[optind][1] == '\0')
375
 
#endif                          /* GETOPT_COMPAT */
376
 
                 )
377
 
            optind++;
378
 
          last_nonopt = optind;
379
 
        }
380
 
 
381
 
      /* Special ARGV-element `--' means premature end of options.
382
 
         Skip it like a null option,
383
 
         then exchange with previous non-options as if it were an option,
384
 
         then skip everything else like a non-option.  */
385
 
 
386
 
      if (optind != argc && !strcmp (argv[optind], "--"))
387
 
        {
388
 
          optind++;
389
 
 
390
 
          if (first_nonopt != last_nonopt && last_nonopt != optind)
391
 
            exchange ((char **) argv);
392
 
          else if (first_nonopt == last_nonopt)
393
 
            first_nonopt = optind;
394
 
          last_nonopt = argc;
395
 
 
396
 
          optind = argc;
397
 
        }
398
 
 
399
 
      /* If we have done all the ARGV-elements, stop the scan
400
 
         and back over any non-options that we skipped and permuted.  */
401
 
 
402
 
      if (optind == argc)
403
 
        {
404
 
          /* Set the next-arg-index to point at the non-options
405
 
             that we previously skipped, so the caller will digest them.  */
406
 
          if (first_nonopt != last_nonopt)
407
 
            optind = first_nonopt;
408
 
          return EOF;
409
 
        }
410
 
 
411
 
      /* If we have come to a non-option and did not permute it,
412
 
         either stop the scan or describe it to the caller and pass it by.  */
413
 
 
414
 
      if ((argv[optind][0] != '-' || argv[optind][1] == '\0')
415
 
#ifdef GETOPT_COMPAT
416
 
          && (longopts == NULL
417
 
              || argv[optind][0] != '+' || argv[optind][1] == '\0')
418
 
#endif                          /* GETOPT_COMPAT */
419
 
          )
420
 
        {
421
 
          if (ordering == REQUIRE_ORDER)
422
 
            return EOF;
423
 
          optarg = argv[optind++];
424
 
          return 1;
425
 
        }
426
 
 
427
 
      /* We have found another option-ARGV-element.
428
 
         Start decoding its characters.  */
429
 
 
430
 
      nextchar = (argv[optind] + 1
431
 
                  + (longopts != NULL && argv[optind][1] == '-'));
432
 
    }
433
 
 
434
 
  if (longopts != NULL
435
 
      && ((argv[optind][0] == '-'
436
 
           && (argv[optind][1] == '-' || long_only))
437
 
#ifdef GETOPT_COMPAT
438
 
          || argv[optind][0] == '+'
439
 
#endif                          /* GETOPT_COMPAT */
440
 
          ))
441
 
    {
442
 
      const struct option *p;
443
 
      char *s = nextchar;
444
 
      int exact = 0;
445
 
      int ambig = 0;
446
 
      const struct option *pfound = NULL;
447
 
      int indfound;
448
 
 
449
 
      while (*s && *s != '=')
450
 
        s++;
451
 
 
452
 
      /* Test all options for either exact match or abbreviated matches.  */
453
 
      for (p = longopts, option_index = 0; p->name;
454
 
           p++, option_index++)
455
 
        if (!strncmp (p->name, nextchar, s - nextchar))
456
 
          {
457
 
            if (s - nextchar == strlen (p->name))
458
 
              {
459
 
                /* Exact match found.  */
460
 
                pfound = p;
461
 
                indfound = option_index;
462
 
                exact = 1;
463
 
                break;
464
 
              }
465
 
            else if (pfound == NULL)
466
 
              {
467
 
                /* First nonexact match found.  */
468
 
                pfound = p;
469
 
                indfound = option_index;
470
 
              }
471
 
            else
472
 
              /* Second nonexact match found.  */
473
 
              ambig = 1;
474
 
          }
475
 
 
476
 
      if (ambig && !exact)
477
 
        {
478
 
          if (opterr)
479
 
            fprintf (stderr, "%s: option `%s' is ambiguous\n",
480
 
                     argv[0], argv[optind]);
481
 
          nextchar += strlen (nextchar);
482
 
          optind++;
483
 
          return '?';
484
 
        }
485
 
 
486
 
      if (pfound != NULL)
487
 
        {
488
 
          option_index = indfound;
489
 
          optind++;
490
 
          if (*s)
491
 
            {
492
 
              /* Don't test has_arg with >, because some C compilers don't
493
 
                 allow it to be used on enums.  */
494
 
              if (pfound->has_arg)
495
 
                optarg = s + 1;
496
 
              else
497
 
                {
498
 
                  if (opterr)
499
 
                    {
500
 
                      if (argv[optind - 1][1] == '-')
501
 
                        /* --option */
502
 
                        fprintf (stderr,
503
 
                                 "%s: option `--%s' doesn't allow an argument\n",
504
 
                                 argv[0], pfound->name);
505
 
                      else
506
 
                        /* +option or -option */
507
 
                        fprintf (stderr,
508
 
                             "%s: option `%c%s' doesn't allow an argument\n",
509
 
                             argv[0], argv[optind - 1][0], pfound->name);
510
 
                    }
511
 
                  nextchar += strlen (nextchar);
512
 
                  return '?';
513
 
                }
514
 
            }
515
 
          else if (pfound->has_arg == 1)
516
 
            {
517
 
              if (optind < argc)
518
 
                optarg = argv[optind++];
519
 
              else
520
 
                {
521
 
                  if (opterr)
522
 
                    fprintf (stderr, "%s: option `%s' requires an argument\n",
523
 
                             argv[0], argv[optind - 1]);
524
 
                  nextchar += strlen (nextchar);
525
 
                  return optstring[0] == ':' ? ':' : '?';
526
 
                }
527
 
            }
528
 
          nextchar += strlen (nextchar);
529
 
          if (longind != NULL)
530
 
            *longind = option_index;
531
 
          if (pfound->flag)
532
 
            {
533
 
              *(pfound->flag) = pfound->val;
534
 
              return 0;
535
 
            }
536
 
          return pfound->val;
537
 
        }
538
 
      /* Can't find it as a long option.  If this is not getopt_long_only,
539
 
         or the option starts with '--' or is not a valid short
540
 
         option, then it's an error.
541
 
         Otherwise interpret it as a short option.  */
542
 
      if (!long_only || argv[optind][1] == '-'
543
 
#ifdef GETOPT_COMPAT
544
 
          || argv[optind][0] == '+'
545
 
#endif                          /* GETOPT_COMPAT */
546
 
          || my_index (optstring, *nextchar) == NULL)
547
 
        {
548
 
          if (opterr)
549
 
            {
550
 
              if (argv[optind][1] == '-')
551
 
                /* --option */
552
 
                fprintf (stderr, "%s: unrecognized option `--%s'\n",
553
 
                         argv[0], nextchar);
554
 
              else
555
 
                /* +option or -option */
556
 
                fprintf (stderr, "%s: unrecognized option `%c%s'\n",
557
 
                         argv[0], argv[optind][0], nextchar);
558
 
            }
559
 
          nextchar = (char *) "";
560
 
          optind++;
561
 
          return '?';
562
 
        }
563
 
    }
564
 
 
565
 
  /* Look at and handle the next option-character.  */
566
 
 
567
 
  {
568
 
    char c = *nextchar++;
569
 
    char *temp = my_index (optstring, c);
570
 
 
571
 
    /* Increment `optind' when we start to process its last character.  */
572
 
    if (*nextchar == '\0')
573
 
      ++optind;
574
 
 
575
 
    if (temp == NULL || c == ':')
576
 
      {
577
 
        if (opterr)
578
 
          {
579
 
#if 0
580
 
            if (c < 040 || c >= 0177)
581
 
              fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
582
 
                       argv[0], c);
583
 
            else
584
 
              fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c);
585
 
#else
586
 
            /* 1003.2 specifies the format of this message.  */
587
 
            fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
588
 
#endif
589
 
          }
590
 
        optopt = c;
591
 
        return '?';
592
 
      }
593
 
    if (temp[1] == ':')
594
 
      {
595
 
        if (temp[2] == ':')
596
 
          {
597
 
            /* This is an option that accepts an argument optionally.  */
598
 
            if (*nextchar != '\0')
599
 
              {
600
 
                optarg = nextchar;
601
 
                optind++;
602
 
              }
603
 
            else
604
 
              optarg = 0;
605
 
            nextchar = NULL;
606
 
          }
607
 
        else
608
 
          {
609
 
            /* This is an option that requires an argument.  */
610
 
            if (*nextchar != '\0')
611
 
              {
612
 
                optarg = nextchar;
613
 
                /* If we end this ARGV-element by taking the rest as an arg,
614
 
                   we must advance to the next element now.  */
615
 
                optind++;
616
 
              }
617
 
            else if (optind == argc)
618
 
              {
619
 
                if (opterr)
620
 
                  {
621
 
#if 0
622
 
                    fprintf (stderr, "%s: option `-%c' requires an argument\n",
623
 
                             argv[0], c);
624
 
#else
625
 
                    /* 1003.2 specifies the format of this message.  */
626
 
                    fprintf (stderr, "%s: option requires an argument -- %c\n",
627
 
                             argv[0], c);
628
 
#endif
629
 
                  }
630
 
                optopt = c;
631
 
                if (optstring[0] == ':')
632
 
                  c = ':';
633
 
                else
634
 
                  c = '?';
635
 
              }
636
 
            else
637
 
              /* We already incremented `optind' once;
638
 
                 increment it again when taking next ARGV-elt as argument.  */
639
 
              optarg = argv[optind++];
640
 
            nextchar = NULL;
641
 
          }
642
 
      }
643
 
    return c;
644
 
  }
645
 
}
646
 
 
647
 
int
648
 
getopt (argc, argv, optstring)
649
 
     int argc;
650
 
     char *const *argv;
651
 
     const char *optstring;
652
 
{
653
 
  return _getopt_internal (argc, argv, optstring,
654
 
                           (const struct option *) 0,
655
 
                           (int *) 0,
656
 
                           0);
657
 
}
658
 
 
659
 
#endif  /* _LIBC or not __GNU_LIBRARY__.  */
660
 
 
661
 
#ifdef TEST
662
 
 
663
 
/* Compile with -DTEST to make an executable for use in testing
664
 
   the above definition of `getopt'.  */
665
 
 
666
 
int
667
 
main (argc, argv)
668
 
     int argc;
669
 
     char **argv;
670
 
{
671
 
  int c;
672
 
  int digit_optind = 0;
673
 
 
674
 
  while (1)
675
 
    {
676
 
      int this_option_optind = optind ? optind : 1;
677
 
 
678
 
      c = getopt (argc, argv, "abc:d:0123456789");
679
 
      if (c == EOF)
680
 
        break;
681
 
 
682
 
      switch (c)
683
 
        {
684
 
        case '0':
685
 
        case '1':
686
 
        case '2':
687
 
        case '3':
688
 
        case '4':
689
 
        case '5':
690
 
        case '6':
691
 
        case '7':
692
 
        case '8':
693
 
        case '9':
694
 
          if (digit_optind != 0 && digit_optind != this_option_optind)
695
 
            printf ("digits occur in two different argv-elements.\n");
696
 
          digit_optind = this_option_optind;
697
 
          printf ("option %c\n", c);
698
 
          break;
699
 
 
700
 
        case 'a':
701
 
          printf ("option a\n");
702
 
          break;
703
 
 
704
 
        case 'b':
705
 
          printf ("option b\n");
706
 
          break;
707
 
 
708
 
        case 'c':
709
 
          printf ("option c with value `%s'\n", optarg);
710
 
          break;
711
 
 
712
 
        case '?':
713
 
          break;
714
 
 
715
 
        default:
716
 
          printf ("?? getopt returned character code 0%o ??\n", c);
717
 
        }
718
 
    }
719
 
 
720
 
  if (optind < argc)
721
 
    {
722
 
      printf ("non-option ARGV-elements: ");
723
 
      while (optind < argc)
724
 
        printf ("%s ", argv[optind++]);
725
 
      printf ("\n");
726
 
    }
727
 
 
728
 
  exit (0);
729
 
}
730
 
 
731
 
#endif /* TEST */