I'm trying to write my own transcripting functions, but it's not working -.-
What I want is to have a custom repl "front-end" function that reads from stdin and passes it to the real REPL and also prints it to the stdout and to my transcript file. Also, the output from the real REPL will be printed on both the stdout and transcript files.
Here's a diagram to help illustrate what I'm thinking of (ascii art):
------- -------- ----------------- | Stdin | | Stdout | | transcript-port | ------- -------- ----------------- | /|\ /|\ | | | |/ \ / (proc input-splitter) ______________________/ | | | | | (proc output-splitter) | /|\ |_____________________________ | | | | |/ |/ | ----------------- ---------------------- | repl-input-port | | output-splitter-port | ----------------- ---------------------- \ /|\ \ | \ / | / |/ / (proc ##repl)
The problem is that (when compiled as a single program, which is what I want) the output seems to be buffered, even though I call force-output, and even if I open the port with buffering disabled.
When run from the REPL however, nothing whatsoever gets sent to the transcript file, however the fake repl displays to stdout just fine.
Here's a sample program:
;;========================================== Start (define transcript-port (open-output-file (list path: "transcript-test-output" create: 'maybe buffering: #f append: #f)))
(define (my-repl) (define stdout (current-output-port)) ; just take the current input and (define stdin (current-input-port)) ; output ports. (define repl-input-port (open-string)) (define output-splitter-port (open-string))
(define (input-splitter) ; Sends stdin to the repl and the output splitter. (define (loop s) (display "input-split") (display s repl-input-port) (force-output repl-input-port) (display s output-splitter-port) (force-output output-splitter-port) (loop (read-line stdin))) (loop (read-line stdin)))
(define (output-splitter) ; Sends output to the transcript and stdout. (define (loop s) (display "output-split") (display s transcript-port) (force-output transcript-port) (display s stdout) (force-output stdout) (loop (read-line output-splitter-port))) (loop (read-line output-splitter-port)))
; Start splitter procs. (thread-start! (make-thread input-splitter 'programmer-interface-input-splitter)) (thread-start! (make-thread output-splitter 'programmer-interface-output-splitter))
; Start real repl. (set! ##stdio/console-repl-channel (##make-repl-channel-ports repl-input-port output-splitter-port)) (##repl)
(close-port repl-input-port) (close-port output-splitter-port))
(my-repl) ;;=========================================== End
Any idea what's wrong?
TJ
Afficher les réponses par date
On 1/28/07, TJ tjay.dreaming@gmail.com wrote:
I'm trying to write my own transcripting functions, but it's not working -.-
Never mind, I noticed the logic was all wrong fixed it. Chalk it up to sleepy brain cells at night -.-
TJ
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 28-Jan-07, at 9:41 PM, TJ wrote:
Never mind, I noticed the logic was all wrong fixed it. Chalk it up to sleepy brain cells at night -.-
For completeness, could you send the correct code?
Marc
On 1/29/07, Marc Feeley feeley@iro.umontreal.ca wrote:
...
For completeness, could you send the correct code?
Marc
Sure thing.
The flow diagram I sent previously was wrong. The "input-splitter" procedure should send input from stdin to "repl-input-port" and "transcript_port", not to "repl-input-port" and "output-splitter-port"
;========================================== Start
; Works fine as a standalone executable. Just tried it from the Gambit REPL ; and it doesn't seem to work there.
(define transcript-port (open-output-file (list path: "transcript-test-output" create: 'maybe buffering: #f append: #f)))
(define (my-repl) (define stdout (current-output-port)) ; just take the current input and (define stdin (current-input-port)) ; output ports. (define repl-input-port (open-string '(buffering: #f))) (define output-splitter-port (open-string '(buffering: #f)))
(define (input-splitter) ; Sends stdin to the repl and the output splitter. (define (loop s) (display s repl-input-port) (newline repl-input-port) (force-output repl-input-port) (display s transcript-port) (newline transcript-port) (force-output transcript-port) (loop (read-line stdin))) (loop (read-line stdin)))
(define (output-splitter) ; Sends output to the transcript and stdout. (define (loop s) ; Print semicolon so results show up as comments and I can (load ...) ; the transcript file directly. (display "; " transcript-port) (display s transcript-port) (newline transcript-port) (force-output transcript-port) (display "; " stdout) (display s stdout) (newline stdout) (force-output stdout) (loop (read-line output-splitter-port))) (loop (read-line output-splitter-port)))
; Start splitter procs. (thread-start! (make-thread input-splitter 'programmer-interface-input-splitter)) (thread-start! (make-thread output-splitter 'programmer-interface-output-splitter))
; Start real repl. (set! ##stdio/console-repl-channel (##make-repl-channel-ports repl-input-port output-splitter-port)) (##repl)
(close-port repl-input-port) (close-port output-splitter-port))
(my-repl)
;============================================ End
Cheers,
TJ
On 1/29/07, TJ tjay.dreaming@gmail.com wrote:
On 1/29/07, Marc Feeley feeley@iro.umontreal.ca wrote:
...
For completeness, could you send the correct code?
Marc
Sure thing.
... new code ...
One consequence of using read-line on the repl's output port is that the repl prompt (the "> ") gets printed on the same line as the results of the expression. This serves my purposes just fine, though, so I didn't clean it up.
TJ