| [476] | 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 | //
|
|---|
| [593] | 27 | // $Id: G4VUIshell.cc,v 1.10 2007/06/14 05:44:58 kmura Exp $
|
|---|
| [989] | 28 | // GEANT4 tag $Name: geant4-09-02-ref-02 $
|
|---|
| [476] | 29 | //
|
|---|
| 30 |
|
|---|
| 31 | #include "G4UImanager.hh"
|
|---|
| 32 | #include "G4UIcommand.hh"
|
|---|
| 33 | #include "G4UIcommandTree.hh"
|
|---|
| 34 | #include "G4StateManager.hh"
|
|---|
| 35 | #include "G4UIcommandStatus.hh"
|
|---|
| 36 | #include "G4VUIshell.hh"
|
|---|
| 37 | #include "G4UIArrayString.hh"
|
|---|
| 38 |
|
|---|
| 39 | // terminal color string
|
|---|
| 40 | static const G4String strESC= '\033';
|
|---|
| 41 | static const G4String TermColorString[8] ={
|
|---|
| 42 | strESC+"[30m", strESC+"[31m", strESC+"[32m", strESC+"[33m",
|
|---|
| 43 | strESC+"[34m", strESC+"[35m", strESC+"[36m", strESC+"[37m"
|
|---|
| 44 | };
|
|---|
| 45 |
|
|---|
| 46 | ///////////////////////////////////////////////////////////////////
|
|---|
| 47 | G4VUIshell::G4VUIshell(const G4String& prompt)
|
|---|
| 48 | : promptSetting(prompt), promptString(""), nColumn(80),
|
|---|
| 49 | lsColorFlag(FALSE), directoryColor(BLACK), commandColor(BLACK),
|
|---|
| 50 | currentCommandDir("/")
|
|---|
| 51 | ///////////////////////////////////////////////////////////////////
|
|---|
| 52 | {
|
|---|
| 53 | }
|
|---|
| 54 |
|
|---|
| 55 | /////////////////////////
|
|---|
| 56 | G4VUIshell::~G4VUIshell()
|
|---|
| 57 | /////////////////////////
|
|---|
| 58 | {
|
|---|
| 59 | }
|
|---|
| 60 |
|
|---|
| [593] | 61 | ////////////////////////////////////////////
|
|---|
| [476] | 62 | void G4VUIshell::MakePrompt(const char* msg)
|
|---|
| [593] | 63 | ////////////////////////////////////////////
|
|---|
| [476] | 64 | {
|
|---|
| 65 | if(promptSetting.length()<=1) {
|
|---|
| 66 | promptString= promptSetting;
|
|---|
| 67 | return;
|
|---|
| 68 | }
|
|---|
| 69 |
|
|---|
| 70 | promptString="";
|
|---|
| 71 | G4int i;
|
|---|
| 72 | for(i=0; i<G4int(promptSetting.length())-1; i++){
|
|---|
| 73 | if(promptSetting[(size_t)i]=='%'){
|
|---|
| 74 | switch (promptSetting[(size_t)(i+1)]) {
|
|---|
| 75 | case 's': // current application status
|
|---|
| 76 | {
|
|---|
| 77 | G4String stateStr;
|
|---|
| 78 | if(msg)
|
|---|
| 79 | { stateStr = msg; }
|
|---|
| 80 | else
|
|---|
| 81 | {
|
|---|
| 82 | G4StateManager* statM= G4StateManager::GetStateManager();
|
|---|
| 83 | stateStr= statM-> GetStateString(statM->GetCurrentState());
|
|---|
| 84 | }
|
|---|
| 85 | promptString.append(stateStr);
|
|---|
| 86 | i++;
|
|---|
| 87 | }
|
|---|
| 88 | break;
|
|---|
| 89 | case '/': // current working directory
|
|---|
| 90 | promptString.append(currentCommandDir);
|
|---|
| 91 | i++;
|
|---|
| 92 | break;
|
|---|
| 93 | default:
|
|---|
| 94 | promptString.append(G4String(promptSetting[(size_t)i]));
|
|---|
| 95 | break;
|
|---|
| 96 | }
|
|---|
| 97 | } else {
|
|---|
| 98 | promptString.append(G4String(promptSetting[(size_t)i]));
|
|---|
| 99 | }
|
|---|
| 100 | }
|
|---|
| 101 |
|
|---|
| 102 | // append last chaacter
|
|---|
| 103 | if(i == G4int(promptSetting.length())-1)
|
|---|
| 104 | promptString.append(G4String(promptSetting[(size_t)i]));
|
|---|
| 105 | }
|
|---|
| 106 |
|
|---|
| 107 |
|
|---|
| [593] | 108 | ////////////////////////////////
|
|---|
| 109 | void G4VUIshell::ResetTerminal()
|
|---|
| 110 | ////////////////////////////////
|
|---|
| 111 | {
|
|---|
| 112 |
|
|---|
| 113 | }
|
|---|
| 114 |
|
|---|
| [476] | 115 | // --------------------------------------------------------------------
|
|---|
| 116 | // G4command operations
|
|---|
| 117 | // --------------------------------------------------------------------
|
|---|
| 118 | ////////////////////////////////////////////////////////////////////////
|
|---|
| 119 | G4UIcommandTree* G4VUIshell::GetCommandTree(const G4String& input) const
|
|---|
| 120 | ////////////////////////////////////////////////////////////////////////
|
|---|
| 121 | {
|
|---|
| 122 | G4UImanager* UI= G4UImanager::GetUIpointer();
|
|---|
| 123 |
|
|---|
| 124 | G4UIcommandTree* cmdTree= UI-> GetTree(); // root tree
|
|---|
| 125 |
|
|---|
| 126 | G4String absPath= input; // G4String::strip() CONST !!
|
|---|
| 127 | absPath= GetAbsCommandDirPath(absPath.strip(G4String::both));
|
|---|
| 128 |
|
|---|
| 129 | // parsing absolute path ...
|
|---|
| 130 | if(absPath.length()==0) return NULL;
|
|---|
| 131 | if(absPath[absPath.length()-1] != '/') return NULL; // error??
|
|---|
| 132 | if(absPath=="/") return cmdTree;
|
|---|
| 133 |
|
|---|
| 134 | for(G4int indx=1; indx<G4int(absPath.length())-1; ) {
|
|---|
| 135 | G4int jslash= absPath.index("/", indx); // search index begin with "/"
|
|---|
| 136 | if(jslash != G4int(G4String::npos)) {
|
|---|
| 137 | if(cmdTree != NULL)
|
|---|
| 138 | cmdTree= cmdTree-> GetTree(G4String(absPath(0,jslash+1)));
|
|---|
| 139 | }
|
|---|
| 140 | indx= jslash+1;
|
|---|
| 141 | }
|
|---|
| 142 |
|
|---|
| 143 | if(cmdTree == NULL) return NULL;
|
|---|
| 144 | else return cmdTree;
|
|---|
| 145 | }
|
|---|
| 146 |
|
|---|
| 147 | //////////////////////////////////////////////////////////////////////
|
|---|
| 148 | G4String G4VUIshell::GetAbsCommandDirPath(const G4String& apath) const
|
|---|
| 149 | //////////////////////////////////////////////////////////////////////
|
|---|
| 150 | {
|
|---|
| [1027] | 151 | printf("G4VUIshell::GetAbsCommandDirPath %s\n",apath.c_str());
|
|---|
| [476] | 152 | if(apath.empty()) return apath; // null string
|
|---|
| 153 |
|
|---|
| 154 | // if "apath" does not start with "/",
|
|---|
| 155 | // then it is treared as relative path
|
|---|
| 156 | G4String bpath= apath;
|
|---|
| 157 | if(apath[(size_t)0] != '/') bpath= currentCommandDir + apath;
|
|---|
| 158 |
|
|---|
| 159 | // parsing...
|
|---|
| [1027] | 160 | printf("G4VUIshell::GetAbsCommandDirPath bpath %s\n",bpath.c_str());
|
|---|
| [476] | 161 | G4String absPath= "/";
|
|---|
| [1027] | 162 | printf("G4VUIshell::GetAbsCommandDirPath num %d \n",G4int(bpath.length())-1);
|
|---|
| [476] | 163 | for(G4int indx=1; indx<=G4int(bpath.length())-1; ) {
|
|---|
| [1027] | 164 | printf("G4VUIshell::GetAbsCommandDirPath for %d/%d \n",indx,G4int(bpath.length())-1);
|
|---|
| [476] | 165 | G4int jslash= bpath.index("/", indx); // search index begin with "/"
|
|---|
| 166 | if(jslash != G4int(G4String::npos)) {
|
|---|
| 167 | if(bpath(indx,jslash-indx) == ".."){ // directory up
|
|---|
| 168 | if(absPath.length() >=1) {
|
|---|
| 169 | absPath.remove(absPath.length()-1); // remove last "/"
|
|---|
| 170 | G4int jpre= absPath.last('/');
|
|---|
| 171 | if(jpre != G4int(G4String::npos)) absPath.remove(jpre+1);
|
|---|
| 172 | }
|
|---|
| 173 | } else if(bpath(indx,jslash-indx) == "."){ // nothing to do
|
|---|
| 174 | } else { // add
|
|---|
| 175 | if( !(jslash==indx && bpath(indx)=='/') ) // truncate "////"
|
|---|
| 176 | absPath+= bpath(indx, jslash-indx+1);
|
|---|
| 177 | // better to be check directory existence. (it costs!)
|
|---|
| 178 | }
|
|---|
| 179 | } else { // directory ONLY (ignore non-"/" terminated string)
|
|---|
| 180 | }
|
|---|
| 181 | indx= jslash+1;
|
|---|
| 182 | }
|
|---|
| [1027] | 183 | printf("G4VUIshell::GetAbsCommandDirPath RETURN %s\n",absPath.c_str());
|
|---|
| [476] | 184 | return absPath;
|
|---|
| 185 | }
|
|---|
| 186 |
|
|---|
| 187 |
|
|---|
| 188 | ////////////////////////////////////////////////////////////////////
|
|---|
| 189 | G4String G4VUIshell::GetCommandPathTail(const G4String& apath) const
|
|---|
| 190 | ////////////////////////////////////////////////////////////////////
|
|---|
| 191 | { // xxx/xxx/zzz -> zzz, trancate /// -> /
|
|---|
| 192 | if(apath.empty()) return apath;
|
|---|
| 193 |
|
|---|
| 194 | G4int lstr= apath.length();
|
|---|
| 195 |
|
|---|
| 196 | // for trancating "/"
|
|---|
| 197 | G4bool Qsla= FALSE;
|
|---|
| 198 | if(apath[(size_t)(lstr-1)]=='/') Qsla= TRUE;
|
|---|
| 199 |
|
|---|
| 200 | // searching last '/' from tail
|
|---|
| 201 | G4int indx= -1;
|
|---|
| 202 | for(G4int i=lstr-1; i>=0; i--) {
|
|---|
| 203 | if(Qsla && apath[(size_t)i]!='/') Qsla= FALSE; // break "/" flag!!
|
|---|
| 204 | if(apath[(size_t)i]=='/' && !Qsla) {
|
|---|
| 205 | indx= i;
|
|---|
| 206 | break;
|
|---|
| 207 | }
|
|---|
| 208 | }
|
|---|
| 209 |
|
|---|
| 210 | if(indx==-1) return apath; // not found
|
|---|
| 211 |
|
|---|
| 212 | if(indx==0 && lstr==1) { // "/"
|
|---|
| 213 | G4String nullStr;
|
|---|
| 214 | return nullStr;
|
|---|
| 215 | } else {
|
|---|
| 216 | //G4String newPath= apath(indx+1,lstr-indx-1);
|
|---|
| 217 | G4String newPath= apath;
|
|---|
| 218 | newPath= newPath(indx+1,lstr-indx-1);
|
|---|
| 219 | return newPath;
|
|---|
| 220 | }
|
|---|
| 221 | }
|
|---|
| 222 |
|
|---|
| 223 | // --------------------------------------------------------------------
|
|---|
| 224 | // shell commands
|
|---|
| 225 | // --------------------------------------------------------------------
|
|---|
| 226 | /////////////////////////////////////////////////////////////
|
|---|
| 227 | void G4VUIshell::ListCommand(const G4String& dir,
|
|---|
| 228 | const G4String& candidate) const
|
|---|
| 229 | /////////////////////////////////////////////////////////////
|
|---|
| 230 | {
|
|---|
| 231 | // specified directpry
|
|---|
| 232 | G4String input= dir; // ...
|
|---|
| 233 | input= input.strip(G4String::both);
|
|---|
| 234 |
|
|---|
| 235 | // command tree of "user specified directory"
|
|---|
| 236 | G4String vpath= currentCommandDir;
|
|---|
| 237 | G4String vcmd;
|
|---|
| 238 |
|
|---|
| 239 | G4int len= input.length();
|
|---|
| 240 | if(! input.empty()) {
|
|---|
| 241 | G4int indx= -1;
|
|---|
| 242 | for(G4int i=len-1; i>=0; i--) { // search last '/'
|
|---|
| 243 | if(input[(size_t)i]=='/') {
|
|---|
| 244 | indx= i;
|
|---|
| 245 | break;
|
|---|
| 246 | }
|
|---|
| 247 | }
|
|---|
| 248 | // get abs. path
|
|---|
| 249 | if(indx != -1) vpath= GetAbsCommandDirPath(input(0,indx+1));
|
|---|
| 250 | if(!(indx==0 && len==1)) vcmd= input(indx+1,len-indx-1); // care for "/"
|
|---|
| 251 | }
|
|---|
| 252 |
|
|---|
| 253 | // check "vcmd" is directory?
|
|---|
| 254 | G4String inputpath= vpath+vcmd;
|
|---|
| 255 | if(! vcmd.empty()){
|
|---|
| 256 | G4String tmpstr= inputpath + "/";
|
|---|
| 257 | if(GetCommandTree(tmpstr) != NULL) {
|
|---|
| 258 | vpath= tmpstr;
|
|---|
| 259 | vcmd= "";
|
|---|
| 260 | }
|
|---|
| 261 | }
|
|---|
| 262 |
|
|---|
| 263 | // check "vpath" directory exists?
|
|---|
| 264 | G4UIcommandTree* atree= GetCommandTree(vpath);
|
|---|
| 265 | if(atree == NULL) {
|
|---|
| 266 | G4cout << "<" << input << ">: No such directory" << G4endl;
|
|---|
| 267 | return;
|
|---|
| 268 | }
|
|---|
| 269 |
|
|---|
| 270 | // list matched directories/commands
|
|---|
| 271 | G4String stream;
|
|---|
| 272 | G4bool isMatch= FALSE;
|
|---|
| 273 |
|
|---|
| 274 | G4int Ndir= atree-> GetTreeEntry();
|
|---|
| 275 | G4int Ncmd= atree-> GetCommandEntry();
|
|---|
| 276 | if(Ndir==0 && Ncmd==0) return; // no contents
|
|---|
| 277 |
|
|---|
| 278 | // directory ...
|
|---|
| 279 | for(G4int idir=1; idir<=Ndir; idir++) {
|
|---|
| 280 | if(idir==1 && lsColorFlag) stream+= TermColorString[directoryColor];
|
|---|
| 281 | G4String fpdir= atree-> GetTree(idir)-> GetPathName();
|
|---|
| 282 | // matching test
|
|---|
| 283 | if(candidate.empty()) { // list all
|
|---|
| 284 | if(vcmd=="" || fpdir==inputpath) {
|
|---|
| 285 | stream+= GetCommandPathTail(fpdir); stream+= " ";
|
|---|
| 286 | isMatch= TRUE;
|
|---|
| 287 | }
|
|---|
| 288 | } else { // list only matched with candidate
|
|---|
| 289 | if( fpdir.index(candidate, 0) == 0) {
|
|---|
| 290 | stream+= GetCommandPathTail(fpdir); stream+= " ";
|
|---|
| 291 | }
|
|---|
| 292 | }
|
|---|
| 293 | }
|
|---|
| 294 |
|
|---|
| 295 | // command ...
|
|---|
| 296 | for(G4int icmd=1; icmd<=Ncmd; icmd++){
|
|---|
| 297 | if(icmd==1 && lsColorFlag) stream+= TermColorString[commandColor];
|
|---|
| 298 | G4String fpcmd= atree-> GetPathName() +
|
|---|
| 299 | atree-> GetCommand(icmd) -> GetCommandName();
|
|---|
| 300 | // matching test
|
|---|
| 301 | if(candidate.empty()) { // list all
|
|---|
| 302 | if(vcmd=="" || fpcmd==inputpath) {
|
|---|
| 303 | stream+= GetCommandPathTail(fpcmd); stream+= "* ";
|
|---|
| 304 | isMatch= TRUE;
|
|---|
| 305 | }
|
|---|
| 306 | } else { // list only matched with candidate
|
|---|
| 307 | if( fpcmd.index(candidate, 0) == 0) {
|
|---|
| 308 | stream+= GetCommandPathTail(fpcmd); stream+= "* ";
|
|---|
| 309 | }
|
|---|
| 310 | }
|
|---|
| 311 | }
|
|---|
| 312 |
|
|---|
| 313 | // waring : not matched
|
|---|
| 314 | if(!isMatch && candidate.empty())
|
|---|
| 315 | G4cout << "<" << input
|
|---|
| 316 | << ">: No such directory or command" << std::flush;
|
|---|
| 317 |
|
|---|
| 318 | // display
|
|---|
| 319 | G4UIArrayString arrayString(stream);
|
|---|
| 320 | arrayString.Show(nColumn);
|
|---|
| 321 | }
|
|---|
| [593] | 322 |
|
|---|