Subversion Repositories Kolibri OS

Rev

Rev 6660 | Go to most recent revision | Details | Last modification | View Log | RSS feed

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