Changeset 1664 for code/branches/gui/src/core/CommandLine.h
- Timestamp:
- Aug 21, 2008, 9:23:11 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/gui/src/core/CommandLine.h
r1663 r1664 36 36 #include "Exception.h" 37 37 38 39 38 #define SetCommandLineArgument(name, defaultValue) \ 40 39 BaseCommandLineArgument& CmdArgumentDummyBoolVar##name \ 41 40 = orxonox::CommandLine::addCommandLineArgument(#name, defaultValue) 41 #define SetCommandLineSwitch(name) \ 42 BaseCommandLineArgument& CmdArgumentDummyBoolVar##name \ 43 = orxonox::CommandLine::addCommandLineArgument(#name, false) 44 42 45 43 46 namespace orxonox 44 47 { 48 /** 49 @brief 50 Template struct which creates a distinct type for every integer constant. 51 @note 52 This allows to select a different function depending on a boolean value 53 when creating a new CommandLineArgument. 54 From 'Modern C++ Design' (Alexandrescu 2001). 55 */ 56 template <int v> 57 struct Int2Type 58 { 59 enum { value = v }; 60 }; 61 62 /** 63 @brief 64 Base class for CommandLineArguments. 65 */ 45 66 class _CoreExport BaseCommandLineArgument 46 67 { … … 48 69 49 70 public: 71 //! Tells whether the value has been changed by the command line. 50 72 bool hasDefaultValue() const { return bHasDefaultValue_; } 73 //! Returns the name of the argument. 51 74 const std::string& getName() const { return name_; } 75 76 //! Returns the shortcut (example: "-p 22" for "--port 22") of the argument. 77 //! Evaluates to "" if none there is none. 52 78 const std::string& getShortcut() const { return shortcut_; } 79 //! Sets the shortcut for the argument 53 80 BaseCommandLineArgument& setShortcut(const std::string& shortcut) 54 81 { this->shortcut_ = shortcut; return *this; } 82 83 //! Returns the usage information 84 const std::string& getInformation() const { return this->usageInformation_; } 85 //! Sets the option information when displaying orxonox usage. 86 BaseCommandLineArgument& setInformation(const std::string& usage) 87 { this->usageInformation_ = usage; return *this; } 55 88 56 89 protected: … … 60 93 { } 61 94 95 //! Undefined copy constructor 62 96 BaseCommandLineArgument(const BaseCommandLineArgument& instance); 63 97 virtual ~BaseCommandLineArgument() { } 64 98 99 //! Parses the value string of a command line argument. 65 100 virtual void parse(const std::string& value) = 0; 66 101 102 //! Tells whether the value has been changed by the command line. 67 103 bool bHasDefaultValue_; 68 104 69 105 private: 70 std::string name_; 71 std::string shortcut_; 106 std::string name_; //!< Name of the argument 107 std::string shortcut_; //!< Shortcut of the argument. @see getShortcut(). 108 std::string usageInformation_; //!< Tells about the usage of this parameter 72 109 }; 73 110 74 111 112 /** 113 @brief 114 Container class for a command line argument of type T. 115 116 Whenever you want to have an option specified by a command line switch, 117 you need to first define it with SetCommandLineArgument(name, defaultValue). 118 It is then added to a map and possibly changed when the command line is being parsed. 119 If the option was not given, you can detect this by asking hasDefaultValue(). 120 121 There is a possibility to define a short cut so you can write "-p 20" instead of "--port 20". 122 Note the difference between "-" and "--"! 123 Also, there is no restriction to the number of strings you add after --name. 124 So "--startVector (2, 4, 5)" is perfectly legal. 125 126 Retrieving an argument is possible with the getCommandLineArgument function of the 127 CommandLine class. It is a Singleton, but the public interface is static. 128 */ 75 129 template <class T> 76 130 class CommandLineArgument : public BaseCommandLineArgument 77 131 { 132 // Only let CommandLine change the value. 78 133 friend class CommandLine; 79 134 80 135 public: 136 //! Returns the actual value of the argument. Can be equal to default value. 81 137 T getValue() const { return value_; } 138 //! Returns the given default value as type T. 82 139 T getDefaultValue() const { return defaultValue_; } 83 140 84 141 private: 142 //! Constructor initialises both value_ and defaultValue_ with defaultValue. 85 143 CommandLineArgument(const std::string& name, const T& defaultValue) 86 144 : BaseCommandLineArgument(name) … … 91 149 virtual void parse(const std::string& value); 92 150 93 T value_; 94 T defaultValue_; 151 T value_; //!< The actual value 152 T defaultValue_; //!< Default value. Should not be changed. 95 153 }; 96 154 155 /** 156 @brief 157 Parses a value string for a command line argument. 158 It simply uses convertValue(Output, Input) to do that. 159 */ 97 160 template <class T> 98 161 void CommandLineArgument<T>::parse(const std::string& value) … … 108 171 } 109 172 110 173 /** 174 @brief 175 Parses a value string for a command line argument. 176 It simply uses convertValue(Output, Input) to do that. 177 This is a template specialisation for bool type. That is necessary 178 so that you can have simple command line switches. 179 */ 180 template <> 181 inline void CommandLineArgument<bool>::parse(const std::string& value) 182 { 183 if (convertValue(&this->value_, value)) 184 { 185 this->bHasDefaultValue_ = false; 186 } 187 else if (value == "") 188 { 189 this->bHasDefaultValue_ = false; 190 this->value_ = true; 191 } 192 else 193 { 194 ThrowException(Argument, "Could not read command line argument '" + getName() + "'."); 195 } 196 } 197 198 199 /** 200 @brief 201 Global interface to command line options. 202 Allows to add and retrieve command line arguments. Also does the parsing. 203 @note 204 Internally it is a Singleton, but the public interface is static. 205 @see 206 CommandLineArgument 207 */ 111 208 class _CoreExport CommandLine 112 209 { 113 210 public: 114 211 115 static void parse(int argc, char** argv) { _getInstance()._parse(argc, argv); } 212 //! Parse redirection to internal member method. 213 static void parse(const std::vector<std::string>& arguments) { _getInstance()._parse(arguments); } 214 215 static std::string getUsageInformation(); 116 216 117 217 template <class T> 118 218 static const CommandLineArgument<T>* getCommandLineArgument(const std::string& name); 119 template <class T> 120 static BaseCommandLineArgument& addCommandLineArgument(const std::string& name, 121 const T& defaultValue); 219 //! Writes the argument value in the given parameter. 220 template <class T> 221 static void getCommandLineValue(const std::string& name, T* value) 222 { *value = getCommandLineArgument<T>(name)->getValue(); } 223 template <class T> 224 static BaseCommandLineArgument& addCommandLineArgument(const std::string& name, T defaultValue); 122 225 123 226 private: 227 //! Constructor initialises bFirstTimeParse_ with true. 124 228 CommandLine() : bFirstTimeParse_(true) { } 229 //! Undefined copy constructor 125 230 CommandLine(const CommandLine& instance); 126 231 ~CommandLine(); … … 128 233 static CommandLine& _getInstance(); 129 234 130 void _parse( int argc, char** argv);235 void _parse(const std::vector<std::string>& arguments); 131 236 void checkFullArgument(const std::string& name, const std::string& value); 132 237 void checkShortcut(const std::string& shortcut, const std::string& value); 133 238 239 template <class T> 240 BaseCommandLineArgument* createArg(const std::string& name, T defaultValue, Int2Type<0> isString); 241 template <class T> 242 BaseCommandLineArgument* createArg(const std::string& name, T defaultValue, Int2Type<1> isString); 243 244 /** 245 Tells whether we parse the first expression. The CommmandLineArguments are added before main(). 246 So when we call parse() the first time, we need to create a map with all shortcuts since these 247 get added after addCommandLineArgument(). 248 */ 134 249 bool bFirstTimeParse_; 135 250 251 //! Holds all pointers to the arguments and serves as a search map by name. 136 252 std::map<std::string, BaseCommandLineArgument*> cmdLineArgs_; 253 //! Search map by chortcut for the arguments. 137 254 std::map<std::string, BaseCommandLineArgument*> cmdLineArgsShortcut_; 138 255 }; 139 256 140 257 258 /** 259 @brief 260 Retrieves a CommandLineArgument. 261 The method throws an exception if 'name' was not found or the value could not be converted. 262 @note 263 You shold of course not call this method before the command line has been parsed. 264 */ 141 265 template <class T> 142 266 const CommandLineArgument<T>* CommandLine::getCommandLineArgument(const std::string& name) … … 162 286 } 163 287 164 template <class T> 165 BaseCommandLineArgument& CommandLine::addCommandLineArgument(const std::string& name, 166 const T& defaultValue) 288 /** 289 @brief 290 Adds a new CommandLineArgument to the internal map. 291 Note that only such arguments are actually valid. 292 @param name 293 Name of the argument. Shortcut can be added later. 294 @param defaultValue 295 Default value that is used when argument was not given. 296 @note 297 In order to store char* strings as std::string too, there's 298 little bit of template programming involved: 299 StaticConversions::exists determines whether T converts to std::string. 300 Int2Type<int> is then used to call the right function. One returns 301 a CommandLineArgument<T> and the other CommandLineArgument<std::string>. 302 */ 303 template <class T> 304 BaseCommandLineArgument& CommandLine::addCommandLineArgument(const std::string& name, T defaultValue) 167 305 { 168 306 std::map<std::string, BaseCommandLineArgument*>::const_iterator it = _getInstance().cmdLineArgs_.find(name); … … 170 308 "Cannot add a command line argument with name '" + name + "' twice."); 171 309 172 return *(_getInstance().cmdLineArgs_[name] = new CommandLineArgument<T>(name, defaultValue)); 310 return *(_getInstance().cmdLineArgs_[name] = 311 _getInstance().createArg(name, defaultValue, Int2Type<StaticConversion<T, std::string>::exists>())); 312 } 313 314 /** 315 Returns a new CommandLineArgument<T>. 316 */ 317 template <class T> 318 BaseCommandLineArgument* CommandLine::createArg(const std::string& name, T defaultValue, Int2Type<0> isPrime) 319 { 320 return new CommandLineArgument<T>(name, defaultValue); 321 } 322 323 /** 324 Returns a new CommandLineArgument<std::string>. 325 */ 326 template <class T> 327 BaseCommandLineArgument* CommandLine::createArg(const std::string& name, T defaultValue, Int2Type<1> isPrime) 328 { 329 return new CommandLineArgument<std::string>(name, defaultValue); 173 330 } 174 331 }
Note: See TracChangeset
for help on using the changeset viewer.