// // ******************************************************************** // * License and Disclaimer * // * * // * The Geant4 software is copyright of the Copyright Holders of * // * the Geant4 Collaboration. It is provided under the terms and * // * conditions of the Geant4 Software License, included in the file * // * LICENSE and available at http://cern.ch/geant4/license . These * // * include a list of copyright holders. * // * * // * Neither the authors of this software system, nor their employing * // * institutes,nor the agencies providing financial support for this * // * work make any representation or warranty, express or implied, * // * regarding this software system or assume any liability for its * // * use. Please see the license in the file LICENSE and URL above * // * for the full disclaimer and the limitation of liability. * // * * // * This code implementation is the result of the scientific and * // * technical work of the GEANT4 collaboration. * // * By using, copying, modifying or distributing the software (or * // * any work based on the software) you agree to acknowledge its * // * use in resulting scientific publications, and indicate your * // * acceptance of all terms of the Geant4 Software license. * // ******************************************************************** // // // $Id: G4UItcsh.cc,v 1.12 2006/06/29 19:09:54 gunter Exp $ // GEANT4 tag $Name: geant4-08-01-patch-01 $ // #ifndef WIN32 #include "G4Types.hh" #include "G4StateManager.hh" #include "G4UIcommandStatus.hh" #include "G4UItcsh.hh" #include #include // ASCII character code static const char AsciiCtrA = '\001'; static const char AsciiCtrB = '\002'; static const char AsciiCtrC = '\003'; static const char AsciiCtrD = '\004'; static const char AsciiCtrE = '\005'; static const char AsciiCtrF = '\006'; static const char AsciiCtrK = '\013'; static const char AsciiCtrL = '\014'; static const char AsciiCtrN = '\016'; static const char AsciiCtrP = '\020'; static const char AsciiCtrQ = '\021'; static const char AsciiCtrS = '\023'; static const char AsciiCtrZ = '\032'; static const char AsciiTAB = '\011'; static const char AsciiBS = '\010'; static const char AsciiDEL = '\177'; static const char AsciiESC = '\033'; static const int AsciiPrintableMin = 32; ///////////////////////////////////////////////////////// G4UItcsh::G4UItcsh(const G4String& prompt, G4int maxhist) : G4VUIshell(prompt), commandLine(""), cursorPosition(1), commandHistory(maxhist), maxHistory(maxhist), currentHistoryNo(1), relativeHistoryIndex(0) ///////////////////////////////////////////////////////// { // get current terminal mode tcgetattr(0, &tios); } ///////////////////// G4UItcsh::~G4UItcsh() ///////////////////// { } /////////////////////////// void G4UItcsh::MakePrompt(const char* msg) /////////////////////////// { if(promptSetting.length()<=1) { promptString= promptSetting; return; } promptString=""; size_t i; for(i=0; i GetStateString(statM->GetCurrentState()); } promptString.append(stateStr); i++; } break; case '/': // current working directory promptString.append(currentCommandDir); i++; break; case 'h': // history# { std::ostringstream os; os << currentHistoryNo; promptString.append(os.str()); i++; } break; default: break; } } else { promptString.append(G4String(promptSetting[i])); } } // append last chaacter if(i == promptSetting.length()-1) promptString.append(G4String(promptSetting[i])); } // -------------------------------------------------------------------- // commad line operations // -------------------------------------------------------------------- ////////////////////////////////////// void G4UItcsh::InitializeCommandLine() ////////////////////////////////////// { commandLine= ""; cursorPosition= 1; } /////////////////////////////////////// void G4UItcsh::InsertCharacter(char cc) /////////////////////////////////////// { if( ! (cc >= AsciiPrintableMin && isprint(cc)) ) return; // display... G4cout << cc; size_t i; for(i=cursorPosition-1; i=2; i--) G4cout << AsciiBS; for(i=1; i<=G4int(commandLine.length()); i++) G4cout << ' '; for(i=1; i<=G4int(commandLine.length()); i++) G4cout << AsciiBS; G4cout << std::flush; // command line string... commandLine.erase(); cursorPosition= 1; } ///////////////////////////////// void G4UItcsh::ClearAfterCursor() ///////////////////////////////// { if(IsCursorLast()) return; // display... G4int i; for(i=cursorPosition; i<=G4int(commandLine.length()); i++) G4cout << ' '; for(i=commandLine.length(); i>=cursorPosition; i--) G4cout << AsciiBS; G4cout << std::flush; // command line string... commandLine.erase(cursorPosition-1, commandLine.length()-cursorPosition+1); } //////////////////////////// void G4UItcsh::ClearScreen() //////////////////////////// { if(! clearString.empty() ) { G4cout << clearString; G4cout << promptString << commandLine << std::flush; // reset cursur position for(G4int i=commandLine.length()+1; i>=cursorPosition+1; i--) G4cout << AsciiBS << std::flush; } } ////////////////////////////// void G4UItcsh::ForwardCursor() ////////////////////////////// { if(IsCursorLast()) return; G4cout << commandLine[(size_t)(cursorPosition-1)] << std::flush; cursorPosition++; } /////////////////////////////// void G4UItcsh::BackwardCursor() /////////////////////////////// { if(cursorPosition==1) return; cursorPosition--; G4cout << AsciiBS << std::flush; } ////////////////////////////// void G4UItcsh::MoveCursorTop() ////////////////////////////// { for(G4int i=cursorPosition; i>1; i--){ G4cout << AsciiBS; } G4cout << std::flush; cursorPosition=1; } ////////////////////////////// void G4UItcsh::MoveCursorEnd() ////////////////////////////// { for(size_t i=cursorPosition-1; i= maxHistory ? maxHistory : currentHistoryNo-1; // retain current input if(relativeHistoryIndex==0) commandLineBuf= commandLine; if(relativeHistoryIndex>=-nhmax+1 && relativeHistoryIndex<=0) { ClearLine(); relativeHistoryIndex--; commandLine= RestoreHistory(currentHistoryNo+relativeHistoryIndex); G4cout << commandLine << std::flush; cursorPosition= commandLine.length()+1; } } //////////////////////////// void G4UItcsh::NextCommand() //////////////////////////// { G4int nhmax= currentHistoryNo-1 >= maxHistory ? maxHistory : currentHistoryNo-1; if(relativeHistoryIndex>=-nhmax && relativeHistoryIndex<=-1) { ClearLine(); relativeHistoryIndex++; if(relativeHistoryIndex==0) commandLine= commandLineBuf; else commandLine= RestoreHistory(currentHistoryNo+relativeHistoryIndex); G4cout << commandLine << std::flush; cursorPosition= commandLine.length()+1; } } /////////////////////////////////// void G4UItcsh::ListMatchedCommand() /////////////////////////////////// { G4cout << G4endl; // input string G4String input= G4String(commandLine).strip(G4String::leading); // target token is last token G4int jhead= input.last(' '); if(jhead != G4int(G4String::npos)) { input.remove(0, jhead); input= input.strip(G4String::leading); } // command tree of "user specified directory" G4String vpath= currentCommandDir; G4String vcmd; if( !input.empty() ) { G4int len= input.length(); G4int indx=-1; for(G4int i=len-1; i>=0; i--) { if(input[(size_t)i]=='/') { indx= i; break; } } // get abs. path if(indx != -1) vpath= GetAbsCommandDirPath(input(0,indx+1)); if(!(indx==0 && len==1)) vcmd= input(indx+1,len-indx-1); // care for "/" } // list matched dirs/commands ListCommand(vpath, vpath+vcmd); G4cout << promptString << commandLine << std::flush; } //////////////////////////////// void G4UItcsh::CompleteCommand() //////////////////////////////// { // inputting string G4String input= G4String(commandLine).strip(G4String::leading); // target token is last token G4int jhead= input.last(' '); if(jhead != G4int(G4String::npos)) { input.remove(0, jhead); input= input.strip(G4String::leading); } // command tree of "user specified directory" G4String vpath= currentCommandDir; G4String vcmd; G4int len= input.length(); if(!input.empty()) { G4int indx= -1; for(G4int i=len-1; i>=0; i--) { if(input(i)=='/') { indx= i; break; } } // get abs. path if(indx != -1) vpath= GetAbsCommandDirPath(input(0,indx+1)); if(!(indx==0 && len==1)) vcmd= input(indx+1,len-indx-1); // care for "/" } G4UIcommandTree* atree= GetCommandTree(vpath); // get command tree if(atree == NULL) return; // list matched directories/commands G4String stream, strtmp; G4String inputpath= vpath+vcmd; G4int nMatch= 0; int Ndir= atree-> GetTreeEntry(); int Ncmd= atree-> GetCommandEntry(); // directory ... for(G4int idir=1; idir<=Ndir; idir++) { G4String fpdir= atree-> GetTree(idir)-> GetPathName(); // matching test if( fpdir.index(inputpath, 0) == 0) { if(nMatch==0) { stream= GetCommandPathTail(fpdir); } else { strtmp= GetCommandPathTail(fpdir); stream= GetFirstMatchedString(stream, strtmp); } nMatch++; } } // command ... for(G4int icmd=1; icmd<=Ncmd; icmd++){ G4String fpcmd= atree-> GetPathName() + atree-> GetCommand(icmd) -> GetCommandName(); // matching test if( fpcmd.index(inputpath, 0) ==0) { if(nMatch==0) { stream= GetCommandPathTail(fpcmd) + " "; } else { strtmp= GetCommandPathTail(fpcmd) + " "; stream= GetFirstMatchedString(stream, strtmp); } nMatch++; } } if(nMatch==0) return; // no matched // display... input= commandLine; // target token is last token jhead= input.last(' '); if(jhead == G4int(G4String::npos)) jhead=0; else jhead++; G4int jt= input.find_last_of('/'); if(jt 0) && ( newCommand[newCommand.length()-1] == '_') ) { newCommand.remove(newCommand.length()-1); G4cout << G4endl; promptString= "? "; G4cout << promptString << std::flush; G4String newLine= ReadLine(); newCommand.append(newLine); } // update history... G4bool isMeaningfull= FALSE; // check NULL command for (size_t i=0; i= currentHistoryNo) return ""; G4int index= histNo%maxHistory; if(index==0) index= maxHistory; return commandHistory[index-1]; // 0-offset } // -------------------------------------------------------------------- // terminal mode // -------------------------------------------------------------------- /////////////////////////////////// void G4UItcsh::SetTermToInputMode() /////////////////////////////////// { termios tiosbuf= tios; tiosbuf.c_iflag &= ~(BRKINT | ISTRIP); tiosbuf.c_iflag |= (IGNBRK | IGNPAR); tiosbuf.c_lflag &= ~(ICANON | IEXTEN | ECHO); tiosbuf.c_cc[VMIN] = 1; tiosbuf.c_cc[VTIME] = 0; tcsetattr(0, TCSAFLUSH, &tiosbuf); } //////////////////////////// void G4UItcsh::RestoreTerm() //////////////////////////// { tcsetattr(0, TCSAFLUSH, &tios); } #endif