Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/examples/extended/medical/dna/chem1/src/CommandLineParser.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

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