50#if defined (__IBMCPP__) && !defined (_RWSTD_NO_IMPLICIT_INCLUSION)
53# define _RWSTD_NO_IMPLICIT_INCLUSION
76class cformat:
public std::codecvt <char, char, std::mbstate_t>
80 horizontal_tab = 0x0002,
81 vertical_tab = 0x0004,
83 carriage_return = 0x0010,
87 question_mark = 0x0100,
88 single_quote = 0x0200,
89 double_quote = 0x0400,
99 :
std::codecvt<char, char,
std::mbstate_t> (ref),
106 const intern_type*,
const intern_type*,
108 extern_type*, extern_type*, extern_type*&)
const;
111 do_in (state_type&,
const extern_type*,
112 const extern_type*,
const extern_type*&,
113 intern_type*, intern_type*, intern_type*&)
const;
117 extern_type*, extern_type*&)
const {
135 do_length (state_type&,
const extern_type*,
136 const extern_type*, std::size_t)
const;
151std::codecvt_base::result
153 const intern_type *from,
154 const intern_type *from_end,
155 const intern_type *&from_next,
158 extern_type *&to_next)
const
161 rw_assert (from <= from_end, __FILE__, __LINE__,
162 "codecvt::do_out (..., from = %#p, from + %d, %#p, "
163 "to = %#p, to + %d, %#p): from <= from_end",
164 from, from_end - from, from_next, to, to_end - to, to_next);
166 rw_assert (to <= to_end, __FILE__, __LINE__,
167 "codecvt::do_out (..., from = %#p, from + %d, %#p, "
168 "to = %#p, to + %d, %#p): to <= to_end",
169 from, from_end - from, from_next, to, to_end - to, to_next);
174 for (from_next = from, to_next = to; from_next != from_end; ++from_next) {
177 if (to_next == to_end) {
183 unsigned char ch = *from_next;
184 extern_type esc = extern_type ();
192 if (!(mask & alert)) {
199 if (!(mask & backspace)) {
206 if (!(mask & horizontal_tab)) {
213 if (!(mask & new_line)) {
220 if (!(mask & vertical_tab)) {
227 if (!(mask & form_feed)) {
234 if (!(mask & carriage_return)) {
241 if (!(mask & backslash)) {
260 if (!(mask & question_mark))
265 if (!(mask & single_quote))
270 if (!(mask & double_quote))
275 if (!(mask & backslash))
280 if (!(mask & trigraphs)) {
284 case '#': ch =
'='; esc =
'?';
break;
285 case '\\': ch =
'/'; esc =
'?';
break;
286 case '^': ch =
'\''; esc =
'?';
break;
287 case '[': ch =
'('; esc =
'?';
break;
288 case ']': ch =
')'; esc =
'?';
break;
289 case '|': ch =
'!'; esc =
'?';
break;
290 case '{': ch =
'<'; esc =
'?';
break;
291 case '}': ch =
'>'; esc =
'?';
break;
292 case '~': ch =
'-'; esc =
'?';
break;
304 if (ch <
' ' || ch >
'~') {
307 if (4 > to_end - to_next) {
312 static const char digits[] =
"0123456789abcdef";
320 *to_next++ =
digits [(ch & 0xf0) >> 4];
321 *to_next++ =
digits [ch & 0xf];
325 *to_next++ =
digits [(ch & (7 << 6)) >> 6];
326 *to_next++ =
digits [(ch & (7 << 3)) >> 3];
327 *to_next++ =
digits [ch & 7];
332 if (2 > to_end - to_next) {
342 else if (
'?' == esc) {
344 if (3 > to_end - to_next) {
369 rw_fatal (from_next >= from && from_next <= from_end, 0, __LINE__,
370 "user-defined codecvt: internal inconsistency");
372 rw_fatal (to_next >= to && to_next <= to_end, 0, __LINE__,
373 "user-defined codecvt: internal inconsistency");
379std::codecvt_base::result
381 const extern_type *from,
382 const extern_type *from_end,
383 const extern_type *&from_next,
386 intern_type *&to_next)
const
389 rw_assert (from <= from_end, __FILE__, __LINE__,
390 "codecvt::do_in (..., from = %#p, from + %d, %#p, "
391 "to = %#p, to + %d, %#p): from <= from_end",
392 from, from_end - from, from_next, to, to_end - to, to_next);
394 rw_assert (to <= to_end, __FILE__, __LINE__,
395 "codecvt::do_in (..., from = %#p, from + %d, %#p, "
396 "to = %#p, to + %d, %#p) to <= to_end",
397 from, from_end - from, from_next, to, to_end - to, to_next);
401 for (from_next = from, to_next = to; from_next != from_end; ++from_next) {
403 unsigned char ch = *from_next;
404 intern_type
c = intern_type ();
408 if (2 > from_end - from_next) {
411 res = (from_end - (extern_type*)0) % 2 ? ok : partial;
421 const extern_type *next = from_next + 2;
426 if (next == from_end) {
434 if (ch >=
'0' && ch <=
'9')
435 c = (
c << 4) | (ch -
'0');
436 else if (ch >=
'a' && ch <=
'f')
437 c = (
c << 4) | (ch -
'a' + 10);
438 else if (ch >=
'A' && ch <=
'F')
439 c = (
c << 4) | (ch -
'A' + 10);
440 else if (next - from_next > 2)
448 from_next = next - 1;
450 else if (
'0' <= ch &&
'7' >= ch) {
454 const extern_type *next = from_next + 1;
457 for (; next - from_next < 4; ++next) {
459 if (next == from_end) {
467 if (ch >=
'0' && ch <=
'7')
468 c = (
c << 3) | (ch -
'0');
469 else if (next - from_next)
479 from_next = next - 1;
484 case 'a':
c =
'\a';
break;
485 case 'b':
c =
'\b';
break;
486 case 't':
c =
'\t';
break;
487 case 'n':
c =
'\n';
break;
488 case 'v':
c =
'\v';
break;
489 case 'f':
c =
'\f';
break;
490 case 'r':
c =
'\r';
break;
493 case '?':
case '"':
case '\'':
case '\\':
c = ch ;
break;
496 default:
return error;
503 else if (
'?' == ch && !(mask & trigraphs)) {
505 if ( 2 > from_end - from_next
506 || (
'?' == from_next [1] && 3 > from_end - from_next)) {
511 if (
'?' == from_next [1]) {
514 switch (from_next [2]) {
516 case '=':
c =
'#';
break;
517 case '/':
c =
'\\';
break;
518 case '\'':
c =
'^';
break;
519 case '(':
c =
'[';
break;
520 case ')':
c =
']';
break;
521 case '!':
c =
'|';
break;
522 case '<':
c =
'{';
break;
523 case '>':
c =
'}';
break;
524 case '-':
c =
'~';
break;
532 if (
c != from_next [0])
552 if (from_next == from_end)
556 rw_fatal (from_next >= from && from_next <= from_end, 0, __LINE__,
557 "user-defined codecvt: internal inconsistency");
559 rw_fatal (to_next >= to && (to_next <= to_end || !to_end), 0, __LINE__,
560 "user-defined codecvt: internal inconsistency");
568 const extern_type *from,
569 const extern_type *from_end,
570 std::size_t
max)
const
572 const extern_type *from_next;
573 intern_type *to_next = 0;
576 std::memset (&st, 0,
sizeof st);
581 do_in (st, from, from_end, from_next,
582 to_next, to_next +
max, to_next);
584 return int (to_next - (intern_type*)0);
590static std::streamsize
591fsize (
const char *fname)
593 std::FILE*
const f = std::fopen (fname,
"r");
597 const std::streamsize
size = std::ftell (
f);
609 rw_info (0, __FILE__, __LINE__,
610 "user-defined codecvt facet -- self test");
612 static const char*
const result[] = {
613 "ok",
"partial",
"error",
"noconv"
621 cformat::intern_type intrn [2][256] = { {
'\0' } };
625 cformat::extern_type extrn [1024] = {
'\0' };
628 for (std::size_t
i = 0;
i !=
sizeof intrn [0] - 1; ++
i)
629 intrn [0][
i] = cformat::intern_type (
i + 1);
631 const cformat::intern_type *intrn_next_0 = 0;
632 cformat::intern_type *intrn_next_1 = 0;
634 cformat::extern_type *extrn_next = 0;
639 std::memset (&st, 0,
sizeof st);
643 std::codecvt_base::result
res;
647 intrn [0], intrn [0] +
sizeof intrn [0], intrn_next_0,
648 extrn, extrn +
sizeof extrn, extrn_next);
651 "codecvt::out (); result == codecvt_base::ok, "
655 rw_assert (extrn_next - extrn > intrn_next_0 - intrn [0], 0, __LINE__,
656 "codecvt::out (); converted size %d, expected > %d",
657 extrn_next - extrn, intrn_next_0 - intrn [0]);
662 const cformat::intern_type *next = extrn;
664 intrn_next_1 = intrn [1];
666 for (; next != extrn_next; ) {
669 std::size_t step = std::size_t (extrn_next - next);
674 next, next + step, next,
675 intrn_next_1, intrn [1] +
sizeof intrn [1], intrn_next_1);
677 if (std::codecvt_base::error ==
res)
683 "codecvt::in (); result == codecvt_base::ok, got "
684 "codecvt_base::%s at offset %d",
result [
res], next - extrn);
686 rw_assert (intrn_next_1 == intrn [1] +
sizeof intrn [1], 0, __LINE__,
687 "codecvt::in (); to_next == %#p, got %#p",
688 intrn [1] +
sizeof intrn [1], intrn_next_1);
690 rw_assert (0 == std::strcmp (intrn [0], intrn [1]), 0, __LINE__,
691 "codecvt<>::out/in ()");
696#define RW_ASSERT_STATE(strm, state) \
697 rw_assert ((strm).rdstate () == (state), 0, __LINE__, \
698 "rdstate () == %{Is}, got %{Is}", \
699 (state), (strm).rdstate ())
702test_noconv (
const char *fname)
704 rw_info (0, 0, __LINE__,
"ifstream extraction without conversion");
706 std::ifstream
f (fname);
712 struct pubbuf: std::streambuf {
715 typedef std::streambuf
Base;
717 virtual std::streamsize showmanyc () {
718 return Base::showmanyc ();
721 return Base::gptr ();
724 return Base::egptr ();
731 std::streamsize filesize = rdbuf->showmanyc ();
735 rw_assert (filesize == fsize (fname), 0, __LINE__,
736 "streambuf::showmanyc () == %ld, got %ld",
737 fsize (fname), filesize);
740 filesize =
f.rdbuf ()->in_avail ();
742 const char *gptr = rdbuf->pubgptr ();
743 const char *egptr = rdbuf->pubgptr ();
745 rw_assert (filesize == (gptr < egptr ? egptr - gptr : fsize (fname)),
747 "streambuf::in_avail () == %ld, got %ld",
748 (gptr < egptr ? egptr - gptr : fsize (fname)), filesize);
752 const std::size_t bufsize = 0x10000;
753 char *tmpbuf =
new char [bufsize];
757 std::memset (tmpbuf,
'\x7f', bufsize);
762#ifndef _RWSTD_PBACK_SIZE
763# define _RWSTD_PBACK_SIZE 1
770 std::streamsize
n =
f.read (tmpbuf,
i).gcount ();
774 "ifstream::read (%#p, %ld) read %ld,"
775 "buffer terminated with '\\%03o'",
776 tmpbuf,
i,
n, tmpbuf [
i]);
780 for (std::streamsize
j = 0;
j !=
i; ++
j) {
781 std::ifstream::int_type
c =
f.rdbuf ()->sungetc ();
783 typedef std::ifstream::traits_type
Traits;
785 rw_assert (Traits::to_int_type (tmpbuf [
n -
j - 1]) ==
c,
787 "filebuf::sungetc() == '\\%03o', got '\\%03o",
788 tmpbuf [
n -
j - 1],
c);
793 std::memset (
buf,
'\x7f',
sizeof buf);
795 std::streamsize
n2 =
f.read (
buf,
i).gcount ();
799 "ifstream::read (%#p, %ld) read %ld,"
800 "buffer terminated with '\\%03o'",
804 for (std::streamsize
k = 0;
k !=
i; ++
k) {
806 "buffer mismatch at offset %ld: got '\\%03o', "
807 "expected '\\%03o'",
k,
buf [
k], tmpbuf [
k]);
809 f.rdbuf ()->sungetc ();
814 const std::streamsize
n =
f.read (tmpbuf, bufsize).gcount ();
821 rw_assert (
n == filesize &&
'\x7f' == tmpbuf [
n], 0, __LINE__,
822 "ifstream::read (%#p, %ld) read %ld, expected %ld; "
823 "buffer terminated with '\\%03o' [%s]",
824 tmpbuf, bufsize,
n, filesize, tmpbuf [
n], fname);
831 if (
i >=
' ' ||
i <=
'~')
833 b = 0 == std::strchr (tmpbuf,
char (
i));
837 "unescaped non-printable character '\\#03o' at offset %ld",
846test_error (
const char *fname)
848 rw_info (0, 0, __LINE__,
"ifstream extraction with a conversion error");
850 const char outbuf[] = {
851 "abcdefghijklmnopqrstuvwxyz\\x20\\xzzABCDEFGHIJKLMNOPQRSTUVWXYZ"
858 std::ofstream
ostrm (fname);
865 std::ifstream
istrm (fname);
872 std::locale l (std::locale::classic (), &fmt);
877 char inbuf [
sizeof outbuf * 4] = { 0 };
881 istrm.read (inbuf, 26L + 4L );
890 "ifstream::read () extracted %d, expected 27",
893 rw_assert ( 0 == std::ifstream::traits_type::compare (inbuf, outbuf, 26)
894 &&
' ' == inbuf [26], 0, __LINE__,
895 "ifstream::read () got \"%s\", expected \"%.26s \"",
901 istrm.read (inbuf,
sizeof inbuf);
906 "ifstream::read () extracted %d, expected 0",
916test_seek (
const char *fname,
917 std::size_t bufsize = std::size_t (-1))
919 std::ifstream
f (fname);
925 if (std::size_t (-1) != bufsize) {
928 "ifstream::seekg()/tellg() - %zu byte buffer", bufsize);
931 f.rdbuf ()->pubsetbuf (0, bufsize);
935 "ifstream::seekg()/tellg() - default buffer size");
943 std::locale l (std::locale::classic (), &fmt);
954 for (std::size_t
n = 0;
n != std::size_t (
max - 1); ++
n) {
956 const char delim = char (
'~' +
n);
959 f.ignore (0x10000, std::fstream::traits_type::to_int_type (delim));
961 "istream::ignore (0x10000, '\\%03o'); "
962 "rdstate() = %{Is}, gcount() = %ld",
963 delim,
f.rdstate (),
f.gcount ());
968 f.seekg (0, std::ios::cur);
973 int syn =
f.rdbuf ()->pubsync ();
975 "filebuf::pubsync () == 0, got %d", syn);
983 "istream::get(char_type) got '\\%03o', expected ' '",
c);
986 const std::ifstream::pos_type
pos =
f.tellg ();
996 "ifstream::operator>>() expected %ld, got %ld",
1000 std::streamsize avail =
f.rdbuf ()->in_avail ();
1002 "filebuf::in_avail() expected > 0, got %ld", avail);
1012 "istream::seekg (%ld); tellg () returns %ld",
1013 long (
pos),
long (
f.tellg ()));
1021 "ifstream::operator>>() expected %ld, got %ld",
1030 const std::streamsize avail =
f.rdbuf ()->in_avail ();
1032 "filebuf::in_avail() expected 0, got %ld", avail);
1052 std::locale l (std::locale::classic (), &fmt);
1060 char buffer [4096] = {
'\0' };
1062 std::size_t buflen = 0;
1067 "ofstream insertion with multibyte conversion");
1069 std::ofstream
f (fname);
1079 const std::ofstream::pos_type
pos =
f.tellp ();
1083 buflen = std::strlen (
buffer);
1086 std::sprintf (
buffer + buflen,
"%ld %c ",
long (
pos),
char (
i));
1094 buflen = std::strlen (
buffer);
1102 test_noconv (fname);
1107 "ifstream extraction with multibyte conversion");
1109 std::ifstream
f (fname);
1119 char tmpbuf [
sizeof buffer];
1123 const std::streamsize
n =
f.read (tmpbuf,
sizeof tmpbuf).gcount ();
1129 rw_assert (std::size_t (
n) == buflen, 0, __LINE__,
1130 "ifstream::read (%#p, %d); read %ld, expected %d",
1131 tmpbuf,
sizeof tmpbuf,
long (
n), buflen);
1135 const long len = std::size_t (
n) < buflen ? std::size_t (
n) : buflen;
1136 for (std::size_t
i = 0;
i !=
len; ++
i) {
1139 "'\\%03o' == '\\%03o'; offset %zu",
1141 (
unsigned char)tmpbuf [
i],
i);
1152 for (std::size_t
n = 4096;
n != std::size_t (-1);
1153 n -= 1024 <
n ? 1024 : 256 <
n ? 256 : 16 <
n ? 16 : 1)
1154 test_seek (fname,
n);
1161 std::remove (fname);
1170 return rw_test (argc, argv, __FILE__,
void run_test(const ForwardIterator &dummy, T *, Predicate *pred)
#define _RWSTD_PBACK_SIZE
#define RW_ASSERT_STATE(strm, state)
#define _RWSTD_STATIC_CAST(T, x)
_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 *,...)
_TEST_EXPORT int rw_fatal(int expr, const char *filename, int line, const char *fmtspec,...)
_TEST_EXPORT int rw_assert(int, const char *, int, const char *,...)
_TEST_EXPORT const char * rw_tmpnam(char *)