Copyright (C) 1987, 1989 Free Software Foundation, Inc.
(Modified by Douglas C. Schmidt for use with GNU G++.)
This file is part of the GNU C++ Library. This library is free
software; you can redistribute it and/or modify it under the terms of
the GNU Library General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version. This library is distributed in the hope
that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
/* AIX requires the alloca decl to be the first thing in the file. */
#define alloca __builtin_alloca
extern "C" void *__builtin_alloca(...);
char* GetOpt::nextchar
= 0;
int GetOpt::first_nonopt
= 0;
int GetOpt::last_nonopt
= 0;
GetOpt::GetOpt (int argc
, char **argv
, const char *optstring
)
:opterr (1), nargc (argc
), nargv (argv
), noptstring (optstring
)
/* Initialize the internal data when the first call is made.
Start processing options with ARGV-element 1 (since ARGV-element 0
is the program name); the sequence of previously skipped
non-option ARGV-elements is empty. */
first_nonopt
= last_nonopt
= optind
= 1;
/* Determine how to handle the ordering of options and nonoptions. */
ordering
= RETURN_IN_ORDER
;
else if (getenv ("_POSIX_OPTION_ORDER") != 0)
ordering
= REQUIRE_ORDER
;
GetOpt::exchange (char **argv
)
= (last_nonopt
- first_nonopt
) * sizeof (char *);
char **temp
= (char **) alloca (nonopts_size
);
/* Interchange the two blocks of data in argv. */
memcpy (temp
, &argv
[first_nonopt
], nonopts_size
);
memcpy (&argv
[first_nonopt
], &argv
[last_nonopt
],
(optind
- last_nonopt
) * sizeof (char *));
memcpy (&argv
[first_nonopt
+ optind
- last_nonopt
], temp
,
/* Update records for the slots the non-options now occupy. */
first_nonopt
+= (optind
- last_nonopt
);
/* Scan elements of ARGV (whose length is ARGC) for option characters
If an element of ARGV starts with '-', and is not exactly "-" or "--",
then it is an option element. The characters of this element
(aside from the initial '-') are option characters. If `getopt'
is called repeatedly, it returns successively each of theoption characters
from each of the option elements.
If `getopt' finds another option character, it returns that character,
updating `optind' and `nextchar' so that the next call to `getopt' can
resume the scan with the following option character or ARGV-element.
If there are no more option characters, `getopt' returns `EOF'.
Then `optind' is the index in ARGV of the first ARGV-element
that is not an option. (The ARGV-elements have been permuted
so that those that are not options now come last.)
OPTSTRING is a string containing the legitimate option characters.
A colon in OPTSTRING means that the previous character is an option
that wants an argument. The argument is taken from the rest of the
current ARGV-element, or from the following ARGV-element,
and returned in `optarg'.
If an option character is seen that is not listed in OPTSTRING,
return '?' after printing an error message. If you set `opterr' to
zero, the error message is suppressed but we still return '?'.
If a char in OPTSTRING is followed by a colon, that means it wants an arg,
so the following text in the same ARGV-element, or the text of the following
ARGV-element, is returned in `optarg. Two colons mean an option that
wants an optional arg; if there is text in the current ARGV-element,
it is returned in `optarg'.
If OPTSTRING starts with `-', it requests a different method of handling the
non-option ARGV-elements. See the comments about RETURN_IN_ORDER, above. */
GetOpt::operator () (void)
if (nextchar
== 0 || *nextchar
== 0)
/* If we have just processed some options following some non-options,
exchange them so that the options come first. */
if (first_nonopt
!= last_nonopt
&& last_nonopt
!= optind
)
else if (last_nonopt
!= optind
)
/* Now skip any additional non-options
and extend the range of non-options previously skipped. */
&& (nargv
[optind
][0] != '-'
|| nargv
[optind
][1] == 0))
/* Special ARGV-element `--' means premature end of options.
Skip it like a null option,
then exchange with previous non-options as if it were an option,
then skip everything else like a non-option. */
if (optind
!= nargc
&& !strcmp (nargv
[optind
], "--"))
if (first_nonopt
!= last_nonopt
&& last_nonopt
!= optind
)
else if (first_nonopt
== last_nonopt
)
/* If we have done all the ARGV-elements, stop the scan
and back over any non-options that we skipped and permuted. */
/* Set the next-arg-index to point at the non-options
that we previously skipped, so the caller will digest them. */
if (first_nonopt
!= last_nonopt
)
/* If we have come to a non-option and did not permute it,
either stop the scan or describe it to the caller and pass it by. */
if (nargv
[optind
][0] != '-' || nargv
[optind
][1] == 0)
if (ordering
== REQUIRE_ORDER
)
optarg
= nargv
[optind
++];
/* We have found another option-ARGV-element.
Start decoding its characters. */
nextchar
= nargv
[optind
] + 1;
/* Look at and handle the next option-character. */
char *temp
= (char *) strchr (noptstring
, c
);
/* Increment `optind' when we start to process its last character. */
if (temp
== 0 || c
== ':')
if (c
< 040 || c
>= 0177)
fprintf (stderr
, "%s: unrecognized option, character code 0%o\n",
fprintf (stderr
, "%s: unrecognized option `-%c'\n",
/* This is an option that accepts an argument optionally. */
/* This is an option that requires an argument. */
/* If we end this ARGV-element by taking the rest as an arg,
we must advance to the next element now. */
else if (optind
== nargc
)
fprintf (stderr
, "%s: no argument for `-%c' option\n",
/* We already incremented `optind' once;
increment it again when taking next ARGV-elt as argument. */
optarg
= nargv
[optind
++];