summaryrefslogtreecommitdiff
path: root/ace/ARGV.h
blob: 1f3350fd24ea89fdccaa10f502d415ef2f438d6b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
// -*- C++ -*-

//==========================================================================
/**
 *  @file    ARGV.h
 *
 *  $Id$
 *
 *  @author Doug Schmidt <schmidt@cs.wustl.edu>
 *  @author Everett Anderson <eea1@cs.wustl.edu>
 */
//==========================================================================

#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/Unbounded_Queue.h"

// Open versioned namespace, if enabled by the user.
ACE_BEGIN_VERSIONED_NAMESPACE_DECL

/**
 * @class ACE_ARGV
 *
 * @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.
 */
class ACE_Export ACE_ARGV
{
public:
  // = Initialization and termination.
  /**
   * 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 ACE_TCHAR 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.
   */
  ACE_ARGV (const ACE_TCHAR 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.
   *
   * @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.
   */
  ACE_ARGV (ACE_TCHAR *argv[],
            bool substitute_env_args = true);

  /**
   * 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.
   */
  ACE_ARGV (ACE_TCHAR *first_argv[],
            ACE_TCHAR *second_argv[],
            bool substitute_env_args = true);

  /**
   * 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.
   */
  ACE_ARGV (bool substitute_env_args = true);

  /// Destructor.
  ~ACE_ARGV (void);

  /** @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 ACE_TCHAR *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.
   */
  ACE_TCHAR **argv (void);

  /// Returns the current number of arguments.
  int argc (void) 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 ACE_TCHAR *buf (void);

  //@}

  /// Dump the state of this object.
  void dump (void) 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.
   *
   * @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 ACE_TCHAR *next_arg);

  /**
   * 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.
   *
   * @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 (ACE_TCHAR *argv[]);

private:
  /// Copy constructor not implemented.
  ACE_ARGV (const ACE_ARGV&);

  /// Assignment operator not implemented.
  ACE_ARGV operator= (const ACE_ARGV&);

  /// Creates buf_ from the queue of added args, deletes previous buf_.
  int create_buf_from_queue (void);

  /// Converts buf_ into the ACE_TCHAR *argv[] format.
  int string_to_argv (void);

  /// Returns the string created from argv in buf and
  /// returns the number of arguments.
  int argv_to_string (ACE_TCHAR **argv, ACE_TCHAR *&buf);

  /// 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.
  ACE_TCHAR **argv_;

  /// Buffer containing the <argv> contents.
  ACE_TCHAR *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<ACE_TCHAR *> queue_;
};

// 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/post.h"
#endif /* ACE_ARGUMENT_VECTOR_H */