Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
21.string.io.cpp
Go to the documentation of this file.
1
28#include <string> // for string
29#include <cstddef> // for size_t
30#include <istream> // for istream
31#include <ostream> // for ostream
32#include <locale> // for locale
33
34#include <rw_strings.h> // for StringMembers
35#include <rw_driver.h> // for rw_test()
36#include <rw_allocator.h> // for UserAlloc
37#include <rw_char.h> // for rw_expand()
38#include <rw_ctype.h> // for UserCtype
39#include <rw_new.h> // for bad_alloc, replacement operator new
40#include <rw_streambuf.h> // for MyStreambuf
41
42
44static const char* const exceptions[] = {
45 "unknown exception", "ios_base::failure", "bad_alloc", "exception"
46};
47
48
50// for convenience
51#define Good std::ios_base::goodbit
52#define Eof std::ios_base::eofbit
53#define Fail std::ios_base::failbit
54#define Bad std::ios_base::badbit
55#define NotGood (Eof | Fail | Bad)
56
57#define Skipws std::ios_base::skipws
58#define Left std::ios_base::left
59#define Right std::ios_base::right
60
61#define WHITESPACE " \f\n\r\t\v"
62
63const char SYMB_THROW = '!';
64
65// off - width
66// size - fmtflags
67// off2 - iostate or exceptions mask
68// size2 - expected iostate or -1 if not verifyed
69// val - expected width
70// str - controlled sequence
71// arg - sequence in stream
72// res - expected result
73
74// bthrow == 0 - off2 is initial stream state
75// == 1 - off2 is exceptions mask
76
77// used to exercise
78// operator>> (istream&, string&)
79static const StringTestCase
80extractor_test_cases [] = {
81
82#undef TEST
83#define TEST(str, arg, width, flags, state, res, res_width, res_st, bthrow) { \
84 __LINE__, width, flags, state, res_st, res_width, \
85 str, sizeof (str) - 1, arg, sizeof (arg) - 1, \
86 res, sizeof (res) - 1, bthrow \
87}
88
89 // 1.
90 // the string argument and stream width should be unchanged when
91 // the stream's initial state is not good, or the initial state
92 // is good and skipws is set and the stream's buffer contains only
93 // whitespace characters or is empty
94
95 // +----------------------------------------------- initial string
96 // | +------------------------------------------ sequence in stream
97 // | | +------------------------------ stream width
98 // | | | +-------------------------- stream flags
99 // | | | | +------------------ stream state
100 // | | | | | or exceptions
101 // | | | | | +--------- expected result
102 // | | | | | | +------- expected width
103 // | | | | | | | +--- expected state
104 // | | | | | | | | +- exception info:
105 // | | | | | | | | | 0 - no exception
106 // | | | | | | | | | 1 - ios_base::failure
107 // | | | | | | | | | -1 - exc. safety
108 // | | | | | | | | |
109 // | | | | | | | | +------------+
110 // | | | | | | | +--+ |
111 // | | | | | | +--+ | |
112 // | | | | | | | | |
113 // V V V V V V V V V
114
115#undef TEST1
116#define TEST1(str) \
117 TEST (str, "", 0, 0, Eof, str, 0, Eof, 0), \
118 TEST (str, "", 1, 0, Fail, str, 1, Fail, 0), \
119 TEST (str, "", 2, 0, Bad, str, 2, Bad, 0), \
120 TEST (str, "", 3, Skipws, Eof, str, 3, Eof, 0), \
121 TEST (str, "", 4, Skipws, Fail, str, 4, Fail, 0), \
122 TEST (str, "", 5, Skipws, Bad, str, 5, Bad, 0), \
123 TEST (str, "", 6, Skipws, Good, str, 6, Eof | Fail, 0), \
124 TEST (str, WHITESPACE, 7, 0, Eof, str, 7, Eof, 0), \
125 TEST (str, WHITESPACE, 8, 0, Fail, str, 8, Fail, 0), \
126 TEST (str, WHITESPACE, 9, 0, Bad, str, 9, Bad, 0), \
127 TEST (str, WHITESPACE, 10, Skipws, Eof, str, 10, Eof, 0), \
128 TEST (str, WHITESPACE, 11, Skipws, Fail, str, 11, Fail, 0), \
129 TEST (str, WHITESPACE, 12, Skipws, Bad, str, 12, Bad, 0), \
130 TEST (str, WHITESPACE, 13, Skipws, Good, str, 13, Eof | Fail, 0), \
131 TEST (str, "", 14, Skipws, NotGood, str, 14, Eof | Fail, 1), \
132 TEST (str, WHITESPACE, 15, Skipws, NotGood, str, 15, Eof | Fail, 1)
133
134 // +----------------------------------------- controlled sequence
135 // |
136 // |
137 // V
138 TEST1 ("" ),
139 TEST1 ("ab" ),
140 TEST1 ("abc" ),
141 TEST1 ("<U0>" ),
142 TEST1 ("<U0>@2ab" ),
143 TEST1 ("a<U0>@2b" ),
144 TEST1 ("ab<U0>@2" ),
145 TEST1 ("a<U0>b<U0>@2c"),
146 TEST1 ("<U0>ab<U0>@2c"),
147 TEST1 ("x@4096" ),
148
149 // 2.
150 // the string argument should be cleared when the stream's initial
151 // state is good and skipws is not set and the stream's buffer is
152 // empty or contains a string which begins with whitespace
153 // width should be reset to 0, and the stream's state should have
154 // failbit set
155
156 // +----------------------------------------------- initial string
157 // | +------------------------------------------ sequence in stream
158 // | | +------------------- stream width
159 // | | | +--------------- stream flags
160 // | | | | +------------ stream state
161 // | | | | | or exceptions
162 // | | | | | +-------- expected result
163 // | | | | | | +----- expected width
164 // | | | | | | | +--- expected state
165 // | | | | | | | | +- exception info:
166 // | | | | | | | | | 0 - no exception
167 // | | | | | | | | | 1 - ios_base::failure
168 // | | | | | | | | | -1 - exc. safety
169 // | | | | | | | | |
170 // | | | | | | | | +-----------------+
171 // | | | | | | | +-------+ |
172 // | | | | | | +-----+ | |
173 // | | | | | +----+ | | |
174 // | | | | | | | | |
175 // V V V V V V V V V
176
177#undef TEST2
178#define TEST2(str) \
179 TEST (str, "", 0, 0, Good, "", 0 , Eof | Fail, 0), \
180 TEST (str, "", 10, 0, Good, "", 0 , Eof | Fail, 0), \
181 TEST (str, WHITESPACE, 0, 0, Good, "", 0 , Fail, 0), \
182 TEST (str, WHITESPACE, 2, 0, Good, "", 0 , Fail, 0), \
183 TEST (str, WHITESPACE, 20, 0, Good, "", 0 , Fail, 0), \
184 TEST (str, WHITESPACE "abc", 0, 0, Good, "", 0 , Fail, 0), \
185 TEST (str, WHITESPACE "abc", 2, 0, Good, "", 0 , Fail, 0), \
186 TEST (str, WHITESPACE "abc", 10, 0, Good, "", 0 , Fail, 0), \
187 TEST (str, WHITESPACE "abc\ndef", 0, 0, Good, "", 0 , Fail, 0), \
188 TEST (str, WHITESPACE "abc\ndef", 3, 0, Good, "", 0 , Fail, 0), \
189 TEST (str, WHITESPACE "abc\ndef", 30, 0, Good, "", 0 , Fail, 0), \
190 TEST (str, WHITESPACE "<U0>@3", 0, 0, Good, "", 0 , Fail, 0), \
191 TEST (str, WHITESPACE "<U0>@3", 2, 0, Good, "", 0 , Fail, 0), \
192 TEST (str, WHITESPACE "<U0>@3", 10, 0, Good, "", 0 , Fail, 0), \
193 TEST (str, "", 0, 0, NotGood, "", 0 , Eof | Fail, 1), \
194 TEST (str, "", 10, 0, NotGood, "", 0 , Eof | Fail, 1), \
195 TEST (str, WHITESPACE, 0, 0, NotGood, "", 0 , Fail, 1), \
196 TEST (str, WHITESPACE, 2, 0, NotGood, "", 0 , Fail, 1), \
197 TEST (str, WHITESPACE, 20, 0, NotGood, "", 0 , Fail, 1), \
198 TEST (str, WHITESPACE "abc", 0, 0, NotGood, "", 0 , Fail, 1), \
199 TEST (str, WHITESPACE "abc", 2, 0, NotGood, "", 0 , Fail, 1), \
200 TEST (str, WHITESPACE "abc", 10, 0, NotGood, "", 0 , Fail, 1), \
201 TEST (str, WHITESPACE "abc\ndef", 0, 0, NotGood, "", 0 , Fail, 1), \
202 TEST (str, WHITESPACE "abc\ndef", 3, 0, NotGood, "", 0 , Fail, 1), \
203 TEST (str, WHITESPACE "abc\ndef", 30, 0, NotGood, "", 0 , Fail, 1), \
204 TEST (str, WHITESPACE "<U0>@3", 0, 0, NotGood, "", 0 , Fail, 1), \
205 TEST (str, WHITESPACE "<U0>@3", 2, 0, NotGood, "", 0 , Fail, 1), \
206 TEST (str, WHITESPACE "<U0>@3", 10, 0, NotGood, "", 0 , Fail, 1)
207
208 // +----------------------------------------- controlled sequence
209 // |
210 // |
211 // V
212 TEST2 ("" ),
213 TEST2 ("ab" ),
214 TEST2 ("abc" ),
215 TEST2 ("<U0>" ),
216 TEST2 ("<U0>@2ab" ),
217 TEST2 ("a<U0>@2b" ),
218 TEST2 ("ab<U0>@2" ),
219 TEST2 ("a<U0>b<U0>@2c"),
220 TEST2 ("<U0>ab<U0>@2c"),
221 TEST2 ("x@4096" ),
222
223
224 // 3.
225 // the string argument should contain the extracted characters when
226 // the stream's initial state is good and either
227 // skipws is clear and the stream's buffer doesn't contain whitespace
228 // or
229 // skipws is set
230 // width should be reset to 0
231
232 // +----------------------------------------------- initial string
233 // | +------------------------------ sequence in stream
234 // | | +------------------------- stream width
235 // | | | +------------------ stream flags
236 // | | | | +----------- stream state
237 // | | | | | or exceptions
238 // | | | | | +-------- expected result
239 // | | | | | | +----- expected width
240 // | | | | | | | +--- expected state
241 // | | | | | | | | +- exception info:
242 // | | | | | | | | | 0 - no exception
243 // | | | | | | | | | 1 - ios_base::failure
244 // | | | | | | | | | -1 - exc. safety
245 // | | | | | | | | |
246 // | | | | | | | | +----------+
247 // | | | | | | | +--------+ |
248 // | | | | | | +------+ | |
249 // | | | | | +-----+ | | |
250 // | | | | | | | | |
251 // V V V V V V V V V
252
253#undef TEST3
254#define TEST3(arg, width, flags, res) \
255 TEST ("", arg, width, flags, Good, res, 0, -1, 0), \
256 TEST ("ab", arg, width, flags, Good, res, 0, -1, 0), \
257 TEST ("abc", arg, width, flags, Good, res, 0, -1, 0), \
258 TEST ("<U0>", arg, width, flags, Good, res, 0, -1, 0), \
259 TEST ("<U0>@2ab", arg, width, flags, Good, res, 0, -1, 0), \
260 TEST ("a<U0>@2b", arg, width, flags, Good, res, 0, -1, 0), \
261 TEST ("ab<U0>@2", arg, width, flags, Good, res, 0, -1, 0), \
262 TEST ("a<U0>b<U0>@2c", arg, width, flags, Good, res, 0, -1, 0), \
263 TEST ("<U0>ab<U0>@2c", arg, width, flags, Good, res, 0, -1, 0), \
264 TEST ("x@4096", arg, width, flags, Good, res, 0, -1, 0), \
265 TEST ("", arg, width, flags, NotGood, res, 0, -1, 1), \
266 TEST ("ab", arg, width, flags, NotGood, res, 0, -1, 1), \
267 TEST ("abc", arg, width, flags, NotGood, res, 0, -1, 1), \
268 TEST ("<U0>", arg, width, flags, NotGood, res, 0, -1, 1), \
269 TEST ("<U0>@2ab", arg, width, flags, NotGood, res, 0, -1, 1), \
270 TEST ("a<U0>@2b", arg, width, flags, NotGood, res, 0, -1, 1), \
271 TEST ("ab<U0>@2", arg, width, flags, NotGood, res, 0, -1, 1), \
272 TEST ("a<U0>b<U0>@2c", arg, width, flags, NotGood, res, 0, -1, 1), \
273 TEST ("<U0>ab<U0>@2c", arg, width, flags, NotGood, res, 0, -1, 1), \
274 TEST ("x@4096", arg, width, flags, NotGood, res, 0, -1, 1)
275
276 // +------------------------------------------------- sequence in stream
277 // | +-------------------- stream width
278 // | | +---------------- stream flags
279 // | | | +-------- expected result
280 // | | | |
281 // | | | |
282 // V V V V
283 TEST3 ("a!bc", 1, 0, "a" ),
284 TEST3 ("a!bc", 2, 0, "a!" ),
285 TEST3 ("a!bc", 10, 0, "a!bc"),
286 TEST3 ("ab!c ", 10, 0, "ab!c"),
287 TEST3 ("ab!c\f", 10, 0, "ab!c"),
288 TEST3 ("ab!c\n", 10, 0, "ab!c"),
289 TEST3 ("ab!c\r", 10, 0, "ab!c"),
290 TEST3 ("ab!c\t", 10, 0, "ab!c"),
291 TEST3 ("ab!c\v", 10, 0, "ab!c"),
292
293 TEST3 ("a!bc" WHITESPACE, 0, 0, "a!bc"),
294 TEST3 ("ab!c" WHITESPACE, 2, 0, "ab" ),
295 TEST3 ("abc!" WHITESPACE, 10, 0, "abc!"),
296
297 TEST3 ("abc!", 0, Skipws, "abc!"),
298 TEST3 ("ab!c", 2, Skipws, "ab" ),
299 TEST3 ("a!bc", 10, Skipws, "a!bc"),
300
301 TEST3 ("abc" WHITESPACE, 0, Skipws, "abc" ),
302 TEST3 ("abc" WHITESPACE, 2, Skipws, "ab" ),
303 TEST3 ("abc" WHITESPACE, 10, Skipws, "abc" ),
304
305 TEST3 (WHITESPACE "abc", 0, Skipws, "abc" ),
306 TEST3 (WHITESPACE "abc", 2, Skipws, "ab" ),
307 TEST3 (WHITESPACE "abc", 30, Skipws, "abc" ),
308
309 TEST3 (WHITESPACE "abc" WHITESPACE, 0, Skipws, "abc" ),
310 TEST3 (WHITESPACE "abc" WHITESPACE, 2, Skipws, "ab" ),
311 TEST3 (WHITESPACE "abc" WHITESPACE, 30, Skipws, "abc" )
312};
313
314
316// off - width
317// size - fmtflags
318// off2 - iostate or exceptions mask
319// size2 - expected iostate or -1 if not verifyed
320// val - unused
321// str - controlled sequence
322// arg - sequence in stream
323// res - expected result
324
325// bthrow == 0 - off2 is initial stream state
326// == 1 - off2 is exceptions mask
327
328// used to exercise
329// getline (istream&, string&)
330static const StringTestCase
331getline_test_cases [] = {
332
333#undef TEST
334#define TEST(str, arg, width, flags, state, res, res_width, res_st, bthrow) { \
335 __LINE__, width, flags, state, res_st, res_width, \
336 str, sizeof (str) - 1, arg, sizeof (arg) - 1, \
337 res, sizeof (res) - 1, bthrow \
338}
339
340 // 1.
341 // string and width should be unchanged when initial iostate is not good
342
343 // +---------------------------------------------- controlled sequence
344 // | +----------------------------------------- sequence in stream
345 // | | +-------------------------- stream width
346 // | | | +---------------------- stream flags
347 // | | | | +-------------- stream state
348 // | | | | | or exceptions
349 // | | | | | +-------- expected result
350 // | | | | | | +----- unused
351 // | | | | | | | +--- expected state
352 // | | | | | | | | +- exception info:
353 // | | | | | | | | | 0 - no exception
354 // | | | | | | | | | 1 - ios_base::failure
355 // | | | | | | | | | -1 - exc. safety
356 // | | | | | | | | |
357 // | | | | | | | | +---------+
358 // | | | | | | | +-----+ |
359 // | | | | | | +---+ | |
360 // | | | | | +--+ | | |
361 // | | | | | | | | |
362 // V V V V V V V V V
363
364#undef TEST1
365#define TEST1(str) \
366 TEST (str, "", 0, 0, Eof, str, 0, Eof, 0), \
367 TEST (str, "", 1, 0, Fail, str, 0, Fail, 0), \
368 TEST (str, "", 2, 0, Bad, str, 0, Bad, 0), \
369 TEST (str, "", 3, Skipws, Eof, str, 0, Eof, 0), \
370 TEST (str, "", 4, Skipws, Fail, str, 0, Fail, 0), \
371 TEST (str, "", 5, Skipws, Bad, str, 0, Bad, 0), \
372 TEST (str, WHITESPACE, 7, 0, Eof, str, 0, Eof, 0), \
373 TEST (str, WHITESPACE, 8, 0, Fail, str, 0, Fail, 0), \
374 TEST (str, WHITESPACE, 9, 0, Bad, str, 0, Bad, 0), \
375 TEST (str, WHITESPACE, 10, Skipws, Eof, str, 0, Eof, 0), \
376 TEST (str, WHITESPACE, 11, Skipws, Fail, str, 0, Fail, 0), \
377 TEST (str, WHITESPACE, 12, Skipws, Bad, str, 0, Bad, 0), \
378 TEST (str, "abc", 13, 0, Eof, str, 0, Eof, 0), \
379 TEST (str, "x@4096", 14, 0, Fail, str, 0, Fail, 0), \
380 TEST (str, "<U0>abc<U0>", 15, 0, Bad, str, 0, Bad, 0), \
381 TEST (str, "abc\ndef", 16, Skipws, Eof, str, 0, Eof, 0), \
382 TEST (str, " \tabc", 17, Skipws, Fail, str, 0, Fail, 0), \
383 TEST (str, "\n\n<U0>\n", 18, Skipws, Bad, str, 0, Bad, 0)
384
385 // +----------------------------------------- controlled sequence
386 // |
387 // |
388 // V
389 TEST1 ("" ),
390 TEST1 ("ab" ),
391 TEST1 ("abc" ),
392 TEST1 ("<U0>" ),
393 TEST1 ("<U0>@2ab" ),
394 TEST1 ("a<U0>@2b" ),
395 TEST1 ("ab<U0>@2" ),
396 TEST1 ("a<U0>b<U0>@2c"),
397 TEST1 ("<U0>ab<U0>@2c"),
398 TEST1 ("x@4096" ),
399
400
401 // 2.
402 // string should be erased when initial iostate is good and
403 // stream empty or contains string which begins from '\n'
404 // width should be unchanged, iostate should have failbit setted
405
406 // +--------------------------------------------- controlled sequence
407 // | +---------------------------------------- sequence in stream
408 // | | +-------------------------- stream width
409 // | | | +---------------------- stream flags
410 // | | | | +-------------- stream state
411 // | | | | | or exceptions
412 // | | | | | +-------- expected result
413 // | | | | | | +----- unused
414 // | | | | | | | +--- expected state
415 // | | | | | | | | +- exception info:
416 // | | | | | | | | | 0 - no exception
417 // | | | | | | | | | 1 - ios_base::failure
418 // | | | | | | | | | -1 - exc. safety
419 // | | | | | | | | |
420 // | | | | | | | | +--------------+
421 // | | | | | | | +----+ |
422 // | | | | | | +---+ | |
423 // | | | | | +--+ | | |
424 // | | | | | | | | |
425 // V V V V V V V V V
426
427#undef TEST2
428#define TEST2(str) \
429 TEST (str, "", 0, Skipws, Good, "", 0, Eof | Fail, 0), \
430 TEST (str, "", 10, 0, Good, "", 0, Eof | Fail, 0), \
431 TEST (str, "\n", 0, Skipws, Good, "", 0, Good, 0), \
432 TEST (str, "\n", 2, 0, Good, "", 0, Good, 0), \
433 TEST (str, "\nabc", 0, Skipws, Good, "", 0, Good, 0), \
434 TEST (str, "\nabc", 2, 0, Good, "", 0, Good, 0), \
435 TEST (str, "\nabc\ndef", 0, Skipws, Good, "", 0, Good, 0), \
436 TEST (str, "\nabc\ndef", 3, 0, Good, "", 0, Good, 0), \
437 TEST (str, "\n<U0>@3", 0, Skipws, Good, "", 0, Good, 0), \
438 TEST (str, "\n<U0>@3", 2, 0, Good, "", 0, Good, 0), \
439 TEST (str, "", 0, Skipws, NotGood, "", 0, Eof | Fail, 1), \
440 TEST (str, "", 10, 0, NotGood, "", 0, Eof | Fail, 1), \
441 TEST (str, "\n", 0, Skipws, NotGood, "", 0, Good, 1), \
442 TEST (str, "\n", 2, 0, NotGood, "", 0, Good, 1), \
443 TEST (str, "\nabc", 0, Skipws, NotGood, "", 0, Good, 1), \
444 TEST (str, "\nabc", 2, 0, NotGood, "", 0, Good, 1), \
445 TEST (str, "\nabc\ndef", 0, Skipws, NotGood, "", 0, Good, 1), \
446 TEST (str, "\nabc\ndef", 3, 0, NotGood, "", 0, Good, 1), \
447 TEST (str, "\n<U0>@3", 0, Skipws, NotGood, "", 0, Good, 1), \
448 TEST (str, "\n<U0>@3", 2, 0, NotGood, "", 0, Good, 1)
449
450 // +----------------------------------------- controlled sequence
451 // |
452 // |
453 // V
454 TEST2 ("" ),
455 TEST2 ("ab" ),
456 TEST2 ("abc" ),
457 TEST2 ("<U0>" ),
458 TEST2 ("<U0>@2ab" ),
459 TEST2 ("a<U0>@2b" ),
460 TEST2 ("ab<U0>@2" ),
461 TEST2 ("a<U0>b<U0>@2c"),
462 TEST2 ("<U0>ab<U0>@2c"),
463 TEST2 ("x@4096" ),
464
465
466 // 3.
467 // string should be compared with result when initial iostate is good
468 // and stream string begins from not '\n'
469 // width should be unchanged
470
471 // +----------------------------------------------- controlled sequence
472 // | +------------------------------ sequence in stream
473 // | | +------------------------- stream width
474 // | | | +--------------------- stream flags
475 // | | | | +------------- stream state
476 // | | | | | or exceptions
477 // | | | | | +-------- expected result
478 // | | | | | | +----- unused
479 // | | | | | | | +--- expected state
480 // | | | | | | | | +- exception info:
481 // | | | | | | | | | 0 - no exception
482 // | | | | | | | | | 1 - ios_base::failure
483 // | | | | | | | | | -1 - exc. safety
484 // | | | | | | | | |
485 // | | | | | | | | +--------+
486 // | | | | | | | +------+ |
487 // | | | | | | +-----+ | |
488 // | | | | | +---+ | | |
489 // | | | | | | | | |
490 // V V V V V V V V V
491
492#undef TEST3
493#define TEST3(arg, res) \
494 TEST ("", arg, 0, Skipws, Good, res, 0, -1, 0), \
495 TEST ("ab", arg, 1, 0, Good, res, 0, -1, 0), \
496 TEST ("abc", arg, 2, Skipws, Good, res, 0, -1, 0), \
497 TEST ("<U0>", arg, 3, 0, Good, res, 0, -1, 0), \
498 TEST ("<U0>@2ab", arg, 4, Skipws, Good, res, 0, -1, 0), \
499 TEST ("a<U0>@2b", arg, 5, 0, Good, res, 0, -1, 0), \
500 TEST ("ab<U0>@2", arg, 6, Skipws, Good, res, 0, -1, 0), \
501 TEST ("a<U0>b<U0>@2c", arg, 7, 0, Good, res, 0, -1, 0), \
502 TEST ("<U0>ab<U0>@2c", arg, 8, Skipws, Good, res, 0, -1, 0), \
503 TEST ("x@4096", arg, 9, 0, Good, res, 0, -1, 0), \
504 TEST ("", arg, 10, Skipws, NotGood, res, 0, -1, 1), \
505 TEST ("ab", arg, 11, 0, NotGood, res, 0, -1, 1), \
506 TEST ("abc", arg, 12, Skipws, NotGood, res, 0, -1, 1), \
507 TEST ("<U0>", arg, 13, 0, NotGood, res, 0, -1, 1), \
508 TEST ("<U0>@2ab", arg, 14, Skipws, NotGood, res, 0, -1, 1), \
509 TEST ("a<U0>@2b", arg, 15, 0, NotGood, res, 0, -1, 1), \
510 TEST ("ab<U0>@2", arg, 16, Skipws, NotGood, res, 0, -1, 1), \
511 TEST ("a<U0>b<U0>@2c", arg, 17, 0, NotGood, res, 0, -1, 1), \
512 TEST ("<U0>ab<U0>@2c", arg, 18, Skipws, NotGood, res, 0, -1, 1), \
513 TEST ("x@4096", arg, 19, 0, NotGood, res, 0, -1, 1)
514
515 // +------------------------------------------------- sequence in stream
516 // | +----------------------- expected result
517 // | |
518 // | |
519 // V V
520 TEST3 ("ab!c", "ab!c" ),
521 TEST3 ("a!b\nc", "a!b" ),
522 TEST3 ("a\n!bc", "a" ),
523 TEST3 (" !\t\n", " !\t" ),
524 TEST3 (" \f\r\t\v\n", " \f\r\t\v" ),
525 TEST3 (" \f\r\n\t\v\n", " \f\r" ),
526 TEST3 ("<U0>a<U0>b<U0>\n<U0>@2", "<U0>a<U0>b<U0>"),
527 TEST3 ("<U0>@7", "<U0>@7" ),
528 TEST3 ("x@4096", "x@4096" ),
529 TEST3 ("x@4096\nx@4096", "x@4096" )
530};
531
532
534// off - width
535// size - fmtflags
536// off2 - iostate or exceptions mask
537// size2 - expected iostate or -1 if not verifyed
538// val - char delim
539// str - controlled sequence
540// arg - sequence in stream
541// res - expected result
542
543// bthrow == 0 - off2 is initial stream state
544// == 1 - off2 is exceptions mask
545
546// used to exercise
547// getline (istream&, string&, char)
548static const StringTestCase
549getline_val_test_cases [] = {
550
551#undef TEST
552#define TEST(str, arg, width, flags, state, res, res_width, res_st, bthrow) { \
553 __LINE__, width, flags, state, res_st, res_width, \
554 str, sizeof (str) - 1, arg, sizeof (arg) - 1, \
555 res, sizeof (res) - 1, bthrow \
556}
557
558 // 1.
559 // string and width should be unchanged when initial iostate is not good
560
561 // +---------------------------------------------- controlled sequence
562 // | +----------------------------------------- sequence in stream
563 // | | +-------------------------- stream width
564 // | | | +---------------------- stream flags
565 // | | | | +-------------- stream state
566 // | | | | | or exceptions
567 // | | | | | +-------- expected result
568 // | | | | | | +----- delim
569 // | | | | | | | +--- expected state
570 // | | | | | | | | +- exception info:
571 // | | | | | | | | | 0 - no exception
572 // | | | | | | | | | 1 - ios_base::failure
573 // | | | | | | | | | -1 - exc. safety
574 // | | | | | | | | |
575 // | | | | | | | | +------------+
576 // | | | | | | | +--------+ |
577 // | | | | | | +----+ | |
578 // | | | | | +--+ | | |
579 // | | | | | | | | |
580 // V V V V V V V V V
581
582#undef TEST1
583#define TEST1(str) \
584 TEST (str, "", 0, 0, Eof, str, '\n', Eof, 0), \
585 TEST (str, "", 1, 0, Fail, str, '\0', Fail, 0), \
586 TEST (str, "", 2, 0, Bad, str, '\r', Bad, 0), \
587 TEST (str, "", 3, Skipws, Eof, str, '\a', Eof, 0), \
588 TEST (str, "", 4, Skipws, Fail, str, '\b', Fail, 0), \
589 TEST (str, "", 5, Skipws, Bad, str, '\t', Bad, 0), \
590 TEST (str, WHITESPACE, 7, 0, Eof, str, '\v', Eof, 0), \
591 TEST (str, WHITESPACE, 8, 0, Fail, str, 'a', Fail, 0), \
592 TEST (str, WHITESPACE, 9, 0, Bad, str, ' ', Bad, 0), \
593 TEST (str, WHITESPACE, 10, Skipws, Eof, str, '1', Eof, 0), \
594 TEST (str, WHITESPACE, 11, Skipws, Fail, str, '5', Fail, 0), \
595 TEST (str, WHITESPACE, 12, Skipws, Bad, str, 'w', Bad, 0), \
596 TEST (str, "abc", 13, 0, Eof, str, 'b', Eof, 0), \
597 TEST (str, "x@4096", 14, 0, Fail, str, 'x', Fail, 0), \
598 TEST (str, "<U0>abc<U0>", 15, 0, Bad, str, 'c', Bad, 0), \
599 TEST (str, "abc\ndef", 16, Skipws, Eof, str, 'e', Eof, 0), \
600 TEST (str, " \tabc", 17, Skipws, Fail, str, '\t', Fail, 0), \
601 TEST (str, "\n\n<U0>\n", 18, Skipws, Bad, str, '\0', Bad, 0)
602
603 // +----------------------------------------- controlled sequence
604 // |
605 // |
606 // V
607 TEST1 ("" ),
608 TEST1 ("ab" ),
609 TEST1 ("abc" ),
610 TEST1 ("<U0>" ),
611 TEST1 ("<U0>@2ab" ),
612 TEST1 ("a<U0>@2b" ),
613 TEST1 ("ab<U0>@2" ),
614 TEST1 ("a<U0>b<U0>@2c"),
615 TEST1 ("<U0>ab<U0>@2c"),
616 TEST1 ("x@4096" ),
617
618
619 // 2.
620 // string should be erased when initial iostate is good and
621 // stream empty or contains string which begins from delim
622 // width should be unchanged, iostate should have failbit setted
623
624 // +--------------------------------------------- controlled sequence
625 // | +---------------------------------------- sequence in stream
626 // | | +-------------------------- stream width
627 // | | | +---------------------- stream flags
628 // | | | | +-------------- stream state
629 // | | | | | or exceptions
630 // | | | | | +-------- expected result
631 // | | | | | | +----- delim
632 // | | | | | | | +--- expected state
633 // | | | | | | | | +- exception info:
634 // | | | | | | | | | 0 - no exception
635 // | | | | | | | | | 1 - ios_base::failure
636 // | | | | | | | | | -1 - exc. safety
637 // | | | | | | | | |
638 // | | | | | | | | +-----------------+
639 // | | | | | | | +-------+ |
640 // | | | | | | +---+ | |
641 // | | | | | +--+ | | |
642 // | | | | | | | | |
643 // V V V V V V V V V
644
645#undef TEST2
646#define TEST2(str) \
647 TEST (str, "", 0, Skipws, Good, "", '\a', Eof | Fail, 0), \
648 TEST (str, "", 10, 0, Good, "", '\0', Eof | Fail, 0), \
649 TEST (str, "<U0>", 0, Skipws, Good, "", '\0', Good, 0), \
650 TEST (str, "\n", 2, 0, Good, "", '\n', Good, 0), \
651 TEST (str, "\rabc", 0, Skipws, Good, "", '\r', Good, 0), \
652 TEST (str, "abc", 2, 0, Good, "", 'a', Good, 0), \
653 TEST (str, "\babc\ndef", 0, Skipws, Good, "", '\b', Good, 0), \
654 TEST (str, "\tabc\ndef", 3, 0, Good, "", '\t', Good, 0), \
655 TEST (str, "\v<U0>@3", 0, Skipws, Good, "", '\v', Good, 0), \
656 TEST (str, " <U0>@3", 2, 0, Good, "", ' ', Good, 0), \
657 TEST (str, "", 0, Skipws, NotGood, "", '\a', Eof | Fail, 1), \
658 TEST (str, "", 10, 0, NotGood, "", '\0', Eof | Fail, 1), \
659 TEST (str, "<U0>", 0, Skipws, NotGood, "", '\0', Good, 1), \
660 TEST (str, "\n", 2, 0, NotGood, "", '\n', Good, 1), \
661 TEST (str, "\rabc", 0, Skipws, NotGood, "", '\r', Good, 1), \
662 TEST (str, "abc", 2, 0, NotGood, "", 'a', Good, 1), \
663 TEST (str, "\babc\ndef", 0, Skipws, NotGood, "", '\b', Good, 1), \
664 TEST (str, "\tabc\ndef", 3, 0, NotGood, "", '\t', Good, 1), \
665 TEST (str, "\v<U0>@3", 0, Skipws, NotGood, "", '\v', Good, 1), \
666 TEST (str, " <U0>@3", 2, 0, NotGood, "", ' ', Good, 1)
667
668 // +----------------------------------------- controlled sequence
669 // |
670 // |
671 // V
672 TEST2 ("" ),
673 TEST2 ("ab" ),
674 TEST2 ("abc" ),
675 TEST2 ("<U0>" ),
676 TEST2 ("<U0>@2ab" ),
677 TEST2 ("a<U0>@2b" ),
678 TEST2 ("ab<U0>@2" ),
679 TEST2 ("a<U0>b<U0>@2c"),
680 TEST2 ("<U0>ab<U0>@2c"),
681 TEST2 ("x@4096" ),
682
683
684 // 3.
685 // string should be compared with result when initial iostate is good
686 // and stream string begins from not delim
687 // width should be unchanged
688
689 // +----------------------------------------------- controlled sequence
690 // | +------------------------------ sequence in stream
691 // | | +------------------------- stream width
692 // | | | +--------------------- stream flags
693 // | | | | +------------- stream state
694 // | | | | | or exceptions
695 // | | | | | +-------- expected result
696 // | | | | | | +----- delim
697 // | | | | | | | +--- expected state
698 // | | | | | | | | +- exception info:
699 // | | | | | | | | | 0 - no exception
700 // | | | | | | | | | 1 - ios_base::failure
701 // | | | | | | | | | -1 - exc. safety
702 // | | | | | | | | |
703 // | | | | | | | | +------------+
704 // | | | | | | | +----------+ |
705 // | | | | | | +-----+ | |
706 // | | | | | +---+ | | |
707 // | | | | | | | | |
708 // V V V V V V V V V
709
710#undef TEST3
711#define TEST3(arg, delim, res) \
712 TEST ("", arg, 0, Skipws, Good, res, delim, -1, 0), \
713 TEST ("ab", arg, 1, 0, Good, res, delim, -1, 0), \
714 TEST ("abc", arg, 2, Skipws, Good, res, delim, -1, 0), \
715 TEST ("<U0>", arg, 3, 0, Good, res, delim, -1, 0), \
716 TEST ("<U0>@2ab", arg, 4, Skipws, Good, res, delim, -1, 0), \
717 TEST ("a<U0>@2b", arg, 5, 0, Good, res, delim, -1, 0), \
718 TEST ("ab<U0>@2", arg, 6, Skipws, Good, res, delim, -1, 0), \
719 TEST ("a<U0>b<U0>@2c", arg, 7, 0, Good, res, delim, -1, 0), \
720 TEST ("<U0>ab<U0>@2c", arg, 8, Skipws, Good, res, delim, -1, 0), \
721 TEST ("x@4096", arg, 9, 0, Good, res, delim, -1, 0), \
722 TEST ("", arg, 10, Skipws, NotGood, res, delim, -1, 1), \
723 TEST ("ab", arg, 11, 0, NotGood, res, delim, -1, 1), \
724 TEST ("abc", arg, 12, Skipws, NotGood, res, delim, -1, 1), \
725 TEST ("<U0>", arg, 13, 0, NotGood, res, delim, -1, 1), \
726 TEST ("<U0>@2ab", arg, 14, Skipws, NotGood, res, delim, -1, 1), \
727 TEST ("a<U0>@2b", arg, 15, 0, NotGood, res, delim, -1, 1), \
728 TEST ("ab<U0>@2", arg, 16, Skipws, NotGood, res, delim, -1, 1), \
729 TEST ("a<U0>b<U0>@2c", arg, 17, 0, NotGood, res, delim, -1, 1), \
730 TEST ("<U0>ab<U0>@2c", arg, 18, Skipws, NotGood, res, delim, -1, 1), \
731 TEST ("x@4096", arg, 19, 0, NotGood, res, delim, -1, 1)
732
733 // +------------------------------------------------- sequence in stream
734 // | +----------------------- delim
735 // | | +----------------- expected result
736 // | | |
737 // | | |
738 // V V V
739 TEST3 ("ab!c", '\t', "ab!c" ),
740 TEST3 ("a!b<U0>c", '\0', "a!b" ),
741 TEST3 ("a\n!bc", 'b', "a\n!" ),
742 TEST3 (" \t\n", '\n', " \t" ),
743 TEST3 (" \f\r\t\v\n", '\v', " \f\r\t" ),
744 TEST3 (" \f\r\n\t\v\n", '\r', " \f" ),
745 TEST3 ("<U0>a<U0>b<U0>\n<U0>@2", 'b', "<U0>a<U0>"),
746 TEST3 ("<U0>@7", '1', "<U0>@7" ),
747 TEST3 ("x@4096", ' ', "x@4096" ),
748 TEST3 ("x@4096yx@4096", 'y', "x@4096" )
749};
750
751
753// off - width
754// size - fmtflags
755// off2 - iostate or exceptions mask
756// size2 - expected iostate or -1 if not verifyed
757// val - expected width
758// str - controlled sequence
759// arg_len - size of streambuf
760// res - expected result
761
762// bthrow == 0 - off2 is initial stream state
763// == 1 - off2 is exceptions mask
764
765// used to exercise
766// operator<< (ostream&, const string&)
767static const StringTestCase
768inserter_test_cases [] = {
769
770#undef TEST
771#define TEST(str, arg, width, flags, state, res, res_width, res_st, bthrow) { \
772 __LINE__, width, flags, state, res_st, res_width, \
773 str, sizeof (str) - 1, 0, arg, res, sizeof (res) - 1, bthrow \
774}
775
776 // 1. if initial state is not good then width should be
777 // unchanged and no data in output stream
778
779 // +----------------------------------------- controlled sequence
780 // | +------------------------------------ size of streambuf
781 // | | +------------------------- stream width
782 // | | | +--------------------- stream flags
783 // | | | | +------------- stream state
784 // | | | | | or exceptions
785 // | | | | | +------- expected result
786 // | | | | | | +----- expected width
787 // | | | | | | | +--- expected state
788 // | | | | | | | | +- exception info:
789 // | | | | | | | | | 0 - no exception
790 // | | | | | | | | | 1 - ios_base::failure
791 // | | | | | | | | | -1 - exc. safety
792 // | | | | | | | | |
793 // | | | | | | | | +-------+
794 // | | | | | | | +---+ |
795 // | | | | | | +-+ | |
796 // | | | | | | | | |
797 // | | | | | | | | |
798 // V V V V V V V V V
799
800#undef TEST1
801#define TEST1(str) \
802 TEST (str, 0, 0, 0, Eof, "", 0, Eof, 0), \
803 TEST (str, 0, 1, 0, Fail, "", 1, Fail, 0), \
804 TEST (str, 0, 2, 0, Bad, "", 2, Bad, 0)
805
806 // +----------------------------------------- controlled sequence
807 // |
808 // |
809 // V
810 TEST1 ("" ),
811 TEST1 ("ab" ),
812 TEST1 ("abc" ),
813 TEST1 ("<U0>" ),
814 TEST1 ("<U0>@2ab" ),
815 TEST1 ("a<U0>@2b" ),
816 TEST1 ("ab<U0>@2" ),
817 TEST1 ("a<U0>b<U0>@2c"),
818 TEST1 ("<U0>ab<U0>@2c"),
819 TEST1 ("x@4096" ),
820
821
822 // 2. if initial state is good then:
823 // if stream has not enough size to get string then badbit should be set
824 // width should be 0
825
826 // +---------------------------------------- controlled sequence
827 // | +----------------------------------- size of streambuf
828 // | | +------------------------------ stream width
829 // | | | +----------------------- stream flags
830 // | | | | +---------------- stream state
831 // | | | | | or exceptions
832 // | | | | | +------- expected result
833 // | | | | | | +----- expected width
834 // | | | | | | | +--- expected state
835 // | | | | | | | | +- exception info:
836 // | | | | | | | | | 0 - no exception
837 // | | | | | | | | | 1 - ios_base::failure
838 // | | | | | | | | | -1 - exc. safety
839 // | | | | | | | | |
840 // | | | | | | | | +-----------------+
841 // | | | | | | | +-----------+ |
842 // | | | | | | +--+ | |
843 // | | | | | | | | |
844 // | | | | | | | | |
845 // V V V V V V V V V
846
847#undef TEST2
848#define TEST2(str, arg, width, flags, res, res_width, res_st) \
849 TEST (str, arg, width, flags, Good, res, res_width, res_st, 0), \
850 TEST (str, arg, width, flags, NotGood, res, res_width, res_st, 1)
851
852 // +------------------------------------------------ controlled sequence
853 // | +------------------------------- size of streambuf
854 // | | +------------------------- stream width
855 // | | | +------------------- stream flags
856 // | | | | +------------ expected result
857 // | | | | | +----- expected width
858 // | | | | | | +-- expected state
859 // | | | | | | |
860 // | | | | | | +---------------+
861 // | | | | | +------------+ |
862 // | | | | | | |
863 // V V V V V V V
864 TEST2 ("", 0, 0, 0, "", 0, Good),
865 TEST2 ("", 0, 0, Right, "", 0, Good),
866 TEST2 ("", 0, 0, Left, "", 0, Good),
867
868 TEST2 ("", 20, 10, 0, " @10", 0, Good),
869 TEST2 ("", 20, 10, Right, " @10", 0, Good),
870 TEST2 ("", 20, 10, Left, " @10", 0, Good),
871
872 TEST2 ("", 5, 10, 0, " @5", 0, Bad ),
873 TEST2 ("", 5, 10, Right, " @5", 0, Bad ),
874 TEST2 ("", 5, 10, Left, " @5", 0, Bad ),
875
876 TEST2 (" @10", 20, 10, 0, " @10", 0, Good),
877 TEST2 (" @10", 20, 10, Right, " @10", 0, Good),
878 TEST2 (" @10", 20, 10, Left, " @10", 0, Good),
879
880 TEST2 ("abc def", 20, 0, 0, "abc def", 0, Good),
881 TEST2 ("abc def", 20, 0, Right, "abc def", 0, Good),
882 TEST2 ("abc def", 20, 0, Left, "abc def", 0, Good),
883
884 TEST2 ("abc def", 5, 0, 0, "abc d", 0, Bad ),
885 TEST2 ("abc def", 5, 0, Right, "abc d", 0, Bad ),
886 TEST2 ("abc def", 5, 0, Left, "abc d", 0, Bad ),
887
888 TEST2 ("abc def", 20, 5, 0, "abc def", 0, Good),
889 TEST2 ("abc def", 20, 5, Right, "abc def", 0, Good),
890 TEST2 ("abc def", 20, 5, Left, "abc def", 0, Good),
891
892 TEST2 ("abc def", 20, 10, 0, " abc def", 0, Good),
893 TEST2 ("abc def", 20, 10, Right, " abc def", 0, Good),
894 TEST2 ("abc def", 20, 10, Left, "abc def ", 0, Good),
895
896 TEST2 ("<U0>", 20, 10, 0, " @9<U0>", 0, Good),
897 TEST2 ("<U0>", 20, 10, Right, " @9<U0>", 0, Good),
898 TEST2 ("<U0>", 20, 10, Left, "<U0> @9", 0, Good),
899
900 TEST2 ("<U0>ab<U0>@2c", 20, 10, 0, " @4<U0>ab<U0>@2c", 0, Good),
901 TEST2 ("<U0>ab<U0>@2c", 20, 10, Right, " @4<U0>ab<U0>@2c", 0, Good),
902 TEST2 ("<U0>ab<U0>@2c", 20, 10, Left, "<U0>ab<U0>@2c @4", 0, Good),
903
904 TEST2 ("x@4096", 4096, 10, 0, "x@4096", 0, Good),
905 TEST2 ("x@4096", 4096, 10, Right, "x@4096", 0, Good),
906 TEST2 ("x@4096", 4096, 10, Left, "x@4096", 0, Good),
907
908 TEST2 ("x@4096", 4097, 4097, 0, " x@4096", 0, Good),
909 TEST2 ("x@4096", 4097, 4097, Right, " x@4096", 0, Good),
910 TEST2 ("x@4096", 4097, 4097, Left, "x@4096 ", 0, Good)
911};
912
913
915template <class charT, class Traits, class Allocator>
917 const StringTestCaseData<charT> &tdata)
918{
919 typedef std::basic_string <charT, Traits, Allocator> String;
921 typedef std::basic_ios<charT, Traits> BasicIos;
922 typedef std::basic_istream<charT, Traits> Istream;
923 typedef std::basic_ostream<charT, Traits> Ostream;
924
925 typedef std::ios_base::fmtflags Fmtflags;
926 typedef std::ios_base::iostate Iostate;
927
928 const StringFunc &func = tdata.func_;
929 const StringTestCase &tcase = tdata.tcase_;
930
931 bool test_inserter = func.which_ == StringIds::inserter_ostream_cstr;
932
933 // construct the string object
934 String str (tdata.str_, tdata.strlen_);
935 // construct a const reference to the string object
936 // for tests exercising output
937 const String& cstr (str);
938
939 static const std::size_t BUFSIZE = 256;
940
941 static char arg_buf [BUFSIZE];
942
943 std::size_t arg_len = 0;
944 const char* arg = rw_expand (arg_buf, tcase.arg, tcase.arg_len, &arg_len);
945
946 // prepare arrays of indexes on which force the exception throwing
947 const charT* arg_throw = test_inserter ? tdata.str_ : tdata.arg_;
948 const std::size_t arg_throw_len =
949 test_inserter ? tdata.strlen_ : tdata.arglen_;
950
951 std::size_t* throw_on = new std::size_t [arg_throw_len + 1];
952 std::size_t pthrow = 0;
953 for (std::size_t k = 0; k < arg_throw_len; ++k) {
954 if (1 == rw_match (&SYMB_THROW, arg_throw + k, 1))
955 throw_on [pthrow++] = k + 1;
956 }
957 throw_on [pthrow] = NPOS;
958
959 // construct ctype facet to install in each stream's locale
960 // (the facet's lifetime must exceed that of the locale in
961 // which it is installed, which might include both the stream
962 // and the stream's streambuf)
963 const UserCtype<charT> ctyp (1);
964
965 // set the initial formatting flags in both streams
966 const Fmtflags flags = Fmtflags (tcase.size);
967
968 // save the state of the const string object before the call
969 // to any (changes to the state of the object after a call)
970 const StringState cstr_state (rw_get_string_state (cstr));
971
972 // Xsgetn, Sync, Xsputn
973 std::size_t throw_count [] = { 1, 1, 1 };
974 std::size_t throw_inx = 0;
975
976 while (1) {
977
978 Streambuf inbuf (arg, arg_len, Throw | Underflow | Sync | Xsgetn, -1);
979
980 Streambuf outbuf (std::streamsize (tcase.arg_len),
981 Throw | Overflow | Sync | Xsputn, -1);
982
983 Streambuf& sbuf = test_inserter ? outbuf : inbuf;
984
985#ifndef _RWSTD_NO_EXCEPTIONS
986
987 // (name of) expected and caught exception
988 const char* expected = 0;
989 const char* caught = 0;
990
991 if (1 == tcase.bthrow) {
992 expected = exceptions [1]; // ios_base::failure
993 }
994 else if (0 == tcase.bthrow) {
995 // set on which call of which method to throw
996 sbuf.throw_when_ [sbuf.memfun_inx (
997 test_inserter ? Overflow : Underflow) ] =
998 int (throw_on [throw_inx]);
999
1000 sbuf.throw_when_ [sbuf.memfun_inx (Xsgetn)] =
1001 int (throw_count [0]);
1002 sbuf.throw_when_ [sbuf.memfun_inx (Sync)] =
1003 int (throw_count [1]);
1004 sbuf.throw_when_ [sbuf.memfun_inx (Xsputn)] =
1005 int (throw_count [2]);
1006 }
1007 else {
1008 // exceptions disabled for this test case
1009 }
1010
1011#else // if defined (_RWSTD_NO_EXCEPTIONS)
1012
1013 if (tcase.bthrow)
1014 return;
1015
1016#endif // _RWSTD_NO_EXCEPTIONS
1017
1018 // construct both stream objects even though only one will be used
1019 Istream is (&inbuf);
1020 Ostream os (&outbuf);
1021
1022 // base referes to the basic_ios subobject of the stream used in
1023 // each test case (to avoid unnecessarily manipulating both streams)
1024 BasicIos &strm = test_inserter ? (BasicIos&)os : (BasicIos&)is;
1025
1026 // install std::ctype<UserChar> facet
1027 strm.imbue (std::locale (strm.getloc (), &ctyp));
1028
1029 // set the initial width of both streams
1030 strm.width (tcase.off);
1031
1032 strm.flags (flags);
1033
1034 const Iostate state = Iostate (tcase.off2);
1035
1036 if (tcase.bthrow) {
1037 // set exception bits leaving the initial stream state good
1038 strm.exceptions (state);
1039 }
1040 else {
1041 // set the initial stream state leaving exceptions clear
1042 strm.clear (state);
1043 }
1044
1045 // start checking for memory leaks
1046 rw_check_leaks (str.get_allocator ());
1047
1048 bool streambuf_threw = false;
1049
1050 try {
1051
1052 // the offset of the address of the returned reference
1053 // from the address of the stream object argument (the
1054 // two must be the same)
1055 std::ptrdiff_t ret_off = 0;
1056
1057 try {
1058 switch (func.which_) {
1059
1060 case StringIds::extractor_istream_str:
1061 ret_off = &is - &(is >> str);
1062 break;
1063
1064 case StringIds::getline_istream_str:
1065 ret_off = &is - &std::getline (is, str);
1066 break;
1067
1068 case StringIds::getline_istream_str_val: {
1069 const charT delim = make_char (tcase.val, (charT*)0);
1070 ret_off = &is - &std::getline (is, str, delim);
1071 break;
1072 }
1073
1074 case StringIds::inserter_ostream_cstr:
1075 ret_off = &os - &(os << cstr);
1076 break;
1077
1078 default:
1079 RW_ASSERT (!"test logic error: unknown io overload");
1080 return;
1081 }
1082 }
1083#ifndef _RWSTD_NO_EXCEPTIONS
1084
1085 catch (std::ios_base::failure& ex) {
1086 caught = exceptions [1];
1087 rw_assert (caught == expected, 0, tcase.line,
1088 "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
1089 "unexpectedly%{;} caught std::%s(%#s)",
1090 __LINE__, 0 != expected, expected, caught,
1091 ex.what ());
1092
1093 }
1094 catch (...) {
1095 caught = exceptions [0];
1096 rw_assert (0, 0, tcase.line,
1097 "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
1098 "unexpectedly%{;} caught %s",
1099 __LINE__, 0 != expected, expected, caught);
1100 }
1101
1102#endif // _RWSTD_NO_EXCEPTIONS
1103
1104 const std::streamsize ret_width = strm.width ();
1105 const Iostate ret_state = strm.rdstate ();
1106 const charT* ret_str = str.data ();
1107 std::size_t ret_sz = str.size ();
1108
1109 if (test_inserter) {
1110 ret_str = outbuf.pubpbase ();
1111 ret_sz = outbuf.pubepptr () - ret_str;
1112 }
1113
1114 streambuf_threw = None != sbuf.threw_;
1115
1116 if (streambuf_threw) {
1117 if (Overflow == sbuf.threw_ || Underflow == sbuf.threw_)
1118 throw_inx++;
1119 if (Xsgetn == sbuf.threw_)
1120 throw_count [0] ++;
1121 if (Sync == sbuf.threw_)
1122 throw_count [1] ++;
1123 if (Xsputn == sbuf.threw_)
1124 throw_count [2] ++;
1125 }
1126
1127 // character width (for convenience)
1128 static const int cwidth = sizeof (charT);
1129
1130 // verify that the reference returned from the function
1131 // refers to the passed stream object
1132 bool success = 0 == ret_off;
1133 rw_assert (success, 0, tcase.line,
1134 "line %d. %{$FUNCALL} returned invalid reference, "
1135 "offset is %td", __LINE__, ret_off);
1136
1137 if (!streambuf_threw) {
1138 // verify the width
1139
1140 const std::streamsize width =
1141 func.which_ == StringIds::getline_istream_str
1142 || func.which_ == StringIds::getline_istream_str_val
1143#ifndef _RWSTD_NO_EXT_KEEP_WIDTH_ON_FAILURE
1144 || ( func.which_ == StringIds::inserter_ostream_cstr
1145 && ret_state != Good)
1146#endif // _RWSTD_NO_EXT_KEEP_WIDTH_ON_FAILURE
1147 ? tcase.off : tcase.val;
1148
1149 success = width == ret_width;
1150 rw_assert (success, 0, tcase.line,
1151 "line %d. %{$FUNCALL}: expected width() == %td, "
1152 "got %td", __LINE__, width, ret_width);
1153 }
1154
1155 // tcase.size2 is the expected iostate
1156 if (0 <= tcase.size2) {
1157
1158 // verify the iostate
1159 const Iostate res_state =
1160 streambuf_threw ? Bad : Iostate (tcase.size2);
1161
1162 success = res_state ?
1163 (res_state == (ret_state & res_state)) : (0 == ret_state);
1164 rw_assert (success, 0, tcase.line,
1165 "line %d. %{$FUNCALL}: expected rdstate() "
1166 "== %{Is}, got %{Is}",
1167 __LINE__, res_state, ret_state);
1168 }
1169
1170 if ( !streambuf_threw
1171 || Overflow == sbuf.threw_ || Underflow == sbuf.threw_) {
1172
1173 std::size_t res_sz = streambuf_threw ?
1174 sbuf.throw_when_ [sbuf.memfun_inx (sbuf.threw_)] - 1 :
1175 tdata.reslen_;
1176
1177 // verify that strings length are equal
1178 success = res_sz == ret_sz;
1179 rw_assert (success, 0, tcase.line,
1180 "line %d. %{$FUNCALL}: expected %{/*.*Gs} with "
1181 "length %zu, got %{/*.*Gs} with length %zu",
1182 __LINE__,
1183 cwidth, int (res_sz), tdata.res_, res_sz,
1184 cwidth, int (ret_sz), ret_str, ret_sz);
1185
1186 if (res_sz == ret_sz) {
1187 // if the result length matches the expected length
1188 // (and only then), also verify that the modified
1189 // string matches the expected result
1190 const std::size_t match = rw_match (tcase.res,
1191 ret_str, ret_sz);
1192
1193 success = match == res_sz;
1194 rw_assert (success, 0, tcase.line,
1195 "line %d. %{$FUNCALL}: expected %{/*.*Gs}, "
1196 "got %{/*.*Gs}, difference at off %zu",
1197 __LINE__, cwidth, int (res_sz), tdata.res_,
1198 cwidth, int (ret_sz), ret_str, match);
1199 }
1200 }
1201 }
1202
1203#ifndef _RWSTD_NO_EXCEPTIONS
1204
1205 catch (const std::bad_alloc &ex) {
1206 caught = exceptions [2];
1207 rw_assert (0, 0, tcase.line,
1208 "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
1209 "unexpectedly%{;} caught std::%s(%#s)",
1210 __LINE__, 0 != expected, expected, caught, ex.what ());
1211 }
1212 catch (const std::exception &ex) {
1213 caught = exceptions [3];
1214 rw_assert (0, 0, tcase.line,
1215 "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
1216 "unexpectedly%{;} caught std::%s(%#s)",
1217 __LINE__, 0 != expected, expected, caught, ex.what ());
1218 }
1219 catch (...) {
1220 caught = exceptions [0];
1221 rw_assert (0, 0, tcase.line,
1222 "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
1223 "unexpectedly%{;} caught %s",
1224 __LINE__, 0 != expected, expected, caught);
1225 }
1226
1227#endif // _RWSTD_NO_EXCEPTIONS
1228
1229 // FIXME: verify the number of blocks the function call
1230 // is expected to allocate and detect any memory leaks
1231 rw_check_leaks (str.get_allocator (), tcase.line,
1232 std::size_t (-1), std::size_t (-1));
1233
1234 if (streambuf_threw && 0 == tcase.bthrow) {
1235 // call the function again until streambuf methods
1236 // not throws the exception
1237 continue;
1238 }
1239 else if (1 < tcase.bthrow) {
1240 rw_assert (caught == expected, 0, tcase.line,
1241 "line %d. %{$FUNCALL} %{?}expected %s, caught %s"
1242 "%{:}unexpectedly caught %s%{;}",
1243 __LINE__, 0 != expected, expected, caught, caught);
1244 }
1245
1246 break;
1247 }
1248
1249 if (StringIds::fid_inserter == (StringIds::fid_mask & int (func.which_))) {
1250 // verify that const string object was not modified during
1251 // the call to the inserter (input functions may, obviously,
1252 // modify it)
1253 cstr_state.assert_equal (rw_get_string_state (cstr),
1254 __LINE__, tcase.line, "call");
1255 }
1256
1257 if (arg != arg_buf)
1258 delete[] arg;
1259
1260 arg = 0;
1261
1262 if (throw_on)
1263 delete[] throw_on;
1264}
1265
1266
1269
1270int main (int argc, char** argv)
1271{
1272 static const StringTest
1273 tests [] = {
1274
1275#undef TEST
1276#define TEST(gsig, sig) { \
1277 gsig, sig ## _test_cases, \
1278 sizeof sig ## _test_cases / sizeof *sig ## _test_cases \
1279}
1280
1281 TEST (StringIds::extractor_istream_str, extractor),
1282 TEST (StringIds::inserter_ostream_cstr, inserter),
1283 TEST (StringIds::getline_istream_str, getline),
1284 TEST (StringIds::getline_istream_str_val, getline_val)
1285 };
1286
1287 const std::size_t test_count = sizeof tests / sizeof *tests;
1288
1289 return rw_run_string_test (argc, argv, __FILE__,
1290 "lib.string.io",
1291 test_io_func_array, tests, test_count);
1292}
#define k
Definition 17.names.cpp:128
#define os
Definition 17.names.cpp:511
#define charT
Definition 17.names.cpp:456
#define strm
Definition 17.names.cpp:549
#define Left
void test_io(charT *, Traits *, Allocator *, const StringTestCaseData< charT > &tdata)
#define TEST1(str)
#define TEST2(str)
#define TEST(str, arg, width, flags, state, res, res_width, res_st, bthrow)
#define TEST3(arg, width, flags, res)
#define Right
#define WHITESPACE
#define Skipws
#define Good
const char SYMB_THROW
#define Bad
#define flags
std::char_traits< S > Traits
#define NPOS
#define main
int caught
const StringTestCase & tcase_
Definition rw_strings.h:692
const charT *const arg_
Definition rw_strings.h:688
const charT *const res_
Definition rw_strings.h:689
const StringFunc & func_
Definition rw_strings.h:691
const charT *const str_
Definition rw_strings.h:687
const char * str
Definition exec.cpp:170
_TEST_EXPORT void rw_check_leaks(const SharedAlloc *=0, int=0, _RWSTD_SIZE_T=0, _RWSTD_SIZE_T=_RWSTD_SIZE_MAX)
UserChar make_char(char c, UserChar *)
Definition rw_char.h:74
_TEST_EXPORT char * rw_expand(char *, const char *, _RWSTD_SIZE_T=_RWSTD_SIZE_MAX, _RWSTD_SIZE_T *=0)
_TEST_EXPORT _RWSTD_SIZE_T rw_match(const char *, const char *, _RWSTD_SIZE_T=_RWSTD_SIZE_MAX)
_TEST_EXPORT int rw_assert(int, const char *, int, const char *,...)
Definition driver.cpp:1630
@ Overflow
@ Xsgetn
@ Throw
@ Sync
@ None
@ Underflow
@ Xsputn
StringState rw_get_string_state(const String &str)
Definition rw_strings.h:752
_TEST_EXPORT int rw_run_string_test(int, char **, const char *, const char *, StringTestFunc *, const StringTest *, _RWSTD_SIZE_T)
#define DEFINE_STRING_TEST_FUNCTIONS(fname)
Definition rw_strings.h:909
#define RW_ASSERT(expr)
int assert_equal(const StringState &, int, int, const char *) const
_RWSTD_SIZE_T arg_len
Definition rw_strings.h:600
const char * arg
Definition rw_strings.h:599
const char * res
Definition rw_strings.h:602
Helper class for suppressing move-construction in single-argument array constructors.
int arg
Definition locale.cpp:2806