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 */);
}

Reply via email to