;;; -*- Mode:gate; Fonts:(HL12 HL12I HL12B CPTFONTB HL12BI HL12B HL12I ) -*- =Node: Introduction to the IO System =Text: 3INTRODUCTION TO THE I/O SYSTEM* Zetalisp provides a powerful and flexible system for performing input and output to peripheral devices. Device independent I/O is generalized in the concept of an 1I/O stream*. A stream is a source or sink for data in the form of characters or integers; sources are called 1input streams* and sinks are called 1output streams*. A stream may be capable of use in either direction, in which case it is a 1bidirectional* stream. In a few unusual cases, it is useful to have a `stream' which supports neither input nor output; for example, opening a file with direction 2:probe* returns one (4(FILEACCESS-1)Opening and Closing File Streams*). Streams on which characters are transferred are called 1character streams*, and are used more often than 1binary streams*, which usually transfer integers of type 2(unsigned-byte 1n*)* for some 1n*. Streams automatically provide a modular separation between the program which implements the stream and the program which uses it, because streams obey a standard protocol. The stream protocol is a special case is based on the general message passing protocol: a stream operation is invoked by calling the stream as a function, with a first argument that is a keyword and identifies the I/O operation desired (such as, 2:tyi* to read a character) and additional arguments as that operation calls for them. The stream protocol consists of a particular set of operation names and calling conventions for them. It is documented in 4(IOSYSTEM-2)I/O Streams*. Many programs do not invoke the stream operations directly; instead, they call standard I/O functions which then invoke stream operations. This is done for two reasons: the functions may provide useful services, and they may be transportable to Common Lisp or Maclisp. Programs that use stream operations directly are not transportable outside Zetalisp. The I/O functions are documented in the first sections of this chapter. The generality of the Zetalisp I/O stream comes from the fact that I/O operations on it can invoke arbitrary Lisp code. For example, it would be very simple to implement a "morse code" stream that accepted character output and used 2beep* with appropriate pauses to `display' it. How to implement a stream is documented in 4(IOSYSTEM-2)Implementing Streams*, and the following sections. The most commonly used streams are windows, which read input from the keyboard and dispose of output by drawing on the screen, file streams, editor buffer streams which get input from the text in a buffer and insert output into the buffer, and string streams which do likewise with the contents of a string. Another unusual aspect of Lisp I/O is the ability to input and output general Lisp objects, represented as text. These are done using the 2read* and related functions and using 2print* and related functions. They are documented in chapter 4(READPRINT-0)Expression Input and Output*. =Node: 4Input Functions* =Text: 3INPUT FUNCTIONS* The input functions read characters, lines, or bytes from an input stream. This argument is called 1stream*. If omitted or 2nil*, the current value of 2*standard-input**. This is the ``default input stream'', which in simple use reads from the terminal keyboard. If the argument is 2t*, the current value of 2*terminal-io** is used; this is conventionally supposed to access ``the user's terminal'' and nearly always reads from the keyboard in processes belonging to windows. If the stream is an interactive one, such as the terminal, the input is echoed, and functions which read more than a single character allow editing as well. 2peek-char* echoes all of the characters that were skipped over if 2read-char* would have echoed them; the character not removed from the stream is not echoed either. When an input stream has no more data to return, it reports end of file. Each stream input operation has a convention for how to do this. The input functions accept an argument 1eof-option* or two arguments 1eof-error* and 1eof-value* to tell them what to do if end of file is encountered instead of any input. The functions that take two 1eof-* arguments are the Common Lisp ones. For them, end of file is an error if 1eof-error* is non-2nil* or if it is unsupplied. If 1eof-error* is 2nil*, then the function returns 1eof-value* at end of file. The functions which have one argument called 1eof-option* are from Maclisp. End of file causes an error if the argument is not supplied. Otherwise, end of file causes the function to return the argument's value. Note that an 1eof-option* of 2nil* means to return 2nil* if the end of the file is reached; it is 1not* equivalent to supplying no 1eof-option*. 3sys:end-of-file* (error) 1Condition* All errors signaled to report end of file possess this condition name. The 2:stream* operation on the condition instance returns the stream on which end of file was reached. =Node: 4String Input Functions* =Text: 3STRING INPUT FUNCTIONS read-line* &optional 1stream* 1(eof-errorp* 1t)* 1eof-value* 1ignore* 1options* Reads a line of text, terminated by a 2Return*. It returns the line as a character string, 1without* the 2Return* character that ended the line. The argument 1ignore* must be accepted for the sake of the Common Lisp specifications but it is not used. This function is usually used to get a line of input from the user. If rubout processing is happening, then 1options* is passed as the list of options to the rubout handler (see 4(IOSYSTEM-4)Rubout Handling*). There is a second value, 2t* if the line was terminated by end of file. 3readline* &optional 1stream* 1eof-option* 1options* Like 2read-line* but uses the Maclisp convention for specifying what to do about end of file. This function can take its first two arguments in the other order, for Maclisp compatibility only; see the note in 4(IOSYSTEM-1)Maclisp Compatibility Input Functions*. 3readline-trim* &optional 1stream* 1eof-option* 1options* This is like 2readline* except that leading and trailing spaces and tabs are discarded from the value before it is returned. 3readline-or-nil* &optional 1stream* 1eof-option* 1options* Like 2readline-trim* except that 2nil* is returned if the line is empty or all blank. 3read-delimited-string* &optional 1delimiter* 1stream* 1eof* 1rubout-handler-options* 1buffer-size* Reads input from 1stream* until a delimiter character is reached, then returns as a string all the input up to but not including the delimiter. 1delimiter* is either a character or a list of characters which all serve as delimiters. It defaults to the character 2End*. 1stream* defaults to the value of 2*standard-input**. If 1eof* is non-2nil*, then end of file on attempting to read the first character is an error. Otherwise it just causes an empty string to be returned. End of file once at least one character has been read is never an error but it does cause the function to return all the input so far. Input is done using rubout handling and echoing if stream supports the 2:rubout-handler* operation. In this case, 1rubout-handler-options* are passed as the options argument to that operation. 1buffer-size* specifies the size of string buffer to allocate initially. The second value returned is 2t* if input ended due to end of file. The third value is the delimiter character which terminated input, or 2nil* if input terminated due to end of file. This character is currently represented as a fixnum, but perhaps someday will be a character object instead. =Node: 4Character-Level Input Functions* =Text: 3CHARACTER-LEVEL INPUT FUNCTIONS read-char* &optional 1stream* 1(eof-errorp* 1t)* 1eof-value* Reads a character from 1stream* and returns it as a character object. End of file is an error if 1eof-errorp* is non-2nil*; otherwise, it causes 2read-char* to return 1eof-value*. This uses the 2:tyi* stream operation. 3read-byte* 1stream* &optional 1(eof-errorp* 1t)* 1eof-value* Like 2read-char* but returns an integer rather than a character object. In strict Common Lisp, only 2read-char* can be used on character streams and only 2read-byte* can be used on binary streams. 3read-char-no-hang* &optional 1stream* 1(eof-errorp* 1t)* 1eof-value* Similar but returns 2nil* immediately when no input is available on an interactive stream. Uses the 2:tyi-no-hang* stream operation (). 3unread-char* 1char* &optional 1stream* Puts 1char* back into 1stream* so that it will be read again as the next input character. 1char* must be the same character that was read from stream most recently. It may not work to unread two characters in a row before reading again. Uses the 2:untyi* stream operation (). 3peek-char* 1peek-type* &optional 1stream* 1(eof-errorp* 1t)* 1eof-value* If 1peek-type* is 2nil*, this is like 2read-char* except leaves the character to be read again by the next input operation. If 1peek-type* is 2t*, skips whitespace characters and peeks at the first nonwhitespace character. That character is the value, and is also left to be reread. If 1peek-type* is a character, reads input until that character is seen. That character is unread and also returned. 3listen* &optional 1stream* 2t* if input is now available on 1stream*. Uses the 2:listen* operation (). 3clear-input* &optional 1stream* Discards any input now available on 1stream*, if it is an interactive stream. Uses the 2:clear-input* stream operation (). =Node: 4Maclisp Compatibility Input Functions* =Text: 3MACLISP COMPATIBILITY INPUT FUNCTIONS* These functions accept an argument 1eof-option* to tell them what to do if end of file is encountered instead of any input. End of file signals an error if the argument is not supplied. Otherwise, end of file causes the function to return the argument's value. Note that an 1eof-option* of 2nil* means to return 2nil* if the end of the file is reached; it is 1not* equivalent to supplying no 1eof-option*. The arguments 1stream* and 1eof-option* can also be given in the reverse order for compatibility with old Maclisp programs. The functions attempt to figure out which way they were called by seeing whether each argument is a plausible stream. Unfortunately, there is an ambiguity with symbols: a symbol might be a stream and it might be an eof-option. If there are two arguments, one being a symbol and the other being something that is a valid stream, or only one argument, which is a symbol, then these functions interpret the symbol as an eof-option instead of as a stream. To force them to interpret a symbol as a stream, give the symbol an 2si:io-stream-p* property whose value is 2t*. 3tyi* &optional 1stream* 1eof-option* Reads one character from 1stream* and returns it. The character is echoed if 1stream* is interactive, except that 2Rubout* is not echoed. The 2Control*, 2Meta*, etc. shifts echo as 2C-*, 2M-*, etc. The 2:tyi* stream operation is preferred over the 2tyi* function for some purposes. Note that it does not echo. See 4(IOSYSTEM-2)Standard Input Stream Operations*. (This function can take its arguments in the other order, for Maclisp compatibility only; see the note above.) 3readch* &optional 1stream* 1eof-option* Like 2tyi* except that instead of returning a fixnum character, it returns a symbol whose print name is the character. The symbol is interned in the current package. This is just Maclisp's version of character object. (This function can take its arguments in the other order, for Maclisp compatibility only; see the note above.) This function is provided only for Maclisp compatibility, since in Zetalisp never uses symbols to represent characters in this way. 3tyipeek* &optional 1peek-type* 1stream* 1eof-option* This function is provided mainly for Maclisp compatibility; the 2:tyipeek* stream operation is usually clearer (see 4(IOSYSTEM-2)Standard Input Stream Operations*). What 2tyipeek* does depends on the 1peek-type*, which defaults to 2nil*. With a 1peek-type* of 2nil*, 2tyipeek* returns the next character to be read from 1stream*, without actually removing it from the input stream. The next time input is done from 1stream* the character will still be there; in general, 2(= (tyipeek) (tyi))* is 2t*. If 1peek-type* is a fixnum less than 1000 octal, then 2tyipeek* reads characters from 1stream* until it gets one equal to 1peek-type*. That character is not removed from the input stream. If 1peek-type* is 2t*, then 2tyipeek* skips over input characters until the start of the printed representation of a Lisp object is reached. As above, the last character (the one that starts an object) is not removed from the input stream. The form of 2tyipeek* supported by Maclisp in which 1peek-type* is a fixnum not less than 1000 octal is not supported, since the readtable formats of the Maclisp reader and the Zetalisp reader are quite different. Characters passed over by 2tyipeek* are echoed if 1stream* is interactive. =Node: 4Interactive Input with Prompting* =Text: 3INTERACTIVE INPUT WITH PROMPTING prompt-and-read* 1type-of-parsing* 1format-string* &rest 1format-args* Reads some sort of object from 2*query-io**, parsing it according to 1type-of-parsing*, and prompting by calling 2format* using 1format-string* and 1format-args*. 1type-of-parsing* is either a keyword or a list starting with a keyword and continuing with a list of options and values, whose meanings depend on the keyword used. Most keywords specify reading a line of input and parsing it in some way. The line can be terminated with 2Return* or 2End*. Sometimes typing just 2End* has a special meaning. The keywords defined are 2:eval-sexp* 2prompt-and-read*This keyword directs 2prompt-and-read* to accept a Lisp expression. It is evaluated, and the value is returned by 2prompt-and-read*. If the Lisp expression is not a constant or quoted, the user is asked to confirm the value it evaluated to. A default value can be specified with an option, as in 3(:eval-sexp :default 1default*)* Then, if the user types 2Space*, 2prompt-and-read* returns the 1default* as the first value and 2:default* as the second value. 2:eval-sexp-or-end* 2prompt-and-read*Synonymously direct 2prompt-and-read* to accept a Lisp expression or just the character 2End*. If 2End* is typed, 2prompt-and-read* returns 2nil* as its first value and 2:end* as its second value. Otherwise, things proceed as for 2:eval-sexp*. A default value is allowed, as in 2:eval-sexp*. 2:read* 2prompt-and-read*Synonymously direct 2prompt-and-read* to read an object and return it, with no evaluation. 2:expression-or-end* Is like 2:expression* except that the user is also allowed to type just 2End*. If he does so, 2prompt-and-read* returns the two values 2nil* and 2:end*. 2:number* Directs 2prompt-and-read* to read and return a number. It insists on getting a number, forcing the user to rub out anything else. Additional features can be specified with options: 3(:number :input-radix 1radix* :or-nil 1nil-ok-flag*)* parses the number using radix 1radix* if the number is a rational. (By default, the ambient radix is used). If 1nil-ok-flag* is non-2nil*, then the user is also permitted to type just 2Return* or 2End*, and then 2nil* is returned. 2:decimal-number* 2prompt-and-read* 2prompt-and-read*Abbreviations for 3(:number :input-radix 10)* 3(:number :or-nil t)* 3(:number :input-radix 10 :or-nil t)* 2:date* Directs 2prompt-and-read* to read a date and time, terminated with 1Return* or 2End*, and return it as a universal time (see 4(DATETIME-1)Getting and Setting the Time*). It allows several options: 3(:date :never-p 1never-ok* :past-p 1past-required*)* If 1past-required* is non-2nil*, the date must be before the present time, or the user must rub out and use a different date. If 1never-ok* is non-2nil*, the user may also type ``never''; then 2nil* is returned. 2:date-or-never* 2prompt-and-read* 2prompt-and-read*Abbreviations for 3(:date :never-p t)* 3(:date :past-p t)* 3(:date :never-p t :past-p t)* 2:character* Directs 2prompt-and-read* to read a single character and return a character object representing it. 2:string* Directs 2prompt-and-read* to read a line and return its contents as a string, using 2readline*. 2:string-or-nil* Directs 2prompt-and-read* to read a line and return its contents as a string, using 2readline-trim*. In addition, if the result would be empty, 2nil* is returned instead of the empty string. 2:string-list* Like 2:string-trim* but regards the line as a sequence of input strings separated by commas. Each substring between commas is trimmed, and a list of the strings is returned. 2:keyword-list* Like 2:string-list* but converts each string to a keyword by interning it in the 2keyword* package. The value is therefore a list of keywords. 2:font-list* Like 2:string-list* but converts each string to a font name by interning it in the 2fonts* package. The symbols must already exist in that package or the user is required to retype the input. 2:delimited-string* Directs 2prompt-and-read* to read a string terminated by specified delimiters. With 3(:delimited-string :delimiter 1delimiter-list** 3 :buffer-size 1size*)* you can specify a list of delimiter characters and an initial size for the buffer. The list defaults to 2(#\end)* and the size to 100. The work is done by 2read-delimited-string* (4(IOSYSTEM-1)String Input Functions*). The delimiters and size are passed to that function. 2:delimited-string-or-nil* Like 2:delimited-string* except that 2nil* is returned instead of the empty string if the first character read is a delimiter. 2:host* Directs 2prompt-and-read* to read a line and interpret the contents as a network host name. The value returned is the host, looked up using 2si:parse-host* (4(FILENAMES-4)Parsing Hostnames*). An option is defined: 3(:host :default 1default-name* :chaos-only 1chaos-only*)* If the line read is empty, the host named 1default-name* is used. If 1chaos-only* is non-2nil*, only hosts on the Chaosnet are permitted input. 2:host-list* Like 2:host* but regards the line as a sequence of host names separated by commas. Each host name is looked up as in 2:host* and a list of the resulting hosts is returned. 2:pathname-host* Like 2:host* but uses 2fs:get-pathname-host* to look up the host object from its name (4(FILENAMES-4)Parsing Hostnames*). Thus, you find hosts that can appear in pathnames rather than hosts that are on the network. 2:pathname* Directs 2prompt-and-read* to read a line and parse it as a pathname, merging it with the defaults. If the line is empty, the default pathname is used. These options are defined: 3(:pathname :defaults 1defaults-alist-or-pathname** 3 :version 1default-version*)* uses 1defaults-alist-or-pathname* as the 1defaults* argument to 2fs:merge-pathname-defaults*, and 1default-version* as the 1version* argument to it. 2:pathname-or-nil* Is like 2:pathname*, but if the user types just 2End* it is interpreted as meaning ``no pathname'' rather than ``use the default''. Then 2nil* is returned. 2:pathname-list* Like 2:pathname* but regards the line as a sequence of filenames separated by commas. Each filename is parsed and defaulted and a list of the resulting pathnames is returned. 2:fquery* Directs 2prompt-and-read* to query the user for a fixed set of alternatives, using 2fquery*. 1type-of-parsing* should always be a list, whose car is 2:fquery* and whose cdr is a list to be passed as the list of options (2fquery*'s first argument). Example: 3(prompt-and-read `(:fquery * 3 . ,format:y-or-p-options)* 3 "Eat it? ")* is equivalent to 3(y-or-n-p "Eat it? ")* This keyword is most useful as a way to get to 2fquery* when going through an interface defined to call 2prompt-and-read*. =Node: 4Output Functions* =Text: 3OUTPUT FUNCTIONS* These functions all take an optional argument called 1stream*, which is where to send the output. If unsupplied 1stream* defaults to the value of 2*standard-output**. If 1stream* is 2nil*, the value of 2*standard-output** (i.e. the default) is used. If it is 2t*, the value of 2*terminal-io** is used (i.e. the interactive terminal). This is all more-or-less compatible with Maclisp, except that instead of the variable 2*standard-output** Maclisp has several variables and complicated rules. For detailed documentation of streams, refer to 4(IOSYSTEM-2)I/O Streams*. For 2print* and the other expression output functions, see 4(READPRINT-3)Expression Output Functions*. 3write-char* 1char* &optional 1stream* 3tyo* 1char* &optional 1stream* Outputs 1char* to 1stream* (using 2:tyo*). 1char* may be an integer or a character object; in the latter case, it is converted to an integer before the 2:tyo*. 3write-byte* 1number* &optional 1stream* Outputs number to stream using 2:tyo*. In strict Common Lisp, output to binary streams can be done only with 2write-byte* and output to character streams requires 2write-char*. In fact, the two functions are identical on the Lisp Machine. 3write-string* 1string* &optional 1stream* &key 1(start* 301)** 1end* Outputs 1string* (or the specified portion of it) to 1stream*. 3write-line* 1string* &optional 1stream* &key 1(start* 301)** 1end* Outputs 1string* (or the specified portion) to 1stream*, followed by a 2Return* character. 3fresh-line* &optional 1stream* Outputs a 2Return* character to 2stream* unless either 2(1)* nothing has been output to 1stream* yet, or 2(2)* the last thing output was a 2Return* character, or 2(3)* 1stream* does not remember what previous output there has been. This uses the 2:fresh-line* stream operation. The value is 2t* if a 2Return* is output, 2nil* if nothing is output. 3force-output* &optional 1stream* Causes 1stream*'s buffered output, if any, to be transmitted immediately. This uses the 2:force-output* stream operation. 3finish-output* &optional 1stream* Causes 1stream*'s buffered output, if any, to be transmitted immediately, and waits until that is finished. This uses the 2:finish* stream operation. 3clear-output* &optional 1stream* Discards any output buffered in 1stream*. This uses the 2:clear-output* stream operation. 3terpri* &optional 1stream* Outputs a 2Return* character to 1stream*. It returns 2t* for Maclisp compatibility. It is wise not to depend on the value 2terpri* returns. 3cli:terpri* &optional 1stream* Outputs a 2Return* character to 1stream*. Returns 2nil* to meet Common Lisp specifications. It is wise not to depend on the value 2cli:terpri* returns. The 2format* function (see 4(IOSYSTEM-3)The Format Function*) is very useful for producing nicely formatted text. It can do anything any of the above functions can do, and it makes it easy to produce good looking messages and such. 2format* can generate a string or output to a stream. 3stream-copy-until-eof* 1from-stream* 1to-stream* &optional 1leader-size* 2stream-copy-until-eof* inputs characters from 1from-stream* and outputs them to 1to-stream*, until it reaches the end of file on the 1from-stream*. For example, if 2x* is bound to a stream for a file opened for input, then 2(stream-copy-until-eof x *terminal-io*)* prints the file on the console. If 1from-stream* supports the 2:line-in* operation and 1to-stream* supports the 2:line-out* operation, then 2stream-copy-until-eof* uses those operations instead of 2:tyi* and 2:tyo*, for greater efficiency. 1leader-size* is passed as the argument to the 2:line-in* operation. 3beep* &optional 1beep-type* 1(stream* 1*terminal-io*)* This function is intended to attract the user's attention by causing an audible beep, or flashing the screen, or something similar. If the stream supports the 2:beep* operation, then this function sends it a 2:beep* message, passing 1beep-type* along as an argument. Otherwise it just causes an audible beep on the terminal. 1beep-type* is a keyword which explains the significance of this beep. Users can redefine 2beep* to make different noises depending on the beep type. The defined beep types are: 2zwei:converse-problem* Used for the beep that is done when Converse is unable to send a message. 2zwei:converse-message-received* Used for the beeps done when a Converse message is received. 2zwei:no-completion* Used when you ask for completion in the editor and the string does not complete. 2tv:notify* Used for the beep done when you get a notification that cannot be printed on the selected window. 2fquery* Used for the beep done by 2yes-or-no-p* or by 2fquery* with the 2:beep* option specified. 2supdup:terminal-bell* Used for the beep requested by the remote host being used through a Supdup window. 2nil* Used whenever no other beep type applies. The 2:beep* operation is described on . 3cursorpos* &rest 1args* This function exists primarily for Maclisp compatibility. Usually it is preferable to send the appropriate messages (see the Window System manual). 2cursorpos* normally operates on the 2*standard-output** stream; however, if the last argument is a stream or 2t* (meaning 2*terminal-io**) then 2cursorpos* uses that stream and ignores it when doing the operations described below. 2cursorpos* only works on streams that are capable of these operations, such as windows. A stream is taken to be any argument that is not a number and not a symbol, or that is a symbol other than 2nil* with a name more than one character long. 2(cursorpos) => (1line* . 1column*)*, the current cursor position. 2(cursorpos 1line* 1column*)* moves the cursor to that position. It returns 2t* if it succeeds and 2nil* if it doesn't. 2(cursorpos 1op*)* performs a special operation coded by 1op*, and returns 2t* if it succeeds and 2nil* if it doesn't. 1op* is tested by string comparison, it is not a keyword symbol and may be in any package. 2f* Moves one space to the right. 2b* Moves one space to the left. 2d* Moves one line down. 2u* Moves one line up. 2t* Homes up (moves to the top left corner). Note that 2t* as the last argument to 2cursorpos* is interpreted as a stream, so a stream 1must* be specified if the 2t* operation is used. 2z* Home down (moves to the bottom left corner). 2a* Advances to a fresh line. See the 2:fresh-line* stream operation. 2c* Clears the window. 2e* Clear from the cursor to the end of the window. 2l* Clear from the cursor to the end of the line. 2k* Clear the character position at the cursor. 2x* 2b* then 2k*.