Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

ARGV.cpp

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

Generated on Mon Jun 16 11:19:03 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002