Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-17 08:06:48

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 // This example is provided by the Geant4-DNA collaboration
0027 // Any report or published results obtained using the Geant4-DNA software
0028 // shall cite the following Geant4-DNA collaboration publication:
0029 // Med. Phys. 37 (2010) 4692-4708
0030 // J. Comput. Phys. 274 (2014) 841-882
0031 // The Geant4-DNA web site is available at http://geant4-dna.org
0032 //
0033 // Author: Mathieu Karamitros
0034 //
0035 //
0036 /// \file CommandLineParser.cc
0037 /// \brief Implementation of the CommandLineParser class
0038 
0039 #include "CommandLineParser.hh"
0040 
0041 #include <iomanip>
0042 
0043 using namespace std;
0044 using namespace G4DNAPARSER;
0045 
0046 CommandLineParser* CommandLineParser::fpInstance(nullptr);
0047 G4String Command::fNoOption = "NoOption";
0048 
0049 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0050 
0051 inline bool MATCH(const char* a, const char* b)
0052 {
0053   return strcmp(a, b) == 0;
0054 }
0055 
0056 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0057 
0058 CommandLineParser::CommandLineParser()
0059 {
0060   fpInstance = this;
0061   AddCommand("--help", Command::WithoutOption, "Print this help");
0062   AddCommand("-h", Command::WithoutOption, "Print this help");
0063   AddCommand("&", Command::WithoutOption);
0064 }
0065 
0066 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0067 
0068 CommandLineParser* CommandLineParser::GetParser()
0069 {
0070   if (!fpInstance) new CommandLineParser;
0071   return fpInstance;
0072 }
0073 
0074 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0075 
0076 CommandLineParser::~CommandLineParser()
0077 {
0078   auto it = fCommandMap.begin();
0079   for (; it != fCommandMap.end(); it++) {
0080     delete it->second;
0081   }
0082 }
0083 
0084 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0085 
0086 void CommandLineParser::DeleteInstance()
0087 {
0088   if (fpInstance) {
0089     delete fpInstance;
0090     fpInstance = nullptr;
0091   }
0092 }
0093 
0094 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0095 
0096 Command::Command(Command::Type commandType, const G4String& description)
0097 {
0098   fType = commandType;
0099   fDescription = description;
0100   fActive = false;
0101 }
0102 
0103 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0104 
0105 CommandWithOption::CommandWithOption(Command::Type commandType, const G4String& description,
0106                                      const G4String& defaultOption, const G4String& optionName)
0107   : Command(commandType, description)
0108 {
0109   fDefaultOption = defaultOption;
0110   fOptionName = optionName;
0111   fOption = "";
0112 }
0113 
0114 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0115 
0116 G4int CommandLineParser::Parse(int& argc, char** argv)
0117 {
0118   static char null[1] = {""};
0119   G4int firstArgc = argc;
0120 
0121   for (G4int i = 1; i < firstArgc; i++) {
0122     auto command = FindCommand(argv[i]);
0123     if (command == nullptr) continue;
0124 
0125     if (fVerbose) G4cout << "Command : " << argv[i] << G4endl;
0126 
0127     fOptionsWereSetup = true;
0128     command->fActive = true;
0129 
0130     G4String marker(argv[i]);
0131 
0132     if (strcmp(argv[i], "-h") != 0 && strcmp(argv[i], "--help") != 0) {
0133       argv[i] = null;
0134     }
0135 
0136     if (command->fType == Command::WithOption) {
0137       if (fVerbose) G4cout << "WithOption" << G4endl;
0138 
0139       if (i + 1 > firstArgc || argv[i + 1] == nullptr || argv[i + 1][0] == '-') {
0140         G4cerr << "An command line option is missing for " << marker << G4endl;
0141         abort();
0142       }
0143 
0144       command->SetOption((const char*)strdup(argv[i + 1]));
0145       argv[i + 1] = null;
0146       i++;
0147     }
0148     else if (command->fType == Command::OptionNotCompulsory) {
0149       if (fVerbose) G4cout << "OptionNotCompulsory" << G4endl;
0150 
0151       if (i + 1 < firstArgc) {
0152         G4String buffer = (const char*)strdup(argv[i + 1]);
0153 
0154         if (!buffer.empty()) {
0155           if (buffer.at(0) != '-' && buffer.at(0) != '&' && buffer.at(0) != '>'
0156               && buffer.at(0) != '|')
0157           {
0158             if (fVerbose) {
0159               G4cout << "facultative option is : " << buffer << G4endl;
0160             }
0161 
0162             command->SetOption((const char*)strdup(argv[i + 1]));
0163             argv[i + 1] = null;
0164             i++;
0165             continue;
0166           }
0167         }
0168       }
0169 
0170       if (fVerbose) G4cout << "Option not set" << G4endl;
0171 
0172       command->SetOption("");
0173     }
0174   }
0175   CorrectRemainingOptions(argc, argv);
0176 
0177   Command* commandLine(nullptr);
0178   if ((commandLine = GetCommandIfActive("--help")) || (commandLine = GetCommandIfActive("-h"))) {
0179     G4cout << "Usage : " << argv[0] << " [OPTIONS]" << G4endl;
0180     PrintHelp();
0181     return 1;
0182   }
0183 
0184   return 0;
0185 }
0186 
0187 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0188 
0189 void CommandLineParser::PrintHelp()
0190 {
0191   std::map<G4String, Command*>::iterator it;
0192 
0193   G4int maxFieldLength = fMaxMarkerLength + fMaxOptionNameLength + 4;
0194 
0195   G4cout << "Options: " << G4endl;
0196 
0197   for (it = fCommandMap.begin(); it != fCommandMap.end(); it++) {
0198     Command* command = it->second;
0199     if (command) {
0200       G4cout << setw(maxFieldLength) << left;
0201 
0202       G4String toPrint = it->first;
0203 
0204       if (toPrint == "&") {
0205         continue;
0206       }
0207       else if (toPrint == "-h")
0208         continue;
0209       else if (toPrint == "--help") {
0210         toPrint += ", -h";
0211       }
0212 
0213       if (command->GetDefaultOption() != "") {
0214         toPrint += " \"" + command->GetDefaultOption() + "\"";
0215       }
0216       G4cout << toPrint;
0217       G4cout << command->GetDescription() << G4endl;
0218     }
0219   }
0220 }
0221 
0222 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0223 
0224 void CommandLineParser::CorrectRemainingOptions(int& argc, char** argv)
0225 {
0226   // remove handled arguments from argument array
0227   G4int j = 0;
0228   for (G4int i = 0; i < argc; i++) {
0229     if (strcmp(argv[i], "")) {
0230       argv[j] = argv[i];
0231       j++;
0232     }
0233   }
0234   argc = j;
0235 }
0236 
0237 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0238 
0239 void CommandLineParser::AddCommand(const G4String& marker, Command::Type type,
0240                                    const G4String& description, const G4String& defaultOption,
0241                                    const G4String& optionName)
0242 {
0243   Command* command = nullptr;
0244   switch (type) {
0245     case Command::WithoutOption:
0246       command = new Command(type, description);
0247       break;
0248 
0249     default:
0250       command = new CommandWithOption(type, description, defaultOption, optionName);
0251       if ((int)defaultOption.length() > fMaxOptionNameLength)
0252         fMaxOptionNameLength = defaultOption.length();
0253       break;
0254   }
0255 
0256   if ((G4int)marker.length() > fMaxMarkerLength) fMaxMarkerLength = marker.length();
0257   fCommandMap.insert(make_pair(marker, command));
0258 }
0259 
0260 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0261 
0262 Command* CommandLineParser::FindCommand(const G4String& marker)
0263 {
0264   auto it = fCommandMap.find(marker);
0265   if (it == fCommandMap.end()) {
0266     return nullptr;
0267   }
0268   return it->second;
0269 }
0270 
0271 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0272 
0273 Command* CommandLineParser::GetCommandIfActive(const G4String& marker)
0274 {
0275   Command* command = FindCommand(marker);
0276   if (command) {
0277     if (command->fActive) {
0278       return command;
0279     }
0280   }
0281   else {
0282     G4ExceptionDescription description;
0283     description << "You try to retrieve a command that was not registered : " << marker << G4endl;
0284     G4Exception("CommandLineParser::GetCommandIfActive", "COMMAND LINE NOT DEFINED", FatalException,
0285                 description, "");
0286   }
0287   return nullptr;
0288 }
0289 
0290 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0291 
0292 bool CommandLineParser::CheckIfNotHandledOptionsExists(int& argc, char** argv)
0293 {
0294   if (argc > 0) {
0295     G4bool kill = false;
0296     for (G4int i = 1; i < argc; i++) {
0297       if (strcmp(argv[i], "")) {
0298         kill = true;
0299         G4cerr << "Unknown argument : " << argv[i] << "\n";
0300       }
0301     }
0302     if (kill) {
0303       G4cerr << "The option " << argv[0] << " is not handled this programme." << G4endl;
0304       G4cout << "Usage : " << argv[0] << " [OPTIONS]" << G4endl;
0305       PrintHelp();
0306       return true;  // KILL APPLICATION
0307     }
0308   }
0309   return false;
0310 }