1 // $Id: ARGV.cpp 81374 2008-04-16 13:07:47Z iliyan $
6 #include "ace/Log_Msg.h"
7 #include "ace/OS_NS_unistd.h"
8 #include "ace/OS_NS_string.h"
9 #include "ace/OS_Memory.h"
11 #if !defined (__ACE_INLINE__)
12 #include "ace/ARGV.inl"
13 #endif /* __ACE_INLINE__ */
15 ACE_RCSID(ace
, ARGV
, "$Id: ARGV.cpp 81374 2008-04-16 13:07:47Z iliyan $")
17 // Open versioned namespace, if enabled by the user.
18 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
20 ACE_ALLOC_HOOK_DEFINE (ACE_ARGV_Queue_Entry
)
21 ACE_ALLOC_HOOK_DEFINE (ACE_ARGV
)
23 template <typename CHAR_TYPE
>
25 ACE_ARGV_Queue_Entry_T
<CHAR_TYPE
>::dump (void) const
27 #if defined (ACE_HAS_DUMP)
28 ACE_TRACE ("ACE_ARGV_Queue_Entry_T::dump");
30 ACE_DEBUG ((LM_DEBUG
, ACE_BEGIN_DUMP
, this));
31 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("arg_ = %s"), this->arg_
));
32 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("quote_arg_ = %d"), (int)this->quote_arg_
));
33 ACE_DEBUG ((LM_DEBUG
, ACE_END_DUMP
));
34 #endif /* ACE_HAS_DUMP */
37 template <typename CHAR_TYPE
>
39 ACE_ARGV_T
<CHAR_TYPE
>::dump (void) const
41 #if defined (ACE_HAS_DUMP)
42 ACE_TRACE ("ACE_ARGV_T::dump");
44 ACE_DEBUG ((LM_DEBUG
, ACE_BEGIN_DUMP
, this));
45 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("argc_ = %d"), this->argc_
));
47 ACE_ARGV
*this_obj
= const_cast<ACE_ARGV
*> (this);
49 for (int i
= 0; i
< this->argc_
; i
++)
51 ACE_TEXT ("\nargv_[%i] = %s"),
53 this_obj
->argv ()[i
]));
55 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nbuf = %s\n"), this->buf_
));
56 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("\n")));
57 ACE_DEBUG ((LM_DEBUG
, ACE_END_DUMP
));
58 #endif /* ACE_HAS_DUMP */
61 // Creates this->argv_ out of this->buf_. New memory is allocated for
62 // each element of the array. This is used by the array-to-string
63 // style constructor and for creating this->argv_ when in iterative
66 template <typename CHAR_TYPE
>
68 ACE_ARGV_T
<CHAR_TYPE
>::string_to_argv (void)
70 ACE_TRACE ("ACE_ARGV_T::string_to_argv");
72 return ACE_OS::string_to_argv (this->buf_
,
75 this->substitute_env_args_
);
78 template <typename CHAR_TYPE
>
79 ACE_ARGV_T
<CHAR_TYPE
>::ACE_ARGV_T (const CHAR_TYPE buf
[],
80 bool substitute_env_args
)
81 : substitute_env_args_ (substitute_env_args
),
89 ACE_TRACE ("ACE_ARGV_T::ACE_ARGV_T CHAR_TYPE[] to CHAR_TYPE *[]");
91 if (buf
== 0 || buf
[0] == 0)
94 // Make an internal copy of the string.
96 CHAR_TYPE
[ACE_OS::strlen (buf
) + 1]);
97 ACE_OS::strcpy (this->buf_
, buf
);
99 // Create this->argv_.
100 if (this->string_to_argv () == -1)
101 ACE_ERROR ((LM_ERROR
,
103 ACE_TEXT ("string_to_argv")));
106 template <typename CHAR_TYPE
>
107 ACE_ARGV_T
<CHAR_TYPE
>::ACE_ARGV_T (CHAR_TYPE
*argv
[],
108 bool substitute_env_args
,
110 : substitute_env_args_ (substitute_env_args
),
118 ACE_TRACE ("ACE_ARGV_T::ACE_ARGV_T CHAR_TYPE*[] to CHAR_TYPE[]");
120 if (argv
== 0 || argv
[0] == 0)
123 this->argc_
= ACE_OS::argv_to_string (argv
,
129 template <typename CHAR_TYPE
>
130 ACE_ARGV_T
<CHAR_TYPE
>::ACE_ARGV_T (int argc
,
132 bool substitute_env_args
,
134 : substitute_env_args_ (substitute_env_args
),
142 ACE_TRACE ("ACE_ARGV_T::ACE_ARGV_T int,CHAR_TYPE*[] to CHAR_TYPE[]");
144 this->argc_
= ACE_OS::argv_to_string (argc
,
152 template <typename CHAR_TYPE
>
153 ACE_ARGV_T
<CHAR_TYPE
>::ACE_ARGV_T (CHAR_TYPE
*first_argv
[],
154 CHAR_TYPE
*second_argv
[],
155 bool substitute_env_args
,
157 : substitute_env_args_ (substitute_env_args
),
165 ACE_TRACE ("ACE_ARGV_T::ACE_ARGV_T CHAR_TYPE*[] + CHAR_TYPE *[] to CHAR_TYPE[]");
170 CHAR_TYPE
*first_buf
= 0;
171 CHAR_TYPE
*second_buf
= 0;
173 // convert the first argv to a string
174 if (first_argv
!= 0 && first_argv
[0] != 0)
176 first_argc
= ACE_OS::argv_to_string (first_argv
,
182 // convert the second argv to a string
183 if (second_argv
!= 0 && second_argv
[0] != 0)
185 second_argc
= ACE_OS::argv_to_string (second_argv
,
191 // Add the number of arguments in both the argvs.
192 this->argc_
= first_argc
+ second_argc
;
195 ACE_OS::strlen (first_buf
) + ACE_OS::strlen (second_buf
) + 1;
197 // Allocate memory to the lenght of the combined argv string.
199 CHAR_TYPE
[buf_len
+ 1]);
201 // copy the first argv string to the buffer
202 ACE_OS::strcpy (this->buf_
, first_buf
);
204 // concatenate the second argv string to the buffer
205 ACE_OS::strcat (this->buf_
, second_buf
);
207 // Delete the first and second buffers
209 delete [] second_buf
;
212 template <typename CHAR_TYPE
>
213 ACE_ARGV_T
<CHAR_TYPE
>::ACE_ARGV_T (bool substitute_env_args
)
214 : substitute_env_args_ (substitute_env_args
),
222 ACE_TRACE ("ACE_ARGV_T::ACE_ARGV_T Iterative");
224 // Nothing to do yet -- the user puts in arguments via add ()
227 template <typename CHAR_TYPE
>
229 ACE_ARGV_T
<CHAR_TYPE
>::add (const CHAR_TYPE
*next_arg
, bool quote_arg
)
231 // Only allow this to work in the "iterative" verion -- the
232 // ACE_ARGVs created with the one argument constructor.
233 if (!this->iterative_
)
239 this->length_
+= ACE_OS::strlen (next_arg
);
240 if (quote_arg
&& ACE_OS::strchr (next_arg
, ' ') != 0)
243 if (ACE_OS::strchr (next_arg
, '"') != 0)
244 for (const CHAR_TYPE
* p
= next_arg
; *p
!= '\0'; ++p
)
245 if (*p
== '"') ++this->length_
;
252 // Put the new argument at the end of the queue.
253 if (this->queue_
.enqueue_tail (ACE_ARGV_Queue_Entry_T
<CHAR_TYPE
> (next_arg
, quote_arg
)) == -1)
254 ACE_ERROR_RETURN ((LM_ERROR
,
255 ACE_TEXT ("Can't add more to ARGV queue")),
260 // Wipe argv_ and buf_ away so that they will be recreated if the
261 // user calls argv () or buf ().
262 if (this->argv_
!= 0)
264 for (int i
= 0; this->argv_
[i
] != 0; i
++)
265 ACE_OS::free ((void *) this->argv_
[i
]);
267 delete [] this->argv_
;
271 delete [] this->buf_
;
277 template <typename CHAR_TYPE
>
279 ACE_ARGV_T
<CHAR_TYPE
>::add (CHAR_TYPE
*argv
[], bool quote_args
)
281 for (int i
= 0; argv
[i
] != 0; i
++)
282 if (this->add (argv
[i
], quote_args
) == -1)
288 // Free up argv_ and buf_
290 template <typename CHAR_TYPE
>
291 ACE_ARGV_T
<CHAR_TYPE
>::~ACE_ARGV_T (void)
293 ACE_TRACE ("ACE_ARGV_T::~ACE_ARGV_T");
295 if (this->argv_
!= 0)
296 for (int i
= 0; this->argv_
[i
] != 0; i
++)
297 ACE_OS::free ((void *) this->argv_
[i
]);
299 delete [] this->argv_
;
300 delete [] this->buf_
;
303 // Create buf_ out of the queue_. This is only used in the
306 template <typename CHAR_TYPE
>
308 ACE_ARGV_T
<CHAR_TYPE
>::create_buf_from_queue (void)
310 ACE_TRACE ("ACE_ARGV_T::create_buf_from_queue");
312 // If the are no arguments, don't do anything
313 if (this->argc_
<= 0)
316 delete [] this->buf_
;
318 ACE_NEW_RETURN (this->buf_
,
319 CHAR_TYPE
[this->length_
+ this->argc_
],
322 // Get an iterator over the queue
323 ACE_Unbounded_Queue_Iterator
<ACE_ARGV_Queue_Entry_T
<CHAR_TYPE
> > iter (this->queue_
);
325 ACE_ARGV_Queue_Entry_T
<CHAR_TYPE
> *arg
= 0;
326 CHAR_TYPE
*ptr
= this->buf_
;
329 while (!iter
.done ())
331 // Get next argument from the queue.
338 if (ACE_OS::strchr (arg
->arg_
, '"') != 0)
341 for (const CHAR_TYPE
* p
= arg
->arg_
; *p
!= '\0'; ++p
)
343 if (*p
== '"' && prev
!= '\\') *ptr
++ = '\\';
349 len
= ACE_OS::strlen (arg
->arg_
);
350 // Copy the argument into buf_
351 ACE_OS::memcpy ((void *) ptr
,
352 (const void *) (arg
->arg_
),
353 len
* sizeof (CHAR_TYPE
));
354 // Move the pointer down.
361 len
= ACE_OS::strlen (arg
->arg_
);
362 // Copy the argument into buf_
363 ACE_OS::memcpy ((void *) ptr
,
364 (const void *) (arg
->arg_
),
365 len
* sizeof (CHAR_TYPE
));
366 // Move the pointer down.
370 // Put in an argument separating space.
374 // Put in the NUL terminator
380 // Close versioned namespace, if enabled by the user.
381 ACE_END_VERSIONED_NAMESPACE_DECL
383 #endif /* ACE_ARGV_CPP */