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
1.4.6
Modified on Mon Dec 07 16:20:35 2009 by modify_doxy.py rev. 173732