mirror of
https://github.com/mangosfour/server.git
synced 2025-12-11 16:37:03 +00:00
234 lines
7.9 KiB
C++
234 lines
7.9 KiB
C++
// -*- C++ -*-
|
|
|
|
//=============================================================================
|
|
/**
|
|
* @file Arg_Shifter.h
|
|
*
|
|
* $Id: Arg_Shifter.h 95972 2012-07-26 10:20:42Z johnnyw $
|
|
*
|
|
* @author Seth Widoff
|
|
*/
|
|
//=============================================================================
|
|
|
|
#ifndef ACE_ARG_SHIFTER_H
|
|
#define ACE_ARG_SHIFTER_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/Global_Macros.h"
|
|
|
|
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
|
|
|
|
/**
|
|
* @class ACE_Arg_Shifter_T
|
|
*
|
|
* @brief This ADT operates on a specified set of arguments (@a argv).
|
|
* As known arguments are scanned, they are shifted to the back of the
|
|
* @a argv vector, so deeper levels of argument parsing can locate the yet
|
|
* unprocessed arguments at the beginning of the vector.
|
|
*
|
|
* Nomenclature:
|
|
* argument - a member of the argv array
|
|
* option - an argument starting with '-'
|
|
* flag - synonym for "option"
|
|
* parameter value - an argument not starting with '-'
|
|
* parameter - synonym for "parameter value"
|
|
*
|
|
* The @c ACE_Arg_Shifter copies the pointers of the @a argv vector
|
|
* into a temporary array, emptying the original. As the @c ACE_Arg_Shifter
|
|
* iterates over the temporary array, it places known arguments in the rear
|
|
* of the original array and places the unknown ones in the beginning of the
|
|
* original array. It modifies argc to be the number of unknown arguments,
|
|
* so it looks to the caller as if the original array contains only unknown
|
|
* arguments. So, after @c ACE_Arg_Shifter has visited all the arguments
|
|
* in the temporary array, the original @a argv array appears to contain
|
|
* only the unknown arguments in their original order (but it actually has
|
|
* all the known arguments, too, beyond argc).
|
|
*/
|
|
template <typename CHAR_TYPE>
|
|
class ACE_Arg_Shifter_T
|
|
{
|
|
public:
|
|
// = Initialization and termination methods.
|
|
/**
|
|
* Initialize the ACE_Arg_Shifter to the vector over which to
|
|
* iterate. Optionally, also provide the temporary array for
|
|
* use in shifting the arguments. If ACE_Arg_Shifter must allocate
|
|
* the temporary vector internally and dynamic allocation fails, the
|
|
* ACE_Arg_Shifter will set all indicators to end of the vector,
|
|
* forbidding iteration. Following iteration over @a argv, the
|
|
* @a argc value will be updated to contain the number of
|
|
* unconsumed arguments.
|
|
* @param argc The number of strings in @a argv. @a argc will be
|
|
* updated to reflect the number of unconsumed arguments.
|
|
* @param argv The argument vector to shift. The string pointers in
|
|
* the vector will be reordered to place the @a argc unconsumed
|
|
* arguments at the front of the vector.
|
|
* @param temp A vector of @c CHAR_TYPE pointers at least @a argc
|
|
* elements long. The vector will be used for argument shifting as
|
|
* the specified @a argv vector is consumed. The vector must not
|
|
* be modified while this object exists. If this argument is 0
|
|
* (the default) the object will allocate and free the temporary
|
|
* vector transparently.
|
|
*/
|
|
ACE_Arg_Shifter_T (int& argc,
|
|
const CHAR_TYPE **argv,
|
|
const CHAR_TYPE **temp = 0);
|
|
|
|
/// Same behavior as the preceding constructor, but without the
|
|
/// "const" qualifier.
|
|
ACE_Arg_Shifter_T (int& argc,
|
|
CHAR_TYPE **argv,
|
|
CHAR_TYPE **temp = 0);
|
|
|
|
/// Destructor.
|
|
~ACE_Arg_Shifter_T (void);
|
|
|
|
/// Get the current head of the vector.
|
|
const CHAR_TYPE *get_current (void) const;
|
|
|
|
/**
|
|
* If the @a flag matches the current_arg of arg shifter
|
|
* this method will attempt to return the associated
|
|
* parameter value
|
|
*
|
|
* Safe to call without checking that a current arg exists
|
|
*
|
|
* In the following examples, a pointer to the char* "value" is ret
|
|
*
|
|
* eg: main -foobar value, main -FooBar value
|
|
* main -FOOBARvalue
|
|
*
|
|
* all of the above will all match the @a flag == -FooBar
|
|
* and will return a char* to "value"
|
|
*
|
|
* main -foobar 4 would succeed and return a char* to "4"
|
|
* main -foobar -4 does not succeed (-4 is not a parameter)
|
|
* but instead, would return 0
|
|
*
|
|
* 0 is returned:
|
|
* If the current argument does not match flag
|
|
* If there is no parameter found after a 'matched' flag
|
|
*
|
|
* If the flag is matched and the flag and parameter DO NOT RUN
|
|
* together, the flag is consumed, the parameter is returned,
|
|
* and the new current argument is the parameter value.
|
|
* ie '-foobarflag VALUE' leaves the new cur arg == "VALUE"
|
|
*
|
|
* If the flag is matched and the flag and parameter RUN
|
|
* together '-foobarflagVALUE', the flag is NOT consumed
|
|
* and the cur arg is left pointing to the entire flag/value pair
|
|
*/
|
|
const CHAR_TYPE *get_the_parameter (const CHAR_TYPE* flag);
|
|
|
|
/**
|
|
* Check if the current argument matches (case insensitive) @a flag
|
|
*
|
|
* ------------------------------------------------------------
|
|
*
|
|
* Case A: Perfect Match (case insensitive)
|
|
* 0 is returned.
|
|
*
|
|
* ie: when current_arg = "-foobar" or "-FOOBAR" or "-fooBAR"
|
|
* this->cur_arg_strncasecmp ("-FooBar);
|
|
* will return 0
|
|
*
|
|
* ------------------------------------------------------------
|
|
*
|
|
* Case B: Perfect Match (case insensitive) but the current_arg
|
|
* is longer than the flag. Returns a number equal to the index
|
|
* in the char* indicating the start of the extra characters
|
|
*
|
|
* ie: when current_arg = "-foobar98023"
|
|
* this->cur_arg_strncasecmp ("-FooBar);
|
|
* will return 7
|
|
*
|
|
* Notice: this number will always be > 0
|
|
*
|
|
* ------------------------------------------------------------
|
|
*
|
|
* Case C: If neither of Case A or B is met (no match)
|
|
* then -1 is returned
|
|
*/
|
|
int cur_arg_strncasecmp (const CHAR_TYPE *flag);
|
|
|
|
/// Consume @a number argument(s) by sticking them/it on the end of
|
|
/// the vector.
|
|
int consume_arg (int number = 1);
|
|
|
|
/// Place @a number arguments in the same relative order ahead of the
|
|
/// known arguments in the vector.
|
|
int ignore_arg (int number = 1);
|
|
|
|
/// Returns the number of args left to see in the vector.
|
|
int is_anything_left (void) const;
|
|
|
|
/// Returns 1 if there's a next item in the vector and it begins with
|
|
/// '-'.
|
|
int is_option_next (void) const;
|
|
|
|
/// Returns 1 if there's a next item in the vector and it doesn't
|
|
/// begin with '-'.
|
|
int is_parameter_next (void) const;
|
|
|
|
/// Returns the number of irrelevant args seen.
|
|
int num_ignored_args (void) const;
|
|
|
|
private:
|
|
/// Copy Constructor should not be used.
|
|
ACE_UNIMPLEMENTED_FUNC (ACE_Arg_Shifter_T (const ACE_Arg_Shifter_T<CHAR_TYPE>&))
|
|
|
|
/// Assignment '=' operator should not be used.
|
|
ACE_UNIMPLEMENTED_FUNC (ACE_Arg_Shifter_T operator= (const ACE_Arg_Shifter_T<CHAR_TYPE>&))
|
|
|
|
/// Refactor the constructor logic.
|
|
void init (void);
|
|
|
|
/// The size of the argument vector.
|
|
int& argc_;
|
|
|
|
/// The size of argv_.
|
|
int total_size_;
|
|
|
|
/// The temporary array over which we traverse.
|
|
const CHAR_TYPE **temp_;
|
|
|
|
/// The array in which the arguments are reordered.
|
|
const CHAR_TYPE **argv_;
|
|
|
|
/// The element in <temp_> we're currently examining.
|
|
int current_index_;
|
|
|
|
/// The index of <argv_> in which we'll stick the next unknown
|
|
/// argument.
|
|
int back_;
|
|
|
|
/// The index of <argv_> in which we'll stick the next known
|
|
/// argument.
|
|
/** This is not really the "front" at all. It's the point after
|
|
* which the unknown arguments end and at which the known arguments begin.
|
|
*/
|
|
int front_;
|
|
};
|
|
|
|
typedef ACE_Arg_Shifter_T<ACE_TCHAR> ACE_Arg_Shifter;
|
|
|
|
ACE_END_VERSIONED_NAMESPACE_DECL
|
|
|
|
#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
|
|
#include "ace/Arg_Shifter.cpp"
|
|
#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
|
|
|
|
#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
|
|
#pragma implementation ("Arg_Shifter.cpp")
|
|
#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
|
|
|
|
#include /**/ "ace/post.h"
|
|
|
|
#endif /* ACE_ARG_SHIFTER_H */
|