Changes to attempt to silence bcc64x
[ACE_TAO.git] / ACE / ace / Arg_Shifter.h
blobc714b992ecb5b9a0a008605cbb0b7b194e5b2e89
1 // -*- C++ -*-
3 //=============================================================================
4 /**
5 * @file Arg_Shifter.h
7 * @author Seth Widoff
8 */
9 //=============================================================================
11 #ifndef ACE_ARG_SHIFTER_H
12 #define ACE_ARG_SHIFTER_H
14 #include /**/ "ace/pre.h"
16 #include /**/ "ace/ACE_export.h"
18 #if !defined (ACE_LACKS_PRAGMA_ONCE)
19 # pragma once
20 #endif /* ACE_LACKS_PRAGMA_ONCE */
22 #include "ace/Global_Macros.h"
24 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
26 /**
27 * @class ACE_Arg_Shifter_T
29 * @brief This ADT operates on a specified set of arguments (@a argv).
30 * As known arguments are scanned, they are shifted to the back of the
31 * @a argv vector, so deeper levels of argument parsing can locate the yet
32 * unprocessed arguments at the beginning of the vector.
34 * Nomenclature:
35 * argument - a member of the argv array
36 * option - an argument starting with '-'
37 * flag - synonym for "option"
38 * parameter value - an argument not starting with '-'
39 * parameter - synonym for "parameter value"
41 * The @c ACE_Arg_Shifter copies the pointers of the @a argv vector
42 * into a temporary array, emptying the original. As the @c ACE_Arg_Shifter
43 * iterates over the temporary array, it places known arguments in the rear
44 * of the original array and places the unknown ones in the beginning of the
45 * original array. It modifies argc to be the number of unknown arguments,
46 * so it looks to the caller as if the original array contains only unknown
47 * arguments. So, after @c ACE_Arg_Shifter has visited all the arguments
48 * in the temporary array, the original @a argv array appears to contain
49 * only the unknown arguments in their original order (but it actually has
50 * all the known arguments, too, beyond argc).
52 template <typename CHAR_TYPE>
53 class ACE_Arg_Shifter_T
55 public:
56 /**
57 * Initialize the ACE_Arg_Shifter to the vector over which to
58 * iterate. Optionally, also provide the temporary array for
59 * use in shifting the arguments. If ACE_Arg_Shifter must allocate
60 * the temporary vector internally and dynamic allocation fails, the
61 * ACE_Arg_Shifter will set all indicators to end of the vector,
62 * forbidding iteration. Following iteration over @a argv, the
63 * @a argc value will be updated to contain the number of
64 * unconsumed arguments.
65 * @param argc The number of strings in @a argv. @a argc will be
66 * updated to reflect the number of unconsumed arguments.
67 * @param argv The argument vector to shift. The string pointers in
68 * the vector will be reordered to place the @a argc unconsumed
69 * arguments at the front of the vector.
70 * @param temp A vector of @c CHAR_TYPE pointers at least @a argc
71 * elements long. The vector will be used for argument shifting as
72 * the specified @a argv vector is consumed. The vector must not
73 * be modified while this object exists. If this argument is 0
74 * (the default) the object will allocate and free the temporary
75 * vector transparently.
77 ACE_Arg_Shifter_T (int &argc,
78 const CHAR_TYPE **argv,
79 const CHAR_TYPE **temp = 0);
81 /// Same behavior as the preceding constructor, but without the
82 /// "const" qualifier.
83 ACE_Arg_Shifter_T (int &argc,
84 CHAR_TYPE **argv,
85 CHAR_TYPE **temp = 0);
87 /// Destructor.
88 ~ACE_Arg_Shifter_T ();
90 /// Get the current head of the vector.
91 const CHAR_TYPE *get_current () const;
93 /**
94 * If the @a flag matches the current_arg of arg shifter
95 * this method will attempt to return the associated
96 * parameter value
98 * Safe to call without checking that a current arg exists
100 * In the following examples, a pointer to the char* "value" is returned
102 * eg: main -foobar value, main -FooBar value
103 * main -FOOBARvalue
105 * all of the above will match the @a flag == -FooBar
106 * and will return a char* to "value"
108 * main -foobar 4 would succeed and return a char* to "4"
109 * main -foobar -4 does not succeed (-4 is not a parameter)
110 * but instead, would return 0
112 * 0 is returned:
113 * If the current argument does not match flag
114 * If there is no parameter found after a 'matched' flag
116 * If the flag is matched and the flag and parameter DO NOT RUN
117 * together, the flag is consumed, the parameter is returned,
118 * and the new current argument is the parameter value.
119 * ie '-foobarflag VALUE' leaves the new cur arg == "VALUE"
121 * If the flag is matched and the flag and parameter RUN
122 * together '-foobarflagVALUE', the flag is NOT consumed
123 * and the cur arg is left pointing to the entire flag/value pair
125 const CHAR_TYPE *get_the_parameter (const CHAR_TYPE *flag);
128 * Check if the current argument matches (case insensitive) @a flag
130 * ------------------------------------------------------------
132 * Case A: Perfect Match (case insensitive)
133 * 0 is returned.
135 * ie: when current_arg = "-foobar" or "-FOOBAR" or "-fooBAR"
136 * this->cur_arg_strncasecmp ("-FooBar");
137 * will return 0
139 * ------------------------------------------------------------
141 * Case B: Perfect Match (case insensitive) but the current_arg
142 * is longer than the flag. Returns a number equal to the index
143 * in the char* indicating the start of the extra characters
144 * after any initial spaces (see below).
146 * ie: when current_arg = "-foobar98023"
147 * this->cur_arg_strncasecmp ("-FooBar");
148 * will return 7
150 * Spaces separating the flag from its value (that are still part
151 * of the same argv element) are counted as part of the return value
153 * ie: when current_arg = "-foobar 98023"
154 * this->cur_arg_strncasecmp ("-FooBar");
155 * will return 8
157 * Notice: this number will always be > 0
159 * ------------------------------------------------------------
161 * Case C: If neither of Case A or B is met (no match)
162 * then -1 is returned
164 int cur_arg_strncasecmp (const CHAR_TYPE *flag);
166 /// Consume @a number argument(s) by sticking them/it on the end of
167 /// the vector.
168 int consume_arg (int number = 1);
170 /// Place @a number arguments in the same relative order ahead of the
171 /// known arguments in the vector.
172 int ignore_arg (int number = 1);
174 /// Returns the number of args left to see in the vector.
175 int is_anything_left () const;
177 /// Returns 1 if there's a next item in the vector and it begins with
178 /// '-'.
179 int is_option_next () const;
181 /// Returns 1 if there's a next item in the vector and it doesn't
182 /// begin with '-'.
183 int is_parameter_next () const;
185 /// Returns the number of irrelevant args seen.
186 int num_ignored_args () const;
188 private:
189 /// Copy Constructor should not be used.
190 ACE_Arg_Shifter_T (const ACE_Arg_Shifter_T<CHAR_TYPE> &) = delete;
192 /// Assignment '=' operator should not be used.
193 ACE_Arg_Shifter_T operator= (const ACE_Arg_Shifter_T<CHAR_TYPE> &) = delete;
195 /// Refactor the constructor logic.
196 void init ();
198 /// The size of the argument vector.
199 int &argc_;
201 /// The size of argv_.
202 int total_size_;
204 /// The temporary array over which we traverse.
205 const CHAR_TYPE **temp_;
207 /// The array in which the arguments are reordered.
208 const CHAR_TYPE **argv_;
210 /// The element in <temp_> we're currently examining.
211 int current_index_;
213 /// The index of <argv_> in which we'll stick the next unknown
214 /// argument.
215 int back_;
217 /// The index of <argv_> in which we'll stick the next known
218 /// argument.
219 /** This is not really the "front" at all. It's the point after
220 * which the unknown arguments end and at which the known arguments begin.
222 int front_;
225 typedef ACE_Arg_Shifter_T<ACE_TCHAR> ACE_Arg_Shifter;
227 ACE_END_VERSIONED_NAMESPACE_DECL
229 #include "ace/Arg_Shifter.cpp"
231 #include /**/ "ace/post.h"
233 #endif /* ACE_ARG_SHIFTER_H */