![]() |
VR-Forces 4.0.4 Class Documentation
|
00001 /******************************************************************************* 00002 ** Copyright (c) 2004 MAK Technologies, Inc. 00003 ** All rights reserved. 00004 *******************************************************************************/ 00005 /******************************************************************************* 00006 ** $RCSfile: argumentParser.h,v $ $Revision: 1.2 $ $State: Exp $ 00007 *******************************************************************************/ 00008 #ifndef argumentParser_H_ 00009 #define argumentParser_H_ 00010 00011 // 00012 // \file argumentParser.h 00013 // \brief This file contains the declaration and description of the DtArgumentParser class. 00014 // 00015 00016 #include "tdbutil/tdbUtilDefines.h" 00017 #include <vlutil/vlConfig.h> 00018 #include "tdbutil/arguments.h" 00019 #include "tdbutil/argumentException.h" 00020 #include <sstream> 00021 00022 class DtVector; 00023 class DtFilename; 00024 00025 // 00026 // DtArgumentParser is a base class for command-line-argument parsers. 00027 // \note The class parses instances of DtArgument classes, so while primarily 00028 // intended for command-line argument parsing, it doesn't matter how the 00029 // DtArguments object was created as long as it is well-formed. 00030 // 00031 // Derive additional argument parsing classes from this one for your specific 00032 // application. Simply override the appropriate parse function for the arguments 00033 // your application is concerned with. 00034 // \note This base class assumes that all arguments (not the options for those 00035 // arguments) are "switches", which means that they all begin with '-'. If 00036 // your application does not enforce that condition, override the processNonSwitch() 00037 // virtual function. 00038 // 00039 class DT_DLL_tdbutil DtArgumentParser 00040 { 00041 00042 public: 00043 DtArgumentParser(); 00044 00045 virtual ~DtArgumentParser() = 0; 00046 00047 // Begins the parsing process. Call this function when you are ready 00048 // to handle the arguments. 00049 void processArguments(const DtArguments& arguments); 00050 00051 protected: 00052 00053 // \return the current argument. 00054 std::string getArgument() const; 00055 00056 // Returns the number of arguments remaining to be processed. Does not 00057 // differentiate between the types of arguments (switches, non-switches, etc). 00058 unsigned numArgumentsLeft() const; 00059 00060 // \name Argument Reading Functions 00062 00063 // \return the current argument as a string. No error-checking performed. 00064 void readString(std::string& stringRead); 00065 00066 // \return the current argument as a string. No error-checking performed. 00067 // \note Does \b not increment the argument iterator. Useful for checking that 00068 // the next argument is the desired type/value before incrementing the iterator 00069 void peekString(std::string& stringRead) const; 00070 00071 // \return the current argument as a file name. If the current argument is not 00072 // a valid filename (validFilename()), it throws an exception. 00073 void readFilename(DtFilename& filenameRead); 00074 00075 // \return the current argument as a double. If the current argument is not 00076 // a valid double (validDouble()), it throws an exception. 00077 void readDouble(double& doubleRead); 00078 00079 // \return the current argument as a a vector of \b 3 doubles. If any number is 00080 // not a valid double (validDouble()), it throws an exception. 00081 void readVector(DtVector& vectorRead); 00082 00083 // \return the current argument as an int. If the current argument is not 00084 // a valid int (validInt()), it throws an exception. 00085 void readInt(int& intRead); 00086 00087 // \return the current argument as an unsigned int. If the current argument 00088 // is not a valid unsigned int (validUnsigned()), it throws an exception. 00089 void readUnsigned(unsigned& unsignedRead); 00090 00091 // \return the current argument as a bool. 'y' or 'yes' result in true. 00092 // 'n' or 'no' result in false. 00093 // Anything else throws an exception. 00094 void readBool(bool& boolRead); 00096 00097 00098 // \name Argument Validation Functions 00100 // 00101 // \return true if a filename is valid. 00102 // \note Currently doesn't check anything, but is there for future enhancement. 00103 bool validFilename(const std::string& argument) const; 00104 00105 // \return true if the string is a valid integer. 00106 bool validInt(const std::string& argument) const; 00107 00108 // \return true if the string is a valid unsigned integer. 00109 bool validUnsigned(const std::string& argument) const; 00110 00111 // \return true if the string is a valid double precisions floating-point number. 00112 bool validDouble(const std::string& argument) const; 00114 00115 00116 // \name Error-Handling Functions 00118 // Throws an exception. Intended for use with the the 00119 // "I-don't-know-what-this-argument-is" case. 00120 void unknownArgument() const; 00121 00122 // Throws an exception with the given error message 00123 void argumentError(const char* message) const; 00125 00126 // \return The lower-case version of the input. 00127 std::string convertToLower(const std::string& inputString) const; 00128 00129 // Defines the handling for arguments which are not directly supported by this 00130 // object. They may be handled by another parser or they may result 00131 // in an UnknownArgument() call. 00132 virtual void bounce(); 00133 00134 // Determines if the specified argument is a switch or not, and calls the 00135 // appropriate function accordingly. 00136 // \see processSwitch 00137 // \see processNonSwitch 00138 virtual void process(const std::string& argument); 00139 00140 // Process arguments which are actually switches. That is to say, they have 00141 // the '-' character first in their chars. 00142 virtual void processSwitch(const std::string& argument); 00143 00144 // Process arguments that are \b not switches. This includes all arguments 00145 // that do not have the '-' character first. 00146 // \see process 00147 virtual void processNonSwitch(const std::string& argument); 00148 00149 // \name Individual Parsing Functions 00150 // Makes it easy for derived classes to parse the arguments they are 00151 // concerned with. Override the specific ones you need to handle, and the 00152 // remaining will call bounce(). 00153 // \note The parse functions can throw DtArgumentExceptions or 00154 // a derived type such as DtUnknownArgumentException. 00156 virtual void parseA(); 00157 virtual void parseB(); 00158 virtual void parseC(); 00159 virtual void parseD(); 00160 virtual void parseE(); 00161 virtual void parseF(); 00162 virtual void parseG(); 00163 virtual void parseH(); 00164 virtual void parseI(); 00165 virtual void parseJ(); 00166 virtual void parseK(); 00167 virtual void parseL(); 00168 virtual void parseM(); 00169 virtual void parseN(); 00170 virtual void parseO(); 00171 virtual void parseP(); 00172 virtual void parseQ(); 00173 virtual void parseR(); 00174 virtual void parseS(); 00175 virtual void parseT(); 00176 virtual void parseU(); 00177 virtual void parseV(); 00178 virtual void parseW(); 00179 virtual void parseX(); 00180 virtual void parseY(); 00181 virtual void parseZ(); 00182 virtual void parseDoubleDash(); 00184 00185 private: 00186 // not implemented 00187 DtArgumentParser& operator=(const DtArgumentParser& other); 00188 DtArgumentParser(const DtArgumentParser& other); 00189 00190 // If the first character of the string is '-', then it is a switch 00191 // \return A boolean indicating whether the argument is a switch or not. 00192 bool isSwitch(const std::string& argument) const; 00193 00194 // Throws an exception when value is not of type expectedType 00195 void errorInRead(const std::string& value, const std::string& expectedType) const; 00196 00197 // This is intended as an easy way of giving useful feedback. 00198 // An example is best: if you call with (3, "A VECTOR") while reading the 00199 // -foo argument, it will throw an exception with the message "An error was 00200 // encountered in the -foo argument:\n Expected to find A VECTOR", if there 00201 // are not at least three more arguments. Note the types/values of the 00202 // arguments are not looked at - it merely examines the number of arguments. 00203 void validateExistence(unsigned numExpectedArguments, 00204 const std::string& expectedArgumentsDescription) const; 00205 00206 DtArguments::DtArgumentConstIter myArgumentsIter; 00207 std::string myCurrentArgument; 00208 const DtArguments* myArguments; 00209 }; 00210 00211 00212 // Identifies an invalid or unknown argument, such as -hhelp or just plain 00213 // garbage like -asdf 00214 class DtUnknownArgumentException : public DtArgumentException 00215 { 00216 public: 00217 inline DtUnknownArgumentException(const char* errorMessage, 00218 const DtException *previousException = 0) throw(); 00219 }; 00220 00221 inline DtUnknownArgumentException::DtUnknownArgumentException( 00222 const char* errorMessage, const DtException *previousException) throw() : 00223 DtArgumentException(errorMessage) 00224 { 00225 } 00226 00227 00228 00229 // Attempts to convert a specified string input into an instance of the type 00230 // specified by the destination parameter. 00231 // 00232 // \return A boolean indicating success or failure at conversion. 00233 // 00234 template< class T > 00235 bool DtConvert(const std::string& input, T& destination) 00236 { 00237 std::istringstream convert(input); 00238 convert >> destination; 00239 00240 return !convert.fail(); 00241 } 00242 00243 00244 00245 #endif 00246 00247 00248