Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4UItcsh.cc
Go to the documentation of this file.
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$
28//
29
30#ifndef WIN32
31
32#include "G4Types.hh"
33#include "G4StateManager.hh"
34#include "G4UIcommandStatus.hh"
35#include "G4UItcsh.hh"
36#include <ctype.h>
37#include <sstream>
38#include <fstream>
39#include <stdlib.h>
40
41// ASCII character code
42static const char AsciiCtrA = '\001';
43static const char AsciiCtrB = '\002';
44static const char AsciiCtrC = '\003';
45static const char AsciiCtrD = '\004';
46static const char AsciiCtrE = '\005';
47static const char AsciiCtrF = '\006';
48static const char AsciiCtrK = '\013';
49static const char AsciiCtrL = '\014';
50static const char AsciiCtrN = '\016';
51static const char AsciiCtrP = '\020';
52static const char AsciiCtrQ = '\021';
53static const char AsciiCtrS = '\023';
54static const char AsciiCtrZ = '\032';
55static const char AsciiTAB = '\011';
56static const char AsciiBS = '\010';
57static const char AsciiDEL = '\177';
58static const char AsciiESC = '\033';
59
60static const int AsciiPrintableMin = 32;
61
62// history file
63static const G4String historyFileName= "/.g4_hist";
64
65/////////////////////////////////////////////////////////
66G4UItcsh::G4UItcsh(const G4String& prompt, G4int maxhist)
67 : G4VUIshell(prompt),
68 commandLine(""), cursorPosition(1),
69 commandHistory(maxhist), maxHistory(maxhist),
70 currentHistoryNo(1), relativeHistoryIndex(0)
71/////////////////////////////////////////////////////////
72{
73 // get current terminal mode
74 tcgetattr(0, &tios);
75
76 // read a shell history file
77 const char* path = getenv("HOME");
78 if( path == NULL ) return;
79
80 G4String homedir= path;
81 G4String fname= homedir + historyFileName;
82
83 std::ifstream histfile;
84 enum { BUFSIZE= 1024 }; char linebuf[BUFSIZE];
85
86 histfile.open(fname, std::ios::in);
87 while (histfile.good()) {
88 if(histfile.eof()) break;
89
90 histfile.getline(linebuf, BUFSIZE);
91 G4String aline= linebuf;
92 aline.strip(G4String::both);
93 if(aline.size() != 0) StoreHistory(linebuf);
94 }
95 histfile.close();
96}
97
98/////////////////////
100/////////////////////
101{
102 // store a shell history
103 const char* path = getenv("HOME");
104 if( path == NULL ) return;
105
106 G4String homedir= path;
107 G4String fname= homedir + historyFileName;
108
109 std::ofstream histfile;
110 histfile.open(fname, std::ios::out);
111
112 G4int n0hist= 1;
114
115 for (G4int i=n0hist; i<= currentHistoryNo; i++) {
116 histfile << RestoreHistory(i) << G4endl;
117 }
118
119 histfile.close();
120}
121
122//////////////////////////////////////////
123void G4UItcsh::MakePrompt(const char* msg)
124//////////////////////////////////////////
125{
126 if(promptSetting.length()<=1) {
128 return;
129 }
130
131 promptString="";
132 size_t i;
133 for(i=0; i<promptSetting.length()-1; i++){
134 if(promptSetting[i]=='%'){
135 switch (promptSetting[i+1]) {
136 case 's': // current application status
137 {
138 G4String stateStr;
139 if(msg)
140 { stateStr = msg; }
141 else
142 {
144 stateStr= statM-> GetStateString(statM->GetCurrentState());
145 }
146 promptString.append(stateStr);
147 i++;
148 }
149 break;
150 case '/': // current working directory
152 i++;
153 break;
154 case 'h': // history#
155 {
156 std::ostringstream os;
157 os << currentHistoryNo;
158 promptString.append(os.str());
159 i++;
160 }
161 break;
162 default:
163 break;
164 }
165 } else {
167 }
168 }
169
170 // append last chaacter
171 if(i == promptSetting.length()-1)
173}
174
175
176//////////////////////////////
178//////////////////////////////
179{
180 RestoreTerm();
181}
182
183
184// --------------------------------------------------------------------
185// commad line operations
186// --------------------------------------------------------------------
187//////////////////////////////////////
189//////////////////////////////////////
190{
191 commandLine= "";
193}
194
195///////////////////////////////////////
197///////////////////////////////////////
198{
199 if( ! (cc >= AsciiPrintableMin && isprint(cc)) ) return;
200
201 // display...
202 G4cout << cc;
203 size_t i;
204 for(i=cursorPosition-1; i<commandLine.length() ;i++)
205 G4cout << commandLine[i];
206 for(i=cursorPosition-1; i<commandLine.length() ;i++)
207 G4cout << AsciiBS;
208 G4cout << std::flush;
209
210 // command line string...
211 if(IsCursorLast()) { // add
212 commandLine+= cc;
213 } else { // insert
214 commandLine.insert(cursorPosition-1, G4String(cc));
215 }
217}
218
219///////////////////////////////////
221///////////////////////////////////
222{
223 if(cursorPosition==1) return;
224
225 // display...
226 if(IsCursorLast()) {
227 G4cout << AsciiBS << ' ' << AsciiBS << std::flush;
228 } else {
229 G4cout << AsciiBS;
230 size_t i;
231 for(i=cursorPosition-2; i< commandLine.length()-1 ;i++){
232 G4cout << commandLine[i+1];
233 }
234 G4cout << ' ';
235 for(i=cursorPosition-2; i< commandLine.length() ;i++){
236 G4cout << AsciiBS;
237 }
238 G4cout << std::flush;
239 }
240
241 // command line string...
242 commandLine.erase(cursorPosition-2, 1);
243
245}
246
247////////////////////////////////
249////////////////////////////////
250{
251 if(IsCursorLast()) return;
252
253 // display...
254 size_t i;
255 for(i=cursorPosition-1; i< commandLine.length()-1 ;i++){
256 G4cout << commandLine[i+1];
257 }
258 G4cout << ' ';
259 for(i=cursorPosition-1; i< commandLine.length() ;i++){
260 G4cout << AsciiBS;
261 }
262 G4cout << std::flush;
263
264 // command lin string...
265 commandLine.erase(cursorPosition-1, 1);
266}
267
268//////////////////////////
270//////////////////////////
271{
272 // display...
273 G4int i;
274 for(i= cursorPosition; i>=2; i--) G4cout << AsciiBS;
275 for(i=1; i<=G4int(commandLine.length()); i++) G4cout << ' ';
276 for(i=1; i<=G4int(commandLine.length()); i++) G4cout << AsciiBS;
277 G4cout << std::flush;
278
279 // command line string...
280 commandLine.erase();
282}
283
284/////////////////////////////////
286/////////////////////////////////
287{
288 if(IsCursorLast()) return;
289
290 // display...
291 G4int i;
292 for(i=cursorPosition; i<=G4int(commandLine.length()); i++) G4cout << ' ';
293 for(i=commandLine.length(); i>=cursorPosition; i--) G4cout << AsciiBS;
294 G4cout << std::flush;
295
296 // command line string...
298 commandLine.length()-cursorPosition+1);
299}
300
301////////////////////////////
303////////////////////////////
304{
305 if(! clearString.empty() ) {
307
308 G4cout << promptString << commandLine << std::flush;
309 // reset cursur position
310 for(G4int i=commandLine.length()+1; i>=cursorPosition+1; i--)
311 G4cout << AsciiBS << std::flush;
312 }
313}
314
315//////////////////////////////
317//////////////////////////////
318{
319 if(IsCursorLast()) return;
320
321 G4cout << commandLine[(size_t)(cursorPosition-1)] << std::flush;
323}
324
325///////////////////////////////
327///////////////////////////////
328{
329 if(cursorPosition==1) return;
330
332 G4cout << AsciiBS << std::flush;
333}
334
335//////////////////////////////
337//////////////////////////////
338{
339 for(G4int i=cursorPosition; i>1; i--){
340 G4cout << AsciiBS;
341 }
342 G4cout << std::flush;
344}
345
346//////////////////////////////
348//////////////////////////////
349{
350 for(size_t i=cursorPosition-1; i<commandLine.length(); i++){
351 G4cout << commandLine[i];
352 }
353 G4cout << std::flush;
354 cursorPosition=commandLine.length()+1;
355}
356
357////////////////////////////////
359////////////////////////////////
360{
361 G4int nhmax= currentHistoryNo-1 >= maxHistory ?
363
364 // retain current input
366
367 if(relativeHistoryIndex>=-nhmax+1 && relativeHistoryIndex<=0) {
368 ClearLine();
371
372 G4cout << commandLine << std::flush;
373 cursorPosition= commandLine.length()+1;
374 }
375}
376
377////////////////////////////
379////////////////////////////
380{
381 G4int nhmax= currentHistoryNo-1 >= maxHistory ?
383
384 if(relativeHistoryIndex>=-nhmax && relativeHistoryIndex<=-1) {
385 ClearLine();
387
390
391 G4cout << commandLine << std::flush;
392 cursorPosition= commandLine.length()+1;
393 }
394}
395
396
397///////////////////////////////////
399///////////////////////////////////
400{
401 G4cout << G4endl;
402
403 // input string
405 // target token is last token
406 G4int jhead= input.last(' ');
407 if(jhead != G4int(G4String::npos)) {
408 input.remove(0, jhead);
409 input= input.strip(G4String::leading);
410 }
411 //G4cout << "@@@@ input=" << input << G4endl;
412
413 // command tree of "user specified directory"
415 G4String vcmd = "";
416
417 if( !input.empty() ) {
418 G4int len= input.length();
419 G4int indx=-1;
420 for(G4int i=len-1; i>=0; i--) {
421 if(input[(size_t)i]=='/') {
422 indx= i;
423 break;
424 }
425 }
426 // get abs. path
427 if(indx != -1) vpath= GetAbsCommandDirPath(input(0,indx+1));
428 if(!(indx==0 && len==1)) vcmd= input(indx+1,len-indx-1); // care for "/"
429 }
430
431 // list matched dirs/commands
432 //G4cout << "@@@ vpath=" << vpath <<":vcmd=" << vcmd << G4endl;
433 ListCommand(vpath, vpath+vcmd);
434
435 G4cout << promptString << commandLine << std::flush;
436}
437
438////////////////////////////////
440////////////////////////////////
441{
442 // inputting string
444 // target token is last token
445 G4int jhead= input.last(' ');
446 if(jhead != G4int(G4String::npos)) {
447 input.remove(0, jhead);
448 input= input.strip(G4String::leading);
449 }
450
451 // tail string
452 size_t thead = input.find_last_of('/');
453 G4String strtail = input;
454 if (thead != G4String::npos) strtail = input(thead+1, input.size()-thead-1);
455
456 // command tree of "user specified directory"
458 G4String vcmd;
459
460 G4int len= input.length();
461 if(!input.empty()) {
462 G4int indx= -1;
463 for(G4int i=len-1; i>=0; i--) {
464 if(input(i)=='/') {
465 indx= i;
466 break;
467 }
468 }
469 // get abs. path
470 if(indx != -1) vpath= GetAbsCommandDirPath(input(0,indx+1));
471 if(!(indx==0 && len==1)) vcmd= input(indx+1,len-indx-1); // care for "/"
472 }
473
474 G4UIcommandTree* atree= GetCommandTree(vpath); // get command tree
475 if(atree == NULL) return;
476
477 // list matched directories/commands
478 G4String stream, strtmp;
479 G4String inputpath= vpath+vcmd;
480 G4int nMatch= 0;
481
482 int Ndir= atree-> GetTreeEntry();
483 int Ncmd= atree-> GetCommandEntry();
484
485 // directory ...
486 for(G4int idir=1; idir<=Ndir; idir++) {
487 G4String fpdir= atree-> GetTree(idir)-> GetPathName();
488 // matching test
489 if( fpdir.index(inputpath, 0) == 0) {
490 if(nMatch==0) {
491 stream= GetCommandPathTail(fpdir);
492 } else {
493 strtmp= GetCommandPathTail(fpdir);
494 stream= GetFirstMatchedString(stream, strtmp);
495 }
496 nMatch++;
497 }
498 }
499
500 // command ...
501 for(G4int icmd=1; icmd<=Ncmd; icmd++){
502 G4String fpcmd= atree-> GetPathName() +
503 atree-> GetCommand(icmd) -> GetCommandName();
504 // matching test
505 if( fpcmd.index(inputpath, 0) ==0) {
506 if(nMatch==0) {
507 stream= GetCommandPathTail(fpcmd) + " ";
508 } else {
509 strtmp= GetCommandPathTail(fpcmd) + " ";
510 stream= GetFirstMatchedString(stream, strtmp);
511 }
512 nMatch++;
513 }
514 }
515
516 // display...
517 input= commandLine;
518 // target token is last token
519 jhead= input.last(' ');
520 if(jhead == G4int(G4String::npos)) jhead=0;
521 else jhead++;
522
523 G4int jt = jhead;
524
525 G4String dspstr;
526 G4int i;
527 for(i=jt; i<=G4int(input.length())-1; i++) dspstr+= G4String(AsciiBS);
528 for(i=jt; i<=G4int(input.length())-1; i++) dspstr+= G4String(' ');
529 for(i=jt; i<=G4int(input.length())-1; i++) dspstr+= G4String(AsciiBS);
530
531 dspstr+= (vpath + stream);
532 if (nMatch == 0) dspstr+= strtail;
533 G4cout << dspstr << std::flush;
534
535 // command line string
536 input.remove(jt);
537 input+= (vpath + stream);
538 if (nMatch==0) input+= strtail;
539
540 commandLine= input;
541 cursorPosition= commandLine.length()+1;
542}
543
544// --------------------------------------------------------------------
545// commad line
546// --------------------------------------------------------------------
547/////////////////////////////
549/////////////////////////////
550{
552
553 char cc;
554 do{ // input loop
555 G4cin.get(cc);
556
557 // treatment for special character
558 switch(cc){
559 case AsciiCtrA: // ... move cursor to the top
561 break;
562 case AsciiCtrB: // ... backward cursor
564 break;
565 case AsciiCtrD: // ... delete/exit/show matched list
566 if(commandLine.length()!=0 && IsCursorLast()) ListMatchedCommand();
567 else if (commandLine.empty()) {
568 return G4String("exit");
569 } else DeleteCharacter();
570 break;
571 case AsciiCtrE: // ... move cursor to the end
573 break;
574 case AsciiCtrF: // ... forward cursor
576 break;
577 case AsciiCtrK: // ... clear after the cursor
579 break;
580 case AsciiCtrL: // ... clear screen
581 // ClearScreen();
582 break;
583 case AsciiCtrN: // ... next command
584 NextCommand();
585 break;
586 case AsciiCtrP: // ... previous command
588 break;
589 case AsciiTAB: // ... command completion
590 if( (!commandLine.empty()) && IsCursorLast()) CompleteCommand();
591 break;
592 case AsciiDEL: // ... backspace
594 break;
595 case AsciiBS: // ... backspace
597 break;
598 case AsciiCtrC: // ... kill prompt
599 break;
600 case AsciiCtrQ: // ... restarts suspeded output
601 break;
602 case AsciiCtrS: // ... suspend output
603 break;
604 case AsciiCtrZ: // ... suspend
605 break;
606 default:
607 break;
608 }
609
610 // treatment for ESC. character
611 if( cc == AsciiESC) { // ESC
612 G4cin.get(cc);
613 if (cc == '[' || cc == 'O') { // care for another termcap, such as konsole
614 G4cin.get(cc);
615 switch(cc) {
616 case 'A': // [UP]
617 cc = 'P' - '@';
618 PreviousCommand(); // ... show previous commad
619 break;
620 case 'B': // [DOWN]
621 cc = 'N' - '@';
622 NextCommand(); // ... show next commad
623 break;
624 case 'C': // [RIGHT]
625 cc = 'F' - '@';
626 ForwardCursor(); // ... forward cursor
627 break;
628 case 'D': // [LEFT]
629 cc = 'B' - '@';
630 BackwardCursor(); // ... backward cursor
631 break;
632 default: // who knows !?
633 cc = 0;
634 break;
635 }
636 }
637 }
638
639 // insert character to command line and display
640 InsertCharacter(cc);
641
642 } while( cc != '\n');
643
644 return commandLine;
645}
646
647////////////////////////////////////////////////////////
649////////////////////////////////////////////////////////
650{
652
653 MakePrompt(msg); // update
655
656 G4cout << promptString << std::flush;
657
658 G4String newCommand= ReadLine(); // read line...
659 // multi-line
660 while( (newCommand.length() > 0) &&
661 ( newCommand[newCommand.length()-1] == '_') ) {
662 newCommand.remove(newCommand.length()-1);
663 G4cout << G4endl;
664 promptString= "? ";
665 G4cout << promptString << std::flush;
666 G4String newLine= ReadLine();
667 newCommand.append(newLine);
668 }
669
670 // update history...
671 G4bool isMeaningfull= FALSE; // check NULL command
672 for (size_t i=0; i<newCommand.length(); i++) {
673 if(newCommand[i] != ' ') {
674 isMeaningfull= TRUE;
675 break;
676 }
677 }
678 if( !newCommand.empty() && isMeaningfull) StoreHistory(newCommand);
679
680 // reset terminal
681 RestoreTerm();
682
683 G4cout << G4endl;
684 return newCommand;
685}
686
687////////////////////////////////////////////////////////////////////
689 const G4String& str2) const
690////////////////////////////////////////////////////////////////////
691{
692 int nlen1= str1.length();
693 int nlen2= str2.length();
694
695 int nmin = nlen1<nlen2 ? nlen1 : nlen2;
696
697 G4String strMatched;
698 for(size_t i=0; G4int(i)<nmin; i++){
699 if(str1[i]==str2[i]) {
700 strMatched+= str1[i];
701 } else {
702 break;
703 }
704 }
705
706 return strMatched;
707}
708
709// --------------------------------------------------------------------
710// history
711// --------------------------------------------------------------------
712//////////////////////////////////////////////
714//////////////////////////////////////////////
715{
717 if(i==0) i=maxHistory;
718
719 commandHistory[i-1]= aCommand; // 0-offset
721}
722
723///////////////////////////////////////////////
725///////////////////////////////////////////////
726{
727 if(histNo>= currentHistoryNo) return "";
728
729 G4int index= histNo%maxHistory;
730 if(index==0) index= maxHistory;
731
732 return commandHistory[index-1]; // 0-offset
733}
734
735// --------------------------------------------------------------------
736// terminal mode
737// --------------------------------------------------------------------
738///////////////////////////////////
740///////////////////////////////////
741{
742 termios tiosbuf= tios;
743
744 tiosbuf.c_iflag &= ~(BRKINT | ISTRIP);
745 tiosbuf.c_iflag |= (IGNBRK | IGNPAR);
746 tiosbuf.c_lflag &= ~(ICANON | IEXTEN | ECHO);
747 tiosbuf.c_cc[VMIN] = 1;
748 tiosbuf.c_cc[VTIME] = 0;
749
750 tcsetattr(0, TCSAFLUSH, &tiosbuf);
751}
752
753
754////////////////////////////
756////////////////////////////
757{
758 tcsetattr(0, TCSAFLUSH, &tios);
759}
760
761#endif
762
int G4int
Definition: G4Types.hh:66
bool G4bool
Definition: G4Types.hh:67
#define G4endl
Definition: G4ios.hh:52
#define G4cin
Definition: G4ios.hh:51
G4DLLIMPORT std::ostream G4cout
G4ApplicationState GetCurrentState() const
static G4StateManager * GetStateManager()
G4String & remove(str_size)
G4String & append(const G4String &)
str_size index(const char *, G4int pos=0) const
G4String strip(G4int strip_Type=trailing, char c=' ')
G4int last(char) const
void MoveCursorTop()
Definition: G4UItcsh.cc:336
void InsertCharacter(char cc)
Definition: G4UItcsh.cc:196
virtual void ResetTerminal()
Definition: G4UItcsh.cc:177
void PreviousCommand()
Definition: G4UItcsh.cc:358
virtual void MakePrompt(const char *msg=0)
Definition: G4UItcsh.cc:123
G4String GetFirstMatchedString(const G4String &str1, const G4String &str2) const
Definition: G4UItcsh.cc:688
void CompleteCommand()
Definition: G4UItcsh.cc:439
void NextCommand()
Definition: G4UItcsh.cc:378
G4String RestoreHistory(G4int index)
Definition: G4UItcsh.cc:724
void RestoreTerm()
Definition: G4UItcsh.cc:755
void ForwardCursor()
Definition: G4UItcsh.cc:316
G4String ReadLine()
Definition: G4UItcsh.cc:548
G4int cursorPosition
Definition: G4UItcsh.hh:76
void MoveCursorEnd()
Definition: G4UItcsh.cc:347
G4int currentHistoryNo
Definition: G4UItcsh.hh:108
void DeleteCharacter()
Definition: G4UItcsh.cc:248
termios tios
Definition: G4UItcsh.hh:116
void SetTermToInputMode()
Definition: G4UItcsh.cc:739
void ListMatchedCommand()
Definition: G4UItcsh.cc:398
G4String clearString
Definition: G4UItcsh.hh:117
G4bool IsCursorLast() const
Definition: G4UItcsh.hh:134
G4String commandLine
Definition: G4UItcsh.hh:75
void InitializeCommandLine()
Definition: G4UItcsh.cc:188
G4String commandLineBuf
Definition: G4UItcsh.hh:77
G4UItcsh(const G4String &prompt="%s> ", G4int maxhist=100)
Definition: G4UItcsh.cc:66
virtual G4String GetCommandLineString(const char *msg=0)
Definition: G4UItcsh.cc:648
std::vector< G4String > commandHistory
Definition: G4UItcsh.hh:106
G4int maxHistory
Definition: G4UItcsh.hh:107
void ClearLine()
Definition: G4UItcsh.cc:269
void BackwardCursor()
Definition: G4UItcsh.cc:326
void ClearAfterCursor()
Definition: G4UItcsh.cc:285
void ClearScreen()
Definition: G4UItcsh.cc:302
void StoreHistory(G4String aCommand)
Definition: G4UItcsh.cc:713
void BackspaceCharacter()
Definition: G4UItcsh.cc:220
G4int relativeHistoryIndex
Definition: G4UItcsh.hh:109
~G4UItcsh()
Definition: G4UItcsh.cc:99
virtual void ListCommand(const G4String &input, const G4String &candidate="") const
Definition: G4VUIshell.cc:231
G4UIcommandTree * GetCommandTree(const G4String &dir) const
Definition: G4VUIshell.cc:118
G4String currentCommandDir
Definition: G4VUIshell.hh:73
G4String promptString
Definition: G4VUIshell.hh:62
G4String promptSetting
Definition: G4VUIshell.hh:61
G4String GetCommandPathTail(const G4String &apath) const
Definition: G4VUIshell.cc:193
G4String GetAbsCommandDirPath(const G4String &apath) const
Definition: G4VUIshell.cc:147
#define TRUE
Definition: globals.hh:55
#define FALSE
Definition: globals.hh:52