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 <[EMAIL PROTECTED]>
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