Geant4 Cross Reference |
1 // 2 // ******************************************************************** 3 // * License and Disclaimer * 4 // * * 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. * 10 // * * 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitation of liability. * 17 // * * 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************************************** 25 // 26 // This example is provided by the Geant4-DNA collaboration 27 // Any report or published results obtained using the Geant4-DNA software 28 // shall cite the following Geant4-DNA collaboration publication: 29 // Med. Phys. 37 (2010) 4692-4708 30 // The Geant4-DNA web site is available at http://geant4-dna.org 31 // 32 // Author: Mathieu Karamitros 33 // 34 // 35 /// \file CommandLineParser.cc 36 /// \brief Implementation of the CommandLineParser class 37 38 #include "CommandLineParser.hh" 39 40 #include <iomanip> 41 42 using namespace std; 43 using namespace G4DNAPARSER; 44 45 CommandLineParser* CommandLineParser::fpInstance(0); 46 G4String Command::fNoOption = "NoOption"; 47 48 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 49 50 inline bool MATCH(const char* a, const char* b) 51 { 52 return strcmp(a, b) == 0; 53 } 54 55 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 56 57 CommandLineParser::CommandLineParser() 58 { 59 // G4cout << "############ NEW PARSE ##########" << G4endl; 60 fpInstance = this; 61 fOptionsWereSetup = false; 62 fMaxMarkerLength = 0; 63 fMaxOptionNameLength = 0; 64 AddCommand("--help", Command::WithoutOption, "Print this help"); 65 AddCommand("-h", Command::WithoutOption, "Print this help"); 66 AddCommand("&", Command::WithoutOption); 67 68 fVerbose = 0; 69 } 70 71 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 72 73 CommandLineParser* CommandLineParser::GetParser() 74 { 75 if (!fpInstance) new CommandLineParser; 76 return fpInstance; 77 } 78 79 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 80 81 CommandLineParser::~CommandLineParser() 82 { 83 std::map<G4String, Command*>::iterator it = fCommandMap.begin(); 84 for (; it != fCommandMap.end(); it++) { 85 if (it->second) delete it->second; 86 } 87 } 88 89 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 90 91 void CommandLineParser::DeleteInstance() 92 { 93 if (fpInstance) { 94 delete fpInstance; 95 fpInstance = 0; 96 } 97 } 98 99 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 100 101 Command::Command(Command::Type commandType, const G4String& description) 102 { 103 fType = commandType; 104 fDescription = description; 105 fActive = false; 106 } 107 108 CommandWithOption::CommandWithOption(Command::Type commandType, const G4String& description, 109 const G4String& defaultOption, const G4String& optionName) 110 : Command(commandType, description) 111 { 112 fDefaultOption = defaultOption; 113 fOptionName = optionName; 114 fOption = ""; 115 } 116 117 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 118 119 int CommandLineParser::Parse(int& argc, char** argv) 120 { 121 // G4cout << "Parse " << G4endl; 122 static char null[1] = {""}; 123 int firstArgc = argc; 124 125 for (int i = 1; i < firstArgc; i++) { 126 Command* command = FindCommand(argv[i]); 127 if (command == 0) continue; 128 129 if (fVerbose) G4cout << "Command : " << argv[i] << G4endl; 130 131 fOptionsWereSetup = true; 132 command->fActive = true; 133 134 G4String marker(argv[i]); 135 136 if (strcmp(argv[i], "-h") != 0 && strcmp(argv[i], "--help") != 0) { 137 argv[i] = null; 138 } 139 140 if (command->fType == Command::WithOption) { 141 if (fVerbose) G4cout << "WithOption" << G4endl; 142 143 if (i + 1 > firstArgc || argv[i + 1] == 0 || argv[i + 1][0] == '-') { 144 G4cerr << "An command line option is missing for " << marker << G4endl; 145 abort(); 146 } 147 148 command->SetOption((const char*)strdup(argv[i + 1])); 149 argv[i + 1] = null; 150 i++; 151 } 152 else if (command->fType == Command::OptionNotCompulsory) { 153 if (fVerbose) G4cout << "OptionNotCompulsory" << G4endl; 154 155 if (i + 1 < firstArgc) { 156 G4String buffer = (const char*)strdup(argv[i + 1]); 157 158 if (buffer.empty() == false) { 159 if (buffer.at(0) != '-' && buffer.at(0) != '&' && buffer.at(0) != '>' 160 && buffer.at(0) != '|') 161 { 162 if (fVerbose) { 163 G4cout << "facultative option is : " << buffer << G4endl; 164 } 165 166 command->SetOption((const char*)strdup(argv[i + 1])); 167 argv[i + 1] = null; 168 i++; 169 continue; 170 } 171 } 172 } 173 174 if (fVerbose) G4cout << "Option not set" << G4endl; 175 176 command->SetOption(""); 177 } 178 } 179 CorrectRemainingOptions(argc, argv); 180 181 Command* commandLine(0); 182 if ((commandLine = GetCommandIfActive("--help")) || (commandLine = GetCommandIfActive("-h"))) { 183 G4cout << "Usage : " << argv[0] << " [OPTIONS]" << G4endl; 184 PrintHelp(); 185 return 1; 186 } 187 188 return 0; 189 } 190 191 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 192 193 void CommandLineParser::PrintHelp() 194 { 195 std::map<G4String, Command*>::iterator it; 196 197 int maxFieldLength = fMaxMarkerLength + fMaxOptionNameLength + 4; 198 199 G4cout << "Options: " << G4endl; 200 201 for (it = fCommandMap.begin(); it != fCommandMap.end(); it++) { 202 Command* command = it->second; 203 if (command) { 204 G4cout << setw(maxFieldLength) << left; 205 206 G4String toPrint = it->first; 207 208 if (toPrint == "&") { 209 continue; 210 } 211 else if (toPrint == "-h") 212 continue; 213 else if (toPrint == "--help") { 214 toPrint += ", -h"; 215 } 216 217 if (command->GetDefaultOption() != "") { 218 toPrint += " \"" + command->GetDefaultOption() + "\""; 219 } 220 221 G4cout << toPrint; 222 223 G4cout << command->GetDescription() << G4endl; 224 } 225 } 226 } 227 228 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 229 230 void CommandLineParser::CorrectRemainingOptions(int& argc, char** argv) 231 { 232 // remove handled arguments from argument array 233 int j = 0; 234 for (int i = 0; i < argc; i++) { 235 if (strcmp(argv[i], "")) { 236 argv[j] = argv[i]; 237 j++; 238 } 239 } 240 argc = j; 241 } 242 243 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 244 245 void CommandLineParser::AddCommand(const G4String& marker, Command::Type type, 246 const G4String& description, const G4String& defaultOption, 247 const G4String& optionName) 248 { 249 // G4cout << "Add command : "<< marker << G4endl; 250 251 Command* command = 0; 252 switch (type) { 253 case Command::WithoutOption: 254 command = new Command(type, description); 255 break; 256 257 default: 258 command = new CommandWithOption(type, description, defaultOption, optionName); 259 if ((int)defaultOption.length() > fMaxOptionNameLength) 260 fMaxOptionNameLength = defaultOption.length(); 261 break; 262 } 263 264 if ((int)marker.length() > fMaxMarkerLength) fMaxMarkerLength = marker.length(); 265 fCommandMap.insert(make_pair(marker, command)); 266 } 267 268 /* 269 // Add one command but multiple markers 270 void Parser::AddCommand(vector<G4String> markers, 271 CommandType type, 272 const G4String& description, 273 const G4String& optionName) 274 { 275 // G4cout << "Add command : "<< marker << G4endl; 276 Command* command = new Command(type, description, optionName); 277 278 for (size_t i = 0; i < markers.size; i++) 279 { 280 G4String marker = markers[i]; 281 if ((int) marker.length() > fMaxMarkerLength) 282 { 283 fMaxMarkerLength = marker.length(); 284 } 285 if ((int) optionName.length() > fMaxOptionNameLength) 286 { 287 fMaxOptionNameLength = optionName.length(); 288 } 289 fCommandMap.insert(make_pair(marker, command)); 290 } 291 } 292 */ 293 294 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 295 296 Command* CommandLineParser::FindCommand(const G4String& marker) 297 { 298 std::map<G4String, Command*>::iterator it = fCommandMap.find(marker); 299 if (it == fCommandMap.end()) { 300 // G4cerr << "command not found" << G4endl; 301 return 0; 302 } 303 return it->second; 304 } 305 306 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 307 308 Command* CommandLineParser::GetCommandIfActive(const G4String& marker) 309 { 310 Command* command = FindCommand(marker); 311 if (command) { 312 // G4cout << "Command found : "<< marker << G4endl; 313 314 if (command->fActive) { 315 // G4cout << "Command Active" << G4endl; 316 return command; 317 } 318 // else 319 // G4cout <<"Command not active" << G4endl; 320 } 321 else { 322 G4ExceptionDescription description; 323 description << "You try to retrieve a command that was not registered : " << marker << G4endl; 324 G4Exception("CommandLineParser::GetCommandIfActive", "COMMAND LINE NOT DEFINED", FatalException, 325 description, ""); 326 // If you are using this class outside of Geant4, use exit(-1) instead 327 // exit(-1); 328 } 329 return 0; 330 } 331 332 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 333 334 bool CommandLineParser::CheckIfNotHandledOptionsExists(int& argc, char** argv) 335 { 336 if (argc > 0) { 337 G4bool kill = false; 338 for (G4int i = 1; i < argc; i++) { 339 if (strcmp(argv[i], "")) { 340 kill = true; 341 G4cerr << "Unknown argument : " << argv[i] << "\n"; 342 } 343 } 344 if (kill) { 345 G4cerr << "The option " << argv[0] << " is not handled this programme." << G4endl; 346 G4cout << "Usage : " << argv[0] << " [OPTIONS]" << G4endl; 347 PrintHelp(); 348 return true; // KILL APPLICATION 349 } 350 } 351 return false; 352 } 353