stdcxx-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From se...@apache.org
Subject svn commit: r642832 - /stdcxx/trunk/tests/localization/22.locale.numpunct.cpp
Date Sun, 30 Mar 2008 22:50:42 GMT
Author: sebor
Date: Sun Mar 30 15:50:34 2008
New Revision: 642832

URL: http://svn.apache.org/viewvc?rev=642832&view=rev
Log:
2008-03-30  Martin Sebor  <sebor@roguewave.com>

	STDCXX-4
	* tests/localization/22.locale.numpunct.cpp: New test exercising
	the required specializations of the std::numpunct facet.

Added:
    stdcxx/trunk/tests/localization/22.locale.numpunct.cpp   (with props)

Added: stdcxx/trunk/tests/localization/22.locale.numpunct.cpp
URL: http://svn.apache.org/viewvc/stdcxx/trunk/tests/localization/22.locale.numpunct.cpp?rev=642832&view=auto
==============================================================================
--- stdcxx/trunk/tests/localization/22.locale.numpunct.cpp (added)
+++ stdcxx/trunk/tests/localization/22.locale.numpunct.cpp Sun Mar 30 15:50:34 2008
@@ -0,0 +1,399 @@
+/************************************************************************
+ *
+ * 22.locale.numpunct.cpp
+ *
+ * test exercising the std::numpunct facet
+ *
+ * $Id$
+ *
+ ***************************************************************************
+ *
+ * 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
+ *
+ * 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.
+ *
+ **************************************************************************/
+
+#include <rw/_defs.h>
+
+#if defined (__IBMCPP__) && !defined (_RWSTD_NO_IMPLICIT_INCLUSION)
+// Disable implicit inclusion to work around
+// a limitation in IBM's VisualAge 5.0.2.0 (see PR#26959)
+
+#  define _RWSTD_NO_IMPLICIT_INCLUSION
+#endif
+
+
+#include <clocale>   // for struct lconv, setlocale()
+#include <cstdio>    // for sprintf()
+#include <cstdlib>   // for getenv()
+#include <cstring>   // for strcmp()
+#include <locale>
+
+#include <driver.h>
+#include <environ.h>
+#include <rw_locale.h>
+
+/**************************************************************************/
+
+template <class charT>
+void run_test (charT*);
+
+template <class charT>
+void check_decimal_point (charT, const char*, const std::locale*);
+
+template <class charT>
+void check_thousands_sep (charT, const char*, const std::locale*);
+
+template <class charT>
+void check_grouping (charT, const char*, const std::string&, const std::locale*);
+
+template <class charT>
+void check_falsename (const std::basic_string<charT>&,
+                      const char*, const std::locale*);
+
+template <class charT>
+void check_truename (const std::basic_string<charT>&,
+                     const char*, const std::locale*);
+
+template <class charT>
+bool check_numpunct (charT, const char*, const char*, const std::locale*);
+
+
+/**************************************************************************/
+
+template <class charT>
+void run_test (charT, const char *tname)
+{
+    rw_info (0, 0, __LINE__, "classic \"C\" locale");
+
+    // create a copy of the classic ("C") locale
+    std::locale *loc = new std::locale (std::locale::classic ());
+
+    // verify (at compile time) that _byname facets can be used
+    // to specialize use_facet() and has_facet()
+    typedef std::numpunct_byname<charT> NumpunctByname;
+
+    if (_STD_HAS_FACET (NumpunctByname, *loc))
+        _STD_USE_FACET (NumpunctByname, *loc);
+
+    // verify values as per 7.4 of C89, and 7.11, p2 of C99
+    check_decimal_point (charT ('.'), tname, loc);
+
+    // verify 22.2.3.1.2, p2
+    check_thousands_sep (charT (','), tname, loc);
+    check_grouping (charT (), tname, "", loc);
+
+    const charT fn[] = { 'f', 'a', 'l', 's', 'e', '\0' };
+    const charT tn[]  = { 't', 'r', 'u', 'e', '\0' };
+
+    check_falsename (std::basic_string<charT>(fn), tname, loc);
+    check_truename (std::basic_string<charT>(tn), tname, loc);
+
+    delete loc;
+    loc = 0;
+
+    //////////////////////////////////////////////////////////////////
+    // verify that the facet can be safely used on its own, without
+    // first having to be installed in a locale and retrieved using
+    // use_facet
+
+    check_decimal_point (charT ('.'), tname, loc);
+    check_thousands_sep (charT (','), tname, loc);
+    check_grouping (charT (), tname, "", loc);
+
+    check_falsename (std::basic_string<charT>(fn), tname, loc);
+    check_truename (std::basic_string<charT>(tn), tname, loc);
+
+    //////////////////////////////////////////////////////////////////
+    // exercise the native locale (affected by the environment
+    // variables LANG, LC_ALL, LC_NUMERIC, etc.)
+    check_numpunct (charT (), tname, "", loc);   // native locale
+
+    // the name of the first non-C (and non-POSIX) locale
+    const char *first_non_c = 0;
+
+    // exercise named locales (including "C" and "POSIX")
+    for (const char* s = rw_locales (); *s; s += std::strlen (s) + 1) {
+        if (check_numpunct (charT (), tname, s, loc))
+            if (   !first_non_c
+                && std::strcmp ("C", s)
+                && std::strcmp ("POSIX", s))
+            first_non_c = s;
+    }
+
+    // verify that numpunct behaves correctly when LC_ALL is set
+    // to the name of the (non-C, non-POSIX) locale
+    char envvar [80];
+    std::sprintf (envvar, "LC_ALL=%s", first_non_c);
+    rw_putenv (envvar);
+    check_numpunct (charT (), tname, "", loc);
+}
+
+/**************************************************************************/
+
+char widen (char, const char *s)
+{
+    return *s;
+}
+
+#ifndef _RWSTD_NO_WCHAR_T
+
+wchar_t widen (wchar_t, const char *s)
+{
+    wchar_t wc = 0;
+
+#  ifndef _RWSTD_NO_MBTOWC
+
+    const int n = s && *s ? std::mbtowc (&wc, s, std::strlen (s)) : 0;
+
+#  else   // if defined (_RWSTD_NO_MBTOWC)
+
+    const int n = 1;
+
+    wc = s ? wchar_t (_RWSTD_STATIC_CAST (unsigned char, *s)) : 0;
+
+#  endif   // _RWSTD_NO_MBTOWC
+
+    return n > 0 ? wc : n ? -1 : 0;
+}
+
+#endif   // _RWSTD_NO_WCHAR_T
+
+
+template <class charT>
+bool check_numpunct (charT,
+                     const char        *tname,
+                     const char        *locname,
+                     const std::locale *loc)
+{
+    // (try to) set the global C locale
+    const char *tmploc = std::setlocale (LC_ALL, locname);
+    if (!tmploc)
+        return false;
+
+    // future setlocale() calls may change tmploc's value, so make a copy
+    // (fixed-size char buf is clunky but avoids memory-leak potential)
+    char locnamebuf [1024];
+    RW_ASSERT ((std::strlen (tmploc) + 1) < sizeof locnamebuf);
+    std::strcpy (locnamebuf, tmploc);
+
+    _TRY {
+
+        rw_info (0, 0, __LINE__,
+                 "locale (%s) -> \"%s\"; LANG=%s, "
+                 "LC_ALL=%s, LC_NUMERIC=%s",
+                 locname, loc,
+                 std::getenv ("LANG"),
+                 std::getenv ("LC_ALL"),
+                 std::getenv ("LC_NUMERIC"));
+
+        // get a pointer to lconv
+        const std::lconv *plconv = std::localeconv ();
+
+        if (!plconv)
+            return false;
+
+        // copy important data; the contents of *plconv may
+        // be overwritten by the call sto setlocale() below
+        // note that decimal_point at al may be multbyte character
+        // strings that need to be widened according to the rules
+        // of the same locale
+        const charT decimal_point = widen (charT (), plconv->decimal_point);
+        const charT thousands_sep = widen (charT (), plconv->thousands_sep);
+
+        const std::string grouping =
+            plconv->grouping ? plconv->grouping : "";
+
+        // reset to default locale given by LC_LANG
+        std::setlocale (LC_ALL, "");
+
+        loc = new std::locale (locname);
+
+        // check that newly constructed locale matches
+
+        if (   'C' == locnamebuf [0] && '\0' == locnamebuf [1]
+            || 'C' == locname [0] && '\0' == locname [1]
+            || *loc == std::locale::classic ()) {
+            // follow requirements in 22.2.3.1.2. p1, 2, and 3
+            check_decimal_point (charT ('.'), tname, loc);
+            check_thousands_sep (charT (','), tname, loc);
+
+            check_grouping (charT (), tname, "", loc);
+        }
+        else {
+            // cast to prevent sign extension between (signed) char and wchar_t
+            // tmp guards against possibly passing along a "(nil)" pointer
+            check_decimal_point (decimal_point, tname, loc);
+            check_thousands_sep (thousands_sep, tname, loc);
+            check_grouping (charT (), tname, grouping.c_str (), loc);
+        }
+
+        // FIXME: exercise falsename() and truename() in named locales
+
+        delete loc;
+        loc = 0;
+    }
+    _CATCH (...) {
+        return false;
+    }
+    return true;
+}
+
+/**************************************************************************/
+
+template <class charT>
+void check_decimal_point (charT              expect,
+                          const char        *tname,
+                          const std::locale *loc)
+{
+    typedef std::numpunct<charT>    Punct;
+    typedef std::char_traits<charT> Traits;
+
+    const charT c = loc ?
+          _STD_USE_FACET (Punct, *loc).decimal_point ()
+        : Punct ().decimal_point ();
+
+
+    rw_assert (Traits::eq (c, expect), 0, __LINE__,
+               "numpunct<%s>::decimal_point() == %{#lc}, got %{#lc}",
+               tname, expect, c);
+}
+
+/**************************************************************************/
+
+template <class charT>
+void check_thousands_sep (charT              expect,
+                          const char        *tname,
+                          const std::locale *loc)
+{
+    typedef std::numpunct<charT>    Punct;
+    typedef std::char_traits<charT> Traits;
+
+    const charT c = loc ?
+          _STD_USE_FACET (Punct, *loc).thousands_sep ()
+        : Punct ().thousands_sep ();
+
+    rw_assert (Traits::eq (c, expect), 0, __LINE__,
+               "numpunct<%s>::thousands_sep() == %{#lc}, got %{#lc}",
+               tname, expect, c);
+}
+
+/**************************************************************************/
+
+template <class charT>
+void check_grouping (charT,
+                     const char        *tname,
+                     const std::string &expect,
+                     const std::locale *loc)
+{
+    typedef std::numpunct<charT> Punct;
+
+    const std::string s = loc ?
+          _STD_USE_FACET (Punct, *loc).grouping ()
+        : Punct ().grouping ();
+
+    if (   s != expect
+        && s.size () != expect.size () && s.size () && expect.size
()) {
+
+        // if the grouping is not exactly the same as the expected result,
+        // verify that the actual grouping is equivalent to the expected
+        // one, e.g., that "\003\003" is equivalent to "\003"
+
+        const std::string *lng  = s.size () > expect.size () ? &expect : &s;
+        const std::string *shrt = s.size () < expect.size () ? &expect : &s;
+
+        std::size_t i = shrt->size () - 1;
+
+        for ( ; i != lng->size (); ++i)
+            if ((*shrt) [shrt->size () - 1] != (*lng)[i])
+                break;
+
+        rw_assert (i == lng->size (), 0, __LINE__,
+                   "numpunct<%s>::grouping() equivalent to %{#S}, got %{#S}",
+                   tname, &expect, &s);
+    }
+    else
+        rw_assert (s == expect, 0, __LINE__,
+                   "numpunct<%s>::grouping() == %{#S}, got %{#S}",
+                   tname, &expect, &s);
+}
+
+/**************************************************************************/
+
+template <class charT>
+void check_falsename (const std::basic_string<charT> &expect,
+                      const char                     *tname,
+                      const std::locale              *loc)
+{
+    typedef std::numpunct<charT> Punct;
+
+    const std::basic_string<charT> s = loc ?
+          _STD_USE_FACET (Punct, *loc).falsename ()
+        : Punct ().falsename ();
+
+    const int char_size = int (sizeof (charT));
+
+    rw_assert (s == expect, 0, __LINE__,
+               "numpunct<%s>::falsename() == %{#*S}, got %{#*S}",
+               tname, char_size, &expect, char_size, &s);
+}
+
+/**************************************************************************/
+
+template <class charT>
+void check_truename (const std::basic_string<charT> &expect,
+                     const char                     *tname,
+                     const std::locale              *loc)
+{
+    typedef std::numpunct<charT> Punct;
+
+    const std::basic_string<charT> s = loc ?
+          _STD_USE_FACET (Punct, *loc).truename ()
+        : Punct ().truename ();
+
+    const int char_size = int (sizeof (charT));
+
+    rw_assert (s == expect, 0, __LINE__,
+               "numpunct<%s>::truename() == %{#*S}, got %{#*S}",
+               tname, char_size, &expect, char_size, &s);
+}
+
+/**************************************************************************/
+
+static int
+run_test (int, char**)
+{
+    run_test (char (), "char");
+
+#ifndef _RWSTD_WCHAR_T
+
+    run_test (wchar_t (), "wchar_t");
+
+#endif   // _RWSTD_WCHAR_T
+
+    return 0;
+}
+
+/**************************************************************************/
+
+int main (int argc, char *argv[])
+{
+    return rw_test (argc, argv, __FILE__,
+                    "lib.locale.numpunct",
+                    "", run_test,
+                    "",
+                    (void*)0);
+}

Propchange: stdcxx/trunk/tests/localization/22.locale.numpunct.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: stdcxx/trunk/tests/localization/22.locale.numpunct.cpp
------------------------------------------------------------------------------
    svn:keywords = Id



Mime
View raw message