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] */