/**
 * @file cmdopt2.h
 *
 * CommandOptions - Classes for evaluating command line options.
 *
 * Copyright: 2002-2005 Thomas Wintergerst. All rights reserved.
 *
 * $FreeBSD$
 * $Id: cmdopt2.h,v 1.1.2.1 2006/02/28 21:35:45 thomas Exp $
 * $Project:    CAPI for BSD $
 * $Target:     Common source files for c4b tools $
 * @date        06.05.2005
 * @author      "Thomas Wintergerst" <twinterg@gmx.de>
 * <p>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * </p>
 */

#ifndef CMDOPT2_H
#define CMDOPT2_H

#include <string>
#include <vector>
#include <limits.h>

#ifdef WIN32

#  ifdef THWUTILS_EXPORTS
#     define THWUTILS_CMDOPT2_API       __declspec(dllexport)
#  else // THWUTILS_EXPORTS
#     define THWUTILS_CMDOPT2_API       __declespec(dllimport)
#  endif // THWUTILS_EXPORTS

#else // WIN32

#  define THWUTILS_CMDOPT2_API // no modifier necessary

#endif // WIN32



namespace thwutil {




// === Public declarations ===============================================





// === Class declarations ================================================





// --- Class for evaluating a command line -------------------------------

#ifdef WIN32
// VC complains about "std::vector<>" not beeing defined with "dllexport" to be
// used by client classes (member m_aOptions of CCmdLineEvaluator). Nevertheless
// it works.
#pragma warning(disable:4251)
#endif // WIN32

class THWUTILS_CMDOPT2_API CCmdOptBase;

/**
 * Class for evaluating a command line.
 *
 * This is the main class of the command line evaluation class suite. It
 * maintains the list of option objects and it contains member functions for the
 * real evaluation and for controlling this process.
 *
 * To use the command line evaluator class suite, an object instance of this
 * class must be created first. Thereafter one or more option objects may be
 * created while specified the address of the command line evaluator object as
 * the first parameter of the constructor. So the evaluator object will
 * successively build up the list of known command line options.
 *
 * Now the command line evaluator is ready for operation. The member function
 * EvalCommandLine() is called to evaluate a command line as passed to the
 * main() function of (nearly) every program. The evaluation stops at the first
 * non-option command line string or if an error occurs.
 *
 * There are several possibilities for controlling the way of processing of the
 * command line evaluator object. See the documentation of this classes member
 * functions.
 */
class THWUTILS_CMDOPT2_API CCmdLineEvaluator
{
   public:
      /// The result values for evaluating a command line.
      enum CmdLineEvalResult_t
      {
         CLE_OK,                ///< No error, function call successful.
         CLE_EVALUATION_TERMINATED,
                                ///< No error, but the evaluation was terminated
                                ///< because the last option handled has the
                                ///< corresponding flag set (e.g. used for
                                ///< "-h").
         CLE_ERR_UNKNOWN_OPTION,///< An unknown option was recognized on the
                                ///< command line.
         CLE_ERR_INVALID_PARAM, ///< The parameter for an option is invalid.
         CLE_ERR_INVALID_CONCATENATION,
                                ///< Some options should be concatenated into
                                ///< one string, but this is not possible.
                                ///< Concatenation is only allowed for single
                                ///< character options.
         CLE_ERR_DUPLICATE_OPTION
                                ///< An option was given a second time on the
                                ///< command line but it is defined to be
                                ///< allowed only once.
      };



      /**
       * Constructor.
       */
      CCmdLineEvaluator (void);
      
      /**
       * Destructor.
       */
      virtual ~CCmdLineEvaluator (void);
      
      /**
       * Set the active switch characters for command line evaluation.
       *
       * The string specified will be used as the set of characters starting an
       * option. If more than one character is specified, each character may
       * introduce an option, even mixed use on the same command line is
       * allowed.
       *
       * It is not possible to specify a string to start an option, i.e. start
       * every option with "--". This may only be accomplished by defining the
       * options themselves to start with an additional "-" at the beginning.
       *
       * The default switch characters are "-" and "/", thus if this function is
       * not called, the string of switching characters is initialized to "-/".
       *
       * @param pszNewSwitchChars
       *                        I: A string of switch characters introducing an
       *                           option. It must not be empty or the NULL
       *                           pointer.
       *
       * @retval None.
       *
       * @throws std::invalid_argument
       *                        The parameter was the NULL pointer or an empty
       *                        string.
       */
      virtual void SetSwitchCharacters
         (const char *pszNewSwitchChars);

      /**
       * Set the active parameter separator characters.
       *
       * The string specified will be used as the set of characters separating
       * options from their parameter if they are defined to have one. Each
       * character of the string may serve as the separation character.
       *
       * The default separator characters are ":" and "=", thus if this function
       * is not called, the string of separator characters is initialized to
       * ":=".
       *
       * @param pszNewParamSepChars
       *                        I: A string of separator characters between
       *                           options and their parameters. It must not be
       *                           empty or the NULL pointer.
       *
       * @retval None.
       *
       * @throws std::invalid_argument
       *                        The parameter was the NULL pointer or an empty
       *                        string.
       */
      virtual void SetParamSeparatorCharacters
         (const char *pszNewParamSepChars);
      
      /**
       * Add a new command line option.
       *
       * This member function is used to add option objects to the command line
       * evaluator. When evaluating a command line, these option objects are
       * compared to the strings of the command line. If no option objects are
       * added, the evaluation call will not deliver any recognized option.
       *
       * @param pCmdOpt         I: The address of the option object to add to
       *                           the internal list of known command line
       *                           options. It must not be NULL.
       *
       * @retval None.
       *
       * @throws std::invalid_argument
       *                        The parameter was the NULL pointer.
       */
      virtual void AddOption
         (CCmdOptBase *pCmdOpt);

      /**
       * Remove a command line option from the internal list.
       *
       * This member function is used to remove an option object from the
       * internal list of known options. It is usually called by the desctructor
       * of the option objects at program termination.
       *
       * The option is identified by its address. Thus it is not possible to
       * create an additional option object with a specific name to remove an
       * option with this name from our list.
       *
       * @param pCmdOpt         I: The address of the option to remove.
       *
       * @retval None.
       */
      virtual void RemoveOption
         (CCmdOptBase *pCmdOpt);

      /**
       * Reset options to default values.
       *
       * This function is used to reset all option objects to "not found". If
       * an option was recognized in a former evaluation call and it is defined
       * as unique, the next evaluation call will succeed even if this option
       * is found once more. Besides resetting the "was found" flag the values
       * for options with parameters are set to their default values, specified
       * during construction time of the respective option object.
       *
       * In short words: For all option objects in the internal list their
       * ResetValue() member function is called.
       *
       * @param None.
       *
       * @retval None.
       */
      virtual void ResetOptions (void);
      
      /**
       * Evaluate a command line and store the results locally.
       *
       * The task of this function is the evaluation of the command line, i.e.
       * the real purpose of this class. All the command line strings specified
       * by the pointer to an array of strings, the string count and the
       * starting index are searched for known options. Every string starting
       * with one of the switch characters is a candidate for an option string.
       * The evaluation stops at the first unknown or malformed option or when
       * a string not starting with a switch character is found. Strings
       * consisting only of a single switch character (e.g. "-") or of a double
       * switch character (e.g. "--") are assumed to be non-options. The single
       * switch character will be returned as the next command line string, the
       * double switch character will be overread and the next string is
       * returned.
       *
       * As mentioned before the parameter piEndIdx will be set to the index of
       * the command line string beeing a non-option behind all evaluated
       * options. If an error occurs, the parameter contains the index of the
       * erraneous command line string. This may be used to evaluate all options
       * at the beginning of the command line. Behind the options a program may
       * expect one or more file names that do not start with a switch
       * character.
       *
       * Options consisting of a single character as the option name may be
       * concatenated to a single string just starting with one single switch
       * character. E.g. the options "-a", "-b" and "-c" may be concatenated to
       * "-abc". This is not possible for options with longer names.
       *
       * @param iArgc           I: The number of strings in the array at
       *                           papszArgv.
       * @param papszArgv       I: An array of string pointers building up the
       *                           command line.
       * @param iStartIdx       I: The evaluation of the command line strings at
       *                           papszArgv starts at this index. This is used
       *                           to ignore some strings, e.g. the program file
       *                           name as the first string of every command
       *                           line.
       * @param piEndIdx        O: The index into papszArgv where the evaluation
       *                           stopped. If the result is O.K., it addresses
       *                           the first non-option behind the options. If
       *                           an error occurs, maybe because of an unknown
       *                           option on the command line, this parameter
       *                           points to the erraneous string.
       *
       * @retval CLE_OK         The command line evaluation was successful,
       *                        *piEndIdx contains the index of the first
       *                        non-option string.
       * @return CLE_EVALUATION_TERMINATED
       *                        The command line evaluation was terminated
       *                        because the last option handled has the
       *                        termination flag set. All other options handled
       *                        until this point are evaluated correctly,
       *                        *piEndIdx points to the command line argument
       *                        containing the option that caused the
       *                        termination.
       * @retval CLE_ERR_UNKNOWN_OPTION
       *                        The command line contains a string starting with
       *                        a switch character, but the string following it
       *                        could not be found in the internal list of known
       *                        options.
       * @retval CLE_ERR_INVALID_CONCATENATION
       *                        The current option has a name of at least two
       *                        characters and it is either following another
       *                        option in the same command line string (i.e. it
       *                        is concatenated to the previous option) or it is
       *                        followed by additional characters (provided the
       *                        current option is not defined to have
       *                        parameters).
       * @retval CLE_ERR_DUPLICATE_OPTION
       *                        The current option was already previously found
       *                        on the command line and it is defined to be
       *                        unique. The option is also assumed to be found a
       *                        second time if it was found in a former call to
       *                        this function without calling ResetOptions()
       *                        between the two calls.
       * @retval CLE_ERR_INVALID_PARAM
       *                        An option is defined to require a parameter but
       *                        none was specified or the parameter value was
       *                        invalid.
       */
      virtual CmdLineEvalResult_t EvalCommandLine
         (int    iArgc,
          char **papszArgv,
          int    iStartIdx,
          int   *piEndIdx);

      /**
       * Copy the local command line option values to public locations.
       *
       * The option objects may be constructed with the address of a memory
       * location to take the value of the option object after command line
       * evaluation. To perform the copy operation from the option objects to
       * these memory locations, this function is called. It should be called
       * after calling EvalCommandLine(), because else the options the options
       * are only set to their default values. And if an option was not found,
       * no copy operation is executed.
       *
       * This feature may be used in conjuction with other configuration
       * methods for a program. An application may first read its configuration
       * from configuration files or from a database. This data may be overriden
       * by command line options. The values for the options are copied to the
       * internal storage of the previously read configuration, so the program
       * only needs to read its configuration data from one location during its
       * run.
       *
       * @param pfnCallback     I: For each option found in a previous call to
       *                           EvalCommandLine the current value is copied
       *                           to the memory location specified at its
       *                           construction time. Before each copy operation
       *                           a caller provided callback function may be
       *                           called. So the caller e.g. may print out
       *                           every command line option and its value as
       *                           evaluated. If this feature is not needed,
       *                           this function pointer may be NULL.
       *
       * @retval None.
       */
      virtual void TakeCommandLineOptions
         (void (*pfnCallback) (CCmdOptBase *pOption) = NULL);
      
      /**
       * Convert an evaluation result value into a text string.
       *
       * The result values of the EvalCommandLine() member function may be
       * translated into readable strings by calling this function. The result
       * strings are constant and never invalidated.
       *
       * @param resVal          I: The command line evaluation result value to
       *                           translate into a string.
       *
       * @retval A pointer to the translated string.
       */
      virtual const char *ResultMsg
         (CmdLineEvalResult_t resVal);
   
   
   
   protected:
      /// The string of active option switch characters (default "-/").
      std::string m_strSwitchChars;
      
      /// The string of active parameter separator characters (default ":=").
      std::string m_strParamSepChars;
      
      /// The type definition for the array of defined command line options.
      typedef std::vector<CCmdOptBase *> CCmdOptionList;
      
      /// The array of defined command line options.
      CCmdOptionList m_aOptions;
   
   
   
   private:
   
   
   
}; // CCmdLineEvaluator

#ifdef WIN32
#pragma warning(default:4251)
#endif // WIN32





// --- Base class for all command line options ---------------------------

/**
 * Base class for all command line options.
 *
 * This class serves as the basis for all command line options. It defines all
 * necessary member functions that may be called by the command line evaluator
 * object or by other program code. The class definition contains pure virtual
 * functions, so there never will be an explicit object instance of this class.
 *
 * An option first owns a name. This name will be specified on the command line,
 * introduced by a switch character. The name may be case sensitive or
 * insensitive. It is the responsibility of the user of this class suite to only
 * define options with distinct names and with names that are not a prefix of
 * another options name.
 *
 * An option may be defined to have a parameter. The parameters type must be
 * defined by a new class derived from this base class. There are already
 * classes implemented which will normally suffice in most cases, e.g. classes
 * with integer, string or enumeration parameters.
 *
 * The parameter may directly follow the option name, start in the next string
 * of the command line or it may be separated from the option name by a
 * separator character. This behaviour is implemented in the command line
 * evaluator object.
 */
class THWUTILS_CMDOPT2_API CCmdOptBase
{
   public:
      /// The flags for several behaviours of an option.
      enum Flags_t
      {
         IGNORE_NAME_CASE     = 0x00000001,
                                ///< Case is not significant in the option name.
         HAS_PARAMETER        = 0x00000002,
                                ///< The option requires a parameter (may be
                                ///< optional if PARAM_OPTIONAL is also
                                ///< specified).
         PARAM_SEPARATOR      = 0x00000004,
                                ///< The parameter for the option must be
                                ///< separated from the option name by a
                                ///< separator character.
         PARAM_OPTIONAL       = 0x00000008,
                                ///< The parameter for the option is optional,
                                ///< i.e. may be left out.
         UINT_HEX_OUTPUT      = 0x00000010,
                                ///< When printing out the current parameter
                                ///< value the representation of unsigned
                                ///< integer values shall be hexadecimal.
         IGNORE_PARAM_CASE    = 0x00000020,
                                ///< The case is not significant for parameter
                                ///< values, supported for enumeration strings.
         UNIQUE_OPTION        = 0x00000040,
                                ///< The option may only be specified once on a
                                ///< command line.
         TERMINATE_EVALUATION = 0x00000080
                                ///< Command line evaluation shall stop when
                                ///< this option is recognized. This may be used
                                ///< e.g. for the help option "-h".
      };
      
      /**
       * Constructor.
       *
       * The constructor initializes all members of an object. Additionally this
       * object is added to the command line evaluator object specified as the
       * first parameter of this constructor.
       *
       * @param cmdLineEvaluator
       *                        I: The command line evaluator object this option
       *                           object will be a member of. The constructor
       *                           will call the member function AddOption() of
       *                           the command line evaluator object with this
       *                           objects address as the parameter.
       * @param pszName         I: The name of the option.
       * @param iFlags          I: A bitmask of flags controlling the behaviour
       *                           of this class and of the command line
       *                           evaluator. It is a combination of the values
       *                           of the enumeration Flags_t.
       */
      CCmdOptBase
         (CCmdLineEvaluator &cmdLineEvaluator,
          const char        *pszName,
          int                iFlags);
      
      /**
       * Destructor.
       *
       * The only purpose of this destructor is to remove this option object
       * from its command line evaluator object.
       */
      virtual ~CCmdOptBase (void);
      
      /**
       * Get the name of this option.
       */
      virtual const std::string &GetName (void);
      
      /**
       * Compare the name of this option with a given string.
       *
       * The case significance is taken from the m_iFlags member variable.
       *
       * @param pszStr          I: The string to compare the option name with.
       *                           It must not be NULL, but the empty string is
       *                           accepted and will lead to a false result.
       *
       * @retval true           The string specified is identical (according to
       *                        the case significance setting in the m_iFlags
       *                        member variable).
       * @retval false          The string specified is not equal to the option
       *                        name.
       *
       * @throws std::invalid_argument
       *                        The parameter is the NULL pointer.
       */
      virtual bool CompareName
         (const char *pszStr);
      
      /**
       * Set the flag if the option was found to the specified value.
       */
      virtual void SetFound
         (bool f);
      
      /**
       * Query if the option was found.
       */
      virtual bool WasFound (void);
      
      /**
       * Query if this option has a parameter.
       */
      virtual bool HasParameter (void);
      
      /**
       * Query if this option has a parameter with a separator from its name.
       */
      virtual bool HasParamSeparator (void);
      
      /**
       * Query if this option has a parameter that is optional.
       */
      virtual bool IsParamOptional (void);
      
      /**
       * Query if this option must be unique on the command line.
       */
      virtual bool IsUnique (void);
      
      /**
       * Query if this option shall terminate the command line evaluation
       * process.
       */
      virtual bool TerminateEvaluation (void);
      
      /**
       * Evaluate a parameter string for this option.
       *
       * This is a dummy implementation that only returns CLE_ERR_INVALID_PARAM.
       * Derived classes supporting parameters must overwrite this member
       * function and implement the functionality needed.
       *
       * @param pszStr          I: The string with the parameter to evaluate. It
       *                           may be the NULL pointer or the empty string.
       *
       * @retval CLE_OK         The parameter was evaluated successfully.
       * @retval CLE_ERR_INVALID_PARAM
       *                        The string specified does not represent a valid
       *                        parameter value for this option.
       */
      virtual CCmdLineEvaluator::CmdLineEvalResult_t EvalParam
         (const char *pszStr);
      
      /**
       * Reset the current value to default and option not found.
       *
       * This implementation only resets the current value for the flag "option
       * was found" to "false". Derived classes supporting parameter values
       * shall reset their current internal values to the respective default.
       *
       * @param None.
       *
       * @retval None.
       */
      virtual void ResetValue (void);
      
      /**
       * Copy the current value to the internally managed address.
       *
       * This function will be called by the TakeCommandLineOptions() member
       * function of the command line evaluator object. The option object shall
       * then copy the current option value to the memory address specified in
       * the constructor call of a derived class. As the parameter type will
       * differ between different option types there is no general
       * implementation. Each option class must implement this functionality by
       * its own.
       *
       * @note This function is only called if the member function WasFound()
       *       returned "true". So the CopyValue() member just needs to perform
       *       the copy operation. There is no need to check the found state of
       *       the option again.
       *
       * @param None.
       *
       * @retval None.
       */
      virtual void CopyValue (void) = 0;
      
      /**
       * Get a string representation of the current value.
       *
       * This function is intended to be used by the user of the command line
       * evaluation class suite. Sometimes it is necessary to log out every
       * command line option found and the possible parameter value recognized.
       *
       * @param None.
       *
       * @result A string representing the current (parameter) value of the
       *         option.
       */
      virtual std::string GetValueString (void) = 0;
   
   
   
   protected:
      /// The command line evaluator object this option object is a member of.
      CCmdLineEvaluator &m_oCmdLineEvaluator;

      /// The name of the option.
      std::string m_strName;
      
      /// The flags defining the behaviour of the option.
      int m_iFlags;
      
      /// The flag if the option was found.
      bool m_fFound;
   
   
   
   private:
      /// No assignment operator supported (only declared, not implemented).
      CCmdOptBase & operator= (const CCmdOptBase &);
   
   
   
}; // CCmdOptBase





// --- Class for a boolean option with or without parameters -------------

/**
 * Class for a boolean option with or without parameters.
 *
 * This class is intended for boolean options. The simplest usage is for options
 * that may specified on the command line or not. In this case the member
 * m_fFound is either "false" or "true". The current value will be set to
 * "false" on initialization, if the option is found, the value will change to
 * "true". To accomplish this the option object is created with a constructor
 * call with arguments up to pfValueTarget. The default values for the rest is
 * just fine for this usage.
 *
 * A more complicated way to use this class is the support of option parameters.
 * A parameter may be specified e.g. as one of the strings "yes", "no", simply
 * as the starting characters "y" or "n", or by specifying "+" or "-". This
 * class will just look at the first character of a parameter and by this decide
 * which option value to set. If the first character of the parameter does not
 * lead to an unambigous decision, the parameter will be evaluated as a
 * numerical value. Zero means "false", any other value will be treated as
 * "true". If the parameter is optional, a default value may be specified for
 * the case of a left out parameter.
 *
 * The last feature is used when there is the need to print out the current
 * option value as a string. By default the strings "yes" or "no" are returned
 * according to the current option value. These two string may be set e.g. to
 * "on" and "off" respectively.
 */
class THWUTILS_CMDOPT2_API CBooleanCmdOpt: public CCmdOptBase
{
   public:
      /**
       * Constructor.
       *
       * @param cmdLineEvaluator
       *                        I: The command line evaluator object this option
       *                           object will be a member of. It is forwarded
       *                           to the constructor of the base class.
       * @param pszName         I: The name of the option.
       * @param iFlags          I: A bitmask of flags controlling the behaviour
       *                           of this class and of the command line
       *                           evaluator. It is a combination of the values
       *                           of the enumeration Flags_t.
       * @param pfValueTarget   I: The address of a memory location to copy the
       *                           current option value to. If this feature is
       *                           not needed, this parameter may be NULL.
       * @param fDefaultValue   I: The default value for the option if it is
       *                           found on the command line. This is only
       *                           relevant if the option has an optional
       *                           parameter. If this parameter is left out on
       *                           the command line, this default value will be
       *                           entered as the current option value.
       * @param pszPosParamStartChars
       *                        I: This string is used for a boolean option with
       *                           a parameter. The first character of the
       *                           parameter specified on the command line will
       *                           be looked up in this string. If it is found,
       *                           the current option value will be set to
       *                           "true".
       * @param pszNegParamStartChars
       *                        I: This string is used for a boolean option with
       *                           a parameter. The first character of the
       *                           parameter specified on the command line will
       *                           be looked up in this string. If it is found,
       *                           the current option value will be set to
       *                           "false".
       * @param pszPosString    I: This parameter is used when GetValueString()
       *                           is called. If the current option value is
       *                           "true" this string will be returned, else
       *                           the string specified for pszNegString.
       * @param pszNegString    I: This parameter is used when GetValueString()
       *                           is called. If the current option value is
       *                           "false" this string will be returned, else
       *                           the string specified for pszPosString.
       */
      CBooleanCmdOpt
         (CCmdLineEvaluator &cmdLineEvaluator,
          const char        *pszName,
          int                iFlags,
          bool              *pfValueTarget,
          bool               fDefaultValue = true,
          const char        *pszPosParamStartChars = "yY+",
          const char        *pszNegParamStartChars = "nN-",
          const char        *pszPosString = "yes",
          const char        *pszNegString = "no");
      
      /**
       * Destructor.
       */
      virtual ~CBooleanCmdOpt (void);
   
      /**
       * Set the flag if the option was found to the specified value.
       */
      virtual void SetFound
         (bool f);
      
      /**
       * Evaluate a parameter string for this option.
       *
       * This function examines the first character of this functions' argument.
       * If it is found in the string a positive option value
       * (m_strPosParamStartChars), the current option value is set to "true",
       * if the character is found in the string for negative values it is set
       * to "false". If it is not found in both strings, the parameter will be
       * treated as a numerical value. Zero means "false", any other value leads
       * to "true".
       *
       * @param pszStr          I: The string with the parameter to evaluate. It
       *                           may be the NULL pointer or the empty string.
       *
       * @retval CLE_OK         The parameter was evaluated successfully.
       * @retval CLE_ERR_INVALID_PARAM
       *                        The string specified does not represent a valid
       *                        parameter value for this option, i.e. it is NULL
       *                        or the empty string and the parameter is not
       *                        optional.
       */
      virtual CCmdLineEvaluator::CmdLineEvalResult_t EvalParam
         (const char *pszStr);
      
      /**
       * Copy the current value to the internally managed address.
       *
       * This function simply copies the current option value to the memory
       * location specified in the constructor call. If it was given as the NULL
       * pointer, no copy operation will take place.
       *
       * @param None.
       *
       * @retval None.
       */
      virtual void CopyValue (void);
      
      /**
       * Get a string representation of the current value.
       *
       * This function returns the current value of the member strings
       * m_strPosValue and m_strNegValue respectively, according to the current
       * option value. The two strings may be specified in the constructor or
       * set later by using SetPositiveString() or SetNegativeString().
       *
       * @param None.
       *
       * @result A string representing the current (parameter) value of the
       *         option.
       */
      virtual std::string GetValueString (void);
      
      /**
       * Get the current value of the option.
       */
      virtual bool GetValue (void);
      
      /**
       * Set the parameter starting characters for positive values.
       */
      virtual void SetPositiveParamChars
         (const char *psz);
      
      /**
       * Set the parameter starting characters for negative values.
       */
      virtual void SetNegativeParamChars
         (const char *psz);
      
      /**
       * Set the string representation for positive values.
       */
      virtual void SetPositiveString
         (const char *psz);
      
      /**
       * Set the string representation for negative values.
       */
      virtual void SetNegativeString
         (const char *psz);
   
   

   protected:
      /// The current parameter starting characters for positive values (default
      /// "yY+").
      std::string m_strPosParamStartChars;
      
      /// The current parameter starting characters for negative values (default
      /// "nN-").
      std::string m_strNegParamStartChars;
      
      /// The default value for the option.
      bool m_fDefaultValue;
      
      /// The current option value.
      bool m_fCurrValue;
      
      /// The reference to the target for the option value.
      bool *m_pfValueTarget;
      
      /// The string representation for positive values for GetValueString().
      std::string m_strPosValue;
      
      /// The string representation for negative values for GetValueString().
      std::string m_strNegValue;
   
   
   
   private:
      /// No assignment operator supported (only declared, not implemented).
      CBooleanCmdOpt & operator= (const CBooleanCmdOpt &);
   
   
   
}; // CBooleanCmdOpt





// --- Class for an option with a signed integer parameter ---------------

/**
 * Class for an option with a signed integer parameter.
 *
 * This class maintains a signed integer member variable with the current option
 * value. A default value may be specified in the constructor call, likewise a
 * minimum and a maximum value. If the current option value should be set
 * through a parameter, the resulting value will be checked to these limits
 * before really taking this new value.
 *
 * The parameter string for this option may be spefied on the command line in
 * decimal, octal or hexadecimal representation, provided the three forms are
 * distinguished by their normal prefixes. I.e. octal numbers start with a "0",
 * hexadecimal number start with "0x" and all others are assumed to be decimal.
 * The decimal representation may also be preceeded by a sign.
 */
class THWUTILS_CMDOPT2_API CIntParamCmdOpt: public CCmdOptBase
{
   public:
      /**
       * Constructor.
       *
       * @param cmdLineEvaluator
       *                        I: The command line evaluator object this option
       *                           object will be a member of. It is passed to
       *                           the base constructor.
       * @param pszName         I: The name of the option.
       * @param iFlags          I: A bitmask of flags controlling the behaviour
       *                           of this class and of the command line
       *                           evaluator. It is a combination of the values
       *                           of the enumeration Flags_t.
       * @param piValueTarget   I: A memory location for copying the current
       *                           option value to when CopyValue() is called.
       *                           If this feature is not needed, this may be
       *                           the NULL pointer.
       * @param iDefaultValue   I: The default value for the option. This is
       *                           normally used for options with optional
       *                           parameters when the parameter is left out on
       *                           the command line.
       * @param iMinValue       I: This argument may be specified as the minimum
       *                           allowed value for the option. If a parameter
       *                           leads to a value below this limit, this value
       *                           is not stored into the current option value.
       * @param iMaxValue       I: This argument may be specified as the maximum
       *                           allowed value for the option. If a parameter
       *                           leads to a value above this limit, this value
       *                           is not stored into the current option value.
       */
      CIntParamCmdOpt
         (CCmdLineEvaluator &cmdLineEvaluator,
          const char        *pszName,
          int                iFlags,
          int               *piValueTarget,
          int                iDefaultValue = 0,
          int                iMinValue = INT_MIN,
          int                iMaxValue = INT_MAX);
      
      /**
       * Destructor.
       */
      virtual ~CIntParamCmdOpt (void);
   
      /**
       * Evaluate a parameter string for this option.
       *
       * Here the function argument is interpreted as a (signed) integer value.
       * The only checks that will be performed, are the test for the NULL
       * pointer or the empty string for the argument and the tests for the
       * minimum and maximum values for this option. It is not verified that the
       * argument is really numerical. If a text string is passed, the current
       * option value will simply be set to zero (if the minimum and maximum
       * values allow this).
       *
       * @param pszStr          I: The string parameter to evaluate as an
       *                           integer value.
       *
       * @retval CLE_OK         The parameter could successfully be evaluated to
       *                        a signed integer value.
       * @retval CLE_INVALID_PARAM
       *                        The function argument is the NULL pointer or the
       *                        empty string and the parameter is not optional.
       */
      virtual CCmdLineEvaluator::CmdLineEvalResult_t EvalParam
         (const char *pszStr);
      
      /**
       * Reset the current value to default and option not found.
       */
      virtual void ResetValue (void);
      
      /**
       * Copy the current value to the internally managed address.
       */
      virtual void CopyValue (void);
      
      /**
       * Get a string representation of the current value.
       */
      virtual std::string GetValueString (void);
   
      /**
       * Get the current value of the option.
       */
      virtual int GetValue (void);
      
   

   protected:
      /// The default value for the option.
      int m_iDefaultValue;
      
      /// The allowed maximum value for the option.
      int m_iMinimumValue;
      
      /// The allowed minimum value for the option.
      int m_iMaximumValue;
      
      /// The current option value.
      int m_iCurrValue;
      
      /// The reference to the target for the option value.
      int *m_piValueTarget;
      
   
   
   
   private:
      /// No assignment operator supported (only declared, not implemented).
      CIntParamCmdOpt & operator= (const CIntParamCmdOpt &);
   
   
   
}; // CIntParamCmdOpt





// --- Class for an option with an unsigned integer parameter ------------

/**
 * Class for an option with an unsigned integer parameter.
 *
 * This class is very much similar to CIntParamCmdOpt. But here an unsigned
 * integer variable is maintained. In addition to the normal decimal output of
 * the GetValueString() function like in class CIntParamCmdOpt, the value of an
 * unsigned option may also be returned as a hexadecimal representation. See the
 * m_iFlags member of the base class CCmdOptBase.
 *
 * The parameter string for this option may be spefied on the command line in
 * decimal, octal or hexadecimal representation, provided the three forms are
 * distinguished by their normal prefixes. I.e. octal numbers start with a "0",
 * hexadecimal number start with "0x" and all others are assumed to be decimal.
 */
class THWUTILS_CMDOPT2_API CUIntParamCmdOpt: public CCmdOptBase
{
   public:
      /**
       * Constructor.
       *
       * @param cmdLineEvaluator
       *                        I: The command line evaluator object this option
       *                           object will be a member of. It is passed to
       *                           the base constructor.
       * @param pszName         I: The name of the option.
       * @param iFlags          I: A bitmask of flags controlling the behaviour
       *                           of this class and of the command line
       *                           evaluator. It is a combination of the values
       *                           of the enumeration Flags_t.
       * @param puValueTarget   I: A memory location for copying the current
       *                           option value to when CopyValue() is called.
       *                           If this feature is not needed, this may be
       *                           the NULL pointer.
       * @param uDefaultValue   I: The default value for the option. This is
       *                           normally used for options with optional
       *                           parameters when the parameter is left out on
       *                           the command line.
       * @param uMinValue       I: This argument may be specified as the minimum
       *                           allowed value for the option. If a parameter
       *                           leads to a value below this limit, this value
       *                           is not stored into the current option value.
       * @param uMaxValue       I: This argument may be specified as the maximum
       *                           allowed value for the option. If a parameter
       *                           leads to a value above this limit, this value
       *                           is not stored into the current option value.
       */
      CUIntParamCmdOpt
         (CCmdLineEvaluator &cmdLineEvaluator,
          const char        *pszName,
          int                iFlags,
          unsigned int      *puValueTarget,
          unsigned int       uDefaultValue = 0,
          unsigned int       uMinValue = 0,
          unsigned int       uMaxValue = UINT_MAX);
      
      /**
       * Destructor.
       */
      virtual ~CUIntParamCmdOpt (void);
   
      /**
       * Evaluate a parameter string for this option.
       *
       * Here the function argument is interpreted as a (signed) integer value.
       * The only checks that will be performed, are the test for the NULL
       * pointer or the empty string for the argument and the tests for the
       * minimum and maximum values for this option. It is not verified that the
       * argument is really numerical. If a text string is passed, the current
       * option value will simply be set to zero (if the minimum and maximum
       * values allow this).
       *
       * @param pszStr          I: The string parameter to evaluate as an
       *                           integer value.
       *
       * @retval CLE_OK         The parameter could successfully be evaluated to
       *                        a signed integer value.
       * @retval CLE_INVALID_PARAM
       *                        The function argument is the NULL pointer or the
       *                        empty string and the parameter is not optional.
       */
      virtual CCmdLineEvaluator::CmdLineEvalResult_t EvalParam
         (const char *pszStr);
      
      /**
       * Reset the current value to default and option not found.
       */
      virtual void ResetValue (void);
      
      /**
       * Copy the current value to the internally managed address.
       */
      virtual void CopyValue (void);
      
      /**
       * Get a string representation of the current value.
       */
      virtual std::string GetValueString (void);
   
      /**
       * Get the current value of the option.
       */
      virtual unsigned int GetValue (void);
      
   

   protected:
      /// The default value for the option.
      unsigned int m_uDefaultValue;
      
      /// The allowed maximum value for the option.
      unsigned int m_uMinimumValue;
      
      /// The allowed minimum value for the option.
      unsigned int m_uMaximumValue;
      
      /// The current option value.
      unsigned int m_uCurrValue;
      
      /// The reference to the target for the option value.
      unsigned int *m_puValueTarget;
      
   
   
   
   private:
      /// No assignment operator supported (only declared, not implemented).
      CUIntParamCmdOpt & operator= (const CUIntParamCmdOpt &);
   
   
   
}; // CUIntParamCmdOpt





// --- Class for an option with a string type parameter ------------------

/**
 * Class for an option with a string type parameter.
 *
 * This class is used for options with a simple string parameter. A maximum
 * length for the string value may be specified for the constructor call. When
 * the feature to copy the current option value to a specific memory location is
 * used, there are two methods distinguished by two distinct constructors. The
 * first one is used to copy the string value to a "normal" C-string memory
 * location of a fixed maximum size. The second form introduces an STL string
 * for the copy destination. For "real" strings the length is not very
 * important. But even in this case the caller may specify a maximum string
 * length for the option value.
 */
class THWUTILS_CMDOPT2_API CStringParamCmdOpt: public CCmdOptBase
{
   public:
      /**
       * Constructor.
       *
       * There are two constructor variants. This version is used to specify the
       * destination for copying the current option value to a memory location
       * as a simple C character array with a fixed maximum length.
       *
       * @param cmdLineEvaluator
       *                        I: The command line evaluator object this option
       *                           object will be a member of. It is passed to
       *                           the base constructor.
       * @param pszName         I: The name of the option.
       * @param iFlags          I: A bitmask of flags controlling the behaviour
       *                           of this class and of the command line
       *                           evaluator. It is a combination of the values
       *                           of the enumeration Flags_t.
       * @param pszValueTarget  I: The address of a memory location (character
       *                           vector) to copy the current option value to
       *                           in member function CopyValue(). If this
       *                           feature is not needed, this argument may be
       *                           the NULL pointer.
       * @param nLenValueTarget I: The size of the memory in bytes at
       *                           pszValueTarget. Even if pszValueTarget is the
       *                           NULL pointer, this argument must be set to a
       *                           reasonable maximum length. This is because
       *                           this length argument is used to check the
       *                           parameter length when assigning a string to
       *                           the current option value.
       * @param pszDefaultValue I: The default option value if the option
       *                           parameter is optional.
       */
      CStringParamCmdOpt
         (CCmdLineEvaluator &cmdLineEvaluator,
          const char        *pszName,
          int                iFlags,
          char              *pszValueTarget,
          size_t             nLenValueTarget,
          const char        *pszDefaultValue = NULL);

      /**
       * Constructor.
       *
       * There are two constructor variants. This version is used to specify the
       * destination for copying the current option value to a memory location
       * as a STL string object with an optional maximum length.
       *
       * @param cmdLineEvaluator
       *                        I: The command line evaluator object this option
       *                           object will be a member of. It is passed to
       *                           the base constructor.
       * @param pszName         I: The name of the option.
       * @param iFlags          I: A bitmask of flags controlling the behaviour
       *                           of this class and of the command line
       *                           evaluator. It is a combination of the values
       *                           of the enumeration Flags_t.
       * @param pstrValueTarget I: The address of a memory location (STL string
       *                           object) to copy the current option value to
       *                           in member function CopyValue(). If this
       *                           feature is not needed, this argument may be
       *                           the NULL pointer.
       * @param nMaxLenValueTarget
       *                        I: The maximum length for the parameter string.
       *                           This is used to check the parameter string
       *                           for validity when assigning it to the current
       *                           option value.
       * @param pszDefaultValue I: The default option value if the option
       *                           parameter is optional.
       */
      CStringParamCmdOpt
         (CCmdLineEvaluator &cmdLineEvaluator,
          const char        *pszName,
          int                iFlags,
          std::string       *pstrValueTarget,
          size_t             nMaxLenValueTarget = UINT_MAX,
          const char        *pszDefaultValue = NULL);
      
      /**
       * Destructor.
       */
      virtual ~CStringParamCmdOpt (void);
   
      /**
       * Evaluate a parameter string for this option.
       *
       * The parameter evaluation for a string option is very simple. The
       * parameter value is only checked for the NULL pointer or the empty
       * string (if the parameter is not optional) and for the maximum string
       * length desired.
       *
       * @param pszStr          I: The parameter to take as the current option
       *                           value string.
       *
       * @retval CLE_OK         The parameter could successfully be copied to
       *                        the internal maintained string object.
       * @retval CLE_INVALID_PARAM
       *                        The function argument is the NULL pointer or the
       *                        empty string and the parameter is not optional.
       */
      virtual CCmdLineEvaluator::CmdLineEvalResult_t EvalParam
         (const char *pszStr);
      
      /**
       * Reset the current value to default and option not found.
       */
      virtual void ResetValue (void);
      
      /**
       * Copy the current value to the internally managed address.
       */
      virtual void CopyValue (void);
      
      /**
       * Get a string representation of the current value.
       */
      virtual std::string GetValueString (void);
   
      /**
       * Get the current value of the option.
       */
      virtual const std::string &GetValue (void);
      
   
   
   protected:
      /// The default value for the option.
      std::string m_strDefaultValue;
      
      /// The maximum length for the value.
      size_t m_nMaxLenValue;
      
      /// The current option value.
      std::string m_strCurrValue;
      
      /// Flag if the value target is specified as a string or as a character
      /// array.
      bool m_fStringValueTarget;
      
      /// The reference to the target for the option value, if it is a string.
      std::string *m_pstrValueTarget;
      
      /// The reference to the target for the option value, if it is a character
      /// array (maximum length is in m_nMaxLenValue).
      char *m_pszValueTarget;
   
   
   
   private:
      /// No assignment operator supported (only declared, not implemented).
      CStringParamCmdOpt & operator= (const CStringParamCmdOpt &);

   
   
}; // CStringParamCmdOpt





// --- Class for an option with an enum parameter derived from a string --

/**
 * Class for an option with an enum parameter derived from a string.
 *
 * This class handles a mixture of an integer option and a string option. The
 * real option value is an integer value, but these values are specified on the
 * command line as mnemonic strings. This is an analogon to the enumeration type
 * in C/C++.
 *
 * The relation between the strings and the numerical values are specified as an
 * array of enumeration definitions. Each definition is a simple structure with
 * an integer value and a character pointer to the corresponding string. When
 * evaluating an option parameter this array is searched for the parameter
 * string. If the string is found, the current option value is set to the
 * corresponding integer value.
 *
 * The other way around the process goes for getting a string representation of
 * the current option value. The enumeration array is searched for the current
 * integer option value. The corresponding string is returned as the string
 * representation of the current option value.
 *
 * @note The integer values of the enumeration array need not in a specific
 *       order. They even do not need to be continous.
 */
class THWUTILS_CMDOPT2_API CEnumStringParamCmdOpt: public CCmdOptBase
{
   public:
      /// The type definition for the specification of possible enum values and
      /// their string representations.
      struct EnumDef_t
      {
         int         iValue;
         const char *pszString;
      };
      
      /**
       * Constructor.
       *
       * The constructor initializes all members of an object. Additionally this
       * object is added to the command line evaluator object specified as the
       * first parameter of this constructor.
       *
       * @param cmdLineEvaluator
       *                        I: The command line evaluator object this option
       *                           object will be a member of. It is passed to
       *                           the base constructor.
       * @param pszName         I: The name of the option.
       * @param iFlags          I: A bitmask of flags controlling the behaviour
       *                           of this class and of the command line
       *                           evaluator. It is a combination of the values
       *                           of the enumeration Flags_t.
       * @param piValueTarget   I: A memory location for copying the current
       *                           option value to when CopyValue() is called.
       *                           If this feature is not needed, this may be
       *                           the NULL pointer.
       * @param paEnumDef       I: The array of enumeration definitions for the
       *                           relation between integer values and strings.
       *                           This must not be the NULL pointer.
       * @param nLenEnumDef     I: The number of entries in the array at
       *                           paEnumDef. This value must not be null, there
       *                           must be at least one enumeration definition.
       * @param iDefaultValueIdx
       *                        I: The index for the default value for this
       *                           option into the enumeration array. This is
       *                           normally used for options with optional
       *                           parameters when the parameter is left out on
       *                           the command line.
       *
       * @throws std::invalid_argument
       *                        The enumeration array was specified as the NULL
       *                        pointer or the number of entries in this array
       *                        is zero.
       */
      CEnumStringParamCmdOpt
         (CCmdLineEvaluator &cmdLineEvaluator,
          const char        *pszName,
          int                iFlags,
          int               *piValueTarget,
          EnumDef_t         *paEnumDef,
          size_t             nLenEnumDef,
          int                iDefaultValueIdx = 0);
      
      /**
       * Destructor.
       */
      virtual ~CEnumStringParamCmdOpt (void);
   
      /**
       * Evaluate a parameter string for this option.
       *
       * This function first checks if the argument is the empty string and if
       * the parameter is not optional. If this is the case, an error is
       * returned.
       *
       * Else the parameter string is looked up in the array of enumerations. If
       * it is found, the corresponding integer value is stored as current
       * option value. If it is not found, an error is returned.
       *
       * @param pszStr          I: The string with the parameter to evaluate.
       *
       * @retval CLE_OK         The parameter was evaluated successfully.
       * @retval CLE_ERR_INVALID_PARAM
       *                        The string specified does not represent a valid
       *                        enumeration string for this option.
       */
      virtual CCmdLineEvaluator::CmdLineEvalResult_t EvalParam
         (const char *pszStr);
      
      /**
       * Reset the current value to default and option not found.
       */
      virtual void ResetValue (void);
      
      /**
       * Copy the current value to the internally managed address.
       */
      virtual void CopyValue (void);
      
      /**
       * Get a string representation of the current value.
       */
      virtual std::string GetValueString (void);
   
      /**
       * Get the current value of the option.
       */
      virtual int GetValue (void);
      
   
   
   protected:
      /// The array of enum definitions provided by the caller.
      EnumDef_t *m_paEnumDef;
      
      /// The number of entries in the array at m_paEnumDef.
      size_t m_nLenEnumDef;
      
      /// The index of the default value into the enum definition array.
      int m_iDefaultValueIdx;
      
      /// The index of the current value into the enum definition array.
      int m_iCurrValueIdx;
      
      /// The reference to the target for the option value.
      int *m_piValueTarget;
   
   
   
   private:
      /// No assignment operator supported (only declared, not implemented).
      CEnumStringParamCmdOpt & operator= (const CEnumStringParamCmdOpt &);
   
   
   
}; // CEnumStringParamCmdOpt





// === Prototypes of interface functions =================================





} // namespace thwutil

#endif // CMDOPT2_H
