Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-13 08:29:40

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 /// \file CommandLineParser.cc
0027 /// \brief Implementation of the G4DNAPARSER::CommandLineParser class
0028 
0029 // This example is provided by the Geant4-DNA collaboration
0030 // Any report or published results obtained using the Geant4-DNA software
0031 // shall cite the following Geant4-DNA collaboration publication:
0032 // Med. Phys. 37 (2010) 4692-4708
0033 // J. Comput. Phys. 274 (2014) 841-882
0034 // The Geant4-DNA web site is available at http://geant4-dna.org
0035 //
0036 // Author: Mathieu Karamitros
0037 //
0038 //
0039 
0040 #include "CommandLineParser.hh"
0041 
0042 #include <iomanip>
0043 
0044 using namespace std;
0045 using namespace G4DNAPARSER;
0046 
0047 CommandLineParser* CommandLineParser::fpInstance(0);
0048 G4String Command::fNoOption = "NoOption";
0049 
0050 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0051 
0052 inline bool MATCH(const char* a, const char* b)
0053 {
0054   return strcmp(a, b) == 0;
0055 }
0056 
0057 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0058 
0059 CommandLineParser::CommandLineParser()
0060 {
0061   // G4cout << "############ NEW PARSE ##########" << G4endl;
0062   fpInstance = this;
0063   fOptionsWereSetup = false;
0064   fMaxMarkerLength = 0;
0065   fMaxOptionNameLength = 0;
0066   AddCommand("--help", Command::WithoutOption, "Print this help");
0067   AddCommand("-h", Command::WithoutOption, "Print this help");
0068   AddCommand("&", Command::WithoutOption);
0069 
0070   fVerbose = 0;
0071 }
0072 
0073 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0074 
0075 CommandLineParser* CommandLineParser::GetParser()
0076 {
0077   if (!fpInstance) new CommandLineParser;
0078   return fpInstance;
0079 }
0080 
0081 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0082 
0083 CommandLineParser::~CommandLineParser()
0084 {
0085   std::map<G4String, Command*>::iterator it = fCommandMap.begin();
0086   for (; it != fCommandMap.end(); it++) {
0087     if (it->second) delete it->second;
0088   }
0089 }
0090 
0091 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0092 
0093 void CommandLineParser::DeleteInstance()
0094 {
0095   if (fpInstance) {
0096     delete fpInstance;
0097     fpInstance = 0;
0098   }
0099 }
0100 
0101 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0102 
0103 Command::Command(Command::Type commandType, const G4String& description)
0104 {
0105   fType = commandType;
0106   fDescription = description;
0107   fActive = false;
0108 }
0109 
0110 CommandWithOption::CommandWithOption(Command::Type commandType, const G4String& description,
0111                                      const G4String& defaultOption, const G4String& optionName)
0112   : Command(commandType, description)
0113 {
0114   fDefaultOption = defaultOption;
0115   fOptionName = optionName;
0116   fOption = "";
0117 }
0118 
0119 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0120 
0121 int CommandLineParser::Parse(int& argc, char** argv)
0122 {
0123   //    G4cout << "Parse " << G4endl;
0124   static char null[1] = {""};
0125   int firstArgc = argc;
0126 
0127   for (int i = 1; i < firstArgc; i++) {
0128     Command* command = FindCommand(argv[i]);
0129     if (command == 0) continue;
0130 
0131     if (fVerbose) G4cout << "Command : " << argv[i] << G4endl;
0132 
0133     fOptionsWereSetup = true;
0134     command->fActive = true;
0135 
0136     G4String marker(argv[i]);
0137 
0138     if (strcmp(argv[i], "-h") != 0 && strcmp(argv[i], "--help") != 0) {
0139       argv[i] = null;
0140     }
0141 
0142     if (command->fType == Command::WithOption) {
0143       if (fVerbose) G4cout << "WithOption" << G4endl;
0144 
0145       if (i + 1 > firstArgc || argv[i + 1] == 0 || argv[i + 1][0] == '-') {
0146         G4cerr << "An command line option is missing for " << marker << G4endl;
0147         abort();
0148       }
0149 
0150       command->SetOption((const char*)strdup(argv[i + 1]));
0151       argv[i + 1] = null;
0152       i++;
0153     }
0154     else if (command->fType == Command::OptionNotCompulsory) {
0155       if (fVerbose) G4cout << "OptionNotCompulsory" << G4endl;
0156 
0157       if (i + 1 < firstArgc) {
0158         G4String buffer = (const char*)strdup(argv[i + 1]);
0159 
0160         if (buffer.empty() == false) {
0161           if (buffer.at(0) != '-' && buffer.at(0) != '&' && buffer.at(0) != '>'
0162               && buffer.at(0) != '|')
0163           {
0164             if (fVerbose) {
0165               G4cout << "facultative option is : " << buffer << G4endl;
0166             }
0167 
0168             command->SetOption((const char*)strdup(argv[i + 1]));
0169             argv[i + 1] = null;
0170             i++;
0171             continue;
0172           }
0173         }
0174       }
0175 
0176       if (fVerbose) G4cout << "Option not set" << G4endl;
0177 
0178       command->SetOption("");
0179     }
0180   }
0181   CorrectRemainingOptions(argc, argv);
0182 
0183   Command* commandLine(0);
0184   if ((commandLine = GetCommandIfActive("--help")) || (commandLine = GetCommandIfActive("-h"))) {
0185     G4cout << "Usage : " << argv[0] << " [OPTIONS]" << G4endl;
0186     PrintHelp();
0187     return 1;
0188   }
0189 
0190   return 0;
0191 }
0192 
0193 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0194 
0195 void CommandLineParser::PrintHelp()
0196 {
0197   std::map<G4String, Command*>::iterator it;
0198 
0199   int maxFieldLength = fMaxMarkerLength + fMaxOptionNameLength + 4;
0200 
0201   G4cout << "Options: " << G4endl;
0202 
0203   for (it = fCommandMap.begin(); it != fCommandMap.end(); it++) {
0204     Command* command = it->second;
0205     if (command) {
0206       G4cout << setw(maxFieldLength) << left;
0207 
0208       G4String toPrint = it->first;
0209 
0210       if (toPrint == "&") {
0211         continue;
0212       }
0213       else if (toPrint == "-h")
0214         continue;
0215       else if (toPrint == "--help") {
0216         toPrint += ", -h";
0217       }
0218 
0219       if (command->GetType() != Command::WithoutOption) {
0220         if (command->GetDefaultOption() != "") {
0221           toPrint += " \"" + command->GetDefaultOption() + "\"";
0222         }
0223       }
0224       G4cout << toPrint;
0225 
0226       G4cout << command->GetDescription() << G4endl;
0227     }
0228   }
0229 }
0230 
0231 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0232 
0233 void CommandLineParser::CorrectRemainingOptions(int& argc, char** argv)
0234 {
0235   // remove handled arguments from argument array
0236   int j = 0;
0237   for (int i = 0; i < argc; i++) {
0238     if (strcmp(argv[i], "")) {
0239       argv[j] = argv[i];
0240       j++;
0241     }
0242   }
0243   argc = j;
0244 }
0245 
0246 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0247 
0248 void CommandLineParser::AddCommand(const G4String& marker, Command::Type type,
0249                                    const G4String& description, const G4String& defaultOption,
0250                                    const G4String& optionName)
0251 {
0252   // G4cout << "Add command : "<< marker << G4endl;
0253 
0254   Command* command = 0;
0255   switch (type) {
0256     case Command::WithoutOption:
0257       command = new Command(type, description);
0258       break;
0259 
0260     default:
0261       command = new CommandWithOption(type, description, defaultOption, optionName);
0262       if ((int)defaultOption.length() > fMaxOptionNameLength)
0263         fMaxOptionNameLength = defaultOption.length();
0264       break;
0265   }
0266 
0267   if ((int)marker.length() > fMaxMarkerLength) fMaxMarkerLength = marker.length();
0268   fCommandMap.insert(make_pair(marker, command));
0269 }
0270 
0271 /*
0272 // Add one command but multiple markers
0273 void Parser::AddCommand(vector<G4String> markers,
0274                         CommandType type,
0275                         const G4String& description,
0276                         const G4String& optionName)
0277 {
0278   // G4cout << "Add command : "<< marker << G4endl;
0279   Command* command = new Command(type, description, optionName);
0280 
0281   for (size_t i = 0; i < markers.size; i++)
0282   {
0283     G4String marker = markers[i];
0284     if ((int) marker.length() > fMaxMarkerLength)
0285     {
0286       fMaxMarkerLength = marker.length();
0287     }
0288     if ((int) optionName.length() > fMaxOptionNameLength)
0289     {
0290       fMaxOptionNameLength = optionName.length();
0291     }
0292     fCommandMap.insert(make_pair(marker, command));
0293   }
0294 }
0295 */
0296 
0297 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0298 
0299 Command* CommandLineParser::FindCommand(const G4String& marker)
0300 {
0301   std::map<G4String, Command*>::iterator it = fCommandMap.find(marker);
0302   if (it == fCommandMap.end()) {
0303     // G4cerr << "command not found" << G4endl;
0304     return 0;
0305   }
0306   return it->second;
0307 }
0308 
0309 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0310 
0311 Command* CommandLineParser::GetCommandIfActive(const G4String& marker)
0312 {
0313   Command* command = FindCommand(marker);
0314   if (command) {
0315     // G4cout << "Command found : "<< marker << G4endl;
0316 
0317     if (command->fActive) {
0318       // G4cout << "Command Active" << G4endl;
0319       return command;
0320     }
0321     // else
0322     //  G4cout <<"Command not active" << G4endl;
0323   }
0324   else {
0325     G4ExceptionDescription description;
0326     description << "You try to retrieve a command that was not registered : " << marker << G4endl;
0327     G4Exception("CommandLineParser::GetCommandIfActive", "COMMAND LINE NOT DEFINED", FatalException,
0328                 description, "");
0329     // If you are using this class outside of Geant4, use exit(-1) instead
0330     // exit(-1);
0331   }
0332   return 0;
0333 }
0334 
0335 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0336 
0337 bool CommandLineParser::CheckIfNotHandledOptionsExists(int& argc, char** argv)
0338 {
0339   if (argc > 0) {
0340     G4bool kill = false;
0341     for (G4int i = 1; i < argc; i++) {
0342       if (strcmp(argv[i], "")) {
0343         kill = true;
0344         G4cerr << "Unknown argument : " << argv[i] << "\n";
0345       }
0346     }
0347     if (kill) {
0348       G4cerr << "The option " << argv[0] << " is not handled this programme." << G4endl;
0349       G4cout << "Usage : " << argv[0] << " [OPTIONS]" << G4endl;
0350       PrintHelp();
0351       return true;  // KILL APPLICATION
0352     }
0353   }
0354   return false;
0355 }