00001 // -*- C++ -*- 00002 00003 //========================================================================== 00004 /** 00005 * @file ARGV.h 00006 * 00007 * $Id: ARGV.h 76208 2006-12-28 15:02:27Z schmidt $ 00008 * 00009 * @author Doug Schmidt <schmidt@cs.wustl.edu> 00010 * @author Everett Anderson <eea1@cs.wustl.edu> 00011 */ 00012 //========================================================================== 00013 00014 #ifndef ACE_ARGUMENT_VECTOR_H 00015 #define ACE_ARGUMENT_VECTOR_H 00016 #include /**/ "ace/pre.h" 00017 00018 #include /**/ "ace/ACE_export.h" 00019 00020 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00021 # pragma once 00022 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00023 00024 #include "ace/Unbounded_Queue.h" 00025 00026 // Open versioned namespace, if enabled by the user. 00027 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 00028 00029 /** 00030 * @class ACE_ARGV_Queue_Entry_T 00031 * 00032 * @brief An entry in the queue which keeps user supplied arguments. 00033 */ 00034 template <typename CHAR_TYPE> 00035 class ACE_ARGV_Queue_Entry_T 00036 { 00037 public: 00038 // = Initialization and termination. 00039 /// Initialize a ACE_ARGV_Queue_Entry_T. 00040 ACE_ARGV_Queue_Entry_T (void); 00041 00042 /** 00043 * Initialize a ACE_ARGV_Queue_Entry_T. 00044 * 00045 * @param arg Pointer to an argument 00046 * 00047 * @param quote_arg The argument @a arg need to be quoted 00048 * while adding to the vector. 00049 */ 00050 ACE_ARGV_Queue_Entry_T (const CHAR_TYPE *arg, 00051 bool quote_arg); 00052 00053 /** 00054 * Initialize a ACE_ARGV_Queue_Entry_T. 00055 * 00056 * @param entry Pointer to a queue entry 00057 */ 00058 ACE_ARGV_Queue_Entry_T (const ACE_ARGV_Queue_Entry_T<CHAR_TYPE> &entry); 00059 00060 /// We need this destructor to keep some compilers from complaining. 00061 /// It's just a no-op, however. 00062 ~ACE_ARGV_Queue_Entry_T (void); 00063 00064 /// Dump the state of this object. 00065 void dump (void) const; 00066 00067 // Declare the dynamic allocation hooks. 00068 ACE_ALLOC_HOOK_DECLARE; 00069 00070 /// Pointer to the argument. 00071 const CHAR_TYPE * arg_; 00072 00073 /// The argument need to be quoted while adding to the vector. 00074 bool quote_arg_; 00075 }; 00076 00077 /** 00078 * @class ACE_ARGV_T 00079 * 00080 * @brief Builds a counted argument vector (ala argc/argv) from either 00081 * a string or a set of separate tokens. This class preserves whitespace 00082 * within tokens only if the whitespace-containing token is enclosed in 00083 * either single (') or double (") quotes. This is consistent with the 00084 * expected behavior if an argument vector obtained using this class is 00085 * passed to, for example, ACE_Get_Opt. 00086 * 00087 * This class can substitute environment variable values for tokens that 00088 * are environment variable references (e.g., @c $VAR). This only works 00089 * if the token is an environment variable reference and nothing else; it 00090 * doesn't substitute environment variable references within a token. 00091 * For example, @c $HOME/file will not substitute the value of the HOME 00092 * environment variable. 00093 */ 00094 template <typename CHAR_TYPE> 00095 class ACE_ARGV_T 00096 { 00097 public: 00098 // = Initialization and termination. 00099 /** 00100 * Splits the specified string into an argument vector. Arguments in the 00101 * string are delimited by whitespace. Whitespace-containing arguments 00102 * must be enclosed in quotes, either single (') or double ("). 00103 * 00104 * @param buf A nul-terminated CHAR_TYPE array to split into arguments 00105 * for the vector. 00106 * 00107 * @param substitute_env_args If non-zero, any token that is an 00108 * environment variable reference (e.g., @c $VAR) will have 00109 * its environment variable value in the resultant vector 00110 * in place of the environment variable name. 00111 */ 00112 ACE_ARGV_T (const CHAR_TYPE buf[], 00113 bool substitute_env_args = true); 00114 00115 /** 00116 * Initializes the argument vector from a set of arguments. Any environment 00117 * variable references are translated (if applicable) during execution of 00118 * this method. 00119 * 00120 * @param argv An array of tokens to initialize the object with. The 00121 * array must be terminated with a 0 pointer. All needed 00122 * data is copied from @a argv during this call; the pointers 00123 * in @a argv are not needed after this call, and the memory 00124 * referred to by @a argv is not referenced by this object. 00125 * 00126 * @param substitute_env_args If non-zero, any element of @a argv that is 00127 * an environment variable reference (e.g., @c $VAR) will have 00128 * its environment variable value in the resultant vector 00129 * in place of the environment variable name. 00130 * 00131 * @param quote_args If non-zero each argument @a argv[i] needs to 00132 * be enclosed in double quotes ('"'). 00133 */ 00134 ACE_ARGV_T (CHAR_TYPE *argv[], 00135 bool substitute_env_args = true, 00136 bool quote_args = false); 00137 00138 /** 00139 * Initializes the argument vector from two combined argument vectors. 00140 * 00141 * @param first_argv An array of tokens to initialize the object with. 00142 * The array must be terminated with a 0 pointer. 00143 * @param second_argv An array of tokens that is concatenated with the 00144 * the tokens in @a first_argv. The array must be 00145 * terminated with a 0 pointer. 00146 * @param substitute_env_args If non-zero, any element of @a first_argv 00147 * or @a second_argv that is an environment variable 00148 * reference (e.g., @c $VAR) will have its environment 00149 * variable value in the resultant vector in place 00150 * of the environment variable name. 00151 * 00152 * @param quote_args If non-zero each arguments @a first_argv[i] and 00153 * @a second_argv[i] needs to be enclosed 00154 * in double quotes ('"'). 00155 */ 00156 ACE_ARGV_T (CHAR_TYPE *first_argv[], 00157 CHAR_TYPE *second_argv[], 00158 bool substitute_env_args = true, 00159 bool quote_args = false); 00160 00161 /** 00162 * Initialize this object so arguments can be added later using one 00163 * of the add methods. This is referred to as the @i iterative method 00164 * of adding arguments to this object. 00165 */ 00166 ACE_ARGV_T (bool substitute_env_args = true); 00167 00168 /// Destructor. 00169 ~ACE_ARGV_T (void); 00170 00171 /** @name Accessor methods 00172 * 00173 * These methods access the argument vector contained in this object. 00174 */ 00175 //@{ 00176 /** 00177 * Returns the specified element of the current argument vector. 00178 * 00179 * @param index Index to the desired element. 00180 * 00181 * @retval Pointer to the indexed string. 00182 * @retval 0 if @a index is out of bounds. 00183 */ 00184 const CHAR_TYPE *operator[] (size_t index); 00185 00186 /** 00187 * Returns the current argument vector. The returned pointers are to data 00188 * maintained internally to this class. Do not change or delete either the 00189 * pointers or the memory to which they refer. 00190 */ 00191 CHAR_TYPE **argv (void); 00192 00193 /// Returns the current number of arguments. 00194 int argc (void) const; 00195 00196 /** 00197 * Returns a single string form of the current arguments. The returned 00198 * pointer refers to memory maintained internally to this class. Do not 00199 * change or delete it. 00200 */ 00201 const CHAR_TYPE *buf (void); 00202 00203 //@} 00204 00205 /// Dump the state of this object. 00206 void dump (void) const; 00207 00208 // Declare the dynamic allocation hooks. 00209 ACE_ALLOC_HOOK_DECLARE; 00210 00211 /** 00212 * Add another argument. This only works in the iterative mode. 00213 * 00214 * @note This method copies the specified pointer, but not the data 00215 * contained in the referenced memory. Thus, if the content of 00216 * the memory referred to by @a next_arg are changed after this 00217 * method returns, the results are undefined. 00218 * 00219 * @param next_arg Pointer to the next argument to add to the vector. 00220 * 00221 * @param quote_arg The argument @a next_arg need to be quoted while 00222 * adding to the vector. 00223 * 00224 * @retval 0 on success; -1 on failure. Most likely @c errno values are: 00225 * - EINVAL: This object is not in iterative mode. 00226 * - ENOMEM: Not enough memory available to save @a next_arg. 00227 */ 00228 int add (const CHAR_TYPE *next_arg, bool quote_arg = false); 00229 00230 /** 00231 * Add an array of arguments. This only works in the iterative mode. 00232 * 00233 * @note This method copies the specified pointers, but not the data 00234 * contained in the referenced memory. Thus, if the content of 00235 * the memory referred to by any of the @a argv elements is 00236 * changed after this method returns, the results are undefined. 00237 * 00238 * @param argv Pointers to the arguments to add to the vector. 00239 * @a argv must be terminated by a 0 pointer. 00240 * 00241 * @param quote_args If non-zero each argument @a argv[i] needs to 00242 * be enclosed in double quotes ('"'). 00243 * 00244 * @retval 0 on success; -1 on failure. Most likely @c errno values are: 00245 * - EINVAL: This object is not in iterative mode. 00246 * - ENOMEM: Not enough memory available to save @a next_arg. 00247 */ 00248 int add (CHAR_TYPE *argv[], bool quote_args = false); 00249 00250 private: 00251 /// Copy constructor not implemented. 00252 ACE_UNIMPLEMENTED_FUNC (ACE_ARGV_T (const ACE_ARGV_T<CHAR_TYPE>&)) 00253 00254 /// Assignment operator not implemented. 00255 ACE_UNIMPLEMENTED_FUNC (ACE_ARGV_T operator= (const ACE_ARGV_T<CHAR_TYPE>&)) 00256 00257 /// Creates buf_ from the queue of added args, deletes previous buf_. 00258 int create_buf_from_queue (void); 00259 00260 /// Converts buf_ into the CHAR_TYPE *argv[] format. 00261 int string_to_argv (void); 00262 00263 /// Replace args with environment variable values? 00264 bool substitute_env_args_; 00265 00266 bool iterative_; 00267 00268 /// Number of arguments in the ARGV array. 00269 int argc_; 00270 00271 /// The array of string arguments. 00272 CHAR_TYPE **argv_; 00273 00274 /// Buffer containing the <argv> contents. 00275 CHAR_TYPE *buf_; 00276 00277 /// Total length of the arguments in the queue, not counting 00278 /// separating spaces 00279 size_t length_; 00280 00281 /// Queue which keeps user supplied arguments. This is only 00282 /// active in the "iterative" mode. 00283 ACE_Unbounded_Queue<ACE_ARGV_Queue_Entry_T<CHAR_TYPE> > queue_; 00284 }; 00285 00286 typedef ACE_ARGV_Queue_Entry_T<ACE_TCHAR> ACE_ARGV_Queue_Entry; 00287 typedef ACE_ARGV_T<ACE_TCHAR> ACE_ARGV; 00288 00289 // Close versioned namespace, if enabled by the user. 00290 ACE_END_VERSIONED_NAMESPACE_DECL 00291 00292 #if defined (__ACE_INLINE__) 00293 #include "ace/ARGV.inl" 00294 #endif /* __ACE_INLINE__ */ 00295 00296 #if defined (ACE_TEMPLATES_REQUIRE_SOURCE) 00297 #include "ace/ARGV.cpp" 00298 #endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ 00299 00300 #if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) 00301 #pragma implementation ("ARGV.cpp") 00302 #endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ 00303 00304 #include /**/ "ace/post.h" 00305 #endif /* ACE_ARGUMENT_VECTOR_H */