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