Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/interfaces/core/src/G4VBasicShell.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 //
 27 //
 28 
 29 #include "G4VBasicShell.hh"
 30 
 31 #include "G4StateManager.hh"
 32 #include "G4UIcommand.hh"
 33 #include "G4UIcommandStatus.hh"
 34 #include "G4UIcommandTree.hh"
 35 #include "G4UImanager.hh"
 36 
 37 #include <sstream>
 38 #include <vector>
 39 
 40 G4VBasicShell::G4VBasicShell() : currentDirectory("/") {}
 41 
 42 G4VBasicShell::~G4VBasicShell() = default;
 43 
 44 G4String G4VBasicShell::ModifyToFullPathCommand(const char* aCommandLine) const
 45 {
 46   const G4String& rawCommandLine = aCommandLine;
 47   if (rawCommandLine.empty() || rawCommandLine[0] == '\0') return rawCommandLine;
 48   const G4String& commandLine = G4StrUtil::strip_copy(rawCommandLine);
 49   G4String commandString;
 50   G4String parameterString;
 51   size_t i = commandLine.find(' ');
 52   if (i != std::string::npos) {
 53     commandString = commandLine.substr(0, i);
 54     parameterString = " ";
 55     parameterString += commandLine.substr(i + 1, commandLine.length() - (i + 1));
 56   }
 57   else {
 58     commandString = commandLine;
 59   }
 60 
 61   G4String fullPathCommandLine = ModifyPath(commandString) + parameterString;
 62   return fullPathCommandLine;
 63 }
 64 
 65 G4String G4VBasicShell::GetCurrentWorkingDirectory() const { return currentDirectory; }
 66 
 67 G4bool G4VBasicShell::ChangeDirectory(const char* newDir)
 68 {
 69   const G4String& newPrefix = G4StrUtil::strip_copy(newDir);
 70 
 71   G4String newDirectory = ModifyPath(newPrefix);
 72   if (newDirectory.back() != '/') {
 73     newDirectory += "/";
 74   }
 75   if (FindDirectory(newDirectory.c_str()) == nullptr) {
 76     return false;
 77   }
 78   currentDirectory = std::move(newDirectory);
 79   return true;
 80 }
 81 
 82 G4UIcommandTree* G4VBasicShell::FindDirectory(const char* dirName) const
 83 {
 84   G4String theDir = G4StrUtil::strip_copy(dirName);
 85 
 86   G4String targetDir = ModifyPath(theDir);
 87   if (targetDir.back() != '/') {
 88     targetDir += "/";
 89   }
 90   G4UIcommandTree* comTree = G4UImanager::GetUIpointer()->GetTree();
 91   if (targetDir == "/") {
 92     return comTree;
 93   }
 94   size_t idx = 1;
 95   while (idx < targetDir.length() - 1) {
 96     size_t i = targetDir.find('/', idx);
 97     comTree = comTree->GetTree(targetDir.substr(0, i + 1).c_str());
 98     if (comTree == nullptr) {
 99       return nullptr;
100     }
101     idx = i + 1;
102   }
103   return comTree;
104 }
105 
106 G4UIcommand* G4VBasicShell::FindCommand(const char* commandName) const
107 {
108   const G4String& commandLine = G4StrUtil::strip_copy(commandName);
109 
110   G4String commandString;
111   std::size_t i = commandLine.find(' ');
112   if (i != std::string::npos) {
113     commandString = commandLine.substr(0, i);
114   }
115   else {
116     commandString = commandLine;
117   }
118 
119   const G4String& targetCom = ModifyPath(commandString);
120   return G4UImanager::GetUIpointer()->GetTree()->FindPath(targetCom);
121 }
122 
123 G4String G4VBasicShell::ModifyPath(const G4String& tempPath) const
124 {
125   if (tempPath.length() == 0) return tempPath;
126 
127   G4String newPath = "";
128 
129   // temporal full path
130   if (tempPath[0] == '/')
131     newPath = tempPath;
132   else
133     newPath = currentDirectory + tempPath;
134 
135   // body of path...
136   while (true) {
137     size_t idx = newPath.find("/./");
138     if (idx == G4String::npos) break;
139     newPath.erase(idx, 2);
140   }
141 
142   while (true) {
143     size_t idx = newPath.find("/../");
144     if (idx == G4String::npos) break;
145     if (idx == 0) {
146       newPath.erase(1, 3);
147       continue;
148     }
149     size_t idx2 = newPath.find_last_of('/', idx - 1);
150     if (idx2 != G4String::npos) newPath.erase(idx2, idx - idx2 + 3);
151   }
152 
153   // end of path...
154   if (newPath.size() >= 3) {
155     if (newPath.substr(newPath.size() - 3, 3) == "/..") {
156       if (newPath.size() == 3) {
157         newPath = "/";
158       }
159       else {
160         size_t idx = newPath.find_last_of('/', newPath.size() - 4);
161         if (idx != G4String::npos) newPath.erase(idx + 1);
162       }
163     }
164   }
165 
166   if (newPath.size() >= 2) {
167     if (newPath.substr(newPath.size() - 2, 2) == "/.") newPath.erase(newPath.size() - 1, 1);
168   }
169 
170   // truncate "/////" to "/"
171   while (true) {
172     size_t idx = newPath.find("//");
173     if (idx == G4String::npos) break;
174     newPath.erase(idx, 1);
175   }
176 
177   return newPath;
178 }
179 ////////////////////////////////////////////
180 // Method used for command completion //////
181 ////////////////////////////////////////////
182 G4String G4VBasicShell::Complete(const G4String& commandName)
183 {
184   const G4String& rawCommandLine = commandName;
185   const G4String& commandLine = G4StrUtil::strip_copy(rawCommandLine);
186 
187   std::size_t i = commandLine.find(' ');
188   if (i != std::string::npos)
189     return rawCommandLine;  // Already entering parameters,
190                             // assume command path is correct.
191   G4String commandString = commandLine;
192   G4String targetCom = ModifyPath(commandString);
193   G4UIcommandTree* tree = G4UImanager::GetUIpointer()->GetTree();
194   G4String value = FindMatchingPath(tree, targetCom);
195   if (value.empty()) return rawCommandLine;
196   return value;
197 }
198 
199 G4String G4VBasicShell::FindMatchingPath(G4UIcommandTree* aTree, const G4String& aCommandPath)
200 {
201   return aTree->CompleteCommandPath(aCommandPath);
202 }
203 
204 ////////////////////////////////////////////
205 // Method involving an interactive G4cout //
206 ////////////////////////////////////////////
207 /***************************************************************************/
208 void G4VBasicShell::ExecuteCommand(const G4String& aCommand)
209 /***************************************************************************/
210 // Should be put in G4VBasicShell.
211 /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
212 {
213   if (aCommand.length() < 2) return;
214   G4UImanager* UI = G4UImanager::GetUIpointer();
215   if (UI == nullptr) return;
216   G4int commandStatus = UI->ApplyCommand(aCommand);
217   switch (commandStatus) {
218     case fCommandSucceeded:
219       break;
220     case fCommandNotFound:
221       G4cerr << "command not found: "
222              << "\"" << aCommand << "\"" << G4endl;
223       break;
224     case fIllegalApplicationState:
225       G4cerr << "illegal application state -- command refused:"
226              << "\"" << aCommand << "\"" << G4endl;
227       break;
228     case fParameterOutOfRange:
229     case fParameterUnreadable:
230     case fParameterOutOfCandidates:
231     default:
232       G4cerr << "command refused (" << commandStatus << "):"
233              << "\"" << aCommand << "\"" << G4endl;
234   }
235 }
236 /***************************************************************************/
237 void G4VBasicShell::ApplyShellCommand(
238   const G4String& a_string, G4bool& exitSession, G4bool& exitPause)
239 /***************************************************************************/
240 /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
241 {
242   G4UImanager* UI = G4UImanager::GetUIpointer();
243   if (UI == nullptr) return;
244 
245   G4String command = G4StrUtil::lstrip_copy(a_string);
246 
247   if (command[0] == '#') {
248     G4cout << command << G4endl;
249   }
250   else if (command == "ls" || command.substr(0, 3) == "ls ") {
251     ListDirectory(command);
252   }
253   else if (command == "pwd") {
254     G4cout << "Current Working Directory : " << GetCurrentWorkingDirectory() << G4endl;
255   }
256   else if (command == "cd" || command.substr(0, 3) == "cd ") {
257     ChangeDirectoryCommand(command);
258   }
259   else if (command == "help" || command.substr(0, 5) == "help ") {
260     TerminalHelp(command);
261   }
262   else if (command[0] == '?') {
263     ShowCurrent(command);
264   }
265   else if (command == "hist" || command == "history") {
266     G4int nh = UI->GetNumberOfHistory();
267     for (G4int i = 0; i < nh; i++) {
268       G4cout << i << ": " << UI->GetPreviousCommand(i) << G4endl;
269     }
270   }
271   else if (command[0] == '!') {
272     G4String ss = command.substr(1, command.length() - 1);
273     G4int vl;
274     const char* tt = ss;
275     std::istringstream is(tt);
276     is >> vl;
277     G4int nh = UI->GetNumberOfHistory();
278     if (vl >= 0 && vl < nh) {
279       G4String prev = UI->GetPreviousCommand(vl);
280       G4cout << prev << G4endl;
281       ExecuteCommand(ModifyToFullPathCommand(prev));
282     }
283     else {
284       G4cerr << "history " << vl << " is not found." << G4endl;
285     }
286   }
287   else if (command == "exit") {
288     if (!exitPause) {  // In a secondary loop.
289       G4cout << "You are now processing RUN." << G4endl;
290       G4cout << "Please abort it using \"/run/abort\" command first" << G4endl;
291       G4cout << " and use \"continue\" command until the application" << G4endl;
292       G4cout << " becomes to Idle." << G4endl;
293     }
294     else {
295       exitSession = true;
296     }
297   }
298   else if (command == "cont" || command == "continue") {
299     exitPause = true;
300   }
301   else {
302     ExecuteCommand(ModifyToFullPathCommand(a_string));
303   }
304 }
305 
306 void G4VBasicShell::ShowCurrent(const G4String& newCommand) const
307 {
308   G4UImanager* UI = G4UImanager::GetUIpointer();
309   if (UI == nullptr) return;
310   G4String comString = newCommand.substr(1, newCommand.length() - 1);
311   G4String theCommand = ModifyToFullPathCommand(comString);
312   G4String curV = UI->GetCurrentValues(theCommand);
313   if (! curV.empty()) {
314     G4cout << "Current value(s) of the parameter(s) : " << curV << G4endl;
315   }
316 }
317 
318 void G4VBasicShell::ChangeDirectoryCommand(const G4String& newCommand)
319 {
320   G4String prefix;
321   if (newCommand.length() <= 3) {
322     prefix = "/";
323   }
324   else {
325     const G4String& aNewPrefix = newCommand.substr(3, newCommand.length() - 3);
326     prefix = G4StrUtil::strip_copy(aNewPrefix);
327   }
328   if (! ChangeDirectory(prefix)) {
329     G4cout << "directory <" << prefix << "> not found." << G4endl;
330   }
331 }
332 
333 void G4VBasicShell::ListDirectory(const G4String& newCommand) const
334 {
335   G4String targetDir;
336   if (newCommand.length() <= 3) {
337     targetDir = GetCurrentWorkingDirectory();
338   }
339   else {
340     const G4String& newPrefix = newCommand.substr(3, newCommand.length() - 3);
341     targetDir = G4StrUtil::strip_copy(newPrefix);
342   }
343   G4UIcommandTree* commandTree = FindDirectory(targetDir);
344   if (commandTree == nullptr) {
345     G4cout << "Directory <" << targetDir << "> is not found." << G4endl;
346   }
347   else {
348     commandTree->ListCurrent();
349   }
350 }
351 void G4VBasicShell::TerminalHelp(const G4String& newCommand)
352 {
353   G4UImanager* UI = G4UImanager::GetUIpointer();
354   if (UI == nullptr) return;
355   G4UIcommandTree* treeTop = UI->GetTree();
356   size_t i = newCommand.find(' ');
357   if (i != std::string::npos) {
358     G4String newValue = newCommand.substr(i + 1, newCommand.length() - (i + 1));
359     G4StrUtil::strip(newValue);
360     G4String targetCom = ModifyToFullPathCommand(newValue);
361     G4UIcommand* theCommand = treeTop->FindPath(targetCom);
362     if (theCommand != nullptr) {
363       theCommand->List();
364       return;
365     }
366 
367     G4cout << "Command <" << newValue << " is not found." << G4endl;
368     return;
369   }
370 
371   G4UIcommandTree* floor[10];
372   floor[0] = treeTop;
373   size_t iFloor = 0;
374   size_t prefixIndex = 1;
375   G4String prefix = GetCurrentWorkingDirectory();
376   while (prefixIndex < prefix.length() - 1) {
377     size_t ii = prefix.find('/', prefixIndex);
378     floor[iFloor + 1] = floor[iFloor]->GetTree(G4String(prefix.substr(0, ii + 1)));
379     prefixIndex = ii + 1;
380     iFloor++;
381   }
382   floor[iFloor]->ListCurrentWithNum();
383   // 1998 Oct 2 non-number input
384   while (true) {
385     // G4cout << G4endl << "Type the number ( 0:end, -n:n level back ) : "<<std::flush;
386     G4cout << G4endl << "Type the number ( 0:end, -n:n level back ) : " << G4endl;
387     G4int j;
388     if (! GetHelpChoice(j)) {
389       G4cout << G4endl << "Not a number, once more" << G4endl;
390       continue;
391     }
392     if (j < 0) {
393       if (iFloor < (size_t)-j)
394         iFloor = 0;
395       else
396         iFloor += j;
397       // iFloor += j;
398       // if( iFloor < 0 ) iFloor = 0;
399       floor[iFloor]->ListCurrentWithNum();
400       continue;
401     }
402     if (j == 0) {
403       break;
404     }
405     if (j > 0) {
406       G4int n_tree = floor[iFloor]->GetTreeEntry();
407       if (j > n_tree) {
408         if (j <= n_tree + floor[iFloor]->GetCommandEntry()) {
409           floor[iFloor]->GetCommand(j - n_tree)->List();
410         }
411       }
412       else {
413         floor[iFloor + 1] = floor[iFloor]->GetTree(j);
414         iFloor++;
415         floor[iFloor]->ListCurrentWithNum();
416       }
417     }
418   }
419   G4cout << "Exit from HELP." << G4endl << G4endl;
420   // G4cout << G4endl;
421   ExitHelp();
422 }
423