1 ;;;; This file is for testing external-format functionality, using
2 ;;;; test machinery which might have side effects (e.g. executing
3 ;;;; DEFUN, writing files). Note that the tests here reach into
4 ;;;; unexported functionality, and should not be used as a guide for
7 ;;;; This software is part of the SBCL system. See the README file for
10 ;;;; While most of SBCL is derived from the CMU CL system, the test
11 ;;;; files (like this one) were written from scratch after the fork
14 ;;;; This software is in the public domain and is provided with
15 ;;;; absolutely no warranty. See the COPYING and CREDITS files for
16 ;;;; more information.
18 ;;; I have absolutely no idea what's going on with ppc64 little-endian,
19 ;;; but this file's realtime is just ridiculous on the test machine
20 ;;; and it totally dominates the time taken in parallel-exec:
21 ;;; big-endian: real 0m3.265s
22 ;;; little-endian: real 2m53.039s
23 ;;; Whereas, with this one file eliminated on ppc64le, the total wallclock
24 ;;; time for parallel-exec (with 12 workers) is approximately 94 seconds
25 ;;; on either machine. What is so horrible about our external-format codecs
26 ;;; that it antagonizes the little-endian CPU so badly?
27 #+(and ppc64 little-endian
) (invoke-restart 'run-tests
::skip-file
)
29 (defmacro do-external-formats
((xf) &body body
)
33 `(sb-int:dovector
(,nxf sb-impl
::*external-formats
*)
35 (let* ((,xfs
(sb-int:ensure-list
,nxf
))
36 (,xfsym
(first (sb-impl::ef-names
(car ,xfs
)))))
37 (dolist (,xf
(append (list ,xfsym
)
38 (when (find :cr
(cdr ,xfs
) :key
#'caar
)
39 (list (list ,xfsym
:newline
:cr
)))
40 (when (find :crlf
(cdr ,xfs
) :key
#'caar
)
41 (list (list ,xfsym
:newline
:crlf
)))))
44 (defmacro with-ef-test
(options &rest rest
)
45 (let* ((test-name (getf options
:name
))
46 (ef-name (car (last test-name
))))
47 (if (sb-impl::get-external-format ef-name
)
48 `(with-test ,options
,@rest
)
49 `(format t
"::: INFO: no external format named ~S~%" ',ef-name
))))
51 (defvar *test-path
* (scratch-file-name))
53 (flet ((s2o-file (string &key external-format
)
54 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
55 :external-format external-format
)
56 (write-sequence string s
))
57 (with-open-file (s *test-path
* :direction
:input
:element-type
'(unsigned-byte 8))
58 (let* ((vector (make-array 10 :initial-element
0))
59 (count (read-sequence vector s
)))
60 (subseq vector
0 count
))))
61 (o2s-file (vector &key external-format
)
62 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
63 :element-type
'(unsigned-byte 8))
64 (write-sequence vector s
))
65 (with-open-file (s *test-path
* :direction
:input
:external-format external-format
)
66 (let* ((string (make-string 10))
67 (count (read-sequence string s
)))
68 (subseq string
0 count
)))))
69 (with-test (:name
(:external-format-options
:ascii
:file
))
71 (octets (coerce '(0 0 0 0) '(vector (unsigned-byte 8)))))
72 (assert (equalp (s2o-file string
:external-format
:ascii
) #(63)))
73 (assert (equalp (o2s-file octets
:external-format
:ascii
) #(#\Nul
#\Nul
#\Nul
#\Nul
)))
74 (assert (equalp (s2o-file string
:external-format
'(:ascii
:replacement
"?"))
76 (assert (equalp (o2s-file octets
:external-format
'(:ascii
:replacement
"?"))
77 #(#\Nul
#\Nul
#\Nul
#\Nul
)))
78 (assert (equalp (s2o-file string
:external-format
'(:ascii
:newline
:lf
)) #(63)))
79 (assert (equalp (o2s-file octets
:external-format
'(:ascii
:newline
:lf
))
80 #(#\Nul
#\Nul
#\Nul
#\Nul
)))
81 (assert (equalp (s2o-file string
:external-format
'(:ascii
:newline
:crlf
)) #(63)))
82 (assert (equalp (o2s-file octets
:external-format
'(:ascii
:newline
:crlf
))
83 #(#\Nul
#\Nul
#\Nul
#\Nul
)))
84 (assert-error (s2o-file string
:external-format
'(:ascii
:replacment
"?")))
85 (assert-error (o2s-file octets
:external-format
'(:ascii
:replacment
"?")))
86 (assert-error (s2o-file string
:external-format
'(:ascii
:replacement
#p
"~")))
87 (assert-error (o2s-file octets
:external-format
'(:ascii
:replacement
#p
"~")))
88 (assert-error (s2o-file string
:external-format
'(:ascii
:nelwine
:crlf
)))
89 (assert-error (o2s-file octets
:external-format
'(:ascii
:nelwine
:crlf
)))
90 (assert-error (s2o-file string
:external-format
'(:ascii
:newline
:clrf
)))
91 (assert-error (o2s-file octets
:external-format
'(:ascii
:newline
:clrf
)))))
92 (with-test (:name
(:external-format-options
:ascii
:octets
))
94 (octets (coerce '(0 0 0 0) '(vector (unsigned-byte 8)))))
95 (assert (equalp (string-to-octets string
:external-format
:ascii
) #(63)))
96 (assert (equalp (octets-to-string octets
:external-format
:ascii
) #(#\Nul
#\Nul
#\Nul
#\Nul
)))
97 (assert (equalp (string-to-octets string
:external-format
'(:ascii
:replacement
"?"))
99 (assert (equalp (octets-to-string octets
:external-format
'(:ascii
:replacement
"?"))
100 #(#\Nul
#\Nul
#\Nul
#\Nul
)))
101 (assert (equalp (string-to-octets string
:external-format
'(:ascii
:newline
:lf
)) #(63)))
102 (assert (equalp (octets-to-string octets
:external-format
'(:ascii
:newline
:lf
))
103 #(#\Nul
#\Nul
#\Nul
#\Nul
)))
104 (assert (equalp (string-to-octets string
:external-format
'(:ascii
:newline
:crlf
)) #(63)))
105 (assert (equalp (octets-to-string octets
:external-format
'(:ascii
:newline
:crlf
))
106 #(#\Nul
#\Nul
#\Nul
#\Nul
)))
107 (assert-error (string-to-octets string
:external-format
'(:ascii
:replacment
"?")))
108 (assert-error (octets-to-string octets
:external-format
'(:ascii
:replacment
"?")))
109 (assert-error (string-to-octets string
:external-format
'(:ascii
:replacement
#p
"~")))
110 (assert-error (octets-to-string octets
:external-format
'(:ascii
:replacement
#p
"~")))
111 (assert-error (string-to-octets string
:external-format
'(:ascii
:nelwine
:crlf
)))
112 (assert-error (octets-to-string octets
:external-format
'(:ascii
:nelwine
:crlf
)))
113 (assert-error (string-to-octets string
:external-format
'(:ascii
:newline
:clrf
)))
114 (assert-error (octets-to-string octets
:external-format
'(:ascii
:newline
:clrf
)))))
116 (with-test (:name
(:external-format-options
:latin-1
:file
))
118 (octets (coerce '(0 0 0 0) '(vector (unsigned-byte 8)))))
119 (assert (equalp (s2o-file string
:external-format
:latin-1
) #(63)))
120 (assert (equalp (o2s-file octets
:external-format
:latin-1
) #(#\Nul
#\Nul
#\Nul
#\Nul
)))
121 (assert (equalp (s2o-file string
:external-format
'(:latin-1
:replacement
"?"))
123 (assert (equalp (o2s-file octets
:external-format
'(:latin-1
:replacement
"?"))
124 #(#\Nul
#\Nul
#\Nul
#\Nul
)))
125 (assert (equalp (s2o-file string
:external-format
'(:latin-1
:newline
:lf
)) #(63)))
126 (assert (equalp (o2s-file octets
:external-format
'(:latin-1
:newline
:lf
))
127 #(#\Nul
#\Nul
#\Nul
#\Nul
)))
128 (assert (equalp (s2o-file string
:external-format
'(:latin-1
:newline
:crlf
)) #(63)))
129 (assert (equalp (o2s-file octets
:external-format
'(:latin-1
:newline
:crlf
))
130 #(#\Nul
#\Nul
#\Nul
#\Nul
)))
131 (assert-error (s2o-file string
:external-format
'(:latin-1
:replacment
"?")))
132 (assert-error (o2s-file octets
:external-format
'(:latin-1
:replacment
"?")))
133 (assert-error (s2o-file string
:external-format
'(:latin-1
:replacement
#p
"~")))
134 (assert-error (o2s-file octets
:external-format
'(:latin-1
:replacement
#p
"~")))
135 (assert-error (s2o-file string
:external-format
'(:latin-1
:nelwine
:crlf
)))
136 (assert-error (o2s-file octets
:external-format
'(:latin-1
:nelwine
:crlf
)))
137 (assert-error (s2o-file string
:external-format
'(:latin-1
:newline
:clrf
)))
138 (assert-error (o2s-file octets
:external-format
'(:latin-1
:newline
:clrf
)))))
139 (with-test (:name
(:external-format-options
:latin-1
:octets
))
141 (octets (coerce '(0 0 0 0) '(vector (unsigned-byte 8)))))
142 (assert (equalp (string-to-octets string
:external-format
:latin-1
) #(63)))
143 (assert (equalp (octets-to-string octets
:external-format
:latin-1
) #(#\Nul
#\Nul
#\Nul
#\Nul
)))
144 (assert (equalp (string-to-octets string
:external-format
'(:latin-1
:replacement
"?"))
146 (assert (equalp (octets-to-string octets
:external-format
'(:latin-1
:replacement
"?"))
147 #(#\Nul
#\Nul
#\Nul
#\Nul
)))
148 (assert (equalp (string-to-octets string
:external-format
'(:latin-1
:newline
:lf
)) #(63)))
149 (assert (equalp (octets-to-string octets
:external-format
'(:latin-1
:newline
:lf
))
150 #(#\Nul
#\Nul
#\Nul
#\Nul
)))
151 (assert (equalp (string-to-octets string
:external-format
'(:latin-1
:newline
:crlf
)) #(63)))
152 (assert (equalp (octets-to-string octets
:external-format
'(:latin-1
:newline
:crlf
))
153 #(#\Nul
#\Nul
#\Nul
#\Nul
)))
154 (assert-error (string-to-octets string
:external-format
'(:latin-1
:replacment
"?")))
155 (assert-error (octets-to-string octets
:external-format
'(:latin-1
:replacment
"?")))
156 (assert-error (string-to-octets string
:external-format
'(:latin-1
:replacement
#p
"~")))
157 (assert-error (octets-to-string octets
:external-format
'(:latin-1
:replacement
#p
"~")))
158 (assert-error (string-to-octets string
:external-format
'(:latin-1
:nelwine
:crlf
)))
159 (assert-error (octets-to-string octets
:external-format
'(:latin-1
:nelwine
:crlf
)))
160 (assert-error (string-to-octets string
:external-format
'(:latin-1
:newline
:clrf
)))
161 (assert-error (octets-to-string octets
:external-format
'(:latin-1
:newline
:clrf
)))))
163 (with-test (:name
(:external-format-options
:utf-8
:file
))
165 (octets (coerce '(0 0 0 0) '(vector (unsigned-byte 8)))))
166 (assert (equalp (s2o-file string
:external-format
:utf-8
) #(63)))
167 (assert (equalp (o2s-file octets
:external-format
:utf-8
) #(#\Nul
#\Nul
#\Nul
#\Nul
)))
168 (assert (equalp (s2o-file string
:external-format
'(:utf-8
:replacement
"?"))
170 (assert (equalp (o2s-file octets
:external-format
'(:utf-8
:replacement
"?"))
171 #(#\Nul
#\Nul
#\Nul
#\Nul
)))
172 (assert (equalp (s2o-file string
:external-format
'(:utf-8
:newline
:lf
)) #(63)))
173 (assert (equalp (o2s-file octets
:external-format
'(:utf-8
:newline
:lf
))
174 #(#\Nul
#\Nul
#\Nul
#\Nul
)))
175 (assert (equalp (s2o-file string
:external-format
'(:utf-8
:newline
:crlf
)) #(63)))
176 (assert (equalp (o2s-file octets
:external-format
'(:utf-8
:newline
:crlf
))
177 #(#\Nul
#\Nul
#\Nul
#\Nul
)))
178 (assert-error (s2o-file string
:external-format
'(:utf-8
:replacment
"?")))
179 (assert-error (o2s-file octets
:external-format
'(:utf-8
:replacment
"?")))
180 (assert-error (s2o-file string
:external-format
'(:utf-8
:replacement
#p
"~")))
181 (assert-error (o2s-file octets
:external-format
'(:utf-8
:replacement
#p
"~")))
182 (assert-error (s2o-file string
:external-format
'(:utf-8
:nelwine
:crlf
)))
183 (assert-error (o2s-file octets
:external-format
'(:utf-8
:nelwine
:crlf
)))
184 (assert-error (s2o-file string
:external-format
'(:utf-8
:newline
:clrf
)))
185 (assert-error (o2s-file octets
:external-format
'(:utf-8
:newline
:clrf
)))))
186 (with-test (:name
(:external-format-options
:utf-8
:octets
))
188 (octets (coerce '(0 0 0 0) '(vector (unsigned-byte 8)))))
189 (assert (equalp (string-to-octets string
:external-format
:utf-8
) #(63)))
190 (assert (equalp (octets-to-string octets
:external-format
:utf-8
) #(#\Nul
#\Nul
#\Nul
#\Nul
)))
191 (assert (equalp (string-to-octets string
:external-format
'(:utf-8
:replacement
"?"))
193 (assert (equalp (octets-to-string octets
:external-format
'(:utf-8
:replacement
"?"))
194 #(#\Nul
#\Nul
#\Nul
#\Nul
)))
195 (assert (equalp (string-to-octets string
:external-format
'(:utf-8
:newline
:lf
)) #(63)))
196 (assert (equalp (octets-to-string octets
:external-format
'(:utf-8
:newline
:lf
))
197 #(#\Nul
#\Nul
#\Nul
#\Nul
)))
198 (assert (equalp (string-to-octets string
:external-format
'(:utf-8
:newline
:crlf
)) #(63)))
199 (assert (equalp (octets-to-string octets
:external-format
'(:utf-8
:newline
:crlf
))
200 #(#\Nul
#\Nul
#\Nul
#\Nul
)))
201 (assert-error (string-to-octets string
:external-format
'(:utf-8
:replacment
"?")))
202 (assert-error (octets-to-string octets
:external-format
'(:utf-8
:replacment
"?")))
203 (assert-error (string-to-octets string
:external-format
'(:utf-8
:replacement
#p
"~")))
204 (assert-error (octets-to-string octets
:external-format
'(:utf-8
:replacement
#p
"~")))
205 (assert-error (string-to-octets string
:external-format
'(:utf-8
:nelwine
:crlf
)))
206 (assert-error (octets-to-string octets
:external-format
'(:utf-8
:nelwine
:crlf
)))
207 (assert-error (string-to-octets string
:external-format
'(:utf-8
:newline
:clrf
)))
208 (assert-error (octets-to-string octets
:external-format
'(:utf-8
:newline
:clrf
)))))
210 (with-test (:name
(:external-format-options
:gbk
:file
)
211 :skipped-on
(or (not :sb-unicode
) :unicode-lite
))
213 (octets (coerce '(0 0 0 0) '(vector (unsigned-byte 8)))))
214 (assert (equalp (s2o-file string
:external-format
:gbk
) #(63)))
215 (assert (equalp (o2s-file octets
:external-format
:gbk
) #(#\Nul
#\Nul
#\Nul
#\Nul
)))
216 (assert (equalp (s2o-file string
:external-format
'(:gbk
:replacement
"?"))
218 (assert (equalp (o2s-file octets
:external-format
'(:gbk
:replacement
"?"))
219 #(#\Nul
#\Nul
#\Nul
#\Nul
)))
220 (assert (equalp (s2o-file string
:external-format
'(:gbk
:newline
:lf
)) #(63)))
221 (assert (equalp (o2s-file octets
:external-format
'(:gbk
:newline
:lf
))
222 #(#\Nul
#\Nul
#\Nul
#\Nul
)))
223 (assert-error (s2o-file string
:external-format
'(:gbk
:newline
:crlf
)))
224 (assert-error (o2s-file octets
:external-format
'(:gbk
:newline
:crlf
)))
225 (assert-error (s2o-file string
:external-format
'(:gbk
:replacment
"?")))
226 (assert-error (o2s-file octets
:external-format
'(:gbk
:replacment
"?")))
227 (assert-error (s2o-file string
:external-format
'(:gbk
:replacement
#p
"~")))
228 (assert-error (o2s-file octets
:external-format
'(:gbk
:replacement
#p
"~")))
229 (assert-error (s2o-file string
:external-format
'(:gbk
:nelwine
:crlf
)))
230 (assert-error (o2s-file octets
:external-format
'(:gbk
:nelwine
:crlf
)))
231 (assert-error (s2o-file string
:external-format
'(:gbk
:newline
:clrf
)))
232 (assert-error (o2s-file octets
:external-format
'(:gbk
:newline
:clrf
)))))
233 (with-test (:name
(:external-format-options
:gbk
:octets
)
234 :skipped-on
(or (not :sb-unicode
) :unicode-lite
))
236 (octets (coerce '(0 0 0 0) '(vector (unsigned-byte 8)))))
237 (assert (equalp (string-to-octets string
:external-format
:gbk
) #(63)))
238 (assert (equalp (octets-to-string octets
:external-format
:gbk
) #(#\Nul
#\Nul
#\Nul
#\Nul
)))
239 (assert (equalp (string-to-octets string
:external-format
'(:gbk
:replacement
"?"))
241 (assert (equalp (octets-to-string octets
:external-format
'(:gbk
:replacement
"?"))
242 #(#\Nul
#\Nul
#\Nul
#\Nul
)))
243 (assert (equalp (string-to-octets string
:external-format
'(:gbk
:newline
:lf
)) #(63)))
244 (assert (equalp (octets-to-string octets
:external-format
'(:gbk
:newline
:lf
))
245 #(#\Nul
#\Nul
#\Nul
#\Nul
)))
246 (assert-error (string-to-octets string
:external-format
'(:gbk
:newline
:crlf
)))
247 (assert-error (octets-to-string octets
:external-format
'(:gbk
:newline
:crlf
)))
248 (assert-error (string-to-octets string
:external-format
'(:gbk
:replacment
"?")))
249 (assert-error (octets-to-string octets
:external-format
'(:gbk
:replacment
"?")))
250 (assert-error (string-to-octets string
:external-format
'(:gbk
:replacement
#p
"~")))
251 (assert-error (octets-to-string octets
:external-format
'(:gbk
:replacement
#p
"~")))
252 (assert-error (string-to-octets string
:external-format
'(:gbk
:nelwine
:crlf
)))
253 (assert-error (octets-to-string octets
:external-format
'(:gbk
:nelwine
:crlf
)))
254 (assert-error (string-to-octets string
:external-format
'(:gbk
:newline
:clrf
)))
255 (assert-error (octets-to-string octets
:external-format
'(:gbk
:newline
:clrf
)))))
257 (with-test (:name
(:external-format-options
:ucs-2le
:file
)
258 :skipped-on
(not :sb-unicode
))
260 (octets (coerce '(0 0 0 0) '(vector (unsigned-byte 8)))))
261 (assert (equalp (s2o-file string
:external-format
:ucs-2le
) #(63 0)))
262 (assert (equalp (o2s-file octets
:external-format
:ucs-2le
) #(#\Nul
#\Nul
)))
263 (assert (equalp (s2o-file string
:external-format
'(:ucs-2le
:replacement
"?"))
265 (assert (equalp (o2s-file octets
:external-format
'(:ucs-2le
:replacement
"?"))
267 (assert (equalp (s2o-file string
:external-format
'(:ucs-2le
:newline
:lf
)) #(63 0)))
268 (assert (equalp (o2s-file octets
:external-format
'(:ucs-2le
:newline
:lf
))
270 (assert-error (s2o-file string
:external-format
'(:ucs-2le
:newline
:crlf
)))
271 (assert-error (o2s-file octets
:external-format
'(:ucs-2le
:newline
:crlf
)))
272 (assert-error (s2o-file string
:external-format
'(:ucs-2le
:replacment
"?")))
273 (assert-error (o2s-file octets
:external-format
'(:ucs-2le
:replacment
"?")))
274 (assert-error (s2o-file string
:external-format
'(:ucs-2le
:replacement
#p
"~")))
275 (assert-error (o2s-file octets
:external-format
'(:ucs-2le
:replacement
#p
"~")))
276 (assert-error (s2o-file string
:external-format
'(:ucs-2le
:nelwine
:crlf
)))
277 (assert-error (o2s-file octets
:external-format
'(:ucs-2le
:nelwine
:crlf
)))
278 (assert-error (s2o-file string
:external-format
'(:ucs-2le
:newline
:clrf
)))
279 (assert-error (o2s-file octets
:external-format
'(:ucs-2le
:newline
:clrf
)))))
280 (with-test (:name
(:external-format-options
:ucs-2le
:octets
)
281 :skipped-on
(not :sb-unicode
))
283 (octets (coerce '(0 0 0 0) '(vector (unsigned-byte 8)))))
284 (assert (equalp (string-to-octets string
:external-format
:ucs-2le
) #(63 0)))
285 (assert (equalp (octets-to-string octets
:external-format
:ucs-2le
) #(#\Nul
#\Nul
)))
286 (assert (equalp (string-to-octets string
:external-format
'(:ucs-2le
:replacement
"?"))
288 (assert (equalp (octets-to-string octets
:external-format
'(:ucs-2le
:replacement
"?"))
290 (assert (equalp (string-to-octets string
:external-format
'(:ucs-2le
:newline
:lf
)) #(63 0)))
291 (assert (equalp (octets-to-string octets
:external-format
'(:ucs-2le
:newline
:lf
))
293 (assert-error (string-to-octets string
:external-format
'(:ucs-2le
:newline
:crlf
)))
294 (assert-error (octets-to-string octets
:external-format
'(:ucs-2le
:newline
:crlf
)))
295 (assert-error (string-to-octets string
:external-format
'(:ucs-2le
:replacment
"?")))
296 (assert-error (octets-to-string octets
:external-format
'(:ucs-2le
:replacment
"?")))
297 (assert-error (string-to-octets string
:external-format
'(:ucs-2le
:replacement
#p
"~")))
298 (assert-error (octets-to-string octets
:external-format
'(:ucs-2le
:replacement
#p
"~")))
299 (assert-error (string-to-octets string
:external-format
'(:ucs-2le
:nelwine
:crlf
)))
300 (assert-error (octets-to-string octets
:external-format
'(:ucs-2le
:nelwine
:crlf
)))
301 (assert-error (string-to-octets string
:external-format
'(:ucs-2le
:newline
:clrf
)))
302 (assert-error (octets-to-string octets
:external-format
'(:ucs-2le
:newline
:clrf
)))))
305 (with-test (:name
:end-of-file
)
306 (do-external-formats (xf)
307 (with-open-file (s #-win32
"/dev/null" #+win32
"nul" :direction
:input
:external-format xf
)
308 (assert (eq (read-char s nil s
) s
)))))
310 ;; Output routines must return the written element
311 (with-test (:name
:output-routine-retval
:skipped-on
:win32
)
312 (dolist (x sb-impl
::*output-routines
*)
313 (with-open-file (f "/dev/null" :direction
:output
:if-exists
:overwrite
)
314 (let ((arg (if (eq (car x
) 'character
) #\z
99))
315 (fun (symbol-function (third x
))))
316 (assert (eql arg
(funcall fun f arg
)))))))
318 ;;; Test standard character read-write equivalency over all external formats.
322 (do-external-formats (xf)
323 (pushnew `(with-test (:name
(:standard-character
:read-write-equivalency
,xf
))
324 (let ((standard-characters "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!$\"'(),_-./:;?+<=>#%&*@[\\]{|}`^~"))
325 (with-open-file (s *test-path
* :direction
:output
326 :if-exists
:supersede
:external-format
',xf
)
327 (loop for character across standard-characters
328 do
(write-char character s
)))
329 (with-open-file (s *test-path
* :direction
:input
330 :external-format
',xf
)
331 (loop for character across standard-characters
332 do
(let ((got (read-char s
)))
333 (unless (eql character got
)
334 (error "wanted ~S, got ~S" character got
)))))))
335 tests
:key
#'cadr
:test
#'equal
))
341 (delete-file *test-path
*)
342 (test-util:report-test-status
)
343 (invoke-restart 'run-tests
::skip-file
))
345 ;;; Test UTF-8 writing and reading of 1, 2, 3 and 4 octet characters with
346 ;;; all possible offsets. Tests for buffer edge bugs. fd-stream buffers are
349 (let ((character (code-char (elt '(1 #x81
#x801
#x10001
) width-1
))))
350 (dotimes (offset (+ width-1
1))
351 (with-open-file (s *test-path
* :direction
:output
352 :if-exists
:supersede
:external-format
:utf-8
)
355 (dotimes (n (+ 4 sb-impl
::+bytes-per-buffer
+))
356 (write-char character s
)))
357 (with-open-file (s *test-path
* :direction
:input
358 :external-format
:utf-8
)
360 (assert (eql (read-char s
) #\a)))
361 (dotimes (n (+ 4 sb-impl
::+bytes-per-buffer
+))
362 (let ((got (read-char s
)))
363 (unless (eql got character
)
364 (error "wanted ~S, got ~S (~S)" character got n
))))
365 (assert (eql (read-char s nil s
) s
))))))
367 ;;; Test character decode restarts.
368 (with-open-file (s *test-path
* :direction
:output
369 :if-exists
:supersede
:element-type
'(unsigned-byte 8))
374 (with-open-file (s *test-path
* :direction
:input
375 :external-format
:utf-8
)
378 ((sb-int:character-decoding-error
#'(lambda (decoding-error)
379 (declare (ignore decoding-error
))
380 (when (> (incf count
) 1)
381 (error "too many errors"))
383 'sb-int
:attempt-resync
))))
384 (assert (equal (read-line s nil s
) "ABC"))
385 (assert (equal (read-line s nil s
) s
)))))
386 (with-open-file (s *test-path
* :direction
:input
387 :external-format
:utf-8
)
390 ((sb-int:character-decoding-error
#'(lambda (decoding-error)
391 (declare (ignore decoding-error
))
392 (when (> (incf count
) 1)
393 (error "too many errors"))
395 'sb-int
:force-end-of-file
))))
396 (assert (equal (read-line s nil s
) "AB"))
398 (assert (equal (read-line s nil s
) s
)))))
400 ;;; And again with more data to account for buffering (this was briefly)
401 ;;; broken in early 0.9.6.
402 (with-open-file (s *test-path
* :direction
:output
403 :if-exists
:supersede
:element-type
'(unsigned-byte 8))
404 (let ((a (make-array 50
405 :element-type
'(unsigned-byte 64)
406 :initial-contents
(map 'list
#'char-code
407 "1234567890123456789012345678901234567890123456789."))))
408 (setf (aref a
49) (char-code #\Newline
))
410 (write-sequence a s
))
413 (write-sequence a s
))))
414 (with-test (:name
(:character-decode-large
:attempt-resync
))
415 (with-open-file (s *test-path
* :direction
:input
416 :external-format
:utf-8
)
419 ((sb-int:character-decoding-error
(lambda (decoding-error)
420 (declare (ignore decoding-error
))
421 (when (> (incf count
) 1)
422 (error "too many errors"))
424 'sb-int
:attempt-resync
)))
425 ;; The failure mode is an infinite loop, add a timeout to
427 (sb-ext:timeout
(lambda (condition)
428 (declare (ignore condition
))
430 (sb-ext:with-timeout
5
432 (assert (equal (read-line s nil s
)
433 "1234567890123456789012345678901234567890123456789"))))))))
435 (with-test (:name
(:character-decode-large
:force-end-of-file
))
436 (with-open-file (s *test-path
* :direction
:input
437 :external-format
:utf-8
)
440 ((sb-int:character-decoding-error
(lambda (decoding-error)
441 (declare (ignore decoding-error
))
442 (when (> (incf count
) 1)
443 (error "too many errors"))
445 'sb-int
:force-end-of-file
)))
446 ;; The failure mode is an infinite loop, add a timeout to detetct it.
447 (sb-ext:timeout
(lambda (condition)
448 (declare (ignore condition
))
450 (sb-ext:with-timeout
5
452 (assert (equal (read-line s nil s
)
453 "1234567890123456789012345678901234567890123456789")))
455 (assert (equal (read-line s nil s
) s
)))))))
457 ;;; Test character encode restarts.
458 (with-open-file (s *test-path
* :direction
:output
459 :if-exists
:supersede
:external-format
:latin-1
)
461 ((sb-int:character-encoding-error
#'(lambda (encoding-error)
462 (declare (ignore encoding-error
))
464 'sb-impl
::output-nothing
))))
467 (write-char (code-char 322) s
)
469 (with-open-file (s *test-path
* :direction
:input
470 :external-format
:latin-1
)
471 (assert (equal (read-line s nil s
) "ABC"))
472 (assert (equal (read-line s nil s
) s
)))
474 (with-open-file (s *test-path
* :direction
:output
475 :if-exists
:supersede
:external-format
:latin-1
)
477 ((sb-int:character-encoding-error
#'(lambda (encoding-error)
478 (declare (ignore encoding-error
))
480 'sb-impl
::output-nothing
))))
481 (let ((string (make-array 4 :element-type
'character
482 :initial-contents
`(#\A
#\B
,(code-char 322)
484 (write-string string s
))))
485 (with-open-file (s *test-path
* :direction
:input
486 :external-format
:latin-1
)
487 (assert (equal (read-line s nil s
) "ABC"))
488 (assert (equal (read-line s nil s
) s
)))
490 ;;; Test skipping character-decode-errors in comments.
491 (let* ((input (scratch-file-name "lisp"))
492 (s (open input
:direction
:output
493 :if-exists
:supersede
:external-format
:latin-1
))
497 (write-string ";;; ABCD" s
)
498 (write-char (code-char 233) s
)
501 (let ((*error-output
* (make-broadcast-stream)))
504 :external-format
:utf-8
:verbose nil
))))
506 (let ((p (probe-file output
)))
511 ;;;; KOI8-R external format
514 (with-open-file (s *test-path
* :direction
:output
515 :if-exists
:supersede
:external-format
:koi8-r
)
516 (write-char (code-char #xB0
) s
)
520 (write-char (code-char #xBAAD
) s
)
522 (sb-int:character-encoding-error
()
525 (with-open-file (s *test-path
* :direction
:input
526 :element-type
'(unsigned-byte 8))
527 (let ((byte (read-byte s
)))
528 (assert (= (eval byte
) #x9C
))))
529 (with-open-file (s *test-path
* :direction
:input
530 :external-format
:koi8-r
)
531 (let ((char (read-char s
)))
532 (assert (= (char-code (eval char
)) #xB0
))))
534 (let* ((koi8-r-codes (coerce '(240 210 201 215 197 212 33) '(vector (unsigned-byte 8))))
535 (uni-codes #(1055 1088 1080 1074 1077 1090 33))
537 (string (octets-to-string koi8-r-codes
:external-format
:koi8-r
))
538 (uni-decoded (map 'vector
#'char-code string
)))
539 (declare (ignore uni-decoded
))
540 (assert (equalp (map 'vector
#'char-code
(octets-to-string koi8-r-codes
:external-format
:koi8-r
))
542 (assert (equalp (string-to-octets (map 'string
#'code-char uni-codes
) :external-format
:koi8-r
)
547 ;;; tests of FILE-STRING-LENGTH
548 (let ((standard-characters "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!$\"'(),_-./:;?+<=>#%&*@[\\]{|}`^~"))
549 (do-external-formats (xf)
550 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
552 (loop for x across standard-characters
553 for position
= (file-position s
)
554 for char-length
= (file-string-length s x
)
556 do
(assert (= (file-position s
) (+ position char-length
))))
557 (let ((position (file-position s
))
558 (string-length (file-string-length s standard-characters
)))
559 (write-string standard-characters s
)
560 (assert (= (file-position s
) (+ position string-length
)))))))
562 (let ((char-codes '(0 1 255 256 511 512 1023 1024 2047 2048 4095 4096
563 8191 8192 16383 16384 32767 32768 65535 65536 131071
564 131072 262143 262144)))
565 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
566 :external-format
:utf-8
)
567 (dolist (code char-codes
)
568 (let* ((char (code-char code
))
569 (position (file-position s
))
570 (char-length (file-string-length s char
)))
572 (assert (= (file-position s
) (+ position char-length
)))))
573 (let* ((string (map 'string
#'code-char char-codes
))
574 (position (file-position s
))
575 (string-length (file-string-length s string
)))
576 (write-string string s
)
577 (assert (= (file-position s
) (+ position string-length
))))))
580 ;;; See sbcl-devel "Subject: Bug in FILE-POSITION on UTF-8-encoded files"
581 ;;; by Lutz Euler on 2006-03-05 for more details.
582 (with-test (:name
(:file-position
:utf-8
))
583 (let ((path *test-path
*))
584 (with-open-file (s path
586 :if-exists
:supersede
587 :element-type
'(unsigned-byte 8))
588 ;; Write #\*, encoded in UTF-8, to the file.
590 ;; Append #\adiaeresis, encoded in UTF-8, to the file.
591 (write-sequence '(195 164) s
))
592 (with-open-file (s path
:external-format
:utf-8
)
594 (let ((pos (file-position s
))
595 (char (read-char s
)))
597 (format t
"read character with code ~a successfully from file position ~a~%"
598 (char-code char
) pos
)
599 (file-position s pos
)
601 (format t
"set file position back to ~a, trying to read-char again~%" pos
)
602 (let ((new-char (read-char s
)))
603 (assert (char= char new-char
)))))
606 ;;; We used to call STREAM-EXTERNAL-FORMAT on the stream in the error
607 ;;; when printing a coding error, but that didn't work if the stream
608 ;;; was closed by the time the error was printed. See sbcl-devel
609 ;;; "Subject: Printing coding errors for closed streams" by Zach Beane
610 ;;; on 2008-10-16 for more info.
611 (with-test (:name
(:character-coding-error-stream-external-format
))
612 (flet ((first-file-character ()
613 (with-open-file (stream *test-path
* :external-format
:utf-8
)
614 (read-char stream
))))
615 (with-open-file (stream *test-path
*
617 :if-exists
:supersede
618 :element-type
'(unsigned-byte 8))
619 (write-byte 192 stream
))
620 (princ-to-string (nth-value 1 (ignore-errors (first-file-character))))))
622 ;;; External format support in SB-ALIEN
624 (with-test (:name
(:sb-alien
:vanilla
))
625 (define-alien-routine (#-win32
"strdup" #+win32
"_strdup" strdup
)
628 (assert (equal "foo" (strdup "foo"))))
630 (with-test (:name
(:sb-alien
:utf-8
:utf-8
))
631 (define-alien-routine (#-win32
"strdup" #+win32
"_strdup" strdup
)
632 (c-string :external-format
:utf-8
)
633 (str (c-string :external-format
:utf-8
)))
634 (assert (equal "foo" (strdup "foo"))))
636 (with-test (:name
(:sb-alien
:latin-1
:utf-8
))
637 (define-alien-routine (#-win32
"strdup" #+win32
"_strdup" strdup
)
638 (c-string :external-format
:latin-1
)
639 (str (c-string :external-format
:utf-8
)))
640 (assert (= (length (strdup (string (code-char 246))))
643 (with-test (:name
(:sb-alien
:utf-8
:latin-1
))
644 (define-alien-routine (#-win32
"strdup" #+win32
"_strdup" strdup
)
645 (c-string :external-format
:utf-8
)
646 (str (c-string :external-format
:latin-1
)))
647 (assert (equal (string (code-char 228))
648 (strdup (concatenate 'string
649 (list (code-char 195))
650 (list (code-char 164)))))))
652 (with-ef-test (:name
(:sb-alien
:ebcdic
:ebcdic-us
))
653 (define-alien-routine (#-win32
"strdup" #+win32
"_strdup" strdup
)
654 (c-string :external-format
:ebcdic-us
)
655 (str (c-string :external-format
:ebcdic-us
)))
656 (assert (equal "foo" (strdup "foo"))))
658 (with-ef-test (:name
(:sb-alien
:latin-1
:ebcdic-us
))
659 (define-alien-routine (#-win32
"strdup" #+win32
"_strdup" strdup
)
660 (c-string :external-format
:latin-1
)
661 (str (c-string :external-format
:ebcdic-us
)))
662 (assert (not (equal "foo" (strdup "foo")))))
664 (with-ef-test (:name
(:sb-alien
:simple-base-string
:ebcdic-us
))
665 (define-alien-routine (#-win32
"strdup" #+win32
"_strdup" strdup
)
666 (c-string :external-format
:ebcdic-us
667 :element-type base-char
)
668 (str (c-string :external-format
:ebcdic-us
)))
669 (assert (typep (strdup "foo") 'simple-base-string
)))
671 (with-test (:name
(:input-replacement
:at-end-of-file
))
673 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:element-type
'(unsigned-byte 8))
675 (handler-bind ((sb-int:character-decoding-error
678 (invoke-restart 'sb-impl
::input-replacement
#\?))))
679 (with-open-file (s *test-path
* :external-format
:utf-8
)
681 ((char= (read-char s
) #\?)
682 (assert (or (= i
(char-code #\?)) (> i
127))))
683 (t (assert (and (not (= i
(char-code #\?))) (< i
128)))))))))
685 (with-ef-test (:name
(:unibyte-invalid-codepoints
:cp857
))
687 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:element-type
'(unsigned-byte 8))
689 (with-open-file (s *test-path
* :external-format
:cp857
)
690 (handler-case (read-char s
)
691 (error () (assert (member i
'(#xd5
#xe7
#xf2
))))
692 (:no-error
(char) char
(assert (not (member i
'(#xd5
#xe7
#xf2
)))))))))
694 (with-ef-test (:name
(:unibyte-input-replacement
:cp857
))
696 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:element-type
'(unsigned-byte 8))
698 (with-open-file (s *test-path
* :external-format
'(:cp857
:replacement
#\?))
699 (let ((char (read-char s
)))
702 (assert (member i
`(,(char-code #\?) #xd5
#xe7
#xf2
))))
703 (t (assert (not (member i
`(,(char-code #\?) #xd5
#xe7
#xf2
))))))))))
705 (with-ef-test (:name
(:unibyte-output-replacement
:cp857
))
706 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:external-format
'(:cp857
:replacement
#\?))
708 (write-char (code-char i
) s
)))
709 (with-open-file (s *test-path
* :external-format
'(:cp857
))
710 (let ((string (make-string 256)))
711 (read-sequence string s
)
713 (assert (= (char-code (char string i
)) i
)))
714 (assert (= 38 (count #\? string
:start
128))))))
716 (with-test (:name
(:unibyte-input-replacement
:ascii
))
718 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:element-type
'(unsigned-byte 8))
720 (with-open-file (s *test-path
* :external-format
'(:ascii
:replacement
#\?))
721 (let ((char (read-char s
)))
724 (assert (or (= i
(char-code #\?)) (> i
127))))
725 (t (assert (and (< i
128) (not (= i
(char-code #\?)))))))))))
727 (with-test (:name
(:unibyte-output-replacement
:ascii
))
728 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:external-format
'(:ascii
:replacement
#\?))
730 (write-char (code-char i
) s
)))
731 (with-open-file (s *test-path
* :external-format
'(:ascii
))
732 (let ((string (make-string 256)))
733 (read-sequence string s
)
735 (assert (= (char-code (char string i
)) i
)))
736 (assert (= 128 (count #\? string
:start
128))))))
738 (with-test (:name
(:unibyte-input-replacement
:latin-1
))
740 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:element-type
'(unsigned-byte 8))
742 (with-open-file (s *test-path
* :external-format
'(:latin-1
:replacement
#\?))
743 (let ((char (read-char s
)))
744 (assert (= (char-code char
) i
))))))
746 (with-test (:name
(:unibyte-output-replacement
:latin-1
))
747 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:external-format
'(:latin-1
:replacement
#\?))
749 (write-char (code-char i
) s
)))
750 (with-open-file (s *test-path
* :external-format
'(:latin-1
))
751 (let ((string (make-string 257)))
752 (read-sequence string s
)
754 (assert (= (char-code (char string i
)) i
)))
755 (assert (char= #\? (char string
256))))))
758 (with-ef-test (:name
(:unibyte-input-replacement
:latin-2
))
760 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:element-type
'(unsigned-byte 8))
762 (with-open-file (s *test-path
* :external-format
'(:latin-2
:replacement
#\?))
763 (let ((char (read-char s
)))
765 ((< i
#xa1
) (assert (= (char-code char
) i
)))
769 (with-ef-test (:name
(:unibyte-output-replacement
:latin-2
))
770 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:external-format
'(:latin-2
:replacement
#\?))
772 (write-char (code-char i
) s
)))
773 (with-open-file (s *test-path
* :external-format
'(:latin-2
))
774 (let ((string (make-string 256)))
775 (read-sequence string s
)
777 (assert (= (char-code (char string i
)) i
)))
778 (assert (= 57 (count #\? string
:start
#xa1
))))))
781 (with-ef-test (:name
(:unibyte-input-replacement
:latin-3
))
783 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:element-type
'(unsigned-byte 8))
785 (with-open-file (s *test-path
* :external-format
'(:latin-3
:replacement
#\?))
786 (let ((char (read-char s
)))
789 (assert #1=(or (= i
(char-code #\?))
790 (member i
'(#xa5
#xae
#xbe
#xc3
#xd0
#xe3
#xf0
)))))
791 (t (assert (not #1#))))))))
793 (with-ef-test (:name
(:unibyte-output-replacement
:latin-3
))
794 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:external-format
'(:latin-3
:replacement
#\?))
796 (write-char (code-char i
) s
)))
797 (with-open-file (s *test-path
* :external-format
'(:latin-3
))
798 (let ((string (make-string 256)))
799 (read-sequence string s
)
801 (assert (= (char-code (char string i
)) i
)))
802 (assert (= 35 (count #\? string
:start
#xa1
))))))
805 (with-ef-test (:name
(:unibyte-input-replacement
:latin-4
))
807 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:element-type
'(unsigned-byte 8))
809 (with-open-file (s *test-path
* :external-format
'(:latin-4
:replacement
#\?))
810 (let ((char (read-char s
)))
812 ((< i
#xa1
) (assert (= (char-code char
) i
)))
816 (with-ef-test (:name
(:unibyte-output-replacement
:latin-4
))
817 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:external-format
'(:latin-4
:replacement
#\?))
819 (write-char (code-char i
) s
)))
820 (with-open-file (s *test-path
* :external-format
'(:latin-4
))
821 (let ((string (make-string 256)))
822 (read-sequence string s
)
824 (assert (= (char-code (char string i
)) i
)))
825 (assert (= 50 (count #\? string
:start
#xa1
))))))
828 (with-ef-test (:name
(:unibyte-input-replacement
:iso-8859-5
))
830 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:element-type
'(unsigned-byte 8))
832 (with-open-file (s *test-path
* :external-format
'(:iso-8859-5
:replacement
#\?))
833 (let ((char (read-char s
)))
835 ((= (char-code char
) i
)
836 (assert (or (< i
#xa1
) (= i
#xad
))))
837 (t (assert (and (>= i
#xa1
) (/= i
#xad
)))))))))
839 (with-ef-test (:name
(:unibyte-output-replacement
:iso-8859-5
))
840 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:external-format
'(:iso-8859-5
:replacement
#\?))
842 (write-char (code-char i
) s
)))
843 (with-open-file (s *test-path
* :external-format
'(:iso-8859-5
))
844 (let ((string (make-string 256)))
845 (read-sequence string s
)
847 (assert (= (char-code (char string i
)) i
)))
848 (assert (= 93 (count #\? string
:start
#xa1
))))))
851 (with-ef-test (:name
(:unibyte-input-replacement
:iso-8859-6
))
853 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:element-type
'(unsigned-byte 8))
855 (with-open-file (s *test-path
* :external-format
'(:iso-8859-6
:replacement
#\?))
856 (let ((char (read-char s
)))
859 (assert #1=(or (= i
(char-code #\?))
860 (<= #xa1 i
#xa3
) (<= #xa5 i
#xab
) (<= #xae i
#xba
)
861 (<= #xbc i
#xbe
) (= i
#xc0
) (<= #xdb i
#xdf
)
863 (t (assert (not #1#))))))))
865 (with-ef-test (:name
(:unibyte-output-replacement
:iso-8859-6
))
866 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:external-format
'(:iso-8859-6
:replacement
#\?))
868 (write-char (code-char i
) s
)))
869 (with-open-file (s *test-path
* :external-format
'(:iso-8859-6
))
870 (let ((string (make-string 256)))
871 (read-sequence string s
)
873 (assert (= (char-code (char string i
)) i
)))
874 (assert (= 93 (count #\? string
:start
#xa1
))))))
877 (with-ef-test (:name
(:unibyte-input-replacement
:iso-8859-7
))
879 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:element-type
'(unsigned-byte 8))
881 (with-open-file (s *test-path
* :external-format
'(:iso-8859-7
:replacement
#\?))
882 (let ((char (read-char s
)))
885 (assert #1=(or (= i
(char-code #\?))
886 (member i
'(#xa4
#xa5
#xaa
#xae
#xd2
#xff
)))))
887 (t (assert (not #1#))))))))
889 (with-ef-test (:name
(:unibyte-output-replacement
:iso-8859-7
))
890 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:external-format
'(:iso-8859-7
:replacement
#\?))
892 (write-char (code-char i
) s
)))
893 (with-open-file (s *test-path
* :external-format
'(:iso-8859-7
))
894 (let ((string (make-string 256)))
895 (read-sequence string s
)
897 (assert (= (char-code (char string i
)) i
)))
898 (assert (= 80 (count #\? string
:start
#xa1
))))))
901 (with-ef-test (:name
(:unibyte-input-replacement
:iso-8859-8
))
903 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:element-type
'(unsigned-byte 8))
905 (with-open-file (s *test-path
* :external-format
'(:iso-8859-8
:replacement
#\?))
906 (let ((char (read-char s
)))
909 (assert #1=(or (= i
(char-code #\?))
910 (= i
#xa1
) (<= #xbf i
#xde
) (>= i
#xfb
))))
911 (t (assert (not #1#))))))))
913 (with-ef-test (:name
(:unibyte-output-replacement
:iso-8859-8
))
914 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:external-format
'(:iso-8859-8
:replacement
#\?))
916 (write-char (code-char i
) s
)))
917 (with-open-file (s *test-path
* :external-format
'(:iso-8859-8
))
918 (let ((string (make-string 256)))
919 (read-sequence string s
)
921 (assert (= (char-code (char string i
)) i
)))
922 (assert (= 67 (count #\? string
:start
#xa1
))))))
925 (with-ef-test (:name
(:unibyte-input-replacement
:latin-5
))
927 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:element-type
'(unsigned-byte 8))
929 (with-open-file (s *test-path
* :external-format
'(:latin-5
:replacement
#\?))
930 (let ((char (read-char s
)))
931 (assert (or (and (= (char-code char
) i
)
932 (not (member i
'(#xd0
#xdd
#xde
#xf0
#xfd
#xfe
))))
933 (and (member i
'(#xd0
#xdd
#xde
#xf0
#xfd
#xfe
))
934 (not (char= char
#\?)))))))))
936 (with-ef-test (:name
(:unibyte-output-replacement
:latin-5
))
937 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:external-format
'(:latin-5
:replacement
#\?))
939 (write-char (code-char i
) s
)))
940 (with-open-file (s *test-path
* :external-format
'(:latin-5
))
941 (let ((string (make-string 256)))
942 (read-sequence string s
)
944 (assert (= (char-code (char string i
)) i
)))
945 (assert (= 6 (count #\? string
:start
#xd0
))))))
948 (with-ef-test (:name
(:unibyte-input-replacement
:latin-6
))
950 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:element-type
'(unsigned-byte 8))
952 (with-open-file (s *test-path
* :external-format
'(:latin-6
:replacement
#\?))
953 (let ((char (read-char s
)))
954 (assert (or (= (char-code char
) i
)
955 (and (<= #xa1 i
#xff
)
956 (not (char= char
#\?)))))))))
958 (with-ef-test (:name
(:unibyte-output-replacement
:latin-6
))
959 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:external-format
'(:latin-6
:replacement
#\?))
961 (write-char (code-char i
) s
)))
962 (with-open-file (s *test-path
* :external-format
'(:latin-6
))
963 (let ((string (make-string 256)))
964 (read-sequence string s
)
966 (assert (= (char-code (char string i
)) i
)))
967 (assert (= 46 (count #\? string
:start
#xa1
))))))
969 ;;; iso-8859-11 tests
970 (with-ef-test (:name
(:unibyte-input-replacement
:iso-8859-11
))
972 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:element-type
'(unsigned-byte 8))
974 (with-open-file (s *test-path
* :external-format
'(:iso-8859-11
:replacement
#\?))
975 (let ((char (read-char s
)))
978 (assert (member i
#1=`(,(char-code #\?) #xdb
#xdc
#xdd
#xde
#xfc
#xfd
#xfe
#xff
))))
979 (t (assert (not (member i
#1#)))))))))
981 (with-ef-test (:name
(:unibyte-output-replacement
:iso-8859-11
))
982 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:external-format
'(:iso-8859-11
:replacement
#\?))
984 (write-char (code-char i
) s
)))
985 (with-open-file (s *test-path
* :external-format
'(:iso-8859-11
))
986 (let ((string (make-string 256)))
987 (read-sequence string s
)
989 (assert (= (char-code (char string i
)) i
)))
990 (assert (= 95 (count #\? string
:start
#xa1
))))))
993 (with-ef-test (:name
(:unibyte-input-replacement
:latin-7
))
995 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:element-type
'(unsigned-byte 8))
997 (with-open-file (s *test-path
* :external-format
'(:latin-7
:replacement
#\?))
998 (let ((char (read-char s
)))
999 (assert (or (= (char-code char
) i
)
1000 (and (<= #xa1 i
#xff
)
1001 (not (char= char
#\?)))))))))
1003 (with-ef-test (:name
(:unibyte-output-replacement
:latin-7
))
1004 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:external-format
'(:latin-7
:replacement
#\?))
1006 (write-char (code-char i
) s
)))
1007 (with-open-file (s *test-path
* :external-format
'(:latin-7
))
1008 (let ((string (make-string 256)))
1009 (read-sequence string s
)
1011 (assert (= (char-code (char string i
)) i
)))
1012 (dolist (i '(#xd8
#xc6
#xf8
#xe6
))
1013 (assert (char/= (char string i
) #\?)))
1014 (assert (= 52 (count #\? string
:start
#xa1
))))))
1017 (with-ef-test (:name
(:unibyte-input-replacement
:latin-8
))
1019 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:element-type
'(unsigned-byte 8))
1021 (with-open-file (s *test-path
* :external-format
'(:latin-8
:replacement
#\?))
1022 (let ((char (read-char s
)))
1023 (assert (or (= (char-code char
) i
)
1024 (and (<= #xa1 i
#xfe
)
1025 (not (char= char
#\?)))))))))
1027 (with-ef-test (:name
(:unibyte-output-replacement
:latin-8
))
1028 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:external-format
'(:latin-8
:replacement
#\?))
1030 (write-char (code-char i
) s
)))
1031 (with-open-file (s *test-path
* :external-format
'(:latin-8
))
1032 (let ((string (make-string 256)))
1033 (read-sequence string s
)
1035 (assert (= (char-code (char string i
)) i
)))
1036 (assert (= 31 (count #\? string
:start
#xa1
))))))
1039 (with-ef-test (:name
(:unibyte-input-replacement
:latin-9
))
1041 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:element-type
'(unsigned-byte 8))
1043 (with-open-file (s *test-path
* :external-format
'(:latin-9
:replacement
#\?))
1044 (let ((char (read-char s
)))
1045 (assert (or (and (= (char-code char
) i
)
1046 (not (member i
'(#xa4
#xa6
#xa8
#xb4
#xb8
#xbc
#xbd
#xbe
))))
1047 (and (member i
'(#xa4
#xa6
#xa8
#xb4
#xb8
#xbc
#xbd
#xbe
))
1048 (not (char= char
#\?)))))))))
1050 (with-ef-test (:name
(:unibyte-output-replacement
:latin-9
))
1051 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:external-format
'(:latin-9
:replacement
#\?))
1053 (write-char (code-char i
) s
)))
1054 (with-open-file (s *test-path
* :external-format
'(:latin-9
))
1055 (let ((string (make-string 256)))
1056 (read-sequence string s
)
1058 (assert (= (char-code (char string i
)) i
)))
1059 (assert (= 8 (count #\? string
:start
#xa4
))))))
1062 (with-ef-test (:name
(:unibyte-input-replacement
:koi8-r
)
1063 :skipped-on
:unicode-lite
)
1065 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:element-type
'(unsigned-byte 8))
1067 (with-open-file (s *test-path
* :external-format
'(:koi8-r
:replacement
#\?))
1068 (let ((char (read-char s
)))
1069 (cond ((= (char-code char
) i
)
1071 (t (assert (> i
127))))))))
1073 (with-ef-test (:name
(:unibyte-output-replacement
:koi8-r
))
1074 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:external-format
'(:koi8-r
:replacement
#\?))
1076 (write-char (code-char i
) s
)))
1077 (with-open-file (s *test-path
* :external-format
'(:koi8-r
))
1078 (let ((string (make-string 256)))
1079 (read-sequence string s
)
1081 (assert (= (char-code (char string i
)) i
)))
1082 (assert (= 122 (count #\? string
:start
#x80
))))))
1085 (with-ef-test (:name
(:unibyte-input-replacement
:koi8-u
))
1087 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:element-type
'(unsigned-byte 8))
1089 (with-open-file (s *test-path
* :external-format
'(:koi8-u
:replacement
#\?))
1090 (let ((char (read-char s
)))
1091 (cond ((= (char-code char
) i
)
1093 (t (assert (> i
127))))))))
1095 (with-ef-test (:name
(:unibyte-output-replacement
:koi8-u
))
1096 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:external-format
'(:koi8-u
:replacement
#\?))
1098 (write-char (code-char i
) s
)))
1099 (with-open-file (s *test-path
* :external-format
'(:koi8-u
))
1100 (let ((string (make-string 256)))
1101 (read-sequence string s
)
1103 (assert (= (char-code (char string i
)) i
)))
1104 (assert (= 122 (count #\? string
:start
#x80
))))))
1106 ;;; x-mac-cyrillic tests
1107 (with-ef-test (:name
(:unibyte-input-replacement
:x-mac-cyrillic
))
1109 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:element-type
'(unsigned-byte 8))
1111 (with-open-file (s *test-path
* :external-format
'(:x-mac-cyrillic
:replacement
#\?))
1112 (let ((char (read-char s
)))
1113 (cond ((= (char-code char
) i
)
1114 (assert (or (< i
128) (member i
'(#xa2
#xa3
#xa9
#xb1
#xb5
)))))
1115 (t (assert (and (> i
127)
1116 (not (member i
'(#xa2
#xa3
#xa9
#xb1
#xb5
)))))))))))
1118 (with-ef-test (:name
(:unibyte-output-replacement
:x-mac-cyrillic
))
1119 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:external-format
'(:x-mac-cyrillic
:replacement
#\?))
1121 (write-char (code-char i
) s
)))
1122 (with-open-file (s *test-path
* :external-format
'(:x-mac-cyrillic
))
1123 (let ((string (make-string 256)))
1124 (read-sequence string s
)
1126 (assert (= (char-code (char string i
)) i
)))
1127 (assert (= 113 (count #\? string
:start
#x80
))))))
1130 (with-test (:name
(:multibyte
:ucs2le
))
1132 (array (map-into (make-array size
:element-type
'(unsigned-byte 16))
1133 (lambda () (random #x10000
)))))
1134 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:element-type
'(unsigned-byte 8))
1136 (write-byte (ldb (byte 8 0) (aref array i
)) s
)
1137 (write-byte (ldb (byte 8 8) (aref array i
)) s
)))
1138 (with-open-file (s *test-path
* :external-format
:ucs2le
)
1139 (let ((string (make-string size
)))
1140 (read-sequence string s
)
1142 (assert (= (char-code (char string i
)) (aref array i
))))))))
1144 (with-test (:name
(:multibyte
:ucs2be
))
1146 (array (map-into (make-array size
:element-type
'(unsigned-byte 16))
1147 (lambda () (random #x10000
)))))
1148 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:element-type
'(unsigned-byte 8))
1150 (write-byte (ldb (byte 8 8) (aref array i
)) s
)
1151 (write-byte (ldb (byte 8 0) (aref array i
)) s
)))
1152 (with-open-file (s *test-path
* :external-format
:ucs2be
)
1153 (let ((string (make-string size
)))
1154 (read-sequence string s
)
1156 (assert (= (char-code (char string i
)) (aref array i
))))))))
1158 (with-test (:name
(:multibyte
:output-replacement
:ucs2le
))
1160 (string (map-into (make-string size
)
1161 (lambda () (code-char (random #x10000
))))))
1162 (setf (char string
0) (code-char #x10001
)
1163 (char string
(1- size
)) (code-char #x10002
))
1164 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:external-format
'(:ucs2le
:replacement
#\replacement_character
))
1165 (write-string string s
))
1166 (with-open-file (s *test-path
* :external-format
:ucs2le
)
1167 (let ((new (make-string size
)))
1168 (read-sequence new s
)
1169 (assert (char= (char new
0) #\replacement_character
))
1170 (assert (char= (char new
(1- size
)) #\replacement_character
))
1171 (assert (string= string new
:start1
1 :start2
1 :end1
(1- size
) :end2
(1- size
)))))))
1173 (with-test (:name
(:multibyte
:output-replacement
:ucs2be
))
1175 (string (map-into (make-string size
)
1176 (lambda () (code-char (random #x10000
))))))
1177 (setf (char string
0) (code-char #x10001
)
1178 (char string
(1- size
)) (code-char #x10002
))
1179 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:external-format
'(:ucs2be
:replacement
#\replacement_character
))
1180 (write-string string s
))
1181 (with-open-file (s *test-path
* :external-format
:ucs2be
)
1182 (let ((new (make-string size
)))
1183 (read-sequence new s
)
1184 (assert (char= (char new
0) #\replacement_character
))
1185 (assert (char= (char new
(1- size
)) #\replacement_character
))
1186 (assert (string= string new
:start1
1 :start2
1 :end1
(1- size
) :end2
(1- size
)))))))
1188 (with-test (:name
(:multibyte
:input-replacement
:ucs4le
))
1189 (let ((octets (coerce '(0 1 1 0 1 0 0 1) '(vector (unsigned-byte 8)))))
1190 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:element-type
'(unsigned-byte 8))
1191 (write-sequence octets s
))
1192 (with-open-file (s *test-path
* :external-format
'(:ucs4le
:replacement
#\replacement_character
))
1193 (let ((string (read-line s
)))
1194 (assert (char= (char string
0) (code-char #x10100
)))
1195 (assert (char= (char string
1) #\replacement_character
))))))
1197 (with-test (:name
(:multibyte
:input-replacement
:ucs4le
))
1198 (let ((octets (coerce '(0 1 1 0 1 0 0 1) '(vector (unsigned-byte 8)))))
1199 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
:element-type
'(unsigned-byte 8))
1200 (write-sequence octets s
))
1201 (with-open-file (s *test-path
* :external-format
'(:ucs4be
:replacement
#\replacement_character
))
1202 (let ((string (read-line s
)))
1203 (assert (char= (char string
0) (code-char #x10100
)))
1204 (assert (char= (char string
1) #\replacement_character
))))))
1207 (with-test (:name
(:utf-16le
:roundtrip
))
1208 (let ((string (map 'string
'code-char
'(#x20
#x200
#x2000
#xfffd
#x10fffd
))))
1209 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
1210 :external-format
:utf-16le
)
1211 (write-string string s
))
1212 (with-open-file (s *test-path
* :external-format
:utf-16le
)
1213 (assert (string= string
(read-line s
))))))
1214 (with-test (:name
(:utf-16be
:roundtrip
))
1215 (let ((string (map 'string
'code-char
'(#x20
#x200
#x2000
#xfffd
#x10fffd
))))
1216 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
1217 :external-format
:utf-16be
)
1218 (write-string string s
))
1219 (with-open-file (s *test-path
* :external-format
:utf-16be
)
1220 (assert (string= string
(read-line s
))))))
1221 (with-test (:name
(:utf-16le
:encoding-error
))
1222 (let ((string (map 'string
'code-char
'(#x20
#xfffe
#xdc00
#xd800
#x1fffe
#x20
))))
1223 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
1224 :external-format
'(:utf-16le
:replacement
#\?))
1225 (write-string string s
))
1226 (with-open-file (s *test-path
* :external-format
:utf-16le
)
1227 (assert (string= " ???? " (read-line s
))))))
1228 (with-test (:name
(:utf-16be
:encoding-error
))
1229 (let ((string (map 'string
'code-char
'(#x20
#xfffe
#xdc00
#xd800
#x1fffe
#x20
))))
1230 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
1231 :external-format
'(:utf-16be
:replacement
#\?))
1232 (write-string string s
))
1233 (with-open-file (s *test-path
* :external-format
:utf-16be
)
1234 (assert (string= " ???? " (read-line s
))))))
1236 (with-test (:name
(:utf-32le
:roundtrip
))
1237 (let ((string (map 'string
'code-char
'(#x20
#x200
#x2000
#xfffd
#x10fffd
))))
1238 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
1239 :external-format
:utf-32le
)
1240 (write-string string s
))
1241 (with-open-file (s *test-path
* :external-format
:utf-32le
)
1242 (assert (string= string
(read-line s
))))))
1243 (with-test (:name
(:utf-32be
:roundtrip
))
1244 (let ((string (map 'string
'code-char
'(#x20
#x200
#x2000
#xfffd
#x10fffd
))))
1245 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
1246 :external-format
:utf-32be
)
1247 (write-string string s
))
1248 (with-open-file (s *test-path
* :external-format
:utf-32be
)
1249 (assert (string= string
(read-line s
))))))
1250 (with-test (:name
(:utf-32le
:encoding-error
))
1251 (let ((string (map 'string
'code-char
'(#x20
#xfffe
#xdc00
#xd800
#x1fffe
#x20
))))
1252 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
1253 :external-format
'(:utf-32le
:replacement
#\?))
1254 (write-string string s
))
1255 (with-open-file (s *test-path
* :external-format
:utf-32le
)
1256 (assert (string= " ???? " (read-line s
))))))
1257 (with-test (:name
(:utf-32be
:encoding-error
))
1258 (let ((string (map 'string
'code-char
'(#x20
#xfffe
#xdc00
#xd800
#x1fffe
#x20
))))
1259 (with-open-file (s *test-path
* :direction
:output
:if-exists
:supersede
1260 :external-format
'(:utf-32be
:replacement
#\?))
1261 (write-string string s
))
1262 (with-open-file (s *test-path
* :external-format
:utf-32be
)
1263 (assert (string= " ???? " (read-line s
))))))
1265 (with-test (:name
:invalid-external-format
)
1266 (labels ((test-error (e)
1267 (assert (typep e
'error
))
1268 (unless (equal "Undefined external-format: :BAD-FORMAT"
1269 (princ-to-string e
))
1270 (error "Bad error:~% ~A" e
)))
1274 (open #-win32
"/dev/null" #+win32
"nul" :direction direction
:external-format
:bad-format
1275 :if-exists
:overwrite
)
1282 (run-program "sh" '() :input
:stream
:external-format
:bad-format
)
1286 (string-to-octets "foobar" :external-format
:bad-format
)
1289 (let ((octets (string-to-octets "foobar" :external-format
:latin1
)))
1291 (octets-to-string octets
:external-format
:bad-format
)
1294 (with-ef-test (:name
(:lp713063
:euc-jp
))
1295 (with-open-file (f *test-path
*
1297 :external-format
'(:euc-jp
:replacement
#\?)
1298 :if-exists
:supersede
)
1299 (write-string (make-string 3 :initial-element
#\horizontal_bar
) f
))
1300 (assert (equal "???"
1301 (with-open-file (f *test-path
*
1303 :external-format
:euc-jp
)
1306 ;; test for lp#659107
1307 (with-test (:name
:cmdline-setq-external-format
1308 :skipped-on
(not :sb-unicode
))
1309 (with-scratch-file (script "lisp")
1310 (with-open-file (stream script
:direction
:output
1311 :if-exists
:supersede
1312 :if-does-not-exist
:create
1313 :external-format
:utf16le
)
1314 (format stream
"(defvar s \"what? ~A\"~%)" (name-char "GRINNING_FACE"))
1315 (format stream
"(sb-ext:exit :code
1316 (if (and (string= (subseq s 0 6) \"what? \") (char= (char s 6) #\\grinning_face)) 0 1))~%"))
1317 (let ((process (run-program
1318 sb-ext
:*runtime-pathname
*
1319 (list "--core" sb-int
:*core-string
*
1320 "--noinform" "--no-sysinit" "--no-userinit" "--noprint"
1321 "--disable-debugger"
1322 "--eval" "(setq *default-external-format* :utf16le)"
1325 (assert (zerop (process-exit-code process
))))))
1327 (delete-file *test-path
*)