blob: deaed78e6ee403e8289d26ca812d64a5d6854727 [file] [log] [blame]
/***************************************************************************
*
* 21.cwchar.cpp - test exercising [lib.string.c.strings], Table 48
*
* $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 2004-2005 Rogue Wave Software.
*
**************************************************************************/
// used in the EVAL() macro below purely to make diagnostic messages
// more informative (i.e., to display which config macros are defined
// when a function isn't declared -- it may not make sense to declare
// some functions if they are not defined in the C library)
enum {
_RWSTD_NO_BTOWC = 1, _RWSTD_NO_BTOWC_IN_LIBC = 1,
_RWSTD_NO_FGETWC = 1, _RWSTD_NO_FGETWC_IN_LIBC = 1,
_RWSTD_NO_FGETWS = 1, _RWSTD_NO_FGETWS_IN_LIBC = 1,
_RWSTD_NO_FPUTWC = 1, _RWSTD_NO_FPUTWC_IN_LIBC = 1,
_RWSTD_NO_FPUTWS = 1, _RWSTD_NO_FPUTWS_IN_LIBC = 1,
_RWSTD_NO_FWIDE = 1, _RWSTD_NO_FWIDE_IN_LIBC = 1,
_RWSTD_NO_FWPRINTF = 1, _RWSTD_NO_FWPRINTF_IN_LIBC = 1,
_RWSTD_NO_FWSCANF = 1, _RWSTD_NO_FWSCANF_IN_LIBC = 1,
_RWSTD_NO_GETWC = 1, _RWSTD_NO_GETWC_IN_LIBC = 1,
_RWSTD_NO_GETWCHAR = 1, _RWSTD_NO_GETWCHAR_IN_LIBC = 1,
_RWSTD_NO_MBRLEN = 1, _RWSTD_NO_MBRLEN_IN_LIBC = 1,
_RWSTD_NO_MBRTOWC = 1, _RWSTD_NO_MBRTOWC_IN_LIBC = 1,
_RWSTD_NO_MBSINIT = 1, _RWSTD_NO_MBSINIT_IN_LIBC = 1,
_RWSTD_NO_MBSRTOWCS = 1, _RWSTD_NO_MBSRTOWCS_IN_LIBC = 1,
_RWSTD_NO_PUTWC = 1, _RWSTD_NO_PUTWC_IN_LIBC = 1,
_RWSTD_NO_PUTWCHAR = 1, _RWSTD_NO_PUTWCHAR_IN_LIBC = 1,
_RWSTD_NO_SWPRINTF = 1, _RWSTD_NO_SWPRINTF_IN_LIBC = 1,
_RWSTD_NO_SWSCANF = 1, _RWSTD_NO_SWSCANF_IN_LIBC = 1,
_RWSTD_NO_UNGETWC = 1, _RWSTD_NO_UNGETWC_IN_LIBC = 1,
_RWSTD_NO_VFWPRINTF = 1, _RWSTD_NO_VFWPRINTF_IN_LIBC = 1,
_RWSTD_NO_VSWPRINTF = 1, _RWSTD_NO_VSWPRINTF_IN_LIBC = 1,
_RWSTD_NO_VWPRINTF = 1, _RWSTD_NO_VWPRINTF_IN_LIBC = 1,
_RWSTD_NO_WCRTOMB = 1, _RWSTD_NO_WCRTOMB_IN_LIBC = 1,
_RWSTD_NO_WCSCAT = 1, _RWSTD_NO_WCSCAT_IN_LIBC = 1,
_RWSTD_NO_WCSCHR = 1, _RWSTD_NO_WCSCHR_IN_LIBC = 1,
_RWSTD_NO_WCSCMP = 1, _RWSTD_NO_WCSCMP_IN_LIBC = 1,
_RWSTD_NO_WCSCOLL = 1, _RWSTD_NO_WCSCOLL_IN_LIBC = 1,
_RWSTD_NO_WCSCPY = 1, _RWSTD_NO_WCSCPY_IN_LIBC = 1,
_RWSTD_NO_WCSCSPN = 1, _RWSTD_NO_WCSCSPN_IN_LIBC = 1,
_RWSTD_NO_WCSFTIME = 1, _RWSTD_NO_WCSFTIME_IN_LIBC = 1,
_RWSTD_NO_WCSLEN = 1, _RWSTD_NO_WCSLEN_IN_LIBC = 1,
_RWSTD_NO_WCSNCAT = 1, _RWSTD_NO_WCSNCAT_IN_LIBC = 1,
_RWSTD_NO_WCSNCMP = 1, _RWSTD_NO_WCSNCMP_IN_LIBC = 1,
_RWSTD_NO_WCSNCPY = 1, _RWSTD_NO_WCSNCPY_IN_LIBC = 1,
_RWSTD_NO_WCSPBRK = 1, _RWSTD_NO_WCSPBRK_IN_LIBC = 1,
_RWSTD_NO_WCSRCHR = 1, _RWSTD_NO_WCSRCHR_IN_LIBC = 1,
_RWSTD_NO_WCSRTOMBS = 1, _RWSTD_NO_WCSRTOMBS_IN_LIBC = 1,
_RWSTD_NO_WCSSPN = 1, _RWSTD_NO_WCSSPN_IN_LIBC = 1,
_RWSTD_NO_WCSSTR = 1, _RWSTD_NO_WCSSTR_IN_LIBC = 1,
_RWSTD_NO_WCSTOD = 1, _RWSTD_NO_WCSTOD_IN_LIBC = 1,
_RWSTD_NO_WCSTOK = 1, _RWSTD_NO_WCSTOK_IN_LIBC = 1,
_RWSTD_NO_WCSTOL = 1, _RWSTD_NO_WCSTOL_IN_LIBC = 1,
_RWSTD_NO_WCSTOUL = 1, _RWSTD_NO_WCSTOUL_IN_LIBC = 1,
_RWSTD_NO_WCSXFRM = 1, _RWSTD_NO_WCSXFRM_IN_LIBC = 1,
_RWSTD_NO_WCTOB = 1, _RWSTD_NO_WCTOB_IN_LIBC = 1,
_RWSTD_NO_WMEMCHR = 1, _RWSTD_NO_WMEMCHR_IN_LIBC = 1,
_RWSTD_NO_WMEMCMP = 1, _RWSTD_NO_WMEMCMP_IN_LIBC = 1,
_RWSTD_NO_WMEMCPY = 1, _RWSTD_NO_WMEMCPY_IN_LIBC = 1,
_RWSTD_NO_WMEMMOVE = 1, _RWSTD_NO_WMEMMOVE_IN_LIBC = 1,
_RWSTD_NO_WMEMSET = 1, _RWSTD_NO_WMEMSET_IN_LIBC = 1,
_RWSTD_NO_WPRINTF = 1, _RWSTD_NO_WPRINTF_IN_LIBC = 1,
_RWSTD_NO_WSCANF = 1, _RWSTD_NO_WSCANF_IN_LIBC = 1
};
/**************************************************************************/
#include <cwchar>
#include <rw_any.h> // for rw_any_t
#include <rw_driver.h> // for rw_test(), ...
/**************************************************************************/
// detect missing macros
const char* const missing_macros [] = {
#ifndef NULL
"NULL",
#else // if defined (NULL)
"",
#endif // NULL
#ifndef WCHAR_MIN
"WCHAR_MIN",
#else // if defined (WCHAR_MIN)
"",
#endif // WCHAR_MIN
#ifndef WCHAR_MAX
"WCHAR_MAX",
#else // if defined (WCHAR_MAX)
"",
#endif // WCHAR_MAX
#ifndef WEOF
"WEOF",
#else // if defined (WEOF)
"",
#endif // WEOF
0
};
/**************************************************************************/
// detect masking macros and undefine them to avoid compilation errors
// they might cause otherwise
const char* const masking_macros [] = {
#ifdef fwprintf
"fwprintf",
# undef fwprintf
#else
"",
#endif // fwprintf
#ifdef fwscanf
"fwscanf",
# undef fwscanf
#else
"",
#endif // fwscanf
#ifdef wprintf
"wprintf",
# undef wprintf
#else
"",
#endif // wprintf
#ifdef wscanf
"wscanf",
# undef wscanf
#else
"",
#endif // wscanf
#ifdef swprintf
"swprintf",
# undef swprintf
#else
"",
#endif // swprintf
#ifdef swscanf
"swscanf",
# undef swscanf
#else
"",
#endif // swscanf
#ifdef vfwprintf
"vfwprintf",
# undef vfwprintf
#else
"",
#endif // vfwprintf
#ifdef vwprintf
"vwprintf",
# undef vwprintf
#else
"",
#endif // vwprintf
#ifdef vswprintf
"vswprintf",
# undef vswprintf
#else
"",
#endif // vswprintf
#ifdef fgetwc
"fgetwc",
# undef fgetwc
#else
"",
#endif // fgetwc
#ifdef fgetws
"fgetws",
# undef fgetws
#else
"",
#endif // fgetws
#ifdef fputwc
"fputwc",
# undef fputwc
#else
"",
#endif // fputwc
#ifdef fputws
"fputws",
# undef fputws
#else
"",
#endif // fputws
#ifdef getwc
"getwc",
# undef getwc
#else
"",
#endif // getwc
#ifdef getwchar
"getwchar",
# undef getwchar
#else
"",
#endif // getwchar
#ifdef putwc
"putwc",
# undef putwc
#else
"",
#endif // putwc
#ifdef putwchar
"putwchar",
# undef putwchar
#else
"",
#endif // putwchar
#ifdef ungetwc
"ungetwc",
# undef ungetwc
#else
"",
#endif // ungetwc
#ifdef fwide
"fwide",
# undef fwide
#else
"",
#endif // fwide
#ifdef wcstod
"wcstod",
# undef wcstod
#else
"",
#endif // wcstod
#ifdef wcstol
"wcstol",
# undef wcstol
#else
"",
#endif // wcstol
#ifdef wcstoul
"wcstoul",
# undef wcstoul
#else
"",
#endif // wcstoul
#ifdef wcscpy
"wcscpy",
# undef wcscpy
#else
"",
#endif // wcscpy
#ifdef wcsncpy
"wcsncpy",
# undef wcsncpy
#else
"",
#endif // wcsncpy
#ifdef wcscat
"wcscat",
# undef wcscat
#else
"",
#endif // wcscat
#ifdef wcsncat
"wcsncat",
# undef wcsncat
#else
"",
#endif // wcsncat
#ifdef wcscmp
"wcscmp",
# undef wcscmp
#else
"",
#endif // wcscmp
#ifdef wcscoll
"wcscoll",
# undef wcscoll
#else
"",
#endif // wcscoll
#ifdef wcsncmp
"wcsncmp",
# undef wcsncmp
#else
"",
#endif // wcsncmp
#ifdef wcsxfrm
"wcsxfrm",
# undef wcsxfrm
#else
"",
#endif // wcsxfrm
#ifdef wcschr
"wcschr",
# undef wcschr
#else
"",
#endif // wcschr
#ifdef wcscspn
"wcscspn",
# undef wcscspn
#else
"",
#endif // wcscspn
#ifdef wcspbrk
"wcspbrk",
# undef wcspbrk
#else
"",
#endif // wcspbrk
#ifdef wcsrchr
"wcsrchr",
# undef wcsrchr
#else
"",
#endif // wcsrchr
#ifdef wcsspn
"wcsspn",
# undef wcsspn
#else
"",
#endif // wcsspn
#ifdef wcsstr
"wcsstr",
# undef wcsstr
#else
"",
#endif // wcsstr
#ifdef wcstok
"wcstok",
# undef wcstok
#else
"",
#endif // wcstok
#ifdef wcslen
"wcslen",
# undef wcslen
#else
"",
#endif // wcslen
#ifdef wmemchr
"wmemchr",
# undef wmemchr
#else
"",
#endif // wmemchr
#ifdef wmemcmp
"wmemcmp",
# undef wmemcmp
#else
"",
#endif // wmemcmp
#ifdef wmemcpy
"wmemcpy",
# undef wmemcpy
#else
"",
#endif // wmemcpy
#ifdef wmemmove
"wmemmove",
# undef wmemmove
#else
"",
#endif // wmemmove
#ifdef wmemset
"wmemset",
# undef wmemset
#else
"",
#endif // wmemset
#ifdef wcsftime
"wcsftime",
# undef wcsftime
#else
"",
#endif // wcsftime
#ifdef btowc
"btowc",
# undef btowc
#else
"",
#endif // btowc
#ifdef wctob
"wctob",
# undef wctob
#else
"",
#endif // wctob
#ifdef mbsinit
"mbsinit",
# undef mbsinit
#else
"",
#endif // mbsinit
#ifdef mbrlen
"mbrlen",
# undef mbrlen
#else
"",
#endif // mbrlen
#ifdef mbrtowc
"mbrtowc",
# undef mbrtowc
#else
"",
#endif // mbrtowc
#ifdef wcrtomb
"wcrtomb",
# undef wcrtomb
#else
"",
#endif // wcrtomb
#ifdef mbsrtowcs
"mbsrtowcs",
# undef mbsrtowcs
#else
"",
#endif // mbsrtowcs
#ifdef wcsrtombs
"wcsrtombs",
# undef wcsrtombs
#else
"",
#endif // wcsrtombs
0
};
/**************************************************************************/
static void
test_macros ()
{
rw_info (0, 0, 0, "checking for missing and masking macros");
for (unsigned i = 0; missing_macros [i]; ++i) {
rw_assert ('\0' == missing_macros [i][0], 0, __LINE__,
"macro %s not defined", missing_macros [i]);
}
for (unsigned i = 0; masking_macros [i]; ++i) {
#ifdef _RWSTD_STRICT_ANSI
rw_assert ('\0' == masking_macros [i][0], 0, __LINE__,
"masking macro %s unexpectedly defined",
masking_macros [i]);
#else
rw_warn ('\0' == masking_macros [i][0], 0, __LINE__,
"masking macro %s unexpectedly defined",
masking_macros [i]);
#endif
}
}
/**************************************************************************/
#ifndef _RWSTD_NO_NAMESPACE
// check types
namespace Fallback {
struct size_t {
int i_;
char dummy_ [256]; // make sure we're bigger than the real thing
// this (fake) size_t emulates a scalar type
size_t (int i): i_ (i) { }
operator int () const { return i_; }
};
struct mbstate_t {
char dummy_ [256]; // make sure we're bigger than the real thing
};
struct wint_t {
int i_;
char dummy_ [256]; // make sure we're bigger than the real thing
// this (fake) wint_t emulates a scalar type
wint_t (int i): i_ (i) { }
operator int () const { return i_; }
};
struct FILE;
struct tm;
} // namespace Fallback
namespace std {
// define test functions in namespace std to detect the presece
// or absence of the required types
namespace Nested {
using namespace Fallback;
// each test_xxx_t typedef aliases std::xxx_t if the corresponding
// type is defined in namespace std, or Fallback::xxx_t otherwise
typedef size_t test_size_t;
typedef mbstate_t test_mbstate_t;
typedef wint_t test_wint_t;
typedef tm test_tm;
} // namespace Nested
} // namespace std
typedef std::Nested::test_size_t test_size_t;
typedef std::Nested::test_mbstate_t test_mbstate_t;
typedef std::Nested::test_wint_t test_wint_t;
typedef std::Nested::test_tm test_tm;
template <class StructTm>
int tm_defined (const StructTm*) { return 1; }
int tm_defined (const Fallback::tm*) { return 0; }
const char std_name[] = "std";
static void
test_types ()
{
rw_info (0, 0, 0,
"types %s::size_t, %1$s::mbstate_t, %1$s::wint_t, and %1$s::tm",
std_name);
rw_assert (sizeof (test_size_t) != sizeof (Fallback::size_t), 0, 0,
"%s::size_t not defined", std_name);
rw_assert (sizeof (test_mbstate_t) != sizeof (Fallback::mbstate_t), 0, 0,
"%s::mbstate_t not defined", std_name);
rw_assert (sizeof (test_wint_t) != sizeof (Fallback::wint_t), 0, 0,
"%s::wint_t not defined", std_name);
rw_assert (tm_defined ((const test_tm*)0), 0, 0,
"%s::tm not defined", std_name);
}
#else // if defined (_RWSTD_NO_NAMESPACE)
const char std_name[] = "";
static void
test_types ()
{
rw_info (0, 0, 0,
"types %s::size_t, %1$s::mbstate_t, %1$s::wint_t, and %1$s::tm",
std_name);
rw_note (0, 0, 0, "_RWSTD_NO_NAMESPACE defined, cannot test");
}
#endif // _RWSTD_NO_NAMESPACE
/**************************************************************************/
int ncalls;
_RWSTD_NAMESPACE (std) {
template <class FileT, class WCharT>
int fwprintf (FileT*, const WCharT*, ...) { return ncalls++; }
template <class FileT, class WCharT>
int fwscanf (FileT*, const WCharT*, ...) { return ncalls++; }
template <class WCharT>
int wprintf (const WCharT* dummy, ...) { return ncalls++; }
template <class WCharT>
int wscanf (const WCharT* dummy, ...) { return ncalls++; }
template <class WCharT, class SizeT>
int swprintf (WCharT*, SizeT, const WCharT* dummy, ...) { return ncalls++; }
template <class WCharT>
int swscanf (const WCharT*, const WCharT* dummy, ...) { return ncalls++; }
template <class FileT, class WCharT, class VAList>
int vfwprintf (FileT*, const WCharT*, VAList) { return ncalls++; }
template <class WCharT, class VAList>
int vwprintf (const WCharT*, VAList) { return ncalls++; }
template <class WCharT, class SizeT, class VAList>
int vswprintf (WCharT*, SizeT, const WCharT*, VAList) { return ncalls++; }
template <class FileT>
wint_t fgetwc (FileT*) { return ncalls++; }
template <class WCharT, class FileT>
WCharT* fgetws (WCharT*, int, FileT*) { ncalls++; return 0; }
template <class WCharT, class FileT>
test_wint_t fputwc (WCharT, FileT*) { return ncalls++; }
template <class WCharT, class FileT>
int fputws (const WCharT*, FileT*) { return ncalls++; }
template <class FileT>
test_wint_t getwc (FileT*) { return ncalls++; }
// cannot exercise
// test_wint_t getwchar();
template <class WCharT, class FileT>
test_wint_t putwc (WCharT, FileT*) { return ncalls++; }
template <class WCharT>
test_wint_t putwchar (WCharT) { return ncalls++; }
template <class WIntT, class FileT>
test_wint_t ungetwc (WIntT, FileT*) { return ncalls++; }
template <class FileT>
int fwide (FileT*, int) { return ncalls++; }
template <class WCharT>
double wcstod (const WCharT*, WCharT**) { return ncalls++; }
template <class WCharT>
long wcstol (const WCharT*, WCharT**, int) { return ncalls++; }
template <class WCharT>
unsigned long wcstoul (const WCharT*, WCharT**, int) { return ncalls++; }
template <class WCharT>
WCharT* wcscpy (WCharT*, const WCharT*) { ncalls++; return 0; }
template <class WCharT, class SizeT>
WCharT* wcsncpy (WCharT*, const WCharT*, SizeT) { ncalls++; return 0; }
template <class WCharT>
WCharT* wcscat (WCharT*, const WCharT*) { ncalls++; return 0; }
template <class WCharT, class SizeT>
WCharT* wcsncat (WCharT*, const WCharT*, SizeT) { ncalls++; return 0; }
template <class WCharT>
int wcscmp (const WCharT*, const WCharT*) { return ncalls++; }
template <class WCharT>
int wcscoll (const WCharT*, const WCharT*) { return ncalls++; }
template <class WCharT, class SizeT>
int wcsncmp (const WCharT*, const WCharT*, SizeT) { return ncalls++; }
template <class WCharT, class SizeT>
SizeT wcsxfrm (WCharT*, const WCharT*, SizeT) { return ncalls++; }
template <class WCharT>
WCharT* wcschr (WCharT*, WCharT) { ncalls++; return 0; }
template <class WCharT>
test_size_t wcscspn (const WCharT*, const WCharT*) { return ncalls++; }
template <class WCharT>
WCharT* wcspbrk (WCharT*, const WCharT*) { ncalls++; return 0; }
template <class WCharT>
WCharT* wcsrchr (WCharT*, WCharT) { ncalls++; return 0; }
template <class WCharT>
test_size_t wcsspn (const WCharT*, const WCharT*) { return ncalls++; }
template <class WCharT>
WCharT* wcsstr (WCharT*, const WCharT*) { ncalls++; return 0; }
template <class WCharT>
WCharT* wcstok (WCharT*, const WCharT*, WCharT**) { ncalls++; return 0; }
template <class WCharT>
test_size_t wcslen (const WCharT*) { return ncalls++; }
template <class WCharT, class SizeT>
WCharT* wmemchr (WCharT*, WCharT, SizeT) { ncalls++; return 0; }
template <class WCharT, class SizeT>
int wmemcmp (const WCharT*, const WCharT*, SizeT) { return ncalls++; }
template <class WCharT, class SizeT>
WCharT* wmemcpy (WCharT*, const WCharT*, SizeT) { ncalls++; return 0; }
template <class WCharT, class SizeT>
WCharT* wmemmove (WCharT*, const WCharT*, SizeT) { ncalls++; return 0; }
template <class WCharT, class SizeT>
WCharT* wmemset (WCharT*, WCharT, SizeT) { ncalls++; return 0; }
template <class WCharT, class SizeT, class StructTm>
SizeT wcsftime (WCharT*, SizeT, const WCharT*, const StructTm*)
{ return ncalls++; }
template <class IntT>
test_wint_t btowc (IntT) { return ncalls++; }
template <class WIntT>
int wctob (WIntT) { return ncalls++; }
template <class MBStateT>
int mbsinit (const MBStateT*) { return ncalls++; }
template <class SizeT, class MBStateT>
SizeT mbrlen (const char*, SizeT, MBStateT*) { return ncalls++; }
template <class WCharT, class SizeT, class MBStateT>
SizeT mbrtowc (WCharT*, const char*, SizeT, MBStateT*) { return ncalls++; }
template <class WCharT, class MBStateT>
test_size_t wcrtomb (char*, WCharT, MBStateT*) { return ncalls++; }
template <class WCharT, class SizeT, class MBStateT>
SizeT mbsrtowcs (WCharT*, const char**, SizeT, MBStateT*) { return ncalls++; }
template <class WCharT, class SizeT, class MBStateT>
SizeT wcsrtombs (char*, const WCharT**, SizeT, MBStateT*) { return ncalls++; }
template <class WCharT>
const WCharT* wcschr (const WCharT*, WCharT) { ncalls++; return 0; }
template <class WCharT>
const WCharT* wcspbrk (const WCharT*, const WCharT*) { ncalls++; return 0; }
template <class WCharT>
const WCharT* wcsrchr (const WCharT*, WCharT) { ncalls++; return 0; }
template <class WCharT>
const WCharT* wcsstr (const WCharT*, const WCharT*) { ncalls++; return 0; }
template <class WCharT, class SizeT>
const WCharT* wmemchr (const WCharT*, WCharT, SizeT) { ncalls++; return 0; }
} // namespace std
struct UniqType;
#define GET_TYPE_NAME(T) \
template <class Type> \
const char* get_type_name (T, Type) { \
return rw_any_t (Type ()).type_name (); \
} \
const char* get_type_name (T, T) { return 0; } \
typedef void unused_typedef /* allow a terminating semicolon */
GET_TYPE_NAME (short);
GET_TYPE_NAME (unsigned short);
GET_TYPE_NAME (int);
GET_TYPE_NAME (unsigned int);
GET_TYPE_NAME (long);
GET_TYPE_NAME (unsigned long);
GET_TYPE_NAME (double);
#ifndef _RWSTD_NO_LONG_LONG
GET_TYPE_NAME (_RWSTD_LONG_LONG);
GET_TYPE_NAME (unsigned _RWSTD_LONG_LONG);
#endif
#ifndef _RWSTD_NO_NATIVE_WCHAR_T
GET_TYPE_NAME (wchar_t);
#endif
GET_TYPE_NAME (wchar_t*);
GET_TYPE_NAME (const wchar_t*);
#define EVAL2(macro) !!(macro - 1)
#define EVAL(name) EVAL2 (_RWSTD_NO_ ## name + 0)
#define EVAL_IN_LIBC(name) EVAL (name ## _IN_LIBC)
static int rw_opt_no_macros; // for --no-macros
static int rw_opt_no_types; // for --no-types
static int rw_opt_no_functions; // for --no-functions
static int rw_opt_no_overloads; // for --no-overloads
void test_functions ()
{
#define TEST(T, fun, args, macro, overload) \
do { \
cstr = (str = array); \
wcstr = (wstr = warray); \
*str = '\0'; *wstr = L'\0'; \
ncalls = 0; \
rw_info (0, 0, __LINE__, "%s::%s(" \
"%{?}%{:}/* %{?}non-%{;}const overload */%{;})", \
std_name, #fun, overload < 0, 0 == overload); \
const char* const return_type_name = \
get_type_name ((T)0, std::fun args); \
rw_warn (0 == ncalls, 0, __LINE__, \
"%s::%s(" \
"%{?}%{:}/* %{?}non-%{;}const overload */%{;}) " \
"not declared (_RWSTD_NO_%s = %d, " \
"_RWSTD_NO_%s_IN_LIBC = %d)", \
std_name, #fun, overload < 0, 0 == overload, \
#macro, EVAL (macro), #macro, EVAL_IN_LIBC (macro)); \
if (0 == ncalls) \
rw_assert (0 == return_type_name, 0, __LINE__, "%s::%s(" \
"%{?}%{:}/* %{?}non-%{;}const overload */%{;}) " \
"expected return type %s, got %s", \
std_name, #fun, overload < 0, 0 == overload, \
#T, return_type_name); \
} while (0)
char array [4] = "";
char* str = array;
const char* cstr = array;
wchar_t warray [32] = L"";
/* */ wchar_t* /* */ wstr = warray;
const wchar_t* /* */ wcstr = warray;
test_size_t size = 0;
const UniqType* const uniqptr = 0;
const test_wint_t wi = 0;
const int i = 0;
TEST (int, wprintf, (L""), WPRINTF, -1);
TEST (int, wprintf, (L"", uniqptr), WPRINTF, -1);
TEST (int, wscanf, (L""), WSCANF, -1);
TEST (int, wscanf, (L"", uniqptr), WSCANF, -1);
TEST (int, swprintf, (wstr, size, L""), SWPRINTF, -1);
TEST (int, swprintf, (wstr, size, L"", uniqptr), SWPRINTF, -1);
TEST (int, swscanf, (wstr, L""), SWSCANF, -1);
TEST (int, swscanf, (wstr, L"", uniqptr), SWSCANF, -1);
TEST (double, wcstod, (L"", &wstr), WCSTOD, -1);
TEST (long, wcstol, (L"", &wstr, i), WCSTOL, -1);
TEST (unsigned long, wcstoul, (L"", &wstr, i), WCSTOUL, -1);
TEST (wchar_t*, wcscpy, (wstr, L""), WCSCPY, -1);
TEST (wchar_t*, wcsncpy, (wstr, L"", size), WCSNCPY, -1);
TEST (wchar_t*, wcscat, (wstr, L""), WCSCAT, -1);
TEST (int, wcscmp, (wstr, L""), WCSCMP, -1);
TEST (int, wcsncmp, (wstr, L"", size), WCSNCMP, -1);
TEST (test_size_t, wcsxfrm, (wstr, L"", size), WCSXFRM, -1);
TEST (test_size_t, wcscspn, (L"", L""), WCSCSPN, -1);
TEST (test_size_t, wcsspn, (L"", L""), WCSSPN, -1);
TEST (wchar_t*, wcstok, (wstr, L"", &wstr), WCSTOK, -1);
TEST (test_size_t, wcslen, (L""), WCSLEN, -1);
TEST (int, wmemcmp, (L"", L"", size), WMEMCMP, -1);
TEST (wchar_t*, wmemcpy, (wstr, L"", size), WMEMCPY, -1);
TEST (wchar_t*, wmemmove, (wstr, L"", size), WMEMMOVE, -1);
TEST (wchar_t*, wmemset, (wstr, L'\0', size), WMEMSET, -1);
// const commented to prevent MSVC 7.0 error:
// error C2147: 'tm_buf' : const automatic array must be fully initialized
/* const */ int tm_buf [16] = { 0 };
const test_tm* tmb = (const test_tm*)&tm_buf;
#ifdef _MSC_VER
// prevent MSVC parameter validation error:
// "Zero length output buffer passed to strftime"
size = 1;
#endif
TEST (test_size_t, wcsftime, (wstr, size, L"", tmb), WCSFTIME, -1);
#ifdef _MSC_VER
// restore size
size = 0;
#endif
TEST (test_wint_t, btowc, (i), BTOWC, -1);
TEST (int, wctob, (wi), WCTOB, -1);
test_mbstate_t state = test_mbstate_t ();
TEST (int, mbsinit, (&state), MBSINIT, -1);
TEST (test_size_t, mbrlen, ("", size, &state), MBRLEN, -1);
TEST (test_size_t, mbrtowc, (wstr, "", size, &state), MBRTOWC, -1);
TEST (test_size_t, wcrtomb, (str, L'\0', &state), WCRTOMB, -1);
TEST (test_size_t, mbsrtowcs, (wstr, &cstr, size, &state), MBSRTOWCS, -1);
TEST (test_size_t, wcsrtombs, (str, &wcstr, size, &state), WCSRTOMBS, -1);
if (rw_opt_no_overloads) {
// exercise the traditional C (const-incorrect) functions
TEST (/* const */ wchar_t*, wmemchr, (L"", L'\0', size), WMEMCHR, -1);
TEST (/* const */ wchar_t*, wcspbrk, (wcstr, L""), WCSPBRK, -1);
TEST (/* const */ wchar_t*, wcsrchr, (L"", L'\0'), WCSRCHR, -1);
TEST (/* const */ wchar_t*, wcsstr, (L"", L""), WCSSTR, -1);
TEST (/* const */ wchar_t*, wcschr, (L"", L'\0'), WCSCHR, -1);
}
else {
// exercise const and non-const overloads that C++ replaces
// the traditional C functions with
TEST (const wchar_t*, wmemchr, (L"", L'\0', size), WMEMCHR, 1);
TEST (wchar_t*, wmemchr, (wstr, L'\0', size), WMEMCHR, 0);
TEST (const wchar_t*, wcspbrk, (wcstr, L""), WCSPBRK, 1);
TEST (wchar_t*, wcspbrk, (wstr, L""), WCSPBRK, 0);
TEST (const wchar_t*, wcsrchr, (L"", L'\0'), WCSRCHR, 1);
TEST (wchar_t*, wcsrchr, (wstr, L'\0'), WCSRCHR, 0);
TEST (const wchar_t*, wcsstr, (L"", L""), WCSSTR, 1);
TEST (wchar_t*, wcsstr, (wstr, L""), WCSSTR, 0);
TEST (const wchar_t*, wcschr, (L"", L'\0'), WCSCHR, 1);
TEST (wchar_t*, wcschr, (wstr, L'\0'), WCSCHR, 0);
}
}
/**************************************************************************/
// included here to avoid namespace pollution
#include <cstdarg> // for va_list
#include <cstdio> // for FILE, fopen()
#include <rw_file.h> // for DEV_NUL
#include <rw_printf.h> // for rw_stdout
namespace std {
// define test types in namespace std to detect the presece
// or absence of the required types
namespace Nested {
using namespace Fallback;
typedef FILE test_FILE;
typedef va_list test_va_list;
} // namespace Nested
} // namespace std
typedef std::Nested::test_FILE test_FILE;
typedef std::Nested::test_va_list test_va_list;
void test_file_functions (int dummy, ...)
{
char array [4] = "";
/* */ char* str = array;
const char* cstr = array;
wchar_t warray [32] = L"";
/* */ wchar_t* /* */ wstr = warray;
const wchar_t* /* */ wcstr = warray;
const int i = 0;
const UniqType* const uniqptr = 0;
const test_wint_t wi = 0;
// cast rw_stdout to FILE* via void* since the latter may be
// an incomplete type and casts between two non-void pointers
// require that the types be complete (in case they are related
// by inheritance and need to be adjusted)
test_FILE* const fp = (test_FILE*)std::fopen (DEV_NULL, "w");
test_va_list va;
va_start (va, dummy);
// call fwide() first before any prior output since 7.19.2, p5
// of C99 prohibits wide character I/O functions from being called
// on a byte-oriented stream
TEST (int, fwide, (fp, i), FWIDE, -1);
TEST (int, fwprintf, (fp, L""), FWPRINTF, -1);
TEST (int, fwprintf, (fp, L"", uniqptr), FWPRINTF, -1);
TEST (int, fwscanf, (fp, L""), FWSCANF, -1);
TEST (int, fwscanf, (fp, L"", uniqptr), FWSCANF, -1);
TEST (int, vfwprintf, (fp, L"", va), VFWPRINTF, -1);
TEST (test_wint_t, fgetwc, (fp), FGETWC, -1);
TEST (wchar_t*, fgetws, (wstr, i, fp), FGETWS, -1);
TEST (test_wint_t, fputwc, (L'\0', fp), FPUTWC, -1);
TEST (int, fputws, (L"", fp), FPUTWS, -1);
TEST (test_wint_t, getwc, (fp), GETWC, -1);
TEST (test_wint_t, putwc, (L'\0', fp), PUTWC, -1);
TEST (test_wint_t, ungetwc, (wi, fp), UNGETWC, -1);
_RWSTD_UNUSED (str);
_RWSTD_UNUSED (cstr);
_RWSTD_UNUSED (wcstr);
}
/**************************************************************************/
static int
run_test (int, char**)
{
if (rw_opt_no_macros)
rw_note (0, 0, 0, "test for macros disabled");
else
test_macros ();
if (rw_opt_no_types)
rw_note (0, 0, 0, "test for types disabled");
else
test_types ();
if (rw_opt_no_functions)
rw_note (0, 0, 0, "test for functions disabled");
else {
test_functions ();
test_file_functions (0 /* dummy */);
}
return 0;
}
/**************************************************************************/
int main (int argc, char *argv[])
{
return rw_test (argc, argv, __FILE__,
"lib.c.strings",
"header <cwchar>",
run_test,
"|-no-macros#0-1 "
"|-no-types#0-1 "
"|-no-functions#0-1 "
"|-no-overloads#0-1 ",
&rw_opt_no_macros,
&rw_opt_no_types,
&rw_opt_no_functions,
&rw_opt_no_overloads);
}