From: Benjamin Kosnik Date: Wed, 7 Jun 2006 14:58:24 +0000 (+0000) Subject: util: New directory. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3416d7cd4ba7b81b97d3b75a97abd7977b417e22;p=gcc.git util: New directory. 2006-06-06 Benjamin Kosnik * testsuite/util: New directory. * testsuite/testsuite_hooks.cc: Move to util sub-directory. * testsuite/testsuite_abi_check.cc: Same. * testsuite/testsuite_abi.cc: Same. * testsuite/testsuite_tr1.h: Same. * testsuite/testsuite_io.h: Same. * testsuite/testsuite_iterators.h: Same. * testsuite/testsuite_allocator.cc: Same. * testsuite/testsuite_allocator.h: Same. * testsuite/testsuite_hooks.h: Same. * testsuite/testsuite_character.cc: Same. * testsuite/testsuite_abi.h: Same. * testsuite/testsuite_character.h: Same. * testsuite/testsuite_visualization.h: Same. * testsuite/testsuite_performance.h: Same. * testsuite/testsuite_shared.cc: Same. * testsuite/testsuite_common_types.h: Same. * testsuite/lib/libstdc++.exp (v3-build_support): Adjust paths. * testsuite/libstdc++-abi/abi.exp: Same. * testsuite/libstdc++-dg/conformance.exp: Remove any files in the utilities subdirectory from the list of test cases. * scripts/testsuite_flags.in (build-includes): Adjust path for testsuite includes. * scripts/create_testsuite_files (dlist): Don't let utility files creep into the testsuite_files list. From-SVN: r114466 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 43405002096..3c7a84b24d5 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,33 @@ +2006-06-06 Benjamin Kosnik + + * testsuite/util: New directory. + * testsuite/testsuite_hooks.cc: Move to util sub-directory. + * testsuite/testsuite_abi_check.cc: Same. + * testsuite/testsuite_abi.cc: Same. + * testsuite/testsuite_tr1.h: Same. + * testsuite/testsuite_io.h: Same. + * testsuite/testsuite_iterators.h: Same. + * testsuite/testsuite_allocator.cc: Same. + * testsuite/testsuite_allocator.h: Same. + * testsuite/testsuite_hooks.h: Same. + * testsuite/testsuite_character.cc: Same. + * testsuite/testsuite_abi.h: Same. + * testsuite/testsuite_character.h: Same. + * testsuite/testsuite_visualization.h: Same. + * testsuite/testsuite_performance.h: Same. + * testsuite/testsuite_shared.cc: Same. + * testsuite/testsuite_common_types.h: Same. + + * testsuite/lib/libstdc++.exp (v3-build_support): Adjust paths. + * testsuite/libstdc++-abi/abi.exp: Same. + * testsuite/libstdc++-dg/conformance.exp: Remove any files in the + utilities subdirectory from the list of test cases. + + * scripts/testsuite_flags.in (build-includes): Adjust path for + testsuite includes. + * scripts/create_testsuite_files (dlist): Don't let utility files + creep into the testsuite_files list. + 2006-06-06 Paolo Carlini * include/tr1/random (mersenne_twister<>::operator==, diff --git a/libstdc++-v3/scripts/create_testsuite_files b/libstdc++-v3/scripts/create_testsuite_files index d5305236140..74b2455d061 100755 --- a/libstdc++-v3/scripts/create_testsuite_files +++ b/libstdc++-v3/scripts/create_testsuite_files @@ -32,9 +32,7 @@ cd $srcdir # This is the ugly version of "everything but the current directory". It's # what has to happen when find(1) doesn't support -mindepth, or -xtype. dlist=`echo [0-9][0-9]*` -for d in [a-z]*; do - test -d $d && dlist="$dlist $d" -done +dlist="$dlist backward demangle ext performance thread tr1" find $dlist "(" -type f -o -type l ")" -name "*.cc" -print > $tmp.01 find $dlist "(" -type f -o -type l ")" -name "*.c" -print > $tmp.02 cat $tmp.01 $tmp.02 | sort > $tmp.1 diff --git a/libstdc++-v3/scripts/testsuite_flags.in b/libstdc++-v3/scripts/testsuite_flags.in index 15a4d8599e6..aa4466a5326 100755 --- a/libstdc++-v3/scripts/testsuite_flags.in +++ b/libstdc++-v3/scripts/testsuite_flags.in @@ -35,7 +35,7 @@ case ${query} in ;; --build-includes) INCLUDES="-nostdinc++ @GLIBCXX_INCLUDES@ - -I${SRC_DIR}/include/backward -I${SRC_DIR}/testsuite" + -I${SRC_DIR}/include/backward -I${SRC_DIR}/testsuite/util" echo ${INCLUDES} ;; --install-cxx) diff --git a/libstdc++-v3/testsuite/lib/libstdc++.exp b/libstdc++-v3/testsuite/lib/libstdc++.exp index 6272027bac3..e98397ba77c 100644 --- a/libstdc++-v3/testsuite/lib/libstdc++.exp +++ b/libstdc++-v3/testsuite/lib/libstdc++.exp @@ -411,7 +411,7 @@ proc v3-build_support { } { set object_file [file rootname $f].o # Compile with "-w" so that warnings issued by the compiler # do not prevent compilation. - if { [v3_target_compile $srcdir/$f $object_file "object" \ + if { [v3_target_compile $srcdir/util/$f $object_file "object" \ [list "incdir=$srcdir" "additional_flags=-w"]] != "" } { error "could not compile $f" @@ -427,7 +427,7 @@ proc v3-build_support { } { set object_file [file rootname $f].so # Compile with "-w" so that warnings issued by the compiler # do not prevent compilation. - if { [v3_target_compile $srcdir/$f $object_file "sharedlib" \ + if { [v3_target_compile $srcdir/util/$f $object_file "sharedlib" \ [list "incdir=$srcdir" "additional_flags=-w -shared -fPIC -DPIC"]] != "" } { error "could not compile $f" diff --git a/libstdc++-v3/testsuite/libstdc++-abi/abi.exp b/libstdc++-v3/testsuite/libstdc++-abi/abi.exp index fac9ed25ee3..b3f5b3b59be 100644 --- a/libstdc++-v3/testsuite/libstdc++-abi/abi.exp +++ b/libstdc++-v3/testsuite/libstdc++-abi/abi.exp @@ -32,7 +32,7 @@ remote_exec "build" "$srcdir/../scripts/extract_symvers" \ [list "../src/.libs/libstdc++.so" "current_symbols.txt"] # Build the abi_check program. -if { [v3_target_compile "$srcdir/testsuite_abi_check.cc" "abi_check" \ +if { [v3_target_compile "$srcdir/util/testsuite_abi_check.cc" "abi_check" \ "executable" [list "additional_flags=-w"]] != "" } { error "could not compile testsuite_abi_check.cc" } diff --git a/libstdc++-v3/testsuite/libstdc++-dg/conformance.exp b/libstdc++-v3/testsuite/libstdc++-dg/conformance.exp index 21bc3c1b915..a05ad3adb3f 100644 --- a/libstdc++-v3/testsuite/libstdc++-dg/conformance.exp +++ b/libstdc++-v3/testsuite/libstdc++-dg/conformance.exp @@ -53,11 +53,14 @@ if {[info exists tests_file] && [file exists $tests_file]} { } else { # Find directories that might have tests. set subdirs [glob "$srcdir/\[0-9\]\[0-9\]*"] - foreach d [glob "$srcdir/\[a-z\]*"] { - if {[file isdirectory $d]} { - lappend subdirs $d - } - } + lappend subdirs "$srcdir/backward" + lappend subdirs "$srcdir/demangle" + lappend subdirs "$srcdir/ext" + lappend subdirs "$srcdir/performance" + lappend subdirs "$srcdir/tr1" + lappend subdirs "$srcdir/thread" + verbose "subdirs are $subdirs" + # Find all the tests. foreach s $subdirs { set subdir_tests [find $s *.cc] @@ -75,6 +78,7 @@ if {[info exists tests_file] && [file exists $tests_file]} { continue } # Filter out: + # 0. utilities, other parts of the testing infrastructure. # 1. interactive tests. # 2. performance tests. # 3. wchar_t tests, if not supported. diff --git a/libstdc++-v3/testsuite/testsuite_abi.cc b/libstdc++-v3/testsuite/testsuite_abi.cc deleted file mode 100644 index 6ed559f3e73..00000000000 --- a/libstdc++-v3/testsuite/testsuite_abi.cc +++ /dev/null @@ -1,530 +0,0 @@ -// -*- C++ -*- - -// Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. - -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2, or (at -// your option) any later version. - -// This library is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this library; see the file COPYING. If not, write to -// the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, -// MA 02110-1301, USA. - -// As a special exception, you may use this file as part of a free -// software library without restriction. Specifically, if other files -// instantiate templates or use macros or inline functions from this -// file, or you compile this file and link it with other files to -// produce an executable, this file does not by itself cause the -// resulting executable to be covered by the GNU General Public -// License. This exception does not however invalidate any other -// reasons why the executable file might be covered by the GNU General -// Public License. - -// Benjamin Kosnik - -#include "testsuite_abi.h" -#include -#include -#include - -using namespace std; - -void -symbol::init(string& data) -{ - const char delim = ':'; - const char version_delim = '@'; - const string::size_type npos = string::npos; - string::size_type n = 0; - - // Set the type. - if (data.find("FUNC") == 0) - type = symbol::function; - else if (data.find("OBJECT") == 0) - type = symbol::object; - - n = data.find_first_of(delim); - if (n != npos) - data.erase(data.begin(), data.begin() + n + 1); - - // Iff object, get size info. - if (type == symbol::object) - { - n = data.find_first_of(delim); - if (n != npos) - { - string size(data.begin(), data.begin() + n); - istringstream iss(size); - int x; - iss >> x; - if (!iss.fail()) - size = x; - data.erase(data.begin(), data.begin() + n + 1); - } - } - - // Set the name and raw_name. - raw_name = string(data.begin(), data.end()); - n = data.find_first_of(version_delim); - if (n != npos) - { - // Found version string. - name = string(data.begin(), data.begin() + n); - n = data.find_last_of(version_delim); - data.erase(data.begin(), data.begin() + n + 1); - - // Set version name. - version_name = data; - } - else - { - // No versioning info. - name = string(data.begin(), data.end()); - version_status = symbol::none; - } - - // Set the demangled name. - demangled_name = demangle(name); -} - -void -symbol::print() const -{ - const char tab = '\t'; - cout << name << endl; - - if (demangled_name != name) - cout << demangled_name << endl; - - string vers; - switch (version_status) - { - case none: - vers = "none"; - break; - case compatible: - vers = "compatible"; - break; - case incompatible: - vers = "incompatible"; - break; - case unversioned: - vers = "unversioned"; - break; - default: - vers = ""; - } - cout << "version status: " << vers << endl; - - if (version_name.size() - && (version_status == compatible || version_status == incompatible)) - cout << version_name << endl; - - string type_string; - switch (type) - { - case function: - type_string = "function"; - break; - case object: - type_string = "object"; - break; - case uncategorized: - type_string = "uncategorized"; - break; - default: - type_string = ""; - } - cout << "type: " << type_string << endl; - - if (type == object) - cout << "type size: " << size << endl; - - string status_string; - switch (status) - { - case added: - status_string = "added"; - break; - case subtracted: - status_string = "subtracted"; - break; - case undesignated: - status_string = "undesignated"; - break; - default: - status_string = ""; - } - cout << "status: " << status_string << endl; - - cout << endl; -} - - -bool -check_version(symbol& test, bool added) -{ - // Construct list of compatible versions. - typedef std::vector compat_list; - static compat_list known_versions; - if (known_versions.empty()) - { - // NB: First version here must be the default version for this - // version of DT_SONAME. - known_versions.push_back("GLIBCXX_3.4"); - known_versions.push_back("GLIBCXX_3.4.1"); - known_versions.push_back("GLIBCXX_3.4.2"); - known_versions.push_back("GLIBCXX_3.4.3"); - known_versions.push_back("GLIBCXX_3.4.4"); - known_versions.push_back("GLIBCXX_3.4.5"); - known_versions.push_back("GLIBCXX_3.4.6"); - known_versions.push_back("GLIBCXX_3.4.7"); - known_versions.push_back("GLIBCXX_3.4.8"); - known_versions.push_back("GLIBCXX_3.4.9"); - known_versions.push_back("GLIBCXX_LDBL_3.4"); - known_versions.push_back("GLIBCXX_LDBL_3.4.7"); - known_versions.push_back("CXXABI_1.3"); - known_versions.push_back("CXXABI_1.3.1"); - known_versions.push_back("CXXABI_LDBL_1.3"); - } - compat_list::iterator begin = known_versions.begin(); - compat_list::iterator end = known_versions.end(); - - // Check for compatible version. - if (test.version_name.size()) - { - compat_list::iterator it1 = find(begin, end, test.version_name); - compat_list::iterator it2 = find(begin, end, test.name); - if (it1 != end) - test.version_status = symbol::compatible; - else - test.version_status = symbol::incompatible; - - // Check that added symbols aren't added in the base version. - if (added && test.version_name == known_versions[0]) - test.version_status = symbol::incompatible; - - // Check for weak label. - if (it1 == end && it2 == end) - test.version_status = symbol::incompatible; - - // Check that - // GLIBCXX_3.4 - // GLIBCXX_3.4.5 - // version as compatible - // XXX - } - else - { - if (added) - { - // New version labels are ok. The rest are not. - compat_list::iterator it2 = find(begin, end, test.name); - if (it2 != end) - test.version_status = symbol::compatible; - else - test.version_status = symbol::incompatible; - } - } - return test.version_status == symbol::compatible; -} - -bool -check_compatible(symbol& lhs, symbol& rhs, bool verbose) -{ - bool ret = true; - const char tab = '\t'; - - // Check to see if symbol_objects are compatible. - if (lhs.type != rhs.type) - { - ret = false; - if (verbose) - cout << tab << "incompatible types" << endl; - } - - if (lhs.name != rhs.name) - { - ret = false; - if (verbose) - cout << tab << "incompatible names" << endl; - } - - if (lhs.size != rhs.size) - { - ret = false; - if (verbose) - { - cout << tab << "incompatible sizes" << endl; - cout << tab << lhs.size << endl; - cout << tab << rhs.size << endl; - } - } - - if (lhs.version_name != rhs.version_name - && !check_version(lhs) && !check_version(rhs)) - { - ret = false; - if (verbose) - { - cout << tab << "incompatible versions" << endl; - cout << tab << lhs.version_name << endl; - cout << tab << rhs.version_name << endl; - } - } - - if (verbose) - cout << endl; - - return ret; -} - - -bool -has_symbol(const string& mangled, const symbols& s) throw() -{ - const symbol_names& names = s.first; - symbol_names::const_iterator i = find(names.begin(), names.end(), mangled); - return i != names.end(); -} - -symbol& -get_symbol(const string& mangled, const symbols& s) -{ - const symbol_names& names = s.first; - symbol_names::const_iterator i = find(names.begin(), names.end(), mangled); - if (i != names.end()) - { - symbol_objects objects = s.second; - return objects[mangled]; - } - else - { - ostringstream os; - os << "get_symbol failed for symbol " << mangled; - __throw_logic_error(os.str().c_str()); - } -} - -void -examine_symbol(const char* name, const char* file) -{ - try - { - symbols s = create_symbols(file); - symbol& sym = get_symbol(name, s); - sym.print(); - } - catch(...) - { __throw_exception_again; } -} - -int -compare_symbols(const char* baseline_file, const char* test_file, - bool verbose) -{ - // Input both lists of symbols into container. - symbols baseline = create_symbols(baseline_file); - symbols test = create_symbols(test_file); - symbol_names& baseline_names = baseline.first; - symbol_objects& baseline_objects = baseline.second; - symbol_names& test_names = test.first; - symbol_objects& test_objects = test.second; - - // Sanity check results. - const symbol_names::size_type baseline_size = baseline_names.size(); - const symbol_names::size_type test_size = test_names.size(); - if (!baseline_size || !test_size) - { - cerr << "Problems parsing the list of exported symbols." << endl; - exit(2); - } - - // Sort out names. - // Assuming baseline_names, test_names are both unique w/ no duplicates. - // - // The names added to missing_names are baseline_names not found in - // test_names - // -> symbols that have been deleted. - // - // The names added to added_names are test_names not in - // baseline_names - // -> symbols that have been added. - symbol_names shared_names; - symbol_names missing_names; - symbol_names added_names = test_names; - for (size_t i = 0; i < baseline_size; ++i) - { - string what(baseline_names[i]); - symbol_names::iterator end = added_names.end(); - symbol_names::iterator it = find(added_names.begin(), end, what); - if (it != end) - { - // Found. - shared_names.push_back(what); - added_names.erase(it); - } - else - missing_names.push_back(what); - } - - // Check missing names for compatibility. - typedef pair symbol_pair; - vector incompatible; - const symbol_names::size_type missing_size = missing_names.size(); - for (size_t j = 0; j < missing_size; ++j) - { - symbol& base = baseline_objects[missing_names[j]]; - base.status = symbol::subtracted; - incompatible.push_back(symbol_pair(base, base)); - } - - // Check shared names for compatibility. - const symbol_names::size_type shared_size = shared_names.size(); - for (size_t k = 0; k < shared_size; ++k) - { - symbol& base = baseline_objects[shared_names[k]]; - symbol& test = test_objects[shared_names[k]]; - test.status = symbol::existing; - if (!check_compatible(base, test)) - incompatible.push_back(symbol_pair(base, test)); - } - - // Check added names for compatibility. - const symbol_names::size_type added_size = added_names.size(); - for (size_t l = 0; l < added_size; ++l) - { - symbol& test = test_objects[added_names[l]]; - test.status = symbol::added; - if (!check_version(test, true)) - incompatible.push_back(symbol_pair(test, test)); - } - - // Report results. - if (verbose && added_names.size()) - { - cout << endl << added_names.size() << " added symbols " << endl; - for (size_t j = 0; j < added_names.size() ; ++j) - { - cout << j << endl; - test_objects[added_names[j]].print(); - } - } - - if (verbose && missing_names.size()) - { - cout << endl << missing_names.size() << " missing symbols " << endl; - for (size_t j = 0; j < missing_names.size() ; ++j) - { - cout << j << endl; - baseline_objects[missing_names[j]].print(); - } - } - - if (verbose && incompatible.size()) - { - cout << endl << incompatible.size() << " incompatible symbols " << endl; - for (size_t j = 0; j < incompatible.size() ; ++j) - { - // First, print index. - cout << j << endl; - - // Second, report name. - symbol& base = incompatible[j].first; - symbol& test = incompatible[j].second; - test.print(); - - // Second, report reason or reasons incompatible. - check_compatible(base, test, true); - } - } - - cout << "\n\t\t=== libstdc++-v3 check-abi Summary ===" << endl; - cout << endl; - cout << "# of added symbols:\t\t " << added_names.size() << endl; - cout << "# of missing symbols:\t\t " << missing_names.size() << endl; - cout << "# of incompatible symbols:\t " << incompatible.size() << endl; - cout << endl; - cout << "using: " << baseline_file << endl; - - return !(missing_names.size() || incompatible.size()); -} - - -symbols -create_symbols(const char* file) -{ - symbols s; - ifstream ifs(file); - if (ifs.is_open()) - { - // Organize file data into container of symbol objects, and a - // container of mangled names without versioning information. - symbol_names& names = s.first; - symbol_objects& objects = s.second; - const string empty; - string line = empty; - while (getline(ifs, line).good()) - { - symbol tmp; - tmp.init(line); - objects[tmp.name] = tmp; - names.push_back(tmp.name); - line = empty; - } - } - else - { - ostringstream os; - os << "create_symbols failed for file " << file; - __throw_runtime_error(os.str().c_str()); - } - return s; -} - - -const char* -demangle(const std::string& mangled) -{ - const char* name; - if (mangled[0] != '_' || mangled[1] != 'Z') - { - // This is not a mangled symbol, thus has "C" linkage. - name = mangled.c_str(); - } - else - { - // Use __cxa_demangle to demangle. - int status = 0; - name = abi::__cxa_demangle(mangled.c_str(), 0, 0, &status); - if (!name) - { - switch (status) - { - case 0: - name = "error code = 0: success"; - break; - case -1: - name = "error code = -1: memory allocation failure"; - break; - case -2: - name = "error code = -2: invalid mangled name"; - break; - case -3: - name = "error code = -3: invalid arguments"; - break; - default: - name = "error code unknown - who knows what happened"; - } - } - } - return name; -} - diff --git a/libstdc++-v3/testsuite/testsuite_abi.h b/libstdc++-v3/testsuite/testsuite_abi.h deleted file mode 100644 index 935d95bd1fe..00000000000 --- a/libstdc++-v3/testsuite/testsuite_abi.h +++ /dev/null @@ -1,128 +0,0 @@ -// -*- C++ -*- - -// Copyright (C) 2004, 2005 Free Software Foundation, Inc. - -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2, or (at -// your option) any later version. - -// This library is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this library; see the file COPYING. If not, write to -// the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, -// MA 02110-1301, USA. - -// As a special exception, you may use this file as part of a free -// software library without restriction. Specifically, if other files -// instantiate templates or use macros or inline functions from this -// file, or you compile this file and link it with other files to -// produce an executable, this file does not by itself cause the -// resulting executable to be covered by the GNU General Public -// License. This exception does not however invalidate any other -// reasons why the executable file might be covered by the GNU General -// Public License. - -// Benjamin Kosnik - -#include -#include -#include -#include -#include - -// Encapsulates symbol characteristics. -struct symbol -{ - enum category { function, object, uncategorized }; - enum designation { existing, added, subtracted, undesignated }; - enum version { none, compatible, incompatible, unversioned }; - enum compatibility - { - compat_type = 1, - compat_name = 2, - compat_size = 4, - compat_version = 8 - }; - - category type; - std::string name; - std::string raw_name; // Name with versioning info still attached. - std::string demangled_name; - int size; - std::string version_name; - version version_status; - designation status; - - symbol() - : type(uncategorized), size(0), version_status(unversioned), - status(undesignated) { } - - symbol(const symbol& other) - : type(other.type), name(other.name), demangled_name(other.demangled_name), - size(other.size), version_name(other.version_name), - version_status(other.version_status), status(other.status) { } - - void - print() const; - - void - init(std::string& data); -}; - -typedef __gnu_cxx::hash_map symbol_objects; - -typedef std::deque symbol_names; - -typedef std::pair symbols; - - -// Check. -bool -check_version(symbol& test, bool added = false); - -bool -check_compatible(symbol& lhs, symbol& rhs, bool verbose = false); - - -// Examine. -bool -has_symbol(const std::string& mangled, const symbols& list) throw(); - -symbol& -get_symbol(const std::string& mangled, const symbols& list); - -extern "C" void -examine_symbol(const char* name, const char* file); - -extern "C" int -compare_symbols(const char* baseline_file, const char* test_file, bool verb); - - -// Util. -symbols -create_symbols(const char* file); - -const char* -demangle(const std::string& mangled); - - -// Specialization. -namespace __gnu_cxx -{ - using namespace std; - - template<> - struct hash - { - size_t operator()(const string& s) const - { - const collate& c = use_facet >(locale::classic()); - return c.hash(s.c_str(), s.c_str() + s.size()); - } - }; -} diff --git a/libstdc++-v3/testsuite/testsuite_abi_check.cc b/libstdc++-v3/testsuite/testsuite_abi_check.cc deleted file mode 100644 index 12e882a436f..00000000000 --- a/libstdc++-v3/testsuite/testsuite_abi_check.cc +++ /dev/null @@ -1,95 +0,0 @@ -// -*- C++ -*- - -// Copyright (C) 2004 Free Software Foundation, Inc. - -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2, or (at -// your option) any later version. - -// This library is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this library; see the file COPYING. If not, write to -// the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, -// MA 02110-1301, USA. - -// As a special exception, you may use this file as part of a free -// software library without restriction. Specifically, if other files -// instantiate templates or use macros or inline functions from this -// file, or you compile this file and link it with other files to -// produce an executable, this file does not by itself cause the -// resulting executable to be covered by the GNU General Public -// License. This exception does not however invalidate any other -// reasons why the executable file might be covered by the GNU General -// Public License. - -// Benjamin Kosnik -// Blame subsequent hacks on Loren J. Rittle , Phil -// Edwards , and a cast of dozens at libstdc++@gcc.gnu.org. - -#include "testsuite_abi.h" -#include -#include // for access(2) - -int -main(int argc, char** argv) -{ - using namespace std; - - // Get arguments. (Heading towards getopt_long, I can feel it.) - string argv1 = argc > 1 ? argv[1] : ""; - if (argv1 == "--help" || argc < 4) - { - cerr << "usage: abi_check --check current baseline\n" - " --check-verbose current baseline\n" - " --examine symbol current\n" - " --help\n" - "\n" - "All arguments are string literals.\n" - "CURRENT is a file generated byextract_symvers.\n" - "BASELINE is a file from config/abi.\n" - "SYMBOL is a mangled name.\n" - << endl; - exit(1); - } - - if (argv1.find("--check") != string::npos) - { - bool verbose = false; - if (argv1 == "--check-verbose") - verbose = true; - - // Quick sanity/setup check for arguments. - const char* test_file = argv[2]; - const char* baseline_file = argv[3]; - if (access(test_file, R_OK) != 0) - { - cerr << "Cannot read symbols file " << test_file - << ", did you forget to build first?" << endl; - exit(1); - } - if (access(baseline_file, R_OK) != 0) - { - cerr << "Cannot read baseline file " << baseline_file << endl; - exit(1); - } - if (!compare_symbols(baseline_file, test_file, verbose)) - exit (1); - } - - if (argv1 == "--examine") - { - const char* file = argv[3]; - if (access(file, R_OK) != 0) - { - cerr << "Cannot read symbol file " << file << endl; - exit(1); - } - examine_symbol(argv[2], file); - } - return 0; -} diff --git a/libstdc++-v3/testsuite/testsuite_allocator.cc b/libstdc++-v3/testsuite/testsuite_allocator.cc deleted file mode 100644 index 66968720555..00000000000 --- a/libstdc++-v3/testsuite/testsuite_allocator.cc +++ /dev/null @@ -1,60 +0,0 @@ -// -*- C++ -*- -// Testing allocator for the C++ library testsuite. -// -// Copyright (C) 2002, 2003 Free Software Foundation, Inc. -// -// This file is part of the GNU ISO C++ Library. This library is free -// software; you can redistribute it and/or modify it under the -// terms of the GNU General Public License as published by the -// Free Software Foundation; either version 2, or (at your option) -// any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, -// USA. -// -// As a special exception, you may use this file as part of a free software -// library without restriction. Specifically, if other files instantiate -// templates or use macros or inline functions from this file, or you compile -// this file and link it with other files to produce an executable, this -// file does not by itself cause the resulting executable to be covered by -// the GNU General Public License. This exception does not however -// invalidate any other reasons why the executable file might be covered by -// the GNU General Public License. - -#include -#include - -namespace __gnu_test -{ - allocation_tracker::size_type allocation_tracker::allocationTotal_ = 0; - allocation_tracker::size_type allocation_tracker::deallocationTotal_ = 0; - int allocation_tracker::constructCount_ = 0; - int allocation_tracker::destructCount_ = 0; - - bool - check_construct_destroy(const char* tag, int expected_c, int expected_d) - { - if (allocation_tracker::constructCount() == expected_c && - allocation_tracker::destructCount() == expected_d) - return true; - - else { - std::cerr << tag << ": " - << " construct = " << allocation_tracker::constructCount() - << " (should be " << expected_c << ")," - << " destroy = " << allocation_tracker::destructCount() - << " (should be " << expected_d << ")" - << std::endl; - return false; - } - } - -}; // namespace __cxx_test - diff --git a/libstdc++-v3/testsuite/testsuite_allocator.h b/libstdc++-v3/testsuite/testsuite_allocator.h deleted file mode 100644 index 0ea1215e3b4..00000000000 --- a/libstdc++-v3/testsuite/testsuite_allocator.h +++ /dev/null @@ -1,443 +0,0 @@ -// -*- C++ -*- -// Testing allocator for the C++ library testsuite. -// -// Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. -// -// This file is part of the GNU ISO C++ Library. This library is free -// software; you can redistribute it and/or modify it under the -// terms of the GNU General Public License as published by the -// Free Software Foundation; either version 2, or (at your option) -// any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, -// USA. -// -// As a special exception, you may use this file as part of a free software -// library without restriction. Specifically, if other files instantiate -// templates or use macros or inline functions from this file, or you compile -// this file and link it with other files to produce an executable, this -// file does not by itself cause the resulting executable to be covered by -// the GNU General Public License. This exception does not however -// invalidate any other reasons why the executable file might be covered by -// the GNU General Public License. - -// This file provides an test instrumentation allocator that can be -// used to verify allocation functionality of standard library -// containers. 2002.11.25 smw - -#ifndef _GLIBCXX_TESTSUITE_ALLOCATOR_H -#define _GLIBCXX_TESTSUITE_ALLOCATOR_H - -#include -#include -#include -#include - -namespace -{ - bool new_called = false; - bool delete_called = false; -}; - -namespace __gnu_test -{ - class allocation_tracker - { - public: - typedef std::size_t size_type; - - static void* - allocate(size_type blocksize) - { - allocationTotal_ += blocksize; - return ::operator new(blocksize); - } - - static void - construct() { constructCount_++; } - - static void - destroy() { destructCount_++; } - - static void - deallocate(void* p, size_type blocksize) - { - ::operator delete(p); - deallocationTotal_ += blocksize; - } - - static size_type - allocationTotal() { return allocationTotal_; } - - static size_type - deallocationTotal() { return deallocationTotal_; } - - static int - constructCount() { return constructCount_; } - - static int - destructCount() { return destructCount_; } - - static void - resetCounts() - { - allocationTotal_ = 0; - deallocationTotal_ = 0; - constructCount_ = 0; - destructCount_ = 0; - } - - private: - static size_type allocationTotal_; - static size_type deallocationTotal_; - static int constructCount_; - static int destructCount_; - }; - - // A simple basic allocator that just forwards to the - // allocation_tracker to fulfill memory requests. This class is - // templated on the target object type, but tracker isn't. - template - class tracker_alloc - { - public: - typedef T value_type; - typedef T* pointer; - typedef const T* const_pointer; - typedef T& reference; - typedef const T& const_reference; - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - - template struct rebind { typedef tracker_alloc other; }; - - pointer - address(reference value) const - { return &value; } - - const_pointer - address(const_reference value) const - { return &value; } - - tracker_alloc() throw() - { } - - tracker_alloc(const tracker_alloc&) throw() - { } - - template - tracker_alloc(const tracker_alloc&) throw() - { } - - ~tracker_alloc() throw() - { } - - size_type - max_size() const throw() - { return std::numeric_limits::max() / sizeof(T); } - - pointer - allocate(size_type n, const void* = 0) - { - return static_cast(allocation_tracker::allocate(n * sizeof(T))); - } - - void - construct(pointer p, const T& value) - { - new (p) T(value); - allocation_tracker::construct(); - } - - void - destroy(pointer p) - { - p->~T(); - allocation_tracker::destroy(); - } - - void - deallocate(pointer p, size_type num) - { allocation_tracker::deallocate(p, num * sizeof(T)); } - }; - - template - bool - operator==(const tracker_alloc&, const tracker_alloc&) throw() - { return true; } - - template - bool - operator!=(const tracker_alloc&, const tracker_alloc&) throw() - { return false; } - - bool - check_construct_destroy(const char* tag, int expected_c, int expected_d); - - template - bool - check_new(Alloc a = Alloc()) - { - bool test __attribute__((unused)) = true; - a.allocate(10); - test &= ( new_called == uses_global_new ); - return test; - } - - template - bool - check_delete(Alloc a = Alloc()) - { - bool test __attribute__((unused)) = true; - typename Alloc::pointer p = a.allocate(10); - a.deallocate(p, 10); - test &= ( delete_called == uses_global_delete ); - return test; - } - - template - bool - check_deallocate_null() - { - // Let's not core here... - Alloc a; - a.deallocate(NULL, 1); - a.deallocate(NULL, 10); - return true; - } - - template - bool - check_allocate_max_size() - { - Alloc a; - try - { - a.allocate(a.max_size() + 1); - } - catch(std::bad_alloc&) - { - return true; - } - catch(...) - { - throw; - } - throw; - } - - - // A simple allocator which can be constructed endowed of a given - // "personality" (an integer), queried in operator== to simulate the - // behavior of realworld "unequal" allocators (i.e., not exploiting - // the provision in 20.1.5/4, first bullet). A global unordered_map, - // filled at allocation time with (pointer, personality) pairs, is - // then consulted to enforce the requirements in Table 32 about - // deallocation vs allocator equality. Note that this allocator is - // swappable, not assignable, consistently with Option 3 of DR 431 - // (see N1599). - struct uneq_allocator_base - { - typedef std::tr1::unordered_map map_type; - - // Avoid static initialization troubles and/or bad interactions - // with tests linking testsuite_allocator.o and playing globally - // with operator new/delete. - static map_type& - get_map() - { - static map_type alloc_map; - return alloc_map; - } - }; - - template - class uneq_allocator - : private uneq_allocator_base - { - public: - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef Tp* pointer; - typedef const Tp* const_pointer; - typedef Tp& reference; - typedef const Tp& const_reference; - typedef Tp value_type; - - template - struct rebind - { typedef uneq_allocator other; }; - - uneq_allocator() throw() - : personality(0) { } - - uneq_allocator(int person) throw() - : personality(person) { } - - template - uneq_allocator(const uneq_allocator& b) throw() - : personality(b.get_personality()) { } - - int get_personality() const { return personality; } - - pointer - address(reference x) const { return &x; } - - const_pointer - address(const_reference x) const { return &x; } - - pointer - allocate(size_type n, const void* = 0) - { - if (__builtin_expect(n > this->max_size(), false)) - std::__throw_bad_alloc(); - - pointer p = static_cast(::operator new(n * sizeof(Tp))); - try - { - get_map().insert(map_type::value_type(reinterpret_cast(p), - personality)); - } - catch(...) - { - ::operator delete(p); - __throw_exception_again; - } - return p; - } - - void - deallocate(pointer p, size_type) - { - assert( p ); - - map_type::iterator it = get_map().find(reinterpret_cast(p)); - assert( it != get_map().end() ); - - // Enforce requirements in Table 32 about deallocation vs - // allocator equality. - assert( it->second == personality ); - - get_map().erase(it); - ::operator delete(p); - } - - size_type - max_size() const throw() - { return size_t(-1) / sizeof(Tp); } - - void - construct(pointer p, const Tp& val) - { ::new(p) Tp(val); } - - void - destroy(pointer p) { p->~Tp(); } - - private: - // Not assignable... - uneq_allocator& - operator=(const uneq_allocator&); - - // ... yet swappable! - friend inline void - swap(uneq_allocator& a, uneq_allocator& b) - { std::swap(a.personality, b.personality); } - - template - friend inline bool - operator==(const uneq_allocator& a, const uneq_allocator& b) - { return a.personality == b.personality; } - - template - friend inline bool - operator!=(const uneq_allocator& a, const uneq_allocator& b) - { return !(a == b); } - - int personality; - }; - - - template - class throw_allocator - { - public: - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - typedef Tp* pointer; - typedef const Tp* const_pointer; - typedef Tp& reference; - typedef const Tp& const_reference; - typedef Tp value_type; - - template - struct rebind - { typedef throw_allocator other; }; - - throw_allocator() throw() - : count(size_type(-1)) { } - - throw_allocator(size_type c) throw() - : count(c) { } - - template - throw_allocator(const throw_allocator& b) throw() - : count(b.get_count()) { } - - size_type get_count() const { return count; } - - pointer - address(reference x) const { return &x; } - - const_pointer - address(const_reference x) const { return &x; } - - pointer - allocate(size_type n, const void* = 0) - { - if (count == 0) - throw std::bad_alloc(); - - if (count != size_type(-1)) - --count; - - return static_cast(::operator new(n * sizeof(Tp))); - } - - void - deallocate(pointer p, size_type) - { ::operator delete(p); } - - size_type - max_size() const throw() - { return size_type(-1) / sizeof(Tp); } - - void - construct(pointer p, const Tp& val) - { ::new(p) Tp(val); } - - void - destroy(pointer p) { p->~Tp(); } - - private: - template - friend inline bool - operator==(const throw_allocator&, const throw_allocator&) - { return true; } - - template - friend inline bool - operator!=(const throw_allocator&, const throw_allocator&) - { return false; } - - size_type count; - }; -}; // namespace __gnu_test - -#endif // _GLIBCXX_TESTSUITE_ALLOCATOR_H diff --git a/libstdc++-v3/testsuite/testsuite_character.cc b/libstdc++-v3/testsuite/testsuite_character.cc deleted file mode 100644 index 63a1fa35bfc..00000000000 --- a/libstdc++-v3/testsuite/testsuite_character.cc +++ /dev/null @@ -1,195 +0,0 @@ -// -*- C++ -*- - -// Utility subroutines for the C++ library testsuite. -// -// Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. -// -// This file is part of the GNU ISO C++ Library. This library is free -// software; you can redistribute it and/or modify it under the -// terms of the GNU General Public License as published by the -// Free Software Foundation; either version 2, or (at your option) -// any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, -// USA. -// -// As a special exception, you may use this file as part of a free software -// library without restriction. Specifically, if other files instantiate -// templates or use macros or inline functions from this file, or you compile -// this file and link it with other files to produce an executable, this -// file does not by itself cause the resulting executable to be covered by -// the GNU General Public License. This exception does not however -// invalidate any other reasons why the executable file might be covered by -// the GNU General Public License. - -#include - -namespace std -{ - locale::id - codecvt<__gnu_test::pod_uchar, char, __gnu_test::pod_state>::id; - - locale::id - ctype<__gnu_test::pod_uchar>::id; - - locale::id - numpunct<__gnu_test::pod_uint>::id; - - locale::id - moneypunct<__gnu_test::pod_uint>::id; - - // Member specializations for the existing facet classes. - // NB: This isn't especially portable. Perhaps a better way would be - // to just specialize all of numpunct and ctype. - using __gnu_test::pod_ushort; - typedef pod_ushort::value_type value_type; - - template<> - bool - ctype:: - do_is(mask, char_type) const { return true; } - - template<> - const pod_ushort* - ctype:: - do_is(const char_type* __lo, const char_type*, mask*) const - { return __lo; } - - template<> - const pod_ushort* - ctype:: - do_scan_is(mask, const char_type* __lo, const char_type*) const - { return __lo; } - - template<> - const pod_ushort* - ctype:: - do_scan_not(mask, const char_type* __lo, const char_type*) const - { return __lo; } - - template<> - pod_ushort - ctype:: - do_toupper(char_type __c) const - { return __c; } - - template<> - const pod_ushort* - ctype:: - do_toupper(char_type*, const char_type* __hi) const - { return __hi; } - - template<> - pod_ushort - ctype:: - do_tolower(char_type __c) const - { return __c; } - - template<> - const pod_ushort* - ctype:: - do_tolower(char_type*, const char_type* __hi) const - { return __hi; } - - template<> - pod_ushort - ctype:: - do_widen(char __c) const - { - char_type ret = { value_type(__c) }; - return ret; - } - - template<> - const char* - ctype:: - do_widen(const char* __lo, const char* __hi, char_type* __dest) const - { - while (__lo < __hi) - { - *__dest = this->do_widen(*__lo); - ++__lo; - ++__dest; - } - return __hi; - } - - template<> - char - ctype:: - do_narrow(char_type __wc, char) const - { return static_cast(__wc.value); } - - template<> - const pod_ushort* - ctype:: - do_narrow(const pod_ushort* __lo, const pod_ushort* __hi, - char, char* __dest) const - { - while (__lo < __hi) - { - *__dest = this->do_narrow(*__lo, char()); - ++__lo; - ++__dest; - } - return __hi; - } - - template<> - ctype::~ctype() { } - - template<> - void - numpunct::_M_initialize_numpunct(__c_locale) - { - if (!_M_data) - _M_data = new __numpunct_cache; - - _M_data->_M_grouping = ""; - _M_data->_M_use_grouping = false; - - _M_data->_M_decimal_point.value = value_type('.'); - _M_data->_M_thousands_sep.value = value_type(','); - - for (size_t i = 0; i < __num_base::_S_oend; ++i) - { - value_type v = __num_base::_S_atoms_out[i]; - _M_data->_M_atoms_out[i].value = v; - } - _M_data->_M_atoms_out[__num_base::_S_oend] = pod_ushort(); - - for (size_t j = 0; j < __num_base::_S_iend; ++j) - _M_data->_M_atoms_in[j].value = value_type(__num_base::_S_atoms_in[j]); - _M_data->_M_atoms_in[__num_base::_S_iend] = pod_ushort(); - - // "true" - pod_ushort* __truename = new pod_ushort[4 + 1]; - __truename[0].value = value_type('t'); - __truename[1].value = value_type('r'); - __truename[2].value = value_type('u'); - __truename[3].value = value_type('e'); - __truename[4] = pod_ushort(); - _M_data->_M_truename = __truename; - - // "false" - pod_ushort* __falsename = new pod_ushort[5 + 1]; - __falsename[0].value = value_type('f'); - __falsename[1].value = value_type('a'); - __falsename[2].value = value_type('l'); - __falsename[3].value = value_type('s'); - __falsename[4].value = value_type('e'); - __falsename[5] = pod_ushort(); - _M_data->_M_falsename = __falsename; - } - - template<> - numpunct::~numpunct() - { delete _M_data; } -} // namespace std diff --git a/libstdc++-v3/testsuite/testsuite_character.h b/libstdc++-v3/testsuite/testsuite_character.h deleted file mode 100644 index a9e4847105b..00000000000 --- a/libstdc++-v3/testsuite/testsuite_character.h +++ /dev/null @@ -1,540 +0,0 @@ -// -*- C++ -*- - -// Testing character type and state type with char_traits and codecvt -// specializations for the C++ library testsuite. -// -// Copyright (C) 2003, 2005 Free Software Foundation, Inc. -// -// This file is part of the GNU ISO C++ Library. This library is free -// software; you can redistribute it and/or modify it under the -// terms of the GNU General Public License as published by the -// Free Software Foundation; either version 2, or (at your option) -// any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, -// USA. -// -// As a special exception, you may use this file as part of a free software -// library without restriction. Specifically, if other files instantiate -// templates or use macros or inline functions from this file, or you compile -// this file and link it with other files to produce an executable, this -// file does not by itself cause the resulting executable to be covered by -// the GNU General Public License. This exception does not however -// invalidate any other reasons why the executable file might be covered by -// the GNU General Public License. - -#ifndef _GLIBCXX_TESTSUITE_CHARACTER_H -#define _GLIBCXX_TESTSUITE_CHARACTER_H - -#include -#include // for char_traits -#include // for codecvt -#include - -namespace __gnu_test -{ - struct pod_int - { - int value; - }; - - inline bool - operator==(const pod_int& lhs, const pod_int& rhs) - { return lhs.value == rhs.value; } - - inline bool - operator<(const pod_int& lhs, const pod_int& rhs) - { return lhs.value < rhs.value; } - - struct pod_state - { - unsigned long value; - }; - - inline bool - operator==(const pod_state& lhs, const pod_state& rhs) - { return lhs.value == rhs.value; } - - inline bool - operator<(const pod_state& lhs, const pod_state& rhs) - { return lhs.value < rhs.value; } - - // Alternate character types. - using __gnu_cxx::character; - typedef character pod_char; - typedef character pod_uchar; - typedef character pod_ushort; - typedef character pod_uint; -} - -namespace __gnu_cxx -{ - // Specializations. - // pod_char - template<> - template - inline __gnu_test::pod_char::char_type - __gnu_test::pod_char::char_type::from(const V2& v) - { - char_type ret = { static_cast(v.value) }; - return ret; - } - - template<> - template - inline V2 - __gnu_test::pod_char::char_type::to(const char_type& c) - { - V2 ret = { c.value }; - return ret; - } - - template<> - template - inline __gnu_test::pod_uchar::char_type - __gnu_test::pod_uchar::char_type::from(const V2& v) - { - char_type ret; - ret.value = (v >> 5); - return ret; - } - - template<> - template - inline V2 - __gnu_test::pod_uchar::char_type::to(const char_type& c) - { return static_cast(c.value << 5); } -}; // namespace __gnu_test - -namespace std -{ - // codecvt specialization - // - // The conversion performed by the specialization is not supposed to - // be useful, rather it has been designed to demonstrate the - // essential features of stateful conversions: - // * Number and value of bytes for each internal character depends on the - // state in addition to the character itself. - // * Unshift produces an unshift sequence and resets the state. On input - // the unshift sequence causes the state to be reset. - // - // The conversion for output is as follows: - // 1. Calculate the value tmp by xor-ing the state and the internal - // character - // 2. Split tmp into either two or three bytes depending on the value of - // state. Output those bytes. - // 3. tmp becomes the new value of state. - template<> - class codecvt<__gnu_test::pod_uchar, char, __gnu_test::pod_state> - : public __codecvt_abstract_base<__gnu_test::pod_uchar, char, - __gnu_test::pod_state> - { - public: - typedef codecvt_base::result result; - typedef __gnu_test::pod_uchar intern_type; - typedef char extern_type; - typedef __gnu_test::pod_state state_type; - typedef __codecvt_abstract_base - base_type; - - explicit codecvt(size_t refs = 0) : base_type(refs) - { } - - static locale::id id; - - protected: - ~codecvt() - { } - - virtual result - do_out(state_type& state, const intern_type* from, - const intern_type* from_end, const intern_type*& from_next, - extern_type* to, extern_type* to_limit, - extern_type*& to_next) const - { - while (from < from_end && to < to_limit) - { - unsigned char tmp = (state.value ^ from->value); - if (state.value & 0x8) - { - if (to >= to_limit - 2) - break; - *to++ = (tmp & 0x7); - *to++ = ((tmp >> 3) & 0x7); - *to++ = ((tmp >> 6) & 0x3); - } - else - { - if (to >= to_limit - 1) - break; - *to++ = (tmp & 0xf); - *to++ = ((tmp >> 4) & 0xf); - } - state.value = tmp; - ++from; - } - - from_next = from; - to_next = to; - return (from < from_end) ? partial : ok; - } - - virtual result - do_in(state_type& state, const extern_type* from, - const extern_type* from_end, const extern_type*& from_next, - intern_type* to, intern_type* to_limit, - intern_type*& to_next) const - { - while (from < from_end && to < to_limit) - { - unsigned char c = *from; - if (c & 0xc0) - { - // Unshift sequence - state.value &= c; - ++from; - continue; - } - - unsigned char tmp; - if (state.value & 0x8) - { - if (from >= from_end - 2) - break; - tmp = (*from++ & 0x7); - tmp |= ((*from++ << 3) & 0x38); - tmp |= ((*from++ << 6) & 0xc0); - } - else - { - if (from >= from_end - 1) - break; - tmp = (*from++ & 0xf); - tmp |= ((*from++ << 4) & 0xf0); - } - to->value = (tmp ^ state.value); - state.value = tmp; - ++to; - } - - from_next = from; - to_next = to; - return (from < from_end) ? partial : ok; - } - - virtual result - do_unshift(state_type& state, extern_type* to, extern_type* to_limit, - extern_type*& to_next) const - { - for (unsigned int i = 0; i < CHAR_BIT; ++i) - { - unsigned int mask = (1 << i); - if (state.value & mask) - { - if (to == to_limit) - { - to_next = to; - return partial; - } - - state.value &= ~mask; - *to++ = static_cast(~mask); - } - } - - to_next = to; - return state.value == 0 ? ok : error; - } - - virtual int - do_encoding() const throw() - { return -1; } - - virtual bool - do_always_noconv() const throw() - { return false; } - - virtual int - do_length(state_type& state, const extern_type* from, - const extern_type* end, size_t max) const - { - const extern_type* beg = from; - while (from < end && max) - { - unsigned char c = *from; - if (c & 0xc0) - { - // Unshift sequence - state.value &= c; - ++from; - continue; - } - - unsigned char tmp; - if (state.value & 0x8) - { - if (from >= end - 2) - break; - tmp = (*from++ & 0x7); - tmp |= ((*from++ << 3) & 0x38); - tmp |= ((*from++ << 6) & 0xc0); - } - else - { - if (from >= end - 1) - break; - tmp = (*from++ & 0xf); - tmp |= ((*from++ << 4) & 0xf0); - } - state.value = tmp; - --max; - } - return from - beg; - } - - // Maximum 8 bytes unshift sequence followed by max 3 bytes for - // one character. - virtual int - do_max_length() const throw() - { return 11; } - }; - - template<> - class ctype<__gnu_test::pod_uchar> - : public __ctype_abstract_base<__gnu_test::pod_uchar> - { - public: - typedef __gnu_test::pod_uchar char_type; - - explicit ctype(size_t refs = 0) - : __ctype_abstract_base<__gnu_test::pod_uchar>(refs) { } - - static locale::id id; - - protected: - ~ctype() - { } - - virtual bool - do_is(mask, char_type) const - { return false; } - - virtual const char_type* - do_is(const char_type* low, const char_type* high, mask* vec) const - { - fill_n(vec, high - low, mask()); - return high; - } - - virtual const char_type* - do_scan_is(mask, const char_type*, const char_type* high) const - { return high; } - - virtual const char_type* - do_scan_not(mask, const char_type* low, const char_type*) const - { return low; } - - virtual char_type - do_toupper(char_type c) const - { return c; } - - virtual const char_type* - do_toupper(char_type*, const char_type* high) const - { return high; } - - virtual char_type - do_tolower(char_type c) const - { return c; } - - virtual const char_type* - do_tolower(char_type*, const char_type* high) const - { return high; } - - virtual char_type - do_widen(char c) const - { return __gnu_test::pod_uchar::from(c); } - - virtual const char* - do_widen(const char* low, const char* high, char_type* dest) const - { - transform(low, high, dest, &__gnu_test::pod_uchar::from); - return high; - } - - virtual char - do_narrow(char_type, char dfault) const - { return dfault; } - - virtual const char_type* - do_narrow(const char_type* low, const char_type* high, - char dfault, char* dest) const - { - fill_n(dest, high - low, dfault); - return high; - } - }; - - // numpunct specializations - template<> - class numpunct<__gnu_test::pod_uint> - : public locale::facet - { - public: - typedef __gnu_test::pod_uint char_type; - typedef basic_string string_type; - - static locale::id id; - - explicit - numpunct(size_t refs = 0) - : locale::facet(refs) - { } - - char_type - decimal_point() const - { return this->do_decimal_point(); } - - char_type - thousands_sep() const - { return this->do_thousands_sep(); } - - string - grouping() const - { return this->do_grouping(); } - - string_type - truename() const - { return this->do_truename(); } - - string_type - falsename() const - { return this->do_falsename(); } - - protected: - ~numpunct() - { } - - virtual char_type - do_decimal_point() const - { return char_type(); } - - virtual char_type - do_thousands_sep() const - { return char_type(); } - - virtual string - do_grouping() const - { return string(); } - - virtual string_type - do_truename() const - { return string_type(); } - - virtual string_type - do_falsename() const - { return string_type(); } - }; - - template<> - class moneypunct<__gnu_test::pod_uint> - : public locale::facet, public money_base - { - public: - typedef __gnu_test::pod_uint char_type; - typedef basic_string string_type; - - static locale::id id; - static const bool intl = false; - - explicit - moneypunct(size_t refs = 0) - : locale::facet(refs) - { } - - char_type - decimal_point() const - { return this->do_decimal_point(); } - - char_type - thousands_sep() const - { return this->do_thousands_sep(); } - - string - grouping() const - { return this->do_grouping(); } - - string_type - curr_symbol() const - { return this->do_curr_symbol(); } - - string_type - positive_sign() const - { return this->do_positive_sign(); } - - string_type - negative_sign() const - { return this->do_negative_sign(); } - - int - frac_digits() const - { return this->do_frac_digits(); } - - pattern - pos_format() const - { return this->do_pos_format(); } - - pattern - neg_format() const - { return this->do_neg_format(); } - - protected: - ~moneypunct() - { } - - virtual char_type - do_decimal_point() const - { return char_type(); } - - virtual char_type - do_thousands_sep() const - { return char_type(); } - - virtual string - do_grouping() const - { return string(); } - - virtual string_type - do_curr_symbol() const - { return string_type(); } - - string_type - do_positive_sign() const - { return string_type(); } - - string_type - do_negative_sign() const - { return string_type(); } - - int - do_frac_digits() const - { return 0; } - - pattern - do_pos_format() const - { return pattern(); } - - pattern - do_neg_format() const - { return pattern(); } - }; -} // namespace std - -#endif // _GLIBCXX_TESTSUITE_CHARACTER_H - diff --git a/libstdc++-v3/testsuite/testsuite_common_types.h b/libstdc++-v3/testsuite/testsuite_common_types.h deleted file mode 100644 index e63f5e0e590..00000000000 --- a/libstdc++-v3/testsuite/testsuite_common_types.h +++ /dev/null @@ -1,425 +0,0 @@ -// -*- C++ -*- -// typelist for the C++ library testsuite. -// -// Copyright (C) 2005 Free Software Foundation, Inc. -// -// This file is part of the GNU ISO C++ Library. This library is free -// software; you can redistribute it and/or modify it under the -// terms of the GNU General Public License as published by the -// Free Software Foundation; either version 2, or (at your option) -// any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, -// USA. -// -// As a special exception, you may use this file as part of a free software -// library without restriction. Specifically, if other files instantiate -// templates or use macros or inline functions from this file, or you compile -// this file and link it with other files to produce an executable, this -// file does not by itself cause the resulting executable to be covered by -// the GNU General Public License. This exception does not however -// invalidate any other reasons why the executable file might be covered by -// the GNU General Public License. - -#ifndef _TESTSUITE_COMMON_TYPES_H -#define _TESTSUITE_COMMON_TYPES_H 1 - -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -namespace __gnu_test -{ - using __gnu_cxx::typelist; - using __gnu_cxx::transform; - using __gnu_cxx::append; - - // All the allocators to test. - template - struct allocator_policies - { - typedef Tp value_type; - typedef __gnu_cxx::new_allocator a1; - typedef __gnu_cxx::malloc_allocator a2; - typedef __gnu_cxx::__common_pool_policy<__gnu_cxx::__pool, Thread> pool_policy; - typedef __gnu_cxx::__mt_alloc a3; - typedef __gnu_cxx::bitmap_allocator a4; - typedef __gnu_cxx::__pool_alloc a5; - typedef typelist<_GLIBCXX_TYPELIST_CHAIN5(a1, a2, a3, a4, a5)> type; - }; - - // Typelists for vector, string, list, deque. - // XXX should just use template templates - template - struct vectors - { - typedef Tp value_type; - - template - struct vector_shell - { - typedef Tl allocator_type; - typedef std::vector type; - }; - - typedef allocator_policies allocator_types; - typedef typename allocator_types::type allocator_typelist; - typedef typename transform::type type; - }; - - template - struct lists - { - typedef Tp value_type; - - template - struct list_shell - { - typedef Tl allocator_type; - typedef std::list type; - }; - - typedef allocator_policies allocator_types; - typedef typename allocator_types::type allocator_typelist; - typedef typename transform::type type; - }; - - template - struct deques - { - typedef Tp value_type; - - template - struct deque_shell - { - typedef Tl allocator_type; - typedef std::deque type; - }; - - typedef allocator_policies allocator_types; - typedef typename allocator_types::type allocator_typelist; - typedef typename transform::type type; - }; - - template - struct strings - { - typedef Tp value_type; - - template - struct string_shell - { - typedef Tl allocator_type; - typedef std::char_traits traits_type; - typedef std::basic_string type; - }; - - typedef allocator_policies allocator_types; - typedef typename allocator_types::type allocator_typelist; - typedef typename transform::type type; - }; - - // A typelist of vector, list, deque, and string all instantiated - // with each of the allocator policies. - template - struct sequence_containers - { - typedef Tp value_type; - - typedef typename vectors::type vector_typelist; - typedef typename lists::type list_typelist; - typedef typename deques::type deque_typelist; - typedef typename strings::type string_typelist; - - typedef typename append::type a1; - typedef typename append::type a2; - typedef typename append::type type; - }; - - // Typelists for map, set, hash_map, hash_set, unordered_set, unordered_map. - template - struct maps - { - typedef Tp value_type; - typedef Tp key_type; - typedef std::pair pair_type; - typedef std::less compare_function; - - template - struct container - { - typedef Tl allocator_type; - typedef std::map type; - }; - - typedef allocator_policies allocator_types; - typedef typename allocator_types::type allocator_typelist; - typedef typename transform::type type; - }; - - template - struct hash_maps - { - typedef Tp value_type; - typedef Tp key_type; - typedef __gnu_cxx::hash hash_function; - typedef std::equal_to equality_function; - - template - struct container - { - typedef Tl allocator_type; - typedef __gnu_cxx::hash_map type; - }; - - typedef allocator_policies allocator_types; - typedef typename allocator_types::type allocator_typelist; - typedef typename transform::type type; - }; - - template - struct unordered_maps - { - typedef Tp value_type; - typedef Tp key_type; - typedef std::pair pair_type; - typedef std::tr1::hash hash_function; - typedef std::equal_to equality_function; - - template - struct container - { - typedef Tl allocator_type; - typedef std::tr1::unordered_map type; - }; - - typedef allocator_policies allocator_types; - typedef typename allocator_types::type allocator_typelist; - typedef typename transform::type type; - }; - - template - struct sets - { - typedef Tp value_type; - typedef Tp key_type; - typedef std::less compare_function; - - template - struct container - { - typedef Tl allocator_type; - typedef std::set type; - }; - - typedef allocator_policies allocator_types; - typedef typename allocator_types::type allocator_typelist; - typedef typename transform::type type; - }; - - template - struct hash_sets - { - typedef Tp value_type; - typedef Tp key_type; - typedef __gnu_cxx::hash hash_function; - typedef std::equal_to equality_function; - - template - struct container - { - typedef Tl allocator_type; - typedef __gnu_cxx::hash_set type; - }; - - typedef allocator_policies allocator_types; - typedef typename allocator_types::type allocator_typelist; - typedef typename transform::type type; - }; - - template - struct unordered_sets - { - typedef Tp value_type; - typedef Tp key_type; - typedef std::tr1::hash hash_function; - typedef std::equal_to equality_function; - - template - struct container - { - typedef Tl allocator_type; - typedef std::tr1::unordered_set type; - }; - - typedef allocator_policies allocator_types; - typedef typename allocator_types::type allocator_typelist; - typedef typename transform::type type; - }; - - - // A typelist of all associated container types, with each of the - // allocator policies. - template - struct associative_containers - { - typedef Tp value_type; - - typedef typename maps::type map_typelist; - typedef typename sets::type set_typelist; - typedef typename hash_maps::type hash_map_typelist; - typedef typename hash_sets::type hash_set_typelist; - typedef typename unordered_maps::type unordered_map_typelist; - typedef typename unordered_sets::type unordered_set_typelist; - - typedef typename append::type a1; - typedef typename append::type a2; - typedef typename append::type a3; - typedef typename append::type a4; - typedef typename append::type type; - }; - -} // namespace __gnu_test - - -// Function template, function objects for the tests. -template - struct value_type : public std::pair - { - inline value_type& operator++() - { - ++this->second; - return *this; - } - - inline operator TestType() const { return this->second; } - }; - -template - void - do_loop(); - -template - void* - do_thread(void* p = NULL) - { - do_loop(); - return p; - } - -template - void - test_container(const char* filename) - { - using namespace __gnu_test; - time_counter time; - resource_counter resource; - { - start_counters(time, resource); - if (!Thread) - { - // No threads, so run 4x. - do_loop(); - } - else - { -#if defined (_GLIBCXX_GCC_GTHR_POSIX_H) && !defined (NOTHREAD) - pthread_t t1, t2, t3, t4; - pthread_create(&t1, 0, &do_thread, 0); - pthread_create(&t2, 0, &do_thread, 0); - pthread_create(&t3, 0, &do_thread, 0); - pthread_create(&t4, 0, &do_thread, 0); - - pthread_join(t1, NULL); - pthread_join(t2, NULL); - pthread_join(t3, NULL); - pthread_join(t4, NULL); -#endif - } - stop_counters(time, resource); - - // Detailed text data. - Container obj; - int status; - std::ostringstream comment; - comment << "type: " << abi::__cxa_demangle(typeid(obj).name(), - 0, 0, &status); - report_header(filename, comment.str()); - report_performance("", "", time, resource); - - // Detailed data for visualization. - std::string vizfilename(filename); - vizfilename += ".dat"; - write_viz_data(time, vizfilename.c_str()); - } - } - -template - struct test_sequence - { - test_sequence(const char* filename) : _M_filename(filename) { } - - template - void - operator()(__gnu_cxx::detail::type_to_type) - { - const int i = 20000; - test_container(_M_filename); - } - - private: - const char* _M_filename; - }; - - -inline std::string::size_type -sequence_find_container(std::string& type) -{ - const std::string::size_type npos = std::string::npos; - std::string::size_type n1 = type.find("vector"); - std::string::size_type n2 = type.find("list"); - std::string::size_type n3 = type.find("deque"); - std::string::size_type n4 = type.find("string"); - - if (n1 != npos || n2 != npos || n3 != npos || n4 != npos) - return std::min(std::min(n1, n2), std::min(n3, n4)); - else - throw std::runtime_error("sequence_find_container not found"); -} - -inline std::string::size_type -associative_find_container(std::string& type) -{ - using std::string; - string::size_type n1 = type.find("map"); - string::size_type n2 = type.find("set"); - if (n1 != string::npos || n2 != string::npos) - return std::min(n1, n2); - else - throw std::runtime_error("associative_find_container not found"); -} -#endif diff --git a/libstdc++-v3/testsuite/testsuite_hooks.cc b/libstdc++-v3/testsuite/testsuite_hooks.cc deleted file mode 100644 index 40189fbf5d4..00000000000 --- a/libstdc++-v3/testsuite/testsuite_hooks.cc +++ /dev/null @@ -1,323 +0,0 @@ -// -*- C++ -*- - -// Utility subroutines for the C++ library testsuite. -// -// Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. -// -// This file is part of the GNU ISO C++ Library. This library is free -// software; you can redistribute it and/or modify it under the -// terms of the GNU General Public License as published by the -// Free Software Foundation; either version 2, or (at your option) -// any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, -// USA. -// -// As a special exception, you may use this file as part of a free software -// library without restriction. Specifically, if other files instantiate -// templates or use macros or inline functions from this file, or you compile -// this file and link it with other files to produce an executable, this -// file does not by itself cause the resulting executable to be covered by -// the GNU General Public License. This exception does not however -// invalidate any other reasons why the executable file might be covered by -// the GNU General Public License. - -#include - -#ifdef _GLIBCXX_RES_LIMITS -#include -#include -#include -#endif -#include -#include -#include -#include -#include -#include - -// If we have , , and , then assume -// that System V semaphores are available. -#if defined(_GLIBCXX_HAVE_SYS_TYPES_H) \ - && defined(_GLIBCXX_HAVE_SYS_IPC_H) \ - && defined(_GLIBCXX_HAVE_SYS_SEM_H) -#define _GLIBCXX_SYSV_SEM -#endif - -#ifdef _GLIBCXX_SYSV_SEM -#include -#include -#include -#endif - -namespace __gnu_test -{ -#ifdef _GLIBCXX_RES_LIMITS - void - set_memory_limits(float size) - { - struct rlimit r; - // Cater to the absence of rlim_t. - __typeof__ (r.rlim_cur) limit = (__typeof__ (r.rlim_cur))(size * 1048576); - - // Heap size, seems to be common. -#if _GLIBCXX_HAVE_LIMIT_DATA - getrlimit(RLIMIT_DATA, &r); - r.rlim_cur = limit; - setrlimit(RLIMIT_DATA, &r); -#endif - - // Resident set size. -#if _GLIBCXX_HAVE_LIMIT_RSS - getrlimit(RLIMIT_RSS, &r); - r.rlim_cur = limit; - setrlimit(RLIMIT_RSS, &r); -#endif - - // Mapped memory (brk + mmap). -#if _GLIBCXX_HAVE_LIMIT_VMEM - getrlimit(RLIMIT_VMEM, &r); - r.rlim_cur = limit; - setrlimit(RLIMIT_VMEM, &r); -#endif - - // Virtual memory. - // On HP-UX 11.23, a trivial C++ program that sets RLIMIT_AS to - // anything less than 128MB cannot "malloc" even 1K of memory. - // Therefore, we skip RLIMIT_AS on HP-UX. -#if _GLIBCXX_HAVE_LIMIT_AS && !defined(__hpux__) - getrlimit(RLIMIT_AS, &r); - r.rlim_cur = limit; - setrlimit(RLIMIT_AS, &r); -#endif - } - -#else - void - set_memory_limits(float) { } -#endif - -#ifdef _GLIBCXX_RES_LIMITS - void - set_file_limit(unsigned long size) - { -#if _GLIBCXX_HAVE_LIMIT_FSIZE - struct rlimit r; - // Cater to the absence of rlim_t. - __typeof__ (r.rlim_cur) limit = (__typeof__ (r.rlim_cur))(size); - - getrlimit(RLIMIT_FSIZE, &r); - r.rlim_cur = limit; - setrlimit(RLIMIT_FSIZE, &r); -#endif - } - -#else - void - set_file_limit(unsigned long) { } -#endif - - void - verify_demangle(const char* mangled, const char* wanted) - { - int status = 0; - const char* s = abi::__cxa_demangle(mangled, 0, 0, &status); - if (!s) - { - switch (status) - { - case 0: - s = "error code = 0: success"; - break; - case -1: - s = "error code = -1: memory allocation failure"; - break; - case -2: - s = "error code = -2: invalid mangled name"; - break; - case -3: - s = "error code = -3: invalid arguments"; - break; - default: - s = "error code unknown - who knows what happened"; - } - } - - std::string w(wanted); - if (w != s) - std::__throw_runtime_error(s); - } - - void - run_tests_wrapped_locale(const char* name, const func_callback& l) - { - using namespace std; - bool test = true; - - // Set the global locale. - locale loc_name = locale(name); - locale orig = locale::global(loc_name); - - const char* res = setlocale(LC_ALL, name); - if (res != NULL) - { - string preLC_ALL = res; - const func_callback::test_type* tests = l.tests(); - for (int i = 0; i < l.size(); ++i) - (*tests[i])(); - string postLC_ALL= setlocale(LC_ALL, NULL); - VERIFY( preLC_ALL == postLC_ALL ); - } - else - { - string s("LC_ALL for "); - s += name; - __throw_runtime_error(s.c_str()); - } - } - - void - run_tests_wrapped_env(const char* name, const char* env, - const func_callback& l) - { - using namespace std; - bool test = true; - -#ifdef _GLIBCXX_HAVE_SETENV - // Set the global locale. - locale loc_name = locale(name); - locale orig = locale::global(loc_name); - - // Set environment variable env to value in name. - const char* oldENV = getenv(env); - if (!setenv(env, name, 1)) - { - const func_callback::test_type* tests = l.tests(); - for (int i = 0; i < l.size(); ++i) - (*tests[i])(); - setenv(env, oldENV ? oldENV : "", 1); - } - else - { - string s(env); - s += string(" to "); - s += string(name); - __throw_runtime_error(s.c_str()); - } -#endif - } - - counter::size_type counter::count = 0; - unsigned int copy_constructor::count_ = 0; - unsigned int copy_constructor::throw_on_ = 0; - unsigned int assignment_operator::count_ = 0; - unsigned int assignment_operator::throw_on_ = 0; - unsigned int destructor::_M_count = 0; - int copy_tracker::next_id_ = 0; - -#ifdef _GLIBCXX_SYSV_SEM - // This union is not declared in system headers. Instead, it must - // be defined by user programs. - union semun - { - int val; - struct semid_ds *buf; - unsigned short *array; - }; -#endif - - semaphore::semaphore() - { -#ifdef _GLIBCXX_SYSV_SEM - // Remeber the PID for the process that created the semaphore set - // so that only one process will destroy the set. - pid_ = getpid(); - - // GLIBC does not define SEM_R and SEM_A. -#ifndef SEM_R -#define SEM_R 0400 -#endif - -#ifndef SEM_A -#define SEM_A 0200 -#endif - - // Get a semaphore set with one semaphore. - sem_set_ = semget(IPC_PRIVATE, 1, SEM_R | SEM_A); - if (sem_set_ == -1) - std::__throw_runtime_error("could not obtain semaphore set"); - - // Initialize the semaphore. - union semun val; - val.val = 0; - if (semctl(sem_set_, 0, SETVAL, val) == -1) - std::__throw_runtime_error("could not initialize semaphore"); -#else - // There are no semaphores on this system. We have no way to mark - // a test as "unsupported" at runtime, so we just exit, pretending - // that the test passed. - exit(0); -#endif - } - - semaphore::~semaphore() - { -#ifdef _GLIBCXX_SYSV_SEM - union semun val; - // Destroy the semaphore set only in the process that created it. - if (pid_ == getpid()) - semctl(sem_set_, 0, IPC_RMID, val); -#endif - } - - void - semaphore::signal() - { -#ifdef _GLIBCXX_SYSV_SEM - struct sembuf op[1] = - { - { 0, 1, 0 } - }; - if (semop(sem_set_, op, 1) == -1) - std::__throw_runtime_error("could not signal semaphore"); -#endif - } - - void - semaphore::wait() - { -#ifdef _GLIBCXX_SYSV_SEM - struct sembuf op[1] = - { - { 0, -1, SEM_UNDO } - }; - if (semop(sem_set_, op, 1) == -1) - std::__throw_runtime_error("could not wait for semaphore"); -#endif - } - - // For use in 22_locale/time_get and time_put. - tm - test_tm(int sec, int min, int hour, int mday, int mon, - int year, int wday, int yday, int isdst) - { - static tm tmp; - tmp.tm_sec = sec; - tmp.tm_min = min; - tmp.tm_hour = hour; - tmp.tm_mday = mday; - tmp.tm_mon = mon; - tmp.tm_year = year; - tmp.tm_wday = wday; - tmp.tm_yday = yday; - tmp.tm_isdst = isdst; - return tmp; - } -}; // namespace __gnu_test diff --git a/libstdc++-v3/testsuite/testsuite_hooks.h b/libstdc++-v3/testsuite/testsuite_hooks.h deleted file mode 100644 index b6c675b12e7..00000000000 --- a/libstdc++-v3/testsuite/testsuite_hooks.h +++ /dev/null @@ -1,396 +0,0 @@ -// -*- C++ -*- -// Utility subroutines for the C++ library testsuite. -// -// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006 -// Free Software Foundation, Inc. -// -// This file is part of the GNU ISO C++ Library. This library is free -// software; you can redistribute it and/or modify it under the -// terms of the GNU General Public License as published by the -// Free Software Foundation; either version 2, or (at your option) -// any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, -// USA. -// -// As a special exception, you may use this file as part of a free software -// library without restriction. Specifically, if other files instantiate -// templates or use macros or inline functions from this file, or you compile -// this file and link it with other files to produce an executable, this -// file does not by itself cause the resulting executable to be covered by -// the GNU General Public License. This exception does not however -// invalidate any other reasons why the executable file might be covered by -// the GNU General Public License. - -// This file provides the following: -// -// 1) VERIFY(), via _GLIBCXX_ASSERT, from Brent Verner . -// This file is included in the various testsuite programs to provide -// #define(able) assert() behavior for debugging/testing. It may be -// a suitable location for other furry woodland creatures as well. -// -// 2) set_memory_limits() -// set_memory_limits() uses setrlimit() to restrict dynamic memory -// allocation. We provide a default memory limit if none is passed by the -// calling application. The argument to set_memory_limits() is the -// limit in megabytes (a floating-point number). If _GLIBCXX_RES_LIMITS is -// not #defined before including this header, then no limiting is attempted. -// -// 3) counter -// This is a POD with a static data member, gnu_counting_struct::count, -// which starts at zero, increments on instance construction, and decrements -// on instance destruction. "assert_count(n)" can be called to VERIFY() -// that the count equals N. -// -// 4) copy_tracker, from Stephen M. Webb . -// A class with nontrivial ctor/dtor that provides the ability to track the -// number of copy ctors and dtors, and will throw on demand during copy. - -#ifndef _GLIBCXX_TESTSUITE_HOOKS_H -#define _GLIBCXX_TESTSUITE_HOOKS_H - -#include -#include -#include -#include -#ifdef _GLIBCXX_HAVE_SYS_STAT_H -#include -#endif - -#ifdef _GLIBCXX_ASSERT -# include -# define VERIFY(fn) assert(fn) -#else -# define VERIFY(fn) test &= (fn) -#endif - -#ifdef _GLIBCXX_HAVE_UNISTD_H -# include -#else -# define unlink(x) -#endif - -namespace __gnu_test -{ - // All macros are defined in GLIBCXX_CONFIGURE_TESTSUITE and imported - // from c++config.h - - // Set memory limits if possible, if not set to 0. -#ifndef _GLIBCXX_RES_LIMITS -# define MEMLIMIT_MB 0 -#else -# ifndef MEMLIMIT_MB -# define MEMLIMIT_MB 16.0 -# endif -#endif - extern void - set_memory_limits(float __size = MEMLIMIT_MB); - - extern void - set_file_limit(unsigned long __size); - - // Check mangled name demangles (using __cxa_demangle) as expected. - void - verify_demangle(const char* mangled, const char* wanted); - - // 17.3.2.1.2 - Bitmask types [lib.bitmask.types] - // bitmask_operators - template - void - bitmask_operators(bitmask_type a = bitmask_type(), - bitmask_type b = bitmask_type()) - { - a | b; - a & b; - a ^ b; - ~b; - a |= b; // set - a &= ~b; // clear - a ^= b; - } - - // Simple callback structure for variable numbers of tests (all with - // same signature). Assume all unit tests are of the signature - // void test01(); - class func_callback - { - public: - typedef void (*test_type) (void); - - private: - int _M_size; - test_type _M_tests[15]; - - func_callback& - operator=(const func_callback&); - - func_callback(const func_callback&); - - public: - func_callback(): _M_size(0) { }; - - int - size() const { return _M_size; } - - const test_type* - tests() const { return _M_tests; } - - void - push_back(test_type test) - { - _M_tests[_M_size] = test; - ++_M_size; - } - }; - - - // Run select unit tests after setting global locale. - void - run_tests_wrapped_locale(const char*, const func_callback&); - - // Run select unit tests after setting environment variables. - void - run_tests_wrapped_env(const char*, const char*, const func_callback&); - - - // For containers (23.1/3). - struct NonDefaultConstructible - { - NonDefaultConstructible(int) { } - }; - - inline bool - operator==(const NonDefaultConstructible&, - const NonDefaultConstructible&) - { return false; } - - inline bool - operator<(const NonDefaultConstructible&, - const NonDefaultConstructible&) - { return false; } - - - // Counting. - struct counter - { - // Specifically and glaringly-obviously marked 'signed' so that when - // COUNT mistakenly goes negative, we can track the patterns of - // deletions more easily. - typedef signed int size_type; - static size_type count; - counter() { ++count; } - counter (const counter&) { ++count; } - ~counter() { --count; } - }; - -#define assert_count(n) VERIFY(__gnu_test::counter::count == n) - - // A (static) class for counting copy constructors and possibly throwing an - // exception on a desired count. - class copy_constructor - { - public: - static unsigned int - count() { return count_; } - - static void - mark_call() - { - count_++; - if (count_ == throw_on_) - std::__throw_runtime_error("copy_constructor::mark_call"); - } - - static void - reset() - { - count_ = 0; - throw_on_ = 0; - } - - static void - throw_on(unsigned int count) { throw_on_ = count; } - - private: - static unsigned int count_; - static unsigned int throw_on_; - }; - - // A (static) class for counting assignment operator calls and - // possibly throwing an exception on a desired count. - class assignment_operator - { - public: - static unsigned int - count() { return count_; } - - static void - mark_call() - { - count_++; - if (count_ == throw_on_) - std::__throw_runtime_error("assignment_operator::mark_call"); - } - - static void - reset() - { - count_ = 0; - throw_on_ = 0; - } - - static void - throw_on(unsigned int count) { throw_on_ = count; } - - private: - static unsigned int count_; - static unsigned int throw_on_; - }; - - // A (static) class for tracking calls to an object's destructor. - class destructor - { - public: - static unsigned int - count() { return _M_count; } - - static void - mark_call() { _M_count++; } - - static void - reset() { _M_count = 0; } - - private: - static unsigned int _M_count; - }; - - // An class of objects that can be used for validating various - // behaviours and guarantees of containers and algorithms defined in - // the standard library. - class copy_tracker - { - public: - // Creates a copy-tracking object with the given ID number. If - // "throw_on_copy" is set, an exception will be thrown if an - // attempt is made to copy this object. - copy_tracker(int id = next_id_--, bool throw_on_copy = false) - : id_(id) , throw_on_copy_(throw_on_copy) { } - - // Copy-constructs the object, marking a call to the copy - // constructor and forcing an exception if indicated. - copy_tracker(const copy_tracker& rhs) - : id_(rhs.id()), throw_on_copy_(rhs.throw_on_copy_) - { - if (throw_on_copy_) - copy_constructor::throw_on(copy_constructor::count() + 1); - copy_constructor::mark_call(); - } - - // Assigns the value of another object to this one, tracking the - // number of times this member function has been called and if the - // other object is supposed to throw an exception when it is - // copied, well, make it so. - copy_tracker& - operator=(const copy_tracker& rhs) - { - id_ = rhs.id(); - if (rhs.throw_on_copy_) - assignment_operator::throw_on(assignment_operator::count() + 1); - assignment_operator::mark_call(); - return *this; - } - - ~copy_tracker() - { destructor::mark_call(); } - - int - id() const { return id_; } - - private: - int id_; - const bool throw_on_copy_; - - public: - static void - reset() - { - copy_constructor::reset(); - assignment_operator::reset(); - destructor::reset(); - } - - // for backwards-compatibility - static int - copyCount() - { return copy_constructor::count(); } - - // for backwards-compatibility - static int - dtorCount() - { return destructor::count(); } - - private: - static int next_id_; - }; - - inline bool - operator==(const copy_tracker& lhs, const copy_tracker& rhs) - { return lhs.id() == rhs.id(); } - - // Class for checking required type conversions, implicit and - // explicit for given library data structures. - template - struct conversion - { - typedef typename _Container::const_iterator const_iterator; - - // Implicit conversion iterator to const_iterator. - static const_iterator - iterator_to_const_iterator() - { - _Container v; - const_iterator it = v.begin(); - const_iterator end = v.end(); - return it == end ? v.end() : it; - } - }; - - // A binary semaphore for use across multiple processes. - class semaphore - { - public: - // Creates a binary semaphore. The semaphore is initially in the - // unsignaled state. - semaphore(); - - // Destroy the semaphore. - ~semaphore(); - - // Signal the semaphore. If there are processes blocked in - // "wait", exactly one will be permitted to proceed. - void signal(); - - // Wait until the semaphore is signaled. - void wait(); - - private: - int sem_set_; - - pid_t pid_; - }; - - // For use in 22_locale/time_get and time_put. - tm test_tm(int sec, int min, int hour, int mday, int mon, - int year, int wday, int yday, int isdst); - -} // namespace __gnu_test - -#endif // _GLIBCXX_TESTSUITE_HOOKS_H - diff --git a/libstdc++-v3/testsuite/testsuite_io.h b/libstdc++-v3/testsuite/testsuite_io.h deleted file mode 100644 index e6f1c03d622..00000000000 --- a/libstdc++-v3/testsuite/testsuite_io.h +++ /dev/null @@ -1,328 +0,0 @@ -// -*- C++ -*- -// Testing streambuf/filebuf/stringbuf for the C++ library testsuite. -// -// Copyright (C) 2003, 2004 Free Software Foundation, Inc. -// -// This file is part of the GNU ISO C++ Library. This library is free -// software; you can redistribute it and/or modify it under the -// terms of the GNU General Public License as published by the -// Free Software Foundation; either version 2, or (at your option) -// any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, -// USA. -// -// As a special exception, you may use this file as part of a free software -// library without restriction. Specifically, if other files instantiate -// templates or use macros or inline functions from this file, or you compile -// this file and link it with other files to produce an executable, this -// file does not by itself cause the resulting executable to be covered by -// the GNU General Public License. This exception does not however -// invalidate any other reasons why the executable file might be covered by -// the GNU General Public License. - -#ifndef _GLIBCXX_TESTSUITE_IO_H -#define _GLIBCXX_TESTSUITE_IO_H - -#include -#include - -namespace __gnu_test -{ - // Used to verify the constraints/requirements on get and put areas - // as defined in - // 27.5.1 - Stream buffer requirements: get and put areas - // 27.8.1.1 - Template class basic_filebuf p 3 - // If the file is not open (ios_base::in) -> input seq. cannot be read - // If the file is not open (ios_base::out) -> output seq. cannot be written - // Joint file position - // 27.8.1.4 - Overridden virtual functions p9 - // If unbuffered, pbase == pptr == NULL - // 27.7.1.1 - Basic_stringbuf constructors p 1 - // 27.8.1.2 - Basic_filebuf constructors p 1 - // ... , initializing the base class with basic_streambuf() 27.5.2.1 - template - class constraint_buf - : public T - { - public: - bool - write_position() - { - bool one = this->pptr() != NULL; - bool two = this->pptr() < this->epptr(); - return one && two; - } - - bool - read_position() - { - bool one = this->gptr() != NULL; - bool two = this->gptr() < this->egptr(); - return one && two; - } - - bool - unbuffered() - { - bool one = this->pbase() == NULL; - bool two = this->pptr() == NULL; - return one && two; - } - - bool - check_pointers() - { - bool one = this->eback() == NULL; - bool two = this->gptr() == NULL; - bool three = this->egptr() == NULL; - - bool four = this->pbase() == NULL; - bool five = this->pptr() == NULL; - bool six = this->epptr() == NULL; - return one && two && three && four && five && six; - } - }; - - typedef constraint_buf constraint_streambuf; - typedef constraint_buf constraint_filebuf; - typedef constraint_buf constraint_stringbuf; -#ifdef _GLIBCXX_USE_WCHAR_T - typedef constraint_buf constraint_wstreambuf; - typedef constraint_buf constraint_wfilebuf; - typedef constraint_buf constraint_wstringbuf; -#endif - - // Used to check if basic_streambuf::pubsync() has been called. - // This is useful for checking if a function creates [io]stream::sentry - // objects, since the sentry constructors call tie()->flush(). - template - class sync_buf - : public T - { - private: - bool m_sync_called; - - public: - sync_buf() - : m_sync_called(false) - { } - - bool sync_called() const - { return m_sync_called; } - - protected: - int sync() - { - m_sync_called = true; - return 0; - } - }; - - typedef sync_buf sync_streambuf; -#ifdef _GLIBCXX_USE_WCHAR_T - typedef sync_buf sync_wstreambuf; -#endif - - // Throws on all overflow and underflow calls. - struct underflow_error: std::exception { }; - struct overflow_error: std::exception { }; - struct positioning_error: std::exception { }; - - template - struct fail_buf - : public T - { - typedef typename T::char_type char_type; - typedef typename T::int_type int_type; - typedef typename T::off_type off_type; - typedef typename T::pos_type pos_type; - - private: - char_type p[2]; - - public: - fail_buf() - { - p[0] = char_type('s'); - p[1] = char_type(); - setg(p, p, p + 1); - } - - virtual int_type underflow() - { - throw underflow_error(); - return int_type(); - } - - virtual int_type uflow() - { - throw underflow_error(); - return int_type(); - } - - virtual int_type - overflow(int_type) - { - throw overflow_error(); - return int_type(); - } - - virtual pos_type - seekoff(off_type, std::ios_base::seekdir, std::ios_base::openmode) - { - throw positioning_error(); - return pos_type(off_type(-1)); - } - - virtual pos_type - seekpos(pos_type, std::ios_base::openmode) - { - throw positioning_error(); - return pos_type(off_type(-1)); - } - - virtual int - sync() - { - throw positioning_error(); - return 0; - } - }; - - typedef fail_buf fail_streambuf; -#ifdef _GLIBCXX_USE_WCHAR_T - typedef fail_buf fail_wstreambuf; -#endif - - // Facets that throw an exception for every virtual function. - struct facet_error: std::exception { }; - - template - class fail_num_get - : public std::num_get - { - typedef std::ios_base ios_base; - typedef typename std::num_get::iter_type iter_type; - - protected: - iter_type - do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const - { throw facet_error(); return iter_type(); } - - virtual iter_type - do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, long&) const - { throw facet_error(); return iter_type(); } - - virtual iter_type - do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, - unsigned short&) const - { throw facet_error(); return iter_type(); } - - virtual iter_type - do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, - unsigned int&) const - { throw facet_error(); return iter_type(); } - - virtual iter_type - do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, - unsigned long&) const - { throw facet_error(); return iter_type(); } - -#ifdef _GLIBCXX_USE_LONG_LONG - virtual iter_type - do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, - long long&) const - { throw facet_error(); return iter_type(); } - - virtual iter_type - do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, - unsigned long long&) const - { throw facet_error(); return iter_type(); } -#endif - - virtual iter_type - do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, - float&) const - { throw facet_error(); return iter_type(); } - - virtual iter_type - do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, - double&) const - { throw facet_error(); return iter_type(); } - - virtual iter_type - do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, - long double&) const - { throw facet_error(); return iter_type(); } - - virtual iter_type - do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, - void*&) const - { throw facet_error(); return iter_type(); } - }; - - typedef fail_num_get fail_num_get_char; -#ifdef _GLIBCXX_USE_WCHAR_T - typedef fail_num_get fail_num_get_wchar_t; -#endif - - template - class fail_num_put - : public std::num_put - { - typedef std::ios_base ios_base; - typedef typename std::num_put::iter_type iter_type; - typedef typename std::num_put::char_type char_type; - - protected: - iter_type - do_put(iter_type, ios_base&, char_type, bool) const - { throw facet_error(); return iter_type(NULL); } - - virtual iter_type - do_put(iter_type, ios_base&, char_type, long) const - { throw facet_error(); return iter_type(NULL); } - - virtual iter_type - do_put(iter_type, ios_base&, char_type, unsigned long) const - { throw facet_error(); return iter_type(NULL); } - -#ifdef _GLIBCXX_USE_LONG_LONG - virtual iter_type - do_put(iter_type, ios_base&, char_type, long long) const - { throw facet_error(); return iter_type(NULL); } - - virtual iter_type - do_put(iter_type, ios_base&, char_type, unsigned long long) const - { throw facet_error(); return iter_type(NULL); } -#endif - - virtual iter_type - do_put(iter_type, ios_base&, char_type, double) const - { throw facet_error(); return iter_type(NULL); } - - virtual iter_type - do_put(iter_type, ios_base&, char_type, long double) const - { throw facet_error(); return iter_type(NULL); } - - virtual iter_type - do_put(iter_type, ios_base&, char_type, const void*) const - { throw facet_error(); return iter_type(NULL); } - }; - - typedef fail_num_put fail_num_put_char; -#ifdef _GLIBCXX_USE_WCHAR_T - typedef fail_num_put fail_num_put_wchar_t; -#endif -}; // namespace __gnu_test - -#endif // _GLIBCXX_TESTSUITE_IO_H - diff --git a/libstdc++-v3/testsuite/testsuite_iterators.h b/libstdc++-v3/testsuite/testsuite_iterators.h deleted file mode 100644 index 7119783c93b..00000000000 --- a/libstdc++-v3/testsuite/testsuite_iterators.h +++ /dev/null @@ -1,545 +0,0 @@ -// -*- C++ -*- -// Iterator Wrappers for the C++ library testsuite. -// -// Copyright (C) 2004, 2005 Free Software Foundation, Inc. -// -// This file is part of the GNU ISO C++ Library. This library is free -// software; you can redistribute it and/or modify it under the -// terms of the GNU General Public License as published by the -// Free Software Foundation; either version 2, or (at your option) -// any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, -// USA. -// -// As a special exception, you may use this file as part of a free software -// library without restriction. Specifically, if other files instantiate -// templates or use macros or inline functions from this file, or you compile -// this file and link it with other files to produce an executable, this -// file does not by itself cause the resulting executable to be covered by -// the GNU General Public License. This exception does not however -// invalidate any other reasons why the executable file might be covered by -// the GNU General Public License. - -// This file provides the following: -// -// input_iterator_wrapper, output_iterator_wrapper -// forward_iterator_wrapper, bidirectional_iterator_wrapper and -// random_access_wrapper, which attempt to exactly perform the requirements -// of these types of iterators. These are constructed from the class -// test_container, which is given two pointers to T and an iterator type. - -#include -#include - -#ifndef _TESTSUITE_ITERATORS -#define _TESTSUITE_ITERATORS - -#ifdef DISABLE_ITERATOR_DEBUG -#define ITERATOR_VERIFY(x) -#else -#define ITERATOR_VERIFY(x) VERIFY(x) -#endif - -namespace __gnu_test -{ - /** - * @brief Simple container for holding two pointers. - * - * Note that input_iterator_wrapper changes first to denote - * how the valid range of == , ++, etc. change as the iterators are used. - */ - template - struct BoundsContainer - { - T* first; - T* last; - BoundsContainer(T* _first, T* _last) - : first(_first), last(_last) - { } - }; - - // Simple container for holding state of a set of output iterators. - template - struct OutputContainer : public BoundsContainer - { - T* incrementedto; - bool* writtento; - OutputContainer(T* _first, T* _last) - : BoundsContainer(_first, _last), incrementedto(_first) - { - writtento = new bool[this->last - this->first]; - for(int i = 0; i < this->last - this->first; i++) - writtento[i] = false; - } - - ~OutputContainer() - { delete[] writtento; } - }; - - // Produced by output_iterator to allow limited writing to pointer - template - class WritableObject - { - T* ptr; - - public: - OutputContainer* SharedInfo; - WritableObject(T* ptr_in,OutputContainer* SharedInfo_in): - ptr(ptr_in), SharedInfo(SharedInfo_in) - { } - - template - void - operator=(const U& new_val) - { - ITERATOR_VERIFY(SharedInfo->writtento[ptr - SharedInfo->first] == 0); - SharedInfo->writtento[ptr - SharedInfo->first] = 1; - *ptr = new_val; - } - }; - - /** - * @brief output_iterator wrapper for pointer - * - * This class takes a pointer and wraps it to provide exactly - * the requirements of a output_iterator. It should not be - * instansiated directly, but generated from a test_container - */ - template - struct output_iterator_wrapper: public std::iterator - - { - typedef OutputContainer ContainerType; - T* ptr; - ContainerType* SharedInfo; - - output_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in) - :ptr(_ptr), SharedInfo(SharedInfo_in) - { - ITERATOR_VERIFY(ptr >= SharedInfo->first && ptr <= SharedInfo->last); - } - - output_iterator_wrapper(const output_iterator_wrapper& in) - :ptr(in.ptr), SharedInfo(in.SharedInfo) - { } - - WritableObject - operator*() const - { - ITERATOR_VERIFY(ptr < SharedInfo->last); - ITERATOR_VERIFY(SharedInfo->writtento[ptr - SharedInfo->first] == false); - return WritableObject(ptr, SharedInfo); - } - - output_iterator_wrapper& - operator=(const output_iterator_wrapper& in) - { - ptr = in.ptr; - SharedInfo = in.SharedInfo; - return *this; - } - - output_iterator_wrapper& - operator++() - { - ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last); - ITERATOR_VERIFY(ptr>=SharedInfo->incrementedto); - ptr++; - SharedInfo->incrementedto=ptr; - return *this; - } - - output_iterator_wrapper - operator++(int) - { - output_iterator_wrapper tmp = *this; - ++*this; - return tmp; - } - - }; - - /** - * @brief input_iterator wrapper for pointer - * - * This class takes a pointer and wraps it to provide exactly - * the requirements of a input_iterator. It should not be - * instansiated directly, but generated from a test_container - */ - template - class input_iterator_wrapper:public std::iterator - - { - protected: - input_iterator_wrapper() - { } - - public: - typedef BoundsContainer ContainerType; - T* ptr; - ContainerType* SharedInfo; - - input_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in) - : ptr(_ptr), SharedInfo(SharedInfo_in) - { ITERATOR_VERIFY(ptr >= SharedInfo->first && ptr <= SharedInfo->last); } - - input_iterator_wrapper(const input_iterator_wrapper& in) - : ptr(in.ptr), SharedInfo(in.SharedInfo) - { } - - bool - operator==(const input_iterator_wrapper& in) const - { - ITERATOR_VERIFY(SharedInfo != NULL && SharedInfo == in.SharedInfo); - ITERATOR_VERIFY(ptr>=SharedInfo->first && in.ptr>=SharedInfo->first); - return ptr == in.ptr; - } - - bool - operator!=(const input_iterator_wrapper& in) const - { - return !(*this == in); - } - - T& - operator*() const - { - ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last); - ITERATOR_VERIFY(ptr >= SharedInfo->first); - return *ptr; - } - - T* - operator->() const - { - return &**this; - } - - input_iterator_wrapper& - operator=(const input_iterator_wrapper& in) - { - ptr = in.ptr; - SharedInfo = in.SharedInfo; - return *this; - } - - input_iterator_wrapper& - operator++() - { - ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last); - ITERATOR_VERIFY(ptr>=SharedInfo->first); - ptr++; - SharedInfo->first=ptr; - return *this; - } - - void - operator++(int) - { - ++*this; - } - }; - - - /** - * @brief forward_iterator wrapper for pointer - * - * This class takes a pointer and wraps it to provide exactly - * the requirements of a forward_iterator. It should not be - * instansiated directly, but generated from a test_container - */ - template - struct forward_iterator_wrapper:public input_iterator_wrapper - { - typedef BoundsContainer ContainerType; - typedef std::forward_iterator_tag iterator_category; - forward_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in) - :input_iterator_wrapper(_ptr, SharedInfo_in) - { } - - forward_iterator_wrapper(const forward_iterator_wrapper& in) - :input_iterator_wrapper(in) - { } - - forward_iterator_wrapper() - { - this->ptr = NULL; - this->SharedInfo = NULL; - } - - T& - operator*() const - { - ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last); - return *(this->ptr); - } - - T* - operator->() const - { return &**this; } - - forward_iterator_wrapper& - operator++() - { - ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last); - this->ptr++; - return *this; - } - - forward_iterator_wrapper - operator++(int) - { - forward_iterator_wrapper tmp = *this; - ++*this; - return tmp; - } - }; - - /** - * @brief bidirectional_iterator wrapper for pointer - * - * This class takes a pointer and wraps it to provide exactly - * the requirements of a forward_iterator. It should not be - * instansiated directly, but generated from a test_container - */ - template - struct bidirectional_iterator_wrapper:public forward_iterator_wrapper - { - typedef BoundsContainer ContainerType; - typedef std::bidirectional_iterator_tag iterator_category; - bidirectional_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in) - :forward_iterator_wrapper(_ptr, SharedInfo_in) - { } - - bidirectional_iterator_wrapper(const bidirectional_iterator_wrapper& in) - :forward_iterator_wrapper(in) - { } - - bidirectional_iterator_wrapper(): forward_iterator_wrapper() - { } - - bidirectional_iterator_wrapper& - operator=(const bidirectional_iterator_wrapper& in) - { - this->ptr = in.ptr; - this->SharedInfo = in.SharedInfo; - return *this; - } - - bidirectional_iterator_wrapper& - operator++() - { - ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last); - this->ptr++; - return *this; - } - - bidirectional_iterator_wrapper - operator++(int) - { - bidirectional_iterator_wrapper tmp = *this; - ++*this; - return tmp; - } - - bidirectional_iterator_wrapper& - operator--() - { - ITERATOR_VERIFY(this->SharedInfo && this->ptr > this->SharedInfo->first); - this->ptr--; - return *this; - } - - bidirectional_iterator_wrapper - operator--(int) - { - bidirectional_iterator_wrapper tmp = *this; - --*this; - return tmp; - } - }; - - /** - * @brief random_access_iterator wrapper for pointer - * - * This class takes a pointer and wraps it to provide exactly - * the requirements of a forward_iterator. It should not be - * instansiated directly, but generated from a test_container - */ - template - struct random_access_iterator_wrapper:public bidirectional_iterator_wrapper - { - typedef BoundsContainer ContainerType; - typedef std::random_access_iterator_tag iterator_category; - random_access_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in) - : bidirectional_iterator_wrapper(_ptr, SharedInfo_in) - { } - - random_access_iterator_wrapper(const random_access_iterator_wrapper& in) - : bidirectional_iterator_wrapper(in) - { } - - random_access_iterator_wrapper():bidirectional_iterator_wrapper() - { } - - random_access_iterator_wrapper& - operator=(const random_access_iterator_wrapper& in) - { - this->ptr = in.ptr; - this->SharedInfo = in.SharedInfo; - return *this; - } - - random_access_iterator_wrapper& - operator++() - { - ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last); - this->ptr++; - return *this; - } - - random_access_iterator_wrapper - operator++(int) - { - random_access_iterator_wrapper tmp = *this; - ++*this; - return tmp; - } - - random_access_iterator_wrapper& - operator--() - { - ITERATOR_VERIFY(this->SharedInfo && this->ptr > this->SharedInfo->first); - this->ptr--; - return *this; - } - - random_access_iterator_wrapper - operator--(int) - { - random_access_iterator_wrapper tmp = *this; - --*this; - return tmp; - } - - random_access_iterator_wrapper& - operator+=(ptrdiff_t n) - { - if(n > 0) - { - ITERATOR_VERIFY(n <= this->SharedInfo->last - this->ptr); - this->ptr += n; - } - else - { - ITERATOR_VERIFY(n <= this->ptr - this->SharedInfo->first); - this->ptr += n; - } - return *this; - } - - random_access_iterator_wrapper& - operator-=(ptrdiff_t n) - { return *this += -n; } - - random_access_iterator_wrapper - operator-(ptrdiff_t n) const - { - random_access_iterator_wrapper tmp = *this; - return tmp -= n; - } - - ptrdiff_t - operator-(const random_access_iterator_wrapper& in) const - { - ITERATOR_VERIFY(this->SharedInfo == in.SharedInfo); - return this->ptr - in.ptr; - } - - T& - operator[](ptrdiff_t n) const - { return *(*this + n); } - - bool - operator<(const random_access_iterator_wrapper& in) const - { - ITERATOR_VERIFY(this->SharedInfo == in.SharedInfo); - return this->ptr < in.ptr; - } - - bool - operator>(const random_access_iterator_wrapper& in) const - { - return in < *this; - } - - bool - operator>=(const random_access_iterator_wrapper& in) const - { - return !(*this < in); - } - - bool - operator<=(const random_access_iterator_wrapper& in) const - { - return !(*this > in); - } - }; - - template - random_access_iterator_wrapper - operator+(random_access_iterator_wrapper it, ptrdiff_t n) - { return it += n; } - - template - random_access_iterator_wrapper - operator+(ptrdiff_t n, random_access_iterator_wrapper it) - { return it += n; } - - - /** - * @brief A container-type class for holding iterator wrappers - * test_container takes two parameters, a class T and an iterator - * wrapper templated by T (for example forward_iterator_wrapper. - * It takes two pointers representing a range and presents them as - * a container of iterators. - */ - template class ItType> - struct test_container - { - typename ItType::ContainerType bounds; - test_container(T* _first, T* _last):bounds(_first, _last) - { } - - ItType - it(int pos) - { - ITERATOR_VERIFY(pos >= 0 && pos <= (bounds.last - bounds.first)); - return ItType(bounds.first + pos, &bounds); - } - - ItType - it(T* pos) - { - ITERATOR_VERIFY(pos >= bounds.first && pos <= bounds.last); - return ItType(pos, &bounds); - } - - ItType - begin() - { return it(bounds.first); } - - ItType - end() - { return it(bounds.last); } - }; -} -#endif diff --git a/libstdc++-v3/testsuite/testsuite_performance.h b/libstdc++-v3/testsuite/testsuite_performance.h deleted file mode 100644 index f902dd0c6d9..00000000000 --- a/libstdc++-v3/testsuite/testsuite_performance.h +++ /dev/null @@ -1,263 +0,0 @@ -// -*- C++ -*- -// Testing performance utilities for the C++ library testsuite. -// -// Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. -// -// This file is part of the GNU ISO C++ Library. This library is free -// software; you can redistribute it and/or modify it under the -// terms of the GNU General Public License as published by the -// Free Software Foundation; either version 2, or (at your option) -// any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, -// USA. -// -// As a special exception, you may use this file as part of a free software -// library without restriction. Specifically, if other files instantiate -// templates or use macros or inline functions from this file, or you compile -// this file and link it with other files to produce an executable, this -// file does not by itself cause the resulting executable to be covered by -// the GNU General Public License. This exception does not however -// invalidate any other reasons why the executable file might be covered by -// the GNU General Public License. - -#ifndef _GLIBCXX_PERFORMANCE_H -#define _GLIBCXX_PERFORMANCE_H - -#include -#include -#include -#include -#include -#include - -#ifdef __linux__ -#include -#elif defined (__FreeBSD__) -extern "C" -{ - struct mallinfo - { - int uordblks; - int hblkhd; - }; - - struct mallinfo - mallinfo(void) - { - struct mallinfo m = { (((size_t) sbrk (0) + 1023) / 1024), 0 }; - return m; - } -} -#elif !defined (__hpux__) -extern "C" -{ - struct mallinfo - { - int uordblks; - int hblkhd; - }; - - struct mallinfo empty = { 0, 0 }; - - struct mallinfo - mallinfo(void) - { return empty; } -} -#endif - -namespace __gnu_test -{ - class time_counter - { - private: - clock_t elapsed_begin; - clock_t elapsed_end; - tms tms_begin; - tms tms_end; - - public: - explicit - time_counter() : elapsed_begin(), elapsed_end(), tms_begin(), tms_end() - { } - - void - clear() throw() - { - elapsed_begin = clock_t(); - elapsed_end = clock_t(); - tms_begin = tms(); - tms_end = tms(); - } - - void - start() - { - this->clear(); - elapsed_begin = times(&tms_begin); - const clock_t err = clock_t(-1); - if (elapsed_begin == err) - std::__throw_runtime_error("time_counter::start"); - } - - void - stop() - { - elapsed_end = times(&tms_end); - const clock_t err = clock_t(-1); - if (elapsed_end == err) - std::__throw_runtime_error("time_counter::stop"); - } - - size_t - real_time() const - { return elapsed_end - elapsed_begin; } - - size_t - user_time() const - { return tms_end.tms_utime - tms_begin.tms_utime; } - - size_t - system_time() const - { return tms_end.tms_stime - tms_begin.tms_stime; } - }; - - class resource_counter - { - int who; - rusage rusage_begin; - rusage rusage_end; - struct mallinfo allocation_begin; - struct mallinfo allocation_end; - - public: - resource_counter(int i = RUSAGE_SELF) : who(i) - { this->clear(); } - - void - clear() throw() - { - memset(&rusage_begin, 0, sizeof(rusage_begin)); - memset(&rusage_end, 0, sizeof(rusage_end)); - memset(&allocation_begin, 0, sizeof(allocation_begin)); - memset(&allocation_end, 0, sizeof(allocation_end)); - } - - void - start() - { - if (getrusage(who, &rusage_begin) != 0 ) - memset(&rusage_begin, 0, sizeof(rusage_begin)); - malloc(0); // Needed for some implementations. - allocation_begin = mallinfo(); - } - - void - stop() - { - if (getrusage(who, &rusage_end) != 0 ) - memset(&rusage_end, 0, sizeof(rusage_end)); - allocation_end = mallinfo(); - } - - int - allocated_memory() const - { return ((allocation_end.uordblks - allocation_begin.uordblks) - + (allocation_end.hblkhd - allocation_begin.hblkhd)); } - - long - hard_page_fault() const - { return rusage_end.ru_majflt - rusage_begin.ru_majflt; } - - long - swapped() const - { return rusage_end.ru_nswap - rusage_begin.ru_nswap; } - }; - - inline void - start_counters(time_counter& t, resource_counter& r) - { - t.start(); - r.start(); - } - - inline void - stop_counters(time_counter& t, resource_counter& r) - { - t.stop(); - r.stop(); - } - - inline void - clear_counters(time_counter& t, resource_counter& r) - { - t.clear(); - r.clear(); - } - - void - report_performance(const std::string file, const std::string comment, - const time_counter& t, const resource_counter& r) - { - const char space = ' '; - const char tab = '\t'; - const char* name = "libstdc++-performance.sum"; - std::string::const_iterator i = file.begin() + file.find_last_of('/') + 1; - std::string testname(i, file.end()); - - std::ofstream out(name, std::ios_base::app); - -#ifdef __GTHREADS - if (__gthread_active_p()) - testname.append("-thread"); -#endif - - out.setf(std::ios_base::left); - out << std::setw(25) << testname << tab; - out << std::setw(25) << comment << tab; - - out.setf(std::ios_base::right); - out << std::setw(4) << t.real_time() << "r" << space; - out << std::setw(4) << t.user_time() << "u" << space; - out << std::setw(4) << t.system_time() << "s" << space; - out << std::setw(8) << r.allocated_memory() << "mem" << space; - out << std::setw(4) << r.hard_page_fault() << "pf" << space; - - out << std::endl; - out.close(); - } - - void - report_header(const std::string file, const std::string header) - { - const char space = ' '; - const char tab = '\t'; - const char* name = "libstdc++-performance.sum"; - std::string::const_iterator i = file.begin() + file.find_last_of('/') + 1; - std::string testname(i, file.end()); - - std::ofstream out(name, std::ios_base::app); - -#ifdef __GTHREADS - if (__gthread_active_p ()) - testname.append("-thread"); -#endif - - out.setf(std::ios_base::left); - out << std::setw(25) << testname << tab; - out << std::setw(40) << header << tab; - - out << std::endl; - out.close(); - } -}; // namespace __gnu_test - -#endif // _GLIBCXX_PERFORMANCE_H - diff --git a/libstdc++-v3/testsuite/testsuite_shared.cc b/libstdc++-v3/testsuite/testsuite_shared.cc deleted file mode 100644 index d651442ed03..00000000000 --- a/libstdc++-v3/testsuite/testsuite_shared.cc +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. -// -// This file is part of the GNU ISO C++ Library. This library is free -// software; you can redistribute it and/or modify it under the -// terms of the GNU General Public License as published by the -// Free Software Foundation; either version 2, or (at your option) -// any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, -// USA. - -#include -#include -#include -#include -#include - -// libstdc++/22309 -extern "C" void -try_allocation() -{ - typedef char value_t; - - typedef __gnu_cxx::__mt_alloc allocator_t; - - typedef std::char_traits traits_t; - typedef std::basic_string string_t; - - string_t s; - s += "west beach, indiana dunes"; -} - -// libstdc++/23591 -extern "C" void -try_throw_exception() -{ - try - { - throw std::bad_exception(); - } - catch (const std::exception& e) - { } -} - -extern "C" void -try_function_random_fail() -{ - long seed = lrand48(); - if (seed < 2000) - seed = 2000; - - { - std::ostringstream s; - s << "random_throw, seed: " << seed << std::endl; - std::cout << s.str(); - } - - while (--seed > 0) - { - try_throw_exception(); - } - - // Randomly throw. See if other threads cleanup. - throw std::bad_exception(); -} diff --git a/libstdc++-v3/testsuite/testsuite_tr1.h b/libstdc++-v3/testsuite/testsuite_tr1.h deleted file mode 100644 index 439d435ee8b..00000000000 --- a/libstdc++-v3/testsuite/testsuite_tr1.h +++ /dev/null @@ -1,192 +0,0 @@ -// -*- C++ -*- -// Testing utilities for the tr1 testsuite. -// -// Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. -// -// This file is part of the GNU ISO C++ Library. This library is free -// software; you can redistribute it and/or modify it under the -// terms of the GNU General Public License as published by the -// Free Software Foundation; either version 2, or (at your option) -// any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, -// USA. -// -// As a special exception, you may use this file as part of a free software -// library without restriction. Specifically, if other files instantiate -// templates or use macros or inline functions from this file, or you compile -// this file and link it with other files to produce an executable, this -// file does not by itself cause the resulting executable to be covered by -// the GNU General Public License. This exception does not however -// invalidate any other reasons why the executable file might be covered by -// the GNU General Public License. - -#ifndef _GLIBCXX_TESTSUITE_TR1_H -#define _GLIBCXX_TESTSUITE_TR1_H - -#include - -namespace __gnu_test -{ - // For tr1/type_traits. - template class Category, - typename Type> - bool - test_category(bool value) - { - bool ret = true; - ret &= Category::value == value; - ret &= Category::value == value; - ret &= Category::value == value; - ret &= Category::value == value; - ret &= Category::type::value == value; - ret &= Category::type::value == value; - ret &= Category::type::value == value; - ret &= Category::type::value == value; - return ret; - } - - template class Property, - typename Type> - bool - test_property(typename Property::value_type value) - { - bool ret = true; - ret &= Property::value == value; - ret &= Property::type::value == value; - return ret; - } - - // For testing tr1/type_traits/extent, which has a second template - // parameter. - template class Property, - typename Type, - unsigned Uint> - bool - test_property(typename Property::value_type value) - { - bool ret = true; - ret &= Property::value == value; - ret &= Property::type::value == value; - return ret; - } - - template class Relationship, - typename Type1, typename Type2> - bool - test_relationship(bool value) - { - bool ret = true; - ret &= Relationship::value == value; - ret &= Relationship::type::value == value; - return ret; - } - - // Test types. - class ClassType { }; - typedef const ClassType cClassType; - typedef volatile ClassType vClassType; - typedef const volatile ClassType cvClassType; - - class DerivedType : public ClassType { }; - - enum EnumType { }; - - struct ConvType - { operator int() const; }; - - class AbstractClass - { - virtual void rotate(int) = 0; - virtual ~AbstractClass(); - }; - - class PolymorphicClass - { - virtual void rotate(int); - virtual ~PolymorphicClass(); - }; - - class DerivedPolymorphic : public PolymorphicClass { }; - - union UnionType { }; - - class IncompleteClass; - - int truncate_float(float x) { return (int)x; } - long truncate_double(double x) { return (long)x; } - - struct do_truncate_float_t - { - do_truncate_float_t() - { - ++live_objects; - } - - do_truncate_float_t(const do_truncate_float_t&) - { - ++live_objects; - } - - ~do_truncate_float_t() - { - --live_objects; - } - - int operator()(float x) { return (int)x; } - - static int live_objects; - }; - - int do_truncate_float_t::live_objects = 0; - - struct do_truncate_double_t - { - do_truncate_double_t() - { - ++live_objects; - } - - do_truncate_double_t(const do_truncate_double_t&) - { - ++live_objects; - } - - ~do_truncate_double_t() - { - --live_objects; - } - - long operator()(double x) { return (long)x; } - - static int live_objects; - }; - - int do_truncate_double_t::live_objects = 0; - - struct X - { - int bar; - - int foo() { return 1; } - int foo_c() const { return 2; } - int foo_v() volatile { return 3; } - int foo_cv() const volatile { return 4; } - }; - - // For use in 8_c_compatibility. - template - typename std::__enable_if::__value>::__type - check_ret_type(T) - { return true; } - -} // namespace __gnu_test - -#endif // _GLIBCXX_TESTSUITE_TR1_H diff --git a/libstdc++-v3/testsuite/testsuite_visualization.h b/libstdc++-v3/testsuite/testsuite_visualization.h deleted file mode 100644 index 0e2757666a4..00000000000 --- a/libstdc++-v3/testsuite/testsuite_visualization.h +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright (C) 2005 Free Software Foundation, Inc. -// -// This file is part of the GNU ISO C++ Library. This library is free -// software; you can redistribute it and/or modify it under the -// terms of the GNU General Public License as published by the -// Free Software Foundation; either version 2, or (at your option) -// any later version. - -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License along -// with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, -// USA. - -// As a special exception, you may use this file as part of a free software -// library without restriction. Specifically, if other files instantiate -// templates or use macros or inline functions from this file, or you compile -// this file and link it with other files to produce an executable, this -// file does not by itself cause the resulting executable to be covered by -// the GNU General Public License. This exception does not however -// invalidate any other reasons why the executable file might be covered by -// the GNU General Public License. - -#include -#include -#include -#include -#include -#include - -// Ah, we wish it wasn't so... -bool first_container = false; -extern const char* filename; - -typedef std::string::size_type (*callback_type) (std::string&); - -template - void - write_viz_container(callback_type find_container, const char* filename) - { - typedef std::string string; - - // Create title. - { - const char ws(' '); - std::ostringstream title; - - std::string titlename(filename); - std::string::size_type n = titlename.find('.'); - if (n != string::npos) - titlename = std::string(titlename.begin(), titlename.begin() + n); - - title << titlename; - title << ws; - title << Iter; - title << ws; -#if 0 - title << "thread<"; - std::boolalpha(title); - title << Thread; - title << '>'; -#endif - - titlename += ".title"; - std::ofstream titlefile(titlename.c_str()); - if (!titlefile.good()) - throw std::runtime_error("write_viz_data cannot open titlename"); - titlefile << title.str() << std::endl; - } - - // Create compressed type name. - Container obj; - int status; - std::string type(abi::__cxa_demangle(typeid(obj).name(), 0, 0, &status)); - - // Extract fully-qualified typename. - // Assumes "set" or "map" are uniquely determinate. - string::iterator beg = type.begin(); - string::iterator end; - string::size_type n = (*find_container)(type); - - // Find start of fully-qualified name. - // Assume map, find end. - string::size_type nend = type.find('<', n); - if (nend != string::npos) - end = type.begin() + nend; - - string compressed_type; - compressed_type += '"'; - compressed_type += string(beg, end); - compressed_type += '<'; -#if 0 - typename Container::key_type v; - compressed_type += typeid(v).name(); -#else - compressed_type += "int"; -#endif - compressed_type += ", A>"; - - // XXX - if (Thread == true) - compressed_type += " thread"; - compressed_type += '"'; - - std::ofstream file(filename, std::ios_base::app); - if (!file.good()) - throw std::runtime_error("write_viz_data cannot open filename"); - - file << compressed_type; - first_container = false; - } - - -void -write_viz_data(__gnu_test::time_counter& time, const char* filename) -{ - std::ofstream file(filename, std::ios_base::app); - if (!file.good()) - throw std::runtime_error("write_viz_data cannot open filename"); - - // Print out score in appropriate column. - const char tab('\t'); - int score = time.real_time(); - file << tab << score; -} - -void -write_viz_endl(const char* filename) -{ - std::ofstream file(filename, std::ios_base::app); - if (!file.good()) - throw std::runtime_error("write_viz_endl cannot open filename"); - file << std::endl; -} - - -#if 0 -// cons -write_viz_container(&sequence_find_container, - filename); -#endif - -#if 0 -// dtor -write_viz_endl(filename) -#endif diff --git a/libstdc++-v3/testsuite/util/testsuite_abi.cc b/libstdc++-v3/testsuite/util/testsuite_abi.cc new file mode 100644 index 00000000000..6ed559f3e73 --- /dev/null +++ b/libstdc++-v3/testsuite/util/testsuite_abi.cc @@ -0,0 +1,530 @@ +// -*- C++ -*- + +// Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. + +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2, or (at +// your option) any later version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, +// MA 02110-1301, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Benjamin Kosnik + +#include "testsuite_abi.h" +#include +#include +#include + +using namespace std; + +void +symbol::init(string& data) +{ + const char delim = ':'; + const char version_delim = '@'; + const string::size_type npos = string::npos; + string::size_type n = 0; + + // Set the type. + if (data.find("FUNC") == 0) + type = symbol::function; + else if (data.find("OBJECT") == 0) + type = symbol::object; + + n = data.find_first_of(delim); + if (n != npos) + data.erase(data.begin(), data.begin() + n + 1); + + // Iff object, get size info. + if (type == symbol::object) + { + n = data.find_first_of(delim); + if (n != npos) + { + string size(data.begin(), data.begin() + n); + istringstream iss(size); + int x; + iss >> x; + if (!iss.fail()) + size = x; + data.erase(data.begin(), data.begin() + n + 1); + } + } + + // Set the name and raw_name. + raw_name = string(data.begin(), data.end()); + n = data.find_first_of(version_delim); + if (n != npos) + { + // Found version string. + name = string(data.begin(), data.begin() + n); + n = data.find_last_of(version_delim); + data.erase(data.begin(), data.begin() + n + 1); + + // Set version name. + version_name = data; + } + else + { + // No versioning info. + name = string(data.begin(), data.end()); + version_status = symbol::none; + } + + // Set the demangled name. + demangled_name = demangle(name); +} + +void +symbol::print() const +{ + const char tab = '\t'; + cout << name << endl; + + if (demangled_name != name) + cout << demangled_name << endl; + + string vers; + switch (version_status) + { + case none: + vers = "none"; + break; + case compatible: + vers = "compatible"; + break; + case incompatible: + vers = "incompatible"; + break; + case unversioned: + vers = "unversioned"; + break; + default: + vers = ""; + } + cout << "version status: " << vers << endl; + + if (version_name.size() + && (version_status == compatible || version_status == incompatible)) + cout << version_name << endl; + + string type_string; + switch (type) + { + case function: + type_string = "function"; + break; + case object: + type_string = "object"; + break; + case uncategorized: + type_string = "uncategorized"; + break; + default: + type_string = ""; + } + cout << "type: " << type_string << endl; + + if (type == object) + cout << "type size: " << size << endl; + + string status_string; + switch (status) + { + case added: + status_string = "added"; + break; + case subtracted: + status_string = "subtracted"; + break; + case undesignated: + status_string = "undesignated"; + break; + default: + status_string = ""; + } + cout << "status: " << status_string << endl; + + cout << endl; +} + + +bool +check_version(symbol& test, bool added) +{ + // Construct list of compatible versions. + typedef std::vector compat_list; + static compat_list known_versions; + if (known_versions.empty()) + { + // NB: First version here must be the default version for this + // version of DT_SONAME. + known_versions.push_back("GLIBCXX_3.4"); + known_versions.push_back("GLIBCXX_3.4.1"); + known_versions.push_back("GLIBCXX_3.4.2"); + known_versions.push_back("GLIBCXX_3.4.3"); + known_versions.push_back("GLIBCXX_3.4.4"); + known_versions.push_back("GLIBCXX_3.4.5"); + known_versions.push_back("GLIBCXX_3.4.6"); + known_versions.push_back("GLIBCXX_3.4.7"); + known_versions.push_back("GLIBCXX_3.4.8"); + known_versions.push_back("GLIBCXX_3.4.9"); + known_versions.push_back("GLIBCXX_LDBL_3.4"); + known_versions.push_back("GLIBCXX_LDBL_3.4.7"); + known_versions.push_back("CXXABI_1.3"); + known_versions.push_back("CXXABI_1.3.1"); + known_versions.push_back("CXXABI_LDBL_1.3"); + } + compat_list::iterator begin = known_versions.begin(); + compat_list::iterator end = known_versions.end(); + + // Check for compatible version. + if (test.version_name.size()) + { + compat_list::iterator it1 = find(begin, end, test.version_name); + compat_list::iterator it2 = find(begin, end, test.name); + if (it1 != end) + test.version_status = symbol::compatible; + else + test.version_status = symbol::incompatible; + + // Check that added symbols aren't added in the base version. + if (added && test.version_name == known_versions[0]) + test.version_status = symbol::incompatible; + + // Check for weak label. + if (it1 == end && it2 == end) + test.version_status = symbol::incompatible; + + // Check that + // GLIBCXX_3.4 + // GLIBCXX_3.4.5 + // version as compatible + // XXX + } + else + { + if (added) + { + // New version labels are ok. The rest are not. + compat_list::iterator it2 = find(begin, end, test.name); + if (it2 != end) + test.version_status = symbol::compatible; + else + test.version_status = symbol::incompatible; + } + } + return test.version_status == symbol::compatible; +} + +bool +check_compatible(symbol& lhs, symbol& rhs, bool verbose) +{ + bool ret = true; + const char tab = '\t'; + + // Check to see if symbol_objects are compatible. + if (lhs.type != rhs.type) + { + ret = false; + if (verbose) + cout << tab << "incompatible types" << endl; + } + + if (lhs.name != rhs.name) + { + ret = false; + if (verbose) + cout << tab << "incompatible names" << endl; + } + + if (lhs.size != rhs.size) + { + ret = false; + if (verbose) + { + cout << tab << "incompatible sizes" << endl; + cout << tab << lhs.size << endl; + cout << tab << rhs.size << endl; + } + } + + if (lhs.version_name != rhs.version_name + && !check_version(lhs) && !check_version(rhs)) + { + ret = false; + if (verbose) + { + cout << tab << "incompatible versions" << endl; + cout << tab << lhs.version_name << endl; + cout << tab << rhs.version_name << endl; + } + } + + if (verbose) + cout << endl; + + return ret; +} + + +bool +has_symbol(const string& mangled, const symbols& s) throw() +{ + const symbol_names& names = s.first; + symbol_names::const_iterator i = find(names.begin(), names.end(), mangled); + return i != names.end(); +} + +symbol& +get_symbol(const string& mangled, const symbols& s) +{ + const symbol_names& names = s.first; + symbol_names::const_iterator i = find(names.begin(), names.end(), mangled); + if (i != names.end()) + { + symbol_objects objects = s.second; + return objects[mangled]; + } + else + { + ostringstream os; + os << "get_symbol failed for symbol " << mangled; + __throw_logic_error(os.str().c_str()); + } +} + +void +examine_symbol(const char* name, const char* file) +{ + try + { + symbols s = create_symbols(file); + symbol& sym = get_symbol(name, s); + sym.print(); + } + catch(...) + { __throw_exception_again; } +} + +int +compare_symbols(const char* baseline_file, const char* test_file, + bool verbose) +{ + // Input both lists of symbols into container. + symbols baseline = create_symbols(baseline_file); + symbols test = create_symbols(test_file); + symbol_names& baseline_names = baseline.first; + symbol_objects& baseline_objects = baseline.second; + symbol_names& test_names = test.first; + symbol_objects& test_objects = test.second; + + // Sanity check results. + const symbol_names::size_type baseline_size = baseline_names.size(); + const symbol_names::size_type test_size = test_names.size(); + if (!baseline_size || !test_size) + { + cerr << "Problems parsing the list of exported symbols." << endl; + exit(2); + } + + // Sort out names. + // Assuming baseline_names, test_names are both unique w/ no duplicates. + // + // The names added to missing_names are baseline_names not found in + // test_names + // -> symbols that have been deleted. + // + // The names added to added_names are test_names not in + // baseline_names + // -> symbols that have been added. + symbol_names shared_names; + symbol_names missing_names; + symbol_names added_names = test_names; + for (size_t i = 0; i < baseline_size; ++i) + { + string what(baseline_names[i]); + symbol_names::iterator end = added_names.end(); + symbol_names::iterator it = find(added_names.begin(), end, what); + if (it != end) + { + // Found. + shared_names.push_back(what); + added_names.erase(it); + } + else + missing_names.push_back(what); + } + + // Check missing names for compatibility. + typedef pair symbol_pair; + vector incompatible; + const symbol_names::size_type missing_size = missing_names.size(); + for (size_t j = 0; j < missing_size; ++j) + { + symbol& base = baseline_objects[missing_names[j]]; + base.status = symbol::subtracted; + incompatible.push_back(symbol_pair(base, base)); + } + + // Check shared names for compatibility. + const symbol_names::size_type shared_size = shared_names.size(); + for (size_t k = 0; k < shared_size; ++k) + { + symbol& base = baseline_objects[shared_names[k]]; + symbol& test = test_objects[shared_names[k]]; + test.status = symbol::existing; + if (!check_compatible(base, test)) + incompatible.push_back(symbol_pair(base, test)); + } + + // Check added names for compatibility. + const symbol_names::size_type added_size = added_names.size(); + for (size_t l = 0; l < added_size; ++l) + { + symbol& test = test_objects[added_names[l]]; + test.status = symbol::added; + if (!check_version(test, true)) + incompatible.push_back(symbol_pair(test, test)); + } + + // Report results. + if (verbose && added_names.size()) + { + cout << endl << added_names.size() << " added symbols " << endl; + for (size_t j = 0; j < added_names.size() ; ++j) + { + cout << j << endl; + test_objects[added_names[j]].print(); + } + } + + if (verbose && missing_names.size()) + { + cout << endl << missing_names.size() << " missing symbols " << endl; + for (size_t j = 0; j < missing_names.size() ; ++j) + { + cout << j << endl; + baseline_objects[missing_names[j]].print(); + } + } + + if (verbose && incompatible.size()) + { + cout << endl << incompatible.size() << " incompatible symbols " << endl; + for (size_t j = 0; j < incompatible.size() ; ++j) + { + // First, print index. + cout << j << endl; + + // Second, report name. + symbol& base = incompatible[j].first; + symbol& test = incompatible[j].second; + test.print(); + + // Second, report reason or reasons incompatible. + check_compatible(base, test, true); + } + } + + cout << "\n\t\t=== libstdc++-v3 check-abi Summary ===" << endl; + cout << endl; + cout << "# of added symbols:\t\t " << added_names.size() << endl; + cout << "# of missing symbols:\t\t " << missing_names.size() << endl; + cout << "# of incompatible symbols:\t " << incompatible.size() << endl; + cout << endl; + cout << "using: " << baseline_file << endl; + + return !(missing_names.size() || incompatible.size()); +} + + +symbols +create_symbols(const char* file) +{ + symbols s; + ifstream ifs(file); + if (ifs.is_open()) + { + // Organize file data into container of symbol objects, and a + // container of mangled names without versioning information. + symbol_names& names = s.first; + symbol_objects& objects = s.second; + const string empty; + string line = empty; + while (getline(ifs, line).good()) + { + symbol tmp; + tmp.init(line); + objects[tmp.name] = tmp; + names.push_back(tmp.name); + line = empty; + } + } + else + { + ostringstream os; + os << "create_symbols failed for file " << file; + __throw_runtime_error(os.str().c_str()); + } + return s; +} + + +const char* +demangle(const std::string& mangled) +{ + const char* name; + if (mangled[0] != '_' || mangled[1] != 'Z') + { + // This is not a mangled symbol, thus has "C" linkage. + name = mangled.c_str(); + } + else + { + // Use __cxa_demangle to demangle. + int status = 0; + name = abi::__cxa_demangle(mangled.c_str(), 0, 0, &status); + if (!name) + { + switch (status) + { + case 0: + name = "error code = 0: success"; + break; + case -1: + name = "error code = -1: memory allocation failure"; + break; + case -2: + name = "error code = -2: invalid mangled name"; + break; + case -3: + name = "error code = -3: invalid arguments"; + break; + default: + name = "error code unknown - who knows what happened"; + } + } + } + return name; +} + diff --git a/libstdc++-v3/testsuite/util/testsuite_abi.h b/libstdc++-v3/testsuite/util/testsuite_abi.h new file mode 100644 index 00000000000..935d95bd1fe --- /dev/null +++ b/libstdc++-v3/testsuite/util/testsuite_abi.h @@ -0,0 +1,128 @@ +// -*- C++ -*- + +// Copyright (C) 2004, 2005 Free Software Foundation, Inc. + +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2, or (at +// your option) any later version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, +// MA 02110-1301, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Benjamin Kosnik + +#include +#include +#include +#include +#include + +// Encapsulates symbol characteristics. +struct symbol +{ + enum category { function, object, uncategorized }; + enum designation { existing, added, subtracted, undesignated }; + enum version { none, compatible, incompatible, unversioned }; + enum compatibility + { + compat_type = 1, + compat_name = 2, + compat_size = 4, + compat_version = 8 + }; + + category type; + std::string name; + std::string raw_name; // Name with versioning info still attached. + std::string demangled_name; + int size; + std::string version_name; + version version_status; + designation status; + + symbol() + : type(uncategorized), size(0), version_status(unversioned), + status(undesignated) { } + + symbol(const symbol& other) + : type(other.type), name(other.name), demangled_name(other.demangled_name), + size(other.size), version_name(other.version_name), + version_status(other.version_status), status(other.status) { } + + void + print() const; + + void + init(std::string& data); +}; + +typedef __gnu_cxx::hash_map symbol_objects; + +typedef std::deque symbol_names; + +typedef std::pair symbols; + + +// Check. +bool +check_version(symbol& test, bool added = false); + +bool +check_compatible(symbol& lhs, symbol& rhs, bool verbose = false); + + +// Examine. +bool +has_symbol(const std::string& mangled, const symbols& list) throw(); + +symbol& +get_symbol(const std::string& mangled, const symbols& list); + +extern "C" void +examine_symbol(const char* name, const char* file); + +extern "C" int +compare_symbols(const char* baseline_file, const char* test_file, bool verb); + + +// Util. +symbols +create_symbols(const char* file); + +const char* +demangle(const std::string& mangled); + + +// Specialization. +namespace __gnu_cxx +{ + using namespace std; + + template<> + struct hash + { + size_t operator()(const string& s) const + { + const collate& c = use_facet >(locale::classic()); + return c.hash(s.c_str(), s.c_str() + s.size()); + } + }; +} diff --git a/libstdc++-v3/testsuite/util/testsuite_abi_check.cc b/libstdc++-v3/testsuite/util/testsuite_abi_check.cc new file mode 100644 index 00000000000..12e882a436f --- /dev/null +++ b/libstdc++-v3/testsuite/util/testsuite_abi_check.cc @@ -0,0 +1,95 @@ +// -*- C++ -*- + +// Copyright (C) 2004 Free Software Foundation, Inc. + +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2, or (at +// your option) any later version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, +// MA 02110-1301, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Benjamin Kosnik +// Blame subsequent hacks on Loren J. Rittle , Phil +// Edwards , and a cast of dozens at libstdc++@gcc.gnu.org. + +#include "testsuite_abi.h" +#include +#include // for access(2) + +int +main(int argc, char** argv) +{ + using namespace std; + + // Get arguments. (Heading towards getopt_long, I can feel it.) + string argv1 = argc > 1 ? argv[1] : ""; + if (argv1 == "--help" || argc < 4) + { + cerr << "usage: abi_check --check current baseline\n" + " --check-verbose current baseline\n" + " --examine symbol current\n" + " --help\n" + "\n" + "All arguments are string literals.\n" + "CURRENT is a file generated byextract_symvers.\n" + "BASELINE is a file from config/abi.\n" + "SYMBOL is a mangled name.\n" + << endl; + exit(1); + } + + if (argv1.find("--check") != string::npos) + { + bool verbose = false; + if (argv1 == "--check-verbose") + verbose = true; + + // Quick sanity/setup check for arguments. + const char* test_file = argv[2]; + const char* baseline_file = argv[3]; + if (access(test_file, R_OK) != 0) + { + cerr << "Cannot read symbols file " << test_file + << ", did you forget to build first?" << endl; + exit(1); + } + if (access(baseline_file, R_OK) != 0) + { + cerr << "Cannot read baseline file " << baseline_file << endl; + exit(1); + } + if (!compare_symbols(baseline_file, test_file, verbose)) + exit (1); + } + + if (argv1 == "--examine") + { + const char* file = argv[3]; + if (access(file, R_OK) != 0) + { + cerr << "Cannot read symbol file " << file << endl; + exit(1); + } + examine_symbol(argv[2], file); + } + return 0; +} diff --git a/libstdc++-v3/testsuite/util/testsuite_allocator.cc b/libstdc++-v3/testsuite/util/testsuite_allocator.cc new file mode 100644 index 00000000000..66968720555 --- /dev/null +++ b/libstdc++-v3/testsuite/util/testsuite_allocator.cc @@ -0,0 +1,60 @@ +// -*- C++ -*- +// Testing allocator for the C++ library testsuite. +// +// Copyright (C) 2002, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. +// +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#include +#include + +namespace __gnu_test +{ + allocation_tracker::size_type allocation_tracker::allocationTotal_ = 0; + allocation_tracker::size_type allocation_tracker::deallocationTotal_ = 0; + int allocation_tracker::constructCount_ = 0; + int allocation_tracker::destructCount_ = 0; + + bool + check_construct_destroy(const char* tag, int expected_c, int expected_d) + { + if (allocation_tracker::constructCount() == expected_c && + allocation_tracker::destructCount() == expected_d) + return true; + + else { + std::cerr << tag << ": " + << " construct = " << allocation_tracker::constructCount() + << " (should be " << expected_c << ")," + << " destroy = " << allocation_tracker::destructCount() + << " (should be " << expected_d << ")" + << std::endl; + return false; + } + } + +}; // namespace __cxx_test + diff --git a/libstdc++-v3/testsuite/util/testsuite_allocator.h b/libstdc++-v3/testsuite/util/testsuite_allocator.h new file mode 100644 index 00000000000..0ea1215e3b4 --- /dev/null +++ b/libstdc++-v3/testsuite/util/testsuite_allocator.h @@ -0,0 +1,443 @@ +// -*- C++ -*- +// Testing allocator for the C++ library testsuite. +// +// Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. +// +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// This file provides an test instrumentation allocator that can be +// used to verify allocation functionality of standard library +// containers. 2002.11.25 smw + +#ifndef _GLIBCXX_TESTSUITE_ALLOCATOR_H +#define _GLIBCXX_TESTSUITE_ALLOCATOR_H + +#include +#include +#include +#include + +namespace +{ + bool new_called = false; + bool delete_called = false; +}; + +namespace __gnu_test +{ + class allocation_tracker + { + public: + typedef std::size_t size_type; + + static void* + allocate(size_type blocksize) + { + allocationTotal_ += blocksize; + return ::operator new(blocksize); + } + + static void + construct() { constructCount_++; } + + static void + destroy() { destructCount_++; } + + static void + deallocate(void* p, size_type blocksize) + { + ::operator delete(p); + deallocationTotal_ += blocksize; + } + + static size_type + allocationTotal() { return allocationTotal_; } + + static size_type + deallocationTotal() { return deallocationTotal_; } + + static int + constructCount() { return constructCount_; } + + static int + destructCount() { return destructCount_; } + + static void + resetCounts() + { + allocationTotal_ = 0; + deallocationTotal_ = 0; + constructCount_ = 0; + destructCount_ = 0; + } + + private: + static size_type allocationTotal_; + static size_type deallocationTotal_; + static int constructCount_; + static int destructCount_; + }; + + // A simple basic allocator that just forwards to the + // allocation_tracker to fulfill memory requests. This class is + // templated on the target object type, but tracker isn't. + template + class tracker_alloc + { + public: + typedef T value_type; + typedef T* pointer; + typedef const T* const_pointer; + typedef T& reference; + typedef const T& const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + template struct rebind { typedef tracker_alloc other; }; + + pointer + address(reference value) const + { return &value; } + + const_pointer + address(const_reference value) const + { return &value; } + + tracker_alloc() throw() + { } + + tracker_alloc(const tracker_alloc&) throw() + { } + + template + tracker_alloc(const tracker_alloc&) throw() + { } + + ~tracker_alloc() throw() + { } + + size_type + max_size() const throw() + { return std::numeric_limits::max() / sizeof(T); } + + pointer + allocate(size_type n, const void* = 0) + { + return static_cast(allocation_tracker::allocate(n * sizeof(T))); + } + + void + construct(pointer p, const T& value) + { + new (p) T(value); + allocation_tracker::construct(); + } + + void + destroy(pointer p) + { + p->~T(); + allocation_tracker::destroy(); + } + + void + deallocate(pointer p, size_type num) + { allocation_tracker::deallocate(p, num * sizeof(T)); } + }; + + template + bool + operator==(const tracker_alloc&, const tracker_alloc&) throw() + { return true; } + + template + bool + operator!=(const tracker_alloc&, const tracker_alloc&) throw() + { return false; } + + bool + check_construct_destroy(const char* tag, int expected_c, int expected_d); + + template + bool + check_new(Alloc a = Alloc()) + { + bool test __attribute__((unused)) = true; + a.allocate(10); + test &= ( new_called == uses_global_new ); + return test; + } + + template + bool + check_delete(Alloc a = Alloc()) + { + bool test __attribute__((unused)) = true; + typename Alloc::pointer p = a.allocate(10); + a.deallocate(p, 10); + test &= ( delete_called == uses_global_delete ); + return test; + } + + template + bool + check_deallocate_null() + { + // Let's not core here... + Alloc a; + a.deallocate(NULL, 1); + a.deallocate(NULL, 10); + return true; + } + + template + bool + check_allocate_max_size() + { + Alloc a; + try + { + a.allocate(a.max_size() + 1); + } + catch(std::bad_alloc&) + { + return true; + } + catch(...) + { + throw; + } + throw; + } + + + // A simple allocator which can be constructed endowed of a given + // "personality" (an integer), queried in operator== to simulate the + // behavior of realworld "unequal" allocators (i.e., not exploiting + // the provision in 20.1.5/4, first bullet). A global unordered_map, + // filled at allocation time with (pointer, personality) pairs, is + // then consulted to enforce the requirements in Table 32 about + // deallocation vs allocator equality. Note that this allocator is + // swappable, not assignable, consistently with Option 3 of DR 431 + // (see N1599). + struct uneq_allocator_base + { + typedef std::tr1::unordered_map map_type; + + // Avoid static initialization troubles and/or bad interactions + // with tests linking testsuite_allocator.o and playing globally + // with operator new/delete. + static map_type& + get_map() + { + static map_type alloc_map; + return alloc_map; + } + }; + + template + class uneq_allocator + : private uneq_allocator_base + { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef Tp* pointer; + typedef const Tp* const_pointer; + typedef Tp& reference; + typedef const Tp& const_reference; + typedef Tp value_type; + + template + struct rebind + { typedef uneq_allocator other; }; + + uneq_allocator() throw() + : personality(0) { } + + uneq_allocator(int person) throw() + : personality(person) { } + + template + uneq_allocator(const uneq_allocator& b) throw() + : personality(b.get_personality()) { } + + int get_personality() const { return personality; } + + pointer + address(reference x) const { return &x; } + + const_pointer + address(const_reference x) const { return &x; } + + pointer + allocate(size_type n, const void* = 0) + { + if (__builtin_expect(n > this->max_size(), false)) + std::__throw_bad_alloc(); + + pointer p = static_cast(::operator new(n * sizeof(Tp))); + try + { + get_map().insert(map_type::value_type(reinterpret_cast(p), + personality)); + } + catch(...) + { + ::operator delete(p); + __throw_exception_again; + } + return p; + } + + void + deallocate(pointer p, size_type) + { + assert( p ); + + map_type::iterator it = get_map().find(reinterpret_cast(p)); + assert( it != get_map().end() ); + + // Enforce requirements in Table 32 about deallocation vs + // allocator equality. + assert( it->second == personality ); + + get_map().erase(it); + ::operator delete(p); + } + + size_type + max_size() const throw() + { return size_t(-1) / sizeof(Tp); } + + void + construct(pointer p, const Tp& val) + { ::new(p) Tp(val); } + + void + destroy(pointer p) { p->~Tp(); } + + private: + // Not assignable... + uneq_allocator& + operator=(const uneq_allocator&); + + // ... yet swappable! + friend inline void + swap(uneq_allocator& a, uneq_allocator& b) + { std::swap(a.personality, b.personality); } + + template + friend inline bool + operator==(const uneq_allocator& a, const uneq_allocator& b) + { return a.personality == b.personality; } + + template + friend inline bool + operator!=(const uneq_allocator& a, const uneq_allocator& b) + { return !(a == b); } + + int personality; + }; + + + template + class throw_allocator + { + public: + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef Tp* pointer; + typedef const Tp* const_pointer; + typedef Tp& reference; + typedef const Tp& const_reference; + typedef Tp value_type; + + template + struct rebind + { typedef throw_allocator other; }; + + throw_allocator() throw() + : count(size_type(-1)) { } + + throw_allocator(size_type c) throw() + : count(c) { } + + template + throw_allocator(const throw_allocator& b) throw() + : count(b.get_count()) { } + + size_type get_count() const { return count; } + + pointer + address(reference x) const { return &x; } + + const_pointer + address(const_reference x) const { return &x; } + + pointer + allocate(size_type n, const void* = 0) + { + if (count == 0) + throw std::bad_alloc(); + + if (count != size_type(-1)) + --count; + + return static_cast(::operator new(n * sizeof(Tp))); + } + + void + deallocate(pointer p, size_type) + { ::operator delete(p); } + + size_type + max_size() const throw() + { return size_type(-1) / sizeof(Tp); } + + void + construct(pointer p, const Tp& val) + { ::new(p) Tp(val); } + + void + destroy(pointer p) { p->~Tp(); } + + private: + template + friend inline bool + operator==(const throw_allocator&, const throw_allocator&) + { return true; } + + template + friend inline bool + operator!=(const throw_allocator&, const throw_allocator&) + { return false; } + + size_type count; + }; +}; // namespace __gnu_test + +#endif // _GLIBCXX_TESTSUITE_ALLOCATOR_H diff --git a/libstdc++-v3/testsuite/util/testsuite_character.cc b/libstdc++-v3/testsuite/util/testsuite_character.cc new file mode 100644 index 00000000000..63a1fa35bfc --- /dev/null +++ b/libstdc++-v3/testsuite/util/testsuite_character.cc @@ -0,0 +1,195 @@ +// -*- C++ -*- + +// Utility subroutines for the C++ library testsuite. +// +// Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. +// +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#include + +namespace std +{ + locale::id + codecvt<__gnu_test::pod_uchar, char, __gnu_test::pod_state>::id; + + locale::id + ctype<__gnu_test::pod_uchar>::id; + + locale::id + numpunct<__gnu_test::pod_uint>::id; + + locale::id + moneypunct<__gnu_test::pod_uint>::id; + + // Member specializations for the existing facet classes. + // NB: This isn't especially portable. Perhaps a better way would be + // to just specialize all of numpunct and ctype. + using __gnu_test::pod_ushort; + typedef pod_ushort::value_type value_type; + + template<> + bool + ctype:: + do_is(mask, char_type) const { return true; } + + template<> + const pod_ushort* + ctype:: + do_is(const char_type* __lo, const char_type*, mask*) const + { return __lo; } + + template<> + const pod_ushort* + ctype:: + do_scan_is(mask, const char_type* __lo, const char_type*) const + { return __lo; } + + template<> + const pod_ushort* + ctype:: + do_scan_not(mask, const char_type* __lo, const char_type*) const + { return __lo; } + + template<> + pod_ushort + ctype:: + do_toupper(char_type __c) const + { return __c; } + + template<> + const pod_ushort* + ctype:: + do_toupper(char_type*, const char_type* __hi) const + { return __hi; } + + template<> + pod_ushort + ctype:: + do_tolower(char_type __c) const + { return __c; } + + template<> + const pod_ushort* + ctype:: + do_tolower(char_type*, const char_type* __hi) const + { return __hi; } + + template<> + pod_ushort + ctype:: + do_widen(char __c) const + { + char_type ret = { value_type(__c) }; + return ret; + } + + template<> + const char* + ctype:: + do_widen(const char* __lo, const char* __hi, char_type* __dest) const + { + while (__lo < __hi) + { + *__dest = this->do_widen(*__lo); + ++__lo; + ++__dest; + } + return __hi; + } + + template<> + char + ctype:: + do_narrow(char_type __wc, char) const + { return static_cast(__wc.value); } + + template<> + const pod_ushort* + ctype:: + do_narrow(const pod_ushort* __lo, const pod_ushort* __hi, + char, char* __dest) const + { + while (__lo < __hi) + { + *__dest = this->do_narrow(*__lo, char()); + ++__lo; + ++__dest; + } + return __hi; + } + + template<> + ctype::~ctype() { } + + template<> + void + numpunct::_M_initialize_numpunct(__c_locale) + { + if (!_M_data) + _M_data = new __numpunct_cache; + + _M_data->_M_grouping = ""; + _M_data->_M_use_grouping = false; + + _M_data->_M_decimal_point.value = value_type('.'); + _M_data->_M_thousands_sep.value = value_type(','); + + for (size_t i = 0; i < __num_base::_S_oend; ++i) + { + value_type v = __num_base::_S_atoms_out[i]; + _M_data->_M_atoms_out[i].value = v; + } + _M_data->_M_atoms_out[__num_base::_S_oend] = pod_ushort(); + + for (size_t j = 0; j < __num_base::_S_iend; ++j) + _M_data->_M_atoms_in[j].value = value_type(__num_base::_S_atoms_in[j]); + _M_data->_M_atoms_in[__num_base::_S_iend] = pod_ushort(); + + // "true" + pod_ushort* __truename = new pod_ushort[4 + 1]; + __truename[0].value = value_type('t'); + __truename[1].value = value_type('r'); + __truename[2].value = value_type('u'); + __truename[3].value = value_type('e'); + __truename[4] = pod_ushort(); + _M_data->_M_truename = __truename; + + // "false" + pod_ushort* __falsename = new pod_ushort[5 + 1]; + __falsename[0].value = value_type('f'); + __falsename[1].value = value_type('a'); + __falsename[2].value = value_type('l'); + __falsename[3].value = value_type('s'); + __falsename[4].value = value_type('e'); + __falsename[5] = pod_ushort(); + _M_data->_M_falsename = __falsename; + } + + template<> + numpunct::~numpunct() + { delete _M_data; } +} // namespace std diff --git a/libstdc++-v3/testsuite/util/testsuite_character.h b/libstdc++-v3/testsuite/util/testsuite_character.h new file mode 100644 index 00000000000..a9e4847105b --- /dev/null +++ b/libstdc++-v3/testsuite/util/testsuite_character.h @@ -0,0 +1,540 @@ +// -*- C++ -*- + +// Testing character type and state type with char_traits and codecvt +// specializations for the C++ library testsuite. +// +// Copyright (C) 2003, 2005 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. +// +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_TESTSUITE_CHARACTER_H +#define _GLIBCXX_TESTSUITE_CHARACTER_H + +#include +#include // for char_traits +#include // for codecvt +#include + +namespace __gnu_test +{ + struct pod_int + { + int value; + }; + + inline bool + operator==(const pod_int& lhs, const pod_int& rhs) + { return lhs.value == rhs.value; } + + inline bool + operator<(const pod_int& lhs, const pod_int& rhs) + { return lhs.value < rhs.value; } + + struct pod_state + { + unsigned long value; + }; + + inline bool + operator==(const pod_state& lhs, const pod_state& rhs) + { return lhs.value == rhs.value; } + + inline bool + operator<(const pod_state& lhs, const pod_state& rhs) + { return lhs.value < rhs.value; } + + // Alternate character types. + using __gnu_cxx::character; + typedef character pod_char; + typedef character pod_uchar; + typedef character pod_ushort; + typedef character pod_uint; +} + +namespace __gnu_cxx +{ + // Specializations. + // pod_char + template<> + template + inline __gnu_test::pod_char::char_type + __gnu_test::pod_char::char_type::from(const V2& v) + { + char_type ret = { static_cast(v.value) }; + return ret; + } + + template<> + template + inline V2 + __gnu_test::pod_char::char_type::to(const char_type& c) + { + V2 ret = { c.value }; + return ret; + } + + template<> + template + inline __gnu_test::pod_uchar::char_type + __gnu_test::pod_uchar::char_type::from(const V2& v) + { + char_type ret; + ret.value = (v >> 5); + return ret; + } + + template<> + template + inline V2 + __gnu_test::pod_uchar::char_type::to(const char_type& c) + { return static_cast(c.value << 5); } +}; // namespace __gnu_test + +namespace std +{ + // codecvt specialization + // + // The conversion performed by the specialization is not supposed to + // be useful, rather it has been designed to demonstrate the + // essential features of stateful conversions: + // * Number and value of bytes for each internal character depends on the + // state in addition to the character itself. + // * Unshift produces an unshift sequence and resets the state. On input + // the unshift sequence causes the state to be reset. + // + // The conversion for output is as follows: + // 1. Calculate the value tmp by xor-ing the state and the internal + // character + // 2. Split tmp into either two or three bytes depending on the value of + // state. Output those bytes. + // 3. tmp becomes the new value of state. + template<> + class codecvt<__gnu_test::pod_uchar, char, __gnu_test::pod_state> + : public __codecvt_abstract_base<__gnu_test::pod_uchar, char, + __gnu_test::pod_state> + { + public: + typedef codecvt_base::result result; + typedef __gnu_test::pod_uchar intern_type; + typedef char extern_type; + typedef __gnu_test::pod_state state_type; + typedef __codecvt_abstract_base + base_type; + + explicit codecvt(size_t refs = 0) : base_type(refs) + { } + + static locale::id id; + + protected: + ~codecvt() + { } + + virtual result + do_out(state_type& state, const intern_type* from, + const intern_type* from_end, const intern_type*& from_next, + extern_type* to, extern_type* to_limit, + extern_type*& to_next) const + { + while (from < from_end && to < to_limit) + { + unsigned char tmp = (state.value ^ from->value); + if (state.value & 0x8) + { + if (to >= to_limit - 2) + break; + *to++ = (tmp & 0x7); + *to++ = ((tmp >> 3) & 0x7); + *to++ = ((tmp >> 6) & 0x3); + } + else + { + if (to >= to_limit - 1) + break; + *to++ = (tmp & 0xf); + *to++ = ((tmp >> 4) & 0xf); + } + state.value = tmp; + ++from; + } + + from_next = from; + to_next = to; + return (from < from_end) ? partial : ok; + } + + virtual result + do_in(state_type& state, const extern_type* from, + const extern_type* from_end, const extern_type*& from_next, + intern_type* to, intern_type* to_limit, + intern_type*& to_next) const + { + while (from < from_end && to < to_limit) + { + unsigned char c = *from; + if (c & 0xc0) + { + // Unshift sequence + state.value &= c; + ++from; + continue; + } + + unsigned char tmp; + if (state.value & 0x8) + { + if (from >= from_end - 2) + break; + tmp = (*from++ & 0x7); + tmp |= ((*from++ << 3) & 0x38); + tmp |= ((*from++ << 6) & 0xc0); + } + else + { + if (from >= from_end - 1) + break; + tmp = (*from++ & 0xf); + tmp |= ((*from++ << 4) & 0xf0); + } + to->value = (tmp ^ state.value); + state.value = tmp; + ++to; + } + + from_next = from; + to_next = to; + return (from < from_end) ? partial : ok; + } + + virtual result + do_unshift(state_type& state, extern_type* to, extern_type* to_limit, + extern_type*& to_next) const + { + for (unsigned int i = 0; i < CHAR_BIT; ++i) + { + unsigned int mask = (1 << i); + if (state.value & mask) + { + if (to == to_limit) + { + to_next = to; + return partial; + } + + state.value &= ~mask; + *to++ = static_cast(~mask); + } + } + + to_next = to; + return state.value == 0 ? ok : error; + } + + virtual int + do_encoding() const throw() + { return -1; } + + virtual bool + do_always_noconv() const throw() + { return false; } + + virtual int + do_length(state_type& state, const extern_type* from, + const extern_type* end, size_t max) const + { + const extern_type* beg = from; + while (from < end && max) + { + unsigned char c = *from; + if (c & 0xc0) + { + // Unshift sequence + state.value &= c; + ++from; + continue; + } + + unsigned char tmp; + if (state.value & 0x8) + { + if (from >= end - 2) + break; + tmp = (*from++ & 0x7); + tmp |= ((*from++ << 3) & 0x38); + tmp |= ((*from++ << 6) & 0xc0); + } + else + { + if (from >= end - 1) + break; + tmp = (*from++ & 0xf); + tmp |= ((*from++ << 4) & 0xf0); + } + state.value = tmp; + --max; + } + return from - beg; + } + + // Maximum 8 bytes unshift sequence followed by max 3 bytes for + // one character. + virtual int + do_max_length() const throw() + { return 11; } + }; + + template<> + class ctype<__gnu_test::pod_uchar> + : public __ctype_abstract_base<__gnu_test::pod_uchar> + { + public: + typedef __gnu_test::pod_uchar char_type; + + explicit ctype(size_t refs = 0) + : __ctype_abstract_base<__gnu_test::pod_uchar>(refs) { } + + static locale::id id; + + protected: + ~ctype() + { } + + virtual bool + do_is(mask, char_type) const + { return false; } + + virtual const char_type* + do_is(const char_type* low, const char_type* high, mask* vec) const + { + fill_n(vec, high - low, mask()); + return high; + } + + virtual const char_type* + do_scan_is(mask, const char_type*, const char_type* high) const + { return high; } + + virtual const char_type* + do_scan_not(mask, const char_type* low, const char_type*) const + { return low; } + + virtual char_type + do_toupper(char_type c) const + { return c; } + + virtual const char_type* + do_toupper(char_type*, const char_type* high) const + { return high; } + + virtual char_type + do_tolower(char_type c) const + { return c; } + + virtual const char_type* + do_tolower(char_type*, const char_type* high) const + { return high; } + + virtual char_type + do_widen(char c) const + { return __gnu_test::pod_uchar::from(c); } + + virtual const char* + do_widen(const char* low, const char* high, char_type* dest) const + { + transform(low, high, dest, &__gnu_test::pod_uchar::from); + return high; + } + + virtual char + do_narrow(char_type, char dfault) const + { return dfault; } + + virtual const char_type* + do_narrow(const char_type* low, const char_type* high, + char dfault, char* dest) const + { + fill_n(dest, high - low, dfault); + return high; + } + }; + + // numpunct specializations + template<> + class numpunct<__gnu_test::pod_uint> + : public locale::facet + { + public: + typedef __gnu_test::pod_uint char_type; + typedef basic_string string_type; + + static locale::id id; + + explicit + numpunct(size_t refs = 0) + : locale::facet(refs) + { } + + char_type + decimal_point() const + { return this->do_decimal_point(); } + + char_type + thousands_sep() const + { return this->do_thousands_sep(); } + + string + grouping() const + { return this->do_grouping(); } + + string_type + truename() const + { return this->do_truename(); } + + string_type + falsename() const + { return this->do_falsename(); } + + protected: + ~numpunct() + { } + + virtual char_type + do_decimal_point() const + { return char_type(); } + + virtual char_type + do_thousands_sep() const + { return char_type(); } + + virtual string + do_grouping() const + { return string(); } + + virtual string_type + do_truename() const + { return string_type(); } + + virtual string_type + do_falsename() const + { return string_type(); } + }; + + template<> + class moneypunct<__gnu_test::pod_uint> + : public locale::facet, public money_base + { + public: + typedef __gnu_test::pod_uint char_type; + typedef basic_string string_type; + + static locale::id id; + static const bool intl = false; + + explicit + moneypunct(size_t refs = 0) + : locale::facet(refs) + { } + + char_type + decimal_point() const + { return this->do_decimal_point(); } + + char_type + thousands_sep() const + { return this->do_thousands_sep(); } + + string + grouping() const + { return this->do_grouping(); } + + string_type + curr_symbol() const + { return this->do_curr_symbol(); } + + string_type + positive_sign() const + { return this->do_positive_sign(); } + + string_type + negative_sign() const + { return this->do_negative_sign(); } + + int + frac_digits() const + { return this->do_frac_digits(); } + + pattern + pos_format() const + { return this->do_pos_format(); } + + pattern + neg_format() const + { return this->do_neg_format(); } + + protected: + ~moneypunct() + { } + + virtual char_type + do_decimal_point() const + { return char_type(); } + + virtual char_type + do_thousands_sep() const + { return char_type(); } + + virtual string + do_grouping() const + { return string(); } + + virtual string_type + do_curr_symbol() const + { return string_type(); } + + string_type + do_positive_sign() const + { return string_type(); } + + string_type + do_negative_sign() const + { return string_type(); } + + int + do_frac_digits() const + { return 0; } + + pattern + do_pos_format() const + { return pattern(); } + + pattern + do_neg_format() const + { return pattern(); } + }; +} // namespace std + +#endif // _GLIBCXX_TESTSUITE_CHARACTER_H + diff --git a/libstdc++-v3/testsuite/util/testsuite_common_types.h b/libstdc++-v3/testsuite/util/testsuite_common_types.h new file mode 100644 index 00000000000..e63f5e0e590 --- /dev/null +++ b/libstdc++-v3/testsuite/util/testsuite_common_types.h @@ -0,0 +1,425 @@ +// -*- C++ -*- +// typelist for the C++ library testsuite. +// +// Copyright (C) 2005 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. +// +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _TESTSUITE_COMMON_TYPES_H +#define _TESTSUITE_COMMON_TYPES_H 1 + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace __gnu_test +{ + using __gnu_cxx::typelist; + using __gnu_cxx::transform; + using __gnu_cxx::append; + + // All the allocators to test. + template + struct allocator_policies + { + typedef Tp value_type; + typedef __gnu_cxx::new_allocator a1; + typedef __gnu_cxx::malloc_allocator a2; + typedef __gnu_cxx::__common_pool_policy<__gnu_cxx::__pool, Thread> pool_policy; + typedef __gnu_cxx::__mt_alloc a3; + typedef __gnu_cxx::bitmap_allocator a4; + typedef __gnu_cxx::__pool_alloc a5; + typedef typelist<_GLIBCXX_TYPELIST_CHAIN5(a1, a2, a3, a4, a5)> type; + }; + + // Typelists for vector, string, list, deque. + // XXX should just use template templates + template + struct vectors + { + typedef Tp value_type; + + template + struct vector_shell + { + typedef Tl allocator_type; + typedef std::vector type; + }; + + typedef allocator_policies allocator_types; + typedef typename allocator_types::type allocator_typelist; + typedef typename transform::type type; + }; + + template + struct lists + { + typedef Tp value_type; + + template + struct list_shell + { + typedef Tl allocator_type; + typedef std::list type; + }; + + typedef allocator_policies allocator_types; + typedef typename allocator_types::type allocator_typelist; + typedef typename transform::type type; + }; + + template + struct deques + { + typedef Tp value_type; + + template + struct deque_shell + { + typedef Tl allocator_type; + typedef std::deque type; + }; + + typedef allocator_policies allocator_types; + typedef typename allocator_types::type allocator_typelist; + typedef typename transform::type type; + }; + + template + struct strings + { + typedef Tp value_type; + + template + struct string_shell + { + typedef Tl allocator_type; + typedef std::char_traits traits_type; + typedef std::basic_string type; + }; + + typedef allocator_policies allocator_types; + typedef typename allocator_types::type allocator_typelist; + typedef typename transform::type type; + }; + + // A typelist of vector, list, deque, and string all instantiated + // with each of the allocator policies. + template + struct sequence_containers + { + typedef Tp value_type; + + typedef typename vectors::type vector_typelist; + typedef typename lists::type list_typelist; + typedef typename deques::type deque_typelist; + typedef typename strings::type string_typelist; + + typedef typename append::type a1; + typedef typename append::type a2; + typedef typename append::type type; + }; + + // Typelists for map, set, hash_map, hash_set, unordered_set, unordered_map. + template + struct maps + { + typedef Tp value_type; + typedef Tp key_type; + typedef std::pair pair_type; + typedef std::less compare_function; + + template + struct container + { + typedef Tl allocator_type; + typedef std::map type; + }; + + typedef allocator_policies allocator_types; + typedef typename allocator_types::type allocator_typelist; + typedef typename transform::type type; + }; + + template + struct hash_maps + { + typedef Tp value_type; + typedef Tp key_type; + typedef __gnu_cxx::hash hash_function; + typedef std::equal_to equality_function; + + template + struct container + { + typedef Tl allocator_type; + typedef __gnu_cxx::hash_map type; + }; + + typedef allocator_policies allocator_types; + typedef typename allocator_types::type allocator_typelist; + typedef typename transform::type type; + }; + + template + struct unordered_maps + { + typedef Tp value_type; + typedef Tp key_type; + typedef std::pair pair_type; + typedef std::tr1::hash hash_function; + typedef std::equal_to equality_function; + + template + struct container + { + typedef Tl allocator_type; + typedef std::tr1::unordered_map type; + }; + + typedef allocator_policies allocator_types; + typedef typename allocator_types::type allocator_typelist; + typedef typename transform::type type; + }; + + template + struct sets + { + typedef Tp value_type; + typedef Tp key_type; + typedef std::less compare_function; + + template + struct container + { + typedef Tl allocator_type; + typedef std::set type; + }; + + typedef allocator_policies allocator_types; + typedef typename allocator_types::type allocator_typelist; + typedef typename transform::type type; + }; + + template + struct hash_sets + { + typedef Tp value_type; + typedef Tp key_type; + typedef __gnu_cxx::hash hash_function; + typedef std::equal_to equality_function; + + template + struct container + { + typedef Tl allocator_type; + typedef __gnu_cxx::hash_set type; + }; + + typedef allocator_policies allocator_types; + typedef typename allocator_types::type allocator_typelist; + typedef typename transform::type type; + }; + + template + struct unordered_sets + { + typedef Tp value_type; + typedef Tp key_type; + typedef std::tr1::hash hash_function; + typedef std::equal_to equality_function; + + template + struct container + { + typedef Tl allocator_type; + typedef std::tr1::unordered_set type; + }; + + typedef allocator_policies allocator_types; + typedef typename allocator_types::type allocator_typelist; + typedef typename transform::type type; + }; + + + // A typelist of all associated container types, with each of the + // allocator policies. + template + struct associative_containers + { + typedef Tp value_type; + + typedef typename maps::type map_typelist; + typedef typename sets::type set_typelist; + typedef typename hash_maps::type hash_map_typelist; + typedef typename hash_sets::type hash_set_typelist; + typedef typename unordered_maps::type unordered_map_typelist; + typedef typename unordered_sets::type unordered_set_typelist; + + typedef typename append::type a1; + typedef typename append::type a2; + typedef typename append::type a3; + typedef typename append::type a4; + typedef typename append::type type; + }; + +} // namespace __gnu_test + + +// Function template, function objects for the tests. +template + struct value_type : public std::pair + { + inline value_type& operator++() + { + ++this->second; + return *this; + } + + inline operator TestType() const { return this->second; } + }; + +template + void + do_loop(); + +template + void* + do_thread(void* p = NULL) + { + do_loop(); + return p; + } + +template + void + test_container(const char* filename) + { + using namespace __gnu_test; + time_counter time; + resource_counter resource; + { + start_counters(time, resource); + if (!Thread) + { + // No threads, so run 4x. + do_loop(); + } + else + { +#if defined (_GLIBCXX_GCC_GTHR_POSIX_H) && !defined (NOTHREAD) + pthread_t t1, t2, t3, t4; + pthread_create(&t1, 0, &do_thread, 0); + pthread_create(&t2, 0, &do_thread, 0); + pthread_create(&t3, 0, &do_thread, 0); + pthread_create(&t4, 0, &do_thread, 0); + + pthread_join(t1, NULL); + pthread_join(t2, NULL); + pthread_join(t3, NULL); + pthread_join(t4, NULL); +#endif + } + stop_counters(time, resource); + + // Detailed text data. + Container obj; + int status; + std::ostringstream comment; + comment << "type: " << abi::__cxa_demangle(typeid(obj).name(), + 0, 0, &status); + report_header(filename, comment.str()); + report_performance("", "", time, resource); + + // Detailed data for visualization. + std::string vizfilename(filename); + vizfilename += ".dat"; + write_viz_data(time, vizfilename.c_str()); + } + } + +template + struct test_sequence + { + test_sequence(const char* filename) : _M_filename(filename) { } + + template + void + operator()(__gnu_cxx::detail::type_to_type) + { + const int i = 20000; + test_container(_M_filename); + } + + private: + const char* _M_filename; + }; + + +inline std::string::size_type +sequence_find_container(std::string& type) +{ + const std::string::size_type npos = std::string::npos; + std::string::size_type n1 = type.find("vector"); + std::string::size_type n2 = type.find("list"); + std::string::size_type n3 = type.find("deque"); + std::string::size_type n4 = type.find("string"); + + if (n1 != npos || n2 != npos || n3 != npos || n4 != npos) + return std::min(std::min(n1, n2), std::min(n3, n4)); + else + throw std::runtime_error("sequence_find_container not found"); +} + +inline std::string::size_type +associative_find_container(std::string& type) +{ + using std::string; + string::size_type n1 = type.find("map"); + string::size_type n2 = type.find("set"); + if (n1 != string::npos || n2 != string::npos) + return std::min(n1, n2); + else + throw std::runtime_error("associative_find_container not found"); +} +#endif diff --git a/libstdc++-v3/testsuite/util/testsuite_hooks.cc b/libstdc++-v3/testsuite/util/testsuite_hooks.cc new file mode 100644 index 00000000000..40189fbf5d4 --- /dev/null +++ b/libstdc++-v3/testsuite/util/testsuite_hooks.cc @@ -0,0 +1,323 @@ +// -*- C++ -*- + +// Utility subroutines for the C++ library testsuite. +// +// Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. +// +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#include + +#ifdef _GLIBCXX_RES_LIMITS +#include +#include +#include +#endif +#include +#include +#include +#include +#include +#include + +// If we have , , and , then assume +// that System V semaphores are available. +#if defined(_GLIBCXX_HAVE_SYS_TYPES_H) \ + && defined(_GLIBCXX_HAVE_SYS_IPC_H) \ + && defined(_GLIBCXX_HAVE_SYS_SEM_H) +#define _GLIBCXX_SYSV_SEM +#endif + +#ifdef _GLIBCXX_SYSV_SEM +#include +#include +#include +#endif + +namespace __gnu_test +{ +#ifdef _GLIBCXX_RES_LIMITS + void + set_memory_limits(float size) + { + struct rlimit r; + // Cater to the absence of rlim_t. + __typeof__ (r.rlim_cur) limit = (__typeof__ (r.rlim_cur))(size * 1048576); + + // Heap size, seems to be common. +#if _GLIBCXX_HAVE_LIMIT_DATA + getrlimit(RLIMIT_DATA, &r); + r.rlim_cur = limit; + setrlimit(RLIMIT_DATA, &r); +#endif + + // Resident set size. +#if _GLIBCXX_HAVE_LIMIT_RSS + getrlimit(RLIMIT_RSS, &r); + r.rlim_cur = limit; + setrlimit(RLIMIT_RSS, &r); +#endif + + // Mapped memory (brk + mmap). +#if _GLIBCXX_HAVE_LIMIT_VMEM + getrlimit(RLIMIT_VMEM, &r); + r.rlim_cur = limit; + setrlimit(RLIMIT_VMEM, &r); +#endif + + // Virtual memory. + // On HP-UX 11.23, a trivial C++ program that sets RLIMIT_AS to + // anything less than 128MB cannot "malloc" even 1K of memory. + // Therefore, we skip RLIMIT_AS on HP-UX. +#if _GLIBCXX_HAVE_LIMIT_AS && !defined(__hpux__) + getrlimit(RLIMIT_AS, &r); + r.rlim_cur = limit; + setrlimit(RLIMIT_AS, &r); +#endif + } + +#else + void + set_memory_limits(float) { } +#endif + +#ifdef _GLIBCXX_RES_LIMITS + void + set_file_limit(unsigned long size) + { +#if _GLIBCXX_HAVE_LIMIT_FSIZE + struct rlimit r; + // Cater to the absence of rlim_t. + __typeof__ (r.rlim_cur) limit = (__typeof__ (r.rlim_cur))(size); + + getrlimit(RLIMIT_FSIZE, &r); + r.rlim_cur = limit; + setrlimit(RLIMIT_FSIZE, &r); +#endif + } + +#else + void + set_file_limit(unsigned long) { } +#endif + + void + verify_demangle(const char* mangled, const char* wanted) + { + int status = 0; + const char* s = abi::__cxa_demangle(mangled, 0, 0, &status); + if (!s) + { + switch (status) + { + case 0: + s = "error code = 0: success"; + break; + case -1: + s = "error code = -1: memory allocation failure"; + break; + case -2: + s = "error code = -2: invalid mangled name"; + break; + case -3: + s = "error code = -3: invalid arguments"; + break; + default: + s = "error code unknown - who knows what happened"; + } + } + + std::string w(wanted); + if (w != s) + std::__throw_runtime_error(s); + } + + void + run_tests_wrapped_locale(const char* name, const func_callback& l) + { + using namespace std; + bool test = true; + + // Set the global locale. + locale loc_name = locale(name); + locale orig = locale::global(loc_name); + + const char* res = setlocale(LC_ALL, name); + if (res != NULL) + { + string preLC_ALL = res; + const func_callback::test_type* tests = l.tests(); + for (int i = 0; i < l.size(); ++i) + (*tests[i])(); + string postLC_ALL= setlocale(LC_ALL, NULL); + VERIFY( preLC_ALL == postLC_ALL ); + } + else + { + string s("LC_ALL for "); + s += name; + __throw_runtime_error(s.c_str()); + } + } + + void + run_tests_wrapped_env(const char* name, const char* env, + const func_callback& l) + { + using namespace std; + bool test = true; + +#ifdef _GLIBCXX_HAVE_SETENV + // Set the global locale. + locale loc_name = locale(name); + locale orig = locale::global(loc_name); + + // Set environment variable env to value in name. + const char* oldENV = getenv(env); + if (!setenv(env, name, 1)) + { + const func_callback::test_type* tests = l.tests(); + for (int i = 0; i < l.size(); ++i) + (*tests[i])(); + setenv(env, oldENV ? oldENV : "", 1); + } + else + { + string s(env); + s += string(" to "); + s += string(name); + __throw_runtime_error(s.c_str()); + } +#endif + } + + counter::size_type counter::count = 0; + unsigned int copy_constructor::count_ = 0; + unsigned int copy_constructor::throw_on_ = 0; + unsigned int assignment_operator::count_ = 0; + unsigned int assignment_operator::throw_on_ = 0; + unsigned int destructor::_M_count = 0; + int copy_tracker::next_id_ = 0; + +#ifdef _GLIBCXX_SYSV_SEM + // This union is not declared in system headers. Instead, it must + // be defined by user programs. + union semun + { + int val; + struct semid_ds *buf; + unsigned short *array; + }; +#endif + + semaphore::semaphore() + { +#ifdef _GLIBCXX_SYSV_SEM + // Remeber the PID for the process that created the semaphore set + // so that only one process will destroy the set. + pid_ = getpid(); + + // GLIBC does not define SEM_R and SEM_A. +#ifndef SEM_R +#define SEM_R 0400 +#endif + +#ifndef SEM_A +#define SEM_A 0200 +#endif + + // Get a semaphore set with one semaphore. + sem_set_ = semget(IPC_PRIVATE, 1, SEM_R | SEM_A); + if (sem_set_ == -1) + std::__throw_runtime_error("could not obtain semaphore set"); + + // Initialize the semaphore. + union semun val; + val.val = 0; + if (semctl(sem_set_, 0, SETVAL, val) == -1) + std::__throw_runtime_error("could not initialize semaphore"); +#else + // There are no semaphores on this system. We have no way to mark + // a test as "unsupported" at runtime, so we just exit, pretending + // that the test passed. + exit(0); +#endif + } + + semaphore::~semaphore() + { +#ifdef _GLIBCXX_SYSV_SEM + union semun val; + // Destroy the semaphore set only in the process that created it. + if (pid_ == getpid()) + semctl(sem_set_, 0, IPC_RMID, val); +#endif + } + + void + semaphore::signal() + { +#ifdef _GLIBCXX_SYSV_SEM + struct sembuf op[1] = + { + { 0, 1, 0 } + }; + if (semop(sem_set_, op, 1) == -1) + std::__throw_runtime_error("could not signal semaphore"); +#endif + } + + void + semaphore::wait() + { +#ifdef _GLIBCXX_SYSV_SEM + struct sembuf op[1] = + { + { 0, -1, SEM_UNDO } + }; + if (semop(sem_set_, op, 1) == -1) + std::__throw_runtime_error("could not wait for semaphore"); +#endif + } + + // For use in 22_locale/time_get and time_put. + tm + test_tm(int sec, int min, int hour, int mday, int mon, + int year, int wday, int yday, int isdst) + { + static tm tmp; + tmp.tm_sec = sec; + tmp.tm_min = min; + tmp.tm_hour = hour; + tmp.tm_mday = mday; + tmp.tm_mon = mon; + tmp.tm_year = year; + tmp.tm_wday = wday; + tmp.tm_yday = yday; + tmp.tm_isdst = isdst; + return tmp; + } +}; // namespace __gnu_test diff --git a/libstdc++-v3/testsuite/util/testsuite_hooks.h b/libstdc++-v3/testsuite/util/testsuite_hooks.h new file mode 100644 index 00000000000..b6c675b12e7 --- /dev/null +++ b/libstdc++-v3/testsuite/util/testsuite_hooks.h @@ -0,0 +1,396 @@ +// -*- C++ -*- +// Utility subroutines for the C++ library testsuite. +// +// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. +// +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// This file provides the following: +// +// 1) VERIFY(), via _GLIBCXX_ASSERT, from Brent Verner . +// This file is included in the various testsuite programs to provide +// #define(able) assert() behavior for debugging/testing. It may be +// a suitable location for other furry woodland creatures as well. +// +// 2) set_memory_limits() +// set_memory_limits() uses setrlimit() to restrict dynamic memory +// allocation. We provide a default memory limit if none is passed by the +// calling application. The argument to set_memory_limits() is the +// limit in megabytes (a floating-point number). If _GLIBCXX_RES_LIMITS is +// not #defined before including this header, then no limiting is attempted. +// +// 3) counter +// This is a POD with a static data member, gnu_counting_struct::count, +// which starts at zero, increments on instance construction, and decrements +// on instance destruction. "assert_count(n)" can be called to VERIFY() +// that the count equals N. +// +// 4) copy_tracker, from Stephen M. Webb . +// A class with nontrivial ctor/dtor that provides the ability to track the +// number of copy ctors and dtors, and will throw on demand during copy. + +#ifndef _GLIBCXX_TESTSUITE_HOOKS_H +#define _GLIBCXX_TESTSUITE_HOOKS_H + +#include +#include +#include +#include +#ifdef _GLIBCXX_HAVE_SYS_STAT_H +#include +#endif + +#ifdef _GLIBCXX_ASSERT +# include +# define VERIFY(fn) assert(fn) +#else +# define VERIFY(fn) test &= (fn) +#endif + +#ifdef _GLIBCXX_HAVE_UNISTD_H +# include +#else +# define unlink(x) +#endif + +namespace __gnu_test +{ + // All macros are defined in GLIBCXX_CONFIGURE_TESTSUITE and imported + // from c++config.h + + // Set memory limits if possible, if not set to 0. +#ifndef _GLIBCXX_RES_LIMITS +# define MEMLIMIT_MB 0 +#else +# ifndef MEMLIMIT_MB +# define MEMLIMIT_MB 16.0 +# endif +#endif + extern void + set_memory_limits(float __size = MEMLIMIT_MB); + + extern void + set_file_limit(unsigned long __size); + + // Check mangled name demangles (using __cxa_demangle) as expected. + void + verify_demangle(const char* mangled, const char* wanted); + + // 17.3.2.1.2 - Bitmask types [lib.bitmask.types] + // bitmask_operators + template + void + bitmask_operators(bitmask_type a = bitmask_type(), + bitmask_type b = bitmask_type()) + { + a | b; + a & b; + a ^ b; + ~b; + a |= b; // set + a &= ~b; // clear + a ^= b; + } + + // Simple callback structure for variable numbers of tests (all with + // same signature). Assume all unit tests are of the signature + // void test01(); + class func_callback + { + public: + typedef void (*test_type) (void); + + private: + int _M_size; + test_type _M_tests[15]; + + func_callback& + operator=(const func_callback&); + + func_callback(const func_callback&); + + public: + func_callback(): _M_size(0) { }; + + int + size() const { return _M_size; } + + const test_type* + tests() const { return _M_tests; } + + void + push_back(test_type test) + { + _M_tests[_M_size] = test; + ++_M_size; + } + }; + + + // Run select unit tests after setting global locale. + void + run_tests_wrapped_locale(const char*, const func_callback&); + + // Run select unit tests after setting environment variables. + void + run_tests_wrapped_env(const char*, const char*, const func_callback&); + + + // For containers (23.1/3). + struct NonDefaultConstructible + { + NonDefaultConstructible(int) { } + }; + + inline bool + operator==(const NonDefaultConstructible&, + const NonDefaultConstructible&) + { return false; } + + inline bool + operator<(const NonDefaultConstructible&, + const NonDefaultConstructible&) + { return false; } + + + // Counting. + struct counter + { + // Specifically and glaringly-obviously marked 'signed' so that when + // COUNT mistakenly goes negative, we can track the patterns of + // deletions more easily. + typedef signed int size_type; + static size_type count; + counter() { ++count; } + counter (const counter&) { ++count; } + ~counter() { --count; } + }; + +#define assert_count(n) VERIFY(__gnu_test::counter::count == n) + + // A (static) class for counting copy constructors and possibly throwing an + // exception on a desired count. + class copy_constructor + { + public: + static unsigned int + count() { return count_; } + + static void + mark_call() + { + count_++; + if (count_ == throw_on_) + std::__throw_runtime_error("copy_constructor::mark_call"); + } + + static void + reset() + { + count_ = 0; + throw_on_ = 0; + } + + static void + throw_on(unsigned int count) { throw_on_ = count; } + + private: + static unsigned int count_; + static unsigned int throw_on_; + }; + + // A (static) class for counting assignment operator calls and + // possibly throwing an exception on a desired count. + class assignment_operator + { + public: + static unsigned int + count() { return count_; } + + static void + mark_call() + { + count_++; + if (count_ == throw_on_) + std::__throw_runtime_error("assignment_operator::mark_call"); + } + + static void + reset() + { + count_ = 0; + throw_on_ = 0; + } + + static void + throw_on(unsigned int count) { throw_on_ = count; } + + private: + static unsigned int count_; + static unsigned int throw_on_; + }; + + // A (static) class for tracking calls to an object's destructor. + class destructor + { + public: + static unsigned int + count() { return _M_count; } + + static void + mark_call() { _M_count++; } + + static void + reset() { _M_count = 0; } + + private: + static unsigned int _M_count; + }; + + // An class of objects that can be used for validating various + // behaviours and guarantees of containers and algorithms defined in + // the standard library. + class copy_tracker + { + public: + // Creates a copy-tracking object with the given ID number. If + // "throw_on_copy" is set, an exception will be thrown if an + // attempt is made to copy this object. + copy_tracker(int id = next_id_--, bool throw_on_copy = false) + : id_(id) , throw_on_copy_(throw_on_copy) { } + + // Copy-constructs the object, marking a call to the copy + // constructor and forcing an exception if indicated. + copy_tracker(const copy_tracker& rhs) + : id_(rhs.id()), throw_on_copy_(rhs.throw_on_copy_) + { + if (throw_on_copy_) + copy_constructor::throw_on(copy_constructor::count() + 1); + copy_constructor::mark_call(); + } + + // Assigns the value of another object to this one, tracking the + // number of times this member function has been called and if the + // other object is supposed to throw an exception when it is + // copied, well, make it so. + copy_tracker& + operator=(const copy_tracker& rhs) + { + id_ = rhs.id(); + if (rhs.throw_on_copy_) + assignment_operator::throw_on(assignment_operator::count() + 1); + assignment_operator::mark_call(); + return *this; + } + + ~copy_tracker() + { destructor::mark_call(); } + + int + id() const { return id_; } + + private: + int id_; + const bool throw_on_copy_; + + public: + static void + reset() + { + copy_constructor::reset(); + assignment_operator::reset(); + destructor::reset(); + } + + // for backwards-compatibility + static int + copyCount() + { return copy_constructor::count(); } + + // for backwards-compatibility + static int + dtorCount() + { return destructor::count(); } + + private: + static int next_id_; + }; + + inline bool + operator==(const copy_tracker& lhs, const copy_tracker& rhs) + { return lhs.id() == rhs.id(); } + + // Class for checking required type conversions, implicit and + // explicit for given library data structures. + template + struct conversion + { + typedef typename _Container::const_iterator const_iterator; + + // Implicit conversion iterator to const_iterator. + static const_iterator + iterator_to_const_iterator() + { + _Container v; + const_iterator it = v.begin(); + const_iterator end = v.end(); + return it == end ? v.end() : it; + } + }; + + // A binary semaphore for use across multiple processes. + class semaphore + { + public: + // Creates a binary semaphore. The semaphore is initially in the + // unsignaled state. + semaphore(); + + // Destroy the semaphore. + ~semaphore(); + + // Signal the semaphore. If there are processes blocked in + // "wait", exactly one will be permitted to proceed. + void signal(); + + // Wait until the semaphore is signaled. + void wait(); + + private: + int sem_set_; + + pid_t pid_; + }; + + // For use in 22_locale/time_get and time_put. + tm test_tm(int sec, int min, int hour, int mday, int mon, + int year, int wday, int yday, int isdst); + +} // namespace __gnu_test + +#endif // _GLIBCXX_TESTSUITE_HOOKS_H + diff --git a/libstdc++-v3/testsuite/util/testsuite_io.h b/libstdc++-v3/testsuite/util/testsuite_io.h new file mode 100644 index 00000000000..e6f1c03d622 --- /dev/null +++ b/libstdc++-v3/testsuite/util/testsuite_io.h @@ -0,0 +1,328 @@ +// -*- C++ -*- +// Testing streambuf/filebuf/stringbuf for the C++ library testsuite. +// +// Copyright (C) 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. +// +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_TESTSUITE_IO_H +#define _GLIBCXX_TESTSUITE_IO_H + +#include +#include + +namespace __gnu_test +{ + // Used to verify the constraints/requirements on get and put areas + // as defined in + // 27.5.1 - Stream buffer requirements: get and put areas + // 27.8.1.1 - Template class basic_filebuf p 3 + // If the file is not open (ios_base::in) -> input seq. cannot be read + // If the file is not open (ios_base::out) -> output seq. cannot be written + // Joint file position + // 27.8.1.4 - Overridden virtual functions p9 + // If unbuffered, pbase == pptr == NULL + // 27.7.1.1 - Basic_stringbuf constructors p 1 + // 27.8.1.2 - Basic_filebuf constructors p 1 + // ... , initializing the base class with basic_streambuf() 27.5.2.1 + template + class constraint_buf + : public T + { + public: + bool + write_position() + { + bool one = this->pptr() != NULL; + bool two = this->pptr() < this->epptr(); + return one && two; + } + + bool + read_position() + { + bool one = this->gptr() != NULL; + bool two = this->gptr() < this->egptr(); + return one && two; + } + + bool + unbuffered() + { + bool one = this->pbase() == NULL; + bool two = this->pptr() == NULL; + return one && two; + } + + bool + check_pointers() + { + bool one = this->eback() == NULL; + bool two = this->gptr() == NULL; + bool three = this->egptr() == NULL; + + bool four = this->pbase() == NULL; + bool five = this->pptr() == NULL; + bool six = this->epptr() == NULL; + return one && two && three && four && five && six; + } + }; + + typedef constraint_buf constraint_streambuf; + typedef constraint_buf constraint_filebuf; + typedef constraint_buf constraint_stringbuf; +#ifdef _GLIBCXX_USE_WCHAR_T + typedef constraint_buf constraint_wstreambuf; + typedef constraint_buf constraint_wfilebuf; + typedef constraint_buf constraint_wstringbuf; +#endif + + // Used to check if basic_streambuf::pubsync() has been called. + // This is useful for checking if a function creates [io]stream::sentry + // objects, since the sentry constructors call tie()->flush(). + template + class sync_buf + : public T + { + private: + bool m_sync_called; + + public: + sync_buf() + : m_sync_called(false) + { } + + bool sync_called() const + { return m_sync_called; } + + protected: + int sync() + { + m_sync_called = true; + return 0; + } + }; + + typedef sync_buf sync_streambuf; +#ifdef _GLIBCXX_USE_WCHAR_T + typedef sync_buf sync_wstreambuf; +#endif + + // Throws on all overflow and underflow calls. + struct underflow_error: std::exception { }; + struct overflow_error: std::exception { }; + struct positioning_error: std::exception { }; + + template + struct fail_buf + : public T + { + typedef typename T::char_type char_type; + typedef typename T::int_type int_type; + typedef typename T::off_type off_type; + typedef typename T::pos_type pos_type; + + private: + char_type p[2]; + + public: + fail_buf() + { + p[0] = char_type('s'); + p[1] = char_type(); + setg(p, p, p + 1); + } + + virtual int_type underflow() + { + throw underflow_error(); + return int_type(); + } + + virtual int_type uflow() + { + throw underflow_error(); + return int_type(); + } + + virtual int_type + overflow(int_type) + { + throw overflow_error(); + return int_type(); + } + + virtual pos_type + seekoff(off_type, std::ios_base::seekdir, std::ios_base::openmode) + { + throw positioning_error(); + return pos_type(off_type(-1)); + } + + virtual pos_type + seekpos(pos_type, std::ios_base::openmode) + { + throw positioning_error(); + return pos_type(off_type(-1)); + } + + virtual int + sync() + { + throw positioning_error(); + return 0; + } + }; + + typedef fail_buf fail_streambuf; +#ifdef _GLIBCXX_USE_WCHAR_T + typedef fail_buf fail_wstreambuf; +#endif + + // Facets that throw an exception for every virtual function. + struct facet_error: std::exception { }; + + template + class fail_num_get + : public std::num_get + { + typedef std::ios_base ios_base; + typedef typename std::num_get::iter_type iter_type; + + protected: + iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const + { throw facet_error(); return iter_type(); } + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, long&) const + { throw facet_error(); return iter_type(); } + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, + unsigned short&) const + { throw facet_error(); return iter_type(); } + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, + unsigned int&) const + { throw facet_error(); return iter_type(); } + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, + unsigned long&) const + { throw facet_error(); return iter_type(); } + +#ifdef _GLIBCXX_USE_LONG_LONG + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, + long long&) const + { throw facet_error(); return iter_type(); } + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, + unsigned long long&) const + { throw facet_error(); return iter_type(); } +#endif + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, + float&) const + { throw facet_error(); return iter_type(); } + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, + double&) const + { throw facet_error(); return iter_type(); } + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, + long double&) const + { throw facet_error(); return iter_type(); } + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, + void*&) const + { throw facet_error(); return iter_type(); } + }; + + typedef fail_num_get fail_num_get_char; +#ifdef _GLIBCXX_USE_WCHAR_T + typedef fail_num_get fail_num_get_wchar_t; +#endif + + template + class fail_num_put + : public std::num_put + { + typedef std::ios_base ios_base; + typedef typename std::num_put::iter_type iter_type; + typedef typename std::num_put::char_type char_type; + + protected: + iter_type + do_put(iter_type, ios_base&, char_type, bool) const + { throw facet_error(); return iter_type(NULL); } + + virtual iter_type + do_put(iter_type, ios_base&, char_type, long) const + { throw facet_error(); return iter_type(NULL); } + + virtual iter_type + do_put(iter_type, ios_base&, char_type, unsigned long) const + { throw facet_error(); return iter_type(NULL); } + +#ifdef _GLIBCXX_USE_LONG_LONG + virtual iter_type + do_put(iter_type, ios_base&, char_type, long long) const + { throw facet_error(); return iter_type(NULL); } + + virtual iter_type + do_put(iter_type, ios_base&, char_type, unsigned long long) const + { throw facet_error(); return iter_type(NULL); } +#endif + + virtual iter_type + do_put(iter_type, ios_base&, char_type, double) const + { throw facet_error(); return iter_type(NULL); } + + virtual iter_type + do_put(iter_type, ios_base&, char_type, long double) const + { throw facet_error(); return iter_type(NULL); } + + virtual iter_type + do_put(iter_type, ios_base&, char_type, const void*) const + { throw facet_error(); return iter_type(NULL); } + }; + + typedef fail_num_put fail_num_put_char; +#ifdef _GLIBCXX_USE_WCHAR_T + typedef fail_num_put fail_num_put_wchar_t; +#endif +}; // namespace __gnu_test + +#endif // _GLIBCXX_TESTSUITE_IO_H + diff --git a/libstdc++-v3/testsuite/util/testsuite_iterators.h b/libstdc++-v3/testsuite/util/testsuite_iterators.h new file mode 100644 index 00000000000..7119783c93b --- /dev/null +++ b/libstdc++-v3/testsuite/util/testsuite_iterators.h @@ -0,0 +1,545 @@ +// -*- C++ -*- +// Iterator Wrappers for the C++ library testsuite. +// +// Copyright (C) 2004, 2005 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. +// +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// This file provides the following: +// +// input_iterator_wrapper, output_iterator_wrapper +// forward_iterator_wrapper, bidirectional_iterator_wrapper and +// random_access_wrapper, which attempt to exactly perform the requirements +// of these types of iterators. These are constructed from the class +// test_container, which is given two pointers to T and an iterator type. + +#include +#include + +#ifndef _TESTSUITE_ITERATORS +#define _TESTSUITE_ITERATORS + +#ifdef DISABLE_ITERATOR_DEBUG +#define ITERATOR_VERIFY(x) +#else +#define ITERATOR_VERIFY(x) VERIFY(x) +#endif + +namespace __gnu_test +{ + /** + * @brief Simple container for holding two pointers. + * + * Note that input_iterator_wrapper changes first to denote + * how the valid range of == , ++, etc. change as the iterators are used. + */ + template + struct BoundsContainer + { + T* first; + T* last; + BoundsContainer(T* _first, T* _last) + : first(_first), last(_last) + { } + }; + + // Simple container for holding state of a set of output iterators. + template + struct OutputContainer : public BoundsContainer + { + T* incrementedto; + bool* writtento; + OutputContainer(T* _first, T* _last) + : BoundsContainer(_first, _last), incrementedto(_first) + { + writtento = new bool[this->last - this->first]; + for(int i = 0; i < this->last - this->first; i++) + writtento[i] = false; + } + + ~OutputContainer() + { delete[] writtento; } + }; + + // Produced by output_iterator to allow limited writing to pointer + template + class WritableObject + { + T* ptr; + + public: + OutputContainer* SharedInfo; + WritableObject(T* ptr_in,OutputContainer* SharedInfo_in): + ptr(ptr_in), SharedInfo(SharedInfo_in) + { } + + template + void + operator=(const U& new_val) + { + ITERATOR_VERIFY(SharedInfo->writtento[ptr - SharedInfo->first] == 0); + SharedInfo->writtento[ptr - SharedInfo->first] = 1; + *ptr = new_val; + } + }; + + /** + * @brief output_iterator wrapper for pointer + * + * This class takes a pointer and wraps it to provide exactly + * the requirements of a output_iterator. It should not be + * instansiated directly, but generated from a test_container + */ + template + struct output_iterator_wrapper: public std::iterator + + { + typedef OutputContainer ContainerType; + T* ptr; + ContainerType* SharedInfo; + + output_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in) + :ptr(_ptr), SharedInfo(SharedInfo_in) + { + ITERATOR_VERIFY(ptr >= SharedInfo->first && ptr <= SharedInfo->last); + } + + output_iterator_wrapper(const output_iterator_wrapper& in) + :ptr(in.ptr), SharedInfo(in.SharedInfo) + { } + + WritableObject + operator*() const + { + ITERATOR_VERIFY(ptr < SharedInfo->last); + ITERATOR_VERIFY(SharedInfo->writtento[ptr - SharedInfo->first] == false); + return WritableObject(ptr, SharedInfo); + } + + output_iterator_wrapper& + operator=(const output_iterator_wrapper& in) + { + ptr = in.ptr; + SharedInfo = in.SharedInfo; + return *this; + } + + output_iterator_wrapper& + operator++() + { + ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last); + ITERATOR_VERIFY(ptr>=SharedInfo->incrementedto); + ptr++; + SharedInfo->incrementedto=ptr; + return *this; + } + + output_iterator_wrapper + operator++(int) + { + output_iterator_wrapper tmp = *this; + ++*this; + return tmp; + } + + }; + + /** + * @brief input_iterator wrapper for pointer + * + * This class takes a pointer and wraps it to provide exactly + * the requirements of a input_iterator. It should not be + * instansiated directly, but generated from a test_container + */ + template + class input_iterator_wrapper:public std::iterator + + { + protected: + input_iterator_wrapper() + { } + + public: + typedef BoundsContainer ContainerType; + T* ptr; + ContainerType* SharedInfo; + + input_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in) + : ptr(_ptr), SharedInfo(SharedInfo_in) + { ITERATOR_VERIFY(ptr >= SharedInfo->first && ptr <= SharedInfo->last); } + + input_iterator_wrapper(const input_iterator_wrapper& in) + : ptr(in.ptr), SharedInfo(in.SharedInfo) + { } + + bool + operator==(const input_iterator_wrapper& in) const + { + ITERATOR_VERIFY(SharedInfo != NULL && SharedInfo == in.SharedInfo); + ITERATOR_VERIFY(ptr>=SharedInfo->first && in.ptr>=SharedInfo->first); + return ptr == in.ptr; + } + + bool + operator!=(const input_iterator_wrapper& in) const + { + return !(*this == in); + } + + T& + operator*() const + { + ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last); + ITERATOR_VERIFY(ptr >= SharedInfo->first); + return *ptr; + } + + T* + operator->() const + { + return &**this; + } + + input_iterator_wrapper& + operator=(const input_iterator_wrapper& in) + { + ptr = in.ptr; + SharedInfo = in.SharedInfo; + return *this; + } + + input_iterator_wrapper& + operator++() + { + ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last); + ITERATOR_VERIFY(ptr>=SharedInfo->first); + ptr++; + SharedInfo->first=ptr; + return *this; + } + + void + operator++(int) + { + ++*this; + } + }; + + + /** + * @brief forward_iterator wrapper for pointer + * + * This class takes a pointer and wraps it to provide exactly + * the requirements of a forward_iterator. It should not be + * instansiated directly, but generated from a test_container + */ + template + struct forward_iterator_wrapper:public input_iterator_wrapper + { + typedef BoundsContainer ContainerType; + typedef std::forward_iterator_tag iterator_category; + forward_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in) + :input_iterator_wrapper(_ptr, SharedInfo_in) + { } + + forward_iterator_wrapper(const forward_iterator_wrapper& in) + :input_iterator_wrapper(in) + { } + + forward_iterator_wrapper() + { + this->ptr = NULL; + this->SharedInfo = NULL; + } + + T& + operator*() const + { + ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last); + return *(this->ptr); + } + + T* + operator->() const + { return &**this; } + + forward_iterator_wrapper& + operator++() + { + ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last); + this->ptr++; + return *this; + } + + forward_iterator_wrapper + operator++(int) + { + forward_iterator_wrapper tmp = *this; + ++*this; + return tmp; + } + }; + + /** + * @brief bidirectional_iterator wrapper for pointer + * + * This class takes a pointer and wraps it to provide exactly + * the requirements of a forward_iterator. It should not be + * instansiated directly, but generated from a test_container + */ + template + struct bidirectional_iterator_wrapper:public forward_iterator_wrapper + { + typedef BoundsContainer ContainerType; + typedef std::bidirectional_iterator_tag iterator_category; + bidirectional_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in) + :forward_iterator_wrapper(_ptr, SharedInfo_in) + { } + + bidirectional_iterator_wrapper(const bidirectional_iterator_wrapper& in) + :forward_iterator_wrapper(in) + { } + + bidirectional_iterator_wrapper(): forward_iterator_wrapper() + { } + + bidirectional_iterator_wrapper& + operator=(const bidirectional_iterator_wrapper& in) + { + this->ptr = in.ptr; + this->SharedInfo = in.SharedInfo; + return *this; + } + + bidirectional_iterator_wrapper& + operator++() + { + ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last); + this->ptr++; + return *this; + } + + bidirectional_iterator_wrapper + operator++(int) + { + bidirectional_iterator_wrapper tmp = *this; + ++*this; + return tmp; + } + + bidirectional_iterator_wrapper& + operator--() + { + ITERATOR_VERIFY(this->SharedInfo && this->ptr > this->SharedInfo->first); + this->ptr--; + return *this; + } + + bidirectional_iterator_wrapper + operator--(int) + { + bidirectional_iterator_wrapper tmp = *this; + --*this; + return tmp; + } + }; + + /** + * @brief random_access_iterator wrapper for pointer + * + * This class takes a pointer and wraps it to provide exactly + * the requirements of a forward_iterator. It should not be + * instansiated directly, but generated from a test_container + */ + template + struct random_access_iterator_wrapper:public bidirectional_iterator_wrapper + { + typedef BoundsContainer ContainerType; + typedef std::random_access_iterator_tag iterator_category; + random_access_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in) + : bidirectional_iterator_wrapper(_ptr, SharedInfo_in) + { } + + random_access_iterator_wrapper(const random_access_iterator_wrapper& in) + : bidirectional_iterator_wrapper(in) + { } + + random_access_iterator_wrapper():bidirectional_iterator_wrapper() + { } + + random_access_iterator_wrapper& + operator=(const random_access_iterator_wrapper& in) + { + this->ptr = in.ptr; + this->SharedInfo = in.SharedInfo; + return *this; + } + + random_access_iterator_wrapper& + operator++() + { + ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last); + this->ptr++; + return *this; + } + + random_access_iterator_wrapper + operator++(int) + { + random_access_iterator_wrapper tmp = *this; + ++*this; + return tmp; + } + + random_access_iterator_wrapper& + operator--() + { + ITERATOR_VERIFY(this->SharedInfo && this->ptr > this->SharedInfo->first); + this->ptr--; + return *this; + } + + random_access_iterator_wrapper + operator--(int) + { + random_access_iterator_wrapper tmp = *this; + --*this; + return tmp; + } + + random_access_iterator_wrapper& + operator+=(ptrdiff_t n) + { + if(n > 0) + { + ITERATOR_VERIFY(n <= this->SharedInfo->last - this->ptr); + this->ptr += n; + } + else + { + ITERATOR_VERIFY(n <= this->ptr - this->SharedInfo->first); + this->ptr += n; + } + return *this; + } + + random_access_iterator_wrapper& + operator-=(ptrdiff_t n) + { return *this += -n; } + + random_access_iterator_wrapper + operator-(ptrdiff_t n) const + { + random_access_iterator_wrapper tmp = *this; + return tmp -= n; + } + + ptrdiff_t + operator-(const random_access_iterator_wrapper& in) const + { + ITERATOR_VERIFY(this->SharedInfo == in.SharedInfo); + return this->ptr - in.ptr; + } + + T& + operator[](ptrdiff_t n) const + { return *(*this + n); } + + bool + operator<(const random_access_iterator_wrapper& in) const + { + ITERATOR_VERIFY(this->SharedInfo == in.SharedInfo); + return this->ptr < in.ptr; + } + + bool + operator>(const random_access_iterator_wrapper& in) const + { + return in < *this; + } + + bool + operator>=(const random_access_iterator_wrapper& in) const + { + return !(*this < in); + } + + bool + operator<=(const random_access_iterator_wrapper& in) const + { + return !(*this > in); + } + }; + + template + random_access_iterator_wrapper + operator+(random_access_iterator_wrapper it, ptrdiff_t n) + { return it += n; } + + template + random_access_iterator_wrapper + operator+(ptrdiff_t n, random_access_iterator_wrapper it) + { return it += n; } + + + /** + * @brief A container-type class for holding iterator wrappers + * test_container takes two parameters, a class T and an iterator + * wrapper templated by T (for example forward_iterator_wrapper. + * It takes two pointers representing a range and presents them as + * a container of iterators. + */ + template class ItType> + struct test_container + { + typename ItType::ContainerType bounds; + test_container(T* _first, T* _last):bounds(_first, _last) + { } + + ItType + it(int pos) + { + ITERATOR_VERIFY(pos >= 0 && pos <= (bounds.last - bounds.first)); + return ItType(bounds.first + pos, &bounds); + } + + ItType + it(T* pos) + { + ITERATOR_VERIFY(pos >= bounds.first && pos <= bounds.last); + return ItType(pos, &bounds); + } + + ItType + begin() + { return it(bounds.first); } + + ItType + end() + { return it(bounds.last); } + }; +} +#endif diff --git a/libstdc++-v3/testsuite/util/testsuite_performance.h b/libstdc++-v3/testsuite/util/testsuite_performance.h new file mode 100644 index 00000000000..f902dd0c6d9 --- /dev/null +++ b/libstdc++-v3/testsuite/util/testsuite_performance.h @@ -0,0 +1,263 @@ +// -*- C++ -*- +// Testing performance utilities for the C++ library testsuite. +// +// Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. +// +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_PERFORMANCE_H +#define _GLIBCXX_PERFORMANCE_H + +#include +#include +#include +#include +#include +#include + +#ifdef __linux__ +#include +#elif defined (__FreeBSD__) +extern "C" +{ + struct mallinfo + { + int uordblks; + int hblkhd; + }; + + struct mallinfo + mallinfo(void) + { + struct mallinfo m = { (((size_t) sbrk (0) + 1023) / 1024), 0 }; + return m; + } +} +#elif !defined (__hpux__) +extern "C" +{ + struct mallinfo + { + int uordblks; + int hblkhd; + }; + + struct mallinfo empty = { 0, 0 }; + + struct mallinfo + mallinfo(void) + { return empty; } +} +#endif + +namespace __gnu_test +{ + class time_counter + { + private: + clock_t elapsed_begin; + clock_t elapsed_end; + tms tms_begin; + tms tms_end; + + public: + explicit + time_counter() : elapsed_begin(), elapsed_end(), tms_begin(), tms_end() + { } + + void + clear() throw() + { + elapsed_begin = clock_t(); + elapsed_end = clock_t(); + tms_begin = tms(); + tms_end = tms(); + } + + void + start() + { + this->clear(); + elapsed_begin = times(&tms_begin); + const clock_t err = clock_t(-1); + if (elapsed_begin == err) + std::__throw_runtime_error("time_counter::start"); + } + + void + stop() + { + elapsed_end = times(&tms_end); + const clock_t err = clock_t(-1); + if (elapsed_end == err) + std::__throw_runtime_error("time_counter::stop"); + } + + size_t + real_time() const + { return elapsed_end - elapsed_begin; } + + size_t + user_time() const + { return tms_end.tms_utime - tms_begin.tms_utime; } + + size_t + system_time() const + { return tms_end.tms_stime - tms_begin.tms_stime; } + }; + + class resource_counter + { + int who; + rusage rusage_begin; + rusage rusage_end; + struct mallinfo allocation_begin; + struct mallinfo allocation_end; + + public: + resource_counter(int i = RUSAGE_SELF) : who(i) + { this->clear(); } + + void + clear() throw() + { + memset(&rusage_begin, 0, sizeof(rusage_begin)); + memset(&rusage_end, 0, sizeof(rusage_end)); + memset(&allocation_begin, 0, sizeof(allocation_begin)); + memset(&allocation_end, 0, sizeof(allocation_end)); + } + + void + start() + { + if (getrusage(who, &rusage_begin) != 0 ) + memset(&rusage_begin, 0, sizeof(rusage_begin)); + malloc(0); // Needed for some implementations. + allocation_begin = mallinfo(); + } + + void + stop() + { + if (getrusage(who, &rusage_end) != 0 ) + memset(&rusage_end, 0, sizeof(rusage_end)); + allocation_end = mallinfo(); + } + + int + allocated_memory() const + { return ((allocation_end.uordblks - allocation_begin.uordblks) + + (allocation_end.hblkhd - allocation_begin.hblkhd)); } + + long + hard_page_fault() const + { return rusage_end.ru_majflt - rusage_begin.ru_majflt; } + + long + swapped() const + { return rusage_end.ru_nswap - rusage_begin.ru_nswap; } + }; + + inline void + start_counters(time_counter& t, resource_counter& r) + { + t.start(); + r.start(); + } + + inline void + stop_counters(time_counter& t, resource_counter& r) + { + t.stop(); + r.stop(); + } + + inline void + clear_counters(time_counter& t, resource_counter& r) + { + t.clear(); + r.clear(); + } + + void + report_performance(const std::string file, const std::string comment, + const time_counter& t, const resource_counter& r) + { + const char space = ' '; + const char tab = '\t'; + const char* name = "libstdc++-performance.sum"; + std::string::const_iterator i = file.begin() + file.find_last_of('/') + 1; + std::string testname(i, file.end()); + + std::ofstream out(name, std::ios_base::app); + +#ifdef __GTHREADS + if (__gthread_active_p()) + testname.append("-thread"); +#endif + + out.setf(std::ios_base::left); + out << std::setw(25) << testname << tab; + out << std::setw(25) << comment << tab; + + out.setf(std::ios_base::right); + out << std::setw(4) << t.real_time() << "r" << space; + out << std::setw(4) << t.user_time() << "u" << space; + out << std::setw(4) << t.system_time() << "s" << space; + out << std::setw(8) << r.allocated_memory() << "mem" << space; + out << std::setw(4) << r.hard_page_fault() << "pf" << space; + + out << std::endl; + out.close(); + } + + void + report_header(const std::string file, const std::string header) + { + const char space = ' '; + const char tab = '\t'; + const char* name = "libstdc++-performance.sum"; + std::string::const_iterator i = file.begin() + file.find_last_of('/') + 1; + std::string testname(i, file.end()); + + std::ofstream out(name, std::ios_base::app); + +#ifdef __GTHREADS + if (__gthread_active_p ()) + testname.append("-thread"); +#endif + + out.setf(std::ios_base::left); + out << std::setw(25) << testname << tab; + out << std::setw(40) << header << tab; + + out << std::endl; + out.close(); + } +}; // namespace __gnu_test + +#endif // _GLIBCXX_PERFORMANCE_H + diff --git a/libstdc++-v3/testsuite/util/testsuite_shared.cc b/libstdc++-v3/testsuite/util/testsuite_shared.cc new file mode 100644 index 00000000000..d651442ed03 --- /dev/null +++ b/libstdc++-v3/testsuite/util/testsuite_shared.cc @@ -0,0 +1,72 @@ +// Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +#include +#include +#include +#include +#include + +// libstdc++/22309 +extern "C" void +try_allocation() +{ + typedef char value_t; + + typedef __gnu_cxx::__mt_alloc allocator_t; + + typedef std::char_traits traits_t; + typedef std::basic_string string_t; + + string_t s; + s += "west beach, indiana dunes"; +} + +// libstdc++/23591 +extern "C" void +try_throw_exception() +{ + try + { + throw std::bad_exception(); + } + catch (const std::exception& e) + { } +} + +extern "C" void +try_function_random_fail() +{ + long seed = lrand48(); + if (seed < 2000) + seed = 2000; + + { + std::ostringstream s; + s << "random_throw, seed: " << seed << std::endl; + std::cout << s.str(); + } + + while (--seed > 0) + { + try_throw_exception(); + } + + // Randomly throw. See if other threads cleanup. + throw std::bad_exception(); +} diff --git a/libstdc++-v3/testsuite/util/testsuite_tr1.h b/libstdc++-v3/testsuite/util/testsuite_tr1.h new file mode 100644 index 00000000000..439d435ee8b --- /dev/null +++ b/libstdc++-v3/testsuite/util/testsuite_tr1.h @@ -0,0 +1,192 @@ +// -*- C++ -*- +// Testing utilities for the tr1 testsuite. +// +// Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. +// +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_TESTSUITE_TR1_H +#define _GLIBCXX_TESTSUITE_TR1_H + +#include + +namespace __gnu_test +{ + // For tr1/type_traits. + template class Category, + typename Type> + bool + test_category(bool value) + { + bool ret = true; + ret &= Category::value == value; + ret &= Category::value == value; + ret &= Category::value == value; + ret &= Category::value == value; + ret &= Category::type::value == value; + ret &= Category::type::value == value; + ret &= Category::type::value == value; + ret &= Category::type::value == value; + return ret; + } + + template class Property, + typename Type> + bool + test_property(typename Property::value_type value) + { + bool ret = true; + ret &= Property::value == value; + ret &= Property::type::value == value; + return ret; + } + + // For testing tr1/type_traits/extent, which has a second template + // parameter. + template class Property, + typename Type, + unsigned Uint> + bool + test_property(typename Property::value_type value) + { + bool ret = true; + ret &= Property::value == value; + ret &= Property::type::value == value; + return ret; + } + + template class Relationship, + typename Type1, typename Type2> + bool + test_relationship(bool value) + { + bool ret = true; + ret &= Relationship::value == value; + ret &= Relationship::type::value == value; + return ret; + } + + // Test types. + class ClassType { }; + typedef const ClassType cClassType; + typedef volatile ClassType vClassType; + typedef const volatile ClassType cvClassType; + + class DerivedType : public ClassType { }; + + enum EnumType { }; + + struct ConvType + { operator int() const; }; + + class AbstractClass + { + virtual void rotate(int) = 0; + virtual ~AbstractClass(); + }; + + class PolymorphicClass + { + virtual void rotate(int); + virtual ~PolymorphicClass(); + }; + + class DerivedPolymorphic : public PolymorphicClass { }; + + union UnionType { }; + + class IncompleteClass; + + int truncate_float(float x) { return (int)x; } + long truncate_double(double x) { return (long)x; } + + struct do_truncate_float_t + { + do_truncate_float_t() + { + ++live_objects; + } + + do_truncate_float_t(const do_truncate_float_t&) + { + ++live_objects; + } + + ~do_truncate_float_t() + { + --live_objects; + } + + int operator()(float x) { return (int)x; } + + static int live_objects; + }; + + int do_truncate_float_t::live_objects = 0; + + struct do_truncate_double_t + { + do_truncate_double_t() + { + ++live_objects; + } + + do_truncate_double_t(const do_truncate_double_t&) + { + ++live_objects; + } + + ~do_truncate_double_t() + { + --live_objects; + } + + long operator()(double x) { return (long)x; } + + static int live_objects; + }; + + int do_truncate_double_t::live_objects = 0; + + struct X + { + int bar; + + int foo() { return 1; } + int foo_c() const { return 2; } + int foo_v() volatile { return 3; } + int foo_cv() const volatile { return 4; } + }; + + // For use in 8_c_compatibility. + template + typename std::__enable_if::__value>::__type + check_ret_type(T) + { return true; } + +} // namespace __gnu_test + +#endif // _GLIBCXX_TESTSUITE_TR1_H diff --git a/libstdc++-v3/testsuite/util/testsuite_visualization.h b/libstdc++-v3/testsuite/util/testsuite_visualization.h new file mode 100644 index 00000000000..0e2757666a4 --- /dev/null +++ b/libstdc++-v3/testsuite/util/testsuite_visualization.h @@ -0,0 +1,150 @@ +// Copyright (C) 2005 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#include +#include +#include +#include +#include +#include + +// Ah, we wish it wasn't so... +bool first_container = false; +extern const char* filename; + +typedef std::string::size_type (*callback_type) (std::string&); + +template + void + write_viz_container(callback_type find_container, const char* filename) + { + typedef std::string string; + + // Create title. + { + const char ws(' '); + std::ostringstream title; + + std::string titlename(filename); + std::string::size_type n = titlename.find('.'); + if (n != string::npos) + titlename = std::string(titlename.begin(), titlename.begin() + n); + + title << titlename; + title << ws; + title << Iter; + title << ws; +#if 0 + title << "thread<"; + std::boolalpha(title); + title << Thread; + title << '>'; +#endif + + titlename += ".title"; + std::ofstream titlefile(titlename.c_str()); + if (!titlefile.good()) + throw std::runtime_error("write_viz_data cannot open titlename"); + titlefile << title.str() << std::endl; + } + + // Create compressed type name. + Container obj; + int status; + std::string type(abi::__cxa_demangle(typeid(obj).name(), 0, 0, &status)); + + // Extract fully-qualified typename. + // Assumes "set" or "map" are uniquely determinate. + string::iterator beg = type.begin(); + string::iterator end; + string::size_type n = (*find_container)(type); + + // Find start of fully-qualified name. + // Assume map, find end. + string::size_type nend = type.find('<', n); + if (nend != string::npos) + end = type.begin() + nend; + + string compressed_type; + compressed_type += '"'; + compressed_type += string(beg, end); + compressed_type += '<'; +#if 0 + typename Container::key_type v; + compressed_type += typeid(v).name(); +#else + compressed_type += "int"; +#endif + compressed_type += ", A>"; + + // XXX + if (Thread == true) + compressed_type += " thread"; + compressed_type += '"'; + + std::ofstream file(filename, std::ios_base::app); + if (!file.good()) + throw std::runtime_error("write_viz_data cannot open filename"); + + file << compressed_type; + first_container = false; + } + + +void +write_viz_data(__gnu_test::time_counter& time, const char* filename) +{ + std::ofstream file(filename, std::ios_base::app); + if (!file.good()) + throw std::runtime_error("write_viz_data cannot open filename"); + + // Print out score in appropriate column. + const char tab('\t'); + int score = time.real_time(); + file << tab << score; +} + +void +write_viz_endl(const char* filename) +{ + std::ofstream file(filename, std::ios_base::app); + if (!file.good()) + throw std::runtime_error("write_viz_endl cannot open filename"); + file << std::endl; +} + + +#if 0 +// cons +write_viz_container(&sequence_find_container, + filename); +#endif + +#if 0 +// dtor +write_viz_endl(filename) +#endif