Now that the stream class has been defined, and all the methods relevant to it have been set up, we can create an instance of our user defined stream to test it. The following function takes a filename and optionally a stream direction as its arguments and makes an instance of
. It ensures that the
slot of the stream contains a Common Lisp
capable of reading from or writing to a file given by the filename argument.
(defun open-unicode-ls-file (filename &key (direction :input))
(make-instance 'unicode-ls-stream :file-stream
The following macro uses
in a similar manner to the Common Lisp macro
(defmacro with-open-unicode-ls-file ((var filename
&key (direction :input))
`(let ((,var (open-unicode-ls-file ,filename
We now have the required functions and macros to test our user defined stream. The following code uses
as a source of input to an instance of our stream, and outputs it to the file
, changing all occurrences of
in the process.
(with-open-unicode-ls-file (ss "C:\\unicode-ls.out"
(write-line "-*- Encoding: Unicode; -*-" ss)
(with-open-file (ii "C:\\config.sys") ; Don't edit this file!
(loop with line = nil
while (setf line (read-line ii nil nil))
do (write-line line ss))))
After running the above code, if your load the file
into an editor (for example, a LispWorks editor), you can see the line separator used instead of CR/LF. Most editors do not yet recognize the Unicode Line Separator character yet. In some editors it appears as a blank glyph, whereas in the LispWorks editor it appears as
. In LispWorks you can use
Alt+X What Cursor Position
to identify the unprintable characters.
You can also use the follow code to print out the contents of the new file line by line.
(with-open-unicode-ls-file (ss "C:\\unicode-ls.out")
(loop while (when-let (line (read-line ss nil nil))