stdcxx-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From se...@apache.org
Subject svn commit: r565991 - in /incubator/stdcxx/trunk/tests: include/rw_locale.h include/testdefs.h localization/22.locale.money.put.mt.cpp localization/22.locale.num.put.mt.cpp localization/22.locale.time.put.mt.cpp src/locale.cpp
Date Wed, 15 Aug 2007 00:53:02 GMT
Author: sebor
Date: Tue Aug 14 17:53:01 2007
New Revision: 565991

URL: http://svn.apache.org/viewvc?view=rev&rev=565991
Log:
2007-08-14  Travis Vitek  <vitek@roguewave.com>

	* rw_locale.h (rw_locales): Added new parameter to indicate the
	"C" locale should appear at the front of returned locale list.
	* locale.cpp (rw_locales): Added support for new parameter.
	* testdefs.h: Added convenience macro RW_COUNT_OF that can beused
	to get the number of elements in an array.
	* 22.locale.money.put.mt.cpp (MyIos, MyStreambuf, MyMoneyData):
	Added structures to simplify testing.
	(run_test): Build a table of in/outptus for verification in test
	threads.
	(thread_func): Assert the data written matches expected.
	(main): Add support for --nlocales and --shared-locale command
	line arguments
	* 22.locale.num.put.mt.cpp (MyIos, MyStreambuf, MyNumData): Added
	structures to simplify testing.
	(run_test): Build a table of in/outptus for verification in test
	threads.
	(thread_func): Assert the data written matches expected.
	(main): Add support for --nlocales and --shared-locale command
	line arguments
	* 22.locale.time.put.mt.cpp (run_test, thread_func): Use macro
	RW_COUNT_OF. Remove "C" locale fallback. Eliminate unnecessary
	rdbuf() calls.

Modified:
    incubator/stdcxx/trunk/tests/include/rw_locale.h
    incubator/stdcxx/trunk/tests/include/testdefs.h
    incubator/stdcxx/trunk/tests/localization/22.locale.money.put.mt.cpp
    incubator/stdcxx/trunk/tests/localization/22.locale.num.put.mt.cpp
    incubator/stdcxx/trunk/tests/localization/22.locale.time.put.mt.cpp
    incubator/stdcxx/trunk/tests/src/locale.cpp

Modified: incubator/stdcxx/trunk/tests/include/rw_locale.h
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/tests/include/rw_locale.h?view=diff&rev=565991&r1=565990&r2=565991
==============================================================================
--- incubator/stdcxx/trunk/tests/include/rw_locale.h (original)
+++ incubator/stdcxx/trunk/tests/include/rw_locale.h Tue Aug 14 17:53:01 2007
@@ -37,7 +37,7 @@
 
 
 _TEST_EXPORT char*
-rw_locales (int = _UNUSED_CAT, const char* = 0);
+rw_locales (int = _UNUSED_CAT, const char* = 0, bool = true);
 
 
 // invokes the locale utility with the arguments specified by 'arg',

Modified: incubator/stdcxx/trunk/tests/include/testdefs.h
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/tests/include/testdefs.h?view=diff&rev=565991&r1=565990&r2=565991
==============================================================================
--- incubator/stdcxx/trunk/tests/include/testdefs.h (original)
+++ incubator/stdcxx/trunk/tests/include/testdefs.h Tue Aug 14 17:53:01 2007
@@ -6,22 +6,25 @@
  *
  ***************************************************************************
  *
- * Copyright 2005-2006 The Apache Software Foundation or its licensors,
- * as applicable.
- *
- * Copyright 2003-2006 Rogue Wave Software.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * Licensed to the Apache Software  Foundation (ASF) under one or more
+ * contributor  license agreements.  See  the NOTICE  file distributed
+ * with  this  work  for  additional information  regarding  copyright
+ * ownership.   The ASF  licenses this  file to  you under  the Apache
+ * License, Version  2.0 (the  "License"); you may  not use  this file
+ * except in  compliance with the License.   You may obtain  a copy of
+ * the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * distributed under the  License is distributed on an  "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY  KIND, either  express or
+ * implied.   See  the License  for  the  specific language  governing
+ * permissions and limitations under the License.
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Copyright 2003-2007 Rogue Wave Software.
  * 
  **************************************************************************/
 
@@ -161,5 +164,7 @@
    ((expr) ? (void)0 : _RW::__rw_assert_fail (#expr, __FILE__, __LINE__, 0))
 #endif   // _RWSTD_NO_PRETTY_FUNCTION, _RWSTD_NO_FUNC
 
+// convenience macro to get number of elements in a c style array
+#define RW_COUNT_OF(x) (sizeof(x) / sizeof(*x))
 
 #endif   // RW_TESTDEFS_H_INCLUDED

Modified: incubator/stdcxx/trunk/tests/localization/22.locale.money.put.mt.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/tests/localization/22.locale.money.put.mt.cpp?view=diff&rev=565991&r1=565990&r2=565991
==============================================================================
--- incubator/stdcxx/trunk/tests/localization/22.locale.money.put.mt.cpp (original)
+++ incubator/stdcxx/trunk/tests/localization/22.locale.money.put.mt.cpp Tue Aug 14 17:53:01
2007
@@ -35,10 +35,12 @@
 #include <rw_locale.h>
 #include <rw_thread.h>
 #include <driver.h>
+#include <valcmp.h>    // for rw_strncmp ()
 
 
 // maximum number of threads allowed by the command line interface
-#define MAX_THREADS   32
+#define MAX_THREADS      32
+#define MAX_LOOPS    100000
 
 // default number of threads (will be adjusted to the number
 // of processors/cores later)
@@ -48,6 +50,13 @@
 // otherwise on the command line)
 int rw_opt_nloops = 100000;
 
+// 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
@@ -60,6 +69,88 @@
 
 /**************************************************************************/
 
+static const char n_money_vals[][20] = {
+    "1", "12", "123", "1234", "12345", "123456", "1234567", "12345678",
+    "-9", "-98", "-987", "-9876", "-98765", "-987654", "-9876543",
+    "1.9", "-12.89", "123.789", "-1234.6789", "-12345.56789"
+};
+
+#ifndef _RWSTD_NO_WCHAR_T
+
+static const wchar_t w_money_vals[][20] = {
+    L"1", L"12", L"123", L"1234", L"12345", L"123456", L"1234567",
+    L"-9", L"-98", L"-987", L"-9876", L"-98765", L"-987654", L"-9876543",
+    L"1.9", L"-12.89", L"123.789", L"-1234.6789", L"-12345.56789"
+};
+
+#endif  // _RWSTD_NO_WCHAR_T
+
+//
+struct MyMoneyData
+{
+    enum { BufferSize = 16 };
+
+    enum PutId {
+        put_ldbl,
+        put_string,
+        put_max
+    };
+
+    // 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_;
+
+    // international or domestic format flag
+    bool intl_;
+
+    // the time struct used to generate strings below
+    double money_value_;
+
+    // type of the data we created string from
+    PutId type_;
+
+    // index into string array [n,w]_money_vals
+    unsigned money_index_;
+
+    // narrow representations of money_
+    char ncs_ [BufferSize];
+
+#ifndef _RWSTD_NO_WCHAR_T
+
+    // wide representations of money_
+    wchar_t wcs_ [BufferSize];
+
+#endif // _RWSTD_NO_WCHAR_T
+
+} my_money_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);
+    }
+};
+
+
 extern "C" {
 
 bool test_char;    // exercise money_put<char>
@@ -69,88 +160,57 @@
 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;
-
-    const char str_vals[][20] = {
-        "1", "12", "123", "1234", "12345", "123456", "1234567", "12345678",
-        "-9", "-98", "-987", "-9876", "-98765", "-987654", "-9876543",
-        "1.9", "-12.89", "123.789", "-1234.6789", "-12345.56789"
-    };
+    char             ncs [MyMoneyData::BufferSize];
+    MyIos<char, std::char_traits<char> >       nio;
+    MyStreambuf<char, std::char_traits<char> > nsb;
+    nio.rdbuf (&nsb);
 
 #ifndef _RWSTD_NO_WCHAR_T
-
-    struct WideBuf: std::wstreambuf {
-        int_type overflow (int_type c) { return c; }
-    } wb;
-
-    const wchar_t wstr_vals[][20] = {
-        L"1", L"12", L"123", L"1234", L"12345", L"123456", L"1234567",
-        L"-9", L"-98", L"-987", L"-9876", L"-98765", L"-987654", L"-9876543",
-        L"1.9", L"-12.89", L"123.789", L"-1234.6789", L"-12345.56789"
-    };
-
-#endif   // _RWSTD_NO_WCHAR_T
-
-    struct Ios: std::ios {
-        Ios () { this->init (0); }
-    } io;
+    wchar_t                wcs [MyMoneyData::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
 
     for (int i = 0; i != rw_opt_nloops; ++i) {
 
         // save the name of the locale
-        const char* const locale_name = locales [i % nlocales];
+        const MyMoneyData& data = my_money_data [i % nlocales];
 
-        // construct a named locale and imbue it in the ios object
-        // so that the locale is used not only by the money_put facet
-        // but also by the numpunct facet
-        const std::locale loc (locale_name);
-        io.imbue (loc);
-
-        enum PutId {
-            put_ldbl,
-            put_string,
-            put_max
-        };
-
-        io.width (i % 16);
-
-        // exercise postive and negative values
-        long double ldval = i & 1 ? -i : i;
-
-        // add some random fractional digits
-        if (i & 2)
-            ldval += ldval / 3.14;
-
-        // exercise domestic formats every other iteration
-        // and international formats the rest
-        const bool intl = 0 == (i & 1);
+        // construct a named locale, get a reference to the money_put
+        // facet from it and use it to format a random money value
+        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
 
-            const std::money_put<char> &mp =
+            const std::money_put<char> &np =
                 std::use_facet<std::money_put<char> >(loc);
 
-            const std::ostreambuf_iterator<char> iter (&sb);
+            nio.imbue (loc);
+            nsb.pubsetp (ncs, RW_COUNT_OF (ncs));
 
-            switch (i % put_max) {
-            case put_ldbl:
-                mp.put (iter, intl, io, ' ', ldval);
+            switch (data.type_) {
+            case MyMoneyData::put_ldbl:
+                *np.put (std::ostreambuf_iterator<char>(&nsb),
+                         data.intl_, nio, ' ', data.money_value_) = '\0';
                 break;
-
-            case put_string: {
-                const char* const strval =
-                    str_vals [i % sizeof str_vals / sizeof *str_vals];
-
-                mp.put (iter, intl, io, ' ', strval);
+            case MyMoneyData::put_string:
+                *np.put (std::ostreambuf_iterator<char>(&nsb),
+                         data.intl_, nio, ' ',
+                         n_money_vals [data.money_index_]) = '\0';
+                break;
+            case MyMoneyData::put_max:
+                // avoid enumeration value `put_max' not handled in switch
+                // this case should never happen
                 break;
             }
-            }
+
+            RW_ASSERT (!nio.fail ());
+            RW_ASSERT (!rw_strncmp(ncs, data.ncs_));
+
         }
 
         // both specializations may be tested at the same time
@@ -160,25 +220,31 @@
 
 #ifndef _RWSTD_NO_WCHAR_T
 
-            const std::money_put<wchar_t> &mp =
+            const std::money_put<wchar_t> &wp =
                 std::use_facet<std::money_put<wchar_t> >(loc);
 
-            const std::ostreambuf_iterator<wchar_t> iter (&wb);
+            wio.imbue (loc);
+            wsb.pubsetp (wcs, RW_COUNT_OF (wcs));
 
-            switch (i % put_max) {
-            case put_ldbl:
-                mp.put (iter, intl, io, ' ', ldval);
+            switch (data.type_) {
+            case MyMoneyData::put_ldbl:
+                *wp.put (std::ostreambuf_iterator<wchar_t>(&wsb),
+                         data.intl_, wio, ' ', data.money_value_) = L'\0';
                 break;
-
-            case put_string: {
-                const wchar_t* const strval =
-                    wstr_vals [i % sizeof wstr_vals / sizeof *wstr_vals];
-
-                mp.put (iter, intl, io, ' ', strval);
+            case MyMoneyData::put_string:
+                *wp.put (std::ostreambuf_iterator<wchar_t>(&wsb),
+                         data.intl_, wio, ' ',
+                         w_money_vals [data.money_index_]) = L'\0';
+                break;
+            case MyMoneyData::put_max:
+                // avoid enumeration value `put_max' not handled in switch
+                // this case should never happen
                 break;
-            }
             }
 
+            RW_ASSERT (!wio.fail ());
+            RW_ASSERT (!rw_strncmp(wcs, data.wcs_));
+
 #endif   // _RWSTD_NO_WCHAR_T
 
         }
@@ -194,25 +260,137 @@
 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;
+    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 (const char* name = locale_list;
+         *name;
+         name += std::strlen (name) + 1) {
+
+        const std::size_t inx = nlocales;
+        locales [inx] = name;
+
+        // fill in the money and results for this locale
+        MyMoneyData& data = my_money_data [inx];
+        data.locale_name_ = name;
+
+        try {
+            const std::locale loc (data.locale_name_);
+
+            // initialize with random but valid values
+
+            data.money_value_ = inx;
+            data.type_ = MyMoneyData::PutId(nlocales % MyMoneyData::put_max);
+            data.money_index_ = inx % RW_COUNT_OF (n_money_vals);
+
+            // exercise domestic formats every other iteration
+            // and international formats the rest
+            data.intl_ = 0 == (inx & 1);
+
+            // exercise postive and negative values
+            if (inx & 1)
+                data.money_value_ *= -1.;
+
+            // add some random fractional digits
+            if (inx & 2)
+                data.money_value_ += data.money_value_ / 3.14;
+
+            const std::money_put<char> &np =
+                std::use_facet<std::money_put<char> >(loc);
+
+            nio.imbue (loc);
+            nsb.pubsetp (data.ncs_, RW_COUNT_OF (data.ncs_));
+            
+            switch (data.type_) {
+            case MyMoneyData::put_ldbl:
+                *np.put (std::ostreambuf_iterator<char>(&nsb),
+                         data.intl_, nio, ' ', data.money_value_) = '\0';
+                break;
+            case MyMoneyData::put_string:
+                *np.put (std::ostreambuf_iterator<char>(&nsb),
+                         data.intl_, nio, ' ',
+                         n_money_vals [data.money_index_]) = '\0';
+                break;
+            case MyMoneyData::put_max:
+                // avoid enumeration value `put_max' not handled in switch
+                // this case should never happen
+                break;
+            }
+
+            rw_assert (!nio.fail (), __FILE__, __LINE__,
+                       "money_put<char>::put(...) "
+                       "failed for locale(%#s)",
+                       data.locale_name_);
+
+#ifndef _RWSTD_NO_WCHAR_T
+
+            const std::money_put<wchar_t> &wp =
+                std::use_facet<std::money_put<wchar_t> >(loc);
+
+            wio.imbue (loc);
+            wsb.pubsetp (data.wcs_, RW_COUNT_OF (data.wcs_));
+
+            switch (data.type_) {
+            case MyMoneyData::put_ldbl:
+                *wp.put (std::ostreambuf_iterator<wchar_t>(&wsb),
+                         data.intl_, wio, L' ', data.money_value_) = '\0';
+                break;
+            case MyMoneyData::put_string:
+                *wp.put (std::ostreambuf_iterator<wchar_t>(&wsb),
+                         data.intl_, wio, L' ',
+                         w_money_vals [data.money_index_]) = L'\0';
+                break;
+            case MyMoneyData::put_max:
+                // avoid enumeration value `put_max' not handled in switch
+                // this case should never happen
+                break;
+            }
+
+            rw_assert (!nio.fail (), __FILE__, __LINE__,
+                       "money_put<wchar_t>::put(...) "
+                       "failed for locale(%#s)",
+                       data.locale_name_);
+
+#endif // _RWSTD_NO_WCHAR_T
 
-    for (const char *name = locale_list; *name; name += std::strlen (name) +1) {
-        locales [nlocales++] = name;
+            if (rw_opt_shared_locale)
+                data.locale_ = loc;
 
-        if (nlocales == maxinx)
+            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::money_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::money_put<char>");
 
@@ -220,7 +398,7 @@
     test_wchar = false;
 
     // create and start a pool of threads and wait for them to finish
-    int result =
+    int result = 
         rw_thread_pool (0, std::size_t (rw_opt_nthreads), 0, thread_func, 0);
 
     rw_error (result == 0, 0, __LINE__,
@@ -242,7 +420,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,
@@ -284,9 +462,13 @@
                     "thread safety", run_test,
                     "|-nloops#0 "        // must be non-negative
                     "|-nthreads#0-* "    // must be in [0, MAX_THREADS]
-                    "|-locales=",        // must be provided
+                    "|-nlocales#0 "      // arg must be non-negative
+                    "|-locales= "        // must be provided
+                    "|-shared-locale# ",
                     &rw_opt_nloops,
                     int (MAX_THREADS),
                     &rw_opt_nthreads,
-                    &rw_opt_setlocales);
+                    &rw_opt_nlocales,
+                    &rw_opt_setlocales,
+                    &rw_opt_shared_locale);
 }

Modified: incubator/stdcxx/trunk/tests/localization/22.locale.num.put.mt.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/tests/localization/22.locale.num.put.mt.cpp?view=diff&rev=565991&r1=565990&r2=565991
==============================================================================
--- incubator/stdcxx/trunk/tests/localization/22.locale.num.put.mt.cpp (original)
+++ incubator/stdcxx/trunk/tests/localization/22.locale.num.put.mt.cpp Tue Aug 14 17:53:01
2007
@@ -35,18 +35,24 @@
 #include <rw_locale.h>
 #include <rw_thread.h>   // for rw_get_processors (), rw_thread_pool()
 #include <driver.h>
+#include <valcmp.h>
 
-
-// maximum number of threads allowed by the command line interface
-#define MAX_THREADS   32
+#define MAX_THREADS      32
+#define MAX_LOOPS    100000
 
 // 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 (unless specified
-// otherwise on the command line)
-int rw_opt_nloops = 200000;
+// 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;
 
 /**************************************************************************/
 
@@ -58,99 +64,177 @@
 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 traitT>
+void
+put_data(const MyNumData& data, 
+         const std::num_put<charT>& np,
+         const std::ostreambuf_iterator<charT>& iter,
+         std::basic_ios<charT, traitT>& 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;
+    }
 
-        const std::ios::fmtflags base =
-            baseflags [i % (sizeof baseflags / sizeof *baseflags)];
+}
 
-        const std::ios::fmtflags fmt =
-            fmtflags [i % (sizeof baseflags / sizeof *baseflags)];
+extern "C" {
 
-        const std::ios::fmtflags adjust =
-            adjustflags [i % (sizeof baseflags / sizeof *baseflags)];
+bool test_char;    // exercise num_put<char>
+bool test_wchar;   // exercise num_put<wchar_t>
 
-        io.flags (base | fmt | adjust);
 
-        io.width (i % 16);
+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);
+
+#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
+
+    for (int i = 0; i != rw_opt_nloops; ++i) {
 
-        // exercise postive and negative values
-        const int ival = i & 1 ? -i : i;
+        // fill in the value and results for this locale
+        const MyNumData& data = my_num_data [i % nlocales];
+
+        // 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
@@ -158,50 +242,14 @@
             const std::num_put<char> &np =
                 std::use_facet<std::num_put<char> >(loc);
 
-            const std::ostreambuf_iterator<char> iter (&sb);
-
-            switch (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;
-
-#ifndef _RWSTD_NO_LONG_LONG
+            nio.imbue (loc);
+            nsb.pubsetp (ncs, RW_COUNT_OF (ncs));
 
-            case put_llong:
-                np.put (iter, io, ' ', (_RWSTD_LONG_LONG)ival);
-                break;
+            put_data(data, np, std::ostreambuf_iterator<char>(&nsb),
+                     nio, ' ', '\0');
 
-#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
@@ -211,48 +259,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);
-
-            switch (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;
+            wio.imbue (loc);
+            wsb.pubsetp (wcs, RW_COUNT_OF (wcs));
 
-#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;
+            put_data(data, wp, std::ostreambuf_iterator<wchar_t>(&wsb),
+                     wio, L' ', L'\0');
 
-#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
 
@@ -266,29 +283,98 @@
 
 /**************************************************************************/
 
+
 static int
 run_test (int, char**)
 {
+    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 (const char *name = locale_list; *name; name += std::strlen (name) +1) {
+    for (const char *name = locale_list;
+         *name;
+         name += std::strlen (name) + 1) {
 
-        locales [nlocales++] = name;
+        const std::size_t inx = nlocales;
+        locales [inx] = name;
 
-        if (nlocales == maxinx)
+        // fill in the value and results for this locale
+        MyNumData& data = my_num_data [nlocales];
+        data.locale_name_ = name;
+
+        try {
+            const std::locale loc (data.locale_name_);
+
+            data.value_ = nlocales & 1 ? -1 * nlocales : nlocales;
+            data.type_ = MyNumData::PutId(nlocales % MyNumData::put_max);
+
+            // 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>");
 
@@ -318,7 +404,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,
@@ -357,11 +443,15 @@
     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]
-                    "|-locales=",        // must be provided
+                    "|-nloops#0 "       // must be non-negative
+                    "|-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_setlocales);
+                    &rw_opt_nlocales,
+                    &rw_opt_setlocales,
+                    &rw_opt_shared_locale);
 }

Modified: incubator/stdcxx/trunk/tests/localization/22.locale.time.put.mt.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/tests/localization/22.locale.time.put.mt.cpp?view=diff&rev=565991&r1=565990&r2=565991
==============================================================================
--- incubator/stdcxx/trunk/tests/localization/22.locale.time.put.mt.cpp (original)
+++ incubator/stdcxx/trunk/tests/localization/22.locale.time.put.mt.cpp Tue Aug 14 17:53:01
2007
@@ -124,8 +124,6 @@
 };
 
 
-#define countof(x) (sizeof (x) / sizeof (*x))
-
 extern "C" {
 
 bool test_char;    // exercise time_put<char>
@@ -138,11 +136,13 @@
     char              ncs [MyTimeData::BufferSize];
     MyIos<char, std::char_traits<char> >       nio;
     MyStreambuf<char, std::char_traits<char> > nsb;
+    nio.rdbuf (&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;
+    wio.rdbuf (&wsb);
 #endif // _RWSTD_NO_WCHAR_T
 
     for (int i = 0; i != rw_opt_nloops; ++i) {
@@ -164,10 +164,7 @@
                 std::use_facet<std::time_put<char> >(loc);
 
             nio.imbue (loc);
-
-            // assign data buffer to streambuf
-            nsb.pubsetp (ncs, countof (ncs));
-            nio.rdbuf (&nsb);
+            nsb.pubsetp (ncs, RW_COUNT_OF (ncs));
 
             // format time using provided format specifier
             *tp.put (std::ostreambuf_iterator<char>(&nsb),
@@ -189,9 +186,7 @@
                 std::use_facet<std::time_put<wchar_t> >(loc);
 
             wio.imbue (loc);
-
-            wsb.pubsetp (wcs, countof (wcs));
-            wio.rdbuf (&wsb);
+            wsb.pubsetp (wcs, RW_COUNT_OF (wcs));
 
             *wp.put (std::ostreambuf_iterator<wchar_t>(&wsb),
                      wio, L' ', &data.time_, data.format_) = L'\0';
@@ -216,109 +211,96 @@
 {
     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 = countof (locales);
+    const std::size_t maxinx = RW_COUNT_OF (locales);
 
-    const char* const possible_locale_options[] = {
-        locale_list, "C\0", 0
-    };
-
-    for (int p = 0; possible_locale_options[p]; ++p) {
-
-        int j = 0;
-        for (const char* name = possible_locale_options[p];
-             *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_, countof (data.ncs_));
-                nio.rdbuf (&nsb);
-                
-                *np.put (std::ostreambuf_iterator<char>(&nsb),
-                         nio, ' ', &data.time_, data.format_) = '\0';
-
-                rw_assert (!nio.fail (), __FILE__, __LINE__,
-                           "time_put<char>::put(..., %c) "
-                           "failed for locale(%#s)",
-                           data.format_, data.locale_name_);
-                
-#ifndef _RWSTD_NO_WCHAR_T
+    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)];
 
-                const std::time_put<wchar_t> &wp =
-                    std::use_facet<std::time_put<wchar_t> >(loc);
+        try {
+            const std::locale loc (data.locale_name_);
 
-                wio.imbue (loc);
+            const std::time_put<char> &np =
+                std::use_facet<std::time_put<char> >(loc);
 
-                wsb.pubsetp (data.wcs_, countof (data.wcs_));
-                wio.rdbuf (&wsb);
-                
-                *wp.put (std::ostreambuf_iterator<wchar_t>(&wsb),
-                         wio, L' ', &data.time_, data.format_) = L'\0';
-                
-                rw_assert (!wio.fail (), __FILE__, __LINE__,
-                           "time_put<wchar_t>::put(..., %c) "
-                           "failed for locale(%#s)",
-                           data.format_, data.locale_name_);
+            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';
 
-#endif // _RWSTD_NO_WCHAR_T
+            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 (rw_opt_shared_locale)
-                    data.locale_ = loc;
+            const std::time_put<wchar_t> &wp =
+                std::use_facet<std::time_put<wchar_t> >(loc);
 
-                nlocales += 1;
+            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_);
 
-            }
-            catch (...) {
-                rw_warn (!rw_opt_locales, 0, __LINE__,
-                         "failed to create locale(%#s)", name);
-            }
+#endif // _RWSTD_NO_WCHAR_T
 
-            if (nlocales == maxinx || nlocales == std::size_t (rw_opt_nlocales))
-                break;
-        }
+            if (rw_opt_shared_locale)
+                data.locale_ = loc;
+
+            nlocales += 1;
 
-        if (nlocales != 0) {
-            break; // found at least one locale
         }
+        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

Modified: incubator/stdcxx/trunk/tests/src/locale.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/tests/src/locale.cpp?view=diff&rev=565991&r1=565990&r2=565991
==============================================================================
--- incubator/stdcxx/trunk/tests/src/locale.cpp (original)
+++ incubator/stdcxx/trunk/tests/src/locale.cpp Tue Aug 14 17:53:01 2007
@@ -327,7 +327,7 @@
 /**************************************************************************/
 
 _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;
@@ -402,12 +402,23 @@
         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)) {
 
             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
 



Mime
View raw message