Changes to attempt to silence bcc64x
[ACE_TAO.git] / ACE / ace / ARGV.cpp
blob2c08788a86639f34aead6b34cc04d8c7de7778cd
1 #ifndef ACE_ARGV_CPP
2 #define ACE_ARGV_CPP
4 #include "ace/Log_Category.h"
5 #include "ace/OS_NS_unistd.h"
6 #include "ace/OS_NS_string.h"
7 #include "ace/OS_Memory.h"
9 #if !defined (__ACE_INLINE__)
10 #include "ace/ARGV.inl"
11 #endif /* __ACE_INLINE__ */
13 // Open versioned namespace, if enabled by the user.
14 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
16 ACE_ALLOC_HOOK_DEFINE_Tt (ACE_ARGV_Queue_Entry_T)
17 ACE_ALLOC_HOOK_DEFINE_Tt (ACE_ARGV_T)
19 template <typename CHAR_TYPE>
20 void
21 ACE_ARGV_Queue_Entry_T<CHAR_TYPE>::dump () const
23 #if defined (ACE_HAS_DUMP)
24 ACE_TRACE ("ACE_ARGV_Queue_Entry_T::dump");
26 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
27 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("arg_ = %s"), this->arg_));
28 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("quote_arg_ = %d"), (int)this->quote_arg_));
29 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
30 #endif /* ACE_HAS_DUMP */
33 template <typename CHAR_TYPE>
34 void
35 ACE_ARGV_T<CHAR_TYPE>::dump () const
37 #if defined (ACE_HAS_DUMP)
38 ACE_TRACE ("ACE_ARGV_T::dump");
40 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
41 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("argc_ = %d"), this->argc_));
43 ACE_ARGV *this_obj = const_cast<ACE_ARGV *> (this);
45 for (int i = 0; i < this->argc_; i++)
46 ACELIB_DEBUG ((LM_DEBUG,
47 ACE_TEXT ("\nargv_[%i] = %s"),
49 this_obj->argv ()[i]));
51 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("\nbuf = %s\n"), this->buf_));
52 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("\n")));
53 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
54 #endif /* ACE_HAS_DUMP */
57 // Creates this->argv_ out of this->buf_. New memory is allocated for
58 // each element of the array. This is used by the array-to-string
59 // style constructor and for creating this->argv_ when in iterative
60 // mode.
62 template <typename CHAR_TYPE>
63 int
64 ACE_ARGV_T<CHAR_TYPE>::string_to_argv ()
66 ACE_TRACE ("ACE_ARGV_T::string_to_argv");
68 return ACE_OS::string_to_argv (this->buf_,
69 this->argc_,
70 this->argv_,
71 this->substitute_env_args_);
74 template <typename CHAR_TYPE>
75 ACE_ARGV_T<CHAR_TYPE>::ACE_ARGV_T (const CHAR_TYPE buf[],
76 bool substitute_env_args)
77 : substitute_env_args_ (substitute_env_args),
78 iterative_ (false),
79 argc_ (0),
80 argv_ (0),
81 buf_ (0),
82 length_ (0),
83 queue_ ()
85 ACE_TRACE ("ACE_ARGV_T::ACE_ARGV_T CHAR_TYPE[] to CHAR_TYPE *[]");
87 if (buf == 0 || buf[0] == 0)
88 return;
90 // Make an internal copy of the string.
91 #if defined (ACE_HAS_ALLOC_HOOKS)
92 ACE_ALLOCATOR(this->buf_,
93 static_cast<char*> (ACE_Allocator::instance()->malloc(sizeof (CHAR_TYPE) * (ACE_OS::strlen (buf) + 1))));
94 #else
95 ACE_NEW (this->buf_,
96 CHAR_TYPE[ACE_OS::strlen (buf) + 1]);
97 #endif /* ACE_HAS_ALLOC_HOOKS */
99 ACE_OS::strcpy (this->buf_, buf);
101 // Create this->argv_.
102 if (this->string_to_argv () == -1)
103 ACELIB_ERROR ((LM_ERROR,
104 ACE_TEXT ("%p\n"),
105 ACE_TEXT ("string_to_argv")));
108 template <typename CHAR_TYPE>
109 ACE_ARGV_T<CHAR_TYPE>::ACE_ARGV_T (CHAR_TYPE *argv[],
110 bool substitute_env_args,
111 bool quote_arg)
112 : substitute_env_args_ (substitute_env_args),
113 iterative_ (false),
114 argc_ (0),
115 argv_ (0),
116 buf_ (0),
117 length_ (0),
118 queue_ ()
120 ACE_TRACE ("ACE_ARGV_T::ACE_ARGV_T CHAR_TYPE*[] to CHAR_TYPE[]");
122 if (argv == 0 || argv[0] == 0)
123 return;
125 this->argc_ = ACE_OS::argv_to_string (argv,
126 this->buf_,
127 substitute_env_args,
128 quote_arg);
131 template <typename CHAR_TYPE>
132 ACE_ARGV_T<CHAR_TYPE>::ACE_ARGV_T (int argc,
133 CHAR_TYPE *argv[],
134 bool substitute_env_args,
135 bool quote_arg)
136 : substitute_env_args_ (substitute_env_args),
137 iterative_ (false),
138 argc_ (0),
139 argv_ (0),
140 buf_ (0),
141 length_ (0),
142 queue_ ()
144 ACE_TRACE ("ACE_ARGV_T::ACE_ARGV_T int,CHAR_TYPE*[] to CHAR_TYPE[]");
146 this->argc_ = ACE_OS::argv_to_string (argc,
147 argv,
148 this->buf_,
149 substitute_env_args,
150 quote_arg);
154 template <typename CHAR_TYPE>
155 ACE_ARGV_T<CHAR_TYPE>::ACE_ARGV_T (CHAR_TYPE *first_argv[],
156 CHAR_TYPE *second_argv[],
157 bool substitute_env_args,
158 bool quote_args)
159 : substitute_env_args_ (substitute_env_args),
160 iterative_ (false),
161 argc_ (0),
162 argv_ (0),
163 buf_ (0),
164 length_ (0),
165 queue_ ()
167 ACE_TRACE ("ACE_ARGV_T::ACE_ARGV_T CHAR_TYPE*[] + CHAR_TYPE *[] to CHAR_TYPE[]");
169 int first_argc = 0;
170 int second_argc = 0;
172 CHAR_TYPE *first_buf = 0;
173 CHAR_TYPE *second_buf = 0;
174 size_t buf_len = 1;
176 // convert the first argv to a string
177 if (first_argv != 0 && first_argv[0] != 0)
179 first_argc = ACE_OS::argv_to_string (first_argv,
180 first_buf,
181 substitute_env_args,
182 quote_args);
183 buf_len += ACE_OS::strlen (first_buf);
186 // convert the second argv to a string
187 if (second_argv != 0 && second_argv[0] != 0)
189 second_argc = ACE_OS::argv_to_string (second_argv,
190 second_buf,
191 substitute_env_args,
192 quote_args);
193 buf_len += ACE_OS::strlen (second_buf);
196 // Add the number of arguments in both the argvs.
197 this->argc_ = first_argc + second_argc;
199 // Allocate memory to the lenght of the combined argv string.
200 ACE_NEW (this->buf_,
201 CHAR_TYPE[buf_len + 1]);
203 // copy the first argv string to the buffer
204 ACE_OS::strcpy (this->buf_, first_buf);
206 // concatenate the second argv string to the buffer
207 ACE_OS::strcat (this->buf_, second_buf);
209 // Delete the first and second buffers
210 #if defined (ACE_HAS_ALLOC_HOOKS)
211 ACE_Allocator::instance()->free (first_buf);
212 ACE_Allocator::instance()->free (second_buf);
213 #else
214 delete [] first_buf;
215 delete [] second_buf;
216 #endif /* ACE_HAS_ALLOC_HOOKS */
219 template <typename CHAR_TYPE>
220 ACE_ARGV_T<CHAR_TYPE>::ACE_ARGV_T (bool substitute_env_args)
221 : substitute_env_args_ (substitute_env_args),
222 iterative_ (true),
223 argc_ (0),
224 argv_ (0),
225 buf_ (0),
226 length_ (0),
227 queue_ ()
229 ACE_TRACE ("ACE_ARGV_T::ACE_ARGV_T Iterative");
231 // Nothing to do yet -- the user puts in arguments via add ()
234 template <typename CHAR_TYPE>
236 ACE_ARGV_T<CHAR_TYPE>::add (const CHAR_TYPE *next_arg, bool quote_arg)
238 // Only allow this to work in the "iterative" verion -- the
239 // ACE_ARGVs created with the one argument constructor.
240 if (!this->iterative_)
242 errno = EINVAL;
243 return -1;
246 this->length_ += ACE_OS::strlen (next_arg);
247 if (quote_arg && ACE_OS::strchr (next_arg, ' ') != 0)
249 this->length_ += 2;
250 if (ACE_OS::strchr (next_arg, '"') != 0)
251 for (const CHAR_TYPE * p = next_arg; *p != '\0'; ++p)
252 if (*p == '"') ++this->length_;
254 else
256 quote_arg = false;
259 // Put the new argument at the end of the queue.
260 if (this->queue_.enqueue_tail (ACE_ARGV_Queue_Entry_T<CHAR_TYPE> (next_arg, quote_arg)) == -1)
261 ACELIB_ERROR_RETURN ((LM_ERROR,
262 ACE_TEXT ("Can't add more to ARGV queue")),
263 -1);
265 ++this->argc_;
267 // Wipe argv_ and buf_ away so that they will be recreated if the
268 // user calls argv () or buf ().
269 if (this->argv_ != 0)
271 for (int i = 0; this->argv_[i] != 0; i++)
272 ACE_OS::free ((void *) this->argv_[i]);
274 #if defined (ACE_HAS_ALLOC_HOOKS)
275 ACE_Allocator::instance()->free (this->argv_);
276 #else
277 delete [] this->argv_;
278 #endif /* ACE_HAS_ALLOC_HOOKS */
279 this->argv_ = 0;
282 #if defined (ACE_HAS_ALLOC_HOOKS)
283 ACE_Allocator::instance()->free (this->buf_);
284 #else
285 delete [] this->buf_;
286 #endif /* ACE_HAS_ALLOC_HOOKS */
287 this->buf_ = 0;
289 return 0;
292 template <typename CHAR_TYPE>
294 ACE_ARGV_T<CHAR_TYPE>::add (CHAR_TYPE *argv[], bool quote_args)
296 for (int i = 0; argv[i] != 0; i++)
297 if (this->add (argv[i], quote_args) == -1)
298 return -1;
300 return 0;
303 // Free up argv_ and buf_
304 template <typename CHAR_TYPE>
305 ACE_ARGV_T<CHAR_TYPE>::~ACE_ARGV_T ()
307 ACE_TRACE ("ACE_ARGV_T::~ACE_ARGV_T");
309 if (this->argv_ != 0)
310 for (int i = 0; this->argv_[i] != 0; i++)
311 #if defined (ACE_HAS_ALLOC_HOOKS)
312 ACE_Allocator::instance()->free ((void *) this->argv_[i]);
313 #else
314 ACE_OS::free ((void *) this->argv_[i]);
315 #endif /* ACE_HAS_ALLOC_HOOKS */
318 #if defined (ACE_HAS_ALLOC_HOOKS)
319 ACE_Allocator::instance()->free (this->argv_);
320 ACE_Allocator::instance()->free (this->buf_);
321 #else
322 delete [] this->argv_;
323 delete [] this->buf_;
324 #endif /* ACE_HAS_ALLOC_HOOKS */
327 // Create buf_ out of the queue_. This is only used in the
328 // "iterative" mode.
330 template <typename CHAR_TYPE>
332 ACE_ARGV_T<CHAR_TYPE>::create_buf_from_queue ()
334 ACE_TRACE ("ACE_ARGV_T::create_buf_from_queue");
336 // If the are no arguments, don't do anything
337 if (this->argc_ <= 0)
338 return -1;
340 #if defined (ACE_HAS_ALLOC_HOOKS)
341 ACE_Allocator::instance()->free (this->buf_);
342 #else
343 delete [] this->buf_;
344 #endif /* ACE_HAS_ALLOC_HOOKS */
346 #if defined (ACE_HAS_ALLOC_HOOKS)
347 ACE_ALLOCATOR_RETURN (this->buf_,
348 static_cast<char*> (ACE_Allocator::instance()->malloc(sizeof (CHAR_TYPE) * (this->length_ + this->argc_))),
349 -1);
350 #else
351 ACE_NEW_RETURN (this->buf_,
352 CHAR_TYPE[this->length_ + this->argc_],
353 -1);
354 #endif /* ACE_HAS_ALLOC_HOOKS */
356 // Get an iterator over the queue
357 ACE_Unbounded_Queue_Iterator<ACE_ARGV_Queue_Entry_T<CHAR_TYPE> > iter (this->queue_);
359 ACE_ARGV_Queue_Entry_T<CHAR_TYPE> *arg = 0;
360 CHAR_TYPE *ptr = this->buf_;
361 size_t len;
363 while (!iter.done ())
365 // Get next argument from the queue.
366 iter.next (arg);
367 iter.advance ();
369 if (arg->quote_arg_)
371 *ptr++ = '"';
372 if (ACE_OS::strchr (arg->arg_, '"') != 0)
374 CHAR_TYPE prev = 0;
375 for (const CHAR_TYPE * p = arg->arg_; *p != '\0'; ++p)
377 if (*p == '"' && prev != '\\') *ptr++ = '\\';
378 prev = *ptr++ = *p;
381 else
383 len = ACE_OS::strlen (arg->arg_);
384 // Copy the argument into buf_
385 ACE_OS::memcpy ((void *) ptr,
386 (const void *) (arg->arg_),
387 len * sizeof (CHAR_TYPE));
388 // Move the pointer down.
389 ptr += len;
391 *ptr++ = '"';
393 else
395 len = ACE_OS::strlen (arg->arg_);
396 // Copy the argument into buf_
397 ACE_OS::memcpy ((void *) ptr,
398 (const void *) (arg->arg_),
399 len * sizeof (CHAR_TYPE));
400 // Move the pointer down.
401 ptr += len;
404 // Put in an argument separating space.
405 *ptr++ = ' ';
408 // Put in the NUL terminator
409 ptr[-1] = '\0';
411 return 0;
414 // Close versioned namespace, if enabled by the user.
415 ACE_END_VERSIONED_NAMESPACE_DECL
417 #endif /* ACE_ARGV_CPP */