~ubuntu-branches/debian/lenny/octave3.0/lenny

« back to all changes in this revision

Viewing changes to liboctave/getopt.c

  • Committer: Bazaar Package Importer
  • Author(s): Rafael Laboissiere
  • Date: 2007-12-23 16:04:15 UTC
  • Revision ID: james.westby@ubuntu.com-20071223160415-n4gk468dihy22e9v
Tags: upstream-3.0.0
ImportĀ upstreamĀ versionĀ 3.0.0

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