File indexing completed on 2025-10-17 08:06:48
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 #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
0050
0051 inline bool MATCH(const char* a, const char* b)
0052 {
0053 return strcmp(a, b) == 0;
0054 }
0055
0056
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
0067
0068 CommandLineParser* CommandLineParser::GetParser()
0069 {
0070 if (!fpInstance) new CommandLineParser;
0071 return fpInstance;
0072 }
0073
0074
0075
0076 CommandLineParser::~CommandLineParser()
0077 {
0078 auto it = fCommandMap.begin();
0079 for (; it != fCommandMap.end(); it++) {
0080 delete it->second;
0081 }
0082 }
0083
0084
0085
0086 void CommandLineParser::DeleteInstance()
0087 {
0088 if (fpInstance) {
0089 delete fpInstance;
0090 fpInstance = nullptr;
0091 }
0092 }
0093
0094
0095
0096 Command::Command(Command::Type commandType, const G4String& description)
0097 {
0098 fType = commandType;
0099 fDescription = description;
0100 fActive = false;
0101 }
0102
0103
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
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
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
0223
0224 void CommandLineParser::CorrectRemainingOptions(int& argc, char** argv)
0225 {
0226
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
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
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
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
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;
0307 }
0308 }
0309 return false;
0310 }