first commit
This commit is contained in:
420
extern/stdcxx/4.2.1/tests/algorithms/25.libc.cpp
vendored
Normal file
420
extern/stdcxx/4.2.1/tests/algorithms/25.libc.cpp
vendored
Normal file
@@ -0,0 +1,420 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 25.libc.cpp - test exercising 25.4 [lib.alg.c.library]
|
||||
*
|
||||
* $Id: 25.libc.cpp 510970 2007-02-23 14:57:45Z 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 1994-2006 Rogue Wave Software.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include <cstdlib> // for bsearch, qsort
|
||||
#include <csignal> // for signal
|
||||
#include <csetjmp> // for setjmp, longjmp
|
||||
|
||||
#include <alg_test.h>
|
||||
#include <rw_value.h> // for UserClass
|
||||
#include <driver.h> // for rw_test()
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
// used as a special value in comp below
|
||||
static int global[] = { 0, 0 };
|
||||
|
||||
|
||||
extern "C" {
|
||||
|
||||
static std::jmp_buf jmp_env;
|
||||
|
||||
// SIGABRT handler
|
||||
static void handle_ABRT (int)
|
||||
{
|
||||
// jump outta here to prevent abort() from trying too hard...
|
||||
std::longjmp (jmp_env, 1);
|
||||
}
|
||||
|
||||
|
||||
static int c_comp (const void *x, const void *y)
|
||||
{
|
||||
#ifndef _RWSTD_NO_EXCEPTIONS
|
||||
|
||||
// verify that a thrown exception can be caught
|
||||
if (x >= global && x < global + sizeof global / sizeof *global)
|
||||
throw x;
|
||||
|
||||
#endif // _RWSTD_NO_EXCEPTIONS
|
||||
|
||||
return (*_RWSTD_STATIC_CAST (const UserClass*, x)).data_.val_
|
||||
- (*_RWSTD_STATIC_CAST (const UserClass*, y)).data_.val_;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C++" {
|
||||
|
||||
static int cxx_comp (const void *x, const void *y)
|
||||
{
|
||||
#ifndef _RWSTD_NO_EXCEPTIONS
|
||||
|
||||
// verify that a thrown exception can be caught
|
||||
if (x >= global && x < global + sizeof global / sizeof *global)
|
||||
throw x;
|
||||
|
||||
#endif // _RWSTD_NO_EXCEPTIONS
|
||||
|
||||
return (*_RWSTD_STATIC_CAST (const UserClass*, x)).data_.val_
|
||||
- (*_RWSTD_STATIC_CAST (const UserClass*, y)).data_.val_;
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
// exrcises std::qqsort (25.4.4)
|
||||
static void
|
||||
test_qsort (int line,
|
||||
const char *src,
|
||||
std::size_t nsrc,
|
||||
bool cxx)
|
||||
{
|
||||
UserClass* const xsrc = UserClass::from_char (src, nsrc);
|
||||
UserClass* const xsrc_end = xsrc + nsrc;
|
||||
RW_ASSERT (0 == nsrc || 0 != xsrc);
|
||||
|
||||
if (cxx)
|
||||
std::qsort (xsrc, nsrc, sizeof *xsrc, cxx_comp);
|
||||
else
|
||||
std::qsort (xsrc, nsrc, sizeof *xsrc, c_comp);
|
||||
|
||||
bool success = is_sorted_lt (xsrc, xsrc_end);
|
||||
rw_assert (success, 0, line,
|
||||
"line %d: extern \"C%{?}++%{;}\" qsort (\"%s\", ...) ==> "
|
||||
"\"%{X=*.*}\" not sorted",
|
||||
__LINE__, cxx, src, int (nsrc), -1, xsrc);
|
||||
|
||||
delete[] xsrc;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
// exrcises std::qsort (25.4.4 Note)
|
||||
static void
|
||||
test_qsort_exception (int line,
|
||||
int *src,
|
||||
std::size_t nsrc,
|
||||
bool cxx)
|
||||
{
|
||||
#ifndef _RWSTD_NO_EXCEPTIONS
|
||||
|
||||
// install a SIGABRT handler in case libc can't throw
|
||||
// exceptions and aborts instead (e.g., glibc/gcc)
|
||||
std::signal (SIGABRT, handle_ABRT);
|
||||
|
||||
bool success = false;
|
||||
try {
|
||||
if (0 == setjmp (jmp_env)) {
|
||||
if (cxx)
|
||||
std::qsort (src, nsrc, sizeof *src, cxx_comp);
|
||||
else
|
||||
std::qsort (src, nsrc, sizeof *src, c_comp);
|
||||
}
|
||||
else {
|
||||
// prevent double assertion
|
||||
success = true;
|
||||
rw_assert (false, 0, line,
|
||||
"line %d: extern \"C%{?}++%{;}\" qsort() aborted "
|
||||
"on exception", __LINE__, cxx);
|
||||
}
|
||||
}
|
||||
catch (const void* x) {
|
||||
success = x >= src && x < src + nsrc;
|
||||
}
|
||||
catch (...) {
|
||||
}
|
||||
|
||||
rw_assert (success, 0, line,
|
||||
"line %d: extern \"C%{?}++%{;}\" qsort() failed to propagate "
|
||||
"exception", __LINE__, cxx);
|
||||
|
||||
#else // if defined (_RWSTD_NO_EXCEPTIONS)
|
||||
|
||||
_RWSTD_UNUSED (line);
|
||||
_RWSTD_UNUSED (src);
|
||||
_RWSTD_UNUSED (nsrc);
|
||||
_RWSTD_UNUSED (key);
|
||||
_RWSTD_UNUSED (cxx);
|
||||
|
||||
#endif // _RWSTD_NO_EXCEPTIONS
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
// exrcises std::bsearch (25.4.3)
|
||||
static void
|
||||
test_bsearch (int line,
|
||||
const char *src,
|
||||
std::size_t nsrc,
|
||||
const char key_val,
|
||||
std::size_t res,
|
||||
bool cxx)
|
||||
{
|
||||
UserClass* const xsrc = UserClass::from_char (src, nsrc,
|
||||
true); // must be sorted
|
||||
RW_ASSERT (0 == nsrc || 0 != xsrc);
|
||||
|
||||
UserClass key;
|
||||
key.data_.val_ = key_val;
|
||||
|
||||
const void* result = cxx ?
|
||||
std::bsearch (&key, xsrc, nsrc, sizeof *xsrc, cxx_comp)
|
||||
: std::bsearch (&key, xsrc, nsrc, sizeof *xsrc, c_comp);
|
||||
|
||||
const UserClass* exp_res = res == _RWSTD_SIZE_MAX ? 0 : xsrc + res;
|
||||
|
||||
bool success = result == exp_res;
|
||||
rw_assert (success, 0, line,
|
||||
"line %d: extern \"C%{?}++%{;}\" bsearch (\"%s\", %#c, ...) "
|
||||
"== %p, got %p, difference is %td elements",
|
||||
__LINE__, cxx, src, key_val, result, exp_res,
|
||||
_RWSTD_STATIC_CAST (const UserClass*, result) - exp_res);
|
||||
|
||||
delete[] xsrc;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
// exrcises std::bsearch (25.4.4 Note)
|
||||
static void
|
||||
test_bsearch_exception (int line,
|
||||
const int *src,
|
||||
std::size_t nsrc,
|
||||
const int *key,
|
||||
bool cxx)
|
||||
{
|
||||
#ifndef _RWSTD_NO_EXCEPTIONS
|
||||
|
||||
// install a SIGABRT handler in case libc can't throw
|
||||
// exceptions and aborts instead (e.g., glibc/gcc)
|
||||
std::signal (SIGABRT, handle_ABRT);
|
||||
|
||||
bool success = false;
|
||||
try {
|
||||
if (0 == setjmp (jmp_env)) {
|
||||
if (cxx)
|
||||
std::bsearch (key, src, nsrc, sizeof *src, cxx_comp);
|
||||
else
|
||||
std::bsearch (key, src, nsrc, sizeof *src, c_comp);
|
||||
}
|
||||
else {
|
||||
// prevent double assertion
|
||||
success = true;
|
||||
rw_assert (false, 0, line,
|
||||
"line %d: extern \"C%{?}++%{;}\" bsearch() aborted "
|
||||
"on exception", __LINE__, cxx);
|
||||
}
|
||||
}
|
||||
catch (const void* x) {
|
||||
success = x >= src && x < src + nsrc;
|
||||
}
|
||||
catch (...) {
|
||||
}
|
||||
|
||||
rw_assert (success, 0, line,
|
||||
"line %d: extern \"C%{?}++%{;}\" bsearch() failed to propagate "
|
||||
"exception", __LINE__, cxx);
|
||||
|
||||
#else // if defined (_RWSTD_NO_EXCEPTIONS)
|
||||
|
||||
_RWSTD_UNUSED (line);
|
||||
_RWSTD_UNUSED (src);
|
||||
_RWSTD_UNUSED (nsrc);
|
||||
_RWSTD_UNUSED (key);
|
||||
_RWSTD_UNUSED (cxx);
|
||||
|
||||
#endif // _RWSTD_NO_EXCEPTIONS
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
static int rw_opt_no_c; // --no-c
|
||||
static int rw_opt_no_cxx; // --no-cpp
|
||||
static int rw_opt_no_bsearch; // --no-bsearch
|
||||
static int rw_opt_no_qsort; // --no-qsort
|
||||
static int rw_opt_no_exceptions; // --no-exceptions
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
static void
|
||||
test_qsort (bool cxx)
|
||||
{
|
||||
rw_info (0, 0, 0,
|
||||
"extern \"C%{?}++%{;}\" qsort (void*, size_t, size_t, "
|
||||
"int (*compar)(const void*, const void*))", cxx);
|
||||
|
||||
#define TEST(src) \
|
||||
test_qsort (__LINE__, src, sizeof src - 1, cxx)
|
||||
|
||||
TEST ("a");
|
||||
|
||||
TEST ("ba");
|
||||
TEST ("cba");
|
||||
TEST ("dcba");
|
||||
TEST ("edcba");
|
||||
TEST ("fedcba");
|
||||
TEST ("gfedcba");
|
||||
TEST ("hgfedcba");
|
||||
TEST ("ihgfedcba");
|
||||
TEST ("jihgfedcba");
|
||||
|
||||
TEST ("ab");
|
||||
TEST ("abc");
|
||||
TEST ("abcd");
|
||||
TEST ("abcde");
|
||||
TEST ("abcdef");
|
||||
TEST ("abcdefg");
|
||||
TEST ("abcdefgh");
|
||||
TEST ("abcdefghi");
|
||||
TEST ("abcdefghij");
|
||||
|
||||
TEST ("aa");
|
||||
TEST ("aabb");
|
||||
TEST ("bbccaa");
|
||||
TEST ("ddbbccaa");
|
||||
TEST ("ddeebbccaa");
|
||||
|
||||
TEST ("aaaaaaaaaa");
|
||||
TEST ("ababababab");
|
||||
TEST ("bababababa");
|
||||
|
||||
#undef TEST
|
||||
|
||||
if (rw_opt_no_exceptions) {
|
||||
rw_note (0, 0, 0, "extern \"C%{?}++%{;}\" qsort() exceptions tests "
|
||||
"disabled", cxx);
|
||||
}
|
||||
else {
|
||||
test_qsort_exception (__LINE__, global,
|
||||
sizeof global / sizeof *global, cxx);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
static void
|
||||
test_bsearch (bool cxx)
|
||||
{
|
||||
rw_info (0, 0, 0,
|
||||
"extern \"C%{?}++%{;}\" bsearch (const void*, const void*, "
|
||||
"size_t, size_t, int (*compar)(const void*, const void*))",
|
||||
cxx);
|
||||
|
||||
#define TEST(src, key, res) \
|
||||
test_bsearch (__LINE__, src, sizeof src - 1, key, \
|
||||
std::size_t (res), cxx)
|
||||
|
||||
TEST ("", 'a', -1);
|
||||
TEST ("a", 'a', 0);
|
||||
TEST ("a", 'b', -1);
|
||||
TEST ("b", 'a', -1);
|
||||
|
||||
TEST ("ab", 'a', 0);
|
||||
TEST ("ac", 'a', 0);
|
||||
TEST ("ab", 'b', 1);
|
||||
TEST ("bc", 'a', -1);
|
||||
|
||||
TEST ("acegi", 'i', 4);
|
||||
TEST ("acegi", 'b', -1);
|
||||
TEST ("acegi", 'g', 3);
|
||||
TEST ("acegi", 'f', -1);
|
||||
TEST ("acegi", 'e', 2);
|
||||
TEST ("acegi", 'j', -1);
|
||||
TEST ("acegi", 'c', 1);
|
||||
TEST ("bdfhj", 'a', -1);
|
||||
|
||||
TEST ("abcdefghij", 'a', 0);
|
||||
TEST ("abcdefghij", 'c', 2);
|
||||
TEST ("abcdefghij", 'f', 5);
|
||||
TEST ("abcdefghij", 'h', 7);
|
||||
TEST ("abcdefghij", 'j', 9);
|
||||
|
||||
#undef TEST
|
||||
|
||||
if (rw_opt_no_exceptions) {
|
||||
rw_note (0, 0, 0, "extern \"C%{?}++%{;}\" bsearch() exceptions "
|
||||
"tests disabled", cxx);
|
||||
}
|
||||
else {
|
||||
test_bsearch_exception (__LINE__, global,
|
||||
sizeof global / sizeof *global, global, cxx);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
static void
|
||||
test_libc (bool cxx)
|
||||
{
|
||||
if (rw_opt_no_qsort)
|
||||
rw_note (0, 0, 0, "qsort test disabled");
|
||||
else
|
||||
test_qsort (cxx);
|
||||
|
||||
if (rw_opt_no_bsearch)
|
||||
rw_note (0, 0, 0, "bsearch test disabled");
|
||||
else
|
||||
test_bsearch (cxx);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
static int
|
||||
run_test (int, char*[])
|
||||
{
|
||||
if (rw_opt_no_c)
|
||||
rw_note (0, 0, 0, "tests of extern \"C\" cfunctions disabled");
|
||||
else
|
||||
test_libc (false);
|
||||
|
||||
if (rw_opt_no_cxx)
|
||||
rw_note (0, 0, 0, "tests of extern \"C++\" functions disabled");
|
||||
else
|
||||
test_libc (true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
return rw_test (argc, argv, __FILE__,
|
||||
"lib.alg.c.library",
|
||||
0 /* no comment */,
|
||||
run_test,
|
||||
"|-no-extern_c# "
|
||||
"|-no-extern_cxx# "
|
||||
"|-no-bsearch# "
|
||||
"|-no-qsort# "
|
||||
"|-no-exceptions",
|
||||
&rw_opt_no_c,
|
||||
&rw_opt_no_cxx,
|
||||
&rw_opt_no_bsearch,
|
||||
&rw_opt_no_qsort,
|
||||
&rw_opt_no_exceptions);
|
||||
}
|
||||
Reference in New Issue
Block a user