source: trunk/source/interfaces/common/src/G4VBasicShell.cc @ 1027

Last change on this file since 1027 was 1027, checked in by garnier, 15 years ago

en test. Ok

File size: 15.7 KB
Line 
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// $Id: G4VBasicShell.cc,v 1.12 2006/06/29 19:10:20 gunter Exp $
28// GEANT4 tag $Name: HEAD $
29//
30
31#include "G4VBasicShell.hh"
32#include "G4StateManager.hh"
33#include "G4UIcommandTree.hh"
34#include "G4UIcommand.hh"
35#include "G4UIcommandStatus.hh"
36#include "G4UImanager.hh"
37#include <vector>
38#include <sstream>
39
40G4VBasicShell::G4VBasicShell()
41:currentDirectory("/")
42{
43}
44
45G4VBasicShell::~G4VBasicShell() 
46{;}
47
48G4String G4VBasicShell::ModifyToFullPathCommand(const char* aCommandLine)
49{
50  G4String rawCommandLine = (G4String)aCommandLine;
51  if(rawCommandLine.isNull()||rawCommandLine(0)=='\0') return rawCommandLine;
52  G4String commandLine = (G4String)rawCommandLine.strip(G4String::both);
53  G4String commandString;
54  G4String parameterString;
55  size_t i = commandLine.index(" ");
56  if( i != std::string::npos )
57  {
58    commandString = (G4String)commandLine(0,i);
59    parameterString = " ";
60    parameterString += (G4String)commandLine(i+1,commandLine.length()-(i+1));
61  }
62  else
63  { commandString = commandLine; }
64
65  G4String fullPathCommandLine
66    = ModifyPath( commandString )+parameterString;
67  return fullPathCommandLine;
68}
69
70G4String G4VBasicShell::GetCurrentWorkingDirectory()
71{
72  return currentDirectory;
73}
74
75G4bool G4VBasicShell::ChangeDirectory(const char* newDir)
76{
77  G4String aNewPrefix = (G4String)newDir;
78  G4String newPrefix = (G4String)aNewPrefix.strip(G4String::both);
79  G4String newDirectory = ModifyPath( newPrefix );
80  if( newDirectory( newDirectory.length() - 1 ) != '/' )
81  { newDirectory += "/"; }
82  if( FindDirectory( (const char*)newDirectory ) == NULL )
83  { return false; }
84  currentDirectory = newDirectory;
85  return true;
86}
87
88G4UIcommandTree* G4VBasicShell::FindDirectory(const char* dirName)
89{
90  G4String aDirName = (G4String)dirName;
91  G4String theDir = (G4String)aDirName.strip(G4String::both);
92  G4String targetDir = ModifyPath( theDir );
93  if( targetDir( targetDir.length()-1 ) != '/' )
94  { targetDir += "/"; }
95  G4UIcommandTree* comTree = G4UImanager::GetUIpointer()->GetTree();
96  if( targetDir == "/" )
97  { return comTree; }
98  size_t idx = 1;
99  while( idx < targetDir.length()-1 )
100  {
101    size_t i = targetDir.index("/",idx);
102    comTree = comTree->GetTree((G4String)targetDir(0,i+1));
103    if( comTree == NULL ) 
104    { return NULL; }
105    idx = i+1;
106  }
107  return comTree;
108}
109
110G4UIcommand* G4VBasicShell::FindCommand(const char* commandName)
111{
112  G4String rawCommandLine = (G4String)commandName;
113  G4String commandLine = (G4String)rawCommandLine.strip(G4String::both);
114  G4String commandString;
115  size_t i = commandLine.index(" ");
116  if( i != std::string::npos )
117  { commandString = (G4String)commandLine(0,i); }
118  else
119  { commandString = commandLine; }
120
121  G4String targetCom = ModifyPath(commandString);
122  return G4UImanager::GetUIpointer()->GetTree()->FindPath(targetCom);
123}
124
125G4String G4VBasicShell::ModifyPath(G4String tempPath)
126{
127  G4String newPath = currentDirectory;
128
129  if( tempPath.length()>0 )
130  {
131
132  if( tempPath(0) == '/' )   // full path is given
133  { newPath = tempPath; }
134  else if( tempPath(0) != '.' ) // add current prefix
135  { newPath += tempPath; }
136  else if( tempPath(0,2) == "./" ) // add current prefix
137  { newPath += (G4String)tempPath(2,tempPath.length()-2); }
138  else                       // swim up with ".."
139  {
140    while( 1 )
141    {
142      if( tempPath(0,2) == ".." )
143      {
144        if( newPath != "/" )
145        { 
146          G4String tmpString = (G4String)newPath(0,newPath.length()-1);
147          newPath = (G4String)newPath(0,tmpString.last('/')+1); 
148        }
149        if( tempPath == ".." || tempPath == "../" )
150        { break; }
151        tempPath = (G4String)tempPath(3,tempPath.length()-3);
152      }
153      else
154      {
155        newPath += tempPath;
156        break;
157      }
158    }
159  }
160
161  }
162
163  return newPath;
164}
165////////////////////////////////////////////
166// Method used for command completion //////
167////////////////////////////////////////////
168G4String G4VBasicShell::Complete(G4String commandName)
169{
170  G4String rawCommandLine = commandName;
171  G4String commandLine = rawCommandLine.strip(G4String::both);
172  size_t i = commandLine.index(" ");
173  if( i != std::string::npos ) return rawCommandLine; // Already entering parameters,
174                                            // assume command path is correct.
175  G4String commandString = commandLine; 
176  G4String targetCom = ModifyPath(commandString);
177  G4UIcommandTree* tree = G4UImanager::GetUIpointer()->GetTree();
178  G4String value = FindMatchingPath(tree,targetCom);
179  if(value=="") return rawCommandLine;
180  return value;
181}
182
183
184
185
186G4String G4VBasicShell::FindMatchingPath(
187 G4UIcommandTree* aTree
188,G4String aCommandPath
189)
190// From intercoms/src/G4UIcommandTree::FindPath.
191{
192  return aTree->CompleteCommandPath(aCommandPath);
193
194#ifdef G4DEBUG
195  printf("G4VBasicShell::FindMatchingPath %s\n",aCommandPath.c_str());
196#endif
197  G4String empty = "";
198  if(aTree==NULL) return empty;
199  G4String pathName = aTree->GetPathName();
200  if( aCommandPath.index( pathName ) == std::string::npos ) return empty;
201  G4String remainingPath = aCommandPath;
202  remainingPath.remove(0,pathName.length());
203  size_t i = remainingPath.first('/');
204#ifdef G4DEBUG
205  printf("G4VBasicShell::FindMatchingPath remainingPath:%s\n",remainingPath.c_str());
206#endif
207  if( i == std::string::npos ) {
208#ifdef G4DEBUG
209  printf("G4VBasicShell::FindMatchingPath npos \n");
210#endif
211    // Look for number of matching commands :
212    std::vector<G4UIcommand*> commands;
213    G4int n_commandEntry = aTree->GetCommandEntry();
214    for( G4int i_thCommand = 1; i_thCommand <= n_commandEntry; i_thCommand++ ) {
215      G4UIcommand* cmd = aTree->GetCommand(i_thCommand);
216      G4String ss = cmd->GetCommandName();
217      ss.resize(remainingPath.length());
218      if( remainingPath == ss ) commands.push_back(cmd);
219#ifdef G4DEBUG
220      printf("look for command check %s %s \n",ss.c_str(),remainingPath.c_str());
221#endif
222    }
223    n_commandEntry = commands.size();
224#ifdef G4DEBUG
225      printf("%d found\n",n_commandEntry);
226#endif
227    if(n_commandEntry==1) {
228      return (pathName + commands[0]->GetCommandName());
229    } else if (n_commandEntry>=2) {
230      G4cout << "Matching commands :" << G4endl; 
231      for( G4int i_thCommand = 0; i_thCommand < n_commandEntry; i_thCommand++ ) {
232        G4UIcommand* cmd = commands[i_thCommand];
233        G4cout << cmd->GetCommandName() << G4endl; 
234#ifdef G4DEBUG
235        printf("%s found\n",cmd->GetCommandName().c_str());
236#endif
237      }
238      return empty;
239    }
240    // Look for sub tree :
241    std::vector<G4UIcommandTree*> trees;
242    G4String nextPath = pathName;
243    nextPath.append(remainingPath);
244    G4int n_treeEntry = aTree->GetTreeEntry();
245    for( G4int i_thTree = 1; i_thTree <= n_treeEntry; i_thTree++ ) {
246      G4UIcommandTree* tree = aTree->GetTree(i_thTree);
247      G4String ss = tree->GetPathName();
248      ss.resize(nextPath.length());
249      if( nextPath == ss ) trees.push_back(tree);
250    }
251    n_treeEntry = trees.size();
252    if(n_treeEntry==1) {
253      return trees[0]->GetPathName();
254    } else if (n_treeEntry>=2) {
255      G4cout << "Matching directories :" << G4endl; 
256      for( G4int i_thTree = 0; i_thTree < n_treeEntry; i_thTree++ ) {
257        G4UIcommandTree* tree = trees[i_thTree];
258        G4cout << tree->GetPathName() << G4endl; 
259      }
260      return empty;
261    } else {
262      return empty; // No match.
263    }
264  } else {
265    // Find path
266    G4String nextPath = pathName;
267    nextPath.append(remainingPath(0,i+1));
268    G4int n_treeEntry = aTree->GetTreeEntry();
269#ifdef G4DEBUG
270    printf(" find PATH\n");
271#endif
272    for( G4int i_thTree = 1; i_thTree <= n_treeEntry; i_thTree++ ) {
273      G4UIcommandTree* tree = aTree->GetTree(i_thTree);
274#ifdef G4DEBUG
275      printf("++++LOOP+++++++++++++%s == %s \n",nextPath.c_str(), tree->GetPathName().c_str());
276#endif
277      if( nextPath == tree->GetPathName() ) { 
278        return FindMatchingPath(tree,aCommandPath ); 
279      }
280    }
281  }
282  return empty;
283}
284////////////////////////////////////////////
285// Method involving an interactive G4cout //
286////////////////////////////////////////////
287/***************************************************************************/
288void G4VBasicShell::ExecuteCommand (
289 G4String aCommand
290)
291/***************************************************************************/
292// Should be put in G4VBasicShell.
293/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
294{
295  if(aCommand.length()<2) return;
296  G4UImanager* UI = G4UImanager::GetUIpointer();
297  if(UI==NULL) return;
298  G4int commandStatus = UI->ApplyCommand(aCommand);
299  switch(commandStatus) {
300  case fCommandSucceeded:
301    break;
302  case fCommandNotFound:
303    G4cerr << "command not found" << G4endl;
304    break;
305  case fIllegalApplicationState:
306    G4cerr << "illegal application state -- command refused" << G4endl;
307    break;
308  case fParameterOutOfRange:
309  case fParameterUnreadable:
310  case fParameterOutOfCandidates:
311  default:
312    G4cerr << "command refused (" << commandStatus << ")" << G4endl;
313  }
314}
315/***************************************************************************/
316void G4VBasicShell::ApplyShellCommand (
317 G4String a_string
318,G4bool& exitSession
319,G4bool& exitPause
320)
321/***************************************************************************/
322/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
323{
324  G4UImanager* UI = G4UImanager::GetUIpointer();
325  if(UI==NULL) return;
326
327  G4String command = a_string.strip(G4String::leading);
328  if( command(0) == '#' ) { 
329
330    G4cout << command << G4endl; 
331
332  } else if( command == "ls" || command(0,3) == "ls " ) {
333
334    ListDirectory( command );
335
336  } else if( command == "pwd" ) { 
337
338    G4cout << "Current Working Directory : " 
339       << GetCurrentWorkingDirectory() << G4endl; 
340
341  } else if( command(0,2) == "cd" ) { 
342
343    ChangeDirectoryCommand ( command );
344
345  } else if( command(0,4) == "help" ) { 
346
347    TerminalHelp( command ); 
348
349  } else if( command(0) == '?' ) { 
350
351    ShowCurrent( command );
352
353  } else if( command(0,4) == "hist" ) {
354
355    G4int nh = UI->GetNumberOfHistory();
356    for(G4int i=0;i<nh;i++) { 
357      G4cout << i << ": " << UI->GetPreviousCommand(i) << G4endl; 
358    }
359
360  } else if( command(0) == '!' ) {
361
362    G4String ss = command(1,command.length()-1);
363    G4int vl;
364    const char* tt = ss;
365    std::istringstream is(tt);
366    is >> vl;
367    G4int nh = UI->GetNumberOfHistory();
368    if(vl>=0 && vl<nh) { 
369      G4String prev = UI->GetPreviousCommand(vl); 
370      G4cout << prev << G4endl;
371      ExecuteCommand (ModifyToFullPathCommand(prev));
372    } else { 
373      G4cerr << "history " << vl << " is not found." << G4endl; 
374    }
375
376  } else if( command(0,4) == "exit" ) { 
377
378    if( exitPause == false) { //In a secondary loop.
379      G4cout << "You are now processing RUN." << G4endl;
380      G4cout << "Please abort it using \"/run/abort\" command first" << G4endl;
381      G4cout << " and use \"continue\" command until the application" << G4endl;
382      G4cout << " becomes to Idle." << G4endl;
383    } else {
384      exitSession = true;
385    }
386
387  } else if( command(0,4) == "cont" ) { 
388
389    exitPause = true;
390
391  } else {
392
393    ExecuteCommand (ModifyToFullPathCommand(a_string));
394
395  }
396}
397void G4VBasicShell::ShowCurrent(G4String newCommand)
398{
399  G4UImanager* UI = G4UImanager::GetUIpointer();
400  if(UI==NULL) return;
401  G4String comString = newCommand(1,newCommand.length()-1);
402  G4String theCommand = ModifyToFullPathCommand(comString);
403  G4String curV = UI->GetCurrentValues(theCommand);
404  if( ! curV.isNull() ) { 
405    G4cout << "Current value(s) of the parameter(s) : " << curV << G4endl; 
406  }
407}
408void G4VBasicShell::ChangeDirectoryCommand(G4String newCommand)
409{
410  G4String prefix;
411  if( newCommand.length() <= 3 ) { 
412    prefix = "/"; 
413  } else {
414    G4String aNewPrefix = newCommand(3,newCommand.length()-3);
415    prefix = aNewPrefix.strip(G4String::both);
416  }
417  if(!ChangeDirectory(prefix)) { 
418    G4cout << "directory <" << prefix << "> not found." << G4endl; 
419  }
420}
421void G4VBasicShell::ListDirectory(G4String newCommand)
422{
423  G4String targetDir;
424  if( newCommand.length() <= 3 ) { 
425    targetDir = GetCurrentWorkingDirectory();
426  } else {
427    G4String newPrefix = newCommand(3,newCommand.length()-3);
428    targetDir = newPrefix.strip(G4String::both);
429  }
430  G4UIcommandTree* commandTree = FindDirectory( targetDir );
431  if( commandTree == NULL ) { 
432    G4cout << "Directory <" << targetDir << "> is not found." << G4endl; 
433  } else { 
434    commandTree->ListCurrent(); 
435  }
436}
437void G4VBasicShell::TerminalHelp(G4String newCommand)
438{
439  G4UImanager* UI = G4UImanager::GetUIpointer();
440  if(UI==NULL) return;
441  G4UIcommandTree * treeTop = UI->GetTree();
442  size_t i = newCommand.index(" ");
443  if( i != std::string::npos )
444  {
445    G4String newValue = newCommand(i+1,newCommand.length()-(i+1));
446    newValue.strip(G4String::both);
447    G4String targetCom = ModifyToFullPathCommand( newValue );
448    G4UIcommand* theCommand = treeTop->FindPath( targetCom );
449    if( theCommand != NULL ) 
450    { 
451      theCommand->List();
452      return;
453    }
454    else
455    {
456      G4cout << "Command <" << newValue << " is not found." << G4endl;
457      return;
458    }
459  }
460
461  G4UIcommandTree * floor[10];
462  floor[0] = treeTop;
463  G4int iFloor = 0;
464  size_t prefixIndex = 1;
465  G4String prefix = GetCurrentWorkingDirectory();
466  while( prefixIndex < prefix.length()-1 )
467  {
468    size_t ii = prefix.index("/",prefixIndex);
469    floor[iFloor+1] = 
470      floor[iFloor]->GetTree(G4String(prefix(0,ii+1)));
471    prefixIndex = ii+1;
472    iFloor++;
473  }
474  floor[iFloor]->ListCurrentWithNum();
475  // 1998 Oct 2 non-number input
476  while(1){
477   //G4cout << G4endl << "Type the number ( 0:end, -n:n level back ) : "<<std::flush;
478    G4cout << G4endl << "Type the number ( 0:end, -n:n level back ) : "<<G4endl;
479    G4int i;
480    if(!GetHelpChoice(i)){
481      G4cout << G4endl << "Not a number, once more" << G4endl; 
482      continue;
483    } else if( i < 0 ){
484      iFloor += i;
485      if( iFloor < 0 ) iFloor = 0;
486      floor[iFloor]->ListCurrentWithNum(); 
487      continue;
488    } else if(i == 0) { 
489      break;
490    } else if( i > 0 ) {
491      G4int n_tree = floor[iFloor]->GetTreeEntry();
492      if( i > n_tree )
493      { 
494        if( i <= n_tree + floor[iFloor]->GetCommandEntry() )
495        { 
496          floor[iFloor]->GetCommand(i-n_tree)->List(); 
497        }
498      }
499      else
500      {
501        floor[iFloor+1] = floor[iFloor]->GetTree(i);
502        iFloor++;
503        floor[iFloor]->ListCurrentWithNum();
504      }
505    }
506  }
507  G4cout << "Exit from HELP." << G4endl << G4endl;
508  //G4cout << G4endl;
509  ExitHelp();
510}
511
512
513
514
515
516
517
518
519
520
521
522
Note: See TracBrowser for help on using the repository browser.