I attached the modified test, it is ending prematurely see log for more details.
Yu (Scott) Zhong
# INFO (S1) (10 lines):
# TEXT:
# COMPILER: gcc 4.1.2, __VERSION__ = "4.1.2 20061115 (prerelease) (SUSE Linux)"
# ENVIRONMENT: i386 running linux-elf 2.6.18 with glibc 2.5
# FILE: 22.locale.ctype.toupper.cpp
# COMPILED: Apr 9 2007, 12:28:25
# COMMENT:
############################################################
# CLAUSE: lib.category.ctype
# NOTE (S2) (5 lines):
# TEXT: executing "rm -rf /tmp/tmpfile-JVTzh2"
# CLAUSE: lib.category.ctype
# FILE: process.cpp
# LINE: 274
# NOTE (S2) (5 lines):
# TEXT: executing "mkdir /tmp/tmpfile-JVTzh2"
# CLAUSE: lib.category.ctype
# FILE: process.cpp
# LINE: 274
# NOTE (S2) (5 lines):
# TEXT: executing "../bin/localedef -w -c -f /tmp/tmpfile-JVTzh2/charmap.src -i /tmp/tmpfile-JVTzh2/locale.src /tmp/tmpfile-JVTzh2/test-locale"
# CLAUSE: lib.category.ctype
# FILE: process.cpp
# LINE: 274
# INFO (S1) (4 lines):
# TEXT: std::ctype<char>::toupper(char) in locale("test-locale")
# CLAUSE: lib.category.ctype
# LINE: 810
# INFO (S1) (4 lines):
# TEXT: std::ctype<char>::toupper(char)
# CLAUSE: lib.category.ctype
# LINE: 776
# NOTE (S2) (5 lines):
# TEXT: executing "locale -a > /tmp/tmpfile-gDAaNC"
# CLAUSE: lib.category.ctype
# FILE: process.cpp
# LINE: 274
# +-----------------------+----------+----------+----------+
# | DIAGNOSTIC | ACTIVE | TOTAL | INACTIVE |
# +-----------------------+----------+----------+----------+
# | (S1) INFO | 3 | 3 | 0% |
# | (S2) NOTE | 4 | 4 | 0% |
# | (S7) ASSERTION | 0 | 209614 | 100% |
# | (S8) ERROR | 0 | 1 | 100% |
# +-----------------------+----------+----------+----------+
/home/scottz/stdcxx/tests/src/driver.cpp:1510: rw_note(): warning: test finished, cannot call
/home/scottz/stdcxx/tests/src/driver.cpp:1381: _rw_vdiag(): warning: test finished, cannot call
/home/scottz/stdcxx/tests/src/driver.cpp:1236: _rw_vissue_diag(): warning: test finished, cannot call
# NOTE (S2) (5 lines):
# TEXT: executing "rm -rf /tmp/tmpfile-JVTzh2"
# CLAUSE: lib.category.ctype
# FILE: process.cpp
# LINE: 274
/***************************************************************************
*
* 22.locale.ctype.toupper.cpp - Tests exercising the ctype facet - toupper
*
* $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.
*
* Copyright 2001-2006 Rogue Wave Software.
*
**************************************************************************/
// DESCRIPTION: test iterates over the locales installed on a machine,
// calling the C character classification functions and
// their C++ counterpart(s), comparing the results of
// the calls against one another.
#include <rw/_defs.h>
#if defined __linux__
// on Linux define _XOPEN_SOURCE to get CODESET defined in <langinfo.h>
# define _XOPEN_SOURCE 500 /* Single Unix conformance */
// bring __int32_t into scope (otherwise <wctype.h> fails to compile)
# include <sys/types.h>
#endif // __linux__
// see Onyx PR #28150
#if defined (__SUNPRO_CC) && __SUNPRO_CC <= 0x540
# include <wchar.h>
#endif // defined (__SUNPRO_CC) && __SUNPRO_CC <= 0x540
#include <locale>
#include <climits>
#include <clocale>
#include <cstring>
#include <cctype>
#include <cstdio>
#include <cstdlib>
#include <cwchar> // for WEOF, btowc(), wctob()
#include <cwctype> // for iswxxx()
#if !defined (_MSC_VER)
# if !defined (LC_MESSAGES)
# define LC_MESSAGES _RWSTD_LC_MESSAGES
# endif // LC_MESSAGES
# include <langinfo.h>
#endif // _MSC_VER
#include <driver.h>
#include <file.h> // for SLASH
#include <rw_locale.h> // for rw_locales()
/**************************************************************************/
// the root of the locale directory (RWSTD_LOCALE_ROOT)
// not set here to avoid Solaris 7 putenv() bug (PR #30017)
const char* locale_root;
#define NLOOPS 25
#define MAX_STR_SIZE 16
#define BEGIN_LOCALE_LOOP(num, locname, loop_cntrl) \
for (const char* locname = rw_locales (LC_CTYPE, 0); \
*locname; locname += std::strlen (locname) + 1) { \
_TRY { \
const std::locale loc (locname); \
const std::ctype<char> &ctc = \
_STD_USE_FACET (std::ctype<char>, loc); \
_RWSTD_UNUSED (ctc); \
const std::ctype<charT> &ctp = \
_STD_USE_FACET (std::ctype<charT>, loc); \
for (int loop_cntrl = 0; loop_cntrl < int (num); loop_cntrl++)
#define END_LOCALE_LOOP(locname) \
} \
_CATCH (...) { \
rw_assert (0, 0, __LINE__, \
"locale (\"%s\") threw an exception", locname); \
} \
}
// for notational convenience
typedef unsigned char UChar;
#define ALPHA std::ctype_base::alpha
#define UPPER std::ctype_base::upper
#define LOWER std::ctype_base::lower
#define DIGIT std::ctype_base::digit
#define SPACE std::ctype_base::space
#define CNTRL std::ctype_base::cntrl
#define PUNCT std::ctype_base::punct
#define XDIGIT std::ctype_base::xdigit
#define GRAPH std::ctype_base::graph
#define PRINT std::ctype_base::print
// wrapper functions for the c library char and wchar_t functions
int libc_isalpha (char ch)
{
return (std::isalpha)(UChar (ch));
}
int libc_isspace (char ch)
{
return (std::isspace)(UChar (ch));
}
int libc_isprint (char ch)
{
return (std::isprint)(UChar (ch));
}
int libc_iscntrl (char ch)
{
return (std::iscntrl)(UChar (ch));
}
int libc_isupper (char ch)
{
return (std::isupper)(UChar (ch));
}
int libc_islower (char ch)
{
return (std::islower)(UChar (ch));
}
int libc_isdigit (char ch)
{
return (std::isdigit)(UChar (ch));
}
int libc_ispunct (char ch)
{
return (std::ispunct)(UChar (ch));
}
int libc_isxdigit (char ch)
{
return (std::isxdigit)(UChar (ch));
}
int libc_isalnum (char ch)
{
return (std::isalnum)(UChar (ch));
}
int libc_isgraph (char ch)
{
return (std::isgraph)(UChar (ch));
}
char libc_tolower (char ch)
{
return std::tolower (UChar (ch));
}
char libc_toupper (char ch)
{
return (std::toupper)(UChar (ch));
}
std::ctype_base::mask libc_mask (int mask, char ch, const char *locname)
{
char curlocname [256];
if (locname) {
std::strcpy (curlocname, std::setlocale (LC_CTYPE, 0));
if (0 == std::setlocale (LC_CTYPE, locname))
return std::ctype_base::mask ();
}
const int c = UChar (ch);
int result = 0;
if (mask & ALPHA && (std::isalpha)(c))
result |= ALPHA;
if (mask & CNTRL && (std::iscntrl)(c))
result |= CNTRL;
if (mask & DIGIT && (std::isdigit)(c))
result |= DIGIT;
if (mask & GRAPH && (std::isgraph)(c))
result |= GRAPH;
if (mask & LOWER && (std::islower)(c))
result |= LOWER;
if (mask & PRINT && (std::isprint)(c))
result |= PRINT;
if (mask & PUNCT && (std::ispunct)(c))
result |= PUNCT;
if (mask & SPACE && (std::isspace)(c))
result |= SPACE;
if (mask & UPPER && (std::isupper)(c))
result |= UPPER;
if (mask & XDIGIT && (std::isxdigit)(c))
result |= XDIGIT;
if (locname)
std::setlocale (LC_CTYPE, curlocname);
return std::ctype_base::mask (result);
}
inline bool libc_is (std::ctype_base::mask mask, char ch, const char *locname)
{
const std::ctype_base::mask m = libc_mask (mask, ch, locname);
return 0 != (m & mask);
}
std::size_t c_strlen (const char *s1)
{
return std::strlen (s1);
}
int c_strcmp (const char *s1, const char *s2)
{
int ret = std::strcoll (s1, s2);
return ret ? ret > 0 ? 1 : -1 : 0;
}
const char* narrow (char *dst, const char *src)
{
if (src == dst || !src || !dst)
return src;
std::memcpy (dst, src, std::strlen (src) + 1);
return dst;
}
const char* widen (char *dst, const char *src)
{
if (src == dst || !src || !dst)
return src;
std::memcpy (dst, src, std::strlen (src) + 1);
return dst;
}
char widen (char, char ch, const char*)
{
return ch;
}
char narrow (char ch, const char*)
{
return ch;
}
// cond1() verifies condition [1] in Test::test_narrow_widen()
// below using libc functions
bool cond1 (std::ctype_base::mask mask, char ch, const char *locname)
{
char curlocname [256];
std::strcpy (curlocname, std::setlocale (LC_CTYPE, 0));
if (0 == std::setlocale (LC_CTYPE, locname))
return false;
#ifdef __SUNPRO_CC
// working around a SunPro bug (PR #28150)
using std::wint_t;
#endif // __SUNPRO_CC
#ifndef _RWSTD_NO_BTOWC
const std::wint_t wc = std::btowc (UChar (ch));
#elif !defined (_RWSTD_NO_MBSTOWCS)
wchar_t tmp;
const std::wint_t wc = 1 == std::mbstowcs (&tmp, &ch, 1) ? tmp : WEOF;
#else
const std::wint_t wc = WEOF;
#endif // _RWSTD_NO_BTOWC, _RWSTD_NO_MBSTOWCS
const bool result =
WEOF == wc || libc_is (mask, ch, 0) || !libc_is (mask, wchar_t (wc), 0);
std::setlocale (LC_CTYPE, curlocname);
return result;
}
// cond3() overloads verify condition [3] in Test::test_narrow_widen()
// below using libc functions
bool cond3 (std::ctype_base::mask, char, const char*)
{
return true;
}
#ifndef _RWSTD_NO_WCHAR_T
int libc_isalpha (wchar_t ch)
{
return (std::iswalpha)(ch);
}
int libc_isspace (wchar_t ch)
{
return (std::iswspace)(ch);
}
int libc_isprint (wchar_t ch)
{
return (std::iswprint)(ch);
}
int libc_iscntrl (wchar_t ch)
{
return (std::iswcntrl)(ch);
}
int libc_isupper (wchar_t ch)
{
return (std::iswupper)(ch);
}
int libc_islower (wchar_t ch)
{
return (std::iswlower)(ch);
}
int libc_isdigit (wchar_t ch)
{
return (std::iswdigit)(ch);
}
int libc_ispunct (wchar_t ch)
{
return (std::iswpunct)(ch);
}
int libc_isxdigit (wchar_t ch)
{
return (std::iswxdigit)(ch);
}
int libc_isalnum (wchar_t ch)
{
return (std::iswalnum)(ch);
}
int libc_isgraph (wchar_t ch)
{
return (std::iswgraph)(ch);
}
wchar_t libc_tolower (wchar_t ch)
{
return (std::towlower)(ch);
}
wchar_t libc_toupper (wchar_t ch)
{
return (std::towupper)(ch);
}
std::size_t c_strlen (const wchar_t *s1)
{
return std::wcslen (s1);
}
int c_strcmp (const wchar_t *s1, const wchar_t *s2)
{
int ret = std::wcscmp (s1, s2);
return ret ? ret > 0 ? 1 : -1 : 0;
}
const char* narrow (char *dst, const wchar_t *src)
{
static char buf [4096];
if (!src)
return 0;
if (!dst)
dst = buf;
std::size_t len = std::wcslen (src);
_RWSTD_ASSERT (len < sizeof buf);
len = std::wcstombs (dst, src, sizeof buf / sizeof *buf);
if (std::size_t (-1) == len)
*dst = 0;
return dst;
}
const wchar_t* widen (wchar_t *dst, const char *src)
{
static wchar_t buf [4096];
if (!src)
return 0;
if (!dst)
dst = buf;
std::size_t len = std::strlen (src);
_RWSTD_ASSERT (len < sizeof buf /sizeof *buf);
len = std::mbstowcs (dst, src, sizeof buf / sizeof *buf);
if (std::size_t (-1) == len)
*dst = 0;
return dst;
}
std::ctype_base::mask libc_mask (int mask, wchar_t ch, const char *locname)
{
char curlocname [256];
if (locname) {
std::strcpy (curlocname, std::setlocale (LC_CTYPE, 0));
if (0 == std::setlocale (LC_CTYPE, locname))
return std::ctype_base::mask ();
}
int result = 0;
if (mask & ALPHA && (std::iswalpha)(ch))
result |= ALPHA;
if (mask & CNTRL && (std::iswcntrl)(ch))
result |= CNTRL;
if (mask & DIGIT && (std::iswdigit)(ch))
result |= DIGIT;
if (mask & GRAPH && (std::iswgraph)(ch))
result |= GRAPH;
if (mask & LOWER && (std::iswlower)(ch))
result |= LOWER;
if (mask & PRINT && (std::iswprint)(ch))
result |= PRINT;
if (mask & PUNCT && (std::iswpunct)(ch))
result |= PUNCT;
if (mask & SPACE && (std::iswspace)(ch))
result |= SPACE;
if (mask & UPPER && (std::iswupper)(ch))
result |= UPPER;
if (mask & XDIGIT && (std::iswxdigit)(ch))
result |= XDIGIT;
if (locname)
std::setlocale (LC_CTYPE, curlocname);
return std::ctype_base::mask (result);
}
bool libc_is (std::ctype_base::mask mask, wchar_t ch, const char *locname)
{
const std::ctype_base::mask m = libc_mask (mask, ch, locname);
return 0 != (m & mask);
}
wchar_t widen (wchar_t, char ch, const char *locname)
{
char curlocname [256];
std::strcpy (curlocname, std::setlocale (LC_CTYPE, 0));
if (0 == std::setlocale (LC_CTYPE, locname))
return UChar (ch);
wchar_t result;
#ifndef _RWSTD_NO_BTOWC
result = std::btowc (UChar (ch));
#elif !defined (_RWSTD_NO_MBTOWC)
if (1 != std::mbtowc (&result, &ch, 1))
result = wchar_t (WEOF);
#else
result = UChar (ch);
#endif // _RWSTD_NO_BTOWC, _RWSTD_NO_MBTOWC
if (locname)
std::setlocale (LC_CTYPE, curlocname);
return result;
}
char narrow (wchar_t ch, const char *locname)
{
char curlocname [256];
std::strcpy (curlocname, std::setlocale (LC_CTYPE, 0));
if (0 == std::setlocale (LC_CTYPE, locname))
return UChar (ch);
char result [MB_LEN_MAX];
#ifndef _RWSTD_NO_WCTOB
result [0] = std::wctob (ch);
#elif !defined (_RWSTD_NO_WCTOMB)
if (1 != std::wctomb (result, ch))
result [0] = '\377';
#else
result [0] = char (ch);
#endif // _RWSTD_NO_WCTOB, _RWSTD_NO_WCTOMB
if (locname)
std::setlocale (LC_CTYPE, curlocname);
return result [0];
}
bool cond3 (std::ctype_base::mask mask, wchar_t ch, const char *locname)
{
char curlocname [256];
std::strcpy (curlocname, std::setlocale (LC_CTYPE, 0));
if (0 == std::setlocale (LC_CTYPE, locname))
return false;
#ifndef _RWSTD_NO_WCTOB
const int byte = std::wctob (ch);
#elif !defined (_RWSTD_NO_WCTOMB)
char buf [MB_LEN_MAX];
const int byte = 1 == std::wctomb (buf, ch) ? buf [0] : EOF;
#else
const int byte = EOF;
#endif // _RWSTD_NO_WCTOB, _RWSTD_NO_WCTOMB
const bool result =
EOF == byte || !libc_is (mask, char (byte), 0) || libc_is (mask, ch, 0);
std::setlocale (LC_CTYPE, curlocname);
return result;
}
#endif // _RWSTD_NO_WCHAR_T
template <class charT>
void gen_str (charT *str, std::size_t size)
{
// generate a random string with the given size
// we do not attempt to check that the size is within the
// valid range for the string.
for (std::size_t i = 0; i < size; i++){
str [i] = UChar (std::rand () % UCHAR_MAX);
// only increment if we are not going to roll over
if (str [i] != charT (UCHAR_MAX - 1U))
++str [i];
}
str [size] = charT ();
_RWSTD_ASSERT (c_strlen (str) == size);
}
// The character map, as well as the source file generated below use
// Unicode literal strings for character symbolic names; the algorithm in
// localedef utility will generate correct databases even if the platform
// does not have a C library locale encoded with the character set we are
// creating.
void write_string (std::FILE *fp, const char *str)
{
// ASCII (ISO-646) character map definition
static const char* const base_chset [] = {
"<U0000>", "<U0001>", "<U0002>", "<U0003>", "<U0004>", "<U0005>",
"<U0006>", "<U0007>", "<U0008>", "<U0009>", "<U000a>", "<U000b>",
"<U000c>", "<U000d>", "<U000e>", "<U000f>", "<U0010>", "<U0011>",
"<U0012>", "<U0013>", "<U0014>", "<U0015>", "<U0016>", "<U0017>",
"<U0018>", "<U0019>", "<U001a>", "<U001b>", "<U001c>", "<U001d>",
"<U001e>", "<U001f>", "<U0020>", "<U0021>", "<U0022>", "<U0023>",
"<U0024>", "<U0025>", "<U0026>", "<U0027>", "<U0028>", "<U0029>",
"<U002a>", "<U002b>", "<U002c>", "<U002d>", "<U002e>", "<U002f>",
"<U0030>", "<U0031>", "<U0032>", "<U0033>", "<U0034>", "<U0035>",
"<U0036>", "<U0037>", "<U0038>", "<U0039>", "<U003a>", "<U003b>",
"<U003c>", "<U003d>", "<U003e>", "<U003f>", "<U0040>", "<U0041>",
"<U0042>", "<U0043>", "<U0044>", "<U0045>", "<U0046>", "<U0047>",
"<U0048>", "<U0049>", "<U004a>", "<U004b>", "<U004c>", "<U004d>",
"<U004e>", "<U004f>", "<U0050>", "<U0051>", "<U0052>", "<U0053>",
"<U0054>", "<U0055>", "<U0056>", "<U0057>", "<U0058>", "<U0059>",
"<U005a>", "<U005b>", "<U005c>", "<U005d>", "<U005e>", "<U005f>",
"<U0060>", "<U0061>", "<U0062>", "<U0063>", "<U0064>", "<U0065>",
"<U0066>", "<U0067>", "<U0068>", "<U0069>", "<U006a>", "<U006b>",
"<U006c>", "<U006d>", "<U006e>", "<U006f>", "<U0070>", "<U0071>",
"<U0072>", "<U0073>", "<U0074>", "<U0075>", "<U0076>", "<U0077>",
"<U0078>", "<U0079>", "<U007a>", "<U007b>", "<U007c>", "<U007d>",
"<U007e>", "<U007f>"
};
static const char* const supp_chset [] = {
// And a set of characters above 128, which have wide equivalents
// with values above 256
/* <U1000> */ "<U1000> \\xa0",
/* <U1001> */ "<U1001> \\xa1",
/* <U1002> */ "<U1002> \\xa2"
};
if (str) {
// write out `str' using the charmap above
for (; *str; ++str)
std::fprintf (fp, "%s", base_chset [UChar (*str)]);
}
else {
#ifndef _RWSTD_NO_NL_LANGINFO
const char* const codeset = nl_langinfo (CODESET);
std::fprintf (fp, "<code_set_name> \"%s\"\n", codeset);
std::fprintf (fp, "<mb_cur_max> 1\n");
std::fprintf (fp, "<mb_cur_min> 1\n");
std::fprintf (fp, "CHARMAP\n");
// write out the basic character set
for (unsigned i = 0; i < sizeof base_chset / sizeof *base_chset; ++i)
std::fprintf (fp, "%s \\x%02x\n", base_chset [i], i);
// write out the additional characters
for (unsigned j = 0; j < sizeof supp_chset / sizeof *supp_chset; ++j)
std::fprintf (fp, "%s\n", supp_chset [j]);
std::fprintf (fp, "END CHARMAP\n");
#endif // _RWSTD_NO_NL_LANGINFO
}
}
// invoke localedef to build a simple locale for testing
const char* create_locale ()
{
// only one locale is enough (avoid invoking localedef more than once)
static const char* locname;
if (locname)
return locname;
// set up RWSTD_LOCALE_ROOT and other environment variables
locale_root = rw_set_locale_root ();
if (0 == locale_root)
return 0;
// 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);
std::FILE *fout = std::fopen (srcfname, "w");
if (!fout) {
std::fprintf (stderr, "%s:%d: fopen(\"%s\", \"w\") failed\n",
__FILE__, __LINE__, srcfname);
return 0;
}
static const char text[] = {
"escape_char /\n"
"LC_CTYPE\n"
"# <A> <B> <C> MYANMAR LETTER KHA\n"
"upper <U0041>;<U0042>;<U0043>;<U1001>\n"
" <a> <b> <c> MYANMAR LETTER KA\n"
"lower <U0061>;<U0062>;<U0063>;<U1000>\n"
"alpha <U0061>;<U0062>;<U0063>;<U0041>;"
"<U0042>;<U0043>;<U1000>;<U1001>\n"
"digit <U0031>;<U0032>;<U0033>;<U1002>\n"
"space <U0020>\n"
"cntrl <U0000>\n"
" <!> <\">\n"
"punct <U0021>; <U0022>\n"
"graph <U0041>;<U0042>;<U0043>;<U0061>;<U0062>;<U0063>;"
"<U1000>;<U1001>;<U1002>;<U1003>;<U1004>;<U1005>;"
"<U0031>;<U0032>;<U0033>;<U0020>;<U0021>;<U0022>\n"
"print <U0041>;<U0042>;<U0043>;"
"<U0061>;<U0062>;<U0063>;"
"<U1000>;<U1001>;<U1002>;<U1003>;<U1004>;<U1005>;"
"<U0031>;<U0032>;<U0033>;<U0020>;<U0021>;<U0022>\n"
"xdigit <U0041>;<U0042>;<U0043>;<U0061>;<U0062>;"
"<U0063>;<U0031>;<U0032>;<U0033>\n"
"toupper (<U0061>,<U0041>);(<U0062>,<U0042>);"
"(<U0063>,<U0043>);(<U1000>,<U1001>)\n"
"tolower (<U0041>,<U0061>);(<U0042>,<U0062>);"
"(<U0043>,<U0063>);(<U1001>,<U1000>)\n"
"END LC_CTYPE\n"
};
std::fprintf (fout, "%s", text);
std::fclose (fout);
// create a temporary character map file
char cmfname [256];
std::sprintf (cmfname, "%s%scharmap.src", locale_root, SLASH);
fout = std::fopen (cmfname, "w");
if (!fout) {
std::fprintf (stderr, "%s:%d: fopen(\"%s\", \"w\") failed\n",
__FILE__, __LINE__, cmfname);
return 0;
}
write_string (fout, 0);
std::fclose (fout);
locname = "test-locale";
// process the locale definition file and character map
if (0 == rw_localedef ("-w", srcfname, cmfname, locname))
locname = 0;
return locname;
}
/**************************************************************************/
template <class charT>
void test_toupper (charT, const char *cname)
{
rw_info (0, 0, __LINE__, "std::ctype<%s>::toupper(%1$s)", cname);
BEGIN_LOCALE_LOOP (UCHAR_MAX, locname2, i) {
const charT ch = charT (i);
// set the global C locale to the locale name for the C library call
std::setlocale (LC_CTYPE, locname2);
const charT uch = libc_toupper (ch);
// set the global C locale to default to make sure
// the C++ library does not asume a set value
std::setlocale (LC_CTYPE, "");
// exercise toupper using ctype<>::toupper ()
rw_assert (uch == (ctp.toupper)(ch), 0, __LINE__,
"ctype<%s>::toupper(%{#lc}) == %{#lc}, got %{#lc} "
"in locale(%#s)",
cname, ch, uch, (ctp.toupper)(ch), locname2);
// exercise toupper using toupper (char, locale)
rw_assert (uch == (charT)(std::toupper)(ch, loc), 0, __LINE__,
"toupper<%s>(%{#lc}, locale(%#s)) == %{#lc}, got %{#lc}",
cname, ch, locname2, uch, (std::toupper)(ch, loc));
} END_LOCALE_LOOP (locname2);
}
template <class charT>
void test_libstd_toupper (charT, const char *cname,
const std::ctype<charT> &ct,
const char *locname)
{
rw_info (0, 0, __LINE__,
"std::ctype<%s>::toupper(%1$s) in locale(%#s)",
cname, locname);
int success;
#undef TEST
#define TEST(lower, upper) \
success = ct.widen (upper) == ct.toupper (ct.widen (lower)); \
rw_assert (success, 0, __LINE__, \
"ctype<%s>::toupper(%d) == %d, got %d", cname, \
lower, upper, ct.toupper((charT)lower)); \
TEST ('a', 'A');
TEST ('b', 'B');
TEST ('c', 'C');
if (sizeof(charT) > 1)
TEST ('\xa0', '\xa1');
#undef TEST
}
/**************************************************************************/
template <class charT>
void test_libstd (charT, const char *cname)
{
// invoke localedef to build a locale to test with
const char* const locname = create_locale ();
if (!rw_error (0 != locname, 0, __LINE__,
"failed to create a locale in %s", locale_root))
return;
const std::locale loc (locname);
const std::ctype<charT> &ct =
_STD_USE_FACET (std::ctype<charT>, loc);
ct._C_opts |= ct._C_use_libstd;
ct._C_opts &= ~ct._C_use_libc;
test_libstd_toupper (charT (), cname, ct, locname);
}
template <class charT>
void test_libc (charT, const char *cname)
{
test_toupper (charT (), cname);
}
/**************************************************************************/
template <class charT>
void run_test (charT, const char *cname)
{
if (0) {
// do a compile time only test on use_facet and has_facet
_STD_HAS_FACET (std::ctype_byname<charT>, std::locale ());
_STD_USE_FACET (std::ctype_byname<charT>, std::locale ());
}
test_libstd (charT (), cname);
test_libc (charT (), cname);
}
/**************************************************************************/
static int
run_test (int, char**)
{
run_test (char (), "char");
run_test (wchar_t (), "wchar_t");
return 0;
}
/**************************************************************************/
int main (int argc, char *argv[])
{
return rw_test (argc, argv, __FILE__,
"lib.category.ctype",
0 /* no comment */,
run_test,
"",
(void*)0 /* sentinel */);
}