// ARGV.cpp // $Id$ // Transforms a string BUF into an ARGV-style vector of strings. #define ACE_BUILD_DLL #include "ace/ARGV.h" #if !defined (__ACE_INLINE__) #include "ace/ARGV.i" #endif /* __ACE_INLINE__ */ 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, "argc_ = %d", this->argc_)); for (size_t i = 0; i < this->argc_; i++) ACE_DEBUG ((LM_DEBUG, "\nargv_[%i] = %s", i, this->argv_[i])); ACE_DEBUG ((LM_DEBUG, "\nbuf = %s\n")); ACE_DEBUG ((LM_DEBUG, "\n")); ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); } ACE_ARGV::ACE_ARGV (char buf[], int substitute_env_args) : argc_ (0), argv_ (0), buf_ (0) { ACE_TRACE ("ACE_ARGV::ACE_ARGV"); if (buf == 0) return; char *cp = buf; // First pass: count arguments. // '#' is the start-comment token.. while (*cp != '\0' && *cp != '#') { // Skip whitespace.. while (isspace (*cp)) cp++; // Increment count and move to next whitespace.. if (*cp != '\0') this->argc_++; // Grok quotes.... if (*cp == '\'' || *cp == '"') { char quote = *cp; // Scan past the string.. for (cp++; *cp != '\0' && *cp != quote; cp++) continue; // '\0' implies unmatched quote.. if (*cp == '\0') { ACE_ERROR ((LM_ERROR, "unmatched %c detected\n", quote)); this->argc_--; break; } else cp++; } else // Skip over non-whitespace.... while (*cp != '\0' && !isspace (*cp)) cp++; } // Second pass: copy arguments.. char arg[BUFSIZ]; // Make a new argv vector of argc + 1 elements. ACE_NEW (this->argv_, char *[this->argc_ + 1]); for (size_t i = 0; i < this->argc_; i++) { // Skip whitespace.. while (isspace (*buf)) buf++; // Copy next argument and move to next whitespace.. if (*buf == '\'' || *buf == '"') { char quote = *buf++; for (cp = arg; *buf != '\0' && *buf != quote; buf++, cp++) if (unsigned (cp - arg) < sizeof arg) *cp = *buf; *cp = '\0'; if (*buf == quote) buf++; } else { for (cp = arg; *buf && !isspace (*buf); buf++, cp++) if (unsigned (cp - arg) < sizeof arg) *cp = *buf; *cp = '\0'; } // Check for environment variable substitution here. if (substitute_env_args) this->argv_[i] = ACE::strenvdup (arg); else this->argv_[i] = ACE_OS::strdup (arg); } this->argv_[this->argc_] = 0; } ACE_ARGV::ACE_ARGV (char *argv[], int substitute_env_args) : argc_ (0), argv_ (0), buf_ (0) { ACE_TRACE ("ACE_ARGV::ACE_ARGV"); if (argv == 0 || argv[0] == 0) return; int buf_len = 0; // Determine the length of the buffer. for (int i = 0; argv[i] != 0; i++) { char *temp; // Account for environment variables. if (substitute_env_args && (argv[i][0] == '$' && (temp = ACE_OS::getenv (&argv[i][1])) != 0)) buf_len += ACE_OS::strlen (temp); else 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_, char[buf_len]); char *end = this->buf_; for (int j = 0; argv[j] != 0; j++) { char *temp; // Account for environment variables. if (substitute_env_args && (argv[j][0] == '$' && (temp = ACE_OS::getenv (&argv[j][1])) != 0)) end = ACE::strecpy (end, temp); else end = ACE::strecpy (end, argv[j]); // Add white space and advance the pointer. *end++ = ' '; } // Null terminate the string. *end = '\0'; } // Free up the space allocated by the constructor.. ACE_ARGV::~ACE_ARGV (void) { ACE_TRACE ("ACE_ARGV::~ACE_ARGV"); if (this->argv_ == 0) return; for (int i = 0; this->argv_[i] != 0; i++) ACE_OS::free ((void *) this->argv_[i]); ACE_OS::free ((void *) this->argv_); delete this->buf_; }