include/corelib/ncbiargs.hpp

Go to the documentation of this file.
00001 #ifndef CORELIB___NCBIARGS__HPP
00002 #define CORELIB___NCBIARGS__HPP
00003 
00004 /*  $Id: ncbiargs.hpp 164557 2009-06-29 13:26:26Z gouriano $
00005  * ===========================================================================
00006  *
00007  *                            PUBLIC DOMAIN NOTICE
00008  *               National Center for Biotechnology Information
00009  *
00010  *  This software/database is a "United States Government Work" under the
00011  *  terms of the United States Copyright Act.  It was written as part of
00012  *  the author's official duties as a United States Government employee and
00013  *  thus cannot be copyrighted.  This software/database is freely available
00014  *  to the public for use. The National Library of Medicine and the U.S.
00015  *  Government have not placed any restriction on its use or reproduction.
00016  *
00017  *  Although all reasonable efforts have been taken to ensure the accuracy
00018  *  and reliability of the software and data, the NLM and the U.S.
00019  *  Government do not and cannot warrant the performance or results that
00020  *  may be obtained by using this software or data. The NLM and the U.S.
00021  *  Government disclaim all warranties, express or implied, including
00022  *  warranties of performance, merchantability or fitness for any particular
00023  *  purpose.
00024  *
00025  *  Please cite the author in any work or product based on this material.
00026  *
00027  * ===========================================================================
00028  *
00029  * Author:  Denis Vakatov
00030  *
00031  *
00032  */
00033 
00034 /// @file ncbiargs.hpp
00035 /// Defines command line argument related classes.
00036 ///
00037 /// The CArgDescriptions and CArgDesc classes are used for describing
00038 /// unparsed arguments; CArgs and CArgValue for parsed argument values;
00039 /// CArgException and CArgHelpException for argument exceptions; and CArgAllow, 
00040 /// CArgAllow_{Strings, ..., Integers, Doubles} for argument constraints.
00041 ///
00042 /// The following description is included as applies to several classes in
00043 /// this file:
00044 ///
00045 /// Parsing and validation of command-line arguments are done according to
00046 /// user-provided descriptions. The command line has the following syntax:
00047 ///
00048 /// Command string:
00049 ///
00050 ///    progname  {arg_key, arg_key_opt, arg_key_dflt, arg_flag} [--]
00051 ///              {arg_pos} {arg_pos_opt, arg_pos_dflt}
00052 ///              {arg_extra} {arg_extra_opt}
00053 ///
00054 /// where:
00055 ///
00056 ///   arg_key        :=  -<key> <value>    -- (mandatory)
00057 ///   arg_key_opt    := [-<key> <value>]   -- (optional, without default value)
00058 ///   arg_key_dflt   := [-<key> <value>]   -- (optional, with default value)
00059 ///   arg_flag       := -<flag>            -- (always optional)
00060 ///   "--" is an optional delimiter to indicate the beginning of pos. args
00061 ///   arg_pos        := <value>            -- (mandatory)
00062 ///   arg_pos_opt    := [<value>]          -- (optional, without default value)
00063 ///   arg_pos_dflt   := [<value>]          -- (optional, with default value)
00064 ///   arg_extra      := <value>            -- (dep. on the constraint policy)
00065 ///   arg_extra_opt  := [<value>]          -- (dep. on the constraint policy)
00066 ///
00067 /// and:
00068 ///
00069 ///   <key> must be followed by <value>
00070 ///   <flag> and <key> are case-sensitive, and they can contain
00071 ///                    only alphanumeric characters
00072 ///   <value> is an arbitrary string (additional constraints can
00073 ///           be applied in the argument description, see "EType")
00074 ///
00075 /// {arg_pos***} and {arg_extra***} -- position-dependent arguments, with
00076 /// no tag preceding them.
00077 /// {arg_pos***} -- have individual names and descriptions (see methods
00078 /// AddPositional***).
00079 /// {arg_extra***} have one description for all (see method AddExtra).
00080 /// User can apply constraints on the number of mandatory and optional
00081 /// {arg_extra***} arguments.
00082 
00083 
00084 #include <corelib/ncbistd.hpp>
00085 #include <corelib/ncbiobj.hpp>
00086 #include <corelib/ncbi_limits.h>
00087 #include <memory>
00088 #include <set>
00089 #include <list>
00090 #include <vector>
00091 
00092 
00093 /** @addtogroup Args
00094  *
00095  * @{
00096  */
00097 
00098 
00099 BEGIN_NCBI_SCOPE
00100 
00101 
00102 // Some necessary forward declarations.
00103 class CNcbiArguments;
00104 class CArgAllow;
00105 
00106 
00107 /////////////////////////////////////////////////////////////////////////////
00108 ///
00109 /// CArgException --
00110 ///
00111 /// Define exceptions class for incorrectly formed arguments.
00112 ///
00113 /// CArgException inherits its basic functionality from CCoreException
00114 /// and defines additional error codes for malformed arguments.
00115 
00116 class  CArgException : public CCoreException
00117 {
00118 public:
00119     /// Error types for improperly formatted arguments.
00120     ///
00121     /// These error conditions are checked for and caught when processing
00122     /// arguments.
00123     enum EErrCode {
00124         eInvalidArg,    ///< Invalid argument
00125         eNoValue,       ///< Expecting an argument value
00126         eWrongCast,     ///< Incorrect cast for an argument
00127         eConvert,       ///< Conversion problem
00128         eNoFile,        ///< Expecting a file
00129         eConstraint,    ///< Argument value outside constraints
00130         eArgType,       ///< Wrong argument type
00131         eNoArg,         ///< No argument
00132         eSynopsis       ///< Synopsis error
00133     };
00134 
00135     /// Translate from the error code value to its string representation.
00136     virtual const char* GetErrCodeString(void) const;
00137 
00138     // Standard exception bolier plate code.
00139     NCBI_EXCEPTION_DEFAULT(CArgException, CCoreException);
00140 };
00141 
00142 
00143 
00144 /////////////////////////////////////////////////////////////////////////////
00145 ///
00146 /// CArgHelpException --
00147 ///
00148 /// Define exception class that gets thrown for Help messages.
00149 ///
00150 /// CArgException inherits its basic functionality from CArgException
00151 /// and defines an additional error code for help.
00152 
00153 class  CArgHelpException : public CArgException
00154 {
00155 public:
00156     /// Error type for help exception.
00157     enum EErrCode {
00158         eHelp,          ///< Error code for short help message
00159         eHelpFull,      ///< Error code for detailed help message
00160         eHelpXml        ///< Error code for XML formatted help message
00161     };
00162 
00163     /// Translate from the error code value to its string representation.
00164     virtual const char* GetErrCodeString(void) const;
00165 
00166     // Standard exception bolier plate code.
00167     NCBI_EXCEPTION_DEFAULT(CArgHelpException, CArgException);
00168 };
00169 
00170 
00171 /////////////////////////////////////////////////////////////////////////////
00172 ///
00173 /// CArgValue --
00174 ///
00175 /// Generic abstract base class for argument values.
00176 
00177 class  CArgValue : public CObject
00178 {
00179 public:
00180     /// Get argument name.
00181     const string& GetName(void) const { return m_Name; }
00182 
00183     /// Check if argument holds a value.
00184     ///
00185     /// Argument does not hold value if it was described as optional argument
00186     /// without default value, and if it was not passed a value in the command
00187     /// line.  On attempt to retrieve the value from such "no-value" argument,
00188     /// exception will be thrown.
00189     virtual bool HasValue(void) const = 0;
00190 
00191     DECLARE_OPERATOR_BOOL(HasValue());
00192 
00193     /// Get the argument's string value.
00194     ///
00195     /// If it is a value of a flag argument, then return either "true"
00196     /// or "false".
00197     /// @sa
00198     ///   AsInteger(), AsInt8(), AsDouble(), AsBoolean()
00199     virtual const string& AsString(void) const = 0;
00200 
00201     /// Get the argument's integer (8-byte long) value.
00202     ///
00203     /// If you request a wrong value type, such as a call to "AsInt8()"
00204     /// for a "boolean" argument, an exception is thrown.
00205     /// This will however work okay for "plain integer" argument.
00206     /// @sa
00207     ///   AsInteger(), AsString(), AsDouble, AsBoolean()
00208     virtual Int8 AsInt8(void) const = 0;
00209 
00210     /// Get the argument's integer value.
00211     ///
00212     /// If you request a wrong value type, such as a call to "AsInteger()"
00213     /// for a "boolean" or even "Int8" argument, an exception is thrown.
00214     /// @sa
00215     ///   AsInt8(), AsString(), AsDouble, AsBoolean()
00216     virtual int    AsInteger(void) const = 0;
00217 
00218     /// Get the argument's double value.
00219     ///
00220     /// If you request a wrong value type, such as a call to "AsDouble()"
00221     /// for a "boolean" argument, an exception is thrown.
00222     /// @sa
00223     ///   AsString(), AsInt8(), AsInteger, AsBoolean()
00224     virtual double AsDouble (void) const = 0;
00225 
00226     /// Get the argument's boolean value.
00227     ///
00228     /// If you request a wrong value type, such as a call to "AsBoolean()"
00229     /// for a "integer" argument, an exception is thrown.
00230     /// @sa
00231     ///   AsString(), AsInt8(), AsInteger, AsDouble()
00232     virtual bool   AsBoolean(void) const = 0;
00233 
00234     /// Get the argument as an input file stream.
00235     virtual CNcbiIstream& AsInputFile (void) const = 0;
00236 
00237     /// Get the argument as an output file stream.
00238     virtual CNcbiOstream& AsOutputFile(void) const = 0;
00239 
00240     /// Close the file.
00241     virtual void CloseFile (void) const = 0;
00242 
00243 
00244 
00245     /// Some values types can contain several value lists
00246     ///
00247     /// Example: CGIs pass list selections by repeating the same name
00248     typedef vector<string>  TStringArray;
00249 
00250     /// Get the value list
00251     virtual const TStringArray& GetStringList() const;
00252 
00253     /// Get reference on value list for further modification
00254     virtual TStringArray& SetStringList();
00255 
00256 protected:
00257     friend class CArgs;
00258 
00259     /// Protected constructor and destructor.
00260     ///
00261     /// Prohibit explicit instantiation of CArgValue with name.
00262     CArgValue(const string& name);
00263     virtual ~CArgValue(void);
00264 
00265     string m_Name;          ///< Argument name
00266 };
00267 
00268 
00269 
00270 /////////////////////////////////////////////////////////////////////////////
00271 ///
00272 /// CArgs --
00273 ///
00274 /// Defines parsed arguments.
00275 ///
00276 /// Argument values are obtained from the unprocessed command-line arguments
00277 /// (via CNcbiArguments) and then verified and processed according to the
00278 /// argument descriptions defined by user in "CArgDescriptions".
00279 ///
00280 /// NOTE:  the extra arguments can be accessed using virtual names:
00281 ///           "#1", "#2", "#3", ..., "#<GetNExtra()>"
00282 ///        in the order of insertion (by method Add).
00283 ///
00284 
00285 class  CArgs
00286 {
00287 public:
00288     /// Constructor.
00289     CArgs(void);
00290 
00291     /// Destructor.
00292     ~CArgs(void);
00293 
00294     /// Check existence of argument description.
00295     ///
00296     /// Return TRUE if arg "name" was described in the parent CArgDescriptions.
00297     bool Exist(const string& name) const;
00298 
00299     /// Get value of argument by name. If the name starts with '-'
00300     /// (e.g. '-arg') the argument can also be found by 'arg' name if there
00301     /// is no another argument named 'arg'.
00302     ///
00303     /// Throw an exception if such argument does not exist.
00304     /// @sa
00305     ///   Exist() above.
00306     const CArgValue& operator[] (const string& name) const;
00307 
00308     /// Get the number of unnamed positional (a.k.a. extra) args.
00309     size_t GetNExtra(void) const { return m_nExtra; }
00310 
00311     /// Return N-th extra arg value,  N = 1 to GetNExtra().
00312     const CArgValue& operator[] (size_t idx) const;
00313 
00314     /// Get all available arguments
00315     vector< CRef<CArgValue> > GetAll(void) const;
00316 
00317     /// Print (append) all arguments to the string "str" and return "str".
00318     string& Print(string& str) const;
00319 
00320     /// Add new argument name and value.
00321     ///
00322     /// Throw an exception if the "name" is not an empty string, and if
00323     /// there is an argument with this name already and "update" parameter is 
00324     /// not set.
00325     ///
00326     /// HINT: Use empty "name" to add extra (unnamed) args, and they will be
00327     /// automagically assigned with the virtual names: "#1", "#2", "#3", etc.
00328     ///
00329     /// @param arg
00330     ///    argument value added to the collection
00331     /// @param update
00332     ///    when TRUE and argument already exists it will be replaced
00333     ///    when FALSE throws an exception 
00334     /// @param add_value
00335     ///    when TRUE and argument already exists the value is
00336     ///    added to the string list (multiple argument)
00337     void Add(CArgValue* arg, 
00338              bool       update    = false,
00339              bool       add_value = false);
00340 
00341     /// Check if there are no arguments in this container.
00342     bool IsEmpty(void) const;
00343 
00344     /// Remove argument of name "name"
00345     void Remove(const string& name);
00346 
00347     /// Remove all arguments
00348     void Reset(void);
00349 
00350 private:
00351     typedef set< CRef<CArgValue> >  TArgs;   ///< Type for arguments
00352     typedef TArgs::iterator         TArgsI;  ///< Type for iterator
00353     typedef TArgs::const_iterator   TArgsCI; ///< Type for const iterator
00354 
00355     TArgs  m_Args;    ///< Assoc. map of arguments' name/value
00356     size_t m_nExtra;  ///< Cached # of unnamed positional arguments 
00357 
00358     /// Find argument value with name "name".
00359     TArgsCI x_Find(const string& name) const;
00360     TArgsI  x_Find(const string& name);
00361 };
00362 
00363 
00364 
00365 class CArgDesc;
00366 
00367 
00368 /////////////////////////////////////////////////////////////////////////////
00369 ///
00370 /// CArgErrorHandler --
00371 ///
00372 /// Base/default error handler for arguments parsing.
00373 
00374 class  CArgErrorHandler : public CObject
00375 {
00376 public:
00377     /// Process invalid argument value. The base implementation returns NULL
00378     /// or throws exception depending on the CArgDesc flags.
00379     /// @param arg_desc
00380     ///   CArgDesc object which failed to initialize.
00381     /// @param value
00382     ///   String value which caused the error.
00383     /// @return
00384     ///   Return new CArgValue object or NULL if the argument should be
00385     ///   ignored (as if it has not been set in the command line).
00386     virtual CArgValue* HandleError(const CArgDesc& arg_desc,
00387                                    const string& value) const;
00388 };
00389 
00390 
00391 
00392 /////////////////////////////////////////////////////////////////////////////
00393 ///
00394 /// CArgDescriptions --
00395 ///
00396 /// Description of unparsed arguments.
00397 ///
00398 /// Container to store the command-line argument descriptions. Provides the
00399 /// means for the parsing and verification of command-line arguments against
00400 /// the contained descriptions.
00401 ///
00402 /// Example: Translating "CNcbiArguments" ---> "CArgs".
00403 /// Can also be used to compose and print out the USAGE info.
00404 
00405 class  CArgDescriptions
00406 {
00407 public:
00408     /// Constructor.
00409     ///
00410     /// If "auto_help" is passed TRUE, then a special flag "-h" will be added
00411     /// to the list of accepted arguments. Passing "-h" in the command line
00412     /// will printout USAGE and ignore all other passed arguments.
00413     /// Error handler is used to process errors when parsing arguments.
00414     /// If not set the default handler is used.
00415     CArgDescriptions(bool auto_help = true,
00416                      CArgErrorHandler* err_handler = 0);
00417 
00418     /// Destructor.
00419     virtual ~CArgDescriptions(void);
00420 
00421     /// Type of CArgDescriptions
00422     /// For a CGI application positional argumants and flags does not make
00423     /// sense (this sintax cannot be expressed by CGI protocol)
00424     enum EArgSetType {
00425         eRegularArgs,  ///< Regular application
00426         eCgiArgs       ///< CGI application
00427     };
00428 
00429     /// Set type of argument description (cmdline vs CGI).
00430     /// Method performs verification of arguments, 
00431     /// throws an exception if it finds positional args set for a CGI
00432     void SetArgsType(EArgSetType args_type);
00433 
00434     EArgSetType GetArgsType() const { return m_ArgsType; }
00435 
00436     /// Processing of positional arguments.
00437     /// In strict mode any value starting with '-' is treated as a key/flag
00438     /// unless any positional arguments have already been found (e.g. after
00439     /// '--' argument). In loose mode any argument is treated as positional
00440     /// if it can not be processed as a valid key or flag.
00441     enum EArgPositionalMode {
00442         ePositionalMode_Strict,  ///< Strict mode (default)
00443         ePositionalMode_Loose    ///< Loose mode
00444     };
00445 
00446     /// Select mode for processing positional arguments.
00447     void SetPositionalMode(EArgPositionalMode positional_mode)
00448         { m_PositionalMode = positional_mode; }
00449 
00450     EArgPositionalMode GetPositionalMode() const { return m_PositionalMode; }
00451 
00452     /// Available argument types.
00453     enum EType {
00454         eString = 0, ///< An arbitrary string
00455         eBoolean,    ///< {'true', 't', 'false', 'f'},  case-insensitive
00456         eInt8,       ///< Convertible into an integer number (Int8 only)
00457         eInteger,    ///< Convertible into an integer number (int or Int8)
00458         eDouble,     ///< Convertible into a floating point number (double)
00459         eInputFile,  ///< Name of file (must exist and be readable)
00460         eOutputFile, ///< Name of file (must be writeable)
00461 
00462         k_EType_Size ///< For internal use only
00463     };
00464 
00465     /// Get argument type's name.
00466     static const char* GetTypeName(EType type);
00467 
00468     /// Additional flags, the first group is file related flags.
00469     ///
00470     /// Must match the argument type, or an exception will be thrown.
00471     /// ( File related are for eInputFile and eOutputFiler argument types.)
00472     enum EFlags {
00473         // file related flags:
00474 
00475         /// Open file right away for eInputFile, eOutputFile
00476         fPreOpen = (1 << 0),
00477         /// Open as binary file for eInputFile, eOutputFile
00478         fBinary  = (1 << 1), 
00479         /// Append to end-of-file for eOutputFile only
00480         fAppend  = (1 << 2),
00481 
00482         /// Mask for all file-related flags
00483         fFileFlags = fPreOpen | fBinary | fAppend,
00484         // multiple keys flag:
00485 
00486         /// Repeated key arguments are legal (use with AddKey)
00487         fAllowMultiple = (1 << 3),
00488 
00489         // Error handling flags
00490 
00491         /// Ignore invalid argument values. If not set, exceptions will be
00492         /// thrown on invalid values.
00493         fIgnoreInvalidValue = (1 << 4),
00494         /// Post warning when an invalid value is ignored (no effect
00495         /// if fIgnoreInvalidValue is not set).
00496         fWarnOnInvalidValue = (1 << 5),
00497 
00498         /// Allow to ignore separator between the argument's name and value.
00499         /// Usual ' ' or '=' separators can still be used with the argument.
00500         /// The following restrictions apply to a no-separator argument:
00501         ///   - the argument must be a key (including optional or default);
00502         ///   - the argument's name must be a single char;
00503         ///   - no other argument's name can start with the same char.
00504         fOptionalSeparator = (1 << 6)
00505     };
00506     typedef unsigned int TFlags;  ///< Binary OR of "EFlags"
00507 
00508     /// Add description for mandatory key.
00509     ///
00510     /// Mandatory key has the syntax:
00511     ///
00512     ///   arg_key := -<key> <value>
00513     ///
00514     /// Will throw exception CArgException if:
00515     ///  - description with name "name" already exists
00516     ///  - "name" contains symbols other than {alnum, '-', '_'}
00517     ///  - "name" starts with more than one '-'
00518     ///  - "synopsis" contains symbols other than {alnum, '_'}
00519     ///  - "flags" are inconsistent with "type"
00520     ///
00521     /// Any argument can be later referenced using its unique name "name".
00522     void AddKey(const string& name,       ///< Name of argument key
00523                 const string& synopsis,   ///< Synopsis for argument
00524                 const string& comment,    ///< Argument description
00525                 EType         type,       ///< Argument type
00526                 TFlags        flags = 0   ///< Optional file related flags
00527                );
00528 
00529     /// Add description for optional key without default value.
00530     ///
00531     /// Optional key without default value has the following syntax:
00532     ///
00533     ///   arg_key_opt := [-<key> <value>]
00534     ///
00535     /// Will throw exception CArgException if:
00536     ///  - description with name "name" already exists
00537     ///  - "name" contains symbols other than {alnum, '-', '_'}
00538     ///  - "name" starts with more than one '-'
00539     ///  - "synopsis" contains symbols other than {alnum, '_'}
00540     ///  - "flags" are inconsistent with "type"
00541     ///
00542     /// Any argument can be later referenced using its unique name "name".
00543     void AddOptionalKey(const string& name,     ///< Name of argument key 
00544                         const string& synopsis, ///< Synopsis for argument
00545                         const string& comment,  ///< Argument description
00546                         EType         type,     ///< Argument type
00547                         TFlags        flags = 0 ///< Optional file flags
00548                        );
00549 
00550     /// Add description for optional key with default value.
00551     ///
00552     /// Optional key with default value has the following syntax:
00553     ///
00554     ///   arg_key_dflt := [-<key> <value>]
00555     ///
00556     /// Will throw exception CArgException if:
00557     ///  - description with name "name" already exists
00558     ///  - "name" contains symbols other than {alnum, '-', '_'}
00559     ///  - "name" starts with more than one '-'
00560     ///  - "synopsis" contains symbols other than {alnum, '_'}
00561     ///  - "flags" are inconsistent with "type"
00562     ///
00563     /// Any argument can be later referenced using its unique name "name".
00564     void AddDefaultKey(const string& name,          ///< Name of argument key 
00565                        const string& synopsis,      ///< Synopsis for argument
00566                        const string& comment,       ///< Argument description
00567                        EType         type,          ///< Argument type
00568                        const string& default_value, ///< Default value
00569                        TFlags        flags = 0,     ///< Optional file flags
00570     /// Optional name of environment variable that contains default value
00571                        const string& env_var = kEmptyStr
00572                       );
00573 
00574     /// Add description for flag argument.
00575     ///
00576     /// Flag argument has the following syntax:
00577     ///
00578     ///  arg_flag  := -<flag>,     <flag> := "name"
00579     ///
00580     /// If argument "set_value" is TRUE, then:
00581     ///    - if the flag is provided (in the command-line), then the resultant
00582     ///      CArgValue::HasValue() will be TRUE;
00583     ///    - else it will be FALSE.
00584     ///
00585     /// Setting argument "set_value" to FALSE will reverse the above meaning.
00586     ///
00587     /// NOTE: If CArgValue::HasValue() is TRUE, then AsBoolean() is
00588     /// always TRUE.
00589     void AddFlag(const string& name,            ///< Name of argument
00590                  const string& comment,         ///< Argument description
00591                  bool          set_value = true ///< Is value set or not?
00592                 );
00593 
00594     /// Add description for mandatory postional argument.
00595     ///
00596     /// Mandatory positional argument has the following syntax:
00597     ///
00598     ///   arg_pos := <value>
00599     ///
00600     /// NOTE: For all types of positional arguments:
00601     /// - The order is important! That is, the N-th positional argument passed
00602     ///   in the cmd.-line will be matched against (and processed according to)
00603     ///   the N-th added named positional argument description.
00604     /// - Mandatory positional args always go first.
00605     ///
00606     /// Will throw exception CArgException if:
00607     ///  - description with name "name" already exists
00608     ///  - "name" contains symbols other than {alnum, '-', '_'}
00609     ///  - "name" starts with more than one '-'
00610     ///  - "flags" are inconsistent with "type"
00611     ///
00612     /// Any argument can be later referenced using its unique name "name".
00613     void AddPositional(const string& name,     ///< Name of argument
00614                        const string& comment,  ///< Argument description
00615                        EType         type,     ///< Argument type
00616                        TFlags        flags = 0 ///< Optional file flags
00617                       );
00618 
00619     /// Add description for optional positional argument without default
00620     /// value.
00621     ///
00622     /// Optional positional argument, without default value has the following
00623     /// syntax:
00624     ///
00625     ///  arg_pos_opt := [<value>]
00626     ///
00627     /// Will throw exception CArgException if:
00628     ///  - description with name "name" already exists
00629     ///  - "name" contains symbols other than {alnum, '-', '_'}
00630     ///  - "name" starts with more than one '-'
00631     ///  - "flags" are inconsistent with "type"
00632     ///
00633     /// Any argument can be later referenced using its unique name "name".
00634     /// @sa
00635     ///   NOTE for AddPositional()
00636     void AddOptionalPositional(const string& name,     ///< Name of argument
00637                                const string& comment,  ///< Argument descr.
00638                                EType         type,     ///< Argument type
00639                                TFlags        flags = 0 ///< Optional file flgs
00640                               );
00641 
00642     /// Add description for optional positional argument with default value.
00643     ///
00644     /// Optional positional argument with default value has the following
00645     /// syntax:
00646     ///
00647     ///  arg_pos_dflt := [<value>]
00648     ///
00649     /// Will throw exception CArgException if:
00650     ///  - description with name "name" already exists
00651     ///  - "name" contains symbols other than {alnum, '-', '_'}
00652     ///  - "name" starts with more than one '-'
00653     ///  - "flags" are inconsistent with "type"
00654     ///
00655     /// @sa
00656     ///   NOTE for AddPositional()
00657     void AddDefaultPositional(const string& name,   ///< Name of argument
00658                               const string& comment,///< Argument description
00659                               EType         type,   ///< Argument type
00660                               const string& default_value, ///< Default value
00661                               TFlags        flags = 0, ///< Optional file flags
00662     /// Optional name of environment variable that contains default value
00663                               const string& env_var = kEmptyStr
00664                              );
00665 
00666     /// Add description for the extra, unnamed positional arguments.
00667     ///
00668     /// The name of this description is always an empty string.
00669     /// Names of the resulting arg.values will be:  "#1", "#2", ...
00670     /// By default, no extra args are allowed.
00671     ///
00672     /// To allow an unlimited # of optional argumens pass
00673     /// "n_optional" = kMax_UInt.
00674     ///
00675     /// Will throw exception CArgException if:
00676     ///  - description with name "name" already exists
00677     ///  - "flags" are inconsistent with "type"
00678     void AddExtra(unsigned      n_mandatory, ///< Number of mandatory args
00679                   unsigned      n_optional,  ///< Number of optional args
00680                   const string& comment,     ///< Argument description
00681                   EType         type,        ///< Argument type
00682                   TFlags        flags = 0    ///< Optional file flags
00683                  );
00684 
00685     /// Add argument alias. The alias can be used in the command line instead
00686     /// of the original argument. Accessing argument value by its alias is
00687     /// not allowed (will be reported as an unknown argument). The alias will
00688     /// be printed in USAGE after the original argument name.
00689     /// @param alias
00690     ///    New alias for a real argument.
00691     /// @param arg_name
00692     ///    The real argument's name.
00693     void AddAlias(const string& alias, const string& arg_name);
00694     /// Add negated alias for a flag argument. Using the alias in the
00695     /// command line produces the same effect as using the original
00696     /// flag with the opposite value. If 'arg_name' does not describe
00697     /// a flag argument, an exception is thrown.
00698     /// @sa
00699     ///   AddAlias()
00700     void AddNegatedFlagAlias(const string& alias,
00701                              const string& arg_name,
00702                              const string& comment = kEmptyStr);
00703 
00704     /// Flag to invert constraint logically
00705     enum EConstraintNegate {
00706         eConstraintInvert,  ///< Logical NOT
00707         eConstraint         ///< Constraint is not inverted (taken as is)
00708     };
00709 
00710     /// Set additional user defined constraint on argument value.
00711     ///
00712     /// Constraint is defined by CArgAllow and its derived classes.
00713     /// The constraint object must be allocated by "new", and it must NOT be
00714     /// freed by "delete" after it has been passed to CArgDescriptions!
00715     ///
00716     /// @param name
00717     ///    Name of the parameter(flag) to check
00718     /// @param constraint
00719     ///    Constraint class
00720     /// @param negate
00721     ///    Flag indicates if this is inverted(NOT) constaint
00722     /// 
00723     /// @sa
00724     ///   See "CArgAllow_***" classes for some pre-defined constraints
00725     void SetConstraint(const string&      name,
00726                        CArgAllow*         constraint,
00727                        EConstraintNegate  negate = eConstraint);
00728 
00729     /// Dependencies between arguments.
00730     enum EDependency {
00731         eRequires, ///< One argument requires another
00732         eExcludes  ///< One argument excludes another
00733     };
00734 
00735     /// Define a dependency. If arg1 was specified and requires arg2,
00736     /// arg2 is treated as a mandatory one even if was defined as optional.
00737     /// If arg1 excludes arg2, arg2 must not be set even if it's mandatory.
00738     /// This allows to create a set of arguments exactly one of which
00739     /// must be set.
00740     void SetDependency(const string& arg1,
00741                        EDependency   dep,
00742                        const string& arg2);
00743 
00744     /// Set current arguments group name. When printing descriptions for
00745     /// optional arguments (on -help command), they will be arranged by
00746     /// group name. Empty group name resets the group. Arguments without
00747     /// group are listed first immediately after mandatory arguments.
00748     void SetCurrentGroup(const string& group);
00749 
00750     /// Set individual error handler for the argument.
00751     /// The handler overrides the default one (if any) provided through
00752     /// the constructor. The same handler may be shared by several arguments.
00753     /// The handler object must be allocated by "new", and it must NOT be
00754     /// freed by "delete" after it has been passed to CArgDescriptions!
00755     ///
00756     /// @param name
00757     ///    Name of the parameter (flag) to set handler for
00758     /// @param err_handler
00759     ///    Error handler
00760     void SetErrorHandler(const string&      name,
00761                          CArgErrorHandler*  err_handler);
00762 
00763     /// Check if there is already an argument description with specified name.
00764     bool Exist(const string& name) const;
00765 
00766     /// Delete description of argument with name "name".
00767     /// Extra arguments get deleted by the name passed as "".
00768     ///
00769     /// Throw the CArgException (eSynopsis error code) exception if the
00770     /// specified name cannot be found.
00771     void Delete(const string& name);
00772 
00773     /// Set extra info to be used by PrintUsage().
00774     void SetUsageContext(const string& usage_name,           ///< Program name  
00775                          const string& usage_description,    ///< Usage descr.
00776                          bool          usage_sort_args = false,///< Sort args.
00777                          SIZE_TYPE     usage_width = 78);    ///< Format width
00778 
00779     /// Print usage and exit.
00780     ///
00781     /// Force to print USAGE unconditionally (and then exit) if no
00782     /// command-line args are present.
00783     void PrintUsageIfNoArgs(bool do_print = true);
00784 
00785     /// Print usage message to end of specified string.
00786     ///
00787     /// Printout USAGE and append to the string "str" using  provided
00788     /// argument descriptions and usage context.
00789     /// @return
00790     ///   Appended "str"
00791     virtual string& PrintUsage(string& str, bool detailed = false) const;
00792 
00793     /// Print argument description in XML format
00794     ///
00795     /// @param out
00796     ///   Print into this output stream
00797     void PrintUsageXml(CNcbiOstream& out) const;
00798 
00799     /// Verify if argument "name" is spelled correctly.
00800     ///
00801     /// Argument name can contain only alphanumeric characters, dashes ('-')
00802     /// and underscore ('_'), or be empty. If the leading dash is present,
00803     /// it must be followed by a non-dash char ('-' or '--foo' are not valid
00804     /// names).
00805     static bool VerifyName(const string& name, bool extended = false);
00806 
00807     /// See if special flag "-h" is activated
00808     bool IsAutoHelpEnabled(void) const
00809     {
00810         return m_AutoHelp;
00811     }
00812 private:
00813     typedef set< AutoPtr<CArgDesc> >  TArgs;    ///< Argument descr. type
00814     typedef TArgs::iterator           TArgsI;   ///< Arguments iterator
00815     typedef TArgs::const_iterator     TArgsCI;  ///< Const arguments iterator
00816     typedef /*deque*/vector<string>   TPosArgs; ///< Positional arg. vector
00817     typedef list<string>              TKeyFlagArgs; ///< List of flag arguments
00818     typedef vector<string>            TArgGroups;   ///< Argument groups
00819 
00820     // Dependencies
00821     struct SArgDependency
00822     {
00823         SArgDependency(const string arg, EDependency dep)
00824             : m_Arg(arg), m_Dep(dep) {}
00825         string      m_Arg;
00826         EDependency m_Dep;
00827     };
00828     // Map arguments to their dependencies
00829     typedef multimap<string, SArgDependency> TDependencies;
00830     typedef TDependencies::const_iterator TDependency_CI;
00831 
00832 private:
00833     EArgSetType  m_ArgsType;     ///< Type of arguments
00834     TArgs        m_Args;         ///< Assoc.map of arguments' name/descr
00835     TPosArgs     m_PosArgs;    ///< Pos. args, ordered by position in cmd.-line
00836     TKeyFlagArgs m_KeyFlagArgs;  ///< Key/flag args, in order of insertion
00837     string       m_NoSeparator;  ///< Arguments allowed to use no separator
00838     unsigned     m_nExtra;       ///> # of mandatory extra args
00839     unsigned     m_nExtraOpt;    ///< # of optional  extra args
00840     TArgGroups   m_ArgGroups;    ///< Argument groups
00841     size_t       m_CurrentGroup; ///< Currently selected group (0 = no group)
00842     EArgPositionalMode m_PositionalMode; ///< Processing of positional args
00843     TDependencies      m_Dependencies;   ///< Arguments' dependencies
00844 
00845     // Extra USAGE info
00846     string    m_UsageName;         ///< Program name
00847     string    m_UsageDescription;  ///< Program description
00848     bool      m_UsageSortArgs;     ///< Sort alphabetically on usage printout
00849     SIZE_TYPE m_UsageWidth;        ///< Maximum length of a usage line
00850     bool      m_AutoHelp;          ///< Special flag "-h" activated
00851     bool      m_UsageIfNoArgs;     ///< Print usage and exit if no args passed
00852 
00853     CRef<CArgErrorHandler> m_ErrorHandler; ///< Global error handler or NULL
00854 
00855     // Internal methods
00856 
00857     void x_PrintAliasesAsXml(CNcbiOstream& out, const string& name,
00858                                                 bool negated=false) const;
00859 
00860     /// Helper method to find named parameter.
00861     /// 'negative' (if provided) will indicate if the name refered to a
00862     /// negative alias.
00863     TArgsI  x_Find(const string& name,
00864                    bool*         negative = NULL);
00865 
00866     /// Helper method to find named parameter -- const version.
00867     /// 'negative' (if provided) will indicate if the name refered to a
00868     /// negative alias.
00869     TArgsCI x_Find(const string& name,
00870                    bool*         negative = NULL) const;
00871 
00872     /// Get group index. Returns group index in the m_ArgGroups, 0 for empty
00873     /// group name or the next group number for undefined group.
00874     size_t x_GetGroupIndex(const string& group) const;
00875 
00876     /// Helper method for adding description.
00877     void x_AddDesc(CArgDesc& arg); 
00878 
00879     /// Helper method for doing pre-processing consistency checks.
00880     void x_PreCheck(void) const; 
00881 
00882     /// Helper method for checking if auto help requested and throw
00883     /// CArgHelpException if help requested.
00884     void x_CheckAutoHelp(const string& arg) const;
00885 
00886     void x_PrintComment(list<string>&   arr,
00887                         const CArgDesc& arg,
00888                         SIZE_TYPE       width) const;
00889 
00890     /// Process arguments.
00891     ///
00892     /// Helper method to process arguments and build a CArgs object that is
00893     /// passed as the args parameter.
00894     /// @return
00895     ///   TRUE if specified "arg2" was used.
00896     bool    x_CreateArg(const string& arg1, ///< Argument to process 
00897                         bool have_arg2, ///< Is there an arg. that follows?
00898                         const string& arg2, ///< Following argument
00899                         unsigned* n_plain,  ///< Indicates number of args 
00900                         CArgs& args         ///< Contains processed args
00901                        ) const;
00902 
00903     /// @return
00904     ///   TRUE if specified "arg2" was used.
00905     bool x_CreateArg(const string& arg1,
00906                      const string& name, 
00907                      bool          have_arg2,
00908                      const string& arg2,
00909                      unsigned int  n_plain,
00910                      CArgs&        args,
00911                      bool          update = false,
00912                      CArgValue**   new_value = 0) const;
00913 
00914     /// @sa x_PostCheck()
00915     enum EPostCheckCaller {
00916         eCreateArgs,  ///< called by CreateArgs()
00917         eConvertKeys  ///< called by ConvertKeys()
00918     };
00919     /// Helper method for doing post-processing consistency checks.
00920     void x_PostCheck(CArgs&           args,
00921                      unsigned int     n_plain,
00922                      EPostCheckCaller caller)
00923         const;
00924 
00925     /// Returns TRUE if parameter supports multiple arguments
00926     bool x_IsMultiArg(const string& name) const;
00927 
00928 public:
00929     /// Create parsed arguments in CArgs object.
00930     ///
00931     /// Parse command-line arguments, and create "CArgs" args object 
00932     /// from the passed command-line arguments "argc" and "argv".
00933     ///
00934     /// Throw 
00935     ///  - CArgException on error
00936     ///  - CArgHelpException if USAGE printout was requested ("-h" flag)
00937     ///
00938     /// NOTE: You can deallocate the resulting "CArgs" object using 'delete'.
00939     ///
00940     /// Examples:
00941     ///
00942     /// (1) int main(int argc, const char* argv[]) {
00943     ///         CreateArgs(desc, argc, argv);
00944     ///     }
00945     ///
00946     /// (2) CNcbiArguments ncbi_args;
00947     ///     CreateArgs(desc, ncbi_args.Size(), ncbi_args);
00948     template<class TSize, class TArray>
00949     CArgs* CreateArgs(TSize argc, TArray argv) const
00950     {
00951         // Check the consistency of argument descriptions
00952         x_PreCheck();
00953 
00954         // Check for "-h" flag
00955         for (TSize i = 1;  i < argc;  i++) {
00956             x_CheckAutoHelp(argv[i]);
00957         }
00958 
00959         // Create new "CArgs" to fill up, and parse cmd.-line args into it
00960         auto_ptr<CArgs> args(new CArgs());
00961 
00962         // Special case for CGI -- a lone positional argument
00963         if (GetArgsType() == eCgiArgs  &&  argc == 2) {
00964             return args.release();
00965         }
00966 
00967         // Regular case for both CGI and non-CGI
00968         unsigned int n_plain = kMax_UInt;
00969         for (TSize i = 1;  i < argc;  i++) {
00970             bool have_arg2 = (i + 1 < argc);
00971             if ( x_CreateArg(argv[i], have_arg2,
00972                              have_arg2 ? (string) argv[i+1] : kEmptyStr,
00973                              &n_plain, *args) ) {
00974                 i++;
00975             }
00976         }
00977 
00978         // Check if there were any arguments at all
00979         if (n_plain == kMax_UInt) {
00980             n_plain = 0;
00981         }
00982 
00983         // Extra checks for the consistency of resultant argument values
00984         x_PostCheck(*args, n_plain, eCreateArgs);
00985         return args.release();
00986     }
00987 
00988     /// Parse command-line arguments 'argv'
00989     CArgs* CreateArgs(const CNcbiArguments& argv) const;
00990 
00991     /// Convert argument map (key-value pairs) into arguments in accordance
00992     /// with the argument descriptions
00993     template<class T>
00994     void ConvertKeys(CArgs* args, const T& arg_map, bool update) const
00995     {
00996         // Check the consistency of argument descriptions
00997         x_PreCheck();
00998 
00999         // Retrieve the arguments and their values
01000         ITERATE(TKeyFlagArgs, it, m_KeyFlagArgs) {
01001             const string& param_name = *it;
01002 
01003             // find first element in the input multimap
01004             typename T::const_iterator vit  = arg_map.find(param_name);
01005             typename T::const_iterator vend = arg_map.end();
01006 
01007             if (vit != vend) {   // at least one value found
01008                 CArgValue* new_arg_value;
01009                 x_CreateArg(param_name, param_name, 
01010                             true, /* value is present */
01011                             vit->second,
01012                             1,
01013                             *args,
01014                             update,
01015                             &new_arg_value);
01016 
01017                 if (new_arg_value  &&  x_IsMultiArg(param_name)) {
01018                     CArgValue::TStringArray& varr =
01019                         new_arg_value->SetStringList();
01020 
01021                     // try to add all additional arguments to arg value
01022                     for (++vit;  vit != vend;  ++vit) {
01023                         if (vit->first != param_name)
01024                             break;
01025                         varr.push_back(vit->second);
01026                     }
01027                 }
01028             }
01029         } // ITERATE
01030 
01031         // Extra checks for the consistency of resultant argument values
01032         x_PostCheck(*args, 0, eConvertKeys);
01033     }
01034 };
01035 
01036 
01037 
01038 /////////////////////////////////////////////////////////////////////////////
01039 ///
01040 /// CArgAllow --
01041 ///
01042 /// Abstract base class for defining argument constraints.
01043 ///
01044 /// Other user defined constraints are defined by deriving from this abstract
01045 /// base class:
01046 ///
01047 ///  - CArgAllow_Symbols  -- symbol from a set of allowed symbols
01048 ///  - CArgAllow_String   -- string to contain only allowed symbols 
01049 ///  - CArgAllow_Strings  -- string from a set of allowed strings
01050 ///  - CArgAllow_Int8s    -- Int8    value to fall within a given interval
01051 ///  - CArgAllow_Integers -- integer value to fall within a given interval
01052 ///  - CArgAllow_Doubles  -- floating-point value to fall in a given interval
01053 ///
01054 /// @sa CArgAllow_Regexp
01055 
01056 class  CArgAllow : public CObject
01057 {
01058 public:
01059     /// Verify if specified value is allowed.
01060     virtual bool Verify(const string &value) const = 0;
01061 
01062     /// Get usage information.
01063     virtual 
01064     string GetUsage(void) const = 0;
01065 
01066     /// Print constraints in XML format
01067     virtual void PrintUsageXml(CNcbiOstream& out) const;
01068 
01069 protected:
01070 #ifdef NCBI_COMPILER_ICC
01071 // In the absence of the following constructor,
01072 // ICC fills the object memory with zeros,
01073 // erasing flags set by CObject::operator new
01074     CArgAllow(void) {}
01075 #endif
01076 
01077     /// Protected destructor.
01078     ///
01079     /// Prohibit from the allocation on stack or in the static data segment,
01080     /// and from the explicit deallocation by "delete".
01081     virtual ~CArgAllow(void);
01082 };
01083 
01084 
01085 
01086 /////////////////////////////////////////////////////////////////////////////
01087 ///
01088 /// CArgAllow_Symbols --
01089 ///
01090 /// Define constraint to describe exactly one symbol.
01091 ///
01092 /// Argument to be exactly one symbol from the specified set of symbols.
01093 ///
01094 /// Examples:
01095 /// - To allow only symbols 'a', 'b' and 'Z' for argument "MyArg":
01096 ///   SetConstraint("MyArg", new CArgAllow_Symbols("abZ"))
01097 /// - To allow only printable symbols (according to "isprint()" from <ctype.h>):
01098 ///   SetConstraint("MyArg", new CArgAllow_Symbols(CArgAllow_Symbols::ePrint))
01099 
01100 class  CArgAllow_Symbols : public CArgAllow
01101 {
01102 public:
01103     /// Symbol class for defining sets of characters.
01104     ///
01105     /// Symbol character classes patterned after those defined in <ctype.h>.
01106     enum ESymbolClass {
01107         // Standard character class from <ctype.h>:  isalpha(), isdigit(), etc.
01108         eAlnum,  ///< Alphanumeric characters
01109         eAlpha,  ///< Alphabet characters
01110         eCntrl,  ///< Control characters
01111         eDigit,  ///< Digit characters
01112         eGraph,  ///< Graphical characters
01113         eLower,  ///< Lowercase characters
01114         ePrint,  ///< Printable characters
01115         ePunct,  ///< Punctuation characters
01116         eSpace,  ///< Space characters
01117         eUpper,  ///< Uppercase characters
01118         eXdigit, ///< Hexadecimal characters
01119         eUser    ///< User defined characters using constructor with string&
01120     };
01121 
01122     /// Constructor.
01123     CArgAllow_Symbols(ESymbolClass symbol_class);
01124 
01125     /// Constructor for user defined eUser class.
01126     CArgAllow_Symbols(const string& symbol_set);
01127 
01128 protected:
01129     /// Verify if specified value is allowed.
01130     virtual bool Verify(const string& value) const;
01131 
01132     /// Get usage information.
01133     virtual string GetUsage(void) const;
01134 
01135     /// Print constraints in XML format
01136     virtual void PrintUsageXml(CNcbiOstream& out) const;
01137 
01138     /// Protected destructor.
01139     virtual ~CArgAllow_Symbols(void);
01140 
01141     ESymbolClass m_SymbolClass; ///< Symbol class for constraint
01142     string       m_SymbolSet;   ///< Use if  m_SymbolClass == eUser
01143 };
01144 
01145 
01146 
01147 /////////////////////////////////////////////////////////////////////////////
01148 ///
01149 /// CArgAllow_String --
01150 ///
01151 /// Define constraint to describe string argument.
01152 ///
01153 /// Argument to be a string containing only allowed symbols.
01154 ///
01155 /// Examples:
01156 /// - To allow string containing only symbols 'a', 'b' and 'Z' for arg MyArg:
01157 ///   SetConstraint("MyArg", new CArgAllow_String("abZ"))
01158 /// - To allow only numeric symbols (according to "isdigit()" from <ctype.h>):
01159 ///   SetConstraint("MyArg", new CArgAllow_String(CArgAllow_String::eDigit))
01160 
01161 class  CArgAllow_String : public CArgAllow_Symbols
01162 {
01163 public:
01164     /// Constructor.
01165     CArgAllow_String(ESymbolClass symbol_class);
01166 
01167     /// Constructor for user defined eUser class.
01168     CArgAllow_String(const string& symbol_set);
01169 
01170 protected:
01171     /// Verify if specified value is allowed.
01172     virtual bool Verify(const string& value) const;
01173 
01174     /// Get usage information.
01175     virtual string GetUsage(void) const;
01176 
01177     /// Print constraints in XML format
01178     virtual void PrintUsageXml(CNcbiOstream& out) const;
01179 };
01180 
01181 
01182 
01183 /////////////////////////////////////////////////////////////////////////////
01184 ///
01185 /// CArgAllow_Strings --
01186 ///
01187 /// Define constraint to describe set of string values.
01188 ///
01189 /// Argument to have only particular string values. Use the Allow() method to
01190 /// add the allowed string values, which can be daisy-chained.
01191 ///
01192 /// Examples:
01193 /// - SetConstraint("a", (new CArgAllow_Strings)->
01194 ///                  Allow("foo")->Allow("bar")->Allow("etc"))
01195 /// - You can use "operator,()" to shorten the notation:
01196 ///   SetConstraint("b", &(*new CArgAllow_Strings, "foo", "bar", "etc"))
01197 
01198 class  CArgAllow_Strings : public CArgAllow
01199 {
01200 public:
01201     /// Constructor
01202     /// @param use_case
01203     ///   If to ignore the case of the characters
01204     CArgAllow_Strings(NStr::ECase use_case = NStr::eCase);
01205 
01206     /// Add allowed string values
01207     /// @param value
01208     ///   String to add to the set of allowed string values
01209     CArgAllow_Strings* Allow(const string& value);
01210 
01211     /// Short notation operator for adding allowed string values
01212     /// @param value
01213     ///   String to add to the set of allowed string values
01214     /// @sa
01215     ///   Allow()
01216     CArgAllow_Strings& operator,(const string& value) { return *Allow(value); }
01217 
01218 protected:
01219     /// Verify if specified value is allowed.
01220     virtual bool Verify(const string& value) const;
01221 
01222     /// Get usage information.
01223     virtual string GetUsage(void) const;
01224 
01225     /// Print constraints in XML format
01226     virtual void PrintUsageXml(CNcbiOstream& out) const;
01227 
01228     /// Protected destructor.
01229     virtual ~CArgAllow_Strings(void);
01230 
01231 private:
01232     /// Type of the container that contains the allowed string values
01233     /// @sa m_Strings
01234     typedef set<string, PNocase_Conditional> TStrings;
01235 
01236     TStrings     m_Strings;  ///< Set of allowed string values
01237 };
01238 
01239 
01240 
01241 /////////////////////////////////////////////////////////////////////////////
01242 ///
01243 /// CArgAllow_Int8s --
01244 ///
01245 /// Define constraint to describe range of 8-byte integer values.
01246 ///
01247 /// Argument to have only integer values falling within given interval.
01248 ///
01249 /// Example:
01250 /// - SetConstraint("a2", new CArgAllow_Int8s(-1001, 123456789012))
01251 
01252 class  CArgAllow_Int8s : public CArgAllow
01253 {
01254 public:
01255     /// Constructor specifying range of allowed integer values.
01256     CArgAllow_Int8s(Int8 x_min, Int8 x_max);
01257 
01258 protected:
01259     /// Verify if specified value is allowed.
01260     virtual bool   Verify(const string& value) const;
01261 
01262     /// Get usage information.
01263     virtual string GetUsage(void) const;
01264 
01265     /// Print constraints in XML format
01266     virtual void PrintUsageXml(CNcbiOstream& out) const;
01267 
01268 private:
01269     Int8 m_Min;  ///< Minimum value of range
01270     Int8 m_Max;  ///< Maximum value of range 
01271 };
01272 
01273 
01274 
01275 /////////////////////////////////////////////////////////////////////////////
01276 ///
01277 /// CArgAllow_Integers --
01278 ///
01279 /// Define constraint to describe range of integer values.
01280 ///
01281 /// Argument to have only integer values falling within given interval.
01282 ///
01283 /// Example:
01284 /// - SetConstraint("i", new CArgAllow_Integers(kMin_Int, 34))
01285 
01286 class  CArgAllow_Integers : public CArgAllow_Int8s
01287 {
01288 public:
01289     /// Constructor specifying range of allowed integer values.
01290     CArgAllow_Integers(int x_min, int x_max);
01291 };
01292 
01293 
01294 
01295 /////////////////////////////////////////////////////////////////////////////
01296 ///
01297 /// CArgAllow_Doubles --
01298 ///
01299 /// Define constraint to describe range of double values.
01300 ///
01301 /// Argument to have only double values falling within given interval.
01302 ///
01303 /// Example:
01304 /// - SetConstraint("d", new CArgAllow_Doubles(0.01, 0.99))
01305 
01306 class  CArgAllow_Doubles : public CArgAllow
01307 {
01308 public:
01309     /// Constructor specifying range of allowed double values.
01310     CArgAllow_Doubles(double x_min, double x_max);
01311 
01312 protected:
01313     /// Verify if specified value is allowed.
01314     virtual bool   Verify(const string& value) const;
01315 
01316     /// Get usage information.
01317     virtual string GetUsage(void) const;
01318 
01319     /// Print constraints in XML format
01320     virtual void PrintUsageXml(CNcbiOstream& out) const;
01321 
01322 private:
01323     double m_Min;   ///< Minimum value of range
01324     double m_Max;   ///< Maximum value of range 
01325 };
01326 
01327 
01328 
01329 /////////////////////////////////////////////////////////////////////////////
01330 ///
01331 /// CArgDesc --
01332 ///
01333 /// Base class for the description of various types of argument.
01334 ///
01335 /// This was a pre-declaration; in MSVC, a predeclaration here causes a heap
01336 /// corruption on termination because this class's virtual destructor isn't
01337 /// defined at the moment the compiler instantiates the destructor of
01338 /// AutoPtr<CArgDesc>.
01339 
01340 class  CArgDesc
01341 {
01342 public:
01343     /// Constructor.
01344     CArgDesc(const string& name,    ///< Argument name
01345              const string& comment  ///< Argument description
01346             );
01347 
01348     /// Destructor.
01349     virtual ~CArgDesc(void);
01350 
01351     /// Get argument name.
01352     const string& GetName   (void) const { return m_Name; }
01353 
01354     /// Get arument description.
01355     const string& GetComment(void) const { return m_Comment; }
01356 
01357     /// Get argument group
01358     virtual size_t GetGroup(void) const { return 0; }
01359     /// Set argument group
01360     virtual void SetGroup(size_t /* group */) {}
01361 
01362     /// Get usage synopsis.
01363     virtual string GetUsageSynopsis(bool name_only = false) const = 0;
01364 
01365     /// Get usage comment attribute.
01366     virtual string GetUsageCommentAttr(void) const = 0;
01367 
01368     /// Process argument with specified value.
01369     virtual CArgValue* ProcessArgument(const string& value) const = 0;
01370 
01371     /// Process argument default.
01372     virtual CArgValue* ProcessDefault(void) const = 0;
01373 
01374     /// Verify argument default value.
01375     virtual void VerifyDefault (void) const;
01376 
01377     /// Set argument constraint.
01378     virtual 
01379     void SetConstraint(CArgAllow*                           constraint,
01380                        CArgDescriptions::EConstraintNegate  negate 
01381                                     = CArgDescriptions::eConstraint);
01382 
01383     /// Returns TRUE if associated contraint is inverted (NOT)
01384     /// @sa SetConstraint
01385     virtual bool IsConstraintInverted() const { return false; }
01386 
01387     /// Get argument constraint.
01388     virtual const CArgAllow* GetConstraint(void) const;
01389 
01390     /// Get usage constraint.
01391     string GetUsageConstraint(void) const;
01392 
01393     /// Get error handler for the argument
01394     virtual const CArgErrorHandler* GetErrorHandler(void) const { return 0; }
01395     /// Set error handler for the argument
01396     virtual void SetErrorHandler(CArgErrorHandler*) { return; }
01397 
01398     /// Get argument flags
01399     virtual CArgDescriptions::TFlags GetFlags(void) const { return 0; }
01400 
01401     /// Print description in XML format
01402     string PrintXml(CNcbiOstream& out) const;
01403 
01404 private:
01405     string m_Name;      ///< Argument name
01406     string m_Comment;   ///< Argument description
01407 };
01408 
01409 
01410 END_NCBI_SCOPE
01411 
01412 
01413 /* @} */
01414 
01415 #endif  /* CORELIB___NCBIARGS__HPP */
01416 
01417 

Generated on Sun Dec 6 21:58:47 2009 for NCBI C++ ToolKit by  doxygen 1.4.6
Modified on Mon Dec 07 16:20:35 2009 by modify_doxy.py rev. 173732