Geant4 Cross Reference |
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 // G4UIterminal.cc 30 // 31 // ==================================================================== 32 #include "G4UIterminal.hh" 33 34 #include "G4StateManager.hh" 35 #include "G4Types.hh" 36 #include "G4UIcommand.hh" 37 #include "G4UIcommandStatus.hh" 38 #include "G4UIcommandTree.hh" 39 #include "G4UIcsh.hh" 40 41 #include <sstream> 42 43 #ifndef WIN32 44 # include <csignal> 45 #endif 46 47 // ==================================================================== 48 // signal handler for soft-abort 49 // ==================================================================== 50 51 static G4ThreadLocal G4VUIshell* theshell = nullptr; 52 53 #ifndef WIN32 54 55 extern "C" 56 { 57 //////////////////////////////// 58 static void SignalHandler(G4int) 59 //////////////////////////////// 60 { 61 G4StateManager* stateManager = G4StateManager::GetStateManager(); 62 G4ApplicationState state = stateManager->GetCurrentState(); 63 64 if (state == G4State_GeomClosed || state == G4State_EventProc) { 65 G4cout << "aborting Run ..."; 66 G4UImanager::GetUIpointer()->ApplyCommand("/run/abort"); 67 G4cout << G4endl; 68 } 69 else { 70 G4cout << G4endl << "Session terminated." << G4endl; 71 theshell->ResetTerminal(); 72 G4Exception( 73 "G4UIterminal::SignalHandler()", "UI0001", FatalException, "KeyboardInterrput with Ctrl-C"); 74 } 75 76 // for original Unix / System V 77 signal(SIGINT, SignalHandler); 78 } 79 } 80 #endif 81 82 // ==================================================================== 83 // 84 // class description 85 // 86 // ==================================================================== 87 88 /////////////////////////////////////////////////////////// 89 G4UIterminal::G4UIterminal(G4VUIshell* aShell, G4bool qsig) 90 /////////////////////////////////////////////////////////// 91 { 92 UI = G4UImanager::GetUIpointer(); 93 UI->SetSession(this); 94 UI->SetCoutDestination(this); 95 96 iExit = false; 97 iCont = false; 98 99 if (aShell != nullptr) 100 shell = aShell; 101 else 102 shell = new G4UIcsh; 103 theshell = shell; // locally stored for the signal handler 104 105 // add signal handler 106 if (qsig) { 107 #ifndef WIN32 108 signal(SIGINT, SignalHandler); 109 #endif 110 } 111 } 112 113 ///////////////////////////// 114 G4UIterminal::~G4UIterminal() 115 ///////////////////////////// 116 { 117 delete shell; 118 119 if (G4UImanager::GetUIpointer() != nullptr) { 120 UI->SetSession(nullptr); 121 UI->SetCoutDestination(nullptr); 122 } 123 } 124 125 //////////////////////////////////////////////////// 126 void G4UIterminal::SetPrompt(const G4String& prompt) 127 //////////////////////////////////////////////////// 128 { 129 shell->SetPrompt(prompt); 130 } 131 132 ///////////////////////////////////////// 133 G4UIsession* G4UIterminal::SessionStart() 134 ///////////////////////////////////////// 135 { 136 iExit = true; 137 138 G4String newCommand = GetCommand(); 139 while (iExit) { 140 ExecuteCommand(newCommand); 141 newCommand = GetCommand(); 142 } 143 return nullptr; 144 } 145 146 ///////////////////////////////////////////////////////// 147 void G4UIterminal::PauseSessionStart(const G4String& msg) 148 ///////////////////////////////////////////////////////// 149 { 150 iCont = true; 151 152 G4String newCommand = GetCommand(msg); 153 while (iCont) { 154 ExecuteCommand(newCommand); 155 newCommand = GetCommand(msg); 156 } 157 } 158 159 /////////////////////////////////////////////////////////// 160 void G4UIterminal::ExecuteCommand(const G4String& aCommand) 161 /////////////////////////////////////////////////////////// 162 { 163 if (aCommand.length() < 2) return; 164 165 G4int returnVal = UI->ApplyCommand(aCommand); 166 167 G4int paramIndex = returnVal % 100; 168 // 0 - 98 : paramIndex-th parameter is invalid 169 // 99 : convination of parameters is invalid 170 G4int commandStatus = returnVal - paramIndex; 171 172 G4UIcommand* cmd = nullptr; 173 if (commandStatus != fCommandSucceeded) { 174 cmd = FindCommand(aCommand); 175 } 176 177 switch (commandStatus) { 178 case fCommandSucceeded: 179 break; 180 case fCommandNotFound: 181 G4cerr << "command <" << UI->SolveAlias(aCommand) << "> not found" << G4endl; 182 if (aCommand.find("@@") != G4String::npos) { 183 G4cout << "@@G4UIterminal" << G4endl; 184 } 185 break; 186 case fIllegalApplicationState: 187 G4cerr << "illegal application state -- command refused" << G4endl; 188 break; 189 case fParameterOutOfRange: 190 // if(paramIndex<99) { 191 // G4cerr << "Parameter is out of range (index " << paramIndex << ")" << G4endl; 192 // G4cerr << "Allowed range : " << cmd->GetParameter(paramIndex)->GetParameterRange() << 193 // G4endl; 194 // } else { 195 // G4cerr << "Parameter is out of range" << G4endl; 196 // G4cerr << "Allowed range : " << cmd->GetRange() << G4endl; 197 // } 198 break; 199 case fParameterOutOfCandidates: 200 G4cerr << "Parameter is out of candidate list (index " << paramIndex << ")" << G4endl; 201 G4cerr << "Candidates : " << cmd->GetParameter(paramIndex)->GetParameterCandidates() 202 << G4endl; 203 break; 204 case fParameterUnreadable: 205 G4cerr << "Parameter is wrong type and/or is not omittable (index " << paramIndex << ")" 206 << G4endl; 207 break; 208 case fAliasNotFound: 209 default: 210 G4cerr << "command refused (" << commandStatus << ")" << G4endl; 211 } 212 } 213 214 ////////////////////////////////////////////////// 215 G4String G4UIterminal::GetCommand(const char* msg) 216 ////////////////////////////////////////////////// 217 { 218 G4String newCommand = shell->GetCommandLineString(msg); 219 const G4String& nullString = ""; 220 221 G4String nC = G4StrUtil::lstrip_copy(newCommand); 222 223 if (nC.length() == 0) { 224 newCommand = nullString; 225 } 226 else if (nC[0] == '#') { 227 G4cout << nC << G4endl; 228 newCommand = nullString; 229 } 230 else if (nC == "ls" || nC.substr(0, 3) == "ls ") { // list commands 231 ListDirectory(nC); 232 newCommand = nullString; 233 } 234 else if (nC == "lc" || nC.substr(0, 3) == "lc ") { // ... by shell 235 shell->ListCommand(nC.erase(0, 2)); 236 newCommand = nullString; 237 } 238 else if (nC == "pwd") { // show current directory 239 G4cout << "Current Command Directory : " << GetCurrentWorkingDirectory() << G4endl; 240 newCommand = nullString; 241 } 242 else if (nC == "cwd") { // ... by shell 243 shell->ShowCurrentDirectory(); 244 newCommand = nullString; 245 } 246 else if (nC == "cd" || nC.substr(0, 3) == "cd ") { // "cd" 247 ChangeDirectoryCommand(nC); 248 shell->SetCurrentDirectory(GetCurrentWorkingDirectory()); 249 newCommand = nullString; 250 } 251 else if (nC == "help" || nC.substr(0, 5) == "help ") { // "help" 252 TerminalHelp(nC); 253 newCommand = nullString; 254 } 255 else if (nC[0] == '?') { // "show current value of a parameter" 256 ShowCurrent(nC); 257 newCommand = nullString; 258 } 259 else if (nC == "hist" || nC == "history") { // "hist/history" 260 G4int nh = UI->GetNumberOfHistory(); 261 for (G4int i = 0; i < nh; i++) { 262 G4cout << i << ": " << UI->GetPreviousCommand(i) << G4endl; 263 } 264 newCommand = nullString; 265 } 266 else if (nC[0] == '!') { // "!" 267 G4String ss = nC.substr(1, nC.length() - 1); 268 G4int vl; 269 const char* tt = ss; 270 std::istringstream is(tt); 271 is >> vl; 272 G4int nh = UI->GetNumberOfHistory(); 273 if (vl >= 0 && vl < nh) { 274 newCommand = UI->GetPreviousCommand(vl); 275 G4cout << newCommand << G4endl; 276 } 277 else { 278 G4cerr << "history " << vl << " is not found." << G4endl; 279 newCommand = nullString; 280 } 281 } 282 else if (nC == "exit") { // "exit" 283 if (iCont) { 284 G4cout << "You are now processing RUN." << G4endl; 285 G4cout << "Please abort it using \"/run/abort\" command first" << G4endl; 286 G4cout << " and use \"continue\" command until the application" << G4endl; 287 G4cout << " becomes to Idle." << G4endl; 288 } 289 else { 290 iExit = false; 291 newCommand = nullString; 292 } 293 } 294 else if (nC == "cont" || nC == "continue") { // "cont/continu" 295 iCont = false; 296 newCommand = nullString; 297 } 298 else if (nC.empty()) { // NULL command 299 newCommand = nullString; 300 } 301 else { 302 } 303 304 return ModifyToFullPathCommand(newCommand); 305 } 306 307 ///////////////////////////////////////////////////////////// 308 G4int G4UIterminal::ReceiveG4debug(const G4String& debugString) 309 ///////////////////////////////////////////////////////////// 310 { 311 std::cout << debugString << std::flush; 312 return 0; 313 } 314 315 ///////////////////////////////////////////////////////////// 316 G4int G4UIterminal::ReceiveG4cout(const G4String& coutString) 317 ///////////////////////////////////////////////////////////// 318 { 319 std::cout << coutString << std::flush; 320 return 0; 321 } 322 323 ///////////////////////////////////////////////////////////// 324 G4int G4UIterminal::ReceiveG4cerr(const G4String& cerrString) 325 ///////////////////////////////////////////////////////////// 326 { 327 std::cerr << cerrString << std::flush; 328 return 0; 329 } 330 331 /////////////////////////////////////////////// 332 G4bool G4UIterminal::GetHelpChoice(G4int& aInt) 333 /////////////////////////////////////////////// 334 { 335 G4cin >> aInt; 336 if (! G4cin.good()) { 337 G4cin.clear(); 338 G4cin.ignore(30, '\n'); 339 return false; 340 } 341 return true; 342 } 343 344 /////////////////////////////////// 345 void G4UIterminal::ExitHelp() const 346 /////////////////////////////////// 347 { 348 char temp[100]; 349 G4cin.getline(temp, 100); 350 } 351