## modules/up/src/Core/gnu/GetOpt.cc

/* [<][>][^][v][top][bottom][index][help] */

## FUNCTIONS

This source file includes following functions.

1. GetOpt
2. exchange

       1 /*
       2 Getopt for GNU.
       3 Copyright (C) 1987, 1989 Free Software Foundation, Inc.
       4
       5 (Modified by Douglas C. Schmidt for use with GNU G++.)
       6 This file is part of the GNU C++ Library.  This library is free
       7 software; you can redistribute it and/or modify it under the terms of
       8 the GNU Library General Public License as published by the Free
       9 Software Foundation; either version 2 of the License, or (at your
      10 option) any later version.  This library is distributed in the hope
      11 that it will be useful, but WITHOUT ANY WARRANTY; without even the
      12 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
      13 PURPOSE.  See the GNU Library General Public License for more details.
      14 You should have received a copy of the GNU Library General Public
      15 License along with this library; if not, write to the Free Software
      16 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
      17 */
      18
      19 #ifdef __GNUG__
      20 #pragma implementation
      21 #endif
      22 /* AIX requires the alloca decl to be the first thing in the file. */
      23 #ifdef __GNUC__
      24 #define alloca __builtin_alloca
      25 #elif defined(sparc)
      26 #include <alloca.h>
      27 extern "C" void *__builtin_alloca(...);
      28 #elif defined(_AIX)
      29 #pragma alloca
      30 #else
      31 char *alloca ();
      32 #endif
      33 #include "gnu/GetOpt.h"
      34
      35 char* GetOpt::nextchar = 0;
      36 int GetOpt::first_nonopt = 0;
      37 int GetOpt::last_nonopt = 0;
      38
      39 GetOpt::GetOpt (int argc, char **argv, const char *optstring)
         /* [<][>][^][v][top][bottom][index][help] */
      40  :opterr (1), nargc (argc), nargv (argv), noptstring (optstring)
      41 {
      42   /* Initialize the internal data when the first call is made.
      43      Start processing options with ARGV-element 1 (since ARGV-element 0
      44      is the program name); the sequence of previously skipped
      45      non-option ARGV-elements is empty.  */
      46
      47   first_nonopt = last_nonopt = optind = 1;
      48   optarg = nextchar = 0;
      49
      50   /* Determine how to handle the ordering of options and nonoptions.  */
      51
      52   if (optstring[0] == '-')
      53     ordering = RETURN_IN_ORDER;
      54   else if (getenv ("_POSIX_OPTION_ORDER") != 0)
      55     ordering = REQUIRE_ORDER;
      56   else
      57     ordering = PERMUTE;
      58 }
      59
      60 void
      61 GetOpt::exchange (char **argv)
         /* [<][>][^][v][top][bottom][index][help] */
      62 {
      63   int nonopts_size
      64     = (last_nonopt - first_nonopt) * sizeof (char *);
      65   char **temp = (char **) alloca (nonopts_size);
      66
      67   /* Interchange the two blocks of data in argv.  */
      68
      69   memcpy (temp, &argv[first_nonopt], nonopts_size);
      70   memcpy (&argv[first_nonopt], &argv[last_nonopt],
      71          (optind - last_nonopt) * sizeof (char *));
      72   memcpy (&argv[first_nonopt + optind - last_nonopt], temp,
      73          nonopts_size);
      74
      75   /* Update records for the slots the non-options now occupy.  */
      76
      77   first_nonopt += (optind - last_nonopt);
      78   last_nonopt = optind;
      79 }
      80
      81 /* Scan elements of ARGV (whose length is ARGC) for option characters
      82    given in OPTSTRING.
      83
      84    If an element of ARGV starts with '-', and is not exactly "-" or "--",
      85    then it is an option element.  The characters of this element
      86    (aside from the initial '-') are option characters.  If `getopt'
      87    is called repeatedly, it returns successively each of theoption characters
      88    from each of the option elements.
      89
      90    If `getopt' finds another option character, it returns that character,
      91    updating `optind' and `nextchar' so that the next call to `getopt' can
      92    resume the scan with the following option character or ARGV-element.
      93
      94    If there are no more option characters, `getopt' returns `EOF'.
      95    Then `optind' is the index in ARGV of the first ARGV-element
      96    that is not an option.  (The ARGV-elements have been permuted
      97    so that those that are not options now come last.)
      98
      99    OPTSTRING is a string containing the legitimate option characters.
     100    A colon in OPTSTRING means that the previous character is an option
     101    that wants an argument.  The argument is taken from the rest of the
     102    current ARGV-element, or from the following ARGV-element,
     103    and returned in `optarg'.
     104
     105    If an option character is seen that is not listed in OPTSTRING,
     106    return '?' after printing an error message.  If you set `opterr' to
     107    zero, the error message is suppressed but we still return '?'.
     108
     109    If a char in OPTSTRING is followed by a colon, that means it wants an arg,
     110    so the following text in the same ARGV-element, or the text of the following
     111    ARGV-element, is returned in `optarg.  Two colons mean an option that
     112    wants an optional arg; if there is text in the current ARGV-element,
     113    it is returned in `optarg'.
     114
     115    If OPTSTRING starts with `-', it requests a different method of handling the
     116    non-option ARGV-elements.  See the comments about RETURN_IN_ORDER, above.  */
     117
     118 int
     119 GetOpt::operator () (void)
     120 {
     121   if (nextchar == 0 || *nextchar == 0)
     122     {
     123       if (ordering == PERMUTE)
     124         {
     125           /* If we have just processed some options following some non-options,
     126              exchange them so that the options come first.  */
     127
     128           if (first_nonopt != last_nonopt && last_nonopt != optind)
     129             exchange (nargv);
     130           else if (last_nonopt != optind)
     131             first_nonopt = optind;
     132
     133           /* Now skip any additional non-options
     134              and extend the range of non-options previously skipped.  */
     135
     136           while (optind < nargc
     137                  && (nargv[optind][0] != '-'
     138                      || nargv[optind][1] == 0))
     139             optind++;
     140           last_nonopt = optind;
     141         }
     142
     143       /* Special ARGV-element `--' means premature end of options.
     144          Skip it like a null option,
     145          then exchange with previous non-options as if it were an option,
     146          then skip everything else like a non-option.  */
     147
     148       if (optind != nargc && !strcmp (nargv[optind], "--"))
     149         {
     150           optind++;
     151
     152           if (first_nonopt != last_nonopt && last_nonopt != optind)
     153             exchange (nargv);
     154           else if (first_nonopt == last_nonopt)
     155             first_nonopt = optind;
     156           last_nonopt = nargc;
     157
     158           optind = nargc;
     159         }
     160
     161       /* If we have done all the ARGV-elements, stop the scan
     162          and back over any non-options that we skipped and permuted.  */
     163
     164       if (optind == nargc)
     165         {
     166           /* Set the next-arg-index to point at the non-options
     167              that we previously skipped, so the caller will digest them.  */
     168           if (first_nonopt != last_nonopt)
     169             optind = first_nonopt;
     170           return EOF;
     171         }
     172
     173       /* If we have come to a non-option and did not permute it,
     174          either stop the scan or describe it to the caller and pass it by.  */
     175
     176       if (nargv[optind][0] != '-' || nargv[optind][1] == 0)
     177         {
     178           if (ordering == REQUIRE_ORDER)
     179             return EOF;
     180           optarg = nargv[optind++];
     181           return 0;
     182         }
     183
     184       /* We have found another option-ARGV-element.
     185          Start decoding its characters.  */
     186
     187       nextchar = nargv[optind] + 1;
     188     }
     189
     190   /* Look at and handle the next option-character.  */
     191
     192   {
     193     char c = *nextchar++;
     194     char *temp = (char *) strchr (noptstring, c);
     195
     196     /* Increment `optind' when we start to process its last character.  */
     197     if (*nextchar == 0)
     198       optind++;
     199
     200     if (temp == 0 || c == ':')
     201       {
     202         if (opterr != 0)
     203           {
     204             if (c < 040 || c >= 0177)
     205               fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
     206                        nargv[0], c);
     207             else
     208               fprintf (stderr, "%s: unrecognized option `-%c'\n",
     209                        nargv[0], c);
     210           }
     211         return '?';
     212       }
     213     if (temp[1] == ':')
     214       {
     215         if (temp[2] == ':')
     216           {
     217             /* This is an option that accepts an argument optionally.  */
     218             if (*nextchar != 0)
     219               {
     220                 optarg = nextchar;
     221                 optind++;
     222               }
     223             else
     224               optarg = 0;
     225             nextchar = 0;
     226           }
     227         else
     228           {
     229             /* This is an option that requires an argument.  */
     230             if (*nextchar != 0)
     231               {
     232                 optarg = nextchar;
     233                 /* If we end this ARGV-element by taking the rest as an arg,
     234                    we must advance to the next element now.  */
     235                 optind++;
     236               }
     237             else if (optind == nargc)
     238               {
     239                 if (opterr != 0)
     240                   fprintf (stderr, "%s: no argument for `-%c' option\n",
     241                            nargv[0], c);
     242                 c = '?';
     243               }
     244             else
     245               /* We already incremented `optind' once;
     246                  increment it again when taking next ARGV-elt as argument.  */
     247               optarg = nargv[optind++];
     248             nextchar = 0;
     249           }
     250       }
     251     return c;
     252   }
     253 }

/* [<][>][^][v][top][bottom][index][help] */