Get_Opt.cpp

Go to the documentation of this file.
00001 // Get_Opt.cpp,v 4.53 2006/04/19 19:13:09 jwillemsen Exp
00002 
00003 #include "ace/Get_Opt.h"
00004 
00005 #if !defined (__ACE_INLINE__)
00006 #include "ace/Get_Opt.inl"
00007 #endif /* __ACE_INLINE__ */
00008 
00009 #include "ace/ACE.h"
00010 #include "ace/Log_Msg.h"
00011 #include "ace/SString.h"
00012 #include "ace/OS_Memory.h"
00013 #include "ace/OS_NS_string.h"
00014 #include "ace/OS_NS_ctype.h"
00015 #include "ace/OS_NS_stdlib.h"
00016 
00017 ACE_RCSID (ace,
00018            Get_Opt,
00019            "Get_Opt.cpp,v 4.53 2006/04/19 19:13:09 jwillemsen Exp")
00020 
00021 /*
00022  * Copyright (c) 1987, 1993, 1994
00023  *      The Regents of the University of California.  All rights reserved.
00024  *
00025  * Redistribution and use in source and binary forms, with or without
00026  * modification, are permitted provided that the following conditions
00027  * are met:
00028  * 1. Redistributions of source code must retain the above copyright
00029  *    notice, this list of conditions and the following disclaimer.
00030  * 2. Redistributions in binary form must reproduce the above copyright
00031  *    notice, this list of conditions and the following disclaimer in the
00032  *    documentation and/or other materials provided with the distribution.
00033  * 3. All advertising materials mentioning features or use of this software
00034  *    must display the following acknowledgement:
00035  *      This product includes software developed by the University of
00036  *      California, Berkeley and its contributors.
00037  * 4. Neither the name of the University nor the names of its contributors
00038  *    may be used to endorse or promote products derived from this software
00039  *    without specific prior written permission.
00040  *
00041  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00042  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00043  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00044  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00045  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00046  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00047  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00048  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00049  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00050  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00051  * SUCH DAMAGE.
00052  */
00053 
00054 /*-
00055  * Copyright (c) 2000 The NetBSD Foundation, Inc.
00056  * All rights reserved.
00057  *
00058  * This code is derived from software contributed to The NetBSD Foundation
00059  * by Dieter Baron and Thomas Klausner.
00060  *
00061  * Redistribution and use in source and binary forms, with or without
00062  * modification, are permitted provided that the following conditions
00063  * are met:
00064  * 1. Redistributions of source code must retain the above copyright
00065  *    notice, this list of conditions and the following disclaimer.
00066  * 2. Redistributions in binary form must reproduce the above copyright
00067  *    notice, this list of conditions and the following disclaimer in the
00068  *    documentation and/or other materials provided with the distribution.
00069  * 3. All advertising materials mentioning features or use of this software
00070  *    must display the following acknowledgement:
00071  *        This product includes software developed by the NetBSD
00072  *        Foundation, Inc. and its contributors.
00073  * 4. Neither the name of The NetBSD Foundation nor the names of its
00074  *    contributors may be used to endorse or promote products derived
00075  *    from this software without specific prior written permission.
00076  *
00077  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
00078  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
00079  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00080  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
00081  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00082  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00083  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00084  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00085  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00086  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00087  * POSSIBILITY OF SUCH DAMAGE.
00088  */
00089 
00090 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00091 
00092 ACE_ALLOC_HOOK_DEFINE(ACE_Get_Opt)
00093 
00094 ACE_Get_Opt::ACE_Get_Opt (int argc,
00095                           ACE_TCHAR **argv,
00096                           const ACE_TCHAR *optstring,
00097                           int skip,
00098                           int report_errors,
00099                           int ordering,
00100                           int long_only)
00101   : argc_ (argc),
00102     argv_ (argv),
00103     optind (skip),
00104     opterr (report_errors),
00105     optarg (0),
00106     optstring_ (0),
00107     long_only_ (long_only),
00108     has_colon_ (0),
00109     last_option_ (0),
00110     nextchar_ (0),
00111     optopt_ (0),
00112     ordering_ (ordering),
00113     nonopt_start_ (optind),
00114     nonopt_end_ (optind),
00115     long_option_ (0)
00116 {
00117   ACE_TRACE ("ACE_Get_Opt::ACE_Get_Opt");
00118 
00119   ACE_NEW (this->optstring_, ACE_TString (optstring));
00120   ACE_NEW (this->last_option_, ACE_TString (ACE_LIB_TEXT ("")));
00121 
00122   // First check to see if POSIXLY_CORRECT was set.
00123   // Win32 is the only platform capable of wide-char env var.
00124 #if defined (ACE_WIN32)
00125   const ACE_TCHAR *env_check = ACE_LIB_TEXT ("POSIXLY_CORRECT");
00126 #else
00127   const char *env_check = "POSIXLY_CORRECT";
00128 #endif
00129   if (ACE_OS::getenv (env_check) != 0)
00130     this->ordering_ = REQUIRE_ORDER;
00131 
00132   // Now, check to see if any or the following were passed at
00133   // the begining of optstring: '+' same as POSIXLY_CORRECT;
00134   // '-' turns off POSIXLY_CORRECT; or ':' which signifies we
00135   // should return ':' if a parameter is missing for an option.
00136   // We use a loop here, since a combination of "{+|-}:" in any
00137   // order should be legal.
00138   int done  = 0;
00139   int offset = 0;
00140   while (!done)
00141     {
00142       switch (optstring[offset++])
00143         {
00144         case '+':
00145           this->ordering_ = REQUIRE_ORDER;
00146           break;
00147         case '-':
00148           this->ordering_ = RETURN_IN_ORDER;
00149           break;
00150         case ':':
00151           this->has_colon_ = 1;
00152           break;
00153         default:
00154           // Quit as soon as we see something else...
00155           done = 1;
00156           break;
00157         }
00158     }
00159 }
00160 
00161 ACE_Get_Opt::~ACE_Get_Opt (void)
00162 {
00163   ACE_TRACE ("ACE_Get_Opt::~ACE_Get_Opt");
00164 
00165   size_t i = 0;
00166   size_t size = this->long_opts_.size ();
00167   ACE_Get_Opt_Long_Option *option = 0;
00168   for (i = 0; i < size; ++i)
00169     {
00170      int retval = this->long_opts_.get (option, i);
00171       if (retval != 0)
00172         {
00173           // Should never happen.
00174           retval = 0;
00175           continue;
00176         }
00177       if (option)
00178         {
00179           delete option;
00180           option = 0;
00181         }
00182     }
00183   delete this->optstring_;
00184   delete this->last_option_;
00185 }
00186 
00187 int
00188 ACE_Get_Opt::nextchar_i (void)
00189 {
00190   ACE_TRACE ("ACE_Get_Opt::nextchar_i");
00191 
00192   if (this->ordering_ == PERMUTE_ARGS)
00193     if (this->permute () == EOF)
00194       return EOF;
00195 
00196   // Update scanning pointer.
00197   if (this->optind >= this->argc_)
00198     {
00199       // We're done...
00200       this->nextchar_ = 0;
00201       return EOF;
00202     }
00203   else if (*(this->nextchar_ = this->argv_[this->optind]) != '-'
00204             || this->nextchar_[1] == '\0')
00205     {
00206       // We didn't get an option.
00207 
00208       if (this->ordering_ == REQUIRE_ORDER
00209           || this->ordering_ == PERMUTE_ARGS)
00210         // If we permuted or require the options to be in order, we're done.
00211         return EOF;
00212 
00213       // It must be RETURN_IN_ORDER...
00214       this->optarg = this->argv_[this->optind++];
00215       this->nextchar_ = 0;
00216       return 1;
00217     }
00218   else if (this->nextchar_[1] != 0
00219            && *++this->nextchar_ == '-'
00220            && this->nextchar_[1] == 0)
00221     {
00222       // Found "--" so we're done...
00223       ++this->optind;
00224       this->nextchar_ = 0;
00225       return EOF;
00226     }
00227 
00228   // If it's a long option, and we allow long options advance nextchar_.
00229   if (*this->nextchar_ == '-' && this->long_opts_.size () != 0)
00230     this->nextchar_++;
00231 
00232   return 0;
00233 }
00234 
00235 int
00236 ACE_Get_Opt::long_option_i (void)
00237 {
00238   ACE_TRACE ("ACE_Get_Opt::long_option_i");
00239 
00240   ACE_Get_Opt_Long_Option *p;
00241   ACE_TCHAR *s = this->nextchar_;
00242   int hits = 0;
00243   int exact = 0;
00244   ACE_Get_Opt_Long_Option *pfound = 0;
00245   int indfound = 0;
00246 
00247   // Advance to the end of the long option name so we can use
00248   // it to get the length for a string compare.
00249   while (*s && *s != '=')
00250     s++;
00251 
00252   size_t len = s - this->nextchar_;
00253   // set last_option_ to nextchar_, up to the '='.
00254   this->last_option (ACE_TString (this->nextchar_, len));
00255 
00256   size_t size = this->long_opts_.size ();
00257   u_int option_index = 0;
00258   for (option_index = 0; option_index < size ; option_index++)
00259     {
00260       p = this->long_opts_[option_index];
00261       ACE_ASSERT (p);
00262 
00263       if (!ACE_OS::strncmp (p->name_, this->nextchar_, len))
00264         {
00265           // Got at least a partial match.
00266           pfound = p;
00267           indfound = option_index;
00268           hits += 1;
00269           if (len == ACE_OS::strlen(p->name_))
00270             {
00271               // And in fact, it's an exact match, so let's use it.
00272               exact = 1;
00273               break;
00274             }
00275         }
00276     }
00277 
00278   if ((hits > 1) && !exact)
00279     {
00280       // Great, we found a match, but unfortunately we found more than
00281       // one and it wasn't exact.
00282       if (this->opterr)
00283         ACE_ERROR ((LM_ERROR,
00284                     ACE_LIB_TEXT ("%s: option `%s' is ambiguous\n"),
00285                     this->argv_[0], this->argv_[this->optind]));
00286       this->nextchar_ = 0;
00287       this->optind++;
00288       return '?';
00289     }
00290 
00291   if (pfound != 0)
00292     {
00293       // Okay, we found a good one (either a single hit or an exact match).
00294       option_index = indfound;
00295       this->optind++;
00296       if (*s)
00297         {
00298           // s must point to '=' which means there's an argument (well
00299           // close enough).
00300           if (pfound->has_arg_ != NO_ARG)
00301             // Good, we want an argument and here it is.
00302             this->optarg = ++s;
00303           else
00304             {
00305               // Whoops, we've got what looks like an argument, but we
00306               // don't want one.
00307               if (this->opterr)
00308                   ACE_ERROR
00309                     ((LM_ERROR,
00310                       ACE_LIB_TEXT ("%s: long option `--%s' doesn't allow ")
00311                       ACE_LIB_TEXT ("an argument\n"),
00312                       this->argv_[0], pfound->name_));
00313               // The spec doesn't cover this, so we keep going and the program
00314               // doesn't know we ignored an argument if opt_err is off!!!
00315             }
00316         }
00317       else if (pfound->has_arg_ == ARG_REQUIRED)
00318         {
00319           // s didn't help us, but we need an argument. Note that
00320           // optional arguments for long options must use the "=" syntax,
00321           // so we won't get here in that case.
00322           if (this->optind < this->argc_)
00323             // We still have some elements left, so use the next one.
00324             this->optarg = this->argv_[this->optind++];
00325           else
00326             {
00327               // All out of elements, so we have to punt...
00328               if (this->opterr)
00329                 ACE_ERROR ((LM_ERROR,
00330                             ACE_LIB_TEXT ("%s: long option '--%s' requires ")
00331                             ACE_LIB_TEXT ("an argument\n"),
00332                             this->argv_[0], pfound->name_));
00333               this->nextchar_ = 0;
00334               this->optopt_ = pfound->val_;   // Remember matching short equiv
00335               return this->has_colon_ ? ':' : '?';
00336             }
00337         }
00338       this->nextchar_ = 0;
00339       this->long_option_ = pfound;
00340       // Since val_ has to be either a valid short option or 0, this works
00341       // great.  If the user really wants to know if a long option was passed.
00342       this->optopt_ = pfound->val_;
00343       return pfound->val_;
00344     }
00345   if (!this->long_only_ || this->argv_[this->optind][1] == '-'
00346       || this->optstring_->find (*this->nextchar_) == ACE_TString::npos)
00347     {
00348       // Okay, we couldn't find a long option.  If it isn't long_only (which
00349       // means try the long first, and if not found try the short) or a long
00350       // signature was passed, e.g. "--", or it's not a short (not sure when
00351       // this could happen) it's an error.
00352       if (this->opterr)
00353         ACE_ERROR ((LM_ERROR,
00354                     ACE_LIB_TEXT ("%s: illegal long option '--%s'\n"),
00355                     this->argv_[0], this->nextchar_));
00356       this->nextchar_ = 0;
00357       this->optind++;
00358       return '?';
00359     }
00360   return this->short_option_i ();
00361 }
00362 
00363 int
00364 ACE_Get_Opt::short_option_i (void)
00365 {
00366   ACE_TRACE ("ACE_Get_Opt::short_option_i");
00367 
00368   /* Look at and handle the next option-character.  */
00369   ACE_TCHAR opt = *this->nextchar_++;
00370   // Set last_option_ to opt
00371   this->last_option (opt);
00372 
00373   ACE_TCHAR *oli = 0;
00374   oli =
00375     const_cast<ACE_TCHAR*> (ACE_OS::strchr (this->optstring_->c_str (), opt));
00376 
00377   /* Increment `optind' when we start to process its last character.  */
00378   if (*this->nextchar_ == '\0')
00379     ++this->optind;
00380 
00381   if (oli == 0 || opt == ':')
00382     {
00383       if (this->opterr)
00384         ACE_ERROR ((LM_ERROR,
00385                     ACE_LIB_TEXT ("%s: illegal short option -- %c\n"),
00386                     this->argv_[0], opt));
00387       return '?';
00388     }
00389   if (opt == 'W' && oli[1] == ';')
00390     {
00391       if (this->nextchar_[0] == 0)
00392         this->nextchar_ = this->argv_[this->optind];
00393       return long_option_i ();
00394     }
00395   this->optopt_ = oli[0];      // Remember the option that matched
00396   if (oli[1] == ':')
00397     {
00398       if (oli[2] == ':')
00399         {
00400           // Takes an optional argument, and since short option args must
00401           // must follow directly in the same argument, a NULL nextchar_
00402           // means we didn't get one.
00403           if (*this->nextchar_ != '\0')
00404             {
00405               this->optarg = this->nextchar_;
00406               this->optind++;
00407             }
00408           else
00409             this->optarg = 0;
00410           this->nextchar_ = 0;
00411         }
00412       else
00413         {
00414           // Takes a required argument.
00415           if (*this->nextchar_ != '\0')
00416             {
00417               // Found argument in same argv-element.
00418               this->optarg = this->nextchar_;
00419               this->optind++;
00420             }
00421           else if (this->optind == this->argc_)
00422             {
00423               // Ran out of arguments before finding required argument.
00424               if (this->opterr)
00425                 ACE_ERROR ((LM_ERROR,
00426                             ACE_LIB_TEXT ("%s: short option requires ")
00427                             ACE_LIB_TEXT ("an argument -- %c\n"),
00428                             this->argv_[0], opt));
00429               opt = this->has_colon_ ? ':' : '?';
00430             }
00431           else
00432             // Use the next argv-element as the argument.
00433             this->optarg = this->argv_[this->optind++];
00434           this->nextchar_ = 0;
00435         }
00436     }
00437   return opt;
00438 }
00439 
00440 int
00441 ACE_Get_Opt::operator () (void)
00442 {
00443   ACE_TRACE ("ACE_Get_Opt_Long::operator");
00444 
00445   // First of all, make sure we reinitialize any pointers..
00446   this->optarg = 0;
00447   this->long_option_ = 0;
00448 
00449   if (this->argv_ == 0)
00450     {
00451       // It can happen, e.g., on VxWorks.
00452       this->optind = 0;
00453       return -1;
00454     }
00455 
00456   // We check this because we can string short options together if the
00457   // preceding one doesn't take an argument.
00458   if (this->nextchar_ == 0 || *this->nextchar_ == '\0')
00459     {
00460       int retval = this->nextchar_i ();
00461       if (retval != 0)
00462         return retval;
00463     }
00464 
00465   if (((this->argv_[this->optind][0] == '-')
00466        && (this->argv_[this->optind][1] == '-')) || this->long_only_)
00467     return this->long_option_i ();
00468 
00469   return this->short_option_i ();
00470 }
00471 
00472 int
00473 ACE_Get_Opt::long_option (const ACE_TCHAR *name,
00474                           OPTION_ARG_MODE has_arg)
00475 {
00476   ACE_TRACE ("ACE_Get_Opt::long_option (const ACE_TCHAR *name, OPTION_ARG_MODE has_arg)");
00477   return this->long_option (name, 0, has_arg);
00478 }
00479 
00480 int
00481 ACE_Get_Opt::long_option (const ACE_TCHAR *name,
00482                           int short_option,
00483                           OPTION_ARG_MODE has_arg)
00484 {
00485   ACE_TRACE ("ACE_Get_Opt::long_option (const ACE_TCHAR *name, int short_option, OPTION_ARG_MODE has_arg)");
00486 
00487   // We only allow valid alpha-numeric characters as short options.
00488   // If short_options is not a valid alpha-numeric, we can still return it
00489   // when the long option is found, but won't allow the caller to pass it on
00490   // the command line (how could they?).  The special case is 0, but since
00491   // we always return it, we let the caller worry about that.
00492 #if defined (_MSC_VER) && (_MSC_VER >= 1300)
00493   // For MSVC 7.x, we need to prevent "illegal" character getting into
00494   // isalnum, otherwise, it will crash the program.
00495   if (short_option > 0 &&
00496       short_option < 256 &&
00497       ACE_OS::ace_isalnum (static_cast<char> (short_option)) != 0)
00498 #else
00499   if (ACE_OS::ace_isalnum (short_option) != 0)
00500 #endif /* _MSC_VER && _MSC_VER >= 1300 */
00501     {
00502       // If the short_option already exists, make sure it matches, otherwise
00503       // add it.
00504       ACE_TCHAR *s = 0;
00505       if ((s = const_cast<ACE_TCHAR*> (
00506                  ACE_OS::strchr (this->optstring_->c_str (),
00507                                  short_option))) != 0)
00508         {
00509           // Short option exists, so verify the argument options
00510           if (s[1] == ':')
00511             {
00512               if (s[2] == ':')
00513                 {
00514                   if (has_arg != ARG_OPTIONAL)
00515                     {
00516                       if (this->opterr)
00517                         ACE_ERROR
00518                           ((LM_ERROR,
00519                             ACE_LIB_TEXT ("Existing short option '%c' takes ")
00520                             ACE_LIB_TEXT ("optional argument; adding %s ")
00521                             ACE_LIB_TEXT ("requires ARG_OPTIONAL\n"),
00522                             short_option, name));
00523                       return -1;
00524                     }
00525                 }
00526               else
00527                 if (has_arg != ARG_REQUIRED)
00528                   {
00529                     if (this->opterr)
00530                       ACE_ERROR
00531                         ((LM_ERROR,
00532                           ACE_LIB_TEXT ("Existing short option '%c' requires ")
00533                           ACE_LIB_TEXT ("an argument; adding %s ")
00534                           ACE_LIB_TEXT ("requires ARG_REQUIRED\n"),
00535                           short_option, name));
00536                     return -1;
00537                   }
00538             }
00539           else if (has_arg != NO_ARG)
00540             {
00541               if (this->opterr)
00542                 ACE_ERROR
00543                   ((LM_ERROR,
00544                     ACE_LIB_TEXT ("Existing short option '%c' does not ")
00545                     ACE_LIB_TEXT ("accept an argument; adding %s ")
00546                     ACE_LIB_TEXT ("requires NO_ARG\n"),
00547                     short_option, name));
00548               return -1;
00549             }
00550         }
00551       else
00552         {
00553           // Didn't find short option, so add it...
00554           *this->optstring_ += (ACE_TCHAR) short_option;
00555           if (has_arg == ARG_REQUIRED)
00556             *this->optstring_ += ACE_LIB_TEXT (":");
00557           else if (has_arg == ARG_OPTIONAL)
00558             *this->optstring_ += ACE_LIB_TEXT ("::");
00559         }
00560     }
00561 
00562   ACE_Get_Opt_Long_Option *option =
00563     new ACE_Get_Opt_Long_Option (name, has_arg, short_option);
00564 
00565   if (!option)
00566     return -1;
00567 
00568   // Add to array
00569   size_t size = this->long_opts_.size ();
00570   if (this->long_opts_.size (size + 1) != 0
00571       || this->long_opts_.set (option, size) != 0)
00572     {
00573       delete option;
00574       ACE_ERROR_RETURN
00575         ((LM_ERROR, ACE_LIB_TEXT ("Could not add long option to array.\n")),
00576          -1);
00577     }
00578   return 0;
00579 }
00580 
00581 const ACE_TCHAR*
00582 ACE_Get_Opt::long_option (void) const
00583 {
00584   ACE_TRACE ("ACE_Get_Opt::long_option (void)");
00585   if (this->long_option_)
00586     return this->long_option_->name_;
00587   return 0;
00588 }
00589 
00590 const ACE_TCHAR*
00591 ACE_Get_Opt::last_option (void) const
00592 {
00593   return this->last_option_->c_str ();
00594 }
00595 
00596 void
00597 ACE_Get_Opt::last_option (const ACE_TString &last_option)
00598 {
00599   *this->last_option_ = last_option;
00600 }
00601 
00602 void
00603 ACE_Get_Opt::dump (void) const
00604 {
00605 #if defined (ACE_HAS_DUMP)
00606   ACE_TRACE ("ACE_Get_Opt::dump");
00607 
00608   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00609   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\n")
00610               ACE_LIB_TEXT ("opstring_ = %s\n")
00611               ACE_LIB_TEXT ("long_only_ = %d\n")
00612               ACE_LIB_TEXT ("has_colon_ = %d\n")
00613               ACE_LIB_TEXT ("last_option_ = %s\n")
00614               ACE_LIB_TEXT ("nextchar_ = %s\n")
00615               ACE_LIB_TEXT ("optopt_ = %c\n")
00616               ACE_LIB_TEXT ("ordering_ = %d\n"),
00617               this->optstring_->c_str (),
00618               this->long_only_,
00619               this->has_colon_,
00620               this->last_option_->c_str (),
00621               this->nextchar_,
00622               this->optopt_,
00623               this->ordering_));
00624 
00625   // now loop through the
00626   size_t size = this->long_opts_.size ();
00627   for (u_int i = 0; i < size ; ++i)
00628     {
00629       ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\n")
00630                   ACE_LIB_TEXT ("long_option name_ = %s\n")
00631                   ACE_LIB_TEXT ("has_arg_ = %d\n")
00632                   ACE_LIB_TEXT ("val_ = %d\n"),
00633                   this->long_opts_[i]->name_,
00634                   this->long_opts_[i]->has_arg_,
00635                   this->long_opts_[i]->val_));
00636     }
00637   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00638 #endif /* ACE_HAS_DUMP */
00639 }
00640 
00641 void
00642 ACE_Get_Opt::permute_args (void)
00643 {
00644   ACE_TRACE ("ACE_Get_Opt::permute_args");
00645 
00646   u_long cyclelen, i, j, ncycle, nnonopts, nopts;
00647   u_long opt_end = this->optind;
00648   int cstart, pos = 0;
00649   ACE_TCHAR *swap = 0;
00650 
00651   nnonopts = this->nonopt_end_ - this->nonopt_start_;
00652   nopts = opt_end - this->nonopt_end_;
00653   ncycle = ACE::gcd (nnonopts, nopts);
00654   cyclelen = (opt_end - this->nonopt_start_) / ncycle;
00655 
00656   this->optind = this->optind - nnonopts;
00657 
00658   for (i = 0; i < ncycle; i++)
00659     {
00660       cstart = this->nonopt_end_ + i;
00661       pos = cstart;
00662       for (j = 0; j < cyclelen; j++)
00663         {
00664           if (pos >= this->nonopt_end_)
00665             pos -= nnonopts;
00666           else
00667             pos += nopts;
00668           swap = this->argv_[pos];
00669 
00670           ((ACE_TCHAR **)this->argv_)[pos] = argv_[cstart];
00671 
00672           ((ACE_TCHAR **)this->argv_)[cstart] = swap;
00673         }
00674     }
00675 }
00676 
00677 int
00678 ACE_Get_Opt::permute (void)
00679 {
00680   ACE_TRACE ("ACE_Get_Opt::permute");
00681 
00682   if (this->nonopt_start_ != this->nonopt_end_
00683       && this->nonopt_start_ != this->optind)
00684     this->permute_args ();
00685 
00686   this->nonopt_start_ = this->optind;
00687 
00688   // Skip over args untill we find the next option.
00689   while (this->optind < this->argc_
00690          && (this->argv_[this->optind][0] != '-'
00691              || this->argv_[this->optind][1] == '\0'))
00692     this->optind++;
00693 
00694   // Got an option, so mark this as the end of the non options.
00695   this->nonopt_end_ = this->optind;
00696 
00697   if (this->optind != this->argc_
00698       && ACE_OS::strcmp (this->argv_[this->optind],
00699                          ACE_LIB_TEXT ("--")) == 0)
00700     {
00701       // We found the marker for the end of the options.
00702       this->optind++;
00703 
00704       if (this->nonopt_start_ != this->nonopt_end_
00705           && this->nonopt_end_ != this->optind)
00706         this->permute_args ();
00707     }
00708 
00709   if (this->optind == this->argc_)
00710     {
00711       if (this->nonopt_start_ != this->nonopt_end_)
00712         this->optind = this->nonopt_start_;
00713       return EOF;
00714     }
00715   return 0;
00716 }
00717 
00718 const ACE_TCHAR *
00719 ACE_Get_Opt::optstring (void) const
00720 {
00721   return this->optstring_->c_str ();
00722 }
00723 
00724 ACE_Get_Opt::ACE_Get_Opt_Long_Option::ACE_Get_Opt_Long_Option (
00725   const ACE_TCHAR *name,
00726   int has_arg,
00727   int val)
00728   :  name_ (ACE::strnew (name)),
00729      has_arg_ (has_arg),
00730      val_ (val)
00731 {}
00732 
00733 ACE_Get_Opt::ACE_Get_Opt_Long_Option::~ACE_Get_Opt_Long_Option (void)
00734 {
00735   delete [] this->name_;
00736 }
00737 
00738 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Thu Nov 9 09:41:51 2006 for ACE by doxygen 1.3.6