kusano 7d535a
/* Getopt for GNU.
kusano 7d535a
   NOTE: getopt is now part of the C library, so if you don't know what
kusano 7d535a
   "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
kusano 7d535a
   before changing it!
kusano 7d535a
kusano 7d535a
   Copyright (C) 1987, 88, 89, 90, 91, 92, 1993
kusano 7d535a
        Free Software Foundation, Inc.
kusano 7d535a
kusano 7d535a
   This program is free software; you can redistribute it and/or modify it
kusano 7d535a
   under the terms of the GNU General Public License as published by the
kusano 7d535a
   Free Software Foundation; either version 2, or (at your option) any
kusano 7d535a
   later version.
kusano 7d535a
kusano 7d535a
   This program is distributed in the hope that it will be useful,
kusano 7d535a
   but WITHOUT ANY WARRANTY; without even the implied warranty of
kusano 7d535a
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
kusano 7d535a
   GNU General Public License for more details.
kusano 7d535a
kusano 7d535a
   You should have received a copy of the GNU General Public License
kusano 7d535a
   along with this program; if not, write to the Free Software
kusano 7d535a
   Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
kusano 7d535a
kusano 7d535a
kusano 7d535a
#ifndef EOF
kusano 7d535a
#include <stdio.h></stdio.h>
kusano 7d535a
#include <string.h></string.h>
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
kusano 7d535a
#undef PROGNAME
kusano 7d535a
#define PROGNAME(x)     (x)
kusano 7d535a
kusano 7d535a
kusano 7d535a
/* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a
kusano 7d535a
   long-named option.  Because this is not POSIX.2 compliant, it is
kusano 7d535a
   being phased out.  */
kusano 7d535a
/* #define GETOPT_COMPAT */
kusano 7d535a
#undef GETOPT_COMPAT
kusano 7d535a
kusano 7d535a
/* This version of `getopt' appears to the caller like standard Unix `getopt'
kusano 7d535a
   but it behaves differently for the user, since it allows the user
kusano 7d535a
   to intersperse the options with the other arguments.
kusano 7d535a
kusano 7d535a
   As `getopt' works, it permutes the elements of ARGV so that,
kusano 7d535a
   when it is done, all the options precede everything else.  Thus
kusano 7d535a
   all application programs are extended to handle flexible argument order.
kusano 7d535a
kusano 7d535a
   Setting the environment variable POSIXLY_CORRECT disables permutation.
kusano 7d535a
   Then the behavior is completely standard.
kusano 7d535a
kusano 7d535a
   GNU application programs can use a third alternative mode in which
kusano 7d535a
   they can distinguish the relative order of options and other arguments.  */
kusano 7d535a
kusano 7d535a
#include "mygetopt.h"
kusano 7d535a
#define option                  mfx_option
kusano 7d535a
#define optarg                  mfx_optarg
kusano 7d535a
#define optind                  mfx_optind
kusano 7d535a
#define opterr                  mfx_opterr
kusano 7d535a
#define optopt                  mfx_optopt
kusano 7d535a
#undef BAD_OPTION
kusano 7d535a
kusano 7d535a
/* For communication from `getopt' to the caller.
kusano 7d535a
   When `getopt' finds an option that takes an argument,
kusano 7d535a
   the argument value is returned here.
kusano 7d535a
   Also, when `ordering' is RETURN_IN_ORDER,
kusano 7d535a
   each non-option ARGV-element is returned here.  */
kusano 7d535a
kusano 7d535a
char *optarg = NULL;
kusano 7d535a
kusano 7d535a
/* Index in ARGV of the next element to be scanned.
kusano 7d535a
   This is used for communication to and from the caller
kusano 7d535a
   and for communication between successive calls to `getopt'.
kusano 7d535a
kusano 7d535a
   On entry to `getopt', zero means this is the first call; initialize.
kusano 7d535a
kusano 7d535a
   When `getopt' returns EOF, this is the index of the first of the
kusano 7d535a
   non-option elements that the caller should itself scan.
kusano 7d535a
kusano 7d535a
   Otherwise, `optind' communicates from one call to the next
kusano 7d535a
   how much of ARGV has been scanned so far.  */
kusano 7d535a
kusano 7d535a
/* XXX 1003.2 says this must be 1 before any call.  */
kusano 7d535a
int optind = 0;
kusano 7d535a
kusano 7d535a
/* The next char to be scanned in the option-element
kusano 7d535a
   in which the last option character we returned was found.
kusano 7d535a
   This allows us to pick up the scan where we left off.
kusano 7d535a
kusano 7d535a
   If this is zero, or a null string, it means resume the scan
kusano 7d535a
   by advancing to the next ARGV-element.  */
kusano 7d535a
kusano 7d535a
static char *nextchar;
kusano 7d535a
kusano 7d535a
/* Callers store zero here to inhibit the error message
kusano 7d535a
   for unrecognized options.  */
kusano 7d535a
kusano 7d535a
int opterr = 1;
kusano 7d535a
kusano 7d535a
/* Set to an option character which was unrecognized.
kusano 7d535a
   This must be initialized on some systems to avoid linking in the
kusano 7d535a
   system's own getopt implementation.  */
kusano 7d535a
kusano 7d535a
#define BAD_OPTION '\0'
kusano 7d535a
int optopt = BAD_OPTION;
kusano 7d535a
kusano 7d535a
/* Describe how to deal with options that follow non-option ARGV-elements.
kusano 7d535a
kusano 7d535a
   If the caller did not specify anything,
kusano 7d535a
   the default is REQUIRE_ORDER if the environment variable
kusano 7d535a
   POSIXLY_CORRECT is defined, PERMUTE otherwise.
kusano 7d535a
kusano 7d535a
   REQUIRE_ORDER means don't recognize them as options;
kusano 7d535a
   stop option processing when the first non-option is seen.
kusano 7d535a
   This is what Unix does.
kusano 7d535a
   This mode of operation is selected by either setting the environment
kusano 7d535a
   variable POSIXLY_CORRECT, or using `+' as the first character
kusano 7d535a
   of the list of option characters.
kusano 7d535a
kusano 7d535a
   PERMUTE is the default.  We permute the contents of ARGV as we scan,
kusano 7d535a
   so that eventually all the non-options are at the end.  This allows options
kusano 7d535a
   to be given in any order, even with programs that were not written to
kusano 7d535a
   expect this.
kusano 7d535a
kusano 7d535a
   RETURN_IN_ORDER is an option available to programs that were written
kusano 7d535a
   to expect options and other ARGV-elements in any order and that care about
kusano 7d535a
   the ordering of the two.  We describe each non-option ARGV-element
kusano 7d535a
   as if it were the argument of an option with character code 1.
kusano 7d535a
   Using `-' as the first character of the list of option characters
kusano 7d535a
   selects this mode of operation.
kusano 7d535a
kusano 7d535a
   The special argument `--' forces an end of option-scanning regardless
kusano 7d535a
   of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
kusano 7d535a
   `--' can cause `getopt' to return EOF with `optind' != ARGC.  */
kusano 7d535a
kusano 7d535a
static enum
kusano 7d535a
{
kusano 7d535a
  REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
kusano 7d535a
} ordering;
kusano 7d535a
kusano 7d535a
/* Handle permutation of arguments.  */
kusano 7d535a
kusano 7d535a
/* Describe the part of ARGV that contains non-options that have
kusano 7d535a
   been skipped.  `first_nonopt' is the index in ARGV of the first of them;
kusano 7d535a
   `last_nonopt' is the index after the last of them.  */
kusano 7d535a
kusano 7d535a
static int first_nonopt;
kusano 7d535a
static int last_nonopt;
kusano 7d535a
kusano 7d535a
/* Exchange two adjacent subsequences of ARGV.
kusano 7d535a
   One subsequence is elements [first_nonopt,last_nonopt)
kusano 7d535a
   which contains all the non-options that have been skipped so far.
kusano 7d535a
   The other is elements [last_nonopt,optind), which contains all
kusano 7d535a
   the options processed since those non-options were skipped.
kusano 7d535a
kusano 7d535a
   `first_nonopt' and `last_nonopt' are relocated so that they describe
kusano 7d535a
   the new indices of the non-options in ARGV after they are moved.
kusano 7d535a
kusano 7d535a
   To perform the swap, we first reverse the order of all elements. So
kusano 7d535a
   all options now come before all non options, but they are in the
kusano 7d535a
   wrong order. So we put back the options and non options in original
kusano 7d535a
   order by reversing them again. For example:
kusano 7d535a
       original input:      a b c -x -y
kusano 7d535a
       reverse all:         -y -x c b a
kusano 7d535a
       reverse options:     -x -y c b a
kusano 7d535a
       reverse non options: -x -y a b c
kusano 7d535a
*/
kusano 7d535a
kusano 7d535a
kusano 7d535a
static void exchange (char **argv)
kusano 7d535a
{
kusano 7d535a
  char *temp; char **first, **last;
kusano 7d535a
kusano 7d535a
  /* Reverse all the elements [first_nonopt, optind) */
kusano 7d535a
  first = &argv[first_nonopt];
kusano 7d535a
  last  = &argv[optind-1];
kusano 7d535a
  while (first < last) {
kusano 7d535a
    temp = *first; *first = *last; *last = temp; first++; last--;
kusano 7d535a
  }
kusano 7d535a
  /* Put back the options in order */
kusano 7d535a
  first = &argv[first_nonopt];
kusano 7d535a
  first_nonopt += (optind - last_nonopt);
kusano 7d535a
  last  = &argv[first_nonopt - 1];
kusano 7d535a
  while (first < last) {
kusano 7d535a
    temp = *first; *first = *last; *last = temp; first++; last--;
kusano 7d535a
  }
kusano 7d535a
kusano 7d535a
  /* Put back the non options in order */
kusano 7d535a
  first = &argv[first_nonopt];
kusano 7d535a
  last_nonopt = optind;
kusano 7d535a
  last  = &argv[last_nonopt-1];
kusano 7d535a
  while (first < last) {
kusano 7d535a
    temp = *first; *first = *last; *last = temp; first++; last--;
kusano 7d535a
  }
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
/* Scan elements of ARGV (whose length is ARGC) for option characters
kusano 7d535a
   given in OPTSTRING.
kusano 7d535a
kusano 7d535a
   If an element of ARGV starts with '-', and is not exactly "-" or "--",
kusano 7d535a
   then it is an option element.  The characters of this element
kusano 7d535a
   (aside from the initial '-') are option characters.  If `getopt'
kusano 7d535a
   is called repeatedly, it returns successively each of the option characters
kusano 7d535a
   from each of the option elements.
kusano 7d535a
kusano 7d535a
   If `getopt' finds another option character, it returns that character,
kusano 7d535a
   updating `optind' and `nextchar' so that the next call to `getopt' can
kusano 7d535a
   resume the scan with the following option character or ARGV-element.
kusano 7d535a
kusano 7d535a
   If there are no more option characters, `getopt' returns `EOF'.
kusano 7d535a
   Then `optind' is the index in ARGV of the first ARGV-element
kusano 7d535a
   that is not an option.  (The ARGV-elements have been permuted
kusano 7d535a
   so that those that are not options now come last.)
kusano 7d535a
kusano 7d535a
   OPTSTRING is a string containing the legitimate option characters.
kusano 7d535a
   If an option character is seen that is not listed in OPTSTRING,
kusano 7d535a
   return BAD_OPTION after printing an error message.  If you set `opterr' to
kusano 7d535a
   zero, the error message is suppressed but we still return BAD_OPTION.
kusano 7d535a
kusano 7d535a
   If a char in OPTSTRING is followed by a colon, that means it wants an arg,
kusano 7d535a
   so the following text in the same ARGV-element, or the text of the following
kusano 7d535a
   ARGV-element, is returned in `optarg'.  Two colons mean an option that
kusano 7d535a
   wants an optional arg; if there is text in the current ARGV-element,
kusano 7d535a
   it is returned in `optarg', otherwise `optarg' is set to zero.
kusano 7d535a
kusano 7d535a
   If OPTSTRING starts with `-' or `+', it requests different methods of
kusano 7d535a
   handling the non-option ARGV-elements.
kusano 7d535a
   See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
kusano 7d535a
kusano 7d535a
   Long-named options begin with `--' instead of `-'.
kusano 7d535a
   Their names may be abbreviated as long as the abbreviation is unique
kusano 7d535a
   or is an exact match for some defined option.  If they have an
kusano 7d535a
   argument, it follows the option name in the same ARGV-element, separated
kusano 7d535a
   from the option name by a `=', or else the in next ARGV-element.
kusano 7d535a
   When `getopt' finds a long-named option, it returns 0 if that option's
kusano 7d535a
   `flag' field is nonzero, the value of the option's `val' field
kusano 7d535a
   if the `flag' field is zero.
kusano 7d535a
kusano 7d535a
   LONGOPTS is a vector of `struct option' terminated by an
kusano 7d535a
   element containing a name which is zero.
kusano 7d535a
kusano 7d535a
   LONGIND returns the index in LONGOPT of the long-named option found.
kusano 7d535a
   It is only valid when a long-named option has been found by the most
kusano 7d535a
   recent call.
kusano 7d535a
kusano 7d535a
   If LONG_ONLY is nonzero, '-' as well as '--' can introduce
kusano 7d535a
   long-named options.  */
kusano 7d535a
kusano 7d535a
static int _getopt_internal (int argc, char **argv, const char *optstring,
kusano 7d535a
                 const struct option *longopts, int *longind,
kusano 7d535a
                 int long_only)
kusano 7d535a
{
kusano 7d535a
  static char empty_string[1];
kusano 7d535a
  int option_index;
kusano 7d535a
kusano 7d535a
  if (longind != NULL)
kusano 7d535a
    *longind = -1;
kusano 7d535a
kusano 7d535a
  optarg = 0;
kusano 7d535a
kusano 7d535a
  /* Initialize the internal data when the first call is made.
kusano 7d535a
     Start processing options with ARGV-element 1 (since ARGV-element 0
kusano 7d535a
     is the program name); the sequence of previously skipped
kusano 7d535a
     non-option ARGV-elements is empty.  */
kusano 7d535a
kusano 7d535a
  if (optind == 0)
kusano 7d535a
    {
kusano 7d535a
      first_nonopt = last_nonopt = optind = 1;
kusano 7d535a
kusano 7d535a
      nextchar = NULL;
kusano 7d535a
kusano 7d535a
      /* Determine how to handle the ordering of options and nonoptions.  */
kusano 7d535a
kusano 7d535a
      if (optstring[0] == '-')
kusano 7d535a
        {
kusano 7d535a
          ordering = RETURN_IN_ORDER;
kusano 7d535a
          ++optstring;
kusano 7d535a
        }
kusano 7d535a
      else if (optstring[0] == '+')
kusano 7d535a
        {
kusano 7d535a
          ordering = REQUIRE_ORDER;
kusano 7d535a
          ++optstring;
kusano 7d535a
        }
kusano 7d535a
#if 0
kusano 7d535a
      else if (getenv ("POSIXLY_CORRECT") != NULL)
kusano 7d535a
        ordering = REQUIRE_ORDER;
kusano 7d535a
#endif
kusano 7d535a
      else
kusano 7d535a
        ordering = PERMUTE;
kusano 7d535a
    }
kusano 7d535a
kusano 7d535a
  if (nextchar == NULL || *nextchar == '\0')
kusano 7d535a
    {
kusano 7d535a
      if (ordering == PERMUTE)
kusano 7d535a
        {
kusano 7d535a
          /* If we have just processed some options following some non-options,
kusano 7d535a
             exchange them so that the options come first.  */
kusano 7d535a
kusano 7d535a
          if (first_nonopt != last_nonopt && last_nonopt != optind)
kusano 7d535a
            exchange (argv);
kusano 7d535a
          else if (last_nonopt != optind)
kusano 7d535a
            first_nonopt = optind;
kusano 7d535a
kusano 7d535a
          /* Now skip any additional non-options
kusano 7d535a
             and extend the range of non-options previously skipped.  */
kusano 7d535a
kusano 7d535a
          while (optind < argc
kusano 7d535a
                 && (argv[optind][0] != '-' || argv[optind][1] == '\0')
kusano 7d535a
#ifdef GETOPT_COMPAT
kusano 7d535a
                 && (longopts == NULL
kusano 7d535a
                     || argv[optind][0] != '+' || argv[optind][1] == '\0')
kusano 7d535a
#endif                          /* GETOPT_COMPAT */
kusano 7d535a
                 )
kusano 7d535a
            optind++;
kusano 7d535a
          last_nonopt = optind;
kusano 7d535a
        }
kusano 7d535a
kusano 7d535a
      /* Special ARGV-element `--' means premature end of options.
kusano 7d535a
         Skip it like a null option,
kusano 7d535a
         then exchange with previous non-options as if it were an option,
kusano 7d535a
         then skip everything else like a non-option.  */
kusano 7d535a
kusano 7d535a
      if (optind != argc && !strcmp (argv[optind], "--"))
kusano 7d535a
        {
kusano 7d535a
          optind++;
kusano 7d535a
kusano 7d535a
          if (first_nonopt != last_nonopt && last_nonopt != optind)
kusano 7d535a
            exchange (argv);
kusano 7d535a
          else if (first_nonopt == last_nonopt)
kusano 7d535a
            first_nonopt = optind;
kusano 7d535a
          last_nonopt = argc;
kusano 7d535a
kusano 7d535a
          optind = argc;
kusano 7d535a
        }
kusano 7d535a
kusano 7d535a
      /* If we have done all the ARGV-elements, stop the scan
kusano 7d535a
         and back over any non-options that we skipped and permuted.  */
kusano 7d535a
kusano 7d535a
      if (optind == argc)
kusano 7d535a
        {
kusano 7d535a
          /* Set the next-arg-index to point at the non-options
kusano 7d535a
             that we previously skipped, so the caller will digest them.  */
kusano 7d535a
          if (first_nonopt != last_nonopt)
kusano 7d535a
            optind = first_nonopt;
kusano 7d535a
          return EOF;
kusano 7d535a
        }
kusano 7d535a
kusano 7d535a
      /* If we have come to a non-option and did not permute it,
kusano 7d535a
         either stop the scan or describe it to the caller and pass it by.  */
kusano 7d535a
kusano 7d535a
      if ((argv[optind][0] != '-' || argv[optind][1] == '\0')
kusano 7d535a
#ifdef GETOPT_COMPAT
kusano 7d535a
          && (longopts == NULL
kusano 7d535a
              || argv[optind][0] != '+' || argv[optind][1] == '\0')
kusano 7d535a
#endif                          /* GETOPT_COMPAT */
kusano 7d535a
          )
kusano 7d535a
        {
kusano 7d535a
          if (ordering == REQUIRE_ORDER)
kusano 7d535a
            return EOF;
kusano 7d535a
          optarg = argv[optind++];
kusano 7d535a
          return 1;
kusano 7d535a
        }
kusano 7d535a
kusano 7d535a
      /* We have found another option-ARGV-element.
kusano 7d535a
         Start decoding its characters.  */
kusano 7d535a
kusano 7d535a
      nextchar = (argv[optind] + 1
kusano 7d535a
                  + (longopts != NULL && argv[optind][1] == '-'));
kusano 7d535a
    }
kusano 7d535a
kusano 7d535a
  if (longopts != NULL
kusano 7d535a
      && ((argv[optind][0] == '-'
kusano 7d535a
           && (argv[optind][1] == '-' || long_only))
kusano 7d535a
#ifdef GETOPT_COMPAT
kusano 7d535a
          || argv[optind][0] == '+'
kusano 7d535a
#endif                          /* GETOPT_COMPAT */
kusano 7d535a
          ))
kusano 7d535a
    {
kusano 7d535a
      const struct option *p;
kusano 7d535a
      char *s = nextchar;
kusano 7d535a
      int exact = 0;
kusano 7d535a
      int ambig = 0;
kusano 7d535a
      const struct option *pfound = NULL;
kusano 7d535a
      int indfound = 0;
kusano 7d535a
      int needexact = 0;
kusano 7d535a
kusano 7d535a
      /* allow `--option#value' because you cannout assign a '='
kusano 7d535a
         to an environment variable under DOS command.com */
kusano 7d535a
      while (*s && *s != '=' && * s != '#')
kusano 7d535a
        s++;
kusano 7d535a
kusano 7d535a
      /* Test all options for either exact match or abbreviated matches.  */
kusano 7d535a
      for (p = longopts, option_index = 0; p->name;
kusano 7d535a
           p++, option_index++)
kusano 7d535a
        if (!strncmp (p->name, nextchar, (unsigned) (s - nextchar)))
kusano 7d535a
          {
kusano 7d535a
            if (p->has_arg & 0x10)
kusano 7d535a
              needexact = 1;
kusano 7d535a
            if ((unsigned) (s - nextchar) == strlen (p->name))
kusano 7d535a
              {
kusano 7d535a
                /* Exact match found.  */
kusano 7d535a
                pfound = p;
kusano 7d535a
                indfound = option_index;
kusano 7d535a
                exact = 1;
kusano 7d535a
                break;
kusano 7d535a
              }
kusano 7d535a
            else if (pfound == NULL)
kusano 7d535a
              {
kusano 7d535a
                /* First nonexact match found.  */
kusano 7d535a
                pfound = p;
kusano 7d535a
                indfound = option_index;
kusano 7d535a
              }
kusano 7d535a
            else
kusano 7d535a
              /* Second nonexact match found.  */
kusano 7d535a
              ambig = 1;
kusano 7d535a
          }
kusano 7d535a
kusano 7d535a
      /* don't allow nonexact longoptions */
kusano 7d535a
      if (needexact && !exact)
kusano 7d535a
        {
kusano 7d535a
          if (opterr)
kusano 7d535a
            fprintf (stderr, "%s: unrecognized option `%s'\n",
kusano 7d535a
                     PROGNAME(argv[0]), argv[optind]);
kusano 7d535a
          nextchar += strlen (nextchar);
kusano 7d535a
          optind++;
kusano 7d535a
          return BAD_OPTION;
kusano 7d535a
        }
kusano 7d535a
      if (ambig && !exact)
kusano 7d535a
        {
kusano 7d535a
          if (opterr)
kusano 7d535a
            fprintf (stderr, "%s: option `%s' is ambiguous\n",
kusano 7d535a
                     PROGNAME(argv[0]), argv[optind]);
kusano 7d535a
          nextchar += strlen (nextchar);
kusano 7d535a
          optind++;
kusano 7d535a
          return BAD_OPTION;
kusano 7d535a
        }
kusano 7d535a
kusano 7d535a
      if (pfound != NULL)
kusano 7d535a
        {
kusano 7d535a
          int have_arg = (s[0] != '\0');
kusano 7d535a
          if (have_arg && (pfound->has_arg & 0xf))
kusano 7d535a
            have_arg = (s[1] != '\0');
kusano 7d535a
          option_index = indfound;
kusano 7d535a
          optind++;
kusano 7d535a
          if (have_arg)
kusano 7d535a
            {
kusano 7d535a
              /* Don't test has_arg with >, because some C compilers don't
kusano 7d535a
                 allow it to be used on enums.  */
kusano 7d535a
              if (pfound->has_arg & 0xf)
kusano 7d535a
                optarg = s + 1;
kusano 7d535a
              else
kusano 7d535a
                {
kusano 7d535a
                  if (opterr)
kusano 7d535a
                    {
kusano 7d535a
                      if (argv[optind - 1][1] == '-')
kusano 7d535a
                        /* --option */
kusano 7d535a
                        fprintf (stderr,
kusano 7d535a
                                 "%s: option `--%s' doesn't allow an argument\n",
kusano 7d535a
                                 PROGNAME(argv[0]), pfound->name);
kusano 7d535a
                      else
kusano 7d535a
                        /* +option or -option */
kusano 7d535a
                        fprintf (stderr,
kusano 7d535a
                             "%s: option `%c%s' doesn't allow an argument\n",
kusano 7d535a
                             PROGNAME(argv[0]), argv[optind - 1][0], pfound->name);
kusano 7d535a
                    }
kusano 7d535a
                  nextchar += strlen (nextchar);
kusano 7d535a
                  return BAD_OPTION;
kusano 7d535a
                }
kusano 7d535a
            }
kusano 7d535a
          else if ((pfound->has_arg & 0xf) == 1)
kusano 7d535a
            {
kusano 7d535a
#if 0
kusano 7d535a
              if (optind < argc)
kusano 7d535a
#else
kusano 7d535a
              if (optind < argc && (pfound->has_arg & 0x20) == 0)
kusano 7d535a
#endif
kusano 7d535a
                optarg = argv[optind++];
kusano 7d535a
              else
kusano 7d535a
                {
kusano 7d535a
                  if (opterr)
kusano 7d535a
                    fprintf (stderr, "%s: option `--%s%s' requires an argument\n",
kusano 7d535a
                             PROGNAME(argv[0]), pfound->name,
kusano 7d535a
                             (pfound->has_arg & 0x20) ? "=" : "");
kusano 7d535a
                  nextchar += strlen (nextchar);
kusano 7d535a
                  return optstring[0] == ':' ? ':' : BAD_OPTION;
kusano 7d535a
                }
kusano 7d535a
            }
kusano 7d535a
          nextchar += strlen (nextchar);
kusano 7d535a
          if (longind != NULL)
kusano 7d535a
            *longind = option_index;
kusano 7d535a
          if (pfound->flag)
kusano 7d535a
            {
kusano 7d535a
              *(pfound->flag) = pfound->val;
kusano 7d535a
              return 0;
kusano 7d535a
            }
kusano 7d535a
          return pfound->val;
kusano 7d535a
        }
kusano 7d535a
      /* Can't find it as a long option.  If this is not getopt_long_only,
kusano 7d535a
         or the option starts with '--' or is not a valid short
kusano 7d535a
         option, then it's an error.
kusano 7d535a
         Otherwise interpret it as a short option.  */
kusano 7d535a
      if (!long_only || argv[optind][1] == '-'
kusano 7d535a
#ifdef GETOPT_COMPAT
kusano 7d535a
          || argv[optind][0] == '+'
kusano 7d535a
#endif                          /* GETOPT_COMPAT */
kusano 7d535a
          || strchr (optstring, *nextchar) == NULL)
kusano 7d535a
        {
kusano 7d535a
          if (opterr)
kusano 7d535a
            {
kusano 7d535a
              if (argv[optind][1] == '-')
kusano 7d535a
                /* --option */
kusano 7d535a
                fprintf (stderr, "%s: unrecognized option `--%s'\n",
kusano 7d535a
                         PROGNAME(argv[0]), nextchar);
kusano 7d535a
              else
kusano 7d535a
                /* +option or -option */
kusano 7d535a
                fprintf (stderr, "%s: unrecognized option `%c%s'\n",
kusano 7d535a
                         PROGNAME(argv[0]), argv[optind][0], nextchar);
kusano 7d535a
            }
kusano 7d535a
          nextchar = empty_string;
kusano 7d535a
          optind++;
kusano 7d535a
          return BAD_OPTION;
kusano 7d535a
        }
kusano 7d535a
        (void) &ambig;  /* UNUSED */
kusano 7d535a
    }
kusano 7d535a
kusano 7d535a
  /* Look at and handle the next option-character.  */
kusano 7d535a
kusano 7d535a
  {
kusano 7d535a
    char c = *nextchar++;
kusano 7d535a
    const char *temp = strchr (optstring, c);
kusano 7d535a
kusano 7d535a
    /* Increment `optind' when we start to process its last character.  */
kusano 7d535a
    if (*nextchar == '\0')
kusano 7d535a
      ++optind;
kusano 7d535a
kusano 7d535a
    if (temp == NULL || c == ':')
kusano 7d535a
      {
kusano 7d535a
        if (opterr)
kusano 7d535a
          {
kusano 7d535a
#if 0
kusano 7d535a
            if (c < 040 || c >= 0177)
kusano 7d535a
              fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
kusano 7d535a
                       PROGNAME(argv[0]), c);
kusano 7d535a
            else
kusano 7d535a
              fprintf (stderr, "%s: unrecognized option `-%c'\n", PROGNAME(argv[0]), c);
kusano 7d535a
#else
kusano 7d535a
            /* 1003.2 specifies the format of this message.  */
kusano 7d535a
            fprintf (stderr, "%s: illegal option -- %c\n", PROGNAME(argv[0]), c);
kusano 7d535a
#endif
kusano 7d535a
          }
kusano 7d535a
        optopt = c;
kusano 7d535a
        return BAD_OPTION;
kusano 7d535a
      }
kusano 7d535a
    if (temp[1] == ':')
kusano 7d535a
      {
kusano 7d535a
        if (temp[2] == ':')
kusano 7d535a
          {
kusano 7d535a
            /* This is an option that accepts an argument optionally.  */
kusano 7d535a
            if (*nextchar != '\0')
kusano 7d535a
              {
kusano 7d535a
                optarg = nextchar;
kusano 7d535a
                optind++;
kusano 7d535a
              }
kusano 7d535a
            else
kusano 7d535a
              optarg = 0;
kusano 7d535a
            nextchar = NULL;
kusano 7d535a
          }
kusano 7d535a
        else
kusano 7d535a
          {
kusano 7d535a
            /* This is an option that requires an argument.  */
kusano 7d535a
            if (*nextchar != '\0')
kusano 7d535a
              {
kusano 7d535a
                optarg = nextchar;
kusano 7d535a
                /* If we end this ARGV-element by taking the rest as an arg,
kusano 7d535a
                   we must advance to the next element now.  */
kusano 7d535a
                optind++;
kusano 7d535a
              }
kusano 7d535a
            else if (optind == argc)
kusano 7d535a
              {
kusano 7d535a
                if (opterr)
kusano 7d535a
                  {
kusano 7d535a
#if 0
kusano 7d535a
                    fprintf (stderr, "%s: option `-%c' requires an argument\n",
kusano 7d535a
                             PROGNAME(argv[0]), c);
kusano 7d535a
#else
kusano 7d535a
                    /* 1003.2 specifies the format of this message.  */
kusano 7d535a
                    fprintf (stderr, "%s: option requires an argument -- %c\n",
kusano 7d535a
                             PROGNAME(argv[0]), c);
kusano 7d535a
#endif
kusano 7d535a
                  }
kusano 7d535a
                optopt = c;
kusano 7d535a
                if (optstring[0] == ':')
kusano 7d535a
                  c = ':';
kusano 7d535a
                else
kusano 7d535a
                  c = BAD_OPTION;
kusano 7d535a
              }
kusano 7d535a
            else
kusano 7d535a
              /* We already incremented `optind' once;
kusano 7d535a
                 increment it again when taking next ARGV-elt as argument.  */
kusano 7d535a
              optarg = argv[optind++];
kusano 7d535a
            nextchar = NULL;
kusano 7d535a
          }
kusano 7d535a
      }
kusano 7d535a
    return c;
kusano 7d535a
  }
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
int mfx_getopt(int argc, char **argv, const char *optstring)
kusano 7d535a
{
kusano 7d535a
  return _getopt_internal (argc, argv, optstring,
kusano 7d535a
                           (const struct option *) 0,
kusano 7d535a
                           (int *) 0,
kusano 7d535a
                           0);
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
int mfx_getopt_long(int argc, char **argv, const char *options,
kusano 7d535a
                    const struct option *long_options, int *opt_index)
kusano 7d535a
{
kusano 7d535a
  return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
#ifdef TEST
kusano 7d535a
kusano 7d535a
/* Compile with -DTEST to make an executable for use in testing
kusano 7d535a
   the above definition of `getopt'.  */
kusano 7d535a
kusano 7d535a
int
kusano 7d535a
main (argc, argv)
kusano 7d535a
     int argc;
kusano 7d535a
     char **argv;
kusano 7d535a
{
kusano 7d535a
  int c;
kusano 7d535a
  int digit_optind = 0;
kusano 7d535a
kusano 7d535a
  while (1)
kusano 7d535a
    {
kusano 7d535a
      int this_option_optind = optind ? optind : 1;
kusano 7d535a
kusano 7d535a
      c = getopt (argc, argv, "abc:d:0123456789");
kusano 7d535a
      if (c == EOF)
kusano 7d535a
        break;
kusano 7d535a
kusano 7d535a
      switch (c)
kusano 7d535a
        {
kusano 7d535a
        case '0':
kusano 7d535a
        case '1':
kusano 7d535a
        case '2':
kusano 7d535a
        case '3':
kusano 7d535a
        case '4':
kusano 7d535a
        case '5':
kusano 7d535a
        case '6':
kusano 7d535a
        case '7':
kusano 7d535a
        case '8':
kusano 7d535a
        case '9':
kusano 7d535a
          if (digit_optind != 0 && digit_optind != this_option_optind)
kusano 7d535a
            printf ("digits occur in two different argv-elements.\n");
kusano 7d535a
          digit_optind = this_option_optind;
kusano 7d535a
          printf ("option %c\n", c);
kusano 7d535a
          break;
kusano 7d535a
kusano 7d535a
        case 'a':
kusano 7d535a
          printf ("option a\n");
kusano 7d535a
          break;
kusano 7d535a
kusano 7d535a
        case 'b':
kusano 7d535a
          printf ("option b\n");
kusano 7d535a
          break;
kusano 7d535a
kusano 7d535a
        case 'c':
kusano 7d535a
          printf ("option c with value `%s'\n", optarg);
kusano 7d535a
          break;
kusano 7d535a
kusano 7d535a
        case BAD_OPTION:
kusano 7d535a
          break;
kusano 7d535a
kusano 7d535a
        default:
kusano 7d535a
          printf ("?? getopt returned character code 0%o ??\n", c);
kusano 7d535a
        }
kusano 7d535a
    }
kusano 7d535a
kusano 7d535a
  if (optind < argc)
kusano 7d535a
    {
kusano 7d535a
      printf ("non-option ARGV-elements: ");
kusano 7d535a
      while (optind < argc)
kusano 7d535a
        printf ("%s ", argv[optind++]);
kusano 7d535a
      printf ("\n");
kusano 7d535a
    }
kusano 7d535a
kusano 7d535a
  exit (0);
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
#endif /* TEST */
kusano 7d535a
kusano 7d535a
kusano 7d535a
/*
kusano 7d535a
vi:ts=4:et:nowrap
kusano 7d535a
*/
kusano 7d535a