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