Arg_Shifter.h

Go to the documentation of this file.
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 */

Generated on Thu Nov 9 09:41:45 2006 for ACE by doxygen 1.3.6