1 ;;;; r6rs-ports.test --- R6RS I/O port tests. -*- coding: utf-8; -*-
3 ;;;; Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
6 ;;;; This library is free software; you can redistribute it and/or
7 ;;;; modify it under the terms of the GNU Lesser General Public
8 ;;;; License as published by the Free Software Foundation; either
9 ;;;; version 3 of the License, or (at your option) any later version.
11 ;;;; This library is distributed in the hope that it will be useful,
12 ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 ;;;; Lesser General Public License for more details.
16 ;;;; You should have received a copy of the GNU Lesser General Public
17 ;;;; License along with this library; if not, write to the Free Software
18 ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 (define-module (test-io-ports)
21 #:use-module (test-suite lib)
22 #:use-module (test-suite guile-test)
23 #:use-module (srfi srfi-1)
24 #:use-module (srfi srfi-11)
25 #:use-module (rnrs io ports)
26 #:use-module (rnrs io simple)
27 #:use-module (rnrs exceptions)
28 #:use-module (rnrs bytevectors))
30 ;;; All these tests assume Guile 1.8's port system, where characters are
31 ;;; treated as octets.
33 ;; Set the default encoding of future ports to be Latin-1.
34 (fluid-set! %default-port-encoding #f)
36 (define-syntax pass-if-condition
38 ((_ name predicate body0 body ...)
39 (let ((cookie (list 'cookie)))
41 (eq? cookie (guard (c ((predicate c) cookie))
45 (data-file-name "ports-test.tmp"))
47 ;; A input/output port that swallows all output, and produces just
48 ;; spaces on input. Reading and writing beyond `failure-position'
49 ;; produces `system-error' exceptions. Used for testing exception
51 (define* (make-failing-port #:optional (failure-position 0))
52 (define (maybe-fail index errno)
53 (if (> index failure-position)
54 (scm-error 'system-error
56 "I/O beyond failure position" '()
60 (define (write-char chr)
61 (set! write-index (+ 1 write-index))
62 (maybe-fail write-index ENOSPC))
65 (lambda (str) ;; write-string
66 (for-each write-char (string->list str)))
67 (lambda () #t) ;; flush-output
68 (lambda () ;; read-char
69 (set! read-index (+ read-index 1))
70 (maybe-fail read-index EIO)
72 (lambda () #t)) ;; close-port
76 (with-test-prefix "7.2.5 End-of-File Object"
79 (and (eqv? (eof-object) (eof-object))
80 (eq? (eof-object) (eof-object))))
83 (port-eof? (open-input-string ""))))
86 (with-test-prefix "7.2.8 Binary Input"
89 (let ((port (open-input-string "A")))
90 (and (= (char->integer #\A) (get-u8 port))
91 (eof-object? (get-u8 port)))))
93 (pass-if "lookahead-u8"
94 (let ((port (open-input-string "A")))
95 (and (= (char->integer #\A) (lookahead-u8 port))
96 (= (char->integer #\A) (lookahead-u8 port))
97 (= (char->integer #\A) (get-u8 port))
98 (eof-object? (get-u8 port)))))
100 (pass-if "lookahead-u8 non-ASCII"
101 (let ((port (with-fluids ((%default-port-encoding "UTF-8"))
102 (open-input-string "λ"))))
103 (and (= 206 (lookahead-u8 port))
104 (= 206 (lookahead-u8 port))
105 (= 206 (get-u8 port))
106 (= 187 (lookahead-u8 port))
107 (= 187 (lookahead-u8 port))
108 (= 187 (get-u8 port))
109 (eof-object? (lookahead-u8 port))
110 (eof-object? (get-u8 port)))))
112 (pass-if "lookahead-u8: result is unsigned"
114 (let ((port (open-bytevector-input-port #vu8(255))))
115 (= (lookahead-u8 port) 255)))
117 (pass-if "get-bytevector-n [short]"
118 (let* ((port (open-input-string "GNU Guile"))
119 (bv (get-bytevector-n port 4)))
120 (and (bytevector? bv)
121 (equal? (bytevector->u8-list bv)
122 (map char->integer (string->list "GNU "))))))
124 (pass-if "get-bytevector-n [long]"
125 (let* ((port (open-input-string "GNU Guile"))
126 (bv (get-bytevector-n port 256)))
127 (and (bytevector? bv)
128 (equal? (bytevector->u8-list bv)
129 (map char->integer (string->list "GNU Guile"))))))
131 (pass-if-exception "get-bytevector-n with closed port"
132 exception:wrong-type-arg
134 (let ((port (%make-void-port "r")))
137 (get-bytevector-n port 3)))
139 (pass-if "get-bytevector-n! [short]"
140 (let* ((port (open-input-string "GNU Guile"))
141 (bv (make-bytevector 4))
142 (read (get-bytevector-n! port bv 0 4)))
144 (equal? (bytevector->u8-list bv)
145 (map char->integer (string->list "GNU "))))))
147 (pass-if "get-bytevector-n! [long]"
148 (let* ((str "GNU Guile")
149 (port (open-input-string str))
150 (bv (make-bytevector 256))
151 (read (get-bytevector-n! port bv 0 256)))
152 (and (equal? read (string-length str))
153 (equal? (map (lambda (i)
154 (bytevector-u8-ref bv i))
156 (map char->integer (string->list str))))))
158 (pass-if "get-bytevector-some [simple]"
159 (let* ((str "GNU Guile")
160 (port (open-input-string str))
161 (bv (get-bytevector-some port)))
162 (and (bytevector? bv)
163 (equal? (bytevector->u8-list bv)
164 (map char->integer (string->list str))))))
166 (pass-if "get-bytevector-some [only-some]"
167 (let* ((str "GNU Guile")
169 (port (make-soft-port
172 (if (>= index (string-length str))
174 (let ((c (string-ref str index)))
175 (set! index (+ index 1))
179 ;; Number of readily available octets: falls to
180 ;; zero after 4 octets have been read.
181 (- 4 (modulo index 5))))
183 (bv (get-bytevector-some port)))
184 (and (bytevector? bv)
186 (= (bytevector-length bv) index)
187 (equal? (bytevector->u8-list bv)
188 (map char->integer (string->list "GNU "))))))
190 (pass-if "get-bytevector-all"
191 (let* ((str "GNU Guile")
193 (port (make-soft-port
196 (if (>= index (string-length str))
198 (let ((c (string-ref str index)))
199 (set! index (+ index 1))
204 ;; Number of readily available octets: falls to
205 ;; zero after 4 octets have been read and then
208 (- (string-length str) index)
209 (- 4 (modulo index 5)))))
210 (if (= 0 a) (set! cont? #t))
213 (bv (get-bytevector-all port)))
214 (and (bytevector? bv)
215 (= index (string-length str))
216 (= (bytevector-length bv) (string-length str))
217 (equal? (bytevector->u8-list bv)
218 (map char->integer (string->list str)))))))
221 (define (make-soft-output-port)
222 (let* ((bv (make-bytevector 1024))
225 (write-char (lambda (chr)
226 (bytevector-u8-set! bv write-index
228 (set! write-index (+ 1 write-index)))))
231 (lambda (str) ;; write-string
232 (for-each write-char (string->list str)))
233 (lambda () #t) ;; flush-output
234 (lambda () ;; read-char
235 (if (>= read-index (bytevector-length bv))
237 (let ((c (bytevector-u8-ref bv read-index)))
238 (set! read-index (+ read-index 1))
240 (lambda () #t)) ;; close-port
243 (with-test-prefix "7.2.11 Binary Output"
246 (let ((port (make-soft-output-port)))
248 (equal? (get-u8 port) 77)))
250 ;; Note: The `put-bytevector' tests below require a Latin-1 locale so
251 ;; that the `scm_from_locale_stringn' call in `sf_write' will let all
252 ;; the bytes through, unmodified. This is hacky, but we can't use
253 ;; "custom binary output ports" here because they're only tested
256 (pass-if "put-bytevector [2 args]"
258 (let ((port (make-soft-output-port))
259 (bv (make-bytevector 256)))
260 (put-bytevector port bv)
261 (equal? (bytevector->u8-list bv)
263 (get-bytevector-n port (bytevector-length bv)))))))
265 (pass-if "put-bytevector [3 args]"
267 (let ((port (make-soft-output-port))
268 (bv (make-bytevector 256))
270 (put-bytevector port bv start)
271 (equal? (drop (bytevector->u8-list bv) start)
273 (get-bytevector-n port (- (bytevector-length bv) start)))))))
275 (pass-if "put-bytevector [4 args]"
277 (let ((port (make-soft-output-port))
278 (bv (make-bytevector 256))
281 (put-bytevector port bv start count)
282 (equal? (take (drop (bytevector->u8-list bv) start) count)
284 (get-bytevector-n port count))))))
286 (pass-if-exception "put-bytevector with closed port"
287 exception:wrong-type-arg
289 (let* ((bv (make-bytevector 4))
290 (port (%make-void-port "w")))
293 (put-bytevector port bv)))
295 (pass-if "put-bytevector with UTF-16 string port"
296 (let* ((str "hello, world")
297 (bv (string->utf16 str)))
299 (with-fluids ((%default-port-encoding "UTF-16BE"))
300 (call-with-output-string
302 (put-bytevector port bv)))))))
304 (pass-if "put-bytevector with wrong-encoding string port"
305 (let* ((str "hello, world")
306 (bv (string->utf16 str)))
307 (catch 'decoding-error
309 (with-fluids ((%default-port-encoding "UTF-32"))
310 (call-with-output-string
312 (put-bytevector port bv)))))
313 (lambda (key subr message errno port)
314 (string? (strerror errno)))))))
317 (with-test-prefix "7.2.7 Input Ports"
319 ;; This section appears here so that it can use the binary input
322 (pass-if "open-bytevector-input-port [1 arg]"
323 (let* ((str "Hello Port!")
324 (bv (u8-list->bytevector (map char->integer
325 (string->list str))))
326 (port (open-bytevector-input-port bv))
329 (let loop ((chr (read-char port))
331 (if (eof-object? chr)
332 (apply string (reverse! result))
333 (loop (read-char port)
334 (cons chr result)))))))
336 (equal? (read-to-string port) str)))
338 (pass-if "bytevector-input-port is binary"
339 (with-fluids ((%default-port-encoding "UTF-8"))
340 (binary-port? (open-bytevector-input-port #vu8(1 2 3)))))
342 (pass-if-exception "bytevector-input-port is read-only"
343 exception:wrong-type-arg
345 (let* ((str "Hello Port!")
346 (bv (u8-list->bytevector (map char->integer
347 (string->list str))))
348 (port (open-bytevector-input-port bv #f)))
350 (write "hello" port)))
352 (pass-if "bytevector input port supports seeking"
353 (let* ((str "Hello Port!")
354 (bv (u8-list->bytevector (map char->integer
355 (string->list str))))
356 (port (open-bytevector-input-port bv #f)))
358 (and (port-has-port-position? port)
359 (= 0 (port-position port))
360 (port-has-set-port-position!? port)
362 (set-port-position! port 6)
363 (= 6 (port-position port)))
364 (bytevector=? (get-bytevector-all port)
366 (map char->integer (string->list "Port!")))))))
368 (pass-if "bytevector input port can seek to very end"
369 (let ((empty (open-bytevector-input-port '#vu8()))
370 (not-empty (open-bytevector-input-port '#vu8(1 2 3))))
371 (and (begin (set-port-position! empty (port-position empty))
372 (= 0 (port-position empty)))
373 (begin (get-bytevector-n not-empty 3)
374 (set-port-position! not-empty (port-position not-empty))
375 (= 3 (port-position not-empty))))))
377 (pass-if-exception "make-custom-binary-input-port [wrong-num-args]"
378 exception:wrong-num-args
380 ;; Prior to Guile-R6RS-Libs 0.2, the last 3 arguments were wrongfully
382 (make-custom-binary-input-port "port" (lambda args #t)))
384 (pass-if "make-custom-binary-input-port"
385 (let* ((source (make-bytevector 7777))
387 (len (bytevector-length source)))
388 (lambda (bv start count)
389 (let ((amount (min count (- len pos))))
391 (bytevector-copy! source pos
393 (set! pos (+ pos amount))
395 (port (make-custom-binary-input-port "the port" read!
398 (and (binary-port? port)
400 (bytevector=? (get-bytevector-all port) source))))
402 (pass-if "custom binary input port does not support `port-position'"
403 (let* ((str "Hello Port!")
404 (source (open-bytevector-input-port
406 (map char->integer (string->list str)))))
407 (read! (lambda (bv start count)
408 (let ((r (get-bytevector-n! source bv start count)))
412 (port (make-custom-binary-input-port "the port" read!
414 (not (or (port-has-port-position? port)
415 (port-has-set-port-position!? port)))))
417 (pass-if "custom binary input port supports `port-position'"
418 (let* ((str "Hello Port!")
419 (source (open-bytevector-input-port
421 (map char->integer (string->list str)))))
422 (read! (lambda (bv start count)
423 (let ((r (get-bytevector-n! source bv start count)))
428 (port-position source)))
429 (set-pos! (lambda (pos)
430 (set-port-position! source pos)))
431 (port (make-custom-binary-input-port "the port" read!
432 get-pos set-pos! #f)))
434 (and (port-has-port-position? port)
435 (= 0 (port-position port))
436 (port-has-set-port-position!? port)
438 (set-port-position! port 6)
439 (= 6 (port-position port)))
440 (bytevector=? (get-bytevector-all port)
442 (map char->integer (string->list "Port!")))))))
444 (pass-if "custom binary input port `close-proc' is called"
446 (read! (lambda (bv start count) 0))
447 (get-pos (lambda () 0))
448 (set-pos! (lambda (pos) #f))
449 (close! (lambda () (set! closed? #t)))
450 (port (make-custom-binary-input-port "the port" read!
455 (gc) ; Test for marking a closed port.
458 (pass-if "standard-input-port is binary"
459 (with-fluids ((%default-port-encoding "UTF-8"))
460 (binary-port? (standard-input-port)))))
463 (with-test-prefix "8.2.10 Output ports"
465 (let ((filename (test-file)))
466 (pass-if "open-file-output-port [opens binary port]"
467 (call-with-port (open-file-output-port filename)
469 (put-bytevector port '#vu8(1 2 3))
470 (binary-port? port))))
472 (pass-if-condition "open-file-output-port [exception: already-exists]"
473 i/o-file-already-exists-error?
474 (open-file-output-port filename))
476 (pass-if "open-file-output-port [no-fail no-truncate]"
478 (call-with-port (open-file-output-port filename
479 (file-options no-fail no-truncate))
481 (= 0 (port-position port))))
482 (= 3 (stat:size (stat filename)))))
484 (pass-if "open-file-output-port [no-fail]"
486 (call-with-port (open-file-output-port filename (file-options no-fail))
488 (= 0 (stat:size (stat filename)))))
490 (delete-file filename)
492 (pass-if-condition "open-file-output-port [exception: does-not-exist]"
493 i/o-file-does-not-exist-error?
494 (open-file-output-port filename (file-options no-create))))
496 (pass-if "open-bytevector-output-port"
497 (let-values (((port get-content)
498 (open-bytevector-output-port #f)))
499 (let ((source (make-bytevector 7777)))
500 (put-bytevector port source)
501 (and (bytevector=? (get-content) source)
502 (bytevector=? (get-content) (make-bytevector 0))))))
504 (pass-if "bytevector-output-port is binary"
505 (binary-port? (open-bytevector-output-port)))
507 (pass-if "open-bytevector-output-port [extract after close]"
508 (let-values (((port get-content)
509 (open-bytevector-output-port)))
510 (let ((source (make-bytevector 12345 #xFE)))
511 (put-bytevector port source)
513 (bytevector=? (get-content) source))))
515 (pass-if "open-bytevector-output-port [put-u8]"
516 (let-values (((port get-content)
517 (open-bytevector-output-port)))
519 (and (bytevector=? (get-content) (make-bytevector 1 77))
520 (bytevector=? (get-content) (make-bytevector 0)))))
522 (pass-if "open-bytevector-output-port [display]"
523 (let-values (((port get-content)
524 (open-bytevector-output-port)))
525 (display "hello" port)
526 (and (bytevector=? (get-content) (string->utf8 "hello"))
527 (bytevector=? (get-content) (make-bytevector 0)))))
529 (pass-if "bytevector output port supports `port-position'"
530 (let-values (((port get-content)
531 (open-bytevector-output-port)))
532 (let ((source (make-bytevector 7777))
533 (overwrite (make-bytevector 33)))
534 (and (port-has-port-position? port)
535 (port-has-set-port-position!? port)
537 (put-bytevector port source)
538 (= (bytevector-length source)
539 (port-position port)))
541 (set-port-position! port 10)
542 (= 10 (port-position port)))
544 (put-bytevector port overwrite)
545 (bytevector-copy! overwrite 0 source 10
546 (bytevector-length overwrite))
547 (= (port-position port)
548 (+ 10 (bytevector-length overwrite))))
549 (bytevector=? (get-content) source)
550 (bytevector=? (get-content) (make-bytevector 0))))))
552 (pass-if "make-custom-binary-output-port"
553 (let ((port (make-custom-binary-output-port "cbop"
556 (and (output-port? port)
558 (not (port-has-port-position? port))
559 (not (port-has-set-port-position!? port)))))
561 (pass-if "make-custom-binary-output-port [partial writes]"
562 (let* ((source (uint-list->bytevector (iota 333)
563 (native-endianness) 2))
564 (sink (make-bytevector (bytevector-length source)))
567 (write! (lambda (bv start count)
572 (let ((u8 (bytevector-u8-ref bv start)))
573 ;; Get one byte at a time.
574 (bytevector-u8-set! sink sink-pos u8)
575 (set! sink-pos (+ 1 sink-pos))
577 (port (make-custom-binary-output-port "cbop" write!
579 (put-bytevector port source)
580 (and (= sink-pos (bytevector-length source))
582 (bytevector=? sink source))))
584 (pass-if "make-custom-binary-output-port [full writes]"
585 (let* ((source (uint-list->bytevector (iota 333)
586 (native-endianness) 2))
587 (sink (make-bytevector (bytevector-length source)))
590 (write! (lambda (bv start count)
596 (bytevector-copy! bv start
599 (set! sink-pos (+ sink-pos count))
601 (port (make-custom-binary-output-port "cbop" write!
603 (put-bytevector port source)
604 (and (= sink-pos (bytevector-length source))
606 (bytevector=? sink source))))
608 (pass-if "standard-output-port is binary"
609 (with-fluids ((%default-port-encoding "UTF-8"))
610 (binary-port? (standard-output-port))))
612 (pass-if "standard-error-port is binary"
613 (with-fluids ((%default-port-encoding "UTF-8"))
614 (binary-port? (standard-error-port)))))
617 (with-test-prefix "8.2.6 Input and output ports"
619 (pass-if "transcoded-port [output]"
620 (let ((s "Hello\nÄÖÜ"))
623 (call-with-bytevector-output-port
625 (call-with-port (transcoded-port bv-port (make-transcoder (utf-8-codec)))
627 (put-string utf8-port s))))))))
629 (pass-if "transcoded-port [input]"
630 (let ((s "Hello\nÄÖÜ"))
634 (transcoded-port (open-bytevector-input-port (string->utf8 s))
635 (make-transcoder (utf-8-codec)))))))
637 (pass-if "transcoded-port [input line]"
639 (get-line (transcoded-port
640 (open-bytevector-input-port (string->utf8 "ÄÖÜ\nFooBar"))
641 (make-transcoder (utf-8-codec))))))
643 (pass-if "transcoded-port [error handling mode = raise]"
644 (let* ((t (make-transcoder (utf-8-codec) (native-eol-style)
645 (error-handling-mode raise)))
646 (b (open-bytevector-input-port #vu8(255 2 1)))
647 (tp (transcoded-port b t)))
648 (guard (c ((i/o-decoding-error? c)
649 (eq? (i/o-error-port c) tp)))
652 (pass-if "transcoded-port [error handling mode = replace]"
653 (let* ((t (make-transcoder (utf-8-codec) (native-eol-style)
654 (error-handling-mode replace)))
655 (b (open-bytevector-input-port #vu8(255 1 2 3 103 110 117)))
656 (tp (transcoded-port b t)))
657 (string-suffix? "gnu" (get-line tp))))
659 (pass-if "transcoded-port, output [error handling mode = raise]"
660 (let-values (((p get)
661 (open-bytevector-output-port)))
662 (let* ((t (make-transcoder (latin-1-codec) (native-eol-style)
663 (error-handling-mode raise)))
664 (tp (transcoded-port p t)))
665 (guard (c ((i/o-encoding-error? c)
666 (and (eq? (i/o-error-port c) tp)
667 (char=? (i/o-encoding-error-char c) #\λ)
668 (bytevector=? (get) (string->utf8 "The letter ")))))
669 (put-string tp "The letter λ cannot be represented in Latin-1.")
672 (pass-if "port-transcoder [binary port]"
673 (not (port-transcoder (open-bytevector-input-port #vu8()))))
675 (pass-if "port-transcoder [transcoded port]"
676 (let* ((p (transcoded-port (open-bytevector-input-port (string->utf8 "foo"))
677 (make-transcoder (utf-8-codec))))
678 (t (port-transcoder p)))
681 (eq? (native-eol-style)
682 (transcoder-eol-style t))
683 (eq? (error-handling-mode replace)
684 (transcoder-error-handling-mode t))))))
686 (with-test-prefix "8.2.9 Textual input"
688 (pass-if "get-string-n [short]"
689 (let ((port (open-input-string "GNU Guile")))
690 (string=? "GNU " (get-string-n port 4))))
691 (pass-if "get-string-n [long]"
692 (let ((port (open-input-string "GNU Guile")))
693 (string=? "GNU Guile" (get-string-n port 256))))
694 (pass-if "get-string-n [eof]"
695 (let ((port (open-input-string "")))
696 (eof-object? (get-string-n port 4))))
698 (pass-if "get-string-n! [short]"
699 (let ((port (open-input-string "GNU Guile"))
700 (s (string-copy "Isn't XXX great?")))
701 (and (= 3 (get-string-n! port s 6 3))
702 (string=? s "Isn't GNU great?"))))
704 (with-test-prefix "read error"
705 (pass-if-condition "get-char" i/o-read-error?
706 (get-char (make-failing-port)))
707 (pass-if-condition "lookahead-char" i/o-read-error?
708 (lookahead-char (make-failing-port)))
709 ;; FIXME: these are not yet exception-correct
711 (pass-if-condition "get-string-n" i/o-read-error?
712 (get-string-n (make-failing-port) 5))
713 (pass-if-condition "get-string-n!" i/o-read-error?
714 (get-string-n! (make-failing-port) (make-string 5) 0 5))
716 (pass-if-condition "get-string-all" i/o-read-error?
717 (get-string-all (make-failing-port 100)))
718 (pass-if-condition "get-line" i/o-read-error?
719 (get-line (make-failing-port)))
720 (pass-if-condition "get-datum" i/o-read-error?
721 (get-datum (make-failing-port)))))
723 (with-test-prefix "8.2.12 Textual Output"
725 (with-test-prefix "write error"
726 (pass-if-condition "put-char" i/o-write-error?
727 (put-char (make-failing-port) #\G))
728 (pass-if-condition "put-string" i/o-write-error?
729 (put-string (make-failing-port) "Hello World!"))
730 (pass-if-condition "put-datum" i/o-write-error?
731 (put-datum (make-failing-port) '(hello world!)))))
733 (with-test-prefix "8.3 Simple I/O"
734 (with-test-prefix "read error"
735 (pass-if-condition "read-char" i/o-read-error?
736 (read-char (make-failing-port)))
737 (pass-if-condition "peek-char" i/o-read-error?
738 (peek-char (make-failing-port)))
739 (pass-if-condition "read" i/o-read-error?
740 (read (make-failing-port))))
741 (with-test-prefix "write error"
742 (pass-if-condition "display" i/o-write-error?
743 (display "Hi there!" (make-failing-port)))
744 (pass-if-condition "write" i/o-write-error?
745 (write '(hi there!) (make-failing-port)))
746 (pass-if-condition "write-char" i/o-write-error?
747 (write-char #\G (make-failing-port)))
748 (pass-if-condition "newline" i/o-write-error?
749 (newline (make-failing-port))))
750 (let ((filename (test-file)))
751 ;; ensure the test file exists
752 (call-with-output-file filename
753 (lambda (port) (write "foo" port)))
754 (pass-if "call-with-input-file [port is textual]"
755 (call-with-input-file filename textual-port?))
756 (pass-if-condition "call-with-input-file [exception: not-found]"
757 i/o-file-does-not-exist-error?
758 (call-with-input-file ",this-is-highly-unlikely-to-exist!"
760 (pass-if-condition "call-with-output-file [exception: already-exists]"
761 i/o-file-already-exists-error?
762 (call-with-output-file filename
764 (delete-file filename)))
768 ;;; eval: (put 'guard 'scheme-indent-function 1)