~ubuntu-branches/ubuntu/oneiric/jabberd2/oneiric-security

« back to all changes in this revision

Viewing changes to subst/getopt.c

  • Committer: Bazaar Package Importer
  • Author(s): Nicolai Spohrer
  • Date: 2008-08-12 16:13:43 UTC
  • mfrom: (1.1.3 upstream) (0.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20080812161343-6trz3r97dtevxd17
Tags: 2.2.1-1ubuntu1
* Merge with Debian unstable (LP: #257130), remaining changes:
  - debian/control:
    + Modify Maintainer field as per spec
    + Depend on libdb4.6-dev instead of libdb4.4-dev
    + Added Conflicts and Replaces: ..., jabber for jabberd2
  - debian/rules: Added libtoolize call (jabberd2 ships with
     an older ltmain.sh version that conflicts with the
     current libtool version)
  - debian/init: create /var/run/jabber directory with correct
     permissions
* Dropped changes:
  - Debian already depends on libpq-dev

Show diffs side-by-side

added added

removed removed

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