Get_Opt.cpp

Go to the documentation of this file.
00001 // $Id: Get_Opt.cpp 80826 2008-03-04 14:51:23Z wotte $
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            "$Id: Get_Opt.cpp 80826 2008-03-04 14:51:23Z wotte $")
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_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_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_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_TEXT ("%s: long option `--%s' doesn't allow ")
00311                       ACE_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_TEXT ("%s: long option '--%s' requires ")
00331                             ACE_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_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_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_TEXT ("%s: short option requires ")
00427                             ACE_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 (ACE_OS::ace_isalnum (short_option) != 0)
00493     {
00494       // If the short_option already exists, make sure it matches, otherwise
00495       // add it.
00496       ACE_TCHAR *s = 0;
00497       if ((s = const_cast<ACE_TCHAR*> (
00498                  ACE_OS::strchr (this->optstring_->c_str (),
00499                                  short_option))) != 0)
00500         {
00501           // Short option exists, so verify the argument options
00502           if (s[1] == ':')
00503             {
00504               if (s[2] == ':')
00505                 {
00506                   if (has_arg != ARG_OPTIONAL)
00507                     {
00508                       if (this->opterr)
00509                         ACE_ERROR
00510                           ((LM_ERROR,
00511                             ACE_TEXT ("Existing short option '%c' takes ")
00512                             ACE_TEXT ("optional argument; adding %s ")
00513                             ACE_TEXT ("requires ARG_OPTIONAL\n"),
00514                             short_option, name));
00515                       return -1;
00516                     }
00517                 }
00518               else
00519                 if (has_arg != ARG_REQUIRED)
00520                   {
00521                     if (this->opterr)
00522                       ACE_ERROR
00523                         ((LM_ERROR,
00524                           ACE_TEXT ("Existing short option '%c' requires ")
00525                           ACE_TEXT ("an argument; adding %s ")
00526                           ACE_TEXT ("requires ARG_REQUIRED\n"),
00527                           short_option, name));
00528                     return -1;
00529                   }
00530             }
00531           else if (has_arg != NO_ARG)
00532             {
00533               if (this->opterr)
00534                 ACE_ERROR
00535                   ((LM_ERROR,
00536                     ACE_TEXT ("Existing short option '%c' does not ")
00537                     ACE_TEXT ("accept an argument; adding %s ")
00538                     ACE_TEXT ("requires NO_ARG\n"),
00539                     short_option, name));
00540               return -1;
00541             }
00542         }
00543       else
00544         {
00545           // Didn't find short option, so add it...
00546           *this->optstring_ += (ACE_TCHAR) short_option;
00547           if (has_arg == ARG_REQUIRED)
00548             *this->optstring_ += ACE_TEXT (":");
00549           else if (has_arg == ARG_OPTIONAL)
00550             *this->optstring_ += ACE_TEXT ("::");
00551         }
00552     }
00553 
00554   ACE_Get_Opt_Long_Option *option =
00555     new ACE_Get_Opt_Long_Option (name, has_arg, short_option);
00556 
00557   if (!option)
00558     return -1;
00559 
00560   // Add to array
00561   size_t size = this->long_opts_.size ();
00562   if (this->long_opts_.size (size + 1) != 0
00563       || this->long_opts_.set (option, size) != 0)
00564     {
00565       delete option;
00566       ACE_ERROR_RETURN
00567         ((LM_ERROR, ACE_TEXT ("Could not add long option to array.\n")),
00568          -1);
00569     }
00570   return 0;
00571 }
00572 
00573 const ACE_TCHAR*
00574 ACE_Get_Opt::long_option (void) const
00575 {
00576   ACE_TRACE ("ACE_Get_Opt::long_option (void)");
00577   if (this->long_option_)
00578     return this->long_option_->name_;
00579   return 0;
00580 }
00581 
00582 const ACE_TCHAR*
00583 ACE_Get_Opt::last_option (void) const
00584 {
00585   return this->last_option_->c_str ();
00586 }
00587 
00588 void
00589 ACE_Get_Opt::last_option (const ACE_TString &last_option)
00590 {
00591   *this->last_option_ = last_option;
00592 }
00593 
00594 void
00595 ACE_Get_Opt::dump (void) const
00596 {
00597 #if defined (ACE_HAS_DUMP)
00598   ACE_TRACE ("ACE_Get_Opt::dump");
00599 
00600   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00601   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n")
00602               ACE_TEXT ("opstring_ = %s\n")
00603               ACE_TEXT ("long_only_ = %d\n")
00604               ACE_TEXT ("has_colon_ = %d\n")
00605               ACE_TEXT ("last_option_ = %s\n")
00606               ACE_TEXT ("nextchar_ = %s\n")
00607               ACE_TEXT ("optopt_ = %c\n")
00608               ACE_TEXT ("ordering_ = %d\n"),
00609               this->optstring_->c_str (),
00610               this->long_only_,
00611               this->has_colon_,
00612               this->last_option_->c_str (),
00613               this->nextchar_,
00614               this->optopt_,
00615               this->ordering_));
00616 
00617   // now loop through the
00618   size_t size = this->long_opts_.size ();
00619   for (u_int i = 0; i < size ; ++i)
00620     {
00621       ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n")
00622                   ACE_TEXT ("long_option name_ = %s\n")
00623                   ACE_TEXT ("has_arg_ = %d\n")
00624                   ACE_TEXT ("val_ = %d\n"),
00625                   this->long_opts_[i]->name_,
00626                   this->long_opts_[i]->has_arg_,
00627                   this->long_opts_[i]->val_));
00628     }
00629   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00630 #endif /* ACE_HAS_DUMP */
00631 }
00632 
00633 void
00634 ACE_Get_Opt::permute_args (void)
00635 {
00636   ACE_TRACE ("ACE_Get_Opt::permute_args");
00637 
00638   u_long cyclelen, i, j, ncycle, nnonopts, nopts;
00639   u_long opt_end = this->optind;
00640   int cstart, pos = 0;
00641   ACE_TCHAR *swap = 0;
00642 
00643   nnonopts = this->nonopt_end_ - this->nonopt_start_;
00644   nopts = opt_end - this->nonopt_end_;
00645   ncycle = ACE::gcd (nnonopts, nopts);
00646   cyclelen = (opt_end - this->nonopt_start_) / ncycle;
00647 
00648   this->optind = this->optind - nnonopts;
00649 
00650   for (i = 0; i < ncycle; i++)
00651     {
00652       cstart = this->nonopt_end_ + i;
00653       pos = cstart;
00654       for (j = 0; j < cyclelen; j++)
00655         {
00656           if (pos >= this->nonopt_end_)
00657             pos -= nnonopts;
00658           else
00659             pos += nopts;
00660           swap = this->argv_[pos];
00661 
00662           ((ACE_TCHAR **)this->argv_)[pos] = argv_[cstart];
00663 
00664           ((ACE_TCHAR **)this->argv_)[cstart] = swap;
00665         }
00666     }
00667 }
00668 
00669 int
00670 ACE_Get_Opt::permute (void)
00671 {
00672   ACE_TRACE ("ACE_Get_Opt::permute");
00673 
00674   if (this->nonopt_start_ != this->nonopt_end_
00675       && this->nonopt_start_ != this->optind)
00676     this->permute_args ();
00677 
00678   this->nonopt_start_ = this->optind;
00679 
00680   // Skip over args untill we find the next option.
00681   while (this->optind < this->argc_
00682          && (this->argv_[this->optind][0] != '-'
00683              || this->argv_[this->optind][1] == '\0'))
00684     this->optind++;
00685 
00686   // Got an option, so mark this as the end of the non options.
00687   this->nonopt_end_ = this->optind;
00688 
00689   if (this->optind != this->argc_
00690       && ACE_OS::strcmp (this->argv_[this->optind],
00691                          ACE_TEXT ("--")) == 0)
00692     {
00693       // We found the marker for the end of the options.
00694       ++this->optind;
00695 
00696       if (this->nonopt_start_ != this->nonopt_end_
00697           && this->nonopt_end_ != this->optind)
00698         this->permute_args ();
00699     }
00700 
00701   if (this->optind == this->argc_)
00702     {
00703       if (this->nonopt_start_ != this->nonopt_end_)
00704         this->optind = this->nonopt_start_;
00705       return EOF;
00706     }
00707   return 0;
00708 }
00709 
00710 const ACE_TCHAR *
00711 ACE_Get_Opt::optstring (void) const
00712 {
00713   return this->optstring_->c_str ();
00714 }
00715 
00716 ACE_Get_Opt::ACE_Get_Opt_Long_Option::ACE_Get_Opt_Long_Option (
00717   const ACE_TCHAR *name,
00718   int has_arg,
00719   int val)
00720   :  name_ (ACE::strnew (name)),
00721      has_arg_ (has_arg),
00722      val_ (val)
00723 {}
00724 
00725 ACE_Get_Opt::ACE_Get_Opt_Long_Option::~ACE_Get_Opt_Long_Option (void)
00726 {
00727   delete [] this->name_;
00728 }
00729 
00730 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:18:39 2010 for ACE by  doxygen 1.4.7