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->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 /*
304 // Add one command but multiple markers
305 void Parser::AddCommand(vector<G4String> markers,
306  CommandType type,
307  const G4String& description,
308  const G4String& optionName)
309 {
310  // G4cout << "Add command : "<< marker << G4endl;
311  Command* command = new Command(type, description, optionName);
312 
313  for (size_t i = 0; i < markers.size; i++)
314  {
315  G4String marker = markers[i];
316  if ((int) marker.length() > fMaxMarkerLength)
317  {
318  fMaxMarkerLength = marker.length();
319  }
320  if ((int) optionName.length() > fMaxOptionNameLength)
321  {
322  fMaxOptionNameLength = optionName.length();
323  }
324  fCommandMap.insert(make_pair(marker, command));
325  }
326 }
327 */
328 
329 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
330 
332 {
333  std::map<G4String, Command*>::iterator it = fCommandMap.find(marker);
334  if (it == fCommandMap.end())
335  {
336  // G4cerr << "command not found" << G4endl;
337  return 0;
338  }
339  return it->second;
340 }
341 
342 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
343 
345 {
346  Command* command = FindCommand(marker);
347  if (command)
348  {
349  // G4cout << "Command found : "<< marker << G4endl;
350 
351  if (command->fActive)
352  {
353  // G4cout << "Command Active" << G4endl;
354  return command;
355  }
356  // else
357  // G4cout <<"Command not active" << G4endl;
358  }
359  else
360  {
361  G4ExceptionDescription description;
362  description << "You try to retrieve a command that was not registered : "
363  << marker << G4endl;
364  G4Exception("CommandLineParser::GetCommandIfActive",
365  "COMMAND LINE NOT DEFINED", FatalException, description, "");
366  // If you are using this class outside of Geant4, use exit(-1) instead
367  //exit(-1);
368  }
369  return 0;
370 }
371 
372 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
373 
374 bool CommandLineParser::CheckIfNotHandledOptionsExists(int& argc, char** argv)
375 {
376  if (argc > 0)
377  {
378  G4bool kill = false;
379  for (G4int i = 1; i < argc; i++)
380  {
381  if (strcmp(argv[i], ""))
382  {
383  kill = true;
384  G4cerr << "Unknown argument : " << argv[i] << "\n";
385  }
386  }
387  if (kill)
388  {
389  G4cerr << "The option " << argv[0]
390  << " is not handled this programme." << G4endl;
391  G4cout << "Usage : " << argv[0] << " [OPTIONS]" << G4endl;
392  PrintHelp();
393  return true; // KILL APPLICATION
394  }
395  }
396  return false;
397 }