// -*- C++ -*- //========================================================================== /** * @file ARGV.h * * @author Doug Schmidt * @author Everett Anderson */ //========================================================================== #ifndef ACE_ARGUMENT_VECTOR_H #define ACE_ARGUMENT_VECTOR_H #include /**/ "ace/pre.h" #include /**/ "ace/ACE_export.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ #include "ace/Global_Macros.h" #include "ace/Unbounded_Queue.h" // Open versioned namespace, if enabled by the user. ACE_BEGIN_VERSIONED_NAMESPACE_DECL /** * @class ACE_ARGV_Queue_Entry_T * * @brief An entry in the queue which keeps user supplied arguments. */ template class ACE_ARGV_Queue_Entry_T { public: /// Initialize a ACE_ARGV_Queue_Entry_T. ACE_ARGV_Queue_Entry_T (); /** * Initialize a ACE_ARGV_Queue_Entry_T. * * @param arg Pointer to an argument * * @param quote_arg The argument @a arg need to be quoted * while adding to the vector. */ ACE_ARGV_Queue_Entry_T (const CHAR_TYPE *arg, bool quote_arg); /** * Initialize a ACE_ARGV_Queue_Entry_T. * * @param entry Pointer to a queue entry */ ACE_ARGV_Queue_Entry_T (const ACE_ARGV_Queue_Entry_T &entry); ACE_ARGV_Queue_Entry_T (ACE_ARGV_Queue_Entry_T&&) = default; ACE_ARGV_Queue_Entry_T &operator = (const ACE_ARGV_Queue_Entry_T &) = default; ACE_ARGV_Queue_Entry_T &operator = (ACE_ARGV_Queue_Entry_T &&) = default; /// We need this destructor to keep some compilers from complaining. /// It's just a no-op, however. ~ACE_ARGV_Queue_Entry_T () = default; /// Dump the state of this object. void dump () const; // Declare the dynamic allocation hooks. ACE_ALLOC_HOOK_DECLARE; /// Pointer to the argument. const CHAR_TYPE * arg_; /// The argument need to be quoted while adding to the vector. bool quote_arg_; }; /** * @class ACE_ARGV_T * * @brief Builds a counted argument vector (ala argc/argv) from either * a string or a set of separate tokens. This class preserves whitespace * within tokens only if the whitespace-containing token is enclosed in * either single (') or double (") quotes. This is consistent with the * expected behavior if an argument vector obtained using this class is * passed to, for example, ACE_Get_Opt. * * This class can substitute environment variable values for tokens that * are environment variable references (e.g., @c $VAR). This only works * if the token is an environment variable reference and nothing else; it * doesn't substitute environment variable references within a token. * For example, @c $HOME/file will not substitute the value of the HOME * environment variable. */ template class ACE_ARGV_T { public: /** * Splits the specified string into an argument vector. Arguments in the * string are delimited by whitespace. Whitespace-containing arguments * must be enclosed in quotes, either single (') or double ("). * * @param buf A nul-terminated CHAR_TYPE array to split into arguments * for the vector. * * @param substitute_env_args If non-zero, any token that is an * environment variable reference (e.g., @c $VAR) will have * its environment variable value in the resultant vector * in place of the environment variable name. */ explicit ACE_ARGV_T (const CHAR_TYPE buf[], bool substitute_env_args = true); /** * Initializes the argument vector from a set of arguments. Any environment * variable references are translated (if applicable) during execution of * this method. In contrast with ACE_ARGV_T(CHAR_TYPE *[], bool, bool), this * ctor does not require argv to be 0-terminated as the number of arguments * is provided explicitely. * * @param argc The number of arguments in the argv array. * * @param argv An array of tokens to initialize the object with. All needed * data is copied from @a argv during this call; the pointers * in @a argv are not needed after this call, and the memory * referred to by @a argv is not referenced by this object. * * @param substitute_env_args If non-zero, any element of @a argv that is * an environment variable reference (e.g., @c $VAR) will have * its environment variable value in the resultant vector * in place of the environment variable name. * * @param quote_args If non-zero each argument @a argv[i] needs to * be enclosed in double quotes ('"'). */ explicit ACE_ARGV_T (int argc, CHAR_TYPE *argv[], bool substitute_env_args = true, bool quote_args = false); /** * Initializes the argument vector from a set of arguments. Any environment * variable references are translated (if applicable) during execution of * this method. * * @param argv An array of tokens to initialize the object with. The * array must be terminated with a 0 pointer. All needed * data is copied from @a argv during this call; the pointers * in @a argv are not needed after this call, and the memory * referred to by @a argv is not referenced by this object. * * @param substitute_env_args If non-zero, any element of @a argv that is * an environment variable reference (e.g., @c $VAR) will have * its environment variable value in the resultant vector * in place of the environment variable name. * * @param quote_args If non-zero each argument @a argv[i] needs to * be enclosed in double quotes ('"'). */ explicit ACE_ARGV_T (CHAR_TYPE *argv[], bool substitute_env_args = true, bool quote_args = false); /** * Initializes the argument vector from two combined argument vectors. * * @param first_argv An array of tokens to initialize the object with. * The array must be terminated with a 0 pointer. * @param second_argv An array of tokens that is concatenated with the * the tokens in @a first_argv. The array must be * terminated with a 0 pointer. * @param substitute_env_args If non-zero, any element of @a first_argv * or @a second_argv that is an environment variable * reference (e.g., @c $VAR) will have its environment * variable value in the resultant vector in place * of the environment variable name. * * @param quote_args If non-zero each arguments @a first_argv[i] and * @a second_argv[i] needs to be enclosed * in double quotes ('"'). */ ACE_ARGV_T (CHAR_TYPE *first_argv[], CHAR_TYPE *second_argv[], bool substitute_env_args = true, bool quote_args = false); /** * Initialize this object so arguments can be added later using one * of the add methods. This is referred to as the @i iterative method * of adding arguments to this object. */ explicit ACE_ARGV_T (bool substitute_env_args = true); /// Destructor. ~ACE_ARGV_T (); /** @name Accessor methods * * These methods access the argument vector contained in this object. */ //@{ /** * Returns the specified element of the current argument vector. * * @param index Index to the desired element. * * @retval Pointer to the indexed string. * @retval 0 if @a index is out of bounds. */ const CHAR_TYPE *operator[] (size_t index); /** * Returns the current argument vector. The returned pointers are to data * maintained internally to this class. Do not change or delete either the * pointers or the memory to which they refer. */ CHAR_TYPE **argv (); /// Returns the current number of arguments. int argc () const; /** * Returns a single string form of the current arguments. The returned * pointer refers to memory maintained internally to this class. Do not * change or delete it. */ const CHAR_TYPE *buf (); //@} /// Dump the state of this object. void dump () const; // Declare the dynamic allocation hooks. ACE_ALLOC_HOOK_DECLARE; /** * Add another argument. This only works in the iterative mode. * * @note This method copies the specified pointer, but not the data * contained in the referenced memory. Thus, if the content of * the memory referred to by @a next_arg are changed after this * method returns, the results are undefined. * * @param next_arg Pointer to the next argument to add to the vector. * * @param quote_arg The argument @a next_arg need to be quoted while * adding to the vector. * * @retval 0 on success; -1 on failure. Most likely @c errno values are: * - EINVAL: This object is not in iterative mode. * - ENOMEM: Not enough memory available to save @a next_arg. */ int add (const CHAR_TYPE *next_arg, bool quote_arg = false); /** * Add an array of arguments. This only works in the iterative mode. * * @note This method copies the specified pointers, but not the data * contained in the referenced memory. Thus, if the content of * the memory referred to by any of the @a argv elements is * changed after this method returns, the results are undefined. * * @param argv Pointers to the arguments to add to the vector. * @a argv must be terminated by a 0 pointer. * * @param quote_args If non-zero each argument @a argv[i] needs to * be enclosed in double quotes ('"'). * * @retval 0 on success; -1 on failure. Most likely @c errno values are: * - EINVAL: This object is not in iterative mode. * - ENOMEM: Not enough memory available to save @a next_arg. */ int add (CHAR_TYPE *argv[], bool quote_args = false); private: ACE_ARGV_T (const ACE_ARGV_T&) = delete; ACE_ARGV_T operator= (const ACE_ARGV_T&) = delete; ACE_ARGV_T (ACE_ARGV_T&&) = delete; ACE_ARGV_T operator= (ACE_ARGV_T&&) = delete; /// Creates buf_ from the queue of added args, deletes previous buf_. int create_buf_from_queue (); /// Converts buf_ into the CHAR_TYPE *argv[] format. int string_to_argv (); /// Replace args with environment variable values? bool substitute_env_args_; bool iterative_; /// Number of arguments in the ARGV array. int argc_; /// The array of string arguments. CHAR_TYPE **argv_; /// Buffer containing the argv contents. CHAR_TYPE *buf_; /// Total length of the arguments in the queue, not counting /// separating spaces size_t length_; /// Queue which keeps user supplied arguments. This is only /// active in the "iterative" mode. ACE_Unbounded_Queue > queue_; }; typedef ACE_ARGV_Queue_Entry_T ACE_ARGV_Queue_Entry; typedef ACE_ARGV_T ACE_ARGV; // Close versioned namespace, if enabled by the user. ACE_END_VERSIONED_NAMESPACE_DECL #if defined (__ACE_INLINE__) #include "ace/ARGV.inl" #endif /* __ACE_INLINE__ */ #include "ace/ARGV.cpp" #include /**/ "ace/post.h" #endif /* ACE_ARGUMENT_VECTOR_H */