You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stdcxx.apache.org by se...@apache.org on 2007/09/28 22:57:41 UTC
svn commit: r580483 [41/42] - in /incubator/stdcxx/branches/4.2.0: ./ bin/
doc/ doc/stdlibref/ doc/stdlibug/ etc/config/ etc/config/src/
etc/config/windows/ etc/nls/charmaps/ etc/nls/posix/charmaps/
etc/nls/posix/src/ etc/nls/src/ examples/manual/ exam...
Modified: incubator/stdcxx/branches/4.2.0/tests/localization/22.locale.num.put.mt.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/branches/4.2.0/tests/localization/22.locale.num.put.mt.cpp?rev=580483&r1=580482&r2=580483&view=diff
==============================================================================
--- incubator/stdcxx/branches/4.2.0/tests/localization/22.locale.num.put.mt.cpp (original)
+++ incubator/stdcxx/branches/4.2.0/tests/localization/22.locale.num.put.mt.cpp Fri Sep 28 13:55:52 2007
@@ -33,24 +33,26 @@
#include <cstring> // for strlen()
#include <rw_locale.h>
-#include <rw_thread.h>
+#include <rw_thread.h> // for rw_get_processors (), rw_thread_pool()
#include <driver.h>
+#include <valcmp.h>
+#define MAX_THREADS 32
+#define MAX_LOOPS 100000
-// maximum number of threads allowed by the command line interface
-#define MAX_THREADS 32
+// default number of threads (will be adjusted to the number
+// of processors/cores later)
+int rw_opt_nthreads = 1;
+// the number of times each thread should iterate
+int rw_opt_nloops = MAX_LOOPS;
-#ifdef _RWSTD_REENTRANT
-int rw_opt_nthreads = 4;
-#else // if !defined (_RWSTD_REENTRANT)
-// in non-threaded builds use just one thread
-int rw_opt_nthreads = 1;
-#endif // _RWSTD_REENTRANT
+// number of locales to use
+int rw_opt_nlocales = MAX_THREADS;
-// the number of times each thread should iterate (unless specified
-// otherwise on the command line)
-int rw_opt_nloops = 200000;
+// should all threads share the same set of locale objects instead
+// of creating their own?
+int rw_opt_shared_locale;
/**************************************************************************/
@@ -62,99 +64,178 @@
static std::size_t
nlocales;
-/**************************************************************************/
-extern "C" {
+struct MyNumData {
-bool test_char; // exercise num_put<char>
-bool test_wchar; // exercise num_put<wchar_t>
+ enum { BufferSize = 32 };
+ enum PutId {
+ put_bool,
+ put_long,
+ put_ulong,
-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;
+#ifndef _RWSTD_NO_LONG_LONG
-#ifndef _RWSTD_NO_WCHAR_T
+ put_llong,
+ put_ullong,
- struct WideBuf: std::wstreambuf {
- int_type overflow (int_type c) { return c; }
- } wb;
+#endif // _RWSTD_NO_LONG_LONG
-#endif // _RWSTD_NO_WCHAR_T
+ put_dbl,
- struct Ios: std::ios {
- Ios () { this->init (0); }
- } io;
-
- const std::ios::fmtflags baseflags[] = {
- std::ios::oct,
- std::ios::dec,
- std::ios::hex
- };
+#ifndef _RWSTD_NO_LONG_DOUBLE
- const std::ios::fmtflags fmtflags[] = {
- std::ios::showpos,
- std::ios::showpoint,
- std::ios::fixed,
- std::ios::scientific
- };
+ put_ldbl,
+
+#endif // _RWSTD_NO_LONG_DOUBLE
- const std::ios::fmtflags adjustflags[] = {
- std::ios::internal,
- std::ios::left,
- std::ios::right
+ put_ptr,
+ put_max
};
- for (int i = 0; i != rw_opt_nloops; ++i) {
+ // name of the locale the data corresponds to
+ const char* locale_name_;
- // save the name of the locale
- const char* const locale_name = locales [i % nlocales];
+ // optionally set to the named locale for threads to share
+ std::locale locale_;
- // 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);
-
- enum PutId {
- put_bool,
- put_long,
- put_ulong,
+ // the value that we will be formatting
+ double value_;
+
+ // the type of the data we put
+ PutId type_;
+
+ // holds the narrow/wide character representation of value_ and
+ // the number of used 'charT' in each buffer.
+ char ncs_ [BufferSize];
+
+#ifndef _RWSTD_NO_WCHAR_T
+
+ wchar_t wcs_ [BufferSize];
+
+#endif // _RWSTD_NO_WCHAR_T
+
+} my_num_data [MAX_THREADS];
+
+/**************************************************************************/
+
+template <class charT, class Traits>
+struct MyIos: std::basic_ios<charT, Traits>
+{
+ MyIos () {
+ this->init (0);
+ }
+};
+
+template <class charT, class Traits>
+struct MyStreambuf: std::basic_streambuf<charT, Traits>
+{
+ typedef std::basic_streambuf<charT, Traits> Base;
+
+ MyStreambuf ()
+ : Base () {
+ }
+
+ void pubsetp (charT *pbeg, std::streamsize n) {
+ this->setp (pbeg, pbeg + n);
+ }
+};
+
+template <class charT, class Traits>
+void
+put_data (const MyNumData &data,
+ const std::num_put<charT> &np,
+ const std::ostreambuf_iterator<charT, Traits> &iter,
+ std::basic_ios<charT, Traits> &io,
+ charT fill,
+ charT term)
+{
+ switch (data.type_) {
+ case MyNumData::put_bool:
+ *np.put (iter, io, fill,
+ data.value_ < 1.f) = term;
+ break;
+ case MyNumData::put_long:
+ *np.put (iter, io, fill,
+ (long)data.value_) = term;
+ break;
+ case MyNumData::put_ulong:
+ *np.put (iter, io, fill,
+ (unsigned long)data.value_) = term;
+ break;
#ifndef _RWSTD_NO_LONG_LONG
- put_llong,
- put_ullong,
+ case MyNumData::put_llong:
+ *np.put (iter, io, fill,
+ (_RWSTD_LONG_LONG)data.value_) = term;
+ break;
+ case MyNumData::put_ullong:
+ *np.put (iter, io, fill,
+ (unsigned _RWSTD_LONG_LONG)data.value_) = term;
+ break;
#endif // _RWSTD_NO_LONG_LONG
- put_dbl,
- put_ldbl,
- put_ptr,
- put_max
- };
+ case MyNumData::put_dbl:
+ *np.put (iter, io, fill,
+ (double)data.value_) = term;
+
+ break;
+
+#ifndef _RWSTD_NO_LONG_DOUBLE
+
+ case MyNumData::put_ldbl:
+ *np.put (iter, io, fill,
+ (long double)data.value_) = term;
+ break;
+
+#endif // _RWSTD_NO_LONG_DOUBLE
+
+ case MyNumData::put_ptr:
+ *np.put (iter, io, fill,
+ (const void*)&data.value_) = term;
+ break;
+
+ case MyNumData::put_max:
+ // avoid enumeration value `put_max' not handled in switch
+ // this case should never happen
+ break;
+ }
+
+}
+
+extern "C" {
+
+bool test_char; // exercise num_put<char>
+bool test_wchar; // exercise num_put<wchar_t>
- const std::ios::fmtflags base =
- baseflags [i % (sizeof baseflags / sizeof *baseflags)];
- const std::ios::fmtflags fmt =
- fmtflags [i % (sizeof baseflags / sizeof *baseflags)];
+static void*
+thread_func (void*)
+{
+ char ncs [MyNumData::BufferSize];
+ MyIos<char, std::char_traits<char> > nio;
+ MyStreambuf<char, std::char_traits<char> > nsb;
+ nio.rdbuf (&nsb);
- const std::ios::fmtflags adjust =
- adjustflags [i % (sizeof baseflags / sizeof *baseflags)];
+#ifndef _RWSTD_NO_WCHAR_T
+ wchar_t wcs [MyNumData::BufferSize];
+ MyIos<wchar_t, std::char_traits<wchar_t> > wio;
+ MyStreambuf<wchar_t, std::char_traits<wchar_t> > wsb;
+ wio.rdbuf (&wsb);
+#endif // _RWSTD_NO_WCHAR_T
- io.flags (base | fmt | adjust);
+ for (int i = 0; i != rw_opt_nloops; ++i) {
- io.width (i % 16);
+ // fill in the value and results for this locale
+ const MyNumData& data = my_num_data [i % nlocales];
- // exercise postive and negative values
- const int ival = i & 1 ? -i : i;
+ // construct a named locale and imbue it in the ios object
+ // so that the locale is used not only by the num_put facet
+ const std::locale loc =
+ rw_opt_shared_locale ? data.locale_
+ : std::locale (data.locale_name_);
if (test_char) {
// exercise the narrow char specialization of the facet
@@ -162,50 +243,14 @@
const std::num_put<char> &np =
std::use_facet<std::num_put<char> >(loc);
- const std::ostreambuf_iterator<char> iter (&sb);
+ nio.imbue (loc);
+ nsb.pubsetp (ncs, RW_COUNT_OF (ncs));
- switch (PutId (i % put_max)) {
- case put_bool:
- if (i & 2)
- io.setf (std::ios::boolalpha);
- else
- io.unsetf (std::ios::boolalpha);
-
- np.put (iter, io, ' ', bool (ival));
- break;
-
- case put_long:
- np.put (iter, io, ' ', long (ival));
- break;
-
- case put_ulong:
- np.put (iter, io, ' ', (unsigned long)ival);
- break;
+ put_data (data, np, std::ostreambuf_iterator<char>(&nsb),
+ nio, ' ', '\0');
-#ifndef _RWSTD_NO_LONG_LONG
-
- case put_llong:
- np.put (iter, io, ' ', (_RWSTD_LONG_LONG)ival);
- break;
-
-#endif // _RWSTD_NO_LONG_LONG
-
- case put_ullong:
- np.put (iter, io, ' ', (unsigned _RWSTD_LONG_LONG)ival);
- break;
-
- case put_dbl:
- np.put (iter, io, ' ', double (ival));
- break;
-
- case put_ldbl:
- np.put (iter, io, ' ', (long double)ival);
- break;
-
- case put_ptr:
- np.put (iter, io, ' ', (void*)ival);
- break;
- }
+ RW_ASSERT (!nio.fail ());
+ RW_ASSERT (!rw_strncmp (ncs, data.ncs_));
}
// both specializations may be tested at the same time
@@ -215,48 +260,17 @@
#ifndef _RWSTD_NO_WCHAR_T
- const std::num_put<wchar_t> &np =
+ const std::num_put<wchar_t> &wp =
std::use_facet<std::num_put<wchar_t> >(loc);
- const std::ostreambuf_iterator<wchar_t> iter (&wb);
+ wio.imbue (loc);
+ wsb.pubsetp (wcs, RW_COUNT_OF (wcs));
- switch (PutId (i % put_max)) {
- case put_bool:
- np.put (iter, io, L' ', bool (ival));
- break;
-
- case put_long:
- np.put (iter, io, L' ', long (ival));
- break;
-
- case put_ulong:
- np.put (iter, io, L' ', (unsigned long)ival);
- break;
+ put_data (data, wp, std::ostreambuf_iterator<wchar_t>(&wsb),
+ wio, L' ', L'\0');
-#ifndef _RWSTD_NO_LONG_LONG
-
- case put_llong:
- np.put (iter, io, L' ', (_RWSTD_LONG_LONG)ival);
- break;
-
- case put_ullong:
- np.put (iter, io, L' ', (unsigned _RWSTD_LONG_LONG)ival);
- break;
-
-#endif // _RWSTD_NO_LONG_LONG
-
- case put_dbl:
- np.put (iter, io, L' ', double (ival));
- break;
-
- case put_ldbl:
- np.put (iter, io, L' ', (long double)ival);
- break;
-
- case put_ptr:
- np.put (iter, io, L' ', (void*)ival);
- break;
- }
+ RW_ASSERT (!wio.fail ());
+ RW_ASSERT (!rw_strncmp (wcs, data.wcs_));
#endif // _RWSTD_NO_WCHAR_T
@@ -270,26 +284,98 @@
/**************************************************************************/
+
static int
run_test (int, char**)
{
- char* const locale_list = rw_locales ();
+ MyIos<char, std::char_traits<char> > nio;
+ MyStreambuf<char, std::char_traits<char> > nsb;
+ nio.rdbuf (&nsb);
+
+#ifndef _RWSTD_NO_WCHAR_T
+ MyIos<wchar_t, std::char_traits<wchar_t> > wio;
+ MyStreambuf<wchar_t, std::char_traits<wchar_t> > wsb;
+ wio.rdbuf (&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 = RW_COUNT_OF (locales);
+
+ for (const char *name = locale_list;
+ *name;
+ name += std::strlen (name) + 1) {
+
+ const std::size_t inx = nlocales;
+ locales [inx] = name;
+
+ // fill in the value and results for this locale
+ MyNumData& data = my_num_data [nlocales];
+ data.locale_name_ = name;
- const std::size_t maxinx = sizeof locales / sizeof *locales;
+ try {
+ const std::locale loc (data.locale_name_);
- for (char *name = locale_list; *name; name += std::strlen (name) + 1) {
- locales [nlocales++] = name;
+ data.value_ = nlocales & 1 ? -1 * nlocales : nlocales;
+ data.type_ = MyNumData::PutId (nlocales % MyNumData::put_max);
- if (nlocales == maxinx)
+ // format data into buffers
+ const std::num_put<char> &np =
+ std::use_facet<std::num_put<char> >(loc);
+
+ nio.imbue (loc);
+ nsb.pubsetp (data.ncs_, RW_COUNT_OF (data.ncs_));
+
+ put_data (data, np, std::ostreambuf_iterator<char>(&nsb),
+ nio, ' ', '\0');
+
+ rw_fatal (!nio.fail (), __FILE__, __LINE__,
+ "num_put<char>::put(...) failed for locale(%#s)",
+ data.locale_name_);
+
+#ifndef _RWSTD_NO_WCHAR_T
+
+ const std::num_put<wchar_t> &wp =
+ std::use_facet<std::num_put<wchar_t> >(loc);
+
+ wio.imbue (loc);
+ wsb.pubsetp (data.wcs_, RW_COUNT_OF (data.wcs_));
+
+ put_data (data, wp, std::ostreambuf_iterator<wchar_t>(&wsb),
+ wio, L' ', L'\0');
+
+ rw_fatal (!wio.fail (), __FILE__, __LINE__,
+ "num_put<wchar_t>::put(...) failed for locale(%#s)",
+ data.locale_name_);
+
+#endif // _RWSTD_NO_WCHAR_T
+
+ if (rw_opt_shared_locale)
+ data.locale_ = loc;
+
+ nlocales += 1;
+ }
+ catch (...) {
+ rw_warn (!rw_opt_locales, 0, __LINE__,
+ "failed to create locale(%#s)", name);
+ }
+
+ if (nlocales == maxinx || nlocales == std::size_t (rw_opt_nlocales))
break;
}
+ // avoid divide by zero in thread if there are no locales to test
+ rw_fatal (nlocales != 0, 0, __LINE__,
+ "failed to create one or more usable locales!");
+
rw_info (0, 0, 0,
"testing std::num_put<charT> with %d thread%{?}s%{;}, "
- "%zu iteration%{?}s%{;} each, in locales { %{ .*A@} }",
+ "%zu iteration%{?}s%{;} each, in %zu locales { %{ .*A@} }",
rw_opt_nthreads, 1 != rw_opt_nthreads,
rw_opt_nloops, 1 != rw_opt_nloops,
- int (nlocales), "%#s", locales);
+ nlocales, int (nlocales), "%#s", locales);
rw_info (0, 0, 0, "exercising std::num_put<char>");
@@ -319,7 +405,7 @@
"rw_thread_pool(0, %d, 0, %{#f}, 0) failed",
rw_opt_nthreads, thread_func);
- // exercise bothe the char and the wchar_t specializations
+ // exercise both the char and the wchar_t specializations
// at the same time
rw_info (0, 0, 0,
@@ -345,12 +431,28 @@
int main (int argc, char *argv[])
{
+#ifdef _RWSTD_REENTRANT
+
+ // set nthreads to the greater of the number of processors
+ // and 2 (for uniprocessor systems) by default
+ rw_opt_nthreads = rw_get_cpus ();
+ if (rw_opt_nthreads < 2)
+ rw_opt_nthreads = 2;
+
+#endif // _RWSTD_REENTRANT
+
return rw_test (argc, argv, __FILE__,
"lib.locale.num.put",
"thread safety", run_test,
"|-nloops#0 " // must be non-negative
- "|-nthreads#0-*", // must be in [0, MAX_THREADS]
+ "|-nthreads#0-* " // must be in [0, MAX_THREADS]
+ "|-nlocales#0 " // arg must be non-negative
+ "|-locales= " // must be provided
+ "|-shared-locale# ",
&rw_opt_nloops,
int (MAX_THREADS),
- &rw_opt_nthreads);
+ &rw_opt_nthreads,
+ &rw_opt_nlocales,
+ &rw_opt_setlocales,
+ &rw_opt_shared_locale);
}
Modified: incubator/stdcxx/branches/4.2.0/tests/localization/22.locale.numpunct.mt.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/branches/4.2.0/tests/localization/22.locale.numpunct.mt.cpp?rev=580483&r1=580482&r2=580483&view=diff
==============================================================================
--- incubator/stdcxx/branches/4.2.0/tests/localization/22.locale.numpunct.mt.cpp (original)
+++ incubator/stdcxx/branches/4.2.0/tests/localization/22.locale.numpunct.mt.cpp Fri Sep 28 13:55:52 2007
@@ -41,18 +41,21 @@
// maximum number of threads allowed by the command line interface
#define MAX_THREADS 32
-
-#ifdef _RWSTD_REENTRANT
-int rw_opt_nthreads = 4;
-#else // if !defined (_RWSTD_REENTRANT)
-// in non-threaded builds use just one thread
+// default number of threads (will be adjusted to the number
+// of processors/cores later)
int rw_opt_nthreads = 1;
-#endif // _RWSTD_REENTRANT
// the number of times each thread should iterate (unless specified
// otherwise on the command line)
int rw_opt_nloops = 200000;
+// number of locales to use
+int rw_opt_nlocales = MAX_THREADS;
+
+// should all threads share the same set of locale objects instead
+// of creating their own?
+int rw_opt_shared_locale;
+
/**************************************************************************/
// array of locale names to use for testing
@@ -67,18 +70,22 @@
struct NumPunctData
{
+ const char* locale_name_;
+ std::locale locale_;
+
+ std::string grouping_;
+
char decimal_point_;
char thousands_sep_;
- char grouping_ [32];
- char truename_ [32];
- char falsename_ [32];
+ std::string truename_;
+ std::string falsename_;
#ifndef _RWSTD_NO_WCHAR_T
wchar_t wdecimal_point_;
wchar_t wthousands_sep_;
- wchar_t wtruename_ [32];
- wchar_t wfalsename_ [32];
+ std::wstring wtruename_;
+ std::wstring wfalsename_;
#endif // _RWSTD_NO_WCHAR_T
@@ -98,16 +105,12 @@
const std::size_t inx = std::size_t (i) % nlocales;
- // save the name of the locale
- const char* const locale_name = locales [inx];
-
- const NumPunctData* const data = punct_data + inx;
+ const NumPunctData& data = punct_data[inx];
// construct a named locale
- const std::locale loc (locale_name);
-
- // exercise postive and negative values
- const int ival = i & 1 ? -i : i;
+ const std::locale loc =
+ rw_opt_shared_locale ? data.locale_
+ : std::locale (data.locale_name_);
if (test_char) {
// exercise the narrow char specialization of the facet
@@ -121,11 +124,14 @@
const std::string tn = np.truename ();
const std::string fn = np.falsename ();
- RW_ASSERT (dp == data->decimal_point_);
- RW_ASSERT (ts == data->thousands_sep_);
- RW_ASSERT (0 == rw_strncmp (grp.c_str (), data->grouping_));
- RW_ASSERT (0 == rw_strncmp (tn.c_str (), data->truename_));
- RW_ASSERT (0 == rw_strncmp (fn.c_str (), data->falsename_));
+ RW_ASSERT (dp == data.decimal_point_);
+ RW_ASSERT (ts == data.thousands_sep_);
+ RW_ASSERT (0 == rw_strncmp (grp.c_str (),
+ data.grouping_.c_str ()));
+ RW_ASSERT (0 == rw_strncmp (tn.c_str (),
+ data.truename_.c_str ()));
+ RW_ASSERT (0 == rw_strncmp (fn.c_str (),
+ data.falsename_.c_str ()));
}
// both specializations may be tested at the same time
@@ -135,20 +141,23 @@
#ifndef _RWSTD_NO_WCHAR_T
- const std::numpunct<wchar_t> &np =
+ const std::numpunct<wchar_t> &wp =
std::use_facet<std::numpunct<wchar_t> >(loc);
- const wchar_t dp = np.decimal_point ();
- const wchar_t ts = np.thousands_sep ();
- const std::string grp = np.grouping ();
- const std::wstring tn = np.truename ();
- const std::wstring fn = np.falsename ();
-
- RW_ASSERT (dp == data->wdecimal_point_);
- RW_ASSERT (ts == data->wthousands_sep_);
- RW_ASSERT (0 == rw_strncmp (grp.c_str (), data->grouping_));
- RW_ASSERT (0 == rw_strncmp (tn.c_str (), data->wtruename_));
- RW_ASSERT (0 == rw_strncmp (fn.c_str (), data->wfalsename_));
+ const wchar_t dp = wp.decimal_point ();
+ const wchar_t ts = wp.thousands_sep ();
+ const std::string grp = wp.grouping ();
+ const std::wstring tn = wp.truename ();
+ const std::wstring fn = wp.falsename ();
+
+ RW_ASSERT (dp == data.wdecimal_point_);
+ RW_ASSERT (ts == data.wthousands_sep_);
+ RW_ASSERT (0 == rw_strncmp (grp.c_str (),
+ data.grouping_.c_str ()));
+ RW_ASSERT (0 == rw_strncmp (tn.c_str (),
+ data.wtruename_.c_str ()));
+ RW_ASSERT (0 == rw_strncmp (fn.c_str (),
+ data.wfalsename_.c_str ()));
#endif // _RWSTD_NO_WCHAR_T
@@ -165,64 +174,67 @@
static int
run_test (int, char**)
{
- // get a NUL-separated list of names of installed locales
- char* const locale_list = rw_locales ();
+ // 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 = sizeof punct_data / sizeof *punct_data;
// iterate over locales, initializing a global punct_data array
- for (char *name = locale_list; *name; name += std::strlen (name) + 1) {
+ for (const char *name = locale_list;
+ *name;
+ name += std::strlen (name) +1) {
const std::size_t inx = nlocales;
-
locales [inx] = name;
- // set LC_NUMERIC and LC_CTYPE to be able to use mbstowcs()
- if (std::setlocale (LC_ALL, name)) {
+ NumPunctData& data = punct_data [inx];
+
+ try {
+ std::locale loc(name);
+ data.locale_name_ = name;
- const std::lconv* const pconv = std::localeconv ();
- NumPunctData* const pdata = punct_data + inx;
+ const std::numpunct<char> &np =
+ std::use_facet<std::numpunct<char> >(loc);
+
+ data.grouping_ = np.grouping ();
- // assign just the first character of the (potentially)
- // multibyte decimal_point and thousands_sep (C++ locale
- // can't deal with more)
- pdata->decimal_point_ = *pconv->decimal_point;
- pdata->thousands_sep_ = *pconv->thousands_sep;
+ data.decimal_point_ = np.decimal_point ();
+ data.thousands_sep_ = np.thousands_sep ();
- // simply copy the narrow grouping
- std::strcpy (pdata->grouping_, pconv->grouping);
+ data.truename_ = np.truename ();
+ data.falsename_ = np.falsename ();
- // FIXME: this will need to change once useful truename
- // and falsename has been implemented
- std::strcpy (pdata->truename_, "true");
- std::strcpy (pdata->falsename_, "false");
+#ifndef _RWSTD_NO_WCHAR_T
- wchar_t tmp [2];
+ const std::numpunct<wchar_t> &wp =
+ std::use_facet<std::numpunct<wchar_t> >(loc);
- // convert multibyte decimal point and thousands separator
- // to wide characters (assumes they are single character
- // each -- C++ locale can't handle more)
- std::mbstowcs (tmp, pconv->decimal_point, 2);
- pdata->wdecimal_point_ = tmp [0];
+ data.wdecimal_point_ = wp.decimal_point ();
+ data.wthousands_sep_ = wp.thousands_sep ();
- std::mbstowcs (tmp, pconv->thousands_sep, 2);
- pdata->wthousands_sep_ = tmp [0];
+ data.wtruename_ = wp.truename ();
+ data.wfalsename_ = wp.falsename ();
- const std::size_t n =
- sizeof pdata->wtruename_ / sizeof (wchar_t);
+#endif
- std::mbstowcs (pdata->wtruename_, pdata->truename_, n);
- std::mbstowcs (pdata->wfalsename_, pdata->falsename_, n);
+ if (rw_opt_shared_locale)
+ data.locale_ = loc;
- ++nlocales;
+ nlocales += 1;
+ }
+ catch (...) {
+ rw_warn (!rw_opt_locales, 0, __LINE__,
+ "failed to create locale(%#s)", name);
}
- if (nlocales == maxinx)
+ if (nlocales == maxinx || nlocales == std::size_t (rw_opt_nlocales))
break;
}
- // reset the global locale
- std::setlocale (LC_ALL, "C");
+ // avoid divide by zero in thread if there are no locales to test
+ rw_fatal (nlocales != 0, 0, __LINE__,
+ "failed to create one or more usable locales!");
rw_info (0, 0, 0,
"testing std::numpunct<charT> with %d thread%{?}s%{;}, "
@@ -286,12 +298,28 @@
int main (int argc, char *argv[])
{
+#ifdef _RWSTD_REENTRANT
+
+ // set nthreads to the greater of the number of processors
+ // and 2 (for uniprocessor systems) by default
+ rw_opt_nthreads = rw_get_cpus ();
+ if (rw_opt_nthreads < 2)
+ rw_opt_nthreads = 2;
+
+#endif // _RWSTD_REENTRANT
+
return rw_test (argc, argv, __FILE__,
"lib.locale.numpunct",
"thread safety", run_test,
"|-nloops#0 " // must be non-negative
- "|-nthreads#0-*", // must be in [0, MAX_THREADS]
+ "|-nthreads#0-* " // must be in [0, MAX_THREADS]
+ "|-nlocales#0 " // arg must be non-negative
+ "|-locales= " // must be provided
+ "|-shared-locale# ",
&rw_opt_nloops,
int (MAX_THREADS),
- &rw_opt_nthreads);
+ &rw_opt_nthreads,
+ &rw_opt_nlocales,
+ &rw_opt_setlocales,
+ &rw_opt_shared_locale);
}
Modified: incubator/stdcxx/branches/4.2.0/tests/localization/22.locale.time.put.mt.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/branches/4.2.0/tests/localization/22.locale.time.put.mt.cpp?rev=580483&r1=580482&r2=580483&view=diff
==============================================================================
--- incubator/stdcxx/branches/4.2.0/tests/localization/22.locale.time.put.mt.cpp (original)
+++ incubator/stdcxx/branches/4.2.0/tests/localization/22.locale.time.put.mt.cpp Fri Sep 28 13:55:52 2007
@@ -32,28 +32,31 @@
#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>
#include <rw_thread.h>
-#include <driver.h>
-
+#include <driver.h> // for rw_assert ()
+#include <valcmp.h> // for rw_strncmp ()
#define MAX_THREADS 32
#define MAX_LOOPS 100000
-
-#ifdef _RWSTD_REENTRANT
-int rw_opt_nthreads = 4;
-#else // if !defined (_RWSTD_REENTRANT)
-// in non-threaded builds use just one thread
+// default number of threads (will be adjusted to the number
+// of processors/cores later)
int rw_opt_nthreads = 1;
-#endif // _RWSTD_REENTRANT
// the number of times each thread should iterate
int rw_opt_nloops = MAX_LOOPS;
+// number of locales to use
+int rw_opt_nlocales = MAX_THREADS;
+
+// should all threads share the same set of locale objects instead
+// of creating their own?
+int rw_opt_shared_locale;
+
/**************************************************************************/
// array of locale names to use for testing
@@ -66,67 +69,93 @@
/**************************************************************************/
-extern "C" {
+//
+struct MyTimeData
+{
+ enum { BufferSize = 64 };
-bool test_char; // exercise time_put<char>
-bool test_wchar; // exercise time_put<wchar_t>
+ // name of the locale the data corresponds to
+ const char* locale_name_;
+ // optionally set to the named locale for threads to share
+ std::locale locale_;
-static void*
-thread_func (void *arg)
+ // the time struct used to generate strings below
+ std::tm time_;
+
+ // the format specifier
+ char format_;
+
+ // narrow representations of time_ given the
+ // locale_name_ and the format_
+ char ncs_ [BufferSize];
+
+#ifndef _RWSTD_NO_WCHAR_T
+
+ // wide representations of time_
+ wchar_t wcs_ [BufferSize];
+
+#endif // _RWSTD_NO_WCHAR_T
+
+} my_time_data [MAX_THREADS];
+
+
+template <class charT, class Traits>
+struct MyIos: std::basic_ios<charT, Traits>
{
- const rw_thread_t* const pthread = (rw_thread_t*)arg;
+ MyIos () {
+ this->init (0);
+ }
+};
- // get the 0-based thread number
- const std::size_t threadno = std::size_t (pthread->threadno);
- std::tm tmb = std::tm ();
+template <class charT, class Traits>
+struct MyStreambuf: std::basic_streambuf<charT, Traits>
+{
+ typedef std::basic_streambuf<charT, Traits> Base;
- const char cvtspecs[] = "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%";
+ MyStreambuf ()
+ : 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;
+ void pubsetp (charT *pbeg, std::streamsize n) {
+ this->setp (pbeg, pbeg + n);
+ }
+};
-#ifndef _RWSTD_NO_WCHAR_T
- struct WideBuf: std::wstreambuf {
- int_type overflow (int_type c) { return c; }
- } wsb;
+extern "C" {
-#endif // _RWSTD_NO_WCHAR_T
+bool test_char; // exercise time_put<char>
+bool test_wchar; // exercise time_put<wchar_t>
- struct Ios: std::ios {
- Ios () { this->init (0); }
- } io;
- int j = 0;
+static void*
+thread_func (void*)
+{
+ char ncs [MyTimeData::BufferSize];
+ MyIos<char, std::char_traits<char> > nio;
+ MyStreambuf<char, std::char_traits<char> > nsb;
+ nio.rdbuf (&nsb);
- for (int i = 0; i != rw_opt_nloops; ++i, ++j) {
+#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;
+ wio.rdbuf (&wsb);
+#endif // _RWSTD_NO_WCHAR_T
- // 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;
-
- // 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)];
+ 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 =
+ rw_opt_shared_locale ? data.locale_
+ : std::locale (data.locale_name_);
if (test_char) {
// exercise the narrow char specialization of the facet
@@ -134,10 +163,15 @@
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);
+ nio.imbue (loc);
+ nsb.pubsetp (ncs, RW_COUNT_OF (ncs));
+
+ // format time using provided format specifier
+ *tp.put (std::ostreambuf_iterator<char>(&nsb),
+ nio, ' ', &data.time_, data.format_) = '\0';
+
+ RW_ASSERT (!nio.fail ());
+ RW_ASSERT (!rw_strncmp(ncs, data.ncs_));
}
@@ -148,13 +182,19 @@
#ifndef _RWSTD_NO_WCHAR_T
- const std::time_put<wchar_t> &wtp =
+ const std::time_put<wchar_t> &wp =
std::use_facet<std::time_put<wchar_t> >(loc);
- wtp.put (std::ostreambuf_iterator<wchar_t>(&wsb),
- io, L' ', &tmb, cvt);
+ wio.imbue (loc);
+ wsb.pubsetp (wcs, RW_COUNT_OF (wcs));
-#endif // _RWSTD_NO_WCHAR_T
+ *wp.put (std::ostreambuf_iterator<wchar_t>(&wsb),
+ wio, L' ', &data.time_, data.format_) = L'\0';
+
+ RW_ASSERT (!wio.fail ());
+ RW_ASSERT (!rw_strncmp(wcs, data.wcs_));
+
+#endif // _RWSTD_NO_WCHAR_T
}
}
@@ -169,23 +209,110 @@
static int
run_test (int, char**)
{
- char* const locale_list = rw_locales ();
+ MyIos<char, std::char_traits<char> > nio;
+ MyStreambuf<char, std::char_traits<char> > nsb;
+ nio.rdbuf (&nsb);
+
+#ifndef _RWSTD_NO_WCHAR_T
+ MyIos<wchar_t, std::char_traits<wchar_t> > wio;
+ MyStreambuf<wchar_t, std::char_traits<wchar_t> > wsb;
+ wio.rdbuf (&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 = RW_COUNT_OF (locales);
- for (char *name = locale_list; *name; name += std::strlen (name) + 1) {
- locales [nlocales++] = name;
+ int j = 0;
+ for (const char* 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 [inx];
+ data.locale_name_ = 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;
+
+ const char cvtspecs[] = "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%";
+
+ // get the "random" conversion specifier used to generate
+ // the result string
+ data.format_ = cvtspecs [nlocales % (sizeof cvtspecs - 1)];
+
+ try {
+ const std::locale loc (data.locale_name_);
+
+ const std::time_put<char> &np =
+ std::use_facet<std::time_put<char> >(loc);
+
+ nio.imbue (loc);
+ nsb.pubsetp (data.ncs_, RW_COUNT_OF (data.ncs_));
+
+ *np.put (std::ostreambuf_iterator<char>(&nsb),
+ nio, ' ', &data.time_, data.format_) = '\0';
+
+ rw_fatal (!nio.fail (), __FILE__, __LINE__,
+ "time_put<char>::put(..., %c) "
+ "failed for locale(%#s)",
+ data.format_, data.locale_name_);
+
+#ifndef _RWSTD_NO_WCHAR_T
- if (nlocales == maxinx)
+ const std::time_put<wchar_t> &wp =
+ std::use_facet<std::time_put<wchar_t> >(loc);
+
+ wio.imbue (loc);
+ wsb.pubsetp (data.wcs_, RW_COUNT_OF (data.wcs_));
+
+ *wp.put (std::ostreambuf_iterator<wchar_t>(&wsb),
+ wio, L' ', &data.time_, data.format_) = L'\0';
+
+ rw_fatal (!wio.fail (), __FILE__, __LINE__,
+ "time_put<wchar_t>::put(..., %c) "
+ "failed for locale(%#s)",
+ data.format_, data.locale_name_);
+
+#endif // _RWSTD_NO_WCHAR_T
+
+ if (rw_opt_shared_locale)
+ data.locale_ = loc;
+
+ nlocales += 1;
+
+ }
+ catch (...) {
+ rw_warn (!rw_opt_locales, 0, __LINE__,
+ "failed to create locale(%#s)", name);
+ }
+
+ if (nlocales == maxinx || nlocales == std::size_t (rw_opt_nlocales))
break;
}
+ // avoid divide by zero in thread if there are no locales to test
+ 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@} }",
+ "%zu iteration%{?}s%{;} each, in %zu locales { %{ .*A@} }",
rw_opt_nthreads, 1 != rw_opt_nthreads,
rw_opt_nloops, 1 != rw_opt_nloops,
- int (nlocales), "%#s", locales);
+ nlocales, int (nlocales), "%#s", locales);
rw_info (0, 0, 0, "exercising std::time_put<char>");
@@ -215,7 +342,7 @@
"rw_thread_pool(0, %d, 0, %{#f}, 0) failed",
rw_opt_nthreads, thread_func);
- // exercise bothe the char and the wchar_t specializations
+ // exercise both the char and the wchar_t specializations
// at the same time
rw_info (0, 0, 0,
@@ -241,12 +368,28 @@
int main (int argc, char *argv[])
{
+#ifdef _RWSTD_REENTRANT
+
+ // set nthreads to the greater of the number of processors
+ // and 2 (for uniprocessor systems) by default
+ rw_opt_nthreads = rw_get_cpus ();
+ if (rw_opt_nthreads < 2)
+ rw_opt_nthreads = 2;
+
+#endif // _RWSTD_REENTRANT
+
return rw_test (argc, argv, __FILE__,
"lib.locale.time.put",
"thread safety", run_test,
"|-nloops#0 " // must be non-negative
- "|-nthreads#0-*", // must be in [0, MAX_THREADS]
+ "|-nthreads#0-* " // must be in [0, MAX_THREADS]
+ "|-nlocales#0 " // arg must be non-negative
+ "|-locales= " // must be provided
+ "|-shared-locale# ",
&rw_opt_nloops,
int (MAX_THREADS),
- &rw_opt_nthreads);
+ &rw_opt_nthreads,
+ &rw_opt_nlocales,
+ &rw_opt_setlocales,
+ &rw_opt_shared_locale);
}
Modified: incubator/stdcxx/branches/4.2.0/tests/self/0.char.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/branches/4.2.0/tests/self/0.char.cpp?rev=580483&r1=580482&r2=580483&view=diff
==============================================================================
--- incubator/stdcxx/branches/4.2.0/tests/self/0.char.cpp (original)
+++ incubator/stdcxx/branches/4.2.0/tests/self/0.char.cpp Fri Sep 28 13:55:52 2007
@@ -394,7 +394,7 @@
rw_assert (cdst == ret, 0, __LINE__,
"rw_widen(char*, %{#s}%{?}, %zu%{;})",
- src, i < nsrc);
+ src, i < nsrc, i);
rw_assert (0 == memcmp (cdst, src, i) && '\0' == cdst [i],
0, __LINE__,
@@ -638,7 +638,7 @@
rw_assert (cdst == ret, 0, __LINE__,
"rw_narrow(char*, %{#s}%{?}, %zu%{;})",
- src, i < nsrc);
+ src, i < nsrc, i);
rw_assert (0 == memcmp (cdst, src, i) && '\0' == cdst [i],
0, __LINE__,
Modified: incubator/stdcxx/branches/4.2.0/tests/self/0.new.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/branches/4.2.0/tests/self/0.new.cpp?rev=580483&r1=580482&r2=580483&view=diff
==============================================================================
--- incubator/stdcxx/branches/4.2.0/tests/self/0.new.cpp (original)
+++ incubator/stdcxx/branches/4.2.0/tests/self/0.new.cpp Fri Sep 28 13:55:52 2007
@@ -467,13 +467,14 @@
int run_test (int, char**)
{
-#define TEST(name) \
+#ifndef _RWSTD_NO_REPLACEABLE_NEW_DELETE
+
+# define TEST(name) \
if (rw_opt_no_ ## name) \
rw_note (0, 0, __LINE__, "%s test disabled", #name); \
-else \
+ else \
test_ ## name ()
-
TEST (bad_alloc);
TEST (mismatch);
TEST (double_delete);
@@ -482,11 +483,22 @@
TEST (leaks);
TEST (stress);
+#else // _RWSTD_NO_REPLACEABLE_NEW_DELETE
+
+ rw_note (0, 0, __LINE__, "Test disabled");
+
+#endif // _RWSTD_NO_REPLACEABLE_NEW_DELETE
+
return 0;
}
/**************************************************************************/
-
+/*
+void* operator new (size_t n) throw (std::bad_alloc)
+{
+ return 0;
+}
+*/
int main (int argc, char** argv)
{
return rw_test (argc, argv, __FILE__,
Modified: incubator/stdcxx/branches/4.2.0/tests/self/0.printf.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/branches/4.2.0/tests/self/0.printf.cpp?rev=580483&r1=580482&r2=580483&view=diff
==============================================================================
--- incubator/stdcxx/branches/4.2.0/tests/self/0.printf.cpp (original)
+++ incubator/stdcxx/branches/4.2.0/tests/self/0.printf.cpp Fri Sep 28 13:55:52 2007
@@ -22,10 +22,14 @@
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*
- * Copyright 2005-2006 Rogue Wave Software.
+ * Copyright 2005-2007 Rogue Wave Software, Inc.
*
**************************************************************************/
+// tell Compaq C++ we need ENOMEM (defined by POSIX
+// but not in the compiler's pure C++ libc headers)
+#undef __PURE_CNAME
+
#include <rw_printf.h>
#include <rw_process.h> // for rw_pid_t
#include <environ.h> // for rw_putenv()
@@ -126,9 +130,9 @@
sprintf (fmt, "%s%c", pfx, spec); \
char* const s0 = rw_sprintfa (fmt, a1, a2, a3); \
char buf [256]; \
- /* variable below avoids warnings about controlling */ \
- /* expression being constant */ \
- const char* const expect_var = (expect); \
+ /* non-const variable below avoids warnings about */ \
+ /* controlling expression being constant */ \
+ const char* /* const */ expect_var = (expect); \
if (expect_var) \
strcpy (buf, expect_var ? expect_var : ""); \
else \
@@ -763,7 +767,7 @@
TEST ("%{#1S}", S ("a\0\0"), 0, 0, "\"a\\0\\0\"");
TEST ("%{#1S}", S ("\0\0\0"), 0, 0, "\"\\0\\0\\0\"");
-#if 2 == _RWSTD_WCHAR_T_SIZE
+#if 2 == _RWSTD_WCHAR_SIZE
TEST ("%{#2S}", 0, 0, 0, "(null)");
TEST ("%{#2S}", WS (""), 0, 0, "L\"\"");
@@ -777,7 +781,7 @@
TEST ("%{#2S}", WS ("a\0\0"), 0, 0, "L\"a\\0\\0\"");
TEST ("%{#2S}", WS ("\0\0\0"), 0, 0, "L\"\\0\\0\\0\"");
-#elif 4 == _RWSTD_WCHAR_T_SIZE
+#elif 4 == _RWSTD_WCHAR_SIZE
TEST ("%{#4S}", 0, 0, 0, "(null)");
TEST ("%{#4S}", WS (""), 0, 0, "L\"\"");
@@ -791,7 +795,7 @@
TEST ("%{#4S}", WS ("a\0\0"), 0, 0, "L\"a\\0\\0\"");
TEST ("%{#4S}", WS ("\0\0\0"), 0, 0, "L\"\\0\\0\\0\"");
-#endif // _RWSTD_WCHAR_T_SIZE
+#endif // _RWSTD_WCHAR_SIZE
}
@@ -2256,6 +2260,12 @@
printf ("%s\n", "extension: \"%{#m}\": errno");
int count = 0;
+
+ errno = 0;
+ TEST ("%{#m}", 0, 0, 0, "E#0");
+
+ errno = 0;
+ TEST ("%{#*m}", 0, 0, 0, "E#0");
#ifdef EDOM
Modified: incubator/stdcxx/branches/4.2.0/tests/self/0.process.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/branches/4.2.0/tests/self/0.process.cpp?rev=580483&r1=580482&r2=580483&view=diff
==============================================================================
--- incubator/stdcxx/branches/4.2.0/tests/self/0.process.cpp (original)
+++ incubator/stdcxx/branches/4.2.0/tests/self/0.process.cpp Fri Sep 28 13:55:52 2007
@@ -25,8 +25,11 @@
*
**************************************************************************/
+// tell Compaq C++ we need POSIX errno constants that are otherwise
+// guarded (not defined) in the compiler's pure C++ libc headers
+#undef __PURE_CNAME
+#include <errno.h> // for ENOENT, ECHILD, ESRCH, errno
#include <string.h> // for strcmp()
-#include <errno.h> // for errno
#include <rw_process.h> // for rw_process_create(), rw_waitpid()
#include <driver.h> // for rw_test()
Modified: incubator/stdcxx/branches/4.2.0/tests/src/char.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/branches/4.2.0/tests/src/char.cpp?rev=580483&r1=580482&r2=580483&view=diff
==============================================================================
--- incubator/stdcxx/branches/4.2.0/tests/src/char.cpp (original)
+++ incubator/stdcxx/branches/4.2.0/tests/src/char.cpp Fri Sep 28 13:55:52 2007
@@ -501,7 +501,7 @@
{
// compute the length of src if not specified
if (_RWSTD_SIZE_MAX == len)
- len = src ? strlen (src) + 1 : 0;
+ len = src ? strlen (src) : 0;
if (len) {
RW_ASSERT (0 != dst);
@@ -851,7 +851,7 @@
{
// compute the length of src if not specified
if (_RWSTD_SIZE_MAX == len)
- len = src ? strlen (src) + 1 : 0;
+ len = src ? strlen (src) : 0;
// if len is non-zero dst must be non-0 as well
RW_ASSERT (0 == len || 0 != dst);
@@ -999,7 +999,7 @@
{
// compute the length of src if not specified
if (_RWSTD_SIZE_MAX == len)
- len = src ? strlen (src) + 1 : 0;
+ len = src ? strlen (src) : 0;
// if len is non-zero dst must be non-0 as well
RW_ASSERT (0 == len || 0 != dst);
@@ -1287,7 +1287,7 @@
nbytes = rw_asnprintf (pbuf, pbufsize, "%{+}%{#*s}", nelems, beg.pc);
}
- else if (_RWSTD_WCHAR_T_SIZE == elemsize) {
+ else if (_RWSTD_WCHAR_SIZE == elemsize) {
if (nelems < 0)
nbytes = rw_asnprintf (pbuf, pbufsize, "%{+}%{#ls}", beg.pwc);
else
Modified: incubator/stdcxx/branches/4.2.0/tests/src/ctype.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/branches/4.2.0/tests/src/ctype.cpp?rev=580483&r1=580482&r2=580483&view=diff
==============================================================================
--- incubator/stdcxx/branches/4.2.0/tests/src/ctype.cpp (original)
+++ incubator/stdcxx/branches/4.2.0/tests/src/ctype.cpp Fri Sep 28 13:55:52 2007
@@ -829,9 +829,11 @@
break;
}
}
+
+ return dfault;
}
- return dfault;
+ return ch;
}
@@ -1235,9 +1237,11 @@
break;
}
}
+
+ return dfault;
}
- return dfault;
+ return char (uch);
}
@@ -1646,9 +1650,11 @@
break;
}
}
+
+ return dfault;
}
- return dfault;
+ return char (uch);
}
Modified: incubator/stdcxx/branches/4.2.0/tests/src/driver.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/branches/4.2.0/tests/src/driver.cpp?rev=580483&r1=580482&r2=580483&view=diff
==============================================================================
--- incubator/stdcxx/branches/4.2.0/tests/src/driver.cpp (original)
+++ incubator/stdcxx/branches/4.2.0/tests/src/driver.cpp Fri Sep 28 13:55:52 2007
@@ -182,6 +182,12 @@
#ifndef RW_TEST_HARDWARE
# if defined (__alpha__) || defined (__alpha)
# define RW_TEST_ARCH "alpha"
+# elif defined (__x86_64__) || defined (__x86_64)
+# if defined (__LP64__) || defined (_LP64)
+# define RW_TEST_ARCH "x86_64/LP64"
+# else
+# define RW_TEST_ARCH "x86_64/ILP32"
+# endif
# elif defined (__amd64__) || defined (__amd64)
# if defined (__LP64__) || defined (_LP64)
# define RW_TEST_ARCH "amd64/LP64"
@@ -240,12 +246,6 @@
# define RW_TEST_ARCH "ia64"
# elif defined (_WIN32)
# define RW_TEST_ARCH "i86"
-# elif defined (__x86_64__) || defined (__x86_64)
-# if defined (__LP64__) || defined (_LP64)
-# define RW_TEST_ARCH "x86_64/LP64"
-# else
-# define RW_TEST_ARCH "x86_64/ILP32"
-# endif
# else
# define RW_TEST_ARCH "unknown"
# endif
@@ -276,23 +276,15 @@
# elif defined (__sgi) && defined (__mips)
# define RW_TEST_OS "irix"
# elif defined (__linux__) || defined (__linux)
-
- // get Linux release string (UTS_RELEASE)
-# include <linux/version.h>
-
-# ifndef UTS_RELEASE
-# define UTS_RELEASE "(unknown release)"
-# endif // UTS_RELEASE
-
# if defined (__ELF__)
# define LINUX_TYPE "linux-elf"
# else
# define LINUX_TYPE "linux"
# endif
-# define RW_TEST_OS LINUX_TYPE " " \
- UTS_RELEASE " with glibc " \
- RW_TEST_STR (__GLIBC__) "." \
+# define RW_TEST_OS LINUX_TYPE " (" \
+ _RWSTD_LINUX_RELEASE ") with glibc " \
+ RW_TEST_STR (__GLIBC__) "." \
RW_TEST_STR (__GLIBC_MINOR__)
# elif defined (__SunOS_5_10)
Modified: incubator/stdcxx/branches/4.2.0/tests/src/fmt_bits.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/branches/4.2.0/tests/src/fmt_bits.cpp?rev=580483&r1=580482&r2=580483&view=diff
==============================================================================
--- incubator/stdcxx/branches/4.2.0/tests/src/fmt_bits.cpp (original)
+++ incubator/stdcxx/branches/4.2.0/tests/src/fmt_bits.cpp Fri Sep 28 13:55:52 2007
@@ -48,6 +48,10 @@
# include <wctype.h> // for iswalpha(), ...
#endif // _RWSTD_NO_WCTYPE_H
+#ifdef _WIN32
+# include <windows.h> // for FormatMessage()
+#endif // _WIN32
+
#include <ios>
#include <iostream>
#include <locale>
@@ -1000,6 +1004,42 @@
newspec.fl_pound = 0;
return _rw_fmtstr (newspec, buf, str, _RWSTD_SIZE_MAX);
+}
+
+/********************************************************************/
+
+/* extern */ int
+_rw_fmtlasterror (const FmtSpec &spec, Buffer &buf, int val)
+{
+#ifdef _WIN32
+
+ LPVOID pmsg;
+ FormatMessage ( FORMAT_MESSAGE_ALLOCATE_BUFFER
+ | FORMAT_MESSAGE_FROM_SYSTEM
+ | FORMAT_MESSAGE_IGNORE_INSERTS,
+ 0, (DWORD)val,
+ MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR)&pmsg,
+ 0, 0);
+
+ FmtSpec newspec (spec);
+ newspec.width = 0;
+ newspec.fl_pound = 0;
+
+ const int result = _rw_fmtstr (newspec, buf,
+ _RWSTD_STATIC_CAST (const char*, pmsg),
+ _RWSTD_SIZE_MAX);
+
+ LocalFree (pmsg);
+
+ return result;
+
+#else // if !defined (_WIN32)
+
+ return _rw_fmterrno (spec, buf, val);
+
+#endif // _WIN32
+
}
/********************************************************************/
Modified: incubator/stdcxx/branches/4.2.0/tests/src/fmt_defs.h
URL: http://svn.apache.org/viewvc/incubator/stdcxx/branches/4.2.0/tests/src/fmt_defs.h?rev=580483&r1=580482&r2=580483&view=diff
==============================================================================
--- incubator/stdcxx/branches/4.2.0/tests/src/fmt_defs.h (original)
+++ incubator/stdcxx/branches/4.2.0/tests/src/fmt_defs.h Fri Sep 28 13:55:52 2007
@@ -186,6 +186,10 @@
extern int
_rw_fmterrno (const FmtSpec&, Buffer&, int);
+// format Windows GetLastError(), or errno value/name
+extern int
+_rw_fmtlasterror (const FmtSpec&, Buffer&, int);
+
// format the name/value of an LC_XXX constant/environment variable
extern int
_rw_fmtlc (const FmtSpec&, Buffer&, int);
Modified: incubator/stdcxx/branches/4.2.0/tests/src/locale.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/branches/4.2.0/tests/src/locale.cpp?rev=580483&r1=580482&r2=580483&view=diff
==============================================================================
--- incubator/stdcxx/branches/4.2.0/tests/src/locale.cpp (original)
+++ incubator/stdcxx/branches/4.2.0/tests/src/locale.cpp Fri Sep 28 13:55:52 2007
@@ -22,7 +22,7 @@
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*
- * Copyright 2001-2006 Rogue Wave Software.
+ * Copyright 2001-2007 Rogue Wave Software.
*
**************************************************************************/
@@ -34,10 +34,8 @@
#include <environ.h> // for rw_putenv()
#include <file.h> // for SHELL_RM_RF, rw_tmpnam
-#include <rw_printf.h> // for rw_fprintf()
#include <rw_process.h> // for rw_system()
-#include <cstdio>
-
+#include <driver.h> // for rw_error()
#if defined (_RWSTD_OS_LINUX) && !defined (_XOPEN_SOURCE)
// on Linux define _XOPEN_SOURCE to get CODESET defined in <langinfo.h>
@@ -62,9 +60,7 @@
#include <locale> // for money_base::pattern
#include <assert.h> // for assert
-#include <errno.h> // for EBADF
-#include <float.h> // for {FLT,DBL,LDBL}_DIG
-#include <limits.h> // for CHAR_BIT, MB_LEN_MAX, PATH_MAX
+#include <limits.h> // for PATH_MAX
#include <locale.h> // for LC_XXX macros, setlocale
#include <stdarg.h> // for va_copy, va_list, ...
#include <stdio.h> // for fgets, remove, sprintf, ...
@@ -73,10 +69,6 @@
#include <ctype.h>
#include <wchar.h> // for wcslen, ...
-#ifndef PATH_MAX
-# define PATH_MAX 1024
-#endif
-
#ifndef _MSC_VER
# include <clocale>
# ifndef LC_MESSAGES
@@ -89,6 +81,13 @@
#endif // _MSC_VER
+#if !defined (PATH_MAX) || PATH_MAX < 128 || 4096 < PATH_MAX
+ // deal with undefined, bogus, or excessive values
+# undef PATH_MAX
+# define PATH_MAX 1024
+#endif
+
+
#define TOPDIR "TOPDIR" /* the TOPDIR environment variable */
#define BINDIR "BINDIR" /* the BINDIR environment variable */
@@ -109,13 +108,20 @@
#define RELPATH "etc" SLASH "nls"
#define TESTS_ETC_PATH "tests" SLASH "etc"
+// extension of the catalog file
+#ifndef _WIN32
+# define RW_CAT_EXT ".cat"
+#else
+# define RW_CAT_EXT ".dll"
+#endif
+
/**************************************************************************/
_TEST_EXPORT int
rw_locale (const char *args, const char *fname)
{
// use BINDIR to determine the location of the locale command
- const char* bindir = getenv ("BINDIR");
+ const char* bindir = getenv (BINDIR);
if (!bindir)
bindir = ".." SLASH "bin";
@@ -202,13 +208,14 @@
// use TOPDIR to determine the root of the source tree
const char* const topdir = getenv (TOPDIR);
if (!topdir || !*topdir) {
- fprintf (stderr, "%s:%d: the environment variable %s is %s\n",
- __FILE__, __LINE__, TOPDIR, topdir ? "empty" : "undefined");
+ rw_error (0, __FILE__, __LINE__,
+ "the environment variable %s is %s",
+ TOPDIR, topdir ? "empty" : "undefined");
return 0;
}
// use BINDIR to determine the location of the localedef command
- const char* bindir = getenv ("BINDIR");
+ const char* bindir = getenv (BINDIR);
if (!bindir)
bindir = ".." SLASH "bin";
@@ -272,7 +279,7 @@
extern "C" {
-static char rw_locale_root [256];
+static char rw_locale_root [PATH_MAX];
static void atexit_rm_locale_root ()
{
@@ -318,8 +325,8 @@
// where std::locale looks for locale database files
rw_putenv (envvar);
- if (atexit (atexit_rm_locale_root))
- perror ("atexit(atexit_rm_locale_root) failed");
+ rw_error (0 == atexit (atexit_rm_locale_root), __FILE__, __LINE__,
+ "atexit(atexit_rm_locale_root) failed: %m");
return locale_root;
}
@@ -327,8 +334,9 @@
/**************************************************************************/
_TEST_EXPORT char*
-rw_locales (int loc_cat, const char* grep_exp)
+rw_locales (int loc_cat, const char* grep_exp, bool prepend_c_loc)
{
+ static char deflocname [3] = "C\0";
static char* slocname = 0;
static size_t size = 0; // the number of elements in the array
@@ -360,7 +368,7 @@
char* locname = slocname;
char* save_localename = 0;
- char namebuf [256];
+ char namebuf [PATH_MAX];
if (loc_cat != _UNUSED_CAT) {
// copy the locale name, the original may be overwitten by libc
@@ -370,7 +378,7 @@
const char* const fname = rw_tmpnam (0);
if (!fname) {
- return 0; // error
+ return deflocname; // error
}
// make sure that grep_exp is <= 80
@@ -385,7 +393,7 @@
: rw_system ("locale -a > %s", fname);
if (exit_status) {
- return 0; // error
+ return deflocname; // error
}
// open file containing the list of installed locales
@@ -401,15 +409,33 @@
char last_name [256];
*last_name = '\0';
+ // put the C locale at the front
+ if (prepend_c_loc) {
+ strcpy (locname, deflocname);
+ locname += strlen (deflocname) + 1;
+ }
+
// if successful, construct a char array with the locales
while (fgets (linebuf, sizeof linebuf, file)) {
- linebuf [strlen (linebuf) - 1] = '\0';
+ const size_t linelen = strlen (linebuf);
+
+ linebuf [linelen ? linelen - 1 : 0] = '\0';
+
+ // don't allow C locale to be in the list again
+ // if we put it at the front of the locale list
+ if (prepend_c_loc && !strcmp (linebuf, deflocname))
+ continue;
#ifdef _RWSTD_OS_SUNOS
- // avoid the bad locale named iso_8859_1 on SunOS
- if (!strcmp ("iso_8859_1", linebuf))
+ const char iso_8859_pfx[] = "iso_8859_";
+
+ // avoid locales named common and iso_8859_* on SunOS
+ // since they are known to cause setlocale() to fail
+ if ( !strcmp ("common", linebuf)
+ || sizeof iso_8859_pfx <= linelen
+ && !memcmp (iso_8859_pfx, linebuf, sizeof iso_8859_pfx - 1))
continue;
#endif // _RWSTD_OS_SUNOS
@@ -422,7 +448,12 @@
_RWSTD_STATIC_CAST (char*, malloc (total_size));
memcpy (tmp, slocname, total_size - 5120);
+
+#ifndef _MSC_VER
free (slocname);
+#else
+ _free_dbg (slocname, _CLIENT_BLOCK);
+#endif
slocname = tmp;
locname = slocname + size - strlen (linebuf) - 1;
@@ -470,7 +501,7 @@
remove (fname);
- return slocname;
+ return *slocname ? slocname : deflocname;
}
/**************************************************************************/
@@ -508,7 +539,7 @@
*buf = '\0';
}
-#if 2 < _RWSTD_WCHAR_T_SIZE
+#if 2 < _RWSTD_WCHAR_SIZE
// if a multibyte character of the requested size is not found
// in the low 64K range, try to find one using a random search
@@ -551,12 +582,11 @@
const char* mbc = _get_mb_char (mb_chars [0], size_t (-1));
- if (!mbc) {
- rw_fprintf (rw_stderr, "*** failed to find any multibyte characters "
- "in locale \"%s\" with MB_CUR_MAX = %u\n",
- setlocale (LC_CTYPE, 0), MB_CUR_MAX);
+ if (0 == rw_note (0 != mbc, __FILE__, __LINE__,
+ "failed to find any multibyte characters "
+ "in locale \"%s\" with MB_CUR_MAX = %u",
+ setlocale (LC_CTYPE, 0), MB_CUR_MAX))
return 0;
- }
size_t mb_cur_max = strlen (mbc);
@@ -571,10 +601,13 @@
mbc = _get_mb_char (mb_chars [i - 1], i);
if (0 == mbc) {
- if (i < mb_cur_max) {
- rw_fprintf (rw_stderr, "*** failed to find %u-byte characters "
- "in locale \"%s\" with MB_CUR_MAX = %u\n",
- i + 1, setlocale (LC_CTYPE, 0), MB_CUR_MAX);
+ // zh_CN.gb18030 and zh_TW.euctw on Linux are examples
+ // of multibyte locales where MB_CUR_MAX == 4 but,
+ // apparently, no 3-byte characters
+ if (0 == rw_note (mb_cur_max <= i, __FILE__, __LINE__,
+ "failed to find %u-byte characters "
+ "in locale \"%s\" with MB_CUR_MAX = %u",
+ i, setlocale (LC_CTYPE, 0), MB_CUR_MAX)) {
mb_cur_max = 0;
break;
}
@@ -586,6 +619,67 @@
}
+_TEST_EXPORT size_t
+rw_get_wchars (wchar_t *wbuf, size_t bufsize, int nbytes /* = 0 */)
+{
+ if (0 == bufsize)
+ return 0;
+
+ char tmp [_RWSTD_MB_LEN_MAX];
+
+ size_t nchars = 0;
+
+ for (int i = 0; i != 65536; ++i) {
+
+ // determine whether the wide character is valid
+ // and if so, the length of the multibyte character
+ // that corresponds to it
+ const int len = wctomb (tmp, wchar_t (i));
+
+ if (nbytes == 0 && 0 < len || nbytes != 0 && nbytes == len) {
+ // if the requested length is 0 (i.e., the caller doesn't
+ // care) and the character is valid, store it
+ // if the requested length is non-zero (including -1),
+ // and the value returned from mblen() is the same, store
+ // it (this makes it possible to find invalid characters
+ // as well as valid ones)
+ wbuf [nchars++];
+ if (nchars == bufsize)
+ return nchars;
+ }
+ }
+
+#if 2 < _RWSTD_WCHAR_SIZE
+
+ // try to find the remaining wide characters by a random
+ // search, iterating only so many times to prevent an
+ // infinite loop
+ for (int i = 0; i != 0x100000; ++i) {
+
+ // make a wide character with a random bit pattern
+ wchar_t wc = wchar_t (rand ());
+
+ if (RAND_MAX < 0x10000) {
+ wc <<= 16;
+ wc |= wchar_t (rand ());
+ }
+
+ const int len = wctomb (tmp, wchar_t (i));
+
+ if (nbytes == 0 && 0 < len || nbytes != 0 && nbytes == len) {
+ wbuf [nchars++];
+ if (nchars == bufsize)
+ return nchars;
+ }
+ }
+
+#endif // 2 < _RWSTD_WCHAR_SIZE
+
+ return nchars;
+
+}
+
+
_TEST_EXPORT const char*
rw_find_mb_locale (size_t *mb_cur_max,
rw_mbchar_array_t mb_chars)
@@ -594,8 +688,8 @@
_RWSTD_ASSERT (0 != mb_chars);
if (2 > _RWSTD_MB_LEN_MAX) {
- rw_fprintf (rw_stderr, "MB_LEN_MAX = %d, giving up\n",
- _RWSTD_MB_LEN_MAX);
+ rw_warn (0, __FILE__, __LINE__, "MB_LEN_MAX = %d, giving up",
+ _RWSTD_MB_LEN_MAX);
return 0;
}
@@ -631,9 +725,10 @@
}
if (*mb_cur_max < 2) {
- rw_fprintf (rw_stderr, "*** failed to find a full set of multibyte "
- "characters in locale \"%s\" with MB_CUR_MAX = %u "
- "(computed)", mb_locale_name, *mb_cur_max);
+ rw_warn (0, __FILE__, __LINE__,
+ "failed to find a full set of multibyte "
+ "characters in locale \"%s\" with MB_CUR_MAX = %u "
+ "(computed)", mb_locale_name, *mb_cur_max);
mb_locale_name = 0;
}
else {
@@ -671,36 +766,36 @@
// create a temporary locale definition file that exercises as
// many different parts of the collate standard as possible
- char srcfname [256];
- std::sprintf (srcfname, "%s%slocale.src", locale_root, SLASH);
+ char srcfname [PATH_MAX];
+ sprintf (srcfname, "%s%slocale.src", locale_root, SLASH);
- std::FILE *fout = std::fopen (srcfname, "w");
+ FILE *fout = fopen (srcfname, "w");
if (!fout) {
- std::fprintf (stderr, "%s:%d: fopen(\"%s\", \"w\") failed\n",
- __FILE__, __LINE__, srcfname);
+ rw_error (0, __FILE__, __LINE__,
+ "fopen(#%s, \"w\") failed: %m", srcfname);
return 0;
}
- std::fprintf (fout, "%s", locale);
+ fprintf (fout, "%s", locale);
- std::fclose (fout);
+ fclose (fout);
// create a temporary character map file
- char cmfname [256];
- std::sprintf (cmfname, "%s%scharmap.src", locale_root, SLASH);
+ char cmfname [PATH_MAX];
+ sprintf (cmfname, "%s%scharmap.src", locale_root, SLASH);
- fout = std::fopen (cmfname, "w");
+ fout = fopen (cmfname, "w");
if (!fout) {
- std::fprintf (stderr, "%s:%d: fopen(\"%s\", \"w\") failed\n",
- __FILE__, __LINE__, cmfname);
+ rw_error (0, __FILE__, __LINE__,
+ "fopen(%#s, \"w\") failed: %m", cmfname);
return 0;
}
- std::fprintf (fout, "%s", charmap);
+ fprintf (fout, "%s", charmap);
- std::fclose (fout);
+ fclose (fout);
locname = "test-locale";
@@ -709,4 +804,116 @@
locname = 0;
return locname;
+}
+
+
+/**************************************************************************/
+
+static const char*
+_rw_locale_names;
+
+_TEST_EXPORT const char* const&
+rw_opt_locales = _rw_locale_names;
+
+
+_TEST_EXPORT int
+rw_opt_setlocales (int argc, char* argv[])
+{
+ if (1 == argc && argv && 0 == argv [0]) {
+ static const char helpstr[] = {
+ "Use the locales specified by the space-parated list of locale"
+ "names given by <arg>.\n"
+ };
+
+ argv [0] = _RWSTD_CONST_CAST (char*, helpstr);
+
+ return 0;
+ }
+
+ // the option requires an equals sign followed by an optional argument
+ char *args = strchr (argv [0], '=');
+
+ RW_ASSERT (0 != args);
+
+ // small static buffer should be sufficient in most cases
+ static char buffer [256];
+
+ const size_t len = strlen (++args);
+
+ // dynamically allocate a bigger buffer when the small buffer
+ // isn't big enough (let the dynamically allocated buffer leak)
+ char* const locale_names =
+ sizeof buffer < len + 2 ? (char*)malloc (len + 2) : buffer;
+
+ if (0 == locale_names)
+ return 1;
+
+ locale_names [len] = '\0';
+ locale_names [len + 1] = '\0';
+
+ memcpy (locale_names, args, len);
+
+ for (char *next = locale_names; ; ) {
+ next = strpbrk (next, ", ");
+ if (next)
+ *next++ = '\0';
+ else
+ break;
+ }
+
+ _rw_locale_names = locale_names;
+
+ // return 0 on success
+ return 0;
+}
+
+
+/**************************************************************************/
+
+_TEST_EXPORT int
+rw_create_catalog (const char * catname, const char * catalog)
+{
+ RW_ASSERT (catname && catalog);
+
+ FILE* const f = fopen (catname, "w");
+
+ if (!f)
+ return -1;
+
+#ifndef _WIN32
+
+ for (int i = 1; *catalog; ++catalog, ++i) {
+ fprintf (f, "$set %d This is Set %d\n", i, i);
+ for (int j = 1; *catalog; catalog += strlen (catalog) + 1, ++j)
+ fprintf (f, "%d %s\n", j, catalog);
+ }
+
+#else // if defined (_WIN32)
+
+ fprintf (f, "STRINGTABLE\nBEGIN\n");
+
+ for (int i = 1; *catalog; ++catalog) {
+ for (; *catalog; catalog += strlen (catalog) + 1, ++i)
+ fprintf (f, "%d \"%s\"\n", i, catalog);
+ }
+
+ fprintf (f, "END\n");
+
+#endif // _WIN32
+
+ fclose (f);
+
+ char *cat_name = new char [strlen (catname) + 1];
+ strcpy (cat_name, catname);
+ if (char *dot = strrchr (cat_name, '.'))
+ *dot = '\0';
+
+ const int ret = rw_system ("gencat %s" RW_CAT_EXT " %s",
+ cat_name, catname);
+
+ delete[] cat_name;
+
+ remove (catname);
+
+ return ret;
}
Modified: incubator/stdcxx/branches/4.2.0/tests/src/printf.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/branches/4.2.0/tests/src/printf.cpp?rev=580483&r1=580482&r2=580483&view=diff
==============================================================================
--- incubator/stdcxx/branches/4.2.0/tests/src/printf.cpp (original)
+++ incubator/stdcxx/branches/4.2.0/tests/src/printf.cpp Fri Sep 28 13:55:52 2007
@@ -57,7 +57,7 @@
// define macros to enable Win98 + WinNT support in <windows.h>
# define _WIN32_WINNT 0x0410
# define WINVER 0x400
-# include <windows.h> // for IsDebuggerPresent()
+# include <windows.h> // for GetLastError(), IsDebuggerPresent()
#else
# include <dlfcn.h>
#endif // _WIN{32,64}
@@ -1843,25 +1843,25 @@
template <class charT>
int _rw_quotechar (char *buf, charT wc, int noesc)
{
-#if _RWSTD_WCHAR_T_MIN < 0
+#if _RWSTD_WCHAR_MIN < 0
// wchar_t is signed, convert its value to unsigned long
// without widening (i.e., treat it as an unsigned type)
-# if _RWSTD_WCHAR_T_MIN == _RWSTD_SHRT_MIN
+# if _RWSTD_WCHAR_MIN == _RWSTD_SHRT_MIN
const ULong wi = UShrt (wc);
-# elif _RWSTD_WCHAR_T_MIN ==_RWSTD_INT_MIN
+# elif _RWSTD_WCHAR_MIN ==_RWSTD_INT_MIN
const ULong wi = UInt (wc);
-# elif _RWSTD_WCHAR_T_MIN == _RWSTD_LONG_MIN
+# elif _RWSTD_WCHAR_MIN == _RWSTD_LONG_MIN
const ULong wi = ULong (wc);
# endif
-#else // if _RWSTD_WCHAR_T_MIN >= 0
+#else // if _RWSTD_WCHAR_MIN >= 0
// wchar_t is unsigned
const ULong wi = ULong (wc);
-#endif // _RWSTD_WCHAR_T_MIN < 0
+#endif // _RWSTD_WCHAR_MIN < 0
if ((1 == sizeof wc || wi < 0x100) && noesc) {
buf [0] = char (wc);
@@ -1978,7 +1978,7 @@
// wchar_t (bot not for an array of wchar_t's being
// formatted using the {%ls} directive -- the caller
// can easily stick the 'L' there themselves)
- if (flags & A_ARRAY && _RWSTD_WCHAR_T_SIZE == sizeof (elemT))
+ if (flags & A_ARRAY && _RWSTD_WCHAR_SIZE == sizeof (elemT))
*next++ = 'L';
*next++ = '"';
@@ -2067,7 +2067,7 @@
if (last_repeat < 0) {
if (flags & (A_CHAR | A_WCHAR)) {
if ( (flags & A_ARRAY)
- && _RWSTD_WCHAR_T_SIZE == sizeof (elemT))
+ && _RWSTD_WCHAR_SIZE == sizeof (elemT))
*s++ = 'L';
// insert an opening quote
@@ -2694,6 +2694,15 @@
}
break;
+ case 'E': // %{E} -- Windows GetLastError(), errno elsewhere
+#ifdef _WIN32
+ spec.param.int_ = -1 == spec.width ? GetLastError () : spec.width;
+#else // if !defined (_WIN32)
+ spec.param.int_ = -1 == spec.width ? errno : spec.width;
+#endif // _WIN32
+ len = _rw_fmtlasterror (spec, buf, spec.param.int_);
+ break;
+
case 'e': // %{e}, %{Ae}
if (spec.mod == spec.mod_ext_A) { // array of floating point values
spec.param.ptr_ = PARAM (ptr_, pva);
@@ -2771,7 +2780,8 @@
break;
case 'm': // %{m} -- errno
- len = _rw_fmterrno (spec, buf, -1 == spec.width ? errno : spec.width);
+ spec.param.int_ = -1 == spec.width ? errno : spec.width;
+ len = _rw_fmterrno (spec, buf, spec.param.int_);
break;
case 'M': // %{M}, %{LM}
@@ -3329,7 +3339,7 @@
va_end (va);
if (-1 < nchars)
- memcpy (buf, tmpbuf, size_t (nchars));
+ memcpy (buf, tmpbuf, size_t (nchars + 1 /* NUL */));
free (tmpbuf);
Modified: incubator/stdcxx/branches/4.2.0/tests/src/process.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/branches/4.2.0/tests/src/process.cpp?rev=580483&r1=580482&r2=580483&view=diff
==============================================================================
--- incubator/stdcxx/branches/4.2.0/tests/src/process.cpp (original)
+++ incubator/stdcxx/branches/4.2.0/tests/src/process.cpp Fri Sep 28 13:55:52 2007
@@ -27,10 +27,6 @@
// expand _TEST_EXPORT macros
#define _RWSTD_TEST_SRC
-// disable Compaq/HP C++ pure libc headers to allow POSIX symbols
-// such as E2BIG to be defined
-#undef __PURE_CNAME
-
#include <rw_process.h>
#include <ctype.h> // for isspace()
Modified: incubator/stdcxx/branches/4.2.0/tests/src/thread.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/branches/4.2.0/tests/src/thread.cpp?rev=580483&r1=580482&r2=580483&view=diff
==============================================================================
--- incubator/stdcxx/branches/4.2.0/tests/src/thread.cpp (original)
+++ incubator/stdcxx/branches/4.2.0/tests/src/thread.cpp Fri Sep 28 13:55:52 2007
@@ -33,6 +33,13 @@
#include <stddef.h> // for size_t
#include <string.h> // for memset()
+#ifndef _WIN32
+# include <stdio.h> // for FILE, fscanf(), popen()
+# include <unistd.h> // for sysconf(), _SC_NPROCESSORS_{CONF,ONLN}
+#else
+# include <windows.h> // for GetSystemInfo()
+#endif // _WIN32
+
/**************************************************************************/
static long maxthreads;
@@ -167,13 +174,6 @@
extern "C" {
-# ifdef __PURE_CNAME
-
-extern int sigsetjmp (jmp_buf, int);
-
-# endif
-
-
_TEST_EXPORT int
rw_thread_create (rw_thread_t *thr_id,
rw_thread_attr_t*,
@@ -240,8 +240,8 @@
/**************************************************************************/
-#elif defined (_WIN32) || defined (_WIN64)
-# include <windows.h>
+#elif defined (_WIN32) && defined (_MT)
+# include <process.h> // for _beginthreadex()
extern "C" {
@@ -258,34 +258,33 @@
if (0 == thr_id)
thr_id = &tmpid;
- DWORD nid; // numerical id
-
- typedef DWORD ThreadProc (LPVOID);
+ unsigned nid; // numerical id
- LPTHREAD_START_ROUTINE win32_thr_proc =
- _RWSTD_REINTERPRET_CAST (LPTHREAD_START_ROUTINE, thr_proc);
+ typedef unsigned int (__stdcall *win32_thr_proc_t)(void *);
+ win32_thr_proc_t win32_thr_proc =
+ _RWSTD_REINTERPRET_CAST (win32_thr_proc_t, thr_proc);
// set the thread number *before* creating the thread
// so that it's visible in thr_proc when it starts to
// run even before CreateThread returns
thr_id->threadno = maxthreads;
- const HANDLE hthread =
- CreateThread (0, // lpThreadAttributes
- 0, // dwStackSize
- win32_thr_proc, // lpStartAddress
- thr_arg, // lpParameter
- 0, // dwCreationFlags
- &nid); // lpThreadId
+ const uintptr_t hthread =
+ _beginthreadex (0, // lpThreadAttributes
+ 0, // dwStackSize
+ win32_thr_proc, // lpStartAddress
+ thr_arg, // lpParameter
+ 0, // dwCreationFlags
+ &nid); // lpThreadId
- if (INVALID_HANDLE_VALUE == hthread) {
+ if (!hthread) {
thr_id->id = -1;
thr_id->handle = 0;
result = -1;
}
else {
thr_id->id = nid;
- thr_id->handle = hthread;
+ thr_id->handle = _RWSTD_REINTERPRET_CAST (void*, hthread);
++maxthreads;
}
@@ -369,22 +368,132 @@
#endif // threads environment
+/**************************************************************************/
+
+// retrieves the number of processors/cores on the system
+_TEST_EXPORT int
+rw_get_cpus ()
+{
+#ifndef _WIN32
+
+ const char* const cmd = {
+ // shell command(s) to obtain the number of processors
+
+# ifdef _RWSTD_OS_AIX
+ // AIX: /etc/lsdev -Cc processor | wc -l
+ "/etc/lsdev -Cc processor | /usr/bin/wc -l"
+# elif defined (_RWSTD_OS_LINUX)
+ // Linux: cat /proc/cpuinfo | grep processor | wc -l
+ "cat /proc/cpuinfo "
+ " | grep processor "
+ " | wc -l"
+# elif defined (_RWSTD_OS_FREEBSD)
+ // FreeBSD: /sbin/sysctl -n hw.ncpu
+ "/sbin/sysctl -n hw.ncpu"
+# elif defined (_RWSTD_OS_HP_UX)
+ // HP-UX: /etc/ioscan -k -C processor | grep processor | wc -l
+ "/etc/ioscan -k -C processor "
+ " | /usr/bin/grep processor "
+ " | /usr/bin/wc -l"
+# elif defined (_RWSTD_OS_IRIX64)
+ // IRIX: hinv | /usr/bin/grep "^[1-9][0-9]* .* Processor"
+ "/sbin/hinv "
+ " | /usr/bin/grep \"^[1-9][0-9]* .* Processor\""
+# elif defined (_RWSTD_OS_OSF1)
+ // Tru64 UNIX: /usr/sbin/psrinfo | grep online | wc -l
+ "/usr/sbin/psrinfo "
+ " | /usr/bin/grep on[-]*line "
+ " | /usr/bin wc -l"
+# elif defined (_RWSTD_OS_SUNOS)
+ // Solaris: /usr/bin/mpstat | wc -l
+ "/usr/bin/mpstat "
+ " | /usr/bin/grep -v \"^CPU\" "
+ " | /usr/bin/wc -l"
+# else
+ 0
+# endif
+
+ };
+
+ int ncpus = -1;
+
+# ifdef _SC_NPROCESSORS_ONLN
+ // try to obtain the number of processors that are currently online
+ // programmatically and fall back on the shell script above if it
+ // fails
+ ncpus = int (sysconf (_SC_NPROCESSORS_ONLN));
+
+# elif defined (_SC_NPROCESSORS_CONF)
+
+ // try to obtain the number of processors the system is configured
+ // with (not all of them are necessarily online) programmatically
+ // and fall back on the shell script above if it fails
+ ncpus = int (sysconf (_SC_NPROCESSORS_CONF));
+
+# endif // _SC_NPROCESSORS_CONF
+
+ if (ncpus < 1 && cmd) {
+ // if the number of processors couldn't be determined using
+ // sysconf() above, open and read the output of the command
+ // from a pipe
+ FILE* const fp = popen (cmd, "r");
+
+ if (fp) {
+ int tmp = 0;
+
+ int n = fscanf (fp, "%d", &tmp);
+
+ if (1 == n)
+ ncpus = tmp;
+
+ fclose (fp);
+ }
+ }
+
+ return ncpus;
+
+#else // _WIN32
+
+ SYSTEM_INFO info;
+ GetSystemInfo (&info);
+ return int (info.dwNumberOfProcessors);
+
+#endif // _WIN32
+}
+
+/**************************************************************************/
extern "C" {
_TEST_EXPORT int
-rw_thread_pool (rw_thread_t *thr_id, size_t nthrs,
+rw_thread_pool (rw_thread_t *thr_id,
+ size_t nthrs,
rw_thread_attr_t*,
- void* (*thr_proc)(void*),
- void **thr_arg)
+ void* (*thr_proc)(void*),
+ void* *thr_arg)
{
// small buffer for thread ids when invoked with (thr_id == 0)
rw_thread_t id_buf [16];
const bool join = 0 == thr_id;
-#ifndef _RWSTD_REENTRANT
+#ifdef _RWSTD_REENTRANT
+
+ if (_RWSTD_SIZE_MAX == nthrs) {
+ // when the number of threads is -1 use the number
+ // of processors plus 1 (in case it's 1 to begin
+ // with)
+
+ const int ncpus = rw_get_cpus ();
+
+ if (0 < ncpus)
+ nthrs = size_t (ncpus) + 1;
+ else
+ nthrs = 2;
+ }
+
+#else
// when not reentrant/thread safe emulate the creation
// of a single thread and then waiting for it to finish
@@ -408,7 +517,6 @@
return 0;
}
-
#endif // !_RWSTD_REENTRANT
bool delete_ids = false;
Modified: incubator/stdcxx/branches/4.2.0/tests/strings/21.cwchar.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/branches/4.2.0/tests/strings/21.cwchar.cpp?rev=580483&r1=580482&r2=580483&view=diff
==============================================================================
--- incubator/stdcxx/branches/4.2.0/tests/strings/21.cwchar.cpp (original)
+++ incubator/stdcxx/branches/4.2.0/tests/strings/21.cwchar.cpp Fri Sep 28 13:55:52 2007
@@ -87,10 +87,6 @@
/**************************************************************************/
-#ifdef _MSC_VER
-#include <crtdbg.h> // for _CrtSetReportMode()
-#endif
-
#include <cwchar>
#include <any.h> // for rw_any_t
#include <driver.h> // for rw_test(), ...
@@ -822,6 +818,11 @@
GET_TYPE_NAME (unsigned long);
GET_TYPE_NAME (double);
+#ifndef _RWSTD_NO_LONG_LONG
+GET_TYPE_NAME (_RWSTD_LONG_LONG);
+GET_TYPE_NAME (unsigned _RWSTD_LONG_LONG);
+#endif
+
#ifndef _RWSTD_NO_NATIVE_WCHAR_T
GET_TYPE_NAME (wchar_t);
#endif
@@ -926,16 +927,16 @@
const test_tm* tmb = (const test_tm*)&tm_buf;
#ifdef _MSC_VER
- // disable GUI window with error:
- // Assertion failed: ("Zero length output buffer passed to strftime",0)
- int oldmode = _CrtSetReportMode (_CRT_ASSERT, _CRTDBG_MODE_DEBUG);
+ // prevent MSVC parameter validation error:
+ // "Zero length output buffer passed to strftime"
+ size = 1;
#endif
TEST (test_size_t, wcsftime, (wstr, size, L"", tmb), WCSFTIME, -1);
#ifdef _MSC_VER
- // restore error report mode
- _CrtSetReportMode (_CRT_ASSERT, oldmode);
+ // restore size
+ size = 0;
#endif
TEST (test_wint_t, btowc, (i), BTOWC, -1);
Modified: incubator/stdcxx/branches/4.2.0/tests/strings/21.string.access.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/branches/4.2.0/tests/strings/21.string.access.cpp?rev=580483&r1=580482&r2=580483&view=diff
==============================================================================
--- incubator/stdcxx/branches/4.2.0/tests/strings/21.string.access.cpp (original)
+++ incubator/stdcxx/branches/4.2.0/tests/strings/21.string.access.cpp Fri Sep 28 13:55:52 2007
@@ -266,10 +266,12 @@
return;
}
- const char exp_res =
- NPOS != tcase.nres ? char (tcase.nres) : char ();
+ const char exp_res [2] = {
+ NPOS != tcase.nres ? char (tcase.nres) : char (),
+ char ()
+ };
- const bool success = 1 == rw_match (&exp_res, pres, 1);
+ const bool success = 1 == rw_match (exp_res, pres, 1);
rw_assert (success, 0, tcase.line,
"line %d. %{$FUNCALL} == %{#c}, got %{#c}",
Modified: incubator/stdcxx/branches/4.2.0/tests/strings/21.string.cons.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/branches/4.2.0/tests/strings/21.string.cons.cpp?rev=580483&r1=580482&r2=580483&view=diff
==============================================================================
--- incubator/stdcxx/branches/4.2.0/tests/strings/21.string.cons.cpp (original)
+++ incubator/stdcxx/branches/4.2.0/tests/strings/21.string.cons.cpp Fri Sep 28 13:55:52 2007
@@ -699,11 +699,11 @@
break;
case Cons (size_val):
- ret_ptr = new String (tcase.size, arg_val);
+ ret_ptr = new String (arg_size, arg_val);
break;
case Cons (size_val_alloc):
- ret_ptr = new String (tcase.size, arg_val, arg_alc);
+ ret_ptr = new String (arg_size, arg_val, arg_alc);
break;
case Cons (range):
Modified: incubator/stdcxx/branches/4.2.0/tests/strings/21.string.copy.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/branches/4.2.0/tests/strings/21.string.copy.cpp?rev=580483&r1=580482&r2=580483&view=diff
==============================================================================
--- incubator/stdcxx/branches/4.2.0/tests/strings/21.string.copy.cpp (original)
+++ incubator/stdcxx/branches/4.2.0/tests/strings/21.string.copy.cpp Fri Sep 28 13:55:52 2007
@@ -187,11 +187,12 @@
std::size_t res = 0;
// create destination array and initialize it with garbage
- charT* const s_res = new charT [min_len + 1];
+ charT* const s_res = new charT [min_len + 2];
- char cgb = '#';
- charT wcgb = make_char (cgb, (charT*)0);
+ const char cgb [2] = "#";
+ const charT wcgb = make_char (cgb [0], (charT*)0);
Traits::assign (s_res, min_len + 1, wcgb);
+ s_res [min_len + 1] = charT ();
// save the state of the string object before the call
// to detect wxception safety violations (changes to
@@ -247,7 +248,7 @@
__LINE__, int (tcase.nres), tcase.res,
int (sizeof (charT)), int (res), s_res, match);
- success = 1 == rw_match (&cgb, &s_res [min_len], 1);
+ success = 1 == rw_match (cgb, s_res + min_len, 1);
rw_assert (success, 0, tcase.line,
"line %d. %{$FUNCALL} detected writing past the end of "
"the provided buffer", __LINE__);
Modified: incubator/stdcxx/branches/4.2.0/tests/strings/21.string.find.first.not.of.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/branches/4.2.0/tests/strings/21.string.find.first.not.of.cpp?rev=580483&r1=580482&r2=580483&view=diff
==============================================================================
--- incubator/stdcxx/branches/4.2.0/tests/strings/21.string.find.first.not.of.cpp (original)
+++ incubator/stdcxx/branches/4.2.0/tests/strings/21.string.find.first.not.of.cpp Fri Sep 28 13:55:52 2007
@@ -396,14 +396,7 @@
TEST ("abcdefghij", "abc", 10, 3, NPOS, 0),
TEST ("abcdefghij", "cba", 10, 1, NPOS, 0),
-#ifndef _RWSTD_NO_EXCEPTIONS
-
- TEST ("", "cba", 0, -1, 0, 1),
- TEST ("abcdefghij", "cba", 0, -1, 0, 1),
- TEST ("x@4096", "xxx", 0, -1, 0, 1),
- TEST ("abcdefghij", "x@4096", 0, -1, 0, 1),
-
-#endif // _RWSTD_NO_EXCEPTIONS
+ TEST ("", "cba", 0, -1, NPOS, 0),
TEST ("last test", "test", 0, 4, 0, 0)
};
Modified: incubator/stdcxx/branches/4.2.0/tests/strings/21.string.find.first.of.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/branches/4.2.0/tests/strings/21.string.find.first.of.cpp?rev=580483&r1=580482&r2=580483&view=diff
==============================================================================
--- incubator/stdcxx/branches/4.2.0/tests/strings/21.string.find.first.of.cpp (original)
+++ incubator/stdcxx/branches/4.2.0/tests/strings/21.string.find.first.of.cpp Fri Sep 28 13:55:52 2007
@@ -404,10 +404,10 @@
TEST ("abcdefghij", "abc", 10, 3, NPOS, 0),
TEST ("abcdefghij", "cba", 10, 1, NPOS, 0),
- TEST ("", "cba", 0, -1, 0, 1),
- TEST ("abcdefghij", "cba", 0, -1, 0, 1),
- TEST ("x@4096", "xxx", 0, -1, 0, 1),
- TEST ("abcdefghij", "x@4096", 0, -1, 0, 1),
+ TEST ("", "cba", 0, -1, NPOS, 0),
+ TEST ("abcdefghij", "cba", 0, -1, 0, 0),
+ TEST ("x@4096", "xxx", 0, -1, 0, 0),
+ TEST ("abcdefghij", "ax@4096", 0, -1, 0, 0),
TEST ("last test", "test", 0, 4, 2, 0)
};
Modified: incubator/stdcxx/branches/4.2.0/tests/strings/21.string.find.last.not.of.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/branches/4.2.0/tests/strings/21.string.find.last.not.of.cpp?rev=580483&r1=580482&r2=580483&view=diff
==============================================================================
--- incubator/stdcxx/branches/4.2.0/tests/strings/21.string.find.last.not.of.cpp (original)
+++ incubator/stdcxx/branches/4.2.0/tests/strings/21.string.find.last.not.of.cpp Fri Sep 28 13:55:52 2007
@@ -404,10 +404,7 @@
TEST ("defghijabc", "abc", 15, 3, 6, 0),
TEST ("defghijabc", "cba", 15, 1, 8, 0),
- TEST ("", "cba", 0, -1, 0, 1),
- TEST ("abcdefghij", "cba", 0, -1, 0, 1),
- TEST ("x@4096", "xxx", 0, -1, 0, 1),
- TEST ("abcdefghij", "x@4096", 0, -1, 0, 1),
+ TEST ("", "cba", 0, -1, NPOS, 0),
TEST ("last test", "test", 9, 4, 4, 0)
};