Return-Path: Delivered-To: apmail-incubator-stdcxx-dev-archive@www.apache.org Received: (qmail 15886 invoked from network); 6 Aug 2007 21:53:20 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 6 Aug 2007 21:53:20 -0000 Received: (qmail 94042 invoked by uid 500); 6 Aug 2007 21:53:19 -0000 Delivered-To: apmail-incubator-stdcxx-dev-archive@incubator.apache.org Received: (qmail 94036 invoked by uid 500); 6 Aug 2007 21:53:19 -0000 Mailing-List: contact stdcxx-dev-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: stdcxx-dev@incubator.apache.org Delivered-To: mailing list stdcxx-dev@incubator.apache.org Received: (qmail 94025 invoked by uid 99); 6 Aug 2007 21:53:19 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 06 Aug 2007 14:53:19 -0700 X-ASF-Spam-Status: No, hits=-0.0 required=10.0 tests=SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: local policy) Received: from [208.30.140.160] (HELO moroha.quovadx.com) (208.30.140.160) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 06 Aug 2007 21:53:16 +0000 Received: from qxvcexch01.ad.quovadx.com ([192.168.170.59]) by moroha.quovadx.com (8.13.6/8.13.6) with ESMTP id l76LqrTE022479 for ; Mon, 6 Aug 2007 21:52:54 GMT X-MimeOLE: Produced By Microsoft Exchange V6.5 Content-class: urn:content-classes:message MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----_=_NextPart_001_01C7D874.17BF473A" Subject: [PATCH] Update test 22.locale.num.put.mt.cpp to validate results Date: Mon, 6 Aug 2007 15:52:06 -0600 Message-ID: X-MS-Has-Attach: yes X-MS-TNEF-Correlator: Thread-Topic: [PATCH] Update test 22.locale.num.put.mt.cpp to validate results Thread-Index: AcfYdAfxhdHSkInCRSSobpkhgkaqPA== From: "Travis Vitek" To: X-Virus-Checked: Checked by ClamAV on apache.org ------_=_NextPart_001_01C7D874.17BF473A Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Attached is a patch to enhance the num_put facet mt test. Threads verify that the values they put compare equal to those put in the primary thread. 2007-08-06 Travis Vitek * 22.locale.num.put.mt.cpp: Added structure for MyIos, MyStreambuf and CnumData types to simplify testing. (thread_func): Verify that data written matches expected. (run_test): Build table of inputs and outputs for verification by test threads. Index: 22.locale.num.put.mt.cpp =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- 22.locale.num.put.mt.cpp (revision 562577) +++ 22.locale.num.put.mt.cpp (working copy) @@ -36,6 +36,8 @@ #include // for rw_get_processors (), rw_thread_pool() #include =20 +// helper gets the number of elements in an array +#define countof(x) (sizeof(x) / sizeof(*x)) =20 // maximum number of threads allowed by the command line interface #define MAX_THREADS 32 @@ -58,8 +60,98 @@ static std::size_t nlocales; =20 +struct CnumData +{ + enum { BufferSize =3D 32 }; + + // name of the locale the data corresponds to + const char* locale_name_; + + // optinally set to the named locale for threads to share + std::locale locale_; + + // holder for original value and character representation + template + struct result + { + result() + : flags_(std::ios::dec) + { + memset(nrep_, 0, sizeof nrep_); + memset(wrep_, 0, sizeof wrep_); + } + + T value_; // the original value + std::ios::fmtflags flags_; // flags used + + // holds the narrow/wide character representation of value_ + char nrep_[BufferSize];=20 + wchar_t wrep_[BufferSize]; + }; + + int width_; + + result bool_; + result long_; + result ulong_; + +#ifndef _RWSTD_NO_LONG_LONG + + result<_RWSTD_LONG_LONG> llong_; + result ullong_; + +#endif // _RWSTD_NO_LONG_LONG + + result dbl_; + +#ifndef _RWSTD_NO_LONG_DOUBLE + + result ldbl_; + +#endif // _RWSTD_NO_LONG_DOUBLE + + result ptr_; + +} num_put_data[MAX_THREADS]; + +const std::ios::fmtflags baseflags[] =3D { + std::ios::oct, + std::ios::dec, + std::ios::hex +}; + +const std::ios::fmtflags fmtflags[] =3D { + std::ios::showpos, + std::ios::showpoint, + std::ios::fixed, + std::ios::scientific +}; + +const std::ios::fmtflags adjustflags[] =3D { + std::ios::internal, + std::ios::left, + std::ios::right +}; + =20 /*********************************************************************** ***/ =20 +template +struct MyIos: std::basic_ios +{ + MyIos () { this->init (0); } +}; + +template +struct MyStreambuf: std::basic_streambuf +{ + typedef std::basic_streambuf Base; + + MyStreambuf (charT *pbeg, charT *pend) + : Base () { + this->setp (pbeg, pend); + } +}; + extern "C" { =20 bool test_char; // exercise num_put @@ -69,54 +161,43 @@ static void* thread_func (void*) { - // dummy streambuf-derived object the doesn't do anything - // but allows ostreambuf_iterator to "think" it can write - // to it - struct NarrowBuf: std::streambuf { - int_type overflow (int_type c) { return c; } - } sb; =20 -#ifndef _RWSTD_NO_WCHAR_T +// these macros should probably assert goodbit =20 - struct WideBuf: std::wstreambuf { - int_type overflow (int_type c) { return c; } - } wb; +#define TEST_PUT(cType, vType, field, value, fill, flag) \ + { \ + MyIos > io; \ + io.imbue(loc); io.flags(flag); io.width(data->width_); \ + \ + cType chars[CnumData::BufferSize]; \ + memset(chars, 0, sizeof chars); \ + \ + MyStreambuf > sb \ + (chars, chars + CnumData::BufferSize); \ + \ + const std::ostreambuf_iterator iter (&sb); \ + \ + np.put(iter, io, fill, value); \ + rw_assert(0 =3D=3D memcmp(field, chars, sizeof chars), = \ + __FILE__, __LINE__, \ + "%s '%s' !=3D '%s'", #vType, field, chars); \ + } =20 -#endif // _RWSTD_NO_WCHAR_T +#define TEST_PUT_NARROW(type, it) \ + TEST_PUT(char, type, it.nrep_, it.value_, ' ', it.flags_) =20 - struct Ios: std::ios { - Ios () { this->init (0); } - } io; +#define TEST_PUT_WIDE(type, it) \ + TEST_PUT(wchar_t, type, it.wrep_, it.value_, L' ', it.flags_) =20 - const std::ios::fmtflags baseflags[] =3D { - std::ios::oct, - std::ios::dec, - std::ios::hex - }; - - const std::ios::fmtflags fmtflags[] =3D { - std::ios::showpos, - std::ios::showpoint, - std::ios::fixed, - std::ios::scientific - }; - - const std::ios::fmtflags adjustflags[] =3D { - std::ios::internal, - std::ios::left, - std::ios::right - }; - for (int i =3D 0; i !=3D rw_opt_nloops; ++i) { =20 - // save the name of the locale - const char* const locale_name =3D locales [i % nlocales]; + // fill in the value and results for this locale + const CnumData* data =3D num_put_data + (i % nlocales); =20 // construct a named locale and imbue it in the ios object // so that the locale is used not only by the num_put facet // but also by the numpunct facet - const std::locale loc (locale_name); - io.imbue (loc); + const std::locale loc (data->locale_name_); =20 enum PutId { put_bool, @@ -131,75 +212,62 @@ #endif // _RWSTD_NO_LONG_LONG =20 put_dbl, + +#ifndef _RWSTD_NO_LONG_DOUBLE + put_ldbl, + +#endif // _RWSTD_NO_LONG_DOUBLE + put_ptr, put_max }; =20 - const std::ios::fmtflags base =3D - baseflags [i % (sizeof baseflags / sizeof *baseflags)]; - - const std::ios::fmtflags fmt =3D - fmtflags [i % (sizeof baseflags / sizeof *baseflags)]; - - const std::ios::fmtflags adjust =3D - adjustflags [i % (sizeof baseflags / sizeof *baseflags)]; - - io.flags (base | fmt | adjust); - - io.width (i % 16); - - // exercise postive and negative values - const int ival =3D i & 1 ? -i : i; - if (test_char) { // exercise the narrow char specialization of the facet =20 const std::num_put &np =3D std::use_facet >(loc); =20 - const std::ostreambuf_iterator iter (&sb); - switch (i % put_max) { case put_bool: - if (i & 2) - io.setf (std::ios::boolalpha); - else - io.unsetf (std::ios::boolalpha); - =20 - np.put (iter, io, ' ', bool (ival)); + TEST_PUT_NARROW(bool, data->bool_); break; =20 case put_long: - np.put (iter, io, ' ', long (ival)); + TEST_PUT_NARROW(long, data->long_); break; =20 case put_ulong: - np.put (iter, io, ' ', (unsigned long)ival); + TEST_PUT_NARROW(unsigned long, data->ulong_); break; =20 #ifndef _RWSTD_NO_LONG_LONG =20 case put_llong: - np.put (iter, io, ' ', (_RWSTD_LONG_LONG)ival); + TEST_PUT_NARROW(long long, data->llong_); break; =20 -#endif // _RWSTD_NO_LONG_LONG - case put_ullong: - np.put (iter, io, ' ', (unsigned _RWSTD_LONG_LONG)ival); + TEST_PUT_NARROW(unsigned long long, data->ullong_); break; =20 +#endif // _RWSTD_NO_LONG_LONG + case put_dbl: - np.put (iter, io, ' ', double (ival)); + TEST_PUT_NARROW(double, data->dbl_); break; =20 +#ifndef _RWSTD_NO_LONG_DOUBLE + case put_ldbl: - np.put (iter, io, ' ', (long double)ival); + TEST_PUT_NARROW(long double, data->ldbl_); break; =20 +#endif // _RWSTD_NO_LONG_DOUBLE + case put_ptr: - np.put (iter, io, ' ', (void*)ival); + TEST_PUT_NARROW(void*, data->ptr_); break; } } @@ -214,43 +282,45 @@ const std::num_put &np =3D std::use_facet >(loc); =20 - const std::ostreambuf_iterator iter (&wb); - switch (i % put_max) { case put_bool: - np.put (iter, io, L' ', bool (ival)); + TEST_PUT_WIDE(bool, data->bool_); break; =20 case put_long: - np.put (iter, io, L' ', long (ival)); + TEST_PUT_WIDE(long, data->long_); break; =20 case put_ulong: - np.put (iter, io, L' ', (unsigned long)ival); + TEST_PUT_WIDE(unsigned long, data->ulong_); break; =20 #ifndef _RWSTD_NO_LONG_LONG =20 case put_llong: - np.put (iter, io, L' ', (_RWSTD_LONG_LONG)ival); + TEST_PUT_WIDE(long, data->llong_); break; =20 case put_ullong: - np.put (iter, io, L' ', (unsigned _RWSTD_LONG_LONG)ival); + TEST_PUT_WIDE(unsigned long long, data->ullong_); break; =20 #endif // _RWSTD_NO_LONG_LONG =20 case put_dbl: - np.put (iter, io, L' ', double (ival)); + TEST_PUT_WIDE(double, data->dbl_); break; =20 +#ifndef _RWSTD_NO_LONG_DOUBLE + case put_ldbl: - np.put (iter, io, L' ', (long double)ival); + TEST_PUT_WIDE(long double, data->ldbl_); break; =20 +#endif // _RWSTD_NO_LONG_DOUBLE + case put_ptr: - np.put (iter, io, L' ', (void*)ival); + TEST_PUT_WIDE(void*, data->ptr_); break; } =20 @@ -273,12 +343,124 @@ const char* const locale_list =3D rw_opt_locales ? rw_opt_locales : rw_locales (_RWSTD_LC_ALL); =20 - const std::size_t maxinx =3D sizeof locales / sizeof *locales; + const std::size_t maxinx =3D countof(locales); =20 for (const char *name =3D locale_list; *name; name +=3D std::strlen (name) +1) { =20 - locales [nlocales++] =3D name; + const std::size_t inx =3D nlocales; + locales [inx] =3D name; =20 + // fill in the value and results for this locale + CnumData* data =3D num_put_data + nlocales; + data->locale_name_ =3D name; + + try { + const std::locale loc(name); + + std::ios::fmtflags base =3D + baseflags [nlocales % countof(baseflags)]; + + std::ios::fmtflags fmt =3D + fmtflags [nlocales % countof(baseflags)]; + + std::ios::fmtflags adjust =3D + adjustflags [nlocales % countof(baseflags)]; + + data->width_ =3D nlocales % 16; + + // exercise postive and negative values + const int ival =3D nlocales & 1 ? -1 * nlocales : nlocales; + + // format data into buffers + const std::num_put &np =3D + std::use_facet >(loc); + +#ifndef _RWSTD_NO_WCHAR_T + + const std::num_put &wp =3D + std::use_facet >(loc); + +#endif // _RWSTD_NO_WCHAR_T + +#define PUT(charT, field, value, fill, flag, putter) \ + { \ + flag =3D base | fmt | adjust; \ + \ + MyIos > io; \ + io.imbue(loc); io.flags(flag); io.width(data->width_); \ + \ + MyStreambuf > sb( \ + field, field + CnumData::BufferSize); \ + const std::ostreambuf_iterator iter (&sb); \ + \ + putter.put(iter, io, fill, value); \ + } + +#if 1 +# define PUT_NARROW(it) \ + PUT(char, it.nrep_, it.value_, ' ', it.flags_, np) +#else +# define PUT_NARROW(thing) +#endif // 1 + +#ifndef _RWSTD_NO_WCHAR_T +# define PUT_WIDE(it) \ + PUT(wchar_t, it.wrep_, it.value_, L' ', it.flags_, wp) +#else +# define PUT_WIDE(thing) +#endif // _RWSTD_NO_WCHAR_T + + data->long_.value_ =3D (long)ival; + PUT_NARROW(data->long_); + PUT_WIDE (data->long_); + + data->ulong_.value_ =3D (unsigned long)ival; + PUT_NARROW(data->ulong_); + PUT_WIDE (data->ulong_); + +#ifndef _RWSTD_NO_LONG_LONG + + data->llong_.value_ =3D (_RWSTD_LONG_LONG)ival; + PUT_NARROW(data->llong_); + PUT_WIDE (data->llong_); + + data->ullong_.value_ =3D + (unsigned _RWSTD_LONG_LONG)ival; + PUT_NARROW(data->ullong_); + PUT_WIDE (data->ullong_); + +#endif // _RWSTD_NO_LONG_LONG + + data->dbl_.value_ =3D (double)ival; + PUT_NARROW(data->dbl_); + PUT_WIDE (data->dbl_); + +#ifndef _RWSTD_NO_LONG_DOUBLE + + data->ldbl_.value_ =3D (long double)ival; + PUT_NARROW(data->ldbl_); + PUT_WIDE (data->ldbl_); + +#endif // _RWSTD_NO_LONG_DOUBLE + + data->ptr_.value_ =3D (void*)ival; + PUT_NARROW(data->ptr_); + PUT_WIDE (data->ptr_); + + // test boolapha flag + if (ival & 1) fmt |=3D std::ios_base::boolalpha; + + data->bool_.value_ =3D ival & 2 ? true : false; + PUT_NARROW(data->bool_); + PUT_WIDE (data->bool_); + + ++nlocales; + } + catch(...) { + // skip over bad locale + //rw_warn(0, 0, 0, "unable to create locale '%s'", name); + } + if (nlocales =3D=3D maxinx) break; } @@ -290,6 +472,13 @@ rw_opt_nloops, 1 !=3D rw_opt_nloops, int (nlocales), "%#s", locales); =20 + // avoid divide by zero in thread if there are no locales to test + if (nlocales < 1) + { + rw_fatal(nlocales !=3D 0, __FILE__, __LINE__, + "failed to create one or more usable locales"); + } + rw_info (0, 0, 0, "exercising std::num_put"); =20 test_char =3D true; ------_=_NextPart_001_01C7D874.17BF473A--