~ubuntu-branches/ubuntu/maverick/bc/maverick

« back to all changes in this revision

Viewing changes to lib/getopt.c

  • Committer: Bazaar Package Importer
  • Author(s): Dirk Eddelbuettel
  • Date: 2002-04-13 11:33:49 UTC
  • Revision ID: james.westby@ubuntu.com-20020413113349-hl2r1t730b91ov68
Tags: upstream-1.06
ImportĀ upstreamĀ versionĀ 1.06

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