#DOCUMENTATION by cg
class: TerminalSession
comment/format in: #documentation
changed:
#collectOutputAndCheckForPrompt:count:
#forgetPrompt:
#onPrompt:do:
#onPrompt:do:onPrompt:do:
--- a/TerminalSession.st Thu Aug 11 16:51:20 2016 +0200
+++ b/TerminalSession.st Fri Aug 12 18:14:07 2016 +0200
@@ -1,3 +1,5 @@
+"{ Encoding: utf8 }"
+
"{ Package: 'stx:libbasic2' }"
"{ NameSpace: Smalltalk }"
@@ -20,13 +22,21 @@
This keeps the state and API to interact with another program
via a terminal session. Under Unix, a pseudo-tty connection
is used; other operating systems might use other mechanisms.
+
This is (currently) used by the GDBApplication, to interact
with gdb, cscope and the program.
It can be used wherever more control is needed than a simple pipe
offers (such as terminal emulation, window size, CTRL-c support etc.)
- A lot of code has been Extracted from TerminalView, which will be refactored,
- once this is stable.
+ A major feature is a mechanism to catch certain prompt strings of the output
+ and get a notification.
+ This is very useful, if a program's output is to be shown both in a terminalview,
+ and also to be analyzed for robot actions.
+ Applications for this are telnet like interaction, interactions with a debugger
+ or monitor (gdb, android-adb) etc.,
+
+ A lot of code has been extracted from TerminalView,
+ which will be refactored, once this is stable.
For now, there is some code duplication (as of Summer 2014).
outStream - the controlled program's output (a pty-half)
@@ -413,7 +423,9 @@
!
forgetPrompt:aString
- promptActions removeKey:aString
+ "/ Transcript show:'forget prompt: '; showCR:aString.
+ promptActions removeKey:aString ifAbsent:[].
+ "/ Transcript show:'prompts now: '; showCR:promptActions.
!
onPrompt:aString do:aBlock
@@ -421,9 +433,9 @@
notice: will only start checking for prompt, when startCollectingOutput
has been called."
- promptActions := Dictionary new
- at:aString put:aBlock;
- yourself
+ "/ Transcript show:'add prompt: '; showCR:aString.
+ promptActions isNil ifTrue:[promptActions := Dictionary new].
+ promptActions at:aString put:aBlock
!
onPrompt:string1 do:block1 onPrompt:string2 do:block2
@@ -431,10 +443,12 @@
notice: will only start checking for prompt, when startCollectingOutput
has been called."
- promptActions := Dictionary new
- at:string1 put:block1;
- at:string2 put:block2;
- yourself
+ "/ Transcript show:'add prompt: '; showCR:string1.
+ "/ Transcript show:'add prompt: '; showCR:string2.
+ promptActions isNil ifTrue:[promptActions := Dictionary new].
+ promptActions
+ at:string1 put:block1;
+ at:string2 put:block2.
!
outputFromAction:aBlock prompt:prompt timeout:seconds
@@ -581,6 +595,7 @@
string := buffer copyTo:n.
collectedOutput nextPutAll:string.
+ "/ Transcript showCR:'prompts: '; showCR:promptActions.
promptActions notNil ifTrue:[
collectedString := collectedOutput contents.
i := collectedString lastIndexOf:Character lf.
@@ -592,9 +607,9 @@
lastLine := (collectedString copyFrom:i2+1 to:i-1) withoutTrailingSeparators.
].
].
- "/ Transcript show:lastLine; showCR:lastLine asByteArray.
+ "/ Transcript show:' got: <'; show:lastLine; showCR:'>'. "/ ; showCR:lastLine asByteArray.
promptActions keysAndValuesDo:[:expectedPrompt :promptAction |
-
+ "/ Transcript show:' looking for: '; showCR:expectedPrompt.
((lastLine endsWith:expectedPrompt)
or:[ (lastLine startsWith:expectedPrompt) ]) ifTrue:[
"/ ('found prompt; call ',promptAction printString) printCR.
@@ -610,7 +625,9 @@
ifFalse:[ each ]]].
collectedLines removeLast. "/ the prompt itself
promptAction value: collectedLines.
- ]
+ ] ifFalse:[
+ (lastLine includesString:'(gdb)') ifTrue:[self halt].
+ ].
].
].
].