ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CommandLineParser.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file CommandLineParser.cc
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 // J. Comput. Phys. 274 (2014) 841-882
31 // The Geant4-DNA web site is available at http://geant4-dna.org
32 //
33 // Author: Mathieu Karamitros
34 //
35 //
38 
39 #include <iomanip>
40 #include "CommandLineParser.hh"
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  {
86  if (it->second) delete it->second;
87  }
88 }
89 
90 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
91 
92 void CommandLineParser::DeleteInstance()
93 {
94  if (fpInstance)
95  {
96  delete fpInstance;
97  fpInstance = 0;
98  }
99 }
100 
101 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
102 
103 Command::Command(Command::Type commandType,
104  const G4String& description)
105 {
106  fType = commandType;
107  fDescription = description;
108  fActive = false;
109 }
110 
111 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
112 
113 CommandWithOption::CommandWithOption(Command::Type commandType,
114  const G4String& description,
115  const G4String& defaultOption,
116  const G4String& optionName) :
117 Command(commandType, description)
118 {
119  fDefaultOption = defaultOption;
120  fOptionName = optionName;
121  fOption = "";
122 }
123 
124 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
125 
126 int CommandLineParser::Parse(int& argc, char **argv)
127 {
128  // G4cout << "Parse " << G4endl;
129  static char null[1] = { "" };
130  int firstArgc = argc;
131 
132  for (int i = 1; i < firstArgc; i++)
133  {
134  Command* command = FindCommand(argv[i]);
135  if (command == 0) continue;
136 
137  if (fVerbose) G4cout << "Command : " << argv[i] << G4endl;
138 
139  fOptionsWereSetup = true;
140  command->fActive = true;
141 
142  G4String marker(argv[i]);
143 
144  if (strcmp(argv[i], "-h") != 0 && strcmp(argv[i], "--help") != 0)
145  {
146  argv[i] = null;
147  }
148 
149  if (command->fType == Command::WithOption)
150  {
151  if (fVerbose) G4cout << "WithOption" << G4endl;
152 
153  if(i+1 > firstArgc || argv[i+1]==0 || argv[i+1][0]=='-')
154  {
155  G4cerr << "An command line option is missing for "
156  << marker << G4endl;
157  abort();
158  }
159 
160  command->SetOption( (const char*) strdup(argv[i+1]) );
161  argv[i+1] = null;
162  i++;
163  }
164  else if(command->fType == Command::OptionNotCompulsory)
165  {
166  if(fVerbose)
167  G4cout <<"OptionNotCompulsory"<<G4endl;
168 
169  if(i+1 < firstArgc)
170  {
171  G4String buffer = (const char*) strdup(argv[i+1]);
172 
173  if(buffer.empty() == false)
174  {
175  if(buffer.at(0) != '-'
176  && buffer.at(0) != '&'
177  && buffer.at(0) != '>'
178  && buffer.at(0) != '|')
179  {
180  if(fVerbose)
181  {
182  G4cout << "facultative option is : " << buffer << G4endl;
183  }
184 
185  command->SetOption( (const char*) strdup(argv[i+1]) );
186  argv[i+1] = null;
187  i++;
188  continue;
189  }
190  }
191  }
192 
193  if(fVerbose)
194  G4cout << "Option not set" << G4endl;
195 
196  command->SetOption("");
197  }
198  }
199  CorrectRemainingOptions(argc, argv);
200 
201  Command* commandLine(0);
202  if ((commandLine = GetCommandIfActive("--help")) || (commandLine =
203  GetCommandIfActive("-h")))
204  {
205  G4cout << "Usage : " << argv[0] << " [OPTIONS]" << G4endl;
206  PrintHelp();
207  return 1;
208  }
209 
210  return 0;
211 }
212 
213 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
214 
216 {
217  std::map<G4String, Command*>::iterator it;
218 
219  int maxFieldLength = fMaxMarkerLength + fMaxOptionNameLength + 4;
220 
221  G4cout << "Options: " << G4endl;
222 
223  for (it = fCommandMap.begin(); it != fCommandMap.end(); it++)
224  {
225  Command* command = it->second;
226  if (command)
227  {
228  G4cout << setw(maxFieldLength) << left;
229 
230  G4String toPrint = it->first;
231 
232  if (toPrint == "&")
233  {
234  continue;
235  }
236  else if (toPrint == "-h") continue;
237  else if (toPrint == "--help")
238  {
239  toPrint += ", -h";
240  }
241 
242  if (command->GetDefaultOption() != "")
243  {
244  toPrint += " \"" + command->GetDefaultOption() + "\"";
245  }
246 
247  G4cout << toPrint;
248 
249  G4cout << command->GetDescription() << G4endl;
250  }
251  }
252 }
253 
254 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
255 
256 void CommandLineParser::CorrectRemainingOptions(int& argc, char **argv)
257 {
258  // remove handled arguments from argument array
259  int j = 0;
260  for (int i = 0; i < argc; i++)
261  {
262  if (strcmp(argv[i], ""))
263  {
264  argv[j] = argv[i];
265  j++;
266  }
267  }
268  argc = j;
269 }
270 
271 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
272 
273 void CommandLineParser::AddCommand(const G4String& marker,
274  Command::Type type,
275  const G4String& description,
276  const G4String& defaultOption,
277  const G4String& optionName)
278 {
279  // G4cout << "Add command : "<< marker << G4endl;
280 
281  Command* command = 0;
282  switch(type)
283  {
285  command = new Command(type, description);
286  break;
287 
288  default:
289  command = new CommandWithOption(type,
290  description,
291  defaultOption,
292  optionName);
293  if ((int) defaultOption.length() > fMaxOptionNameLength)
294  fMaxOptionNameLength = defaultOption.length();
295  break;
296  }
297 
298  if ((int) marker.length() > fMaxMarkerLength) fMaxMarkerLength =
299  marker.length();
300  fCommandMap.insert(make_pair(marker, command));
301 }
302 
303 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
304 
305 /*
306 // Add one command but multiple markers
307 void Parser::AddCommand(vector<G4String> markers,
308  CommandType type,
309  const G4String& description,
310  const G4String& optionName)
311 {
312  // G4cout << "Add command : "<< marker << G4endl;
313  Command* command = new Command(type, description, optionName);
314 
315  for (size_t i = 0; i < markers.size; i++)
316  {
317  G4String marker = markers[i];
318  if ((int) marker.length() > fMaxMarkerLength)
319  {
320  fMaxMarkerLength = marker.length();
321  }
322  if ((int) optionName.length() > fMaxOptionNameLength)
323  {
324  fMaxOptionNameLength = optionName.length();
325  }
326  fCommandMap.insert(make_pair(marker, command));
327  }
328 }
329 */
330 
331 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
332 
334 {
335  std::map<G4String, Command*>::iterator it = fCommandMap.find(marker);
336  if (it == fCommandMap.end())
337  {
338  // G4cerr << "command not found" << G4endl;
339  return 0;
340  }
341  return it->second;
342 }
343 
344 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
345 
347 {
348  Command* command = FindCommand(marker);
349  if (command)
350  {
351  // G4cout << "Command found : "<< marker << G4endl;
352 
353  if (command->fActive)
354  {
355  // G4cout << "Command Active" << G4endl;
356  return command;
357  }
358  // else
359  // G4cout <<"Command not active" << G4endl;
360  }
361  else
362  {
363  G4ExceptionDescription description;
364  description << "You try to retrieve a command that was not registered : "
365  << marker << G4endl;
366  G4Exception("CommandLineParser::GetCommandIfActive",
367  "COMMAND LINE NOT DEFINED", FatalException, description, "");
368  // If you are using this class outside of Geant4, use exit(-1) instead
369  //exit(-1);
370  }
371  return 0;
372 }
373 
374 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
375 
376 bool CommandLineParser::CheckIfNotHandledOptionsExists(int& argc, char** argv)
377 {
378  if (argc > 0)
379  {
380  G4bool kill = false;
381  for (G4int i = 1; i < argc; i++)
382  {
383  if (strcmp(argv[i], ""))
384  {
385  kill = true;
386  G4cerr << "Unknown argument : " << argv[i] << "\n";
387  }
388  }
389  if (kill)
390  {
391  G4cerr << "The option " << argv[0]
392  << " is not handled this programme." << G4endl;
393  G4cout << "Usage : " << argv[0] << " [OPTIONS]" << G4endl;
394  PrintHelp();
395  return true; // KILL APPLICATION
396  }
397  }
398  return false;
399 }