Author: sebor
Date: Mon Feb 20 16:36:19 2006
New Revision: 379300
URL: http://svn.apache.org/viewcvs?rev=379300&view=rev
Log:
2006-02-20 Anton Pevtsov <[EMAIL PROTECTED]>
STDCXX-4
* 25.libc.cpp: New test exercising lib.alg.c.library.
Added:
incubator/stdcxx/trunk/tests/algorithms/25.libc.cpp (with props)
Added: incubator/stdcxx/trunk/tests/algorithms/25.libc.cpp
URL:
http://svn.apache.org/viewcvs/incubator/stdcxx/trunk/tests/algorithms/25.libc.cpp?rev=379300&view=auto
==============================================================================
--- incubator/stdcxx/trunk/tests/algorithms/25.libc.cpp (added)
+++ incubator/stdcxx/trunk/tests/algorithms/25.libc.cpp Mon Feb 20 16:36:19 2006
@@ -0,0 +1,411 @@
+/***************************************************************************
+ *
+ * 25.libc.cpp - test exercising 25.4 [lib.alg.c.library]
+ *
+ * $Id$
+ *
+ ***************************************************************************
+ *
+ * Copyright (c) 1994-2005 Quovadx, Inc., acting through its Rogue Wave
+ * Software division. Licensed 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.
+ *
+ ***************************************************************************/
+
+#include <cstdlib> // for bsearch, qsort
+#include <csignal> // for signal
+#include <csetjmp> // for setjmp, longjmp
+
+#include <alg_test.h>
+#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 X*, x)).val_
+ - (*_RWSTD_STATIC_CAST (const X*, y)).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 X*, x)).val_
+ - (*_RWSTD_STATIC_CAST (const X*, y)).val_;
+ }
+}
+
+/**************************************************************************/
+
+// exrcises std::qqsort (25.4.4)
+static void
+test_qsort (int line,
+ const char *src,
+ std::size_t nsrc,
+ bool cxx)
+{
+ X* const xsrc = X::from_char (src, nsrc);
+ X* 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)
+{
+ X* const xsrc = X::from_char (src, nsrc, true); // must be sorted
+ RW_ASSERT (0 == nsrc || 0 != xsrc);
+
+ X key;
+ key.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 X* 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 X*, 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);
+}
Propchange: incubator/stdcxx/trunk/tests/algorithms/25.libc.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/stdcxx/trunk/tests/algorithms/25.libc.cpp
------------------------------------------------------------------------------
svn:keywords = Id