Input and output

The R4RS states that ports represent input and output devices. However, it defines only ports which are attached to files. In STK, ports can also be attached to strings or to a external command input or output. String ports are similar to file ports, except that characters are read from (or written to) a string rather than a file. External command input or output ports are implemented with Unix pipes and are called pipe ports. A pipe port is created by specifying the command to execute prefixed with the string "| ". Specification of a pipe port can occur everywhere a file name is needed.





`=̀13`(ndexfile(index-entry "call-with-input-file" "tt" main )call-with-input-filestring proc)
procedure
`=̀13`(ndexfile(index-entry "call-with-output-file" "tt" main )call-with-output-filestring proc)
procedure
Note: if string starts with the two characters "| ", these procedures return a pipe port. Consequently, it is not possible to open a file whose name starts with those two characters.





`=̀13`(ndexfile(index-entry "call-with-input-string" "tt" main )call-with-input-stringstring proc)
procedure
behaves exactly as ndexfile(index-entry "call-with-input-file" "tt" aux )call-with-input-file except that the port passed to proc is the string port obtained from string.

$\Longrightarrow$
$\Longrightarrow$ unspecified error makeotherˆ`=̀13`


          gobblecr(call-with-input-string "123 456" (lambda (x) (read x))) 123





`=̀13`(ndexfile(index-entry "call-with-output-string" "tt" main )call-with-output-stringproc)
procedure
Proc should be a procedure of one argument. ndexfile(index-entry "Call-with-output-string" "tt" aux )Call-with-output-string calls proc with a freshly opened output string port. The result of this procedure is a string containing all the text that has been written on the string port. $\Longrightarrow$
$\Longrightarrow$ unspecified error makeotherˆ`=̀13`


          gobblecr(call-with-output-string   (lambda (x) (write 123 x) (display "Hello" x))) "123Hello"





`=̀13`(ndexfile(index-entry "input-port?" "tt" main )input-port?obj)
procedure
`=̀13`(ndexfile(index-entry "output-port?" "tt" main )output-port?obj)
procedure
Identical to R4RS.





`=̀13`(ndexfile(index-entry "input-string-port?" "tt" main )input-string-port?obj)
procedure
`=̀13`(ndexfile(index-entry "output-string-port?" "tt" main )output-string-port?obj)
procedure
Returns #t if obj is either an input or an output string port, otherwise returns #f.





`=̀13`(ndexfile(index-entry "current-input-port" "tt" main )current-input-port)
procedure
`=̀13`(ndexfile(index-entry "current-output-port" "tt" main )current-output-port)
procedure
Identical to R4RS.





`=̀13`(ndexfile(index-entry "current-error-port" "tt" main )current-error-port)
procedure
Returns the current default error port.





`=̀13`(ndexfile(index-entry "with-input-from-file" "tt" main )with-input-from-filestring thunk)
procedure
`=̀13`(ndexfile(index-entry "with-output-to-file" "tt" main )with-output-to-filestring thunk)
procedure
Identical to R4RS.

The following example uses a pipe port opened for reading. It permits to read all the lines produced by an external ls command (i.e. the ouput of the ls command is redirected to the Scheme pipe port).

$\Longrightarrow$
$\Longrightarrow$ unspecified error makeotherˆ`=̀13`


          gobblecr(with-input-from-file "| ls -ls"   (lambda ()    (do ((l (read-line) (read-line)))        ((eof-object? l))      (display l)      (newline))))

Hereafter is another example of Unix command redirection. This time, it is the standard input of the Unix command which is redirected. $\Longrightarrow$
$\Longrightarrow$ unspecified error makeotherˆ`=̀13`


          gobblecr(with-output-to-file "| mail root"  (lambda()    (format #t "A simple mail sent from STk\n")))





`=̀13`(ndexfile(index-entry "with-input-from-string" "tt" main )with-input-from-stringstring thunk)
procedure
A string port is opened for input from string. ndexfile(index-entry "Current-input-port" "tt" aux )Current-input-port is set to the port and thunk is called. When thunk returns, the previous default input port is restored. ndexfile(index-entry "With-input-from-string" "tt" aux )With-input-from-string returns the value yielded by thunk.

$\Longrightarrow$
$\Longrightarrow$ unspecified error makeotherˆ`=̀13`


          gobblecr(with-input-from-string "123 456" (lambda () (read)))   123





`=̀13`(ndexfile(index-entry "with-output-to-string" "tt" main )with-output-to-stringthunk)
procedure
A string port is opened for output. ndexfile(index-entry "Current-output-port" "tt" aux )Current-output-port is set to it and thunk is called. When the thunk returns, the previous default output port is restored. ndexfile(index-entry "With-output-to-string" "tt" aux )With-output-to-string returns the string containing all the text written on the string port.

$\Longrightarrow$
$\Longrightarrow$ unspecified error makeotherˆ`=̀13`


          gobblecr(with-output-to-string (lambda () (write 123) (write "Hello"))) "123Hello"





`=̀13`(ndexfile(index-entry "open-input-file" "tt" main )open-input-filefilename)
procedure
`=̀13`(ndexfile(index-entry "open-output-file" "tt" main )open-output-filefilename)
procedure
Identical to R4RS.

Note: if filename starts with the string "| ", these procedure return a pipe port. Consequently, it is not possible to open a file whose name starts with those two characters.





`=̀13`(ndexfile(index-entry "open-input-string" "tt" main )open-input-stringstring)
procedure
Returns an input string port capable of delivering characters from string.





`=̀13`(ndexfile(index-entry "open-output-string" "tt" main )open-output-string)
procedure
Returns an output string port capable of receiving and collecting characters.





`=̀13`(ndexfile(index-entry "get-output-string" "tt" main )get-output-stringport)
procedure
Returns a string containing all the text that has been written on the output string port. $\Longrightarrow$
$\Longrightarrow$ unspecified error makeotherˆ`=̀13`


          gobblecr(let ((p (open-output-string)))  (display "Hello, world" p)  (get-output-string p))         "Hello, world"





`=̀13`(ndexfile(index-entry "close-input-port" "tt" main )close-input-portport)
procedure
`=̀13`(ndexfile(index-entry "close-output-port" "tt" main )close-output-portport)
procedure
Identical to R4RS.





`=̀13`(ndexfile(index-entry "read" "tt" main )read)
procedure
`=̀13`(ndexfile(index-entry "read" "tt" main )readport)
procedure
`=̀13`(ndexfile(index-entry "read-char" "tt" main )read-char)
procedure
`=̀13`(ndexfile(index-entry "read-char" "tt" main )read-charport)
procedure
`=̀13`(ndexfile(index-entry "peek-char" "tt" main )peek-char)
procedure
`=̀13`(ndexfile(index-entry "peek-char" "tt" main )peek-charport)
procedure
`=̀13`(ndexfile(index-entry "char-ready?" "tt" main )char-ready?)
procedure
`=̀13`(ndexfile(index-entry "char-ready?" "tt" main )char-ready?port)
procedure
Identical to R4RS.





`=̀13`(ndexfile(index-entry "read-line" "tt" main )read-line)
procedure
`=̀13`(ndexfile(index-entry "read-line" "tt" main )read-lineport)
procedure
Reads the next line available from the input port port and returns it as a string. The terminating newline is not included in the string. If no more characters are available, an end of file object is returned. Port may be omitted, in which case it defaults to the value returned by ndexfile(index-entry "current-input-port" "tt" aux )current-input-port.





`=̀13`(ndexfile(index-entry "write" "tt" main )writeobj)
procedure
`=̀13`(ndexfile(index-entry "write" "tt" main )writeobj port)
procedure
`=̀13`(ndexfile(index-entry "display" "tt" main )displayobj)
procedure
`=̀13`(ndexfile(index-entry "display" "tt" main )displayobj port)
procedure
`=̀13`(ndexfile(index-entry "newline" "tt" main )newline)
procedure
`=̀13`(ndexfile(index-entry "newline" "tt" main )newlineport)
procedure
`=̀13`(ndexfile(index-entry "write-char" "tt" main )write-charchar)
procedure
`=̀13`(ndexfile(index-entry "write-char" "tt" main )write-charchar port)
procedure
Identical to R4RS.





`=̀13`(ndexfile(index-entry "format" "tt" main )formatport string obj1 obj2 … )
procedure
Writes the objs to the given port, according to the format string string. String is written literally, except for the following sequences:

Port can be a boolean, a port or a string port. If port is #t, output goes to the current output port; if port is #f, the output is returned as a string. Otherwise, the output is printed on the specified port. $\Longrightarrow$
$\Longrightarrow$ unspecified error makeotherˆ`=̀13`


          gobblecr(format #f "A test.")       "A test."(format #f "A ~a." "test")  "A test."(format #f "A ~s." "test")  "A \"test\"."





`=̀13`(ndexfile(index-entry "get-output-string" "tt" main )get-output-stringport)
procedure
Returns the string associated with the output string port. $\Longrightarrow$
$\Longrightarrow$ unspecified error makeotherˆ`=̀13`


          gobblecr(let ((p (open-output-string)))  (display "Hello, world" p)  (get-output-string p))         "Hello, world"





`=̀13`(ndexfile(index-entry "flush" "tt" main )flush)
procedure
`=̀13`(ndexfile(index-entry "flush" "tt" main )flushport)
procedure
Flushes the buffer associated with the given port. The port argument may be omitted, in which case it defaults to the value returned by ndexfile(index-entry "current-output-port" "tt" aux )current-output-port.





`=̀13`(ndexfile(index-entry "when-port-readable" "tt" main )when-port-readableport handler)
procedure
`=̀13`(ndexfile(index-entry "when-port-readable" "tt" main )when-port-readableport)
procedure
When port is ready for reading, handler, which must be a thunk, is called leaving the current evaluation suspended. When handler execution is terminated, normal evaluation is resumed at its suspension point. If the special value #f is provided as handler, the current handler for port is deleted. If a handler is provided, the value returned by ndexfile(index-entry "when-port-readable" "tt" aux )when-port-readable is undefined. Otherwise, it returns the handler currently associated to port.

The example below shows a simple usage of the ndexfile(index-entry "when-port-readable" "tt" aux )when-port-readable procedure: the command cmd is run with its output redirected in a pipe associated to the p Scheme port. $\Longrightarrow$
$\Longrightarrow$ unspecified error makeotherˆ`=̀13`


          gobblecr(define p (open-input-file "| cmd"))(when-port-readable p             (lambda()              (let (( l (read-line p)))                (if (eof-object? l)                    (begin                      ;; delete handler                      (when-port-readable p #f)                      ;; and close port                      (close-input-port p))                    (format #t "Line read: ~A\n" l)))))






`=̀13`(ndexfile(index-entry "when-port-writable" "tt" main )when-port-writableport handler)
procedure
`=̀13`(ndexfile(index-entry "when-port-writable" "tt" main )when-port-writableport)
procedure
When port is ready for writing, handler, which must be a thunk, is called leaving the current evaluation suspended. When handler execution is terminated, normal evaluation is resumed at its suspension point. If the special value #f is provided as handler, the current handler for port is deleted. If a handler is provided, the value returned by ndexfile(index-entry "when-port-writable" "tt" aux )when-port-writable is undefined. Otherwise, it returns the handler currently associated to port.





`=̀13`(ndexfile(index-entry "load" "tt" main )loadfilename)
procedure
Identical to R4RS.

Note: The load primitive has been extended to allow loading of object files, though this is not implemented on all systems 2. See [#!STkExtension!#] for more details.





`=̀13`(ndexfile(index-entry "try-load" "tt" main )try-loadfilename)
procedure
Tries to load the file named filename. If filename exists and is readable, it is loaded, and ndexfile(index-entry "try-load" "tt" aux )try-load returns #t. Otherwise, the result of the call is #f.





`=̀13`(ndexfile(index-entry "autoload" "tt" main )autoloadfilename symbol1 symbol2 … )
syntax
Defines symbols as autoload symbols associated to file filename. Fisrt evaluation of an autoload symbol will cause the loading of its associated file. Filename must provide a definition for the symbol which lead to its loading, otherwise an error is signaled.





`=̀13`(ndexfile(index-entry "autoload?" "tt" main )autoload?symbol)
procedure
Returns #t if symbol is an autoload symbol; returns #f otherwise.





`=̀13`(ndexfile(index-entry "require" "tt" main )requirestring)
procedure
`=̀13`(ndexfile(index-entry "provide" "tt" main )providestring)
procedure
`=̀13`(ndexfile(index-entry "provided?" "tt" main )provided?string)
procedure
ndexfile(index-entry "Require" "tt" aux )Require loads the file whose name is string if it was not previously ``provided''.ndexfile(index-entry "Provide" "tt" aux )Provide permits to store string in the list of already provided files. Providing a file permits to avoid subsequent loads of this file. ndexfile(index-entry "Provided?" "tt" aux )Provided? returns #t if string was already provided; it returns #f otherwise.





`=̀13`(ndexfile(index-entry "transcript-on" "tt" main )transcript-onfilename)
procedure
`=̀13`(ndexfile(index-entry "transcript-off" "tt" main )transcript-off)
procedure
Not implemented.





`=̀13`(ndexfile(index-entry "open-file" "tt" main )open-filefilename mode)
procedure
Opens the file whose name is filename with the specified mode. Mode must be ``r'' to open for reading or ``w'' to open for writing. If the file can be opened, open-file returns the port associated with the given file, otherwise it returns #f. Here again, the ``magic'' string "| `` permit to open a pipe port.





`=̀13`(ndexfile(index-entry "close-port" "tt" main )close-portport)
procedure
Closes port. If port denotes a string port, further reading or writing on this port is disallowed.





`=̀13`(ndexfile(index-entry "transcript-on" "tt" main )transcript-onfilename)
procedure
`=̀13`(ndexfile(index-entry "transcript-off" "tt" main )transcript-off)
procedure
Not implemented.





`=̀13`(ndexfile(index-entry "port->string" "tt" main )port->stringport)
procedure
`=̀13`(ndexfile(index-entry "port->list" "tt" main )port->listreader port)
procedure
`=̀13`(ndexfile(index-entry "port->string-list" "tt" main )port->string-listport)
procedure
`=̀13`(ndexfile(index-entry "port->sexp-list" "tt" main )port->sexp-listport)
procedure
Those procedures are utility for generally parsing input streams. Their specification has been stolen from scsh.

ndexfile(index-entry "Port->string" "tt" aux )Port->string reads the input port until eof, then returns the accumulated string. $\Longrightarrow$
$\Longrightarrow$ unspecified error makeotherˆ`=̀13`


          gobblecr(port->string (open-input-file "| (echo AAA; echo BBB)"))    "AAA\nBBB\n"(define exec         (lambda (command)           (call-with-input-file               (string-append "| " command) port->string)))

(exec "ls -l") a string which contains the result of "ls -l"

ndexfile(index-entry "Port->list" "tt" aux )Port->list uses the reader function to repeatedly read objects from port. Thes objects are accumulated in a list which is returned upon eof. $\Longrightarrow$
$\Longrightarrow$ unspecified error makeotherˆ`=̀13`


          gobblecr(port->list read-line (open-input-file "| (echo AAA; echo BBB)"))   ("AAA" "BBB")

ndexfile(index-entry "Port->string-list" "tt" aux )Port->string-list reads the input port line by line until eof, then returns the accumulated list of lines. This procedure is defined as $\Longrightarrow$
$\Longrightarrow$ unspecified error makeotherˆ`=̀13`


          gobblecr(define port->string-list (lambda (p)(port->list read-line p)))

ndexfile(index-entry "Port->sexp-list" "tt" aux )Port->sexp-list repeatedly reads data from the port until eof, then returns the accumulated list of items. This procedure is defined as $\Longrightarrow$
$\Longrightarrow$ unspecified error makeotherˆ`=̀13`


          gobblecr(define port->sexp-list (lambda (p) (port->list read p)))
For instance, the following expression gives the list of users currently connected on the machine running the STK interpreter. $\Longrightarrow$
$\Longrightarrow$ unspecified error makeotherˆ`=̀13`

          gobblecr(port->sexp-list (open-input-file "| users"))