[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Zetalisp represents characters as fixnums. The Lisp Machine's mapping between these numbers and the characters is listed here. The mapping is similar to ASCII, but somewhat modified to allow the use of the so-called SAIL extended graphics, while avoiding certain ambiguities present in ITS. For a long time ITS treated the Backspace, Control-H, and Lambda keys on the keyboard identically as character code 10 octal; this problem is avoided from the start in the Lisp Machine's mapping.
It is worth pointing out that although the Zetalisp character set is different from the pdp-10 character set, when files are transferred between Lisp Machines and pdp-10's the characters are automatically converted. Details of the mapping are explained below.
Fundamental characters are eight bits wide. Those less than 200 octal (with the 200 bit off) and only those are printing graphics; when output to a device they are assumed to print a character and move the "cursor" one character position to the right. (All software provides for variable-width fonts, so the term "character position" shouldn't be taken too literally.)
Characters in the range of 200 to 236 inclusive are used for special characters. Character 200 is a "null character", which does not correspond to any key on the keyboard. The null character is not used for anything much; fasload uses it internally. Characters 201 through 236 correspond to the special function keys on the keyboard such as Return and Call. The remaining characters are reserved for future expansion.
It should never be necessary for a user or a source program to know these numerical values. Indeed, they are likely to be changed in the future. There are symbolic names for all characters; see below.
Most of the special characters do not normally appear in files (although it is not forbidden for files to contain them). These characters exist mainly to be used as "commands" from the keyboard.
A few special characters, however, are "format effectors" which are just as legitimate as printing characters in text files. The names and meanings of these characters are:
Return
Page
Tab
The space character is considered to be a printing character whose printed image happens to be blank, rather than a format effector.
In some contexts, a fixnum can hold both a character code and a font number for that character. The following byte specifiers are defined:
Characters read in from the keyboard include a character code and control bits. A character cannot contain both a font number and control bits, since these data are both stored in the same bits. The following byte specifiers are provided: .setq %%kbd page
This bit is also set if Control and/or Meta is typed in combination with Shift and a letter. Shift is much easier than Hyper to reach with the left hand.
The following fields are used by some programs that encode signals from the mouse in a the format of a character. Refer to the window system documentation for an explanation of how these characters are generated.
When any of the control bits (Control, Meta, Super, or Hyper) is set in conjunction with a letter, the letter will always be upper-case. The character codes which consist of a lower-case letter and non-zero control bits are "holes" in the character set which are never used for anything. Note that when Shift is typed in conjuction with Control and/or Meta and a letter, it means Hyper rather than Shift.
Since the control bits are not part of the fundamental 8-bit character codes, there is no way to express keyboard input in terms of simple character codes. However, there is a convention which the relevant programs accept for encoding keyboard input into a string of characters: if a character has its Control bit on, prefix it with an Alpha. If a character has its Meta bit on, prefix it with a Beta. If a character has both its Control and Meta bits on, prefix it with an Epsilon. If a character has its Super bit on, prefix it with a Pi. If a character has its Hyper bit on, prefix it with a Lambda. To get an Alpha, Beta, Epsilon, Pi, Lambda, or Equivalence into the string, quote it by prefixing it with an Equivalence.
.setq character-set-differences page
When characters are written to a file server computer that normally uses the ASCII character set to store text, Lisp Machine characters are mapped into an encoding that is reasonably close to an ASCII transliteration of the text. When a file is written, the characters are converted into this encoding, and the inverse transformation is done when a file is read back. No information is lost. Note that the length of a file, in characters, will not be the same measured in original Lisp Machine characters as it will measured in the encoded ASCII characters. In the currently implemented ASCII file servers, the following encoding is used. All printing characters and any characters not mentioned explicitly here are represented as themselves. Codes 010 (lambda), 011 (gamma), 012 (delta), 014 (plus-minus), 015 (circle-plus), 177 (integral), 200 through 207 inclusive, 213 (delete/vt), and 216 and anything higher, are preceeded by a 177; that is, 177 is used as a "quoting character" for these codes. Codes 210 (overstrike), 211 (tab), 212 (line), and 214 (page), are converted to their ASCII cognates, namely 010 (backspace), 011 (horizontal tab), 012 (line feed), and 014 (form feed) respectively. Code 215 (return) is converted into 015 (carriage return) followed by 012 (line feed). Code 377 is ignored completely, and so cannot be stored in files. 7 .group
000 center-dot ( ) 040 space 100 @ 140 ` 001 down arrow () 041 ! 101 A 141 a 002 alpha () 042 " 102 B 142 b 003 beta () 043 # 103 C 143 c 004 and-sign () 044 $ 104 D 144 d 005 not-sign () 045 % 105 E 145 e 006 epsilon () 046 & 106 F 146 f 007 pi () 047 ' 107 G 147 g 010 lambda ((ctl-h)) 050 ( 110 H 150 h 011 gamma ( ) 051 ) 111 I 151 i 012 delta ( ) 052 * 112 J 152 j 013 uparrow () 053 + 113 K 153 k 014 plus-minus () 054 , 114 L 154 l 015 circle-plus ((ctl-m)) 055 - 115 M 155 m 016 infinity () 056 . 116 N 156 n 017 partial delta () 057 / 117 O 157 o 020 left horseshoe () 060 0 120 P 160 p 021 right horseshoe () 061 1 121 Q 161 q 022 up horseshoe () 062 2 122 R 162 r 023 down horseshoe () 063 3 123 S 163 s 024 universal quantifier () 064 4 124 T 164 t 025 existential quantifier () 065 5 125 U 165 u 026 circle-X () 066 6 126 V 166 v 027 double-arrow () 067 7 127 W 167 w 030 left arrow () 070 8 130 X 170 x 031 right arrow () 071 9 131 Y 171 y 032 not-equals () 072 : 132 Z 172 z 033 diamond (altmode) () 073 ; 133 [ 173 { 034 less-or-equal () 074 < 134 \ 174 | 035 greater-or-equal () 075 = 135 ] 175 } 036 equivalence () 076 > 136 ^ 176 ~ 037 or () 077 ? 137 _ 177 (ctl-qm) 200 null character 210 overstrike 220 stop-output 230 roman-iv 201 break 211 tab 221 abort 231 hand-up 202 clear 212 line 222 resume 232 hand-down 203 call 213 delete/vt 223 status 233 hand-left 204 terminal escape 214 page 224 end 234 hand-right 205 macro/backnext 215 return 225 roman-i 235 system 206 help 216 quote 226 roman-ii 236 network 207 rubout 217 hold-output 227 roman-iii 237-377 reserved for the future The Lisp Machine Character Set |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
People cannot deal directly with Lisp objects, because the objects live inside the machine. In order to let us get at and talk about Lisp objects, Lisp provides a representation of objects in the form of printed text; this is called the printed representation. This is what you have been seeing in the examples throughout this manual. Functions such as print, prin1, and princ take a Lisp object, and send the characters of its printed representation to a stream. These functions (and the internal functions they call) are known as the printer. The read function takes characters from a stream, interprets them as a printed representation of a Lisp object, builds a corresponding object and returns it; it and its subfunctions are known as the reader. (Streams are explained in (streams).)
This section describes in detail what the printed representation is for any Lisp object, and just what read does. For the rest of the chapter, the phrase "printed representation" will usually be abbreviated as "p.r.".
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
.setq slashification page Printing is done either with or without slashification. The non-slashified version is nicer looking in general, but if you give it to read it won't do the right thing. The slashified version is carefully set up so that read will be able to read it in. The primary effects of slashification are that special characters used with other than their normal meanings (e.g. a parenthesis appearing in the name of a symbol) are preceeded by slashes or cause the name of the symbol to be enclosed in vertical bars, and that symbols which are not from the current package get printed out with their package prefixes (a package prefix looks like a symbol followed by a colon).
For a fixnum or a bignum: if the number is negative, the printed representation begins with a minus sign ("-"). Then, the value of the variable base is examined. If base is a positive fixnum, the number is printed out in that base (base defaults to 8); if it is a symbol with a si:princ-function property, the value of the property will be applied to two arguments: minus of the number to be printed, and the stream to which to print it (this is a hook to allow output in Roman numerals and the like); otherwise the value of base is invalid and an error is signalled Finally, if base equals 10. and the variable *nopoint is nil, a decimal point is printed out. Slashification does not affect the printing of numbers.
For a flonum: the printer first decides whether to use ordinary notation or exponential notation. If the magnitude of the number is too large or too small, such that the ordinary notation would require an unreasonable number of leading or trailing zeroes, then exponential notation will be used. The number is printed as an optional leading minus sign, one or more digits, a decimal point, one or more digits, and an optional trailing exponent, consisting of the letter "e", an optional minus sign, and the power of ten. The number of digits printed is the "correct" number; no information present in the flonum is lost, and no extra trailing digits are printed that do not represent information in the flonum. Feeding the p.r. of a flonum back to the reader is always supposed to produce an equal flonum. Flonums are always printed in decimal; they are not affected by slashification nor by base and *nopoint.
For a small flonum: the printed representation is very similar to that of a flonum, except that exponential notation is always used and the exponent is delimited by "s" rather than "e".
For a symbol: if slashification is off, the p.r. is simply the successive characters of the print-name of the symbol. If slashification is on, two changes must be made. First, the symbol might require a package prefix in order that read work correctly, assuming that the package into which read will read the symbol is the one in which it is being printed. See the section on packages ((package)) for an explanation of the package name prefix. Secondly, if the p.r. would not read in as a symbol at all (that is, if the print-name looks like a number, or contains special characters), then the p.r. must have some quoting for those characters, either by the use of slashes ("/") before each special character, or by the use of vertical bars ("|") around the whole name. The decision whether quoting is required is done using the readtable (see (readtable)), so it is always accurate provided that readtable has the same value when the output is read back in as when it was printed.
For a string: if slashification is off, the p.r. is simply the successive characters of the string. If slashification is on, the string is printed between double quotes, and any characters inside the string which need to be preceeded by slashes will be. Normally these are just double-quote and slash. Compatibly with Maclisp, carriage return is not ignored inside strings and vertical bars.
For an instance or an entity: if the object has a method for the :print-self message, that message is sent with three arguments: the stream to print to, the current depth of list structure (see below), and whether slashification is enabled. The object should print a suitable p.r. on the stream. See (flavor) for documentation on instances. Most such objects print like "any other data type" below, except with additional information such as a name. Some objects print only their name when slashification is not in effect (when princ'ed).
For an array which is a named structure: if the array has a named structure symbol with a named-structure-invoke property which is the name of a function, then that function is called on five arguments: the symbol :print-self, the object itself, the stream to print to, the current depth of list structure (see below), and whether slashification is enabled. A suitable printed representation should be sent to the stream. This allows a user to define his own p.r. for his named structures; more information can be found in the named structure section (see (named-structure)). If the named structure symbol does not have a named-structure-invoke property, the printed-representation is like that for random data-types: a number sign and a less than sign, the named structure symbol, the numerical address of the array, and a greater than sign.
Other arrays: the p.r. starts with a number sign and a less-than sign. Then the "art-" symbol for the array type is printed. Next the dimensions of the array are printed, separated by hyphens. This is followed by a space, the machine address of the array, and a greater-than sign.
Conses: The p.r. for conses tends to favor lists. It starts with an open-parenthesis. Then, the car of the cons is printed, and the cdr of the cons is examined. If it is nil, a close parenthesis is printed. If it is anything else but a cons, space dot space followed by that object is printed. If it is a cons, we print a space and start all over (from the point after we printed the open-parenthesis) using this new cons. Thus, a list is printed as an open-parenthesis, the p.r.'s of its elements separated by spaces, and a close-parenthesis.
This is how the usual printed representations such as (a b (foo bar) c) are produced.
The following additional feature is provided for the p.r. of conses: as a list is printed, print maintains the length of the list so far, and the depth of recursion of printing lists. If the length exceeds the value of the variable prinlength, print will terminate the printed representation of the list with an ellipsis (three periods) and a close-parenthesis. If the depth of recursion exceeds the value of the variable prinlevel, then the list will be printed as "**". These two features allow a kind of abbreviated printing which is more concise and suppresses detail. Of course, neither the ellipsis nor the "**" can be interpreted by read, since the relevant information is lost.
For any other data type: the p.r. starts with a number sign and a less-than sign ("<"), the "dtp-" symbol for this datatype, a space, and the octal machine address of the object. Then, if the object is a microcoded function, compiled function, or stack group, its name is printed. Finally a greater-than sign (">") is printed.
Including the machine address in the p.r. makes it possible to tell two objects of this kind apart without explicitly calling eq on them. This can be very useful during debugging. It is important to know that if garbage collection is turned on, objects will occasionally be moved, and therefore their octal machine addresses will be changed. It is best to shut off garbage collection temporarily when depending on these numbers.
None of the p.r.'s beginning with a number sign can be read back in, nor, in general, can anything produced by instances, entities, and named structures. (Just what read accepts is the topic of the next section.) This can be a problem if, for example, you are printing a structure into a file with the intent of reading it in later. The following feature allows you to make sure that what you are printing may indeed be read with the reader.
(si:printing-random-object (ship stream) (princ (typep ship) stream) (tyo #\space stream) (prin1 (ship-name ship) stream)) |
The following keywords may be used to modify the behaviour of si:printing-random-object:
.setq customizing-the-printer section-page
If you want to control the printed representation of some object, usually the right way to do it is to make the object an array which is a named structure (see (named-structure)), or an instance of a flavor (see (flavor)). However, occasionally it is desirable to get control over all printing of objects, in order to change, in some way, how they are printed. If you need to do this, the best way to proceed is to customize the behavior of si:print-object (see (si:print-object-fun)), which is the main internal function of the printer. All of the printing functions, such as print and princ, as well as format, go through this function. The way to customize it is by using the "advice" facility (see (advise)).
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This section shows what kind of p.r.'s the reader understands, and explains the readtable, reader macros, and various features provided by read.
In general, the reader operates by recognizing tokens in the input stream. Tokens can be self-delimiting or can be separated by delimiters such as whitespace. A token is the p.r. of an atomic object such as a symbol or a number, or a special character such as a parenthesis. The reader reads one or more tokens until the complete p.r. of an object has been seen, and then constructs and returns that object.
The reader understands the p.r.'s of fixnums in a way more general than is employed by the printer. Here is a complete description of the format for fixnums.
Let a simple fixnum be a string of digits, optionally preceeded by a plus sign or a minus sign, and optionally followed by a trailing decimal point. A simple fixnum will be interpreted by read as a fixnum. If the trailing decimal point is present, the digits will be interpreted in decimal radix; otherwise, they will be considered as a number whose radix is the value of the variable ibase.
read will also understand a simple fixnum, followed by an underscore ("_") or a circumflex ("^"), followed by another simple fixnum. The two simple fixnums will be interpreted in the usual way, then the character in between indicates an operation to be performed on the two fixnums. The underscore indicates a binary "left shift"; that is, the fixnum to its left is doubled the number of times indicated by the fixnum to its right. The circumflex multiplies the fixnum to its left by ibase the number of times indicated by the fixnum to its right. (The second simple fixnum is not allowed to have a leading minus sign.) Examples: 645_6 means 64500 (in octal) and 645^3 means 645000. Here are some examples of valid representations of fixnums to be given to read:
4 23456. -546 +45^+6 2_11 |
The syntax for bignums is identical to the syntax for fixnums. A number is a bignum rather than a fixnum if and only if it is too large to be represented as a fixnum. Here are some examples of valid representations of bignums:
72361356126536125376512375126535123712635 -123456789. 105_1000 105_1000. |
.setq flonum-examples page The syntax for a flonum is an optional plus or minus sign, optionally some digits, a decimal point, and one or more digits. Such a flonum or a simple fixnum, followed by an "e" (or "E") and a simple fixnum, is also a flonum; the fixnum after the "e" is the exponent of 10 by which the number is to be scaled. (The exponent is not allowed to have a trailing decimal point.) If the exponent is introduced by "s" (or "S") rather than "e", the number is a small-flonum. Here are some examples of printed-representations that read as flonums:
0.0 1.5 14.0 0.01 .707 -.3 +3.14159 6.03e23 1E-9 1.e3 |
Here are some examples of printed-representations that read as small-flonums:
0s0 1.5s9 -42S3 1.s5 |
A string of letters, numbers, and "extended alphabetic" characters is recognized by the reader as a symbol, provided it cannot be interpreted as a number. Alphabetic case is ignored in symbols; lower-case letters are translated to upper-case. When the reader sees the p.r. of a symbol, it interns it on a package (see (package) for an explanation of interning and the package system). Symbols may start with digits; you could even have one named "-345T"; read will accept this as a symbol without complaint. If you want to put strange characters (such as lower-case letters, parentheses, or reader macro characters) inside the name of a symbol, put a slash before each strange character. If you want to have a symbol whose print-name looks like a number, put a slash before some character in the name. You can also enclose the name of a symbol in vertical bars, which quotes all characters inside, except vertical bars and slashes, which must be quoted with slash.
Examples of symbols: foo bar/(baz/) 34w23 |Frob Sale| |
The reader will also recognize strings, which should be surrounded by double-quotes. If you want to put a double-quote or a slash inside a string, preceed it by a slash.
Examples of strings: "This is a typical string." "That is known as a /"cons cell/" in Lisp." |
When read sees an open parenthesis, it knows that the p.r. of a cons is coming, and calls itself recursively to get the elements of the cons or the list that follows. Any of the following are valid:
(foo . bar) (foo bar baz) (foo . (bar . (baz . nil))) (foo bar . quux) |
Whenever the reader sees any of the above, it creates new cons cells; it never returns existing list structure. This contrasts with the case for symbols, as very often read returns symbols that it found interned in the package rather than creating new symbols itself. Symbols are the only thing that work this way.
The dot that separates the two elements of a dotted-pair p.r. for a cons is only recognized if it is surrounded by delimiters (typically spaces). Thus dot may be freely used within print-names of symbols and within numbers. This is not compatible with Maclisp; in Maclisp (a.b) reads as a cons of symbols a and b, whereas in Zetalisp it reads as a list of a symbol a.b.
If the circle-X (7"") character is encountered, it is an octal escape, which may be useful for including weird characters in the input. The next three characters are read and interpreted as an octal number, and the character whose code is that number replaces the circle-X and the digits in the input stream. This character is always taken to be an alphabetic character, just as if it had been preceded by a slash.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Certain characters are defined to be macro characters. When the reader sees one of these, it calls a function associated with the character. This function reads whatever syntax it likes and returns the object represented by that syntax. Macro characters are always token delimiters; however, they are not recognized when quoted by slash or vertical bar, nor when inside a string. Macro characters are a syntax-extension mechanism available to the user. Lisp comes with several predefined macro characters:
Quote (') is an abbreviation to make it easier to put constants in programs. 'foo reads the same as (quote foo).
Semicolon (;) is used to enter comments. The semicolon and everything up through the next carriage return are ignored. Thus a comment can be put at the end of any line without affecting the reader.
Backquote (`) makes it easier to write programs to construct lists and trees by using a template. See (backquote) for details.
Comma (,) is part of the syntax of backquote and is invalid if used other than inside the body of a backquote. See (backquote) for details.
Sharp sign (#) introduces a number of other syntax extensions. See the following section. Unlike the preceding characters, sharp sign is not a delimiter. A sharp sign in the middle of a symbol is an ordinary character.
The function set-syntax-macro-char (see (set-syntax-macro-char-fun)) can be used to define your own macro characters.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The reader's syntax includes several abbreviations introduced by sharp sign (#). These take the general form of a sharp sign, a second character which identifies the syntax, and following arguments. Certain abbreviations allow a decimal number or certain special "modifier" characters between the sharp sign and the second character. Here are the currently-defined sharp sign constructs; more are likely to be added in the future.
#/
As in strings, upper and lower-case letters are distinguished after #/. Any character works after #/, even those that are normally special to read, such as parentheses. Even non-printing characters may be used, although for them #\ is preferred.
The character can be modified with control and meta bits by inserting one or more special characters between the 7# and the 7/. This syntax is obsolete since it is not mnemonic and it generally unclear; it is superseded by the \# syntax (see below). However, it is used in some old programs, so here is how it is defined. 7#/x generates Control-x. 7#/x generates Meta-x. 7#/x generates Super-x. 7#(ctl-h)/x generates Hyper-x. These can be combined, for instance 7#/& generates Super-Meta-ampersand. Also, 7#/x is an abbreviation for 7#/x. When control bits are specified, and x is a lower-case alphabetic character, the character code for the upper-case version of the character is produced.
#\
When the system types out the name of a special character, it uses the same table as the #\ reader; therefore any character name typed out is acceptable as input.
#\ can also be used to read in the names of characters that have control and meta bits set. The syntax looks like #\control-meta-b to get a "B" character with the control and meta bits set. You can use any of the prefix bit names control, meta, hyper, and super. They may be in any order, and upper and lower-case letters are not distinguished. Also, control may be spelled ctrl as it is on the keyboards. The last hyphen may be followed by a single character, or by any of the special character names normally recognized by #\. If it is a single character, it is treated the same way the reader normally treats characters in symbols; if you want to use a lower-case character or a special character such as a parenthesis, you must preceed it by a slash character. Examples: #\Hyper-Super-A, \meta-hyper-roman-i, #\CTRL-META-/(.
The character can also be modified with control and meta bits by inserting special Greek characters as with 7#/, but this is less clear than spelling them out, and should be avoided in new programs.
#^
#'
#,
#.
#O
#X
#R
For example, #3R102 is another way of writing 11. and #11R32 is another way of writing 35. Bases larger than ten do not work completely, since there are only ten digit characters.
#Q
#M
#N
#+
For example, #+lispm form makes form exist if being read by Zetalisp, and is thus equivalent to #Q form. Similarly, #+maclisp form is equivalent to #M form. #+(or lispm nil) form will make form exist on either Zetalisp or in NIL. Note that items may be added to the (status features) list by means of (sstatus feature feature), thus allowing the user to selectively interpret or compile pieces of code by parameterizing this list. See (sstatus-fun).
#-
#<
The function set-syntax-#-macro-char (see (set-syntax-#-macro-char-fun)) can be used to define your own sharp sign abbreviations.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The following are the recognized special character names, in alphabetical order except with synonyms together and linked with equal signs. These names can be used after a "#\" to get the character code for that character. Most of these characters type out as this name enclosed in a lozenge. First we list the special function keys.
abort break call clear-input=clear delete=vt end hand-down hand-left hand-right hand-up help hold-output roman-i roman-ii roman-iii roman-iv line=lf macro=back-next network overstrike=backspace=bs page=clear-screen=form quote resume return=cr rubout space=sp status stop-output system tab terminal=esc |
These are printing characters which also have special names because they may be hard to type on a pdp-10.
altmode circle-plus delta gamma integral lambda plus-minus uparrow |
The following are special characters sometimes used to represent single and double mouse clicks. The buttons can be called either l, m, r or 1, 2, 3 depending on stylistic preference. These characters all contain the %%kbd-mouse bit.
mouse-l-1=mouse-1-1 mouse-l-2=mouse-1-2 mouse-m-1=mouse-2-1 mouse-m-2=mouse-2-2 mouse-r-1=mouse-3-1 mouse-r-2=mouse-3-2 |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
There is a data structure called the readtable which is used to control the reader. It contains information about the syntax of each character. Initially it is set up to give the standard Lisp meanings to all the characters, but the user can change the meanings of characters to alter and customize the syntax of characters. It is also possible to have several readtables describing different syntaxes and to switch from one to another by binding the symbol readtable.
The user can program the reader by changing the readtable in any of three ways. The syntax of a character can be set to one of several predefined possibilities. A character can be made into a macro character, whose interpretation is controlled by a user-supplied function which is called when the character is read. The user can create a completely new readtable, using the readtable compiler (sys: io; rtc) to define new kinds of syntax and to assign syntax classes to characters. Use of the readtable compiler is not documented here.
function is called with two arguments: list-so-far and the input stream. When a list is being read, list-so-far is that list (nil if this is the first element). At the "top level" of read, list-so-far is the symbol :toplevel. After a dotted-pair dot, list-so-far is the symbol :after-dot. function may read any number of characters from the input stream and process them however it likes.
function should return three values, called thing, type, and splice-p. thing is the object read. If splice-p is nil, thing is the result. If splice-p is non-nil, then when reading a list thing replaces the list being read--often it will be list-so-far with something else nconc'ed onto the end. At top-level and after a dot if splice-p is non-nil the thing is ignored and the macro-character does not contribute anything to the result of read. type is a historical artifact and is not really used; nil is a safe value. Most macro character functions return just one value and let the other two default to nil.
function should not have any side-effects other than on the stream and list-so-far. Because of the way the rubout-handler works, function can be called several times during the reading of a single expression in which the macro character only appears once.
char is given the same syntax that single-quote, backquote, and comma have in the initial readtable (it is called :macro syntax).
si:alphabetic
si:break
si:whitespace
si:single
si:slash
si:verticalbar
si:doublequote
si:macro
si:circlecross
These symbols will probably be moved to the standard keyword package at some point. readtable defaults to the current readtable.
nil
a symbol
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Most of these functions take optional arguments called stream and eof-option. stream is the stream from which the input is to be read; if unsupplied it defaults to the value of standard-input. The special pseudo-streams nil and t are also accepted, mainly for Maclisp compatibility. nil means the value of standard-input (i.e. the default) and t means the value of terminal-io (i.e. the interactive terminal). This is all more-or-less compatible with Maclisp, except that instead of the variable standard-input Maclisp has several variables and complicated rules. For detailed documentation of streams, refer to (streams).
eof-option controls what happens if input is from a file (or any other input source that has a definite end) and the end of the file is reached. If no eof-option argument is supplied, an error will be signalled. If there is an eof-option, it is the value to be returned. Note that an eof-option of nil means to return nil if the end of the file is reached; it is not equivalent to supplying no eof-option.
Functions such as read which read an "object" rather than a single character will always signal an error, regardless of eof-option, if the file ends in the middle of an object. For example, if a file does not contain enough right parentheses to balance the left parentheses in it, read will complain. If a file ends in a symbol or a number immediately followed by end-of-file, read will read the symbol or number successfully and when called again will see the end-of-file and obey eof-option. If a file contains ignorable text at the end, such as blank lines and comments, read will not consider it to end in the middle of an object and will obey eof-option.
These end-of-file conventions are not completely compatible with Maclisp. Maclisp's deviations from this are generally considered to be bugs rather than features.
The functions below that take stream and eof-option arguments can also be called with the stream and eof-option in the other order. This functionality is only for compatibility with old Maclisp programs, and should never be used in new 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 will 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 si:io-stream-p property whose value is t.
Note that all of these functions will echo their input if used on an interactive stream (one which supports the :rubout-handler operation; see below.) The functions that input more than one character at a time (read, readline) allow the input to be edited using rubout. tyipeek echoes all of the characters that were skipped over if tyi would have echoed them; the character not removed from the stream is not echoed either.
If read-preserve-delimiters is bound to t around a call to read, no delimiting characters will be thrown away, even if they are whitespace. This may be useful for certain reader macros or special syntaxes.
The :tyi stream operation is preferred over the tyi function for some purposes. Note that it does not echo. See (general-stream-ops).
(This function can take its arguments in the other order, for Maclisp compatibility only; see the note above.)
(This function can take its arguments in the other order, for uniformity with read only; see the note above.)
What tyipeek does depends on the peek-type, which defaults to nil. With a peek-type of nil, tyipeek returns the next character to be read from stream, without actually removing it from the input stream. The next time input is done from stream the character will still be there; in general, (= (tyipeek) (tyi)) is t. (See the description of the :tyipeek stream operation ((:tyipeek-stream-operation)) for details.)
If peek-type is a fixnum less than 1000 octal, then tyipeek reads characters from stream until it gets one equal to peek-type. That character is not removed from the input stream.
If peek-type is t, then tyipeek 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 tyipeek supported by Maclisp in which peek-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 tyipeek are echoed if stream is interactive.
The following functions are related functions which do not operate on streams. Most of the text at the beginning of this section does not apply to them.
eof-option is what to return if the end of the string is reached, as with other reading functions. idx is the index in the string of the first character to be read.
read-from-string returns two values; the first is the object read and the second is the index of the first character in the string not read. If the entire string was read, this will be either the length of the string or 1 more than the length of the string.
Example: (read-from-string "(a b c)") => (a b c) and 7 |
If there are more characters in char-list beyond those needed to define an object, the extra characters are ignored. If there are not enough characters, an "eof in middle of object" error is signalled.
See also the with-input-from-string special form ((with-input-from-string-fun)).
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
These functions all take an optional argument called stream, which is where to send the output. If unsupplied stream defaults to the value of standard-output. If stream is nil, the value of standard-output (i.e. the default) is used. If it is t, the value of terminal-io is used (i.e. the interactive terminal). If stream is a list of streams, then the output is performed to all of the streams (this is not implemented yet, and an error is signalled in this case). This is all more-or-less compatible with Maclisp, except that instead of the variable standard-output Maclisp has several variables and complicated rules. For detailed documentation of streams, refer to (streams).
The format function (see (format-fun)) 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. format can generate a string or output to a stream.
The grindef function (see (grindef-fun)) is useful for formatting Lisp programs.
See also the with-output-to-string special form ((with-output-to-string-fun)).
If from-stream supports the :line-in operation and to-stream supports the :line-out operation, then stream-copy-until-eof will use those operations instead of :tyi and :tyo, for greater efficiency. leader-size will be passed as the argument to the :line-in operation.
cursorpos normally operates on the standard-output stream; however, if the last argument is a stream or t (meaning terminal-io) then cursorpos uses that stream and ignores it when doing the operations described below. Note that cursorpos only works on streams which are capable of these operations, for instance windows. A stream is taken to be any argument which is not a number and not a symbol, or a symbol other than nil with a name more than one character long.
(cursorpos) => (line . column), the current cursor position.
(cursorpos line column) moves the cursor to that position. It returns t if it succeeds and nil if it doesn't.
(cursorpos op) performs a special operation coded by op, and returns t if it succeeds and nil if it doesn't. op is tested by string comparison, it is not a keyword symbol and may be in any package.
F
B
D
U
T
Z
A
C
E
L
K
X
Example: (exploden '(+ /12 3)) => (50 53 40 61 62 40 63 51) |
Example: (explodec '(+ /12 3)) => ( /( + / /1 /2 / /3 /) ) |
Example: (explode '(+ /12 3)) => ( /( + / // /1 /2 / /3 /) ) |
.insert lmman;stream >
.insert lmman;fd.fio >
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The rubout handler is a feature of all interactive streams, that is, streams which connect to terminals. Its purpose is to allow the user to edit minor mistakes in typein. At the same time, it is not supposed to get in the way; input is to be seen by Lisp as soon as a syntactically complete form has been typed. The definition of "syntactically complete form" depends on the function that is reading from the stream; for read, it is a Lisp expression.
Some interactive streams ("editing Lisp listeners") have a rubout handler which allows input to be edited with the full power of the Zwei editor. Other streams have a simple rubout handler which just allows rubbing out of single characters, and a few simple commands like clearing the screen and erasing the entire input typed so far. This section describes the general protocol used to deal with any rubout handler, and it also discusses the simple rubout handler and what commands it deals with.
The tricky thing about the rubout handler is the need for it to figure out when you are all done. The idea of a rubout handler is that you can type in characters, and they are saved up in a buffer so that if you change your mind, you can rub them out and type different characters. However, at some point, the rubout handler has to decide that the time has come to stop putting characters into the buffer, and let the function, such as read, start processing the characters. This is called "activating". The right time to activate depends on the function calling the rubout handler, and may be very complicated (if the function is read, figuring out when one Lisp expression has been typed requires knowledge of all the various printed representations, what all currently-defined reader macros do, and so on). Rubout handlers should not have to know how to parse the characters in the buffer to figure out what the caller is reading and when to activate; only the caller should have to know this. The rubout handler interface is organized so that the calling function can do all the parsing, while the rubout handler does all the handling of rubouts, and the two are kept completely separate.
The basic way that the rubout handler works is as follows. When an input function that reads an "object", such as read or readline (but not tyi), is called to read from a stream which has :rubout-handler in its :which-operations list, that function "enters" the rubout handler. It then goes ahead :tyi'ing characters from the stream. Because control is inside the rubout handler, the stream will echo these characters so the user can see what he is typing. (Normally echoing is considered to be a higher-level function outside of the province of streams, but when the higher-level function tells the stream to enter the rubout handler it is also handing it the responsibility for echoing). The rubout handler is also saving all these characters in a buffer, for reasons disclosed in the following paragraph. When the function, read or whatever, decides it has enough input, it returns and control "leaves" the rubout handler. That was the easy case.
If the user types a rubout, a *throw is done, out of all recursive levels of read, reader macros, and so forth, back to the point where the rubout handler was entered. Also the rubout is echoed by erasing from the screen the character which was rubbed out. Now the read is tried over again, re-reading all the characters which had been typed and not rubbed out, not echoing them this time. When the saved characters have been exhausted, additional input is read from the user in the usual fashion.
The effect of this is a complete separation of the functions of rubout handling and parsing, while at the same time mingling the execution of these two functions in such a way that input is always "activated" at just the right time. It does mean that the parsing function (in the usual case, read and all macro-character definitions) must be prepared to be thrown through at any time and should not have non-trivial side-effects, since it may be called multiple times.
If an error occurs while inside the rubout handler, the error message is printed and then additional characters are read. When the user types a rubout, it rubs out the error message as well as the character that caused the error. The user can then proceed to type the corrected expression; the input will be reparsed from the beginning in the usual fashion.
The simple rubout handler also recognizes the special characters Clear-Input, Clear-Screen, and Delete. (These are Clear, Form, and VT on old keyboards.) Clear-Screen clears the screen and echoes back the buffered input. Clear-Input is like hitting enough rubouts to flush all the buffered input. Delete is like Clear-Screen in that it echoes back the input, but it does not clear the screen. [It should be moved to a different key, shouldn't it?]
If a character with control shifts (Control, Meta, Super, or Hyper) is typed at a rubout handler that does not support the full set of editing commands, such as the simple rubout handler, it beeps and ignores the character. These characters are reserved in this context for editing use. The rubout handler based on the Zwei editor interprets control characters in the usual Zwei way: as editing commands, allowing you to edit your buffered input. When not inside the rubout handler, and when typing at a program that uses control characters for its own purposes, control characters are treated the same as ordinary characters.
The following explanation tells you how to write your own function that invokes the rubout handler. The functions read and readline both work this way. You should use the readline1 example, below, as a template for writing your own function.
The way that the rubout handler is entered is complicated, since a *catch must be established. The variable rubout-handler is non-nil if the current process is inside the rubout handler. This is used to handle recursive calls to read from inside reader macros and the like. If rubout-handler is nil, and the stream being read from has :rubout-handler in its :which-operations, functions such as read send the :rubout-handler message to the stream with arguments of a list of options, the function, and its arguments. The rubout handler initializes itself and establishes its *catch, then calls back to the specified function with rubout-handler bound to t. User-written input reading functions should follow this same protocol, to get the same input editing benefits as read and readline.
As an example of how to use the rubout handler, here is a simplified version of the readline function. It doesn't bother about end-of-file handling, use of :line-in for efficiency, etc.
(defun readline1 (stream) ;; If stream does rubout handling, get inside rubout handler (cond ((and (not rubout-handler) (memq ':rubout-handler (funcall stream ':which-operations))) (funcall stream ':rubout-handler '() #'readline1 stream)) ;; Accumulate characters until return (t (do ((ch (funcall stream ':tyi) (funcall stream ':tyi)) (len 100) (string (make-array 100 ':type 'art-string)) (idx 0)) ((or (null ch) (= ch #\cr)) (adjust-array-size string idx) string) (if (= idx len) (adjust-array-size string (setq len (+ len 40)))) (aset ch string idx) (setq idx (1+ idx)))))) |
The first argument to the :rubout-handler message is a list of options. The second argument is the function that the rubout handler should call to do the reading, and the rest of the arguments are passed to that function. Note that in the example above, readline1 is sending the :rubout-handler message passing itself as the function, and its own arguments as the arguments. This is the usual thing to do. It isn't passing any options. The returned values of the message are normally the returned values of the function (except sometimes when the :full-rubout option is used; see below).
Each option in the list of options given as the first argument to the :rubout-handler message consists of a list whose first element is a keyword and whose remaining elements are "arguments" to that keyword. Note that this is not the same format as the arguments to a typical function that takes keyword arguments; rather this is an a-list of options. The standard options are:
(:full-rubout val)
(:pass-through char1 char2...)
(:prompt function)
(:reprompt function)
The difference between :prompt and :reprompt is that the latter does not call the prompt function when the rubout handler is first entered, but only when the input is redisplayed (e.g. after a screen clear). If both options are specified then :reprompt overrides :prompt except when the rubout handler is first entered.
(:initial-input string)
.setq :do-not-echo-option page
(:do-not-echo char-1 char-2...)
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A stream can specially handle the reading and printing of objects by handling the :read and :print stream operations. Note that these operations are optional and most streams do not support them.
If the read function is given a stream which has :read in its which-operations, then instead of reading in the normal way it sends the :read message to the stream with one argument, read's eof-option if it had one or a magic internal marker if it didn't. Whatever the stream returns is what read returns. If the stream wants to implement the :read operation by internally calling read, it must use a different stream which does not have :read in its which-operations.
If a stream has :print in its which-operations, it may intercept all object printing operations, including those due to the print, prin1, and princ functions, those due to format, and those used internally, for instance in printing the elements of a list. The stream receives the :print message with three arguments: the object being printed, the prindepth (for comparison against the prinlevel variable), and slashify-p (t for prin1, nil for princ). If the stream returns nil, then normal printing takes place as usual. If the stream returns non-nil, then print does nothing; the stream is assumed to have output an appropriate printed representation for the object. The two following functions are useful in this connection; however, they are in the system-internals package and may be changed without much notice.
If you want to customize the behavior of all printing of Lisp objects, advising (see (advise)) this function is the way to do it. See (customizing-the-printer).
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The Lisp Machine can access files on a variety of remote file servers, which are typically (but not necessarily) accessed through the Chaosnet, as well as accessing files on the Lisp Machine itself, if the machine has its its own file system. This section tells you how to get a stream which reads or writes a given file, and what the device-dependent operations on that stream are. Files are named with pathnames. Since pathnames are quite complex they have their own chapter; see (pathname).
When control leaves the body, either normally or abnormally (via *throw), the file is closed. If a new output file is being written, and control leaves abnormally, the file is aborted and it is as if it were never written. Because it always closes the file, even when an error exit is taken, with-open-file is preferred over open. Opening a large number of files and forgetting to close them tends to break some remote file servers, ITS's for example.
pathname is the name of the file to be opened; it can be a pathname object, a string, a symbol, or a Maclisp-compatible "namelist". It can be anything acceptable to fs:parse-pathname; the complete rules for parsing pathnames are explained in (pathname).
If an error, such as file not found, occurs the user is asked to supply an alternate pathname, unless this is overridden by options. At that point he can quit out or enter the error handler, if the error was not due to a misspelled pathname.
When the caller is finished with the stream, it should close the file by using the :close operation or the close function. The with-open-file special form does this automatically, and so is usually preferred. open should only be used when the control structure of the program necessitates opening and closing of a file in some way more complex than the simple way provided by with-open-file. Any program that uses open should set up unwind-protect handlers (see (unwind-protect-fun)) to close its files in the event of an abnormal exit.
.setq file-opening-options page The options used when opening a file are normally alternating keywords and values, like any other function that takes keyword arguments. In addition, for compatibility with the Maclisp open function, if only a single option is specified it is either a keyword or a list of keywords (not alternating with values).
The file-opening options control things like whether the stream is for input from a existing file or output to a new file, whether the file is text or binary, etc.
The following option keywords are standardly recognized; additional keywords can be implemented by particular file system hosts.
[Are all these keywords supported by all file systems?]
:direction
:characters
:byte-size
:error
:new-file
:new-version
:old-file
nil or :replace
t or :rewrite
:append
:error
:rename
:rename-and-delete
:new-version
:inhibit-links
:deleted
:temporary
:preserve-dates
:flavor
:link-to
:estimated-size
:physical-volume
:logical-volume
:incremental-update
:super-image
:raw
In the Maclisp compatibility mode, there is only one option, and it is either a symbol or a list of symbols. These symbols are recognized no matter what package they are in, since Maclisp does not have packages. The following symbols are recognized:
in, read
out, write, print
binary, fixnum
character, ascii
single, block
byte-size
probe, error, noerror, raw, super-image, deleted, temporary
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
To load a file is to read through the file, evaluating each form in it. Programs are typically stored in files; the expressions in the file are mostly special forms such as defun and defvar which define the functions and variables of the program.
Loading a compiled (or QFASL) file is similar, except that the file does not contain text but rather pre-digested expressions created by the compiler which can be loaded more quickly.
These functions are for loading single files. There is a system for keeping track of programs which consist of more than one file; for further information refer to (system-system).
pathname can be anything acceptable to fs:parse-pathname; pathnames and the complete rules for parsing them are explained in (pathname). pathname is defaulted from fs:load-pathname-defaults (see (fs:load-pathname-defaults-var)), which is the set of defaults used by load, qc-file, and similar functions. Normally load updates the pathname defaults from pathname, but if dont-set-default is specified this is suppressed.
If pathname contains an FN1 but no FN2, load will first look for the file with an FN2 of QFASL, then it will look for an FN2 of >. For non-ITS file systems, this generalizes to: if pathname specifies a type and/or a version, load loads that file. Otherwise it first looks for a type-QFASL file, then a type-LISP file, in both cases looking for the newest version.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Any text file can contain a "property list" which specifies several attributes of the file. The above loading functions, the compiler, and the editor look at this property list. File property lists are especially useful in program source files, i.e. a file that is intended to be loaded (or compiled and then loaded).
If the first non-blank line in the file contains the three characters 7"-*-", some text, and 7"-*-" again, the text is recognized as the file's property list. Each property consists of the property name, a colon, and the property value. If there is more than one property they are separated by semicolons. An example of such a property list is:
; -*- Mode:Lisp; Package:Cellophane; Base:10 -*- |
.c This is part of the Lisp machine manual. -*- Mode:Bolio -*- |
A property name is made up of letters, numbers, and otherwise-undefined punctuation characters such as hyphens. A property value can be such a name, or a decimal number, or several such items separated by commas. Spaces may be used freely to separate tokens. Upper and lower-case letters are not distinguished. There is no quoting convention for special characters such as colons and semicolons. Thus file property lists are similar in spirit to Lisp property lists.
The file property list format actually has nothing to do with Lisp; it is just a convention for placing some information into a file that is easy for a program to interpret. The Emacs editor on the pdp-10 knows how to interpret these property lists (primarily in order to look at the Mode property).
Within the Lisp Machine, there exists a parser for file property lists that creates some Lisp data structure that corresponds to the file property list. When a file property list is read in and given to the parser (the fs:file-read-property-list function, see below), it is converted into Lisp objects as follows: Property names are interpreted as Lisp symbols, and interned on the keyword package. Numbers are interpreted as Lisp fixnums, and are read in decimal. If a property value contains any commas, then the commas separate several expressions which are formed into a list.
When a file is edited, loaded, or compiled, its file property list is read in and the properties are stored on the property list of the generic pathname (see (generic-pathname)) for that file, where they can be retrieved with the :get and :plist messages. So the way you examine the properties of a file is usually to use messages to a pathname object that represents the generic pathname of a file. Note that there other properties there, too. The function fs:file-read-property-list (see below) reads the file property list of a file and sets up the properties on the generic pathname; editing, loading, or compiling a file will call this function, but you can call it yourself if you want to examine the properties of an arbitrary file.
If the property list text contains no colons, it is an old Emacs format, containing only the value of the Mode property.
The following are some of the property names allowed and what they mean.
Mode
Package
Base
Lowercase
Fonts
Backspace
Patch-File
You are free to define additional file properties of your own. Howver, you should choose names that are different from all the names above, and from any names likely to be defined by anybody else's programs, to avoid accidental name conflicts.
The following function is the parser for file property lists.
[Is the above function really supposed to be called FS:READ-SYNTAX-PLIST?]
The fundamental way that programs in the Lisp Machine react to the presence of properties on a file's file property list is to examine the property list in the generic pathname. However, there is another way that is more convenient for some applications. File properties can cause special variables to be bound whenever Lisp expressions are being read from the file--when the file is being loaded, when it is being compiled, when it is being read from by the editor, and when its QFASL file is being loaded. This is how the Package and Base properties work. You can also deal with properties this way, by using the following function:
Usually pathname is a generic pathname. It can also be a locative, in which case it is interpreted to be the property list itself.
Of the standard property names, the following ones have fs:file-property-bindings, with the following effects. Package binds the variable package (see (package-var)) to the package. Base binds the variables base (see (base-var)) and ibase (see (ibase-var)) to the value. Patch-file binds fs:this-is-a-patch-file to the value.
Any properties whose names do not have a fs:file-property-bindings property are ignored completely.
You can also add your own property names that affect bindings. If an indicator symbol has an fs:file-property-bindings property, the value of that property is a function which is called when a file with a file property of that name is going to be read from. The function is given three arguments: the file pathname, the property name, and the property value. It must return two values: a list of variables to be bound and a list of values to bind them to. The function for the Base keyword could have been defined by:
(defun (:base file-property-bindings) (file ignore bse) (if (not (and (typep bse 'fixnum) (> bse 1) (< bse 37.))) (ferror nil "File ~A has an illegal -*- Base:~s -*-" file bse)) (values (list 'base 'ibase) (list bse bse))) |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The following messages may be sent to file streams, in addition to the normal I/O messages which work on all streams. Note that several of these messages are useful to send to a file stream which has been closed. Some of these messages use pathnames; refer to (pathname) for an explanation of pathnames.
.defmessage :pathname Returns the pathname that was opened to get this stream. This may not be identical to the argument to open, since missing components will have been filled in from defaults, and the pathname may have been replaced wholesale if an error occurred in the attempt to open the original pathname. .end_defmessage
.defmessage :truename Returns the pathname of the file actually open on this stream. This can be different from what :pathname returns because of file links, logical devices, mapping of "newest" version to a particular version number, etc. For an output stream the truename is not meaningful until after the stream has been closed, at least when the file server is an ITS. .end_defmessage
.defmessage :qfaslp Returns t if the file has a magic flag at the front that says it is a QFASL file, nil if it is an ordinary file. .end_defmessage
.defmessage :length Returns the length of the file, in bytes or characters. For text files on pdp-10 file servers, this is the number of pdp-10 characters, not Lisp Machine characters. The numbers are different because of character-set translation; see (character-set-differences) for a full explanation. For an output stream the length is not meaningful until after the stream has been closed, at least when the file server is an ITS. .end_defmessage
.defmessage :creation-date Returns the creation date of the file, as a number which is a universal time. See the chapter on the time package ((time)). .end_defmessage
.defmessage :info Returns a string which contains the version number and creation date of the file. This can be used to tell if the file has been modified between two opens. For an output stream the info is not meaningful until after the stream has been closed, at least when the file server is an ITS. .end_defmessage
.defmessage :set-byte-size new-byte-size This is only allowed on binary ("fixnum mode") file streams. The byte size can be changed to any number of bits from 1 to 16. .end_defmessage
.defmessage :delete &optional (error-p t) Deletes the file open on this stream. For the meaning of error-p, see the deletef function. The file doesn't really go away until the stream is closed. .end_defmessage
.defmessage :rename new-name &optional (error-p t) Renames the file open on this stream. For the meaning of error-p, see the renamef function. .end_defmessage
File output streams implement the :finish and :force-output messages.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
To understand the functions in this section, it helps to have read the following chapter, on pathnames.
The matching is done using both host-independent and host-dependent conventions. Any component of pathname which is :wild matches anything; all files that match the remaining components of pathname will be listed, regardless of their value for the wild component. In addition, there is host-dependent matching. Typically this uses the asterisk character (*) as a wild-card character. A pathname component that consists of just a * matches any value of that component (the same as :wild). A pathname component that contains * and other characters matches any character (on ITS) or any string of characters (on TOPS-20) in the starred positions and requires the specified characters otherwise. Other hosts will follow similar but not necessarily identical conventions.
The options are keywords which modify the operation. The following options are currently defined:
:noerror
:deleted
The properties that may appear in the list of property lists returned by fs:directory-list are host-dependent to some extent. The following properties are those that are defined for both ITS and TOPS-20 file servers. This set of properties is likely to be extended or changed in the future.
:length-in-bytes
:byte-size
:length-in-blocks
:block-size
:creation-date
:reference-date
:author
:not-backed-up
fs:change-file-properties changes one or more properties of a file. pathname names the file. The properties arguments are alternating keywords and values. The error-p argument is the same as with renamef; if an error occurs and it is nil a string describing the error will be returned; if it is t a Lisp error will be signalled. If no error occurs, fs:change-file-properties returns t.
defaults, type, and version are the arguments that will be given to fs:merge-pathname-defaults (see (fs:merge-pathname-defaults-fun)) when the user's input is eventually parsed and defaulted.
options are keywords (without following values) which control how the completion will be performed. The following option keywords are allowed:
:read or :in
:print or :write or :out
.kitem :old Look only for files that already exist. This is the default.
.kitem :new-ok Allow either a file that already exists, or a file that does not yet exist. An example of the use of this is the c-X c-F (Find File) command in the editor.
The first value returned is always a string containing a file name; either the original string, or a new, more specific string. The second value returned indicates the success or failure status of the completion. It is nil if an error occurred. One possible error is that the file is on a file system that does not support completion, in which case the original string will be returned unchanged. Other possible second values are :old, which means that the string completed to the name of a file that exists, :new, which means that the string completed to the name of a file which could be created, and nil again, which means that there is no possible completion.
[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |