ARGV.cpp

Go to the documentation of this file.
00001 // $Id: ARGV.cpp 81374 2008-04-16 13:07:47Z iliyan $
00002 
00003 #ifndef ACE_ARGV_CPP
00004 #define ACE_ARGV_CPP
00005 
00006 #include "ace/Log_Msg.h"
00007 #include "ace/OS_NS_unistd.h"
00008 #include "ace/OS_NS_string.h"
00009 #include "ace/OS_Memory.h"
00010 
00011 #if !defined (__ACE_INLINE__)
00012 #include "ace/ARGV.inl"
00013 #endif /* __ACE_INLINE__ */
00014 
00015 ACE_RCSID(ace, ARGV, "$Id: ARGV.cpp 81374 2008-04-16 13:07:47Z iliyan $")
00016 
00017 // Open versioned namespace, if enabled by the user.
00018 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00019 
00020 ACE_ALLOC_HOOK_DEFINE (ACE_ARGV_Queue_Entry)
00021 ACE_ALLOC_HOOK_DEFINE (ACE_ARGV)
00022 
00023 template <typename CHAR_TYPE>
00024 void
00025 ACE_ARGV_Queue_Entry_T<CHAR_TYPE>::dump (void) const
00026 {
00027 #if defined (ACE_HAS_DUMP)
00028   ACE_TRACE ("ACE_ARGV_Queue_Entry_T::dump");
00029 
00030   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00031   ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("arg_ = %s"), this->arg_));
00032   ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("quote_arg_ = %d"), (int)this->quote_arg_));
00033   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00034 #endif /* ACE_HAS_DUMP */
00035 }
00036 
00037 template <typename CHAR_TYPE>
00038 void
00039 ACE_ARGV_T<CHAR_TYPE>::dump (void) const
00040 {
00041 #if defined (ACE_HAS_DUMP)
00042   ACE_TRACE ("ACE_ARGV_T::dump");
00043 
00044   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00045   ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("argc_ = %d"), this->argc_));
00046 
00047   ACE_ARGV *this_obj = const_cast<ACE_ARGV *> (this);
00048 
00049   for (int i = 0; i < this->argc_; i++)
00050     ACE_DEBUG ((LM_DEBUG,
00051                 ACE_TEXT ("\nargv_[%i] = %s"),
00052                 i,
00053                 this_obj->argv ()[i]));
00054 
00055   ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("\nbuf = %s\n"), this->buf_));
00056   ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("\n")));
00057   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00058 #endif /* ACE_HAS_DUMP */
00059 }
00060 
00061 // Creates this->argv_ out of this->buf_.  New memory is allocated for
00062 // each element of the array.  This is used by the array-to-string
00063 // style constructor and for creating this->argv_ when in iterative
00064 // mode.
00065 
00066 template <typename CHAR_TYPE>
00067 int
00068 ACE_ARGV_T<CHAR_TYPE>::string_to_argv (void)
00069 {
00070   ACE_TRACE ("ACE_ARGV_T::string_to_argv");
00071 
00072   return ACE_OS::string_to_argv (this->buf_,
00073                                  this->argc_,
00074                                  this->argv_,
00075                                  this->substitute_env_args_);
00076 }
00077 
00078 template <typename CHAR_TYPE>
00079 ACE_ARGV_T<CHAR_TYPE>::ACE_ARGV_T (const CHAR_TYPE buf[],
00080                                    bool substitute_env_args)
00081   : substitute_env_args_ (substitute_env_args),
00082     iterative_ (false),
00083     argc_ (0),
00084     argv_ (0),
00085     buf_ (0),
00086     length_ (0),
00087     queue_ ()
00088 {
00089   ACE_TRACE ("ACE_ARGV_T::ACE_ARGV_T CHAR_TYPE[] to CHAR_TYPE *[]");
00090 
00091   if (buf == 0 || buf[0] == 0)
00092     return;
00093 
00094   // Make an internal copy of the string.
00095   ACE_NEW (this->buf_,
00096            CHAR_TYPE[ACE_OS::strlen (buf) + 1]);
00097   ACE_OS::strcpy (this->buf_, buf);
00098 
00099   // Create this->argv_.
00100   if (this->string_to_argv () == -1)
00101     ACE_ERROR ((LM_ERROR,
00102                 ACE_TEXT ("%p\n"),
00103                 ACE_TEXT ("string_to_argv")));
00104 }
00105 
00106 template <typename CHAR_TYPE>
00107 ACE_ARGV_T<CHAR_TYPE>::ACE_ARGV_T (CHAR_TYPE *argv[],
00108                                    bool substitute_env_args,
00109                                    bool quote_arg)
00110   : substitute_env_args_ (substitute_env_args),
00111     iterative_ (false),
00112     argc_ (0),
00113     argv_ (0),
00114     buf_ (0),
00115     length_ (0),
00116     queue_ ()
00117 {
00118   ACE_TRACE ("ACE_ARGV_T::ACE_ARGV_T CHAR_TYPE*[] to CHAR_TYPE[]");
00119 
00120   if (argv == 0 || argv[0] == 0)
00121     return;
00122 
00123   this->argc_ = ACE_OS::argv_to_string (argv,
00124                                         this->buf_,
00125                                         substitute_env_args,
00126                                         quote_arg);
00127 }
00128 
00129 template <typename CHAR_TYPE>
00130 ACE_ARGV_T<CHAR_TYPE>::ACE_ARGV_T (int argc,
00131                                    CHAR_TYPE *argv[],
00132                                    bool substitute_env_args,
00133                                    bool quote_arg)
00134   : substitute_env_args_ (substitute_env_args),
00135     iterative_ (false),
00136     argc_ (0),
00137     argv_ (0),
00138     buf_ (0),
00139     length_ (0),
00140     queue_ ()
00141 {
00142   ACE_TRACE ("ACE_ARGV_T::ACE_ARGV_T int,CHAR_TYPE*[] to CHAR_TYPE[]");
00143 
00144   this->argc_ = ACE_OS::argv_to_string (argc,
00145                                         argv,
00146                                         this->buf_,
00147                                         substitute_env_args,
00148                                         quote_arg);
00149 }
00150 
00151 
00152 template <typename CHAR_TYPE>
00153 ACE_ARGV_T<CHAR_TYPE>::ACE_ARGV_T (CHAR_TYPE *first_argv[],
00154                                    CHAR_TYPE *second_argv[],
00155                                    bool substitute_env_args,
00156                                    bool quote_args)
00157   : substitute_env_args_ (substitute_env_args),
00158     iterative_ (false),
00159     argc_ (0),
00160     argv_ (0),
00161     buf_ (0),
00162     length_ (0),
00163     queue_ ()
00164 {
00165   ACE_TRACE ("ACE_ARGV_T::ACE_ARGV_T CHAR_TYPE*[] + CHAR_TYPE *[] to CHAR_TYPE[]");
00166 
00167   int first_argc = 0;
00168   int second_argc = 0;
00169 
00170   CHAR_TYPE *first_buf = 0;
00171   CHAR_TYPE *second_buf = 0;
00172 
00173   // convert the first argv to a string
00174   if (first_argv != 0 && first_argv[0] != 0)
00175     {
00176       first_argc = ACE_OS::argv_to_string (first_argv,
00177                                            first_buf,
00178                                            substitute_env_args,
00179                                            quote_args);
00180     }
00181 
00182   // convert the second argv to a string
00183   if (second_argv != 0 && second_argv[0] != 0)
00184     {
00185       second_argc = ACE_OS::argv_to_string (second_argv,
00186                                             second_buf,
00187                                             substitute_env_args,
00188                                             quote_args);
00189     }
00190 
00191   // Add the number of arguments in both the argvs.
00192   this->argc_ = first_argc + second_argc;
00193 
00194   size_t buf_len =
00195     ACE_OS::strlen (first_buf) + ACE_OS::strlen (second_buf) + 1;
00196 
00197   // Allocate memory to the lenght of the combined argv string.
00198   ACE_NEW (this->buf_,
00199            CHAR_TYPE[buf_len + 1]);
00200 
00201   // copy the first argv string to the buffer
00202   ACE_OS::strcpy (this->buf_, first_buf);
00203 
00204   // concatenate the second argv string to the buffer
00205   ACE_OS::strcat (this->buf_, second_buf);
00206 
00207   //   Delete the first and second buffers
00208   delete [] first_buf;
00209   delete [] second_buf;
00210 }
00211 
00212 template <typename CHAR_TYPE>
00213 ACE_ARGV_T<CHAR_TYPE>::ACE_ARGV_T (bool substitute_env_args)
00214   : substitute_env_args_ (substitute_env_args),
00215     iterative_ (true),
00216     argc_ (0),
00217     argv_ (0),
00218     buf_ (0),
00219     length_ (0),
00220     queue_ ()
00221 {
00222   ACE_TRACE ("ACE_ARGV_T::ACE_ARGV_T Iterative");
00223 
00224   // Nothing to do yet -- the user puts in arguments via add ()
00225 }
00226 
00227 template <typename CHAR_TYPE>
00228 int
00229 ACE_ARGV_T<CHAR_TYPE>::add (const CHAR_TYPE *next_arg, bool quote_arg)
00230 {
00231   // Only allow this to work in the "iterative" verion -- the
00232   // ACE_ARGVs created with the one argument constructor.
00233   if (!this->iterative_)
00234     {
00235       errno = EINVAL;
00236       return -1;
00237     }
00238 
00239   this->length_ += ACE_OS::strlen (next_arg);
00240   if (quote_arg && ACE_OS::strchr (next_arg, ' ') != 0)
00241     {
00242       this->length_ += 2;
00243       if (ACE_OS::strchr (next_arg, '"') != 0)
00244         for (const CHAR_TYPE * p = next_arg; *p != '\0'; ++p)
00245           if (*p == '"') ++this->length_;
00246     }
00247   else
00248     {
00249       quote_arg = false;
00250     }
00251 
00252   // Put the new argument at the end of the queue.
00253   if (this->queue_.enqueue_tail (ACE_ARGV_Queue_Entry_T<CHAR_TYPE> (next_arg, quote_arg)) == -1)
00254     ACE_ERROR_RETURN ((LM_ERROR,
00255                        ACE_TEXT ("Can't add more to ARGV queue")),
00256                       -1);
00257 
00258   ++this->argc_;
00259 
00260   // Wipe argv_ and buf_ away so that they will be recreated if the
00261   // user calls argv () or buf ().
00262   if (this->argv_ != 0)
00263     {
00264       for (int i = 0; this->argv_[i] != 0; i++)
00265         ACE_OS::free ((void *) this->argv_[i]);
00266 
00267       delete [] this->argv_;
00268       this->argv_ = 0;
00269     }
00270 
00271   delete [] this->buf_;
00272   this->buf_ = 0;
00273 
00274   return 0;
00275 }
00276 
00277 template <typename CHAR_TYPE>
00278 int
00279 ACE_ARGV_T<CHAR_TYPE>::add (CHAR_TYPE *argv[], bool quote_args)
00280 {
00281   for (int i = 0; argv[i] != 0; i++)
00282     if (this->add (argv[i], quote_args) == -1)
00283       return -1;
00284 
00285   return 0;
00286 }
00287 
00288 // Free up argv_ and buf_
00289 
00290 template <typename CHAR_TYPE>
00291 ACE_ARGV_T<CHAR_TYPE>::~ACE_ARGV_T (void)
00292 {
00293   ACE_TRACE ("ACE_ARGV_T::~ACE_ARGV_T");
00294 
00295   if (this->argv_ != 0)
00296     for (int i = 0; this->argv_[i] != 0; i++)
00297       ACE_OS::free ((void *) this->argv_[i]);
00298 
00299   delete [] this->argv_;
00300   delete [] this->buf_;
00301 }
00302 
00303 // Create buf_ out of the queue_.  This is only used in the
00304 // "iterative" mode.
00305 
00306 template <typename CHAR_TYPE>
00307 int
00308 ACE_ARGV_T<CHAR_TYPE>::create_buf_from_queue (void)
00309 {
00310   ACE_TRACE ("ACE_ARGV_T::create_buf_from_queue");
00311 
00312   // If the are no arguments, don't do anything
00313   if (this->argc_ <= 0)
00314     return -1;
00315 
00316   delete [] this->buf_;
00317 
00318   ACE_NEW_RETURN (this->buf_,
00319                   CHAR_TYPE[this->length_ + this->argc_],
00320                   -1);
00321 
00322   // Get an iterator over the queue
00323   ACE_Unbounded_Queue_Iterator<ACE_ARGV_Queue_Entry_T<CHAR_TYPE> > iter (this->queue_);
00324 
00325   ACE_ARGV_Queue_Entry_T<CHAR_TYPE> *arg = 0;
00326   CHAR_TYPE *ptr = this->buf_;
00327   size_t len;
00328 
00329   while (!iter.done ())
00330     {
00331       // Get next argument from the queue.
00332       iter.next (arg);
00333       iter.advance ();
00334 
00335       if (arg->quote_arg_)
00336         {
00337           *ptr++ = '"';
00338           if (ACE_OS::strchr (arg->arg_, '"') != 0)
00339             {
00340               CHAR_TYPE prev = 0;
00341               for (const CHAR_TYPE * p = arg->arg_; *p != '\0'; ++p)
00342                 {
00343                   if (*p == '"' && prev != '\\') *ptr++ = '\\';
00344                   prev = *ptr++ = *p;
00345                 }
00346             }
00347           else
00348             {
00349               len = ACE_OS::strlen (arg->arg_);
00350               // Copy the argument into buf_
00351               ACE_OS::memcpy ((void *) ptr,
00352                               (const void *) (arg->arg_),
00353                               len * sizeof (CHAR_TYPE));
00354               // Move the pointer down.
00355               ptr += len;
00356             }
00357           *ptr++ = '"';
00358         }
00359       else
00360         {
00361           len = ACE_OS::strlen (arg->arg_);
00362           // Copy the argument into buf_
00363           ACE_OS::memcpy ((void *) ptr,
00364                           (const void *) (arg->arg_),
00365                           len * sizeof (CHAR_TYPE));
00366           // Move the pointer down.
00367           ptr += len;
00368         }
00369 
00370       // Put in an argument separating space.
00371       *ptr++ = ' ';
00372     }
00373 
00374   // Put in the NUL terminator
00375   ptr[-1] = '\0';
00376 
00377   return 0;
00378 }
00379 
00380 // Close versioned namespace, if enabled by the user.
00381 ACE_END_VERSIONED_NAMESPACE_DECL
00382 
00383 #endif /* ACE_ARGV_CPP */

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