G4VBasicShell.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 //
00027 // $Id$
00028 //
00029 
00030 #include "G4VBasicShell.hh"
00031 #include "G4StateManager.hh"
00032 #include "G4UIcommandTree.hh"
00033 #include "G4UIcommand.hh"
00034 #include "G4UIcommandStatus.hh"
00035 #include "G4UImanager.hh"
00036 #include <vector>
00037 #include <sstream>
00038 
00039 G4VBasicShell::G4VBasicShell()
00040 :currentDirectory("/")
00041 {
00042 }
00043 
00044 G4VBasicShell::~G4VBasicShell()
00045 {
00046 }
00047 
00048 G4String G4VBasicShell::ModifyToFullPathCommand(const char* aCommandLine) const
00049 {
00050   G4String rawCommandLine = aCommandLine;
00051   if(rawCommandLine.isNull()||rawCommandLine(0)=='\0') return rawCommandLine;
00052   G4String commandLine = rawCommandLine.strip(G4String::both);
00053   G4String commandString;
00054   G4String parameterString;
00055   size_t i = commandLine.index(" ");
00056   if( i != std::string::npos )
00057   {
00058     commandString = commandLine(0,i);
00059     parameterString = " ";
00060     parameterString += commandLine(i+1,commandLine.length()-(i+1));
00061   }
00062   else
00063   { commandString = commandLine; }
00064 
00065   G4String fullPathCommandLine
00066     = ModifyPath( commandString )+parameterString;
00067   return fullPathCommandLine;
00068 }
00069 
00070 G4String G4VBasicShell::GetCurrentWorkingDirectory() const
00071 {
00072   return currentDirectory;
00073 }
00074 
00075 G4bool G4VBasicShell::ChangeDirectory(const char* newDir)
00076 {
00077   G4String aNewPrefix = newDir;
00078   G4String newPrefix = aNewPrefix.strip(G4String::both);
00079   G4String newDirectory = ModifyPath( newPrefix );
00080   if( newDirectory( newDirectory.length() - 1 ) != '/' )
00081   { newDirectory += "/"; }
00082   if( FindDirectory( newDirectory.c_str() ) == NULL )
00083   { return false; }
00084   currentDirectory = newDirectory;
00085   return true;
00086 }
00087 
00088 G4UIcommandTree* G4VBasicShell::FindDirectory(const char* dirName) const
00089 {
00090   G4String aDirName = dirName;
00091   G4String theDir = aDirName.strip(G4String::both);
00092   G4String targetDir = ModifyPath( theDir );
00093   if( targetDir( targetDir.length()-1 ) != '/' )
00094   { targetDir += "/"; }
00095   G4UIcommandTree* comTree = G4UImanager::GetUIpointer()->GetTree();
00096   if( targetDir == "/" )
00097   { return comTree; }
00098   size_t idx = 1;
00099   while( idx < targetDir.length()-1 )
00100   {
00101     size_t i = targetDir.index("/",idx);
00102     comTree = comTree->GetTree(targetDir.substr(0,i+1).c_str());
00103     if( comTree == NULL )
00104     { return NULL; }
00105     idx = i+1;
00106   }
00107   return comTree;
00108 }
00109 
00110 G4UIcommand* G4VBasicShell::FindCommand(const char* commandName) const
00111 {
00112   G4String rawCommandLine = commandName;
00113   G4String commandLine = rawCommandLine.strip(G4String::both);
00114   G4String commandString;
00115   size_t i = commandLine.index(" ");
00116   if( i != std::string::npos )
00117   { commandString = commandLine(0,i); }
00118   else
00119   { commandString = commandLine; }
00120 
00121   G4String targetCom = ModifyPath(commandString);
00122   return G4UImanager::GetUIpointer()->GetTree()->FindPath(targetCom);
00123 }
00124 
00125 G4String G4VBasicShell::ModifyPath(const G4String& tempPath) const
00126 {
00127   if( tempPath.length() == 0 ) return tempPath;
00128 
00129   G4String newPath = "";
00130 
00131   // temporal full path
00132   if( tempPath(0) == '/') newPath = tempPath;
00133   else newPath = currentDirectory + tempPath;
00134 
00135   // body of path...
00136   while(1){
00137     size_t idx = newPath.find("/./");
00138     if( idx == G4String::npos) break;
00139     newPath.erase(idx,2);
00140   }
00141 
00142   while(1) {
00143     size_t idx = newPath.find("/../");
00144     if( idx == G4String::npos) break;
00145     if( idx == 0) {
00146       newPath.erase(1,3);
00147       continue;
00148     }
00149     size_t idx2 = newPath.find_last_of('/', idx-1);
00150     if(idx2 != G4String::npos) newPath.erase(idx2, idx-idx2+3);
00151   }
00152 
00153   // end of path...
00154   if(newPath(newPath.size()-3,3) == "/..") {
00155     if( newPath.size() == 3) {
00156       newPath = "/";
00157     } else {
00158       size_t idx = newPath.find_last_of('/', newPath.size()-4);
00159       if(idx != G4String::npos) newPath.erase(idx+1);
00160     }
00161   }
00162   if(newPath(newPath.size()-2,2) == "/.") newPath.erase(newPath.size()-1,1);
00163 
00164   // truncate "/////" to "/"
00165   while(1) {
00166     size_t idx = newPath.find("//");
00167     if( idx == G4String::npos) break;
00168     newPath.erase(idx,1);
00169   }
00170 
00171   return newPath;
00172 }
00174 // Method used for command completion //////
00176 G4String G4VBasicShell::Complete(const G4String& commandName)
00177 {
00178   G4String rawCommandLine = commandName;
00179   G4String commandLine = rawCommandLine.strip(G4String::both);
00180   size_t i = commandLine.index(" ");
00181   if( i != std::string::npos ) return rawCommandLine; // Already entering parameters,
00182                                             // assume command path is correct.
00183   G4String commandString = commandLine;
00184   G4String targetCom = ModifyPath(commandString);
00185   G4UIcommandTree* tree = G4UImanager::GetUIpointer()->GetTree();
00186   G4String value = FindMatchingPath(tree,targetCom);
00187   if(value=="") return rawCommandLine;
00188   return value;
00189 }
00190 
00191 G4String G4VBasicShell::FindMatchingPath(G4UIcommandTree* aTree,
00192                                          const G4String& aCommandPath)
00193 {
00194   return aTree-> CompleteCommandPath(aCommandPath);
00195 }
00196 
00198 // Method involving an interactive G4cout //
00200 /***************************************************************************/
00201 void G4VBasicShell::ExecuteCommand(const G4String& aCommand)
00202 /***************************************************************************/
00203 // Should be put in G4VBasicShell.
00205 {
00206   if(aCommand.length()<2) return;
00207   G4UImanager* UI = G4UImanager::GetUIpointer();
00208   if(UI==NULL) return;
00209   G4int commandStatus = UI->ApplyCommand(aCommand);
00210   switch(commandStatus) {
00211   case fCommandSucceeded:
00212     break;
00213   case fCommandNotFound:
00214     G4cerr << "command not found" << G4endl;
00215     break;
00216   case fIllegalApplicationState:
00217     G4cerr << "illegal application state -- command refused" << G4endl;
00218     break;
00219   case fParameterOutOfRange:
00220   case fParameterUnreadable:
00221   case fParameterOutOfCandidates:
00222   default:
00223     G4cerr << "command refused (" << commandStatus << ")" << G4endl;
00224   }
00225 }
00226 /***************************************************************************/
00227 void G4VBasicShell::ApplyShellCommand (const G4String& a_string,
00228                                        G4bool& exitSession, G4bool& exitPause
00229 )
00230 /***************************************************************************/
00232 {
00233   G4UImanager* UI = G4UImanager::GetUIpointer();
00234   if(UI==NULL) return;
00235 
00236   G4String command = a_string;
00237   command.strip(G4String::leading);
00238 
00239   if( command(0) == '#' ) {
00240 
00241     G4cout << command << G4endl;
00242 
00243   } else if( command == "ls" || command(0,3) == "ls " ) {
00244 
00245     ListDirectory( command );
00246 
00247   } else if( command == "pwd" ) {
00248 
00249     G4cout << "Current Working Directory : "
00250        << GetCurrentWorkingDirectory() << G4endl;
00251 
00252   } else if( command == "cd" || command(0,3) == "cd ") {
00253 
00254     ChangeDirectoryCommand ( command );
00255 
00256   } else if( command == "help" || command(0,5) == "help ") {
00257 
00258     TerminalHelp( command );
00259 
00260   } else if( command(0) == '?' ) {
00261 
00262     ShowCurrent( command );
00263 
00264   } else if( command == "hist" || command == "history") {
00265 
00266     G4int nh = UI->GetNumberOfHistory();
00267     for(G4int i=0;i<nh;i++) {
00268       G4cout << i << ": " << UI->GetPreviousCommand(i) << G4endl;
00269     }
00270 
00271   } else if( command(0) == '!' ) {
00272 
00273     G4String ss = command(1,command.length()-1);
00274     G4int vl;
00275     const char* tt = ss;
00276     std::istringstream is(tt);
00277     is >> vl;
00278     G4int nh = UI->GetNumberOfHistory();
00279     if(vl>=0 && vl<nh) {
00280       G4String prev = UI->GetPreviousCommand(vl);
00281       G4cout << prev << G4endl;
00282       ExecuteCommand (ModifyToFullPathCommand(prev));
00283     } else {
00284       G4cerr << "history " << vl << " is not found." << G4endl;
00285     }
00286 
00287   } else if( command == "exit" ) {
00288 
00289     if( exitPause == false) { //In a secondary loop.
00290       G4cout << "You are now processing RUN." << G4endl;
00291       G4cout << "Please abort it using \"/run/abort\" command first" << G4endl;
00292       G4cout << " and use \"continue\" command until the application" << G4endl;
00293       G4cout << " becomes to Idle." << G4endl;
00294     } else {
00295       exitSession = true;
00296     }
00297 
00298   } else if( command == "cont" || command == "continue"){
00299 
00300     exitPause = true;
00301 
00302   } else {
00303 
00304     ExecuteCommand(ModifyToFullPathCommand(a_string));
00305 
00306   }
00307 }
00308 
00309 void G4VBasicShell::ShowCurrent(const G4String& newCommand) const
00310 {
00311   G4UImanager* UI = G4UImanager::GetUIpointer();
00312   if(UI==NULL) return;
00313   G4String comString = newCommand.substr(1,newCommand.length()-1);
00314   G4String theCommand = ModifyToFullPathCommand(comString);
00315   G4String curV = UI->GetCurrentValues(theCommand);
00316   if( ! curV.isNull() ) {
00317     G4cout << "Current value(s) of the parameter(s) : " << curV << G4endl;
00318   }
00319 }
00320 
00321 void G4VBasicShell::ChangeDirectoryCommand(const G4String& newCommand)
00322 {
00323   G4String prefix;
00324   if( newCommand.length() <= 3 ) {
00325     prefix = "/";
00326   } else {
00327     G4String aNewPrefix = newCommand.substr(3, newCommand.length()-3);
00328     prefix = aNewPrefix.strip(G4String::both);
00329   }
00330   if(!ChangeDirectory(prefix)) {
00331     G4cout << "directory <" << prefix << "> not found." << G4endl;
00332   }
00333 }
00334 
00335 void G4VBasicShell::ListDirectory(const G4String& newCommand) const
00336 {
00337   G4String targetDir;
00338   if( newCommand.length() <= 3 ) {
00339     targetDir = GetCurrentWorkingDirectory();
00340   } else {
00341     G4String newPrefix = newCommand.substr(3, newCommand.length()-3);
00342     targetDir = newPrefix.strip(G4String::both);
00343   }
00344   G4UIcommandTree* commandTree = FindDirectory( targetDir );
00345   if( commandTree == NULL ) {
00346     G4cout << "Directory <" << targetDir << "> is not found." << G4endl;
00347   } else {
00348     commandTree->ListCurrent();
00349   }
00350 }
00351 void G4VBasicShell::TerminalHelp(const G4String& newCommand)
00352 {
00353   G4UImanager* UI = G4UImanager::GetUIpointer();
00354   if(UI==NULL) return;
00355   G4UIcommandTree * treeTop = UI->GetTree();
00356   size_t i = newCommand.index(" ");
00357   if( i != std::string::npos )
00358   {
00359     G4String newValue = newCommand.substr(i+1, newCommand.length()-(i+1));
00360     newValue.strip(G4String::both);
00361     G4String targetCom = ModifyToFullPathCommand(newValue);
00362     G4UIcommand* theCommand = treeTop->FindPath(targetCom);
00363     if( theCommand != NULL )
00364     {
00365       theCommand->List();
00366       return;
00367     }
00368     else
00369     {
00370       G4cout << "Command <" << newValue << " is not found." << G4endl;
00371       return;
00372     }
00373   }
00374 
00375   G4UIcommandTree * floor[10];
00376   floor[0] = treeTop;
00377   size_t iFloor = 0;
00378   size_t prefixIndex = 1;
00379   G4String prefix = GetCurrentWorkingDirectory();
00380   while( prefixIndex < prefix.length()-1 )
00381   {
00382     size_t ii = prefix.index("/",prefixIndex);
00383     floor[iFloor+1] =
00384       floor[iFloor]->GetTree(G4String(prefix(0,ii+1)));
00385     prefixIndex = ii+1;
00386     iFloor++;
00387   }
00388   floor[iFloor]->ListCurrentWithNum();
00389   // 1998 Oct 2 non-number input
00390   while(1){
00391    //G4cout << G4endl << "Type the number ( 0:end, -n:n level back ) : "<<std::flush;
00392     G4cout << G4endl << "Type the number ( 0:end, -n:n level back ) : "<<G4endl;
00393     G4int j;
00394     if(!GetHelpChoice(j)){
00395       G4cout << G4endl << "Not a number, once more" << G4endl;
00396       continue;
00397     } else if( j < 0 ){
00398       if( iFloor < (size_t)-j ) iFloor = 0;
00399       else iFloor += j;
00400       //iFloor += j;
00401       //if( iFloor < 0 ) iFloor = 0;
00402       floor[iFloor]->ListCurrentWithNum();
00403       continue;
00404     } else if(j == 0) {
00405       break;
00406     } else if( j > 0 ) {
00407       G4int n_tree = floor[iFloor]->GetTreeEntry();
00408       if( j > n_tree )
00409       {
00410         if( j <= n_tree + floor[iFloor]->GetCommandEntry() )
00411         {
00412           floor[iFloor]->GetCommand(j-n_tree)->List();
00413         }
00414       }
00415       else
00416       {
00417         floor[iFloor+1] = floor[iFloor]->GetTree(j);
00418         iFloor++;
00419         floor[iFloor]->ListCurrentWithNum();
00420       }
00421     }
00422   }
00423   G4cout << "Exit from HELP." << G4endl << G4endl;
00424   //G4cout << G4endl;
00425   ExitHelp();
00426 }

Generated on Mon May 27 17:50:09 2013 for Geant4 by  doxygen 1.4.7