OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [linux/] [uClibc/] [libc/] [unistd/] [getopt.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.