Changeset 3280 for code/trunk/src/core/CommandLine.cc
- Timestamp:
- Jul 12, 2009, 11:58:01 PM (16 years ago)
- Location:
- code/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
code/trunk
- Property svn:mergeinfo changed
/code/branches/core4 (added) merged: 3235-3237,3245-3250,3253-3254,3260-3261,3265,3270
- Property svn:mergeinfo changed
-
code/trunk/src/core/CommandLine.cc
r3196 r3280 29 29 #include "CommandLine.h" 30 30 31 #include <algorithm> 32 #include <sstream> 31 33 #include <boost/filesystem.hpp> 32 34 … … 34 36 #include "util/Debug.h" 35 37 #include "util/Exception.h" 36 #include "util/String .h"38 #include "util/StringUtils.h" 37 39 #include "util/SubString.h" 38 40 #include "Core.h" … … 40 42 namespace orxonox 41 43 { 42 SetCommandLine Argument(optionsFile, "start.ini").shortcut("o");44 SetCommandLineOnlyArgument(optionsFile, "start.ini").shortcut("o"); 43 45 44 46 /** … … 49 51 so that you can have simple command line switches. 50 52 */ 51 void CommandLineArgument::parse(const std::string& value) 52 { 53 if (value_.getType() == MT_bool) 53 void CommandLineArgument::parse(const std::string& value, bool bParsingFile) 54 { 55 if (bParsingFile && this->bCommandLineOnly_) 56 ThrowException(Argument, "Command line argument '" + getName() + "' is not allowed in files."); 57 if (value_.getType() == MT_Type::Bool) 54 58 { 55 59 // simulate command line switch … … 66 70 } 67 71 else 68 {69 72 ThrowException(Argument, "Could not read command line argument '" + getName() + "'."); 70 }71 73 } 72 74 else … … 126 128 Vector of space separated strings. 127 129 */ 128 void CommandLine::_parse(const std::vector<std::string>& arguments) 129 { 130 // why this? See bFirstTimeParse_ declaration. 131 if (bFirstTimeParse_) 132 { 133 // first shove all the shortcuts in a map 134 for (std::map<std::string, CommandLineArgument*>::const_iterator it = cmdLineArgs_.begin(); 135 it != cmdLineArgs_.end(); ++it) 136 { 137 OrxAssert(cmdLineArgsShortcut_.find(it->second->getShortcut()) == cmdLineArgsShortcut_.end(), 138 "Cannot have two command line shortcut with the same name."); 139 if (it->second->getShortcut() != "") 140 cmdLineArgsShortcut_[it->second->getShortcut()] = it->second; 141 } 142 bFirstTimeParse_ = false; 143 } 144 145 std::string name; 146 std::string shortcut; 147 std::string value; 148 for (unsigned int i = 0; i < arguments.size(); ++i) 149 { 150 if (arguments[i].size() != 0) 151 { 152 // sure not "" 153 if (arguments[i][0] == '-') 130 void CommandLine::_parse(const std::vector<std::string>& arguments, bool bParsingFile) 131 { 132 try 133 { 134 // why this? See bFirstTimeParse_ declaration. 135 if (bFirstTimeParse_) 136 { 137 // first shove all the shortcuts in a map 138 for (std::map<std::string, CommandLineArgument*>::const_iterator it = cmdLineArgs_.begin(); 139 it != cmdLineArgs_.end(); ++it) 154 140 { 155 // start with "-" 156 if (arguments[i].size() == 1) 141 OrxAssert(cmdLineArgsShortcut_.find(it->second->getShortcut()) == cmdLineArgsShortcut_.end(), 142 "Cannot have two command line shortcut with the same name."); 143 if (it->second->getShortcut() != "") 144 cmdLineArgsShortcut_[it->second->getShortcut()] = it->second; 145 } 146 bFirstTimeParse_ = false; 147 } 148 149 std::string name; 150 std::string shortcut; 151 std::string value; 152 for (unsigned int i = 0; i < arguments.size(); ++i) 153 { 154 if (arguments[i].size() != 0) 155 { 156 // sure not "" 157 if (arguments[i][0] == '-') 157 158 { 158 // argument[i] is "-", probably a minus sign 159 value += "- "; 160 } 161 else if (arguments[i][1] <= 57 && arguments[i][1] >= 48) 162 { 163 // negative number as a value 164 value += arguments[i] + " "; 159 // start with "-" 160 if (arguments[i].size() == 1) 161 { 162 // argument[i] is "-", probably a minus sign 163 value += "- "; 164 } 165 else if (arguments[i][1] <= 57 && arguments[i][1] >= 48) 166 { 167 // negative number as a value 168 value += arguments[i] + " "; 169 } 170 else 171 { 172 // can be shortcut or full name argument 173 174 // save old data first 175 value = removeTrailingWhitespaces(value); 176 if (name != "") 177 { 178 checkFullArgument(name, value, bParsingFile); 179 name = ""; 180 assert(shortcut == ""); 181 } 182 else if (shortcut != "") 183 { 184 checkShortcut(shortcut, value, bParsingFile); 185 shortcut = ""; 186 assert(name == ""); 187 } 188 189 if (arguments[i][1] == '-') 190 { 191 // full name argument with "--name" 192 name = arguments[i].substr(2); 193 } 194 else 195 { 196 // shortcut with "-s" 197 shortcut = arguments[i].substr(1); 198 } 199 200 // reset value string 201 value = ""; 202 } 165 203 } 166 204 else 167 205 { 168 // can be shortcut or full name argument 169 170 // save old data first 171 value = removeTrailingWhitespaces(value); 172 if (name != "") 206 // value string 207 208 if (name == "" && shortcut == "") 173 209 { 174 checkFullArgument(name, value); 175 name = ""; 176 assert(shortcut == ""); 210 ThrowException(Argument, "Expected \"-\" or \"-\" in command line arguments.\n"); 177 211 } 178 else if (shortcut != "") 179 { 180 checkShortcut(shortcut, value); 181 shortcut = ""; 182 assert(name == ""); 183 } 184 185 if (arguments[i][1] == '-') 186 { 187 // full name argument with "--name" 188 name = arguments[i].substr(2); 189 } 190 else 191 { 192 // shortcut with "-s" 193 shortcut = arguments[i].substr(1); 194 } 195 196 // reset value string 197 value = ""; 212 213 // Concatenate strings as long as there's no new argument by "-" or "--" 214 value += arguments[i] + ' '; 198 215 } 199 216 } 200 else 201 { 202 // value string 203 204 if (name == "" && shortcut == "") 205 { 206 ThrowException(Argument, "Expected \"-\" or \"-\" in command line arguments.\n"); 207 } 208 209 // Concatenate strings as long as there's no new argument by "-" or "--" 210 value += arguments[i] + ' '; 211 } 212 } 213 } 214 215 // parse last argument 216 value = removeTrailingWhitespaces(value); 217 if (name != "") 218 { 219 checkFullArgument(name, value); 220 assert(shortcut == ""); 221 } 222 else if (shortcut != "") 223 { 224 checkShortcut(shortcut, value); 225 assert(name == ""); 217 } 218 219 // parse last argument 220 value = removeTrailingWhitespaces(value); 221 if (name != "") 222 { 223 checkFullArgument(name, value, bParsingFile); 224 assert(shortcut == ""); 225 } 226 else if (shortcut != "") 227 { 228 checkShortcut(shortcut, value, bParsingFile); 229 assert(name == ""); 230 } 231 } 232 catch (const ArgumentException& ex) 233 { 234 COUT(0) << "Could not parse command line (including additional files): " << ex.what() << std::endl; 235 COUT(0) << CommandLine::getUsageInformation() << std::endl; 236 throw GeneralException(""); 226 237 } 227 238 } … … 235 246 String containing the value 236 247 */ 237 void CommandLine::checkFullArgument(const std::string& name, const std::string& value )248 void CommandLine::checkFullArgument(const std::string& name, const std::string& value, bool bParsingFile) 238 249 { 239 250 std::map<std::string, CommandLineArgument*>::const_iterator it = cmdLineArgs_.find(name); … … 241 252 ThrowException(Argument, "Command line argument '" + name + "' does not exist."); 242 253 243 it->second->parse(value );254 it->second->parse(value, bParsingFile); 244 255 } 245 256 … … 252 263 String containing the value 253 264 */ 254 void CommandLine::checkShortcut(const std::string& shortcut, const std::string& value )265 void CommandLine::checkShortcut(const std::string& shortcut, const std::string& value, bool bParsingFile) 255 266 { 256 267 std::map<std::string, CommandLineArgument*>::const_iterator it = cmdLineArgsShortcut_.find(shortcut); … … 258 269 ThrowException(Argument, "Command line shortcut '" + shortcut + "' does not exist."); 259 270 260 it->second->parse(value );271 it->second->parse(value, bParsingFile); 261 272 } 262 273 263 274 std::string CommandLine::getUsageInformation() 264 275 { 265 CommandLine* inst = &_getInstance(); 266 std::string infoStr; 267 for (std::map<std::string, CommandLineArgument*>::const_iterator it = inst->cmdLineArgs_.begin(); 268 it != inst->cmdLineArgs_.end(); ++it) 269 { 270 infoStr += "[--" + it->second->getName() + " " + it->second->getInformation() + "] "; 271 } 272 return infoStr; 276 CommandLine& inst = _getInstance(); 277 std::ostringstream infoStr; 278 279 // determine maximum name size 280 size_t maxNameSize = 0; 281 for (std::map<std::string, CommandLineArgument*>::const_iterator it = inst.cmdLineArgs_.begin(); 282 it != inst.cmdLineArgs_.end(); ++it) 283 { 284 maxNameSize = std::max(it->second->getName().size(), maxNameSize); 285 } 286 287 infoStr << "Usage: orxonox [options]" << std::endl; 288 infoStr << "Available options:" << std::endl; 289 290 for (std::map<std::string, CommandLineArgument*>::const_iterator it = inst.cmdLineArgs_.begin(); 291 it != inst.cmdLineArgs_.end(); ++it) 292 { 293 if (it->second->getShortcut() != "") 294 infoStr << " [-" << it->second->getShortcut() << "] "; 295 else 296 infoStr << " "; 297 infoStr << "--" << it->second->getName() << " "; 298 if (it->second->getValue().getType() != MT_Type::Bool) 299 infoStr << "ARG "; 300 else 301 infoStr << " "; 302 // fill with the necessary amount of blanks 303 infoStr << std::string(maxNameSize - it->second->getName().size(), ' '); 304 infoStr << ": " << it->second->getInformation(); 305 infoStr << std::endl; 306 } 307 return infoStr.str(); 273 308 } 274 309 … … 295 330 /** 296 331 @brief 297 Parses both command line and start.ini for CommandLineArguments. 298 */ 299 void CommandLine::_parseAll(int argc, char** argv) 300 { 301 // parse command line first 332 Parses only the command line for CommandLineArguments. 333 */ 334 void CommandLine::_parseCommandLine(int argc, char** argv) 335 { 302 336 std::vector<std::string> args; 303 337 for (int i = 1; i < argc; ++i) 304 338 args.push_back(argv[i]); 305 this->_parse(args); 306 339 this->_parse(args, false); 340 } 341 342 /** 343 @brief 344 Parses start.ini (or the file specified with --optionsFile) for CommandLineArguments. 345 */ 346 void CommandLine::_parseFile() 347 { 307 348 std::string filename = CommandLine::getValue("optionsFile").getString(); 308 349 boost::filesystem::path filepath(Core::getConfigPath() / filename); … … 312 353 std::ifstream file; 313 354 file.open(filepath.string().c_str()); 314 args.clear();355 std::vector<std::string> args; 315 356 if (file) 316 357 { … … 332 373 } 333 374 334 try 335 { 336 _parse(args); 337 } 338 catch (orxonox::ArgumentException& ex) 339 { 340 COUT(1) << "An Exception occured while parsing " << filename << std::endl; 341 throw(ex); 342 } 375 _parse(args, true); 343 376 } 344 377 }
Note: See TracChangeset
for help on using the changeset viewer.