www.pudn.com > ACE-5.3 > ARGV.cpp, change:2002-08-27,size:8699b
// ARGV.cpp
// ARGV.cpp,v 4.37 2002/08/27 17:35:08 shuston Exp
// Transforms a string BUF into an ARGV-style vector of strings.
#include "ace/ARGV.h"
#include "ace/Log_Msg.h"
#if !defined (__ACE_INLINE__)
#include "ace/ARGV.i"
#endif /* __ACE_INLINE__ */
ACE_RCSID(ace, ARGV, "ARGV.cpp,v 4.37 2002/08/27 17:35:08 shuston Exp")
ACE_ALLOC_HOOK_DEFINE (ACE_ARGV)
void
ACE_ARGV::dump (void) const
{
ACE_TRACE ("ACE_ARGV::dump");
ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("argc_ = %d"), this->argc_));
ACE_ARGV *this_obj = ACE_const_cast (ACE_ARGV *, this);
for (int i = 0; i this->argc_; i++)
ACE_DEBUG ((LM_DEBUG,
ACE_LIB_TEXT ("\nargv_[%i] = %s"),
i,
this_obj->argv ()[i]));
ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nbuf = %s\n"), this->buf_));
ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\n")));
ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
}
// Creates this->argv_ out of this->buf_. New memory is allocated for
// each element of the array. This is used by the array-to-string
// style constructor and for creating this->argv_ when in iterative
// mode.
int
ACE_ARGV::string_to_argv (void)
{
ACE_TRACE ("ACE_ARGV::string_to_argv");
return ACE_OS::string_to_argv (this->buf_,
this->argc_,
this->argv_,
this->substitute_env_args_);
}
int
ACE_ARGV::argv_to_string (ACE_TCHAR **argv, ACE_TCHAR *&buf)
{
return ACE_OS::argv_to_string (argv, buf);
}
ACE_ARGV::ACE_ARGV (const ACE_TCHAR buf[],
int substitute_env_args)
: substitute_env_args_ (substitute_env_args),
state_ (TO_PTR_ARRAY),
argc_ (0),
argv_ (0),
buf_ (0),
length_ (0),
queue_ ()
{
ACE_TRACE ("ACE_ARGV::ACE_ARGV ACE_TCHAR[] to ACE_TCHAR *[]");
if (buf == 0 || buf[0] == 0)
return;
// Make an internal copy of the string.
ACE_NEW (this->buf_,
ACE_TCHAR[ACE_OS::strlen (buf) + 1]);
ACE_OS::strcpy (this->buf_, buf);
// Create this->argv_.
if (this->string_to_argv () == -1)
ACE_ERROR ((LM_ERROR,
ACE_LIB_TEXT ("%p\n"),
ACE_LIB_TEXT ("string_to_argv")));
}
ACE_ARGV::ACE_ARGV (ACE_TCHAR *argv[],
int substitute_env_args)
: substitute_env_args_ (substitute_env_args),
state_ (TO_STRING),
argc_ (0),
argv_ (0),
buf_ (0),
length_ (0),
queue_ ()
{
ACE_TRACE ("ACE_ARGV::ACE_ARGV ACE_TCHAR*[] to ACE_TCHAR[]");
if (argv == 0 || argv[0] == 0)
return;
size_t buf_len = 0;
// Determine the length of the buffer.
for (int i = 0; argv[i] != 0; i++)
{
#if !defined (ACE_LACKS_ENV)
ACE_TCHAR *temp = 0;
// Account for environment variables.
if (this->substitute_env_args_
&& (argv[i][0] == '$'
&& (temp = ACE_OS::getenv (&argv[i][1])) != 0))
buf_len += ACE_OS::strlen (temp);
else
#endif /* !ACE_LACKS_ENV */
buf_len += ACE_OS::strlen (argv[i]);
// Add one for the extra space between each string.
buf_len++;
}
// Step through all argv params and copy each one into buf; separate
// each param with white space.
ACE_NEW (this->buf_,
ACE_TCHAR[buf_len + 1]);
ACE_TCHAR *end = this->buf_;
int j;
for (j = 0; argv[j] != 0; j++)
{
#if !defined (ACE_LACKS_ENV)
ACE_TCHAR *temp = 0;
// Account for environment variables.
if (this->substitute_env_args_
&& (argv[j][0] == '$'
&& (temp = ACE_OS::getenv (&argv[j][1])) != 0))
end = ACE_OS::strecpy (end, temp);
else
#endif /* ACE_LACKS_ENV */
end = ACE_OS::strecpy (end, argv[j]);
// Replace the null char that strecpy copies with white space as
// a separator.
*(end - 1) = ACE_LIB_TEXT (' ');
}
// Remember how many arguments there are
this->argc_ = j;
// Null terminate the string.
*end = '\0';
}
ACE_ARGV::ACE_ARGV (ACE_TCHAR *first_argv[],
ACE_TCHAR *second_argv[],
int substitute_env_args)
: substitute_env_args_ (substitute_env_args),
state_ (TO_STRING),
argc_ (0),
argv_ (0),
buf_ (0),
length_ (0),
queue_ ()
{
ACE_TRACE ("ACE_ARGV::ACE_ARGV ACE_TCHAR*[] + ACE_TCHAR *[] to ACE_TCHAR[]");
int first_argc;
int second_argc;
ACE_TCHAR *first_buf;
ACE_TCHAR *second_buf;
// convert the first argv to a string
first_argc = this->argv_to_string (first_argv,first_buf);
// convert the second argv to a string
second_argc = this->argv_to_string (second_argv,second_buf);
// Add the number of arguments in both the argvs.
this->argc_ = first_argc + second_argc;
size_t buf_len =
ACE_OS::strlen (first_buf) + ACE_OS::strlen (second_buf) + 1;
// Allocate memory to the lenght of the combined argv string.
ACE_NEW (this->buf_,
ACE_TCHAR[buf_len + 1]);
// copy the first argv string to the buffer
ACE_OS::strcpy (this->buf_, first_buf);
// concatenate the second argv string to the buffer
ACE_OS::strcat (this->buf_, second_buf);
// Delete the first and second buffers
delete [] first_buf;
delete [] second_buf;
}
ACE_ARGV::ACE_ARGV (int substitute_env_args)
: substitute_env_args_ (substitute_env_args),
state_ (ITERATIVE),
argc_ (0),
argv_ (0),
buf_ (0),
length_ (0),
queue_ ()
{
ACE_TRACE ("ACE_ARGV::ACE_ARGV Iterative");
// Nothing to do yet -- the user puts in arguments via add ()
}
int
ACE_ARGV::add (const ACE_TCHAR *next_arg)
{
// Only allow this to work in the "iterative" verion -- the
// ACE_ARGVs created with the one argument constructor.
if (this->state_ != ITERATIVE)
{
errno = EINVAL;
return -1;
}
// Put the new argument at the end of the queue.
if (this->queue_.enqueue_tail ((ACE_TCHAR *) next_arg) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_LIB_TEXT ("Can't add more to ARGV queue")),
-1);
this->length_ += ACE_OS::strlen (next_arg);
this->argc_++;
// Wipe argv_ and buf_ away so that they will be recreated if the
// user calls argv () or buf ().
if (this->argv_ != 0)
{
for (int i = 0; this->argv_[i] != 0; i++)
ACE_OS::free ((void *) this->argv_[i]);
delete [] this->argv_;
this->argv_ = 0;
}
delete [] this->buf_;
this->buf_ = 0;
return 0;
}
int
ACE_ARGV::add (ACE_TCHAR *argv[])
{
for (int i = 0; argv[i] != 0; i++)
if (this->add (argv[i]) == -1)
return -1;
return 0;
}
// Free up argv_ and buf_
ACE_ARGV::~ACE_ARGV (void)
{
ACE_TRACE ("ACE_ARGV::~ACE_ARGV");
if (this->argv_ != 0)
for (int i = 0; this->argv_[i] != 0; i++)
ACE_OS::free ((void *) this->argv_[i]);
delete [] this->argv_;
delete [] this->buf_;
}
// Create buf_ out of the queue_. This is only used in the
// "iterative" mode.
int
ACE_ARGV::create_buf_from_queue (void)
{
ACE_TRACE ("ACE_ARGV::create_buf_from_queue");
// If the are no arguments, don't do anything
if (this->argc_ = 0)
return -1;
delete [] this->buf_;
ACE_NEW_RETURN (this->buf_,
ACE_TCHAR[this->length_ + this->argc_],
-1);
// Get an iterator over the queue
ACE_Unbounded_Queue_Iterator<ACE_TCHAR *> iter (this->queue_);
ACE_TCHAR **arg;
ACE_TCHAR *ptr = this->buf_;
size_t len;
int more = 0;
while (!iter.done ())
{
// Get next argument from the queue.
iter.next (arg);
more = iter.advance ();
len = ACE_OS::strlen (*arg);
// Copy the argument into buf_
ACE_OS::memcpy ((void *) ptr,
(const void *) (*arg),
len * sizeof (ACE_TCHAR));
// Move the pointer down.
ptr += len;
// Put in an argument separating space.
if (more != 0)
*ptr++ = ' ';
}
// Put in the NUL terminator
*ptr = '\0';
return 0;
}
#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
template class ACE_Unbounded_Queue<ACE_TCHAR *>;
template class ACE_Unbounded_Queue_Iterator<ACE_TCHAR *>;
template class ACE_Node<ACE_TCHAR *>;
#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
#pragma instantiate ACE_Unbounded_Queue<ACE_TCHAR *>
#pragma instantiate ACE_Unbounded_Queue_Iterator<ACE_TCHAR *>
#pragma instantiate ACE_Node<ACE_TCHAR *>
#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */