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