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