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 
49 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
50 
51 inline bool MATCH(const char *a, const char *b)
52 {
53  return strcmp(a, b) == 0;
54 }
55 
56 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
57 
58 CommandLineParser::CommandLineParser()
59 {
60  // G4cout << "############ NEW PARSE ##########" << G4endl;
61  fpInstance = this;
62  fOptionsWereSetup = false;
63  fMaxMarkerLength = 0;
64  fMaxOptionNameLength = 0;
65  AddCommand("--help", Command::WithoutOption, "Print this help");
66  AddCommand("-h", Command::WithoutOption, "Print this help");
67  AddCommand("&", Command::WithoutOption);
68 
69  fVerbose = 0;
70 }
71 
72 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
73 
74 CommandLineParser* CommandLineParser::GetParser()
75 {
76  if (!fpInstance) new CommandLineParser;
77  return fpInstance;
78 }
79 
80 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
81 
82 CommandLineParser::~CommandLineParser()
83 {
84  std::map<G4String, Command*>::iterator it = fCommandMap.begin();
85  for (; it != fCommandMap.end(); it++)
86  {
87  if (it->second) delete it->second;
88  }
89 }
90 
91 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
92 
93 void CommandLineParser::DeleteInstance()
94 {
95  if (fpInstance)
96  {
97  delete fpInstance;
98  fpInstance = 0;
99  }
100 }
101 
102 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
103 
104 Command::Command(Command::Type commandType,
105  const G4String& description)
106 {
107  fType = commandType;
108  fDescription = description;
109  fActive = false;
110 }
111 
112 CommandWithOption::CommandWithOption(Command::Type commandType,
113  const G4String& description,
114  const G4String& defaultOption,
115  const G4String& optionName) :
116 Command(commandType, description)
117 {
118  fDefaultOption = defaultOption;
119  fOptionName = optionName;
120  fOption = "";
121 }
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->GetType() != Command::WithoutOption)
243  {
244  if (command->GetDefaultOption() != "")
245  {
246  toPrint += " \"" + command->GetDefaultOption() + "\"";
247  }
248  }
249  G4cout << toPrint;
250 
251  G4cout << command->GetDescription() << G4endl;
252  }
253  }
254 }
255 
256 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
257 
258 void CommandLineParser::CorrectRemainingOptions(int& argc, char **argv)
259 {
260  // remove handled arguments from argument array
261  int j = 0;
262  for (int i = 0; i < argc; i++)
263  {
264  if (strcmp(argv[i], ""))
265  {
266  argv[j] = argv[i];
267  j++;
268  }
269  }
270  argc = j;
271 }
272 
273 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
274 
275 void CommandLineParser::AddCommand(const G4String& marker,
276  Command::Type type,
277  const G4String& description,
278  const G4String& defaultOption,
279  const G4String& optionName)
280 {
281  // G4cout << "Add command : "<< marker << G4endl;
282 
283  Command* command = 0;
284  switch(type)
285  {
287  command = new Command(type, description);
288  break;
289 
290  default:
291  command = new CommandWithOption(type,
292  description,
293  defaultOption,
294  optionName);
295  if ((int) defaultOption.length() > fMaxOptionNameLength)
296  fMaxOptionNameLength = defaultOption.length();
297  break;
298  }
299 
300  if ((int) marker.length() > fMaxMarkerLength) fMaxMarkerLength =
301  marker.length();
302  fCommandMap.insert(make_pair(marker, command));
303 }
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 }