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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [or1ksim/] [argtable2/] [getopt.c] - Blame information for rev 351

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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