incubator-stdcxx-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Martin Sebor <se...@roguewave.com>
Subject Re: [PATCH] Update test 22.locale.time.put.mt.cpp to validate results
Date Tue, 07 Aug 2007 16:46:14 GMT
Travis Vitek wrote:
> Looks like my attachment got stripped. This is really annoying. Does
> anyone have any idea why ezmlm hates me so?

I suspect it hates Outlook users more than the rest of us ;-)
Check to see the MIME type of the attachment in your outgoing
email and cross-reference it with the list in INFRA-1194 to
see if it's forbidden. If it is, you'll either need to figure
out how to change it to a type that's not forbidden or get
the Apache infrastructure team to allow that type. You might
also want to try sending it from a different mailer, such
as Mozilla or Thunderbird. They both work for me (for plain
text attachments.)

> 
> I'm going to try one more time. I'm attaching the patch file, and I'm
> pasting the contents below the patch information. If that fails I'll
> stop trying to paste/attach patches and I'll just start opening JIRAs.

That might be what we need to do in the meantime, until you
get one of the approaches above to work. It would be a huge
hassle to have to open a new Jira for every patch.

Martin

> 
> Travis
> 
> -----Original Message-----
> 
> Attached is a patch to enhance the time_put facet mt test. Threads
> verify that the values they put compare equal to those put in the
> primary thread.
> 
> 2007-08-07	Travis Vitek	<vitek@roguewave.com>
> 
> 	* 22.locale.time.put.mt.cpp (MyIos, MyStreambuf, MyTimeData):
>       Added structures to simplify testing.
> 	(run_test): Build table of in/outputs for verification in test
>       threads. 
>       (thread_func): Assert that data written matches expected.
> 
> Index: 22.locale.time.put.mt.cpp
> ===================================================================
> --- 22.locale.time.put.mt.cpp	(revision 562577)
> +++ 22.locale.time.put.mt.cpp	(working copy)
> @@ -32,7 +32,7 @@
>  #include <iterator>   // for ostreambuf_iterator
>  #include <locale>     // for locale, time_put
>  
> -#include <cstring>    // for strlen()
> +#include <cstring>    // for strlen ()
>  #include <ctime>      // for tm
>  
>  #include <rw_locale.h>
> @@ -60,76 +60,124 @@
>  static std::size_t
>  nlocales;
>  
> -/**********************************************************************
> ****/
> +struct MyTimeData
> +{
> +    enum { BufferSize = 64 };
>  
> -extern "C" {
> +    // name of the locale the data corresponds to
> +    const char* locale_name_;
>  
> -bool test_char;    // exercise time_put<char>
> -bool test_wchar;   // exercise time_put<wchar_t>
> +    // optinally set to the named locale for threads to share
> +    std::locale locale_;
>  
> +    // the time struct used to generate strings below
> +    std::tm time_;
>  
> -static void*
> -thread_func (void*)
> +    // the format specifier
> +    char format_;
> +
> +    // narrow representations of time_ given the 
> +    // locale_name_ and the format_
> +    char ncs_ [BufferSize];
> +    std::char_traits<char>::off_type nlen_;
> +    
> +#ifndef _RWSTD_NO_WCHAR_T
> +
> +    // wide representations of time_
> +    wchar_t wcs_ [BufferSize];
> +    std::char_traits<wchar_t>::off_type wlen_;
> +
> +#endif // _RWSTD_NO_WCHAR_T
> +
> +} my_time_data [MAX_THREADS];
> +
> +
> +/**********************************************************************
> ****/
> +
> +template <class charT, class Traits>
> +struct MyIos: std::basic_ios<charT, Traits>
>  {
> -    std::tm tmb = std::tm ();
> +    MyIos () {
> +        this->init (0);
> +    }
> +};
>  
> -    const char cvtspecs[] = "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%";
> +template <class charT, class Traits>
> +struct MyStreambuf: std::basic_streambuf<charT, Traits>
> +{
> +    typedef std::basic_streambuf<charT, Traits> Base;
>  
> -    // 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;
> +    MyStreambuf ()
> +        : Base () {
> +    }
>  
> -#ifndef _RWSTD_NO_WCHAR_T
> +    void pubsetp (charT *pbeg, charT *pend) {
> +        this->setp (pbeg, pend);
> +    }
>  
> -    struct WideBuf: std::wstreambuf {
> -        int_type overflow (int_type c) { return c; }
> -    } wsb;
> +    charT* pubpbase () const {
> +        return pbase ();
> +    }
>  
> -#endif   // _RWSTD_NO_WCHAR_T
> +    charT* pubpptr () const {
> +        return pptr ();
> +    }
>  
> -    struct Ios: std::ios {
> -        Ios () { this->init (0); }
> -    } io;
> +    charT* pubepptr () const {
> +        return epptr ();
> +    }
> +};
>  
> -    int j = 0;
> +#define countof(x) (sizeof (x) / sizeof (*x))
>  
> -    for (int i = 0; i != rw_opt_nloops; ++i, ++j) {
> +extern "C" {
>  
> -        // initialize tm with random but valid values
> -        tmb.tm_sec  = ++j % 61;
> -        tmb.tm_min  = ++j % 60;
> -        tmb.tm_min  = ++j % 60;
> -        tmb.tm_wday = ++j % 7;
> -        tmb.tm_mon  = ++j % 12;
> -        tmb.tm_year = ++j;
> +bool test_char;    // exercise time_put<char>
> +bool test_wchar;   // exercise time_put<wchar_t>
>  
> -        // generate a "random" conversion specifier from the set
> -        // of valid specifiers recognized by the facet to exercise
> -        // all (or most) code paths
> -        const char cvt = cvtspecs [i % (sizeof cvtspecs - 1)];
>  
> +static void*
> +thread_func (void*)
> +{
> +    char                                       ncs
> [MyTimeData::BufferSize];
> +    MyIos<char, std::char_traits<char> >       nio;
> +    MyStreambuf<char, std::char_traits<char> > nsb;
> +
> +#ifndef _RWSTD_NO_WCHAR_T
> +    wchar_t                                          wcs
> [MyTimeData::BufferSize];
> +    MyIos<wchar_t, std::char_traits<wchar_t> >       wio;
> +    MyStreambuf<wchar_t, std::char_traits<wchar_t> > wsb;
> +#endif // _RWSTD_NO_WCHAR_T
> +
> +    for (int i = 0; i != rw_opt_nloops; ++i) {
> +
>          // save the name of the locale
> -        const char* const locale_name = locales [i % nlocales];
> +        const MyTimeData& data = my_time_data[i % nlocales];
>  
>          // construct a named locale, get a reference to the time_put
>          // facet from it and use it to format a random time value
>          // using a random conversion specifier
> -        const std::locale loc (locale_name);
> +        const std::locale loc (data.locale_name_);
>  
>          if (test_char) {
>              // exercise the narrow char specialization of the facet
>  
> +            // should this be hoisted out of the loop?
>              const std::time_put<char> &tp =
>                  std::use_facet<std::time_put<char> >(loc);
>  
> -            // format a "random" but valid tm value using the random
> -            // format specifier
> -            tp.put (std::ostreambuf_iterator<char>(&sb),
> -                    io, ' ', &tmb, cvt);
> +            // assign data buffer to streambuf
> +            nsb.pubsetp (ncs, ncs + countof (ncs));
>  
> +            // format time using provided format specifier
> +            tp.put (std::ostreambuf_iterator<char>(&nsb),
> +                    nio, ' ', &data.time_, data.format_);
> +
> +            const std::char_traits<char>::off_type nlen =
> +                nsb.pubpptr() - nsb.pubpbase();
> +
> +            RW_ASSERT (nlen == data.nlen_ &&
> +                       !memcmp (data.ncs_, ncs, nlen));
>          }
>  
>          // both specializations may be tested at the same time
> @@ -139,14 +187,23 @@
>  
>  #ifndef _RWSTD_NO_WCHAR_T
>  
> +            // should this be hoisted out of the loop?
>              const std::time_put<wchar_t> &wtp =
>                  std::use_facet<std::time_put<wchar_t> >(loc);
>  
> +            wsb.pubsetp (wcs, wcs + countof (wcs));
> +
>              wtp.put (std::ostreambuf_iterator<wchar_t>(&wsb),
> -                     io, L' ', &tmb, cvt);
> +                     wio, L' ', &data.time_, data.format_);
>  
> -#endif   // _RWSTD_NO_WCHAR_T
> +            const std::char_traits<wchar_t>::off_type wlen =
> +                wsb.pubpptr() - wsb.pubpbase();
>  
> +            RW_ASSERT (wlen == data.wlen_ &&
> +                       !memcmp (data.wcs_, wcs, wlen));
> +
> +#endif // _RWSTD_NO_WCHAR_T
> +
>          }
>      }
>  
> @@ -160,19 +217,91 @@
>  static int
>  run_test (int, char**)
>  {
> -    // find all installed locales for which setlocale(LC_ALL) succeeds
> +    MyIos<char, std::char_traits<char> >       nio;
> +    MyStreambuf<char, std::char_traits<char> > nsb;
> +
> +#ifndef _RWSTD_NO_WCHAR_T
> +    MyIos<wchar_t, std::char_traits<wchar_t> >       wio;
> +    MyStreambuf<wchar_t, std::char_traits<wchar_t> > wsb;
> +#endif // _RWSTD_NO_WCHAR_T
> +
> +    // find all installed locales for which setlocale (LC_ALL) succeeds
>      const char* const locale_list =
>          rw_opt_locales ? rw_opt_locales : rw_locales (_RWSTD_LC_ALL);
>  
> -    const std::size_t maxinx = sizeof locales / sizeof *locales;
> +    const std::size_t maxinx = countof (locales);
>  
> -    for (const char *name = locale_list; *name; name += std::strlen
> (name) +1) {
> -        locales [nlocales++] = name;
> +    const char cvtspecs [] = "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%";
>  
> +    int j = 0;
> +    for (const char const *name = locale_list;
> +         *name;
> +         name += std::strlen (name) + 1) {
> +
> +        const std::size_t inx = nlocales;
> +        locales [inx] = name;
> +
> +        // fill in the time and results for this locale
> +        MyTimeData& data = my_time_data[nlocales];
> +        data.locale_name_ = name;
> +
> +        try {
> +            const std::locale loc (name);
> +
> +            // initialize tm with random but valid values
> +            data.time_.tm_sec  = ++j % 61;
> +            data.time_.tm_min  = ++j % 60;
> +            data.time_.tm_hour = ++j % 12;
> +            data.time_.tm_wday = ++j % 7;
> +            data.time_.tm_mon  = ++j % 12;
> +            data.time_.tm_mday = ++j % 31;
> +            data.time_.tm_yday = ++j % 366;
> +            data.time_.tm_year = ++j;
> +
> +            // get the "random" conversion specifier used to generate
> +            // the result string
> +            data.format_ = cvtspecs [nlocales % (sizeof cvtspecs - 1)];
> +
> +            const std::time_put<char> &np =
> +                std::use_facet<std::time_put<char> >(loc);
> +
> +            nsb.pubsetp (data.ncs_, data.ncs_ + countof (data.ncs_));
> +            
> +            np.put (std::ostreambuf_iterator<char>(&nsb),
> +                    nio, ' ', &data.time_, data.format_);
> +
> +            data.nlen_ = nsb.pubpptr() - nsb.pubpbase();
> +
> +#ifndef _RWSTD_NO_WCHAR_T
> +
> +            const std::time_put<wchar_t> &wp =
> +                std::use_facet<std::time_put<wchar_t> >(loc);
> +
> +            wsb.pubsetp (data.wcs_, data.wcs_ + countof (data.wcs_));
> +            
> +            wp.put (std::ostreambuf_iterator<wchar_t>(&wsb),
> +                    wio, L' ', &data.time_, data.format_);
> +
> +            data.wlen_ = wsb.pubpptr() - wsb.pubpbase();
> +
> +#endif // _RWSTD_NO_WCHAR_T
> +
> +        } catch (...) {
> +            // skip over bad locale
> +        }
> +
> +        nlocales += 1;
> +
>          if (nlocales == maxinx)
>              break;
>      }
>  
> +    // avoid divide by zero in thread if there are no locales to test
> +    if (nlocales < 1) {
> +        rw_fatal(nlocales != 0, 0, __LINE__,
> +                 "failed to create one or more usable locales");
> +    }
> +
>      rw_info (0, 0, 0,
>               "testing std::time_put<charT> with %d thread%{?}s%{;}, "
>               "%zu iteration%{?}s%{;} each, in locales { %{ .*A@} }",


Mime
View raw message