Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
0.ctype.cpp
Go to the documentation of this file.
1
29#include <rw_char.h> // for UserChar
30#include <rw_ctype.h> // for UserCtype
31#include <rw_printf.h> // for rw_printf
32#include <rw_driver.h>
33
34#include <stdlib.h> // for free()
35#include <string.h> // for memset(), size_t, strlen()
36
37
39extern const char
40cntrl[] = {
41
42#if 'A' == 0x41 // ASCII
43 "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
44 "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x7f"
45#elif 'A' == 0xc1 // EBCDIC
46 ""
47#endif
48
49};
50
51extern const std::size_t
52n_cntrl = sizeof cntrl - 1;
53
54extern const char
55digits[] = "0123456789";
56
57extern const std::size_t
58n_digits = sizeof digits - 1;
59
60extern const char
61graph[] = "!\"#$%&\\()*+,-./0123456789:;<=>?@[]^_`{|}~";
62
63extern const std::size_t
64n_graph = sizeof graph - 1;
65
66extern const char
67lower[] = "abcdefghijklmnopqrstuvwxyz";
68
69extern const std::size_t
70n_lower = sizeof lower - 1;
71
72extern const char
73punct[] = "!#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~";
74
75extern const std::size_t
76n_punct = sizeof punct - 1;
77
78extern const char
79print[] = {
80 "!\"#$%&\\()*+,-./0123456789:;<=>?@[]^_`{|}~"
81 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
82 "abcdefghijklmnopqrstuvwxyz"
83};
84
85extern const std::size_t
86n_print = sizeof print - 1;
87
88extern const char
89spaces[] = " \t\v\f\r\n";
90
91extern const std::size_t
92n_spaces = sizeof spaces - 1;
93
94extern const char
95upper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
96
97extern const std::size_t
98n_upper = sizeof upper - 1;
99
100extern const char
101xdigits[] = "0123456789ABCDEFabcdef";
102
103extern const std::size_t
104n_xdigits = sizeof xdigits - 1;
105
106
108template <class charT>
109void
110test_id (charT*, const char *cname)
111{
112 rw_info (0, 0, __LINE__, "UserCtype<%s>::id", cname);
113
114 std::locale::id* const pid_b = &std::ctype<charT>::id;
115 std::locale::id* const pid_d = &UserCtype<charT>::id;
116
117 rw_assert (pid_b == pid_d, 0, __LINE__,
118 "&ctype<%s>::id == &UserCtype<%1$s>::id "
119 "(%#p == %2$#p, got %#p)",
120 cname, pid_b, pid_d);
121}
122
123
125template <class charT>
126void
127test_is (charT*, const char *cname,
128 std::ctype_base::mask m,
129 const char *chars, std::size_t n_chars)
130{
132
133 std::size_t n_calls = ctp.n_calls_ [ctp.mf_is];
134 std::size_t n_throws = ctp.n_throws_ [ctp.mf_is];
135
136 std::size_t expect_calls = 0;
137 std::size_t expect_throws = 0;
138
139 for (std::size_t i = 0; i != n_chars; ++i) {
140 const charT ch = make_char (chars [i], (charT*)0);
141
142 unsigned result = -1;
143
144#ifndef _RWSTD_NO_EXCEPTIONS
145
146 // let the first call call succeed and trigger an exception
147 // on the second call to UserCtype::is()
148 ctp.throw_at_calls_ [ctp.mf_is] =
149 ctp.n_calls_ [ctp.mf_is] + 2;
150
151 for (int j = 0; j != 2; ++j) {
152
153 if (1 < sizeof (charT)) {
154 // can only count UserCtype<charT>::is() calls when
155 // charT != char since there is no virtual do_is()
156 // in the char explicit specialization
157 ++expect_calls;
158 }
159 else if (j) {
160 // cannot induce an exception out of UserCtype<char>::is()
161 // since there is no virtual do_is() in the specialization
162 break;
163 }
164
165 if (j)
166 ++expect_throws;
167
168 unsigned threw = 0;
169
170 try {
171 result = ctp.is (m, ch);
172 }
173 catch (...) {
174 threw = 1;
175 }
176
177 rw_assert (j == threw, 0, __LINE__,
178 "UserCtype<%s>::is(%{LC}, %{#c}) "
179 "%{?}unexpectedly threw%{:}failed to throw%{;}",
180 cname, m, ch, j == threw);
181 }
182
183#else // if defined (_RWSTD_NO_EXCEPTIONS)
184
185 ++expect_calls;
186 result = ctp.is (m, ch);
187
188#endif // _RWSTD_NO_EXCEPTIONS
189
190 rw_assert (result, 0, __LINE__,
191 "UserCtype<%s>::is(%{LC}, %{#c}) == true",
192 cname, m, chars [i]);
193 }
194
195 n_calls = ctp.n_calls_ [ctp.mf_is] - n_calls;
196
197 rw_assert (expect_calls == n_calls, 0, __LINE__,
198 "expected %zu calls to UserCtype<%s>::is(%{LC}, char_type), "
199 "got %zu", expect_calls, cname, m, n_calls);
200
201 n_throws = ctp.n_throws_ [ctp.mf_is] - n_throws;
202
203 rw_assert (expect_throws == n_throws, 0, __LINE__,
204 "expected %zu exceptions thrown by UserCtype<%s>::is(%{LC}, "
205 "char_type), got %zu", expect_throws, cname, m, n_throws);
206}
207
208template <class charT>
209void
210test_is (charT*, const char *cname)
211{
212 rw_info (0, 0, __LINE__, "UserCtype<%s>::is"
213 "(mask, char_type) const", cname);
214
216 // exercise default behavior
217
218 test_is ((charT*)0, cname, std::ctype_base::alnum, lower, n_lower);
219 test_is ((charT*)0, cname, std::ctype_base::alnum, upper, n_upper);
220 test_is ((charT*)0, cname, std::ctype_base::alnum, digits, n_digits);
221 test_is ((charT*)0, cname, std::ctype_base::alnum, xdigits, n_xdigits);
222 test_is ((charT*)0, cname, std::ctype_base::alpha, lower, n_lower);
223 test_is ((charT*)0, cname, std::ctype_base::alpha, upper, n_upper);
224 test_is ((charT*)0, cname, std::ctype_base::cntrl, cntrl, n_cntrl);
225 test_is ((charT*)0, cname, std::ctype_base::digit, digits, n_digits);
226 test_is ((charT*)0, cname, std::ctype_base::graph, graph, n_graph);
227 test_is ((charT*)0, cname, std::ctype_base::lower, lower, n_lower);
228 test_is ((charT*)0, cname, std::ctype_base::print, print, n_print);
229 test_is ((charT*)0, cname, std::ctype_base::punct, punct, n_punct);
230 test_is ((charT*)0, cname, std::ctype_base::space, spaces, n_spaces);
231 test_is ((charT*)0, cname, std::ctype_base::xdigit, xdigits, n_xdigits);
232
234 // exercise custom behavior
235
236 static const unsigned chars[] = {
237 '0', '1', '2', '3', 'a', 'b', 'c',
238 0x100, 0x7fff, 0x8000, 0xffff,
239#if 2 < _RWSTD_INT_SIZE
240 0x10000, 0x7fffffff, 0x80000000, 0xffffffff,
241#else
242 0x1ff, 0x700, 0x8fff, 0xf000,
243#endif
244 0xFF // end of chars
245 };
246
247 static const unsigned masks[] = {
248 /* '0' */ std::ctype_base::alpha,
249 /* '1' */ std::ctype_base::cntrl,
250 /* '2' */ std::ctype_base::digit,
251 /* '3' */ std::ctype_base::lower,
252 /* 'a' */ std::ctype_base::print,
253 /* 'b' */ std::ctype_base::punct,
254 /* 'c' */ std::ctype_base::space,
255 /* 0x100 */ std::ctype_base::upper,
256 /* 0x7fff */ std::ctype_base::xdigit,
257 /* 0x8000 */ std::ctype_base::alpha | std::ctype_base::cntrl,
258 /* 0xffff */ std::ctype_base::cntrl | std::ctype_base::digit,
259 /* 0x10000 */ std::ctype_base::digit | std::ctype_base::lower,
260 /* 0x7fffffff */ std::ctype_base::lower | std::ctype_base::print,
261 /* 0x80000000 */ std::ctype_base::print | std::ctype_base::punct,
262 /* 0xffffffff */ std::ctype_base::punct | std::ctype_base::space,
263 0xFF // end of masks
264 };
265
266 static const unsigned mask_all =
267 std::ctype_base::alpha
268 | std::ctype_base::cntrl
269 | std::ctype_base::digit
270 | std::ctype_base::lower
271 | std::ctype_base::print
272 | std::ctype_base::punct
273 | std::ctype_base::space
274 | std::ctype_base::upper
275 | std::ctype_base::xdigit;
276
277 const UserCtype<charT> cust (chars, masks);
278
279 for (std::size_t i = 0; 0 <= chars [i]; ++i) {
280
281 // FIXME: enable tests of characters greater than CHAR_MAX
282 if ( _RWSTD_UCHAR_MAX < std::size_t (chars [i])
283 /* && sizeof (char) == sizeof (charT) */) {
284 // when charT == char break out when the character
285 // value is greater than CHAR_MAX
286 break;
287 }
288
289 const charT ch = make_char (chars [i], (charT*)0);
290
291 const std::ctype_base::mask m_is =
292 std::ctype_base::mask (masks [i]);
293
294 rw_assert (cust.is (m_is, ch),
295 0, __LINE__,
296 "UserCtype<%s>::is(%{LC}, %{#lc}) == true",
297 cname, m_is, chars [i]);
298
299 const std::ctype_base::mask m_not =
300 std::ctype_base::mask (~m_is & mask_all);
301
302 rw_assert (!cust.is (m_not, ch), 0, __LINE__,
303 "UserCtype<%s>::is(%{LC}, %{#lc}) == false",
304 cname, m_not, chars [i]);
305 }
306}
307
308
310template <class charT>
311void
312test_scan_is (charT*, const char *cname)
313{
314 rw_info (0, 0, __LINE__, "UserCtype<%s>::scan_is"
315 "(mask, const char_type*, const char_type*) const", cname);
316
317 rw_warn (0, 0, __LINE__, "UserCtype<%s>::scan_is"
318 "(mask, const char_type*, const char_type*) const"
319 " not exercised", cname);
320}
321
322
324template <class charT>
325void
326test_scan_not (charT*, const char *cname)
327{
328 rw_info (0, 0, __LINE__, "UserCtype<%s>::scan_not"
329 "(mask, const char_type*, const char_type*) const", cname);
330
331 rw_warn (0, 0, __LINE__, "UserCtype<%s>::scan_not"
332 "(mask, const char_type*, const char_type*) const "
333 "not exercised", cname);
334}
335
336
338template <class charT>
339void
340test_toupper (charT*, const char *cname)
341{
342 rw_info (0, 0, __LINE__, "UserCtype<%s>::toupper"
343 "(char_type) const", cname);
344
345 rw_warn (0, 0, __LINE__, "UserCtype<%s>::toupper"
346 "(char_type) const not exercised", cname);
347
348 rw_info (0, 0, __LINE__, "UserCtype<%s>::toupper"
349 "(char_type*, const char_type) const", cname);
350
351 rw_warn (0, 0, __LINE__, "UserCtype<%s>::toupper"
352 "(char_type*, const char_type) const not exercised", cname);
353}
354
355
357template <class charT>
358void
359test_tolower (charT*, const char *cname)
360{
361 rw_info (0, 0, __LINE__, "UserCtype<%s>::tolower"
362 "(char_type) const", cname);
363
364 rw_warn (0, 0, __LINE__, "UserCtype<%s>::tolower"
365 "(char_type) const not exercised", cname);
366
367 rw_info (0, 0, __LINE__, "UserCtype<%s>::tolower"
368 "(char_type*, const char_type) const", cname);
369
370 rw_warn (0, 0, __LINE__, "UserCtype<%s>::tolower"
371 "(char_type*, const char_type) const not exercised", cname);
372}
373
374
376template <class charT>
377void
378test_widen (charT*, const char *cname)
379{
380 rw_info (0, 0, __LINE__, "UserCtype<%s>::widen"
381 "(char) const", cname);
382
383 rw_warn (0, 0, __LINE__, "UserCtype<%s>::widen"
384 "(char) const not exercised", cname);
385
386 rw_info (0, 0, __LINE__, "UserCtype<%s>::widen"
387 "(const char*, const char*, char_type*) const", cname);
388
389 rw_warn (0, 0, __LINE__, "UserCtype<%s>::widen"
390 "(const char*, const char*, char_type*) const not exercised",
391 cname);
392}
393
394
396template <class charT>
397void
398test_narrow (charT*, const char *cname)
399{
400 rw_info (0, 0, __LINE__, "UserCtype<%s>::narrow"
401 "(char_type, char) const", cname);
402
403 rw_warn (0, 0, __LINE__, "UserCtype<%s>::narrow"
404 "(char_type, char) const not exercised", cname);
405
406 rw_info (0, 0, __LINE__, "UserCtype<%s>::narrow"
407 "(const char_type*, const char_type*, char, char*) const",
408 cname);
409
410 rw_warn (0, 0, __LINE__, "UserCtype<%s>::narrow"
411 "(const char_type*, const char_type*, char, char*) const"
412 " not exercised",
413 cname);
414}
415
416
418/* extern */ unsigned opt_id;
419
420/* extern */ unsigned opt_is;
421/* extern */ unsigned opt_scan_is;
422/* extern */ unsigned opt_scan_not;
423
424/* extern */ unsigned opt_toupper;
425/* extern */ unsigned opt_tolower;
426
427/* extern */ unsigned opt_widen;
428/* extern */ unsigned opt_narrow;
429
430
431template <class charT>
432void
433test (charT*, const char *cname)
434{
435#define TEST(func) \
436 if (0 <= opt_ ## func) \
437 test_ ## func ((charT*)0, cname); \
438 else \
439 rw_note (0, 0, __LINE__, \
440 "UserCtype<%s>::%s() tests disabled", \
441 cname, # func)
442
443 TEST (id);
444
445 TEST (is);
446 TEST (scan_is);
447 TEST (scan_not);
448
449 TEST (toupper);
450 TEST (tolower);
451
452 TEST (widen);
453 TEST (narrow);
454}
455
456
458static int
459run_test (int, char**)
460{
461 test ((char*)0, "char");
462
463#ifndef _RWSTD_NO_WCHAR_T
464 test ((wchar_t*)0, "wchar_t");
465#endif // _RWSTD_NO_WCHAR_T
466
467 test ((UserChar*)0, "UserChar");
468
469 return 0;
470}
471
472
474int main (int argc, char *argv[])
475{
476 return rw_test (argc, argv, __FILE__,
477 "",
478 0,
479 run_test,
480 "|-id~ "
481 "|-is~ "
482 "|-scan_is~ "
483 "|-scan_not~ "
484 "|-toupper~ "
485 "|-tolower~ "
486 "|-widen~ "
487 "|-narrow~ ",
488 &opt_id,
489 &opt_is,
494 &opt_widen,
495 &opt_narrow,
496 (void*)0 /* sentinel */);
497}
unsigned opt_is
Definition 0.ctype.cpp:420
unsigned opt_id
Definition 0.ctype.cpp:418
const std::size_t n_cntrl
const std::size_t n_graph
const char lower[]
const char graph[]
unsigned opt_toupper
Definition 0.ctype.cpp:424
unsigned opt_tolower
Definition 0.ctype.cpp:425
const std::size_t n_spaces
const std::size_t n_digits
const char xdigits[]
const char upper[]
void test_tolower(charT *, const char *cname)
Definition 0.ctype.cpp:359
const char cntrl[]
const std::size_t n_xdigits
void test_is(charT *, const char *cname, std::ctype_base::mask m, const char *chars, std::size_t n_chars)
Definition 0.ctype.cpp:127
const std::size_t n_punct
const char digits[]
void test_narrow(charT *, const char *cname)
Definition 0.ctype.cpp:398
unsigned opt_scan_is
Definition 0.ctype.cpp:421
void test_toupper(charT *, const char *cname)
Definition 0.ctype.cpp:340
unsigned opt_narrow
Definition 0.ctype.cpp:428
void test_widen(charT *, const char *cname)
Definition 0.ctype.cpp:378
void test_scan_is(charT *, const char *cname)
Definition 0.ctype.cpp:312
const std::size_t n_print
unsigned opt_widen
Definition 0.ctype.cpp:427
const std::size_t n_lower
const char print[]
#define TEST(func)
const char punct[]
void test_scan_not(charT *, const char *cname)
Definition 0.ctype.cpp:326
const char spaces[]
void test_id(charT *, const char *cname)
Definition 0.ctype.cpp:110
unsigned opt_scan_not
Definition 0.ctype.cpp:422
const std::size_t n_upper
#define m
Definition 17.names.cpp:129
#define i
Definition 17.names.cpp:126
#define j
Definition 17.names.cpp:127
#define charT
Definition 17.names.cpp:456
volatile int result
const char * widen(char *dst, const char *src)
const char * narrow(char *dst, const char *src)
void run_test(const ForwardIterator &dummy, T *, Predicate *pred)
#define main
UserChar make_char(char c, UserChar *)
Definition rw_char.h:74
_TEST_EXPORT int rw_test(int argc, char *argv[], const char *filename, const char *clause, const char *comment, int(*testfun)(int, char **), const char *optspec,...)
_TEST_EXPORT int rw_info(int, const char *, int, const char *,...)
Definition driver.cpp:1681
_TEST_EXPORT int rw_assert(int, const char *, int, const char *,...)
Definition driver.cpp:1630
_TEST_EXPORT int rw_warn(int, const char *, int, const char *,...)
Definition driver.cpp:1647