Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
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