/*************************************************************************** * * 21.cwchar.cpp - test exercising [lib.string.c.strings], Table 48 * * $Id: 21.cwchar.cpp 597425 2007-11-22 15:20:29Z faridz $ * *************************************************************************** * * 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 #include // for rw_any_t #include // 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 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 int fwprintf (FileT*, const WCharT*, ...) { return ncalls++; } template int fwscanf (FileT*, const WCharT*, ...) { return ncalls++; } template int wprintf (const WCharT* dummy, ...) { return ncalls++; } template int wscanf (const WCharT* dummy, ...) { return ncalls++; } template int swprintf (WCharT*, SizeT, const WCharT* dummy, ...) { return ncalls++; } template int swscanf (const WCharT*, const WCharT* dummy, ...) { return ncalls++; } template int vfwprintf (FileT*, const WCharT*, VAList) { return ncalls++; } template int vwprintf (const WCharT*, VAList) { return ncalls++; } template int vswprintf (WCharT*, SizeT, const WCharT*, VAList) { return ncalls++; } template wint_t fgetwc (FileT*) { return ncalls++; } template WCharT* fgetws (WCharT*, int, FileT*) { ncalls++; return 0; } template test_wint_t fputwc (WCharT, FileT*) { return ncalls++; } template int fputws (const WCharT*, FileT*) { return ncalls++; } template test_wint_t getwc (FileT*) { return ncalls++; } // cannot exercise // test_wint_t getwchar(); template test_wint_t putwc (WCharT, FileT*) { return ncalls++; } template test_wint_t putwchar (WCharT) { return ncalls++; } template test_wint_t ungetwc (WIntT, FileT*) { return ncalls++; } template int fwide (FileT*, int) { return ncalls++; } template double wcstod (const WCharT*, WCharT**) { return ncalls++; } template long wcstol (const WCharT*, WCharT**, int) { return ncalls++; } template unsigned long wcstoul (const WCharT*, WCharT**, int) { return ncalls++; } template WCharT* wcscpy (WCharT*, const WCharT*) { ncalls++; return 0; } template WCharT* wcsncpy (WCharT*, const WCharT*, SizeT) { ncalls++; return 0; } template WCharT* wcscat (WCharT*, const WCharT*) { ncalls++; return 0; } template WCharT* wcsncat (WCharT*, const WCharT*, SizeT) { ncalls++; return 0; } template int wcscmp (const WCharT*, const WCharT*) { return ncalls++; } template int wcscoll (const WCharT*, const WCharT*) { return ncalls++; } template int wcsncmp (const WCharT*, const WCharT*, SizeT) { return ncalls++; } template SizeT wcsxfrm (WCharT*, const WCharT*, SizeT) { return ncalls++; } template WCharT* wcschr (WCharT*, WCharT) { ncalls++; return 0; } template test_size_t wcscspn (const WCharT*, const WCharT*) { return ncalls++; } template WCharT* wcspbrk (WCharT*, const WCharT*) { ncalls++; return 0; } template WCharT* wcsrchr (WCharT*, WCharT) { ncalls++; return 0; } template test_size_t wcsspn (const WCharT*, const WCharT*) { return ncalls++; } template WCharT* wcsstr (WCharT*, const WCharT*) { ncalls++; return 0; } template WCharT* wcstok (WCharT*, const WCharT*, WCharT**) { ncalls++; return 0; } template test_size_t wcslen (const WCharT*) { return ncalls++; } template WCharT* wmemchr (WCharT*, WCharT, SizeT) { ncalls++; return 0; } template int wmemcmp (const WCharT*, const WCharT*, SizeT) { return ncalls++; } template WCharT* wmemcpy (WCharT*, const WCharT*, SizeT) { ncalls++; return 0; } template WCharT* wmemmove (WCharT*, const WCharT*, SizeT) { ncalls++; return 0; } template WCharT* wmemset (WCharT*, WCharT, SizeT) { ncalls++; return 0; } template SizeT wcsftime (WCharT*, SizeT, const WCharT*, const StructTm*) { return ncalls++; } template test_wint_t btowc (IntT) { return ncalls++; } template int wctob (WIntT) { return ncalls++; } template int mbsinit (const MBStateT*) { return ncalls++; } template SizeT mbrlen (const char*, SizeT, MBStateT*) { return ncalls++; } template SizeT mbrtowc (WCharT*, const char*, SizeT, MBStateT*) { return ncalls++; } template test_size_t wcrtomb (char*, WCharT, MBStateT*) { return ncalls++; } template SizeT mbsrtowcs (WCharT*, const char**, SizeT, MBStateT*) { return ncalls++; } template SizeT wcsrtombs (char*, const WCharT**, SizeT, MBStateT*) { return ncalls++; } template const WCharT* wcschr (const WCharT*, WCharT) { ncalls++; return 0; } template const WCharT* wcspbrk (const WCharT*, const WCharT*) { ncalls++; return 0; } template const WCharT* wcsrchr (const WCharT*, WCharT) { ncalls++; return 0; } template const WCharT* wcsstr (const WCharT*, const WCharT*) { ncalls++; return 0; } template const WCharT* wmemchr (const WCharT*, WCharT, SizeT) { ncalls++; return 0; } } // namespace std struct UniqType; #define GET_TYPE_NAME(T) \ template \ 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 // for va_list #include // for FILE, fopen() #include // for DEV_NUL #include // 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 ", 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); }