00001 // -*- C++ -*- 00002 00003 //============================================================================= 00004 /** 00005 * @file Arg_Shifter.h 00006 * 00007 * Arg_Shifter.h,v 4.25 2006/06/09 10:12:03 jwillemsen Exp 00008 * 00009 * @author Seth Widoff 00010 */ 00011 //============================================================================= 00012 00013 #ifndef ACE_ARG_SHIFTER_H 00014 #define ACE_ARG_SHIFTER_H 00015 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/Global_Macros.h" 00025 00026 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 00027 00028 /** 00029 * @class ACE_Arg_Shifter_T 00030 * 00031 * @brief This ADT operates on a specified set of arguments (@a argv). 00032 * As known arguments are scanned, they are shifted to the back of the 00033 * @a argv vector, so deeper levels of argument parsing can locate the yet 00034 * unprocessed arguments at the beginning of the vector. 00035 * 00036 * The @c ACE_Arg_Shifter copies the pointers of the @a argv vector 00037 * into a temporary array. As the @c ACE_Arg_Shifter iterates over 00038 * the copied vector, it places known arguments in the rear of the 00039 * vector, leaving the unknown ones in the beginning. So, after having 00040 * visited all the arguments in the temporary vector, @c ACE_Arg_Shifter 00041 * has placed all the unknown arguments in their original order at 00042 * the front of original @a argv. 00043 */ 00044 template <typename CHAR_TYPE> 00045 class ACE_Arg_Shifter_T 00046 { 00047 public: 00048 // = Initialization and termination methods. 00049 /** 00050 * Initialize the ACE_Arg_Shifter to the vector over which to 00051 * iterate. Optionally, also provide the temporary array for 00052 * use in shifting the arguments. If ACE_Arg_Shifter must allocate 00053 * the temporary vector internally and dynamic allocation fails, the 00054 * ACE_Arg_Shifter will set all indicators to end of the vector, 00055 * forbidding iteration. Following iteration over @a argv, the 00056 * @a argc value will be updated to contain the number of 00057 * unconsumed arguments. 00058 * @param argc The number of strings in @a argv. @a argc will be 00059 * updated to reflect the number of unconsumed arguments. 00060 * @param argv The argument vector to shift. The string pointers in 00061 * the vector will be reordered to place the @a argc unconsumed 00062 * arguments at the front of the vector. 00063 * @param temp A vector of @c CHAR_TYPE pointers at least @a argc 00064 * elements long. The vector will be used for argument shifting as 00065 * the specified @a argv vector is consumed. The vector must not 00066 * be modified while this object exists. If this argument is 0 00067 * (the default) the object will allocate and free the temporary 00068 * vector transparently. 00069 */ 00070 ACE_Arg_Shifter_T (int& argc, 00071 const CHAR_TYPE **argv, 00072 const CHAR_TYPE **temp = 0); 00073 00074 /// Same behavior as the preceding constructor, but without the 00075 /// "const" qualifier. 00076 ACE_Arg_Shifter_T (int& argc, 00077 CHAR_TYPE **argv, 00078 CHAR_TYPE **temp = 0); 00079 00080 /// Destructor. 00081 ~ACE_Arg_Shifter_T (void); 00082 00083 /// Get the current head of the vector. 00084 const CHAR_TYPE *get_current (void) const; 00085 00086 /** 00087 * If the @a flag matches the current_arg of arg shifter 00088 * this method will attempt to return the associated 00089 * parameter value 00090 * 00091 * Safe to call without checking that a current arg exists 00092 * 00093 * In the following examples, a pointer to the char* "value" is ret 00094 * 00095 * eg: main -foobar value, main -FooBar value 00096 * main -FOOBARvalue 00097 * 00098 * all of the above will all match the @a flag == -FooBar 00099 * and will return a char* to "value" 00100 * 00101 * main -foobar 4 would succeed and return a char* to "4" 00102 * main -foobar -4 does not succeed (-4 is not a parameter) 00103 * but instead, would return 0 00104 * 00105 * 0 is returned: 00106 * If the current argument does not match flag 00107 * If there is no parameter found after a 'matched' flag 00108 * 00109 * If the flag is matched and the flag and paramter DO NOT RUN 00110 * together, the flag is consumed, the parameter is returned, 00111 * and the new current argument is the parameter value. 00112 * ie '-foobarflag VALUE' leaves the new cur arg == "VALUE" 00113 * 00114 * If the flag is matched and the flag and parameter RUN 00115 * together '-foobarflagVALUE', the flag is NOT consumed 00116 * and the cur arg is left pointing to the entire flag/value pair 00117 */ 00118 const CHAR_TYPE *get_the_parameter (const CHAR_TYPE* flag); 00119 00120 /** 00121 * Check if the current argument matches (case insensitive) <flag> 00122 * 00123 * ------------------------------------------------------------ 00124 * 00125 * Case A: Perfect Match (case insensitive) 00126 * 0 is returned. 00127 * 00128 * ie: when current_arg = "-foobar" or "-FOOBAR" or "-fooBAR" 00129 * this->cur_arg_strncasecmp ("-FooBar); 00130 * will return 0 00131 * 00132 * ------------------------------------------------------------ 00133 * 00134 * Case B: Perfect Match (case insensitive) but the current_arg 00135 * is longer than the flag. Returns a number equal to the index 00136 * in the char* indicating the start of the extra characters 00137 * 00138 * ie: when current_arg = "-foobar98023" 00139 * this->cur_arg_strncasecmp ("-FooBar); 00140 * will return 7 00141 * 00142 * Notice: this number will always be > 0 00143 * 00144 * ------------------------------------------------------------ 00145 * 00146 * Case C: If neither of Case A or B is met (no match) 00147 * then -1 is returned 00148 */ 00149 int cur_arg_strncasecmp (const CHAR_TYPE *flag); 00150 00151 /// Consume @a number argument(s) by sticking them/it on the end of 00152 /// the vector. 00153 int consume_arg (int number = 1); 00154 00155 /// Place @a number arguments in the same relative order ahead of the 00156 /// known arguments in the vector. 00157 int ignore_arg (int number = 1); 00158 00159 /// Returns the number of args left to see in the vector. 00160 int is_anything_left (void) const; 00161 00162 /// Returns 1 if there's a next item in the vector and it begins with 00163 /// '-'. 00164 int is_option_next (void) const; 00165 00166 /// Returns 1 if there's a next item in the vector and it doesn't 00167 /// begin with '-'. 00168 int is_parameter_next (void) const; 00169 00170 /// Returns the number of irrelevant args seen. 00171 int num_ignored_args (void) const; 00172 00173 private: 00174 /// Copy Constructor should not be used. 00175 ACE_UNIMPLEMENTED_FUNC (ACE_Arg_Shifter_T (const ACE_Arg_Shifter_T<CHAR_TYPE>&)) 00176 00177 /// Assignment '=' operator should not be used. 00178 ACE_UNIMPLEMENTED_FUNC (ACE_Arg_Shifter_T operator= (const ACE_Arg_Shifter_T<CHAR_TYPE>&)) 00179 00180 /// Refactor the constructor logic. 00181 void init (void); 00182 00183 /// The size of the argument vector. 00184 int& argc_; 00185 00186 /// The size of argv_. 00187 int total_size_; 00188 00189 /// The temporary array over which we traverse. 00190 const CHAR_TYPE **temp_; 00191 00192 /// The array in which the arguments are reordered. 00193 const CHAR_TYPE **argv_; 00194 00195 /// The element in <temp_> we're currently examining. 00196 int current_index_; 00197 00198 /// The index of <argv_> in which we'll stick the next unknown 00199 /// argument. 00200 int back_; 00201 00202 /// The index of <argv_> in which we'll stick the next known 00203 /// argument. 00204 int front_; 00205 }; 00206 00207 typedef ACE_Arg_Shifter_T<ACE_TCHAR> ACE_Arg_Shifter; 00208 00209 ACE_END_VERSIONED_NAMESPACE_DECL 00210 00211 #if defined (ACE_TEMPLATES_REQUIRE_SOURCE) 00212 #include "ace/Arg_Shifter.cpp" 00213 #endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ 00214 00215 #if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) 00216 #pragma implementation ("Arg_Shifter.cpp") 00217 #endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ 00218 00219 #include /**/ "ace/post.h" 00220 00221 #endif /* ACE_ARG_SHIFTER_H */