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