ARGV.cpp

Go to the documentation of this file.
00001 // $Id: ARGV.cpp 79134 2007-07-31 18:23:50Z johnnyw $
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 79134 2007-07-31 18:23:50Z johnnyw $")
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 (CHAR_TYPE *first_argv[],
00131                                    CHAR_TYPE *second_argv[],
00132                                    bool substitute_env_args,
00133                                    bool quote_args)
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 CHAR_TYPE*[] + CHAR_TYPE *[] to CHAR_TYPE[]");
00143 
00144   int first_argc = 0;
00145   int second_argc = 0;
00146 
00147   CHAR_TYPE *first_buf = 0;
00148   CHAR_TYPE *second_buf = 0;
00149 
00150   // convert the first argv to a string
00151   if (first_argv != 0 && first_argv[0] != 0)
00152     {
00153       first_argc = ACE_OS::argv_to_string (first_argv,
00154                                            first_buf,
00155                                            substitute_env_args,
00156                                            quote_args);
00157     }
00158 
00159   // convert the second argv to a string
00160   if (second_argv != 0 && second_argv[0] != 0)
00161     {
00162       second_argc = ACE_OS::argv_to_string (second_argv,
00163                                             second_buf,
00164                                             substitute_env_args,
00165                                             quote_args);
00166     }
00167 
00168   // Add the number of arguments in both the argvs.
00169   this->argc_ = first_argc + second_argc;
00170 
00171   size_t buf_len =
00172     ACE_OS::strlen (first_buf) + ACE_OS::strlen (second_buf) + 1;
00173 
00174   // Allocate memory to the lenght of the combined argv string.
00175   ACE_NEW (this->buf_,
00176            CHAR_TYPE[buf_len + 1]);
00177 
00178   // copy the first argv string to the buffer
00179   ACE_OS::strcpy (this->buf_, first_buf);
00180 
00181   // concatenate the second argv string to the buffer
00182   ACE_OS::strcat (this->buf_, second_buf);
00183 
00184   //   Delete the first and second buffers
00185   delete [] first_buf;
00186   delete [] second_buf;
00187 }
00188 
00189 template <typename CHAR_TYPE>
00190 ACE_ARGV_T<CHAR_TYPE>::ACE_ARGV_T (bool substitute_env_args)
00191   : substitute_env_args_ (substitute_env_args),
00192     iterative_ (true),
00193     argc_ (0),
00194     argv_ (0),
00195     buf_ (0),
00196     length_ (0),
00197     queue_ ()
00198 {
00199   ACE_TRACE ("ACE_ARGV_T::ACE_ARGV_T Iterative");
00200 
00201   // Nothing to do yet -- the user puts in arguments via add ()
00202 }
00203 
00204 template <typename CHAR_TYPE>
00205 int
00206 ACE_ARGV_T<CHAR_TYPE>::add (const CHAR_TYPE *next_arg, bool quote_arg)
00207 {
00208   // Only allow this to work in the "iterative" verion -- the
00209   // ACE_ARGVs created with the one argument constructor.
00210   if (!this->iterative_)
00211     {
00212       errno = EINVAL;
00213       return -1;
00214     }
00215 
00216   this->length_ += ACE_OS::strlen (next_arg);
00217   if (quote_arg && ACE_OS::strchr (next_arg, ' ') != 0)
00218     {
00219       this->length_ += 2;
00220       if (ACE_OS::strchr (next_arg, '"') != 0)
00221         for (const CHAR_TYPE * p = next_arg; *p != '\0'; ++p)
00222           if (*p == '"') ++this->length_;
00223     }
00224   else
00225     {
00226       quote_arg = false;
00227     }
00228 
00229   // Put the new argument at the end of the queue.
00230   if (this->queue_.enqueue_tail (ACE_ARGV_Queue_Entry_T<CHAR_TYPE> (next_arg, quote_arg)) == -1)
00231     ACE_ERROR_RETURN ((LM_ERROR,
00232                        ACE_TEXT ("Can't add more to ARGV queue")),
00233                       -1);
00234 
00235   ++this->argc_;
00236 
00237   // Wipe argv_ and buf_ away so that they will be recreated if the
00238   // user calls argv () or buf ().
00239   if (this->argv_ != 0)
00240     {
00241       for (int i = 0; this->argv_[i] != 0; i++)
00242         ACE_OS::free ((void *) this->argv_[i]);
00243 
00244       delete [] this->argv_;
00245       this->argv_ = 0;
00246     }
00247 
00248   delete [] this->buf_;
00249   this->buf_ = 0;
00250 
00251   return 0;
00252 }
00253 
00254 template <typename CHAR_TYPE>
00255 int
00256 ACE_ARGV_T<CHAR_TYPE>::add (CHAR_TYPE *argv[], bool quote_args)
00257 {
00258   for (int i = 0; argv[i] != 0; i++)
00259     if (this->add (argv[i], quote_args) == -1)
00260       return -1;
00261 
00262   return 0;
00263 }
00264 
00265 // Free up argv_ and buf_
00266 
00267 template <typename CHAR_TYPE>
00268 ACE_ARGV_T<CHAR_TYPE>::~ACE_ARGV_T (void)
00269 {
00270   ACE_TRACE ("ACE_ARGV_T::~ACE_ARGV_T");
00271 
00272   if (this->argv_ != 0)
00273     for (int i = 0; this->argv_[i] != 0; i++)
00274       ACE_OS::free ((void *) this->argv_[i]);
00275 
00276   delete [] this->argv_;
00277   delete [] this->buf_;
00278 }
00279 
00280 // Create buf_ out of the queue_.  This is only used in the
00281 // "iterative" mode.
00282 
00283 template <typename CHAR_TYPE>
00284 int
00285 ACE_ARGV_T<CHAR_TYPE>::create_buf_from_queue (void)
00286 {
00287   ACE_TRACE ("ACE_ARGV_T::create_buf_from_queue");
00288 
00289   // If the are no arguments, don't do anything
00290   if (this->argc_ <= 0)
00291     return -1;
00292 
00293   delete [] this->buf_;
00294 
00295   ACE_NEW_RETURN (this->buf_,
00296                   CHAR_TYPE[this->length_ + this->argc_],
00297                   -1);
00298 
00299   // Get an iterator over the queue
00300   ACE_Unbounded_Queue_Iterator<ACE_ARGV_Queue_Entry_T<CHAR_TYPE> > iter (this->queue_);
00301 
00302   ACE_ARGV_Queue_Entry_T<CHAR_TYPE> *arg = 0;
00303   CHAR_TYPE *ptr = this->buf_;
00304   size_t len;
00305 
00306   while (!iter.done ())
00307     {
00308       // Get next argument from the queue.
00309       iter.next (arg);
00310       iter.advance ();
00311 
00312       if (arg->quote_arg_)
00313         {
00314           *ptr++ = '"';
00315           if (ACE_OS::strchr (arg->arg_, '"') != 0)
00316             {
00317               for (const CHAR_TYPE * p = arg->arg_; *p != '\0'; ++p)
00318                 {
00319                   if (*p == '"') *ptr++ = '\\';
00320                   *ptr++ = *p;
00321                 }
00322             }
00323           else
00324             {
00325               len = ACE_OS::strlen (arg->arg_);
00326               // Copy the argument into buf_
00327               ACE_OS::memcpy ((void *) ptr,
00328                               (const void *) (arg->arg_),
00329                               len * sizeof (CHAR_TYPE));
00330               // Move the pointer down.
00331               ptr += len;
00332             }
00333           *ptr++ = '"';
00334         }
00335       else
00336         {
00337           len = ACE_OS::strlen (arg->arg_);
00338           // Copy the argument into buf_
00339           ACE_OS::memcpy ((void *) ptr,
00340                           (const void *) (arg->arg_),
00341                           len * sizeof (CHAR_TYPE));
00342           // Move the pointer down.
00343           ptr += len;
00344         }
00345 
00346       // Put in an argument separating space.
00347       *ptr++ = ' ';
00348     }
00349 
00350   // Put in the NUL terminator
00351   ptr[-1] = '\0';
00352 
00353   return 0;
00354 }
00355 
00356 // Close versioned namespace, if enabled by the user.
00357 ACE_END_VERSIONED_NAMESPACE_DECL
00358 
00359 #endif /* ACE_ARGV_CPP */

Generated on Sun Jan 27 12:05:20 2008 for ACE by doxygen 1.3.6