class: TerminalSession
class definition
added:7 methods
changed:
#checkForPrompt:count:
#readAnyAvailableData
--- a/TerminalSession.st Fri Aug 16 16:32:49 2013 +0200
+++ b/TerminalSession.st Fri Aug 16 17:03:36 2013 +0200
@@ -4,7 +4,8 @@
instanceVariableNames:'inStream outStream errStream readerProcess shellPid shellCommand
shellDirectory readerDelay pluggableCheckBeforeReadAction
pluggableProcessInputAction execFDArray stxToStdinPipe
- stdOutToStxPipe pty ptyName terminatedAction'
+ stdOutToStxPipe pty ptyName terminatedAction collectedOutput
+ expectedPrompt promptAction'
classVariableNames:'Debug'
poolDictionaries:''
category:'Views-TerminalViews'
@@ -350,6 +351,10 @@
!TerminalSession methodsFor:'misc'!
+collectedOutput
+ ^ collectedOutput
+!
+
defineWindowSizeLines:numberOfLines columns:numberOfColumns
| delta prevNumCols prevNumLines|
@@ -385,6 +390,65 @@
"Modified: / 5.5.1999 / 19:45:09 / cg"
!
+onPrompt:aString do:aBlock
+ "remember what to do, when a prompt arrives;
+ notice: will only start checking for prompt, when startCollectingOutput
+ has been called."
+
+ promptAction := aBlock.
+ expectedPrompt := aString.
+!
+
+outputFromAction:aBlock prompt:prompt timeout:seconds
+ "evaluate aBlock and wait for the prompt.
+ return gdb output as string collection"
+
+ |sema output|
+
+ sema := Semaphore new.
+ self startCollectingOutput.
+ self onPrompt:prompt do:[:strings | output := strings. sema signal. ].
+
+ aBlock value.
+
+ (sema waitWithTimeout:seconds) isNil ifTrue:[
+ self information:'Error: command timeout.'.
+ self stopCollectingOutput.
+ self onPrompt:nil do:nil.
+ AbortOperationRequest raise.
+ ].
+ output first isEmpty ifTrue:[
+ "/ self halt.
+ output := output copyFrom:2
+ ].
+ ^ output
+!
+
+outputFromCommand:aCommand prompt:prompt timeout:seconds
+ "return a command's output as string collection"
+
+ |output firstLine|
+
+ output := self
+ outputFromAction:[ self sendLine:aCommand ]
+ prompt:prompt timeout:seconds.
+
+ "/ the first line of output is the echo
+ firstLine := output first withoutLeadingSeparators.
+ firstLine ~= aCommand ifTrue:[
+ OperatingSystem isMSWINDOWSlike ifFalse:[
+ "/ sigh - it is sometimes truncated (to be investigated)
+ (aCommand startsWith:firstLine) ifTrue:[
+ self halt.
+ ^ output.
+ ].
+ self halt.
+ ].
+ ^ output.
+ ].
+ ^ output copyFrom:2
+!
+
sendInterruptSignal
"send an INT-signal to the shell (UNIX only)"
@@ -401,10 +465,52 @@
shellPid notNil ifTrue:[
OperatingSystem sendSignal:(OperatingSystem sigKILL) to:shellPid negated.
]
+!
+
+startCollectingOutput
+ collectedOutput := '' writeStream.
+!
+
+stopCollectingOutput
+ collectedOutput := nil.
! !
!TerminalSession methodsFor:'reader process'!
+collectOutputAndCheckForPrompt:buffer count:n
+ |string collectedString collectedLines i lastLine|
+
+ collectedOutput isNil ifTrue:[^ self].
+
+ string := buffer copyTo:n.
+ collectedOutput nextPutAll:string.
+
+ promptAction notNil ifTrue:[
+ collectedString := collectedOutput contents.
+
+ i := collectedString lastIndexOf:Character lf.
+ i ~= 0 ifTrue:[
+ lastLine := (collectedString copyFrom:i+1) withoutTrailingSeparators.
+ ((lastLine endsWith:expectedPrompt)
+ or:[ (lastLine startsWith:expectedPrompt) ]) ifTrue:[
+ "/ ('found prompt; call ',promptAction printString) printCR.
+
+ "/ perform the promptaction
+ collectedLines := collectedString asStringCollection
+ collect:[:each |
+ (each endsWith:String crlf)
+ ifTrue:[ each copyButLast:2 ]
+ ifFalse:[
+ (each endsWith:Character return)
+ ifTrue:[ each copyButLast:1 ]
+ ifFalse:[ each ]]].
+ collectedLines removeLast. "/ the prompt itself
+ promptAction value: collectedLines.
+ ]
+ ].
+ ].
+!
+
readAnyAvailableData
"read data from the stream,
and sends me #processInput:n: events if something arrived.
@@ -422,6 +528,9 @@
] do:[
n := outStream nextAvailableBytes:bufferSize into:buffer startingAt:1.
n > 0 ifTrue:[
+ collectedOutput notNil ifTrue:[
+ self collectOutputAndCheckForPrompt:buffer count:n
+ ].
pluggableProcessInputAction notNil ifTrue:[
pluggableProcessInputAction value:buffer value:n.
]
@@ -511,11 +620,11 @@
!TerminalSession class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic2/TerminalSession.st,v 1.8 2013-08-16 12:39:29 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic2/TerminalSession.st,v 1.9 2013-08-16 15:03:36 cg Exp $'
!
version_CVS
- ^ '$Header: /cvs/stx/stx/libbasic2/TerminalSession.st,v 1.8 2013-08-16 12:39:29 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic2/TerminalSession.st,v 1.9 2013-08-16 15:03:36 cg Exp $'
! !