diff options
Diffstat (limited to 'libstdc++-v3')
12 files changed, 1791 insertions, 0 deletions
diff --git a/libstdc++-v3/include/debug/formatter.h b/libstdc++-v3/include/debug/formatter.h new file mode 100644 index 00000000000..1a627a98dda --- /dev/null +++ b/libstdc++-v3/include/debug/formatter.h @@ -0,0 +1,389 @@ +// Debug-mode error formatting implementation -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// 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_DEBUG_FORMATTER_H +#define _GLIBCXX_DEBUG_FORMATTER_H 1 + +#include <typeinfo> +#include <debug/debug.h> + +namespace __gnu_debug +{ + using namespace std; + + /** Determine if the two types are the same. */ + template<typename _Type1, typename _Type2> + struct __is_same + { + static const bool value = false; + }; + + template<typename _Type> + struct __is_same<_Type, _Type> + { + static const bool value = true; + }; + + template<bool> struct __truth { }; + + class _Safe_sequence_base; + + template<typename _Iterator, typename _Sequence> + class _Safe_iterator; + + template<typename _Sequence> + class _Safe_sequence; + + enum _Debug_msg_id + { + // General checks + __msg_valid_range, + __msg_insert_singular, + __msg_insert_different, + __msg_erase_bad, + __msg_erase_different, + __msg_subscript_oob, + __msg_empty, + __msg_unpartitioned, + __msg_unpartitioned_pred, + __msg_unsorted, + __msg_unsorted_pred, + __msg_not_heap, + __msg_not_heap_pred, + // std::bitset checks + __msg_bad_bitset_write, + __msg_bad_bitset_read, + __msg_bad_bitset_flip, + // std::list checks + __msg_self_splice, + __msg_splice_alloc, + __msg_splice_bad, + __msg_splice_other, + __msg_splice_overlap, + // iterator checks + __msg_init_singular, + __msg_init_copy_singular, + __msg_init_const_singular, + __msg_copy_singular, + __msg_bad_deref, + __msg_bad_inc, + __msg_bad_dec, + __msg_iter_subscript_oob, + __msg_advance_oob, + __msg_retreat_oob, + __msg_iter_compare_bad, + __msg_compare_different, + __msg_iter_order_bad, + __msg_order_different, + __msg_distance_bad, + __msg_distance_different, + // istream_iterator + __msg_deref_istream, + __msg_inc_istream, + // ostream_iterator + __msg_output_ostream, + // istreambuf_iterator + __msg_deref_istreambuf, + __msg_inc_istreambuf + }; + + class _Error_formatter + { + /// Whether an iterator is constant, mutable, or unknown + enum _Constness + { + __unknown_constness, + __const_iterator, + __mutable_iterator, + __last_constness + }; + + // The state of the iterator (fine-grained), if we know it. + enum _Iterator_state + { + __unknown_state, + __singular, // singular, may still be attached to a sequence + __begin, // dereferenceable, and at the beginning + __middle, // dereferenceable, not at the beginning + __end, // past-the-end, may be at beginning if sequence empty + __last_state + }; + + // Tags denoting the type of parameter for construction + struct _Is_iterator { }; + struct _Is_sequence { }; + + // A parameter that may be referenced by an error message + struct _Parameter + { + enum + { + __unused_param, + __iterator, + __sequence, + __integer, + __string + } _M_kind; + + union + { + // When _M_kind == __iterator + struct + { + const char* _M_name; + const void* _M_address; + const type_info* _M_type; + _Constness _M_constness; + _Iterator_state _M_state; + const void* _M_sequence; + const type_info* _M_seq_type; + } _M_iterator; + + // When _M_kind == __sequence + struct + { + const char* _M_name; + const void* _M_address; + const type_info* _M_type; + } _M_sequence; + + // When _M_kind == __integer + struct + { + const char* _M_name; + long _M_value; + } _M_integer; + + // When _M_kind == __string + struct + { + const char* _M_name; + const char* _M_value; + } _M_string; + } _M_variant; + + _Parameter() : _M_kind(__unused_param) { } + + _Parameter(long __value, const char* __name) : _M_kind(__integer) + { + _M_variant._M_integer._M_name = __name; + _M_variant._M_integer._M_value = __value; + } + + _Parameter(const char* __value, const char* __name) : _M_kind(__string) + { + _M_variant._M_string._M_name = __name; + _M_variant._M_string._M_value = __value; + } + + template<typename _Iterator, typename _Sequence> + _Parameter(const _Safe_iterator<_Iterator, _Sequence>& __it, + const char* __name, _Is_iterator) + : _M_kind(__iterator) + { + _M_variant._M_iterator._M_name = __name; + _M_variant._M_iterator._M_address = &__it; + _M_variant._M_iterator._M_type = &typeid(__it); + _M_variant._M_iterator._M_constness = + __is_same<_Safe_iterator<_Iterator, _Sequence>, + typename _Sequence::iterator>:: + value? __mutable_iterator : __const_iterator; + _M_variant._M_iterator._M_sequence = __it._M_get_sequence(); + _M_variant._M_iterator._M_seq_type = &typeid(_Sequence); + + if (__it._M_singular()) + _M_variant._M_iterator._M_state = __singular; + else + { + bool __is_begin = __it._M_is_begin(); + bool __is_end = __it._M_is_end(); + if (__is_end) + _M_variant._M_iterator._M_state = __end; + else if (__is_begin) + _M_variant._M_iterator._M_state = __begin; + else + _M_variant._M_iterator._M_state = __middle; + } + } + + template<typename _Type> + _Parameter(const _Type*& __it, const char* __name, _Is_iterator) + : _M_kind(__iterator) + { + _M_variant._M_iterator._M_name = __name; + _M_variant._M_iterator._M_address = &__it; + _M_variant._M_iterator._M_type = &typeid(__it); + _M_variant._M_iterator._M_constness = __mutable_iterator; + _M_variant._M_iterator._M_state = __it? __unknown_state : __singular; + _M_variant._M_iterator._M_sequence = 0; + _M_variant._M_iterator._M_seq_type = 0; + } + + template<typename _Type> + _Parameter(_Type*& __it, const char* __name, _Is_iterator) + : _M_kind(__iterator) + { + _M_variant._M_iterator._M_name = __name; + _M_variant._M_iterator._M_address = &__it; + _M_variant._M_iterator._M_type = &typeid(__it); + _M_variant._M_iterator._M_constness = __const_iterator; + _M_variant._M_iterator._M_state = __it? __unknown_state : __singular; + _M_variant._M_iterator._M_sequence = 0; + _M_variant._M_iterator._M_seq_type = 0; + } + + template<typename _Iterator> + _Parameter(const _Iterator& __it, const char* __name, _Is_iterator) + : _M_kind(__iterator) + { + _M_variant._M_iterator._M_name = __name; + _M_variant._M_iterator._M_address = &__it; + _M_variant._M_iterator._M_type = &typeid(__it); + _M_variant._M_iterator._M_constness = __unknown_constness; + _M_variant._M_iterator._M_state = + __gnu_debug::__check_singular(__it)? __singular : __unknown_state; + _M_variant._M_iterator._M_sequence = 0; + _M_variant._M_iterator._M_seq_type = 0; + } + + template<typename _Sequence> + _Parameter(const _Safe_sequence<_Sequence>& __seq, + const char* __name, _Is_sequence) + : _M_kind(__sequence) + { + _M_variant._M_sequence._M_name = __name; + _M_variant._M_sequence._M_address = + static_cast<const _Sequence*>(&__seq); + _M_variant._M_sequence._M_type = &typeid(_Sequence); + } + + template<typename _Sequence> + _Parameter(const _Sequence& __seq, const char* __name, _Is_sequence) + : _M_kind(__sequence) + { + _M_variant._M_sequence._M_name = __name; + _M_variant._M_sequence._M_address = &__seq; + _M_variant._M_sequence._M_type = &typeid(_Sequence); + } + + void + _M_print_field(const _Error_formatter* __formatter, + const char* __name) const; + + void + _M_print_description(const _Error_formatter* __formatter) const; + }; + + friend struct _Parameter; + + public: + template<typename _Iterator> + const _Error_formatter& + _M_iterator(const _Iterator& __it, const char* __name = 0) const + { + if (_M_num_parameters < __max_parameters) + _M_parameters[_M_num_parameters++] = _Parameter(__it, __name, + _Is_iterator()); + return *this; + } + + const _Error_formatter& + _M_integer(long __value, const char* __name = 0) const + { + if (_M_num_parameters < __max_parameters) + _M_parameters[_M_num_parameters++] = _Parameter(__value, __name); + return *this; + } + + const _Error_formatter& + _M_string(const char* __value, const char* __name = 0) const + { + if (_M_num_parameters < __max_parameters) + _M_parameters[_M_num_parameters++] = _Parameter(__value, __name); + return *this; + } + + template<typename _Sequence> + const _Error_formatter& + _M_sequence(const _Sequence& __seq, const char* __name = 0) const + { + if (_M_num_parameters < __max_parameters) + _M_parameters[_M_num_parameters++] = _Parameter(__seq, __name, + _Is_sequence()); + return *this; + } + + const _Error_formatter& + _M_message(const char* __text) const + { _M_text = __text; return *this; } + + const _Error_formatter& + _M_message(_Debug_msg_id __id) const; + + void + _M_error() const; + + private: + _Error_formatter(const char* __file, size_t __line) + : _M_file(__file), _M_line(__line), _M_num_parameters(0), _M_text(0), + _M_max_length(78), _M_column(1), _M_first_line(true), _M_wordwrap(false) + { } + + template<typename _Tp> + void + _M_format_word(char*, int, const char*, _Tp) const; + + void + _M_print_word(const char* __word) const; + + void + _M_print_string(const char* __string) const; + + enum { __max_parameters = 9 }; + + const char* _M_file; + size_t _M_line; + mutable _Parameter _M_parameters[__max_parameters]; + mutable size_t _M_num_parameters; + mutable const char* _M_text; + mutable size_t _M_max_length; + enum { _M_indent = 4 } ; + mutable size_t _M_column; + mutable bool _M_first_line; + mutable bool _M_wordwrap; + + public: + static _Error_formatter + _M_at(const char* __file, size_t __line) + { return _Error_formatter(__file, __line); } + }; +} // namespace __gnu_debug + +#endif diff --git a/libstdc++-v3/src/debug.cc b/libstdc++-v3/src/debug.cc new file mode 100644 index 00000000000..a78bdec2df3 --- /dev/null +++ b/libstdc++-v3/src/debug.cc @@ -0,0 +1,660 @@ +// Debugging mode support code -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// 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 <debug/debug.h> +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> +#include <algorithm> +#include <cstdlib> +#include <cassert> +#include <cstring> +#include <cstdio> +#include <cctype> + +using namespace std; + +namespace __gnu_debug +{ + const char* _S_debug_messages[] = + { + "function requires a valid iterator range [%1.name;, %2.name;)", + "attempt to insert into container with a singular iterator", + "attempt to insert into container with an iterator" + " from a different container", + "attempt to erase from container with a %2.state; iterator", + "attempt to erase from container with an iterator" + " from a different container", + "attempt to subscript container with out-of-bounds index %2;," + " but container only holds %3; elements", + "attempt to access an element in an empty container", + "elements in iterator range [%1.name;, %2.name;)" + " are not partitioned by the value %3;", + "elements in iterator range [%1.name;, %2.name;)" + " are not partitioned by the predicate %3; and value %4;", + "elements in iterator range [%1.name;, %2.name;) are not sorted", + "elements in iterator range [%1.name;, %2.name;)" + " are not sorted according to the predicate %3;", + "elements in iterator range [%1.name;, %2.name;) do not form a heap", + "elements in iterator range [%1.name;, %2.name;)" + " do not form a heap with respect to the predicate %3;", + "attempt to write through a singular bitset reference", + "attempt to read from a singular bitset reference", + "attempt to flip a singular bitset reference", + "attempt to splice a list into itself", + "attempt to splice lists with inequal allocators", + "attempt to splice elements referenced by a %1.state; iterator", + "attempt to splice an iterator from a different container", + "splice destination %1.name;" + " occurs within source range [%2.name;, %3.name;)", + "attempt to initialize an iterator that will immediately become singular", + "attempt to copy-construct an iterator from a singular iterator", + "attempt to construct a constant iterator" + " from a singular mutable iterator", + "attempt to copy from a singular iterator", + "attempt to dereference a %1.state; iterator", + "attempt to increment a %1.state; iterator", + "attempt to decrement a %1.state; iterator", + "attempt to subscript a %1.state; iterator %2; step from" + " its current position, which falls outside its dereferenceable range", + "attempt to advance a %1.state; iterator %2; steps," + " which falls outside its valid range", + "attempt to retreat a %1.state; iterator %2; steps," + " which falls outside its valid range", + "attempt to compare a %1.state; iterator to a %2.state; iterator", + "attempt to compare iterators from different sequences", + "attempt to order a %1.state; iterator to a %2.state; iterator", + "attempt to order iterators from different sequences", + "attempt to compute the difference between a %1.state;" + " iterator to a %2.state; iterator", + "attempt to compute the different between two iterators" + " from different sequences", + "attempt to dereference an end-of-stream istream_iterator", + "attempt to increment an end-of-stream istream_iterator", + "attempt to output via an ostream_iterator with no associated stream", + "attempt to dereference an end-of-stream istreambuf_iterator" + " (this is a GNU extension)", + "attempt to increment an end-of-stream istreambuf_iterator" + }; + + void + _Safe_sequence_base:: + _M_detach_all() + { + for (_Safe_iterator_base* iter = _M_iterators; iter; ) + { + _Safe_iterator_base* old = iter; + iter = iter->_M_next; + old->_M_attach(0, false); + } + + for (_Safe_iterator_base* iter = _M_const_iterators; iter; ) + { + _Safe_iterator_base* old = iter; + iter = iter->_M_next; + old->_M_attach(0, true); + } + } + + void + _Safe_sequence_base:: + _M_detach_singular() + { + for (_Safe_iterator_base* iter = _M_iterators; iter; ) + { + _Safe_iterator_base* old = iter; + iter = iter->_M_next; + if (old->_M_singular()) + old->_M_attach(0, false); + } + + for (_Safe_iterator_base* iter = _M_const_iterators; iter; ) + { + _Safe_iterator_base* old = iter; + iter = iter->_M_next; + if (old->_M_singular()) + old->_M_attach(0, true); + } + } + + void + _Safe_sequence_base:: + _M_revalidate_singular() + { + _Safe_iterator_base* iter; + for (iter = _M_iterators; iter; iter = iter->_M_next) + { + iter->_M_version = _M_version; + iter = iter->_M_next; + } + + for (iter = _M_const_iterators; iter; iter = iter->_M_next) + { + iter->_M_version = _M_version; + iter = iter->_M_next; + } + } + + void + _Safe_sequence_base:: + _M_swap(_Safe_sequence_base& __x) + { + swap(_M_iterators, __x._M_iterators); + swap(_M_const_iterators, __x._M_const_iterators); + swap(_M_version, __x._M_version); + _Safe_iterator_base* iter; + for (iter = _M_iterators; iter; iter = iter->_M_next) + iter->_M_sequence = this; + for (iter = __x._M_iterators; iter; iter = iter->_M_next) + iter->_M_sequence = &__x; + for (iter = _M_const_iterators; iter; iter = iter->_M_next) + iter->_M_sequence = this; + for (iter = __x._M_const_iterators; iter; iter = iter->_M_next) + iter->_M_sequence = &__x; + } + + void + _Safe_iterator_base:: + _M_attach(_Safe_sequence_base* __seq, bool __constant) + { + _M_detach(); + + // Attach to the new sequence (if there is one) + if (__seq) + { + _M_sequence = __seq; + _M_version = _M_sequence->_M_version; + _M_prior = 0; + if (__constant) + { + _M_next = _M_sequence->_M_const_iterators; + if (_M_next) + _M_next->_M_prior = this; + _M_sequence->_M_const_iterators = this; + } + else + { + _M_next = _M_sequence->_M_iterators; + if (_M_next) + _M_next->_M_prior = this; + _M_sequence->_M_iterators = this; + } + } + } + + void + _Safe_iterator_base:: + _M_detach() + { + if (_M_sequence) + { + // Remove us from this sequence's list + if (_M_prior) + _M_prior->_M_next = _M_next; + if (_M_next) + _M_next->_M_prior = _M_prior; + + if (_M_sequence->_M_const_iterators == this) + _M_sequence->_M_const_iterators = _M_next; + if (_M_sequence->_M_iterators == this) + _M_sequence->_M_iterators = _M_next; + } + + _M_sequence = 0; + _M_version = 0; + _M_prior = 0; + _M_next = 0; + } + + bool + _Safe_iterator_base:: + _M_singular() const + { return !_M_sequence || _M_version != _M_sequence->_M_version; } + + bool + _Safe_iterator_base:: + _M_can_compare(const _Safe_iterator_base& __x) const + { + return (!_M_singular() && !__x._M_singular() + && _M_sequence == __x._M_sequence); + } + + void + _Error_formatter::_Parameter:: + _M_print_field(const _Error_formatter* __formatter, const char* __name) const + { + assert(this->_M_kind != _Parameter::__unused_param); + const int bufsize = 64; + char buf[bufsize]; + + if (_M_kind == __iterator) + { + if (strcmp(__name, "name") == 0) + { + assert(_M_variant._M_iterator._M_name); + __formatter->_M_print_word(_M_variant._M_iterator._M_name); + } + else if (strcmp(__name, "address") == 0) + { + __formatter->_M_format_word(buf, bufsize, "%p", + _M_variant._M_iterator._M_address); + __formatter->_M_print_word(buf); + } + else if (strcmp(__name, "type") == 0) + { + assert(_M_variant._M_iterator._M_type); + // TBD: demangle! + __formatter->_M_print_word(_M_variant._M_iterator._M_type->name()); + } + else if (strcmp(__name, "constness") == 0) + { + static const char* __constness_names[__last_constness] = + { + "<unknown>", + "constant", + "mutable" + }; + __formatter->_M_print_word(__constness_names[_M_variant._M_iterator._M_constness]); + } + else if (strcmp(__name, "state") == 0) + { + static const char* __state_names[__last_state] = + { + "<unknown>", + "singular", + "dereferenceable (start-of-sequence)", + "dereferenceable", + "past-the-end" + }; + __formatter->_M_print_word(__state_names[_M_variant._M_iterator._M_state]); + } + else if (strcmp(__name, "sequence") == 0) + { + assert(_M_variant._M_iterator._M_sequence); + __formatter->_M_format_word(buf, bufsize, "%p", + _M_variant._M_iterator._M_sequence); + __formatter->_M_print_word(buf); + } + else if (strcmp(__name, "seq_type") == 0) + { + // TBD: demangle! + assert(_M_variant._M_iterator._M_seq_type); + __formatter->_M_print_word(_M_variant._M_iterator._M_seq_type->name()); + } + else + assert(false); + } + else if (_M_kind == __sequence) + { + if (strcmp(__name, "name") == 0) + { + assert(_M_variant._M_sequence._M_name); + __formatter->_M_print_word(_M_variant._M_sequence._M_name); + } + else if (strcmp(__name, "address") == 0) + { + assert(_M_variant._M_sequence._M_address); + __formatter->_M_format_word(buf, bufsize, "%p", + _M_variant._M_sequence._M_address); + __formatter->_M_print_word(buf); + } + else if (strcmp(__name, "type") == 0) + { + // TBD: demangle! + assert(_M_variant._M_sequence._M_type); + __formatter->_M_print_word(_M_variant._M_sequence._M_type->name()); + } + else + assert(false); + } + else if (_M_kind == __integer) + { + if (strcmp(__name, "name") == 0) + { + assert(_M_variant._M_integer._M_name); + __formatter->_M_print_word(_M_variant._M_integer._M_name); + } + else + assert(false); + } + else if (_M_kind == __string) + { + if (strcmp(__name, "name") == 0) + { + assert(_M_variant._M_string._M_name); + __formatter->_M_print_word(_M_variant._M_string._M_name); + } + else + assert(false); + } + else + { + assert(false); + } + } + + void + _Error_formatter::_Parameter:: + _M_print_description(const _Error_formatter* __formatter) const + { + const int bufsize = 128; + char buf[bufsize]; + + if (_M_kind == __iterator) + { + __formatter->_M_print_word("iterator "); + if (_M_variant._M_iterator._M_name) + { + __formatter->_M_format_word(buf, bufsize, "\"%s\" ", + _M_variant._M_iterator._M_name); + __formatter->_M_print_word(buf); + } + + __formatter->_M_format_word(buf, bufsize, "@ 0x%p {\n", + _M_variant._M_iterator._M_address); + __formatter->_M_print_word(buf); + if (_M_variant._M_iterator._M_type) + { + __formatter->_M_print_word("type = "); + _M_print_field(__formatter, "type"); + + if (_M_variant._M_iterator._M_constness != __unknown_constness) + { + __formatter->_M_print_word(" ("); + _M_print_field(__formatter, "constness"); + __formatter->_M_print_word(" iterator)"); + } + __formatter->_M_print_word(";\n"); + } + + if (_M_variant._M_iterator._M_state != __unknown_state) + { + __formatter->_M_print_word(" state = "); + _M_print_field(__formatter, "state"); + __formatter->_M_print_word(";\n"); + } + + if (_M_variant._M_iterator._M_sequence) + { + __formatter->_M_print_word(" references sequence "); + if (_M_variant._M_iterator._M_seq_type) + { + __formatter->_M_print_word("with type `"); + _M_print_field(__formatter, "seq_type"); + __formatter->_M_print_word("' "); + } + + __formatter->_M_format_word(buf, bufsize, "@ 0x%p\n", + _M_variant._M_sequence._M_address); + __formatter->_M_print_word(buf); + } + __formatter->_M_print_word("}\n"); + } + else if (_M_kind == __sequence) + { + __formatter->_M_print_word("sequence "); + if (_M_variant._M_sequence._M_name) + { + __formatter->_M_format_word(buf, bufsize, "\"%s\" ", + _M_variant._M_sequence._M_name); + __formatter->_M_print_word(buf); + } + + __formatter->_M_format_word(buf, bufsize, "@ 0x%p {\n", + _M_variant._M_sequence._M_address); + __formatter->_M_print_word(buf); + + if (_M_variant._M_sequence._M_type) + { + __formatter->_M_print_word(" type = "); + _M_print_field(__formatter, "type"); + __formatter->_M_print_word(";\n"); + } + __formatter->_M_print_word("}\n"); + } + } + + const _Error_formatter& + _Error_formatter::_M_message(_Debug_msg_id __id) const + { return this->_M_message(_S_debug_messages[__id]); } + + void + _Error_formatter::_M_error() const + { + const int bufsize = 128; + char buf[bufsize]; + + // Emit file & line number information + _M_column = 1; + _M_wordwrap = false; + if (_M_file) + { + _M_format_word(buf, bufsize, "%s:", _M_file); + _M_print_word(buf); + _M_column += strlen(buf); + } + + if (_M_line > 0) + { + _M_format_word(buf, bufsize, "%u:", _M_line); + _M_print_word(buf); + _M_column += strlen(buf); + } + + _M_wordwrap = true; + _M_print_word("error: "); + + // Print the error message + assert(_M_text); + _M_print_string(_M_text); + _M_print_word(".\n"); + + // Emit descriptions of the objects involved in the operation + _M_wordwrap = false; + bool has_noninteger_parameters = false; + for (unsigned int i = 0; i < _M_num_parameters; ++i) + { + if (_M_parameters[i]._M_kind == _Parameter::__iterator + || _M_parameters[i]._M_kind == _Parameter::__sequence) + { + if (!has_noninteger_parameters) + { + _M_first_line = true; + _M_print_word("\nObjects involved in the operation:\n"); + has_noninteger_parameters = true; + } + _M_parameters[i]._M_print_description(this); + } + } + + abort(); + } + + template<typename _Tp> + void + _Error_formatter::_M_format_word(char* __buf, + int __n __attribute__((__unused__)), + const char* __fmt, _Tp __s) const + { +#ifdef _GLIBCXX_USE_C99 + std::snprintf(__buf, __n, __fmt, __s); +#else + std::sprintf(__buf, __fmt, __s); +#endif + } + + + void + _Error_formatter::_M_print_word(const char* __word) const + { + if (!_M_wordwrap) + { + fprintf(stderr, "%s", __word); + return; + } + + size_t __length = strlen(__word); + if (__length == 0) + return; + + if ((_M_column + __length < _M_max_length) + || (__length >= _M_max_length && _M_column == 1)) + { + // If this isn't the first line, indent + if (_M_column == 1 && !_M_first_line) + { + char spacing[_M_indent + 1]; + for (int i = 0; i < _M_indent; ++i) + spacing[i] = ' '; + spacing[_M_indent] = '\0'; + fprintf(stderr, "%s", spacing); + _M_column += _M_indent; + } + + fprintf(stderr, "%s", __word); + _M_column += __length; + + if (__word[__length - 1] == '\n') + { + _M_first_line = false; + _M_column = 1; + } + } + else + { + _M_column = 1; + _M_print_word("\n"); + _M_print_word(__word); + } + } + + void + _Error_formatter:: + _M_print_string(const char* __string) const + { + const char* __start = __string; + const char* __end = __start; + const int bufsize = 128; + char buf[bufsize]; + + while (*__start) + { + if (*__start != '%') + { + // [__start, __end) denotes the next word + __end = __start; + while (isalnum(*__end)) ++__end; + if (__start == __end) ++__end; + if (isspace(*__end)) ++__end; + + assert(__end - __start + 1< bufsize); + _M_format_word(buf, __end - __start + 1, "%s", __start); + _M_print_word(buf); + __start = __end; + + // Skip extra whitespace + while (*__start == ' ') + ++__start; + + continue; + } + + ++__start; + assert(*__start); + if (*__start == '%') + { + _M_print_word("%"); + ++__start; + continue; + } + + // Get the parameter number + assert(*__start >= '1' && *__start <= '9'); + size_t param = *__start - '0'; + --param; + assert(param < _M_num_parameters); + + // '.' separates the parameter number from the field + // name, if there is one. + ++__start; + if (*__start != '.') + { + assert(*__start == ';'); + ++__start; + buf[0] = '\0'; + if (_M_parameters[param]._M_kind == _Parameter::__integer) + { + _M_format_word(buf, bufsize, "%ld", + _M_parameters[param]._M_variant._M_integer._M_value); + _M_print_word(buf); + } + else if (_M_parameters[param]._M_kind == _Parameter::__string) + _M_print_string(_M_parameters[param]._M_variant._M_string._M_value); + continue; + } + + // Extract the field name we want + enum { max_field_len = 16 }; + char field[max_field_len]; + int field_idx = 0; + ++__start; + while (*__start != ';') + { + assert(*__start); + assert(field_idx < max_field_len-1); + field[field_idx++] = *__start++; + } + ++__start; + field[field_idx] = 0; + + _M_parameters[param]._M_print_field(this, field); + } + } + + // Instantiations. + template + void + _Error_formatter::_M_format_word(char* __buf, int __n, const char* __fmt, + const void* __s) const; + + template + void + _Error_formatter::_M_format_word(char* __buf, int __n, const char* __fmt, + long __s) const; + + template + void + _Error_formatter::_M_format_word(char* __buf, int __n, const char* __fmt, + std::size_t __s) const; + + template + void + _Error_formatter::_M_format_word(char* __buf, int __n, const char* __fmt, + const char* __s) const; +} // namespace __gnu_debug diff --git a/libstdc++-v3/testsuite/22_locale/num_put/put/char/8.cc b/libstdc++-v3/testsuite/22_locale/num_put/put/char/8.cc new file mode 100644 index 00000000000..4ec8de1d958 --- /dev/null +++ b/libstdc++-v3/testsuite/22_locale/num_put/put/char/8.cc @@ -0,0 +1,68 @@ +// Copyright (C) 2003 Free Software Foundation +// +// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 22.2.2.2.1 num_put members + +#include <locale> +#include <sstream> +#include <testsuite_hooks.h> + +struct Ctype: std::ctype<char> +{ + char + do_widen(char c) const + { return 'A' + c % 26; } + + const char* + do_widen(const char* lo, const char* hi, char* to) const + { + for (; lo != hi; *to++ = Ctype::do_widen(*lo++)); + return hi; + } +}; + +// See http://gcc.gnu.org/ml/libstdc++/2003-11/msg00154.html +void test01() +{ + using namespace std; + bool test __attribute__((unused)) = true; + + ostringstream oss; + oss.imbue(locale(locale::classic(), new Ctype)); + const num_put<char>& np = use_facet<num_put<char> >(oss.getloc()); + + const string empty; + string result; + long inum = 123; + double fnum = 123.456; + + np.put(oss.rdbuf(), oss, '+', inum); + result = oss.str(); + VERIFY( result == "XYZ" ); + + oss.clear(); + oss.str(empty); + np.put(oss.rdbuf(), oss, '+', fnum); + result = oss.str(); + VERIFY( result == "XYZ.ABC" ); +} + +int main() +{ + test01(); +} diff --git a/libstdc++-v3/testsuite/22_locale/num_put/put/wchar_t/8.cc b/libstdc++-v3/testsuite/22_locale/num_put/put/wchar_t/8.cc new file mode 100644 index 00000000000..b1915d4d9f6 --- /dev/null +++ b/libstdc++-v3/testsuite/22_locale/num_put/put/wchar_t/8.cc @@ -0,0 +1,68 @@ +// Copyright (C) 2003 Free Software Foundation +// +// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 22.2.2.2.1 num_put members + +#include <locale> +#include <sstream> +#include <testsuite_hooks.h> + +struct Ctype: std::ctype<wchar_t> +{ + wchar_t + do_widen(char c) const + { return L'A' + c % 26; } + + const char* + do_widen(const char* lo, const char* hi, wchar_t* to) const + { + for (; lo != hi; *to++ = Ctype::do_widen(*lo++)); + return hi; + } +}; + +// See http://gcc.gnu.org/ml/libstdc++/2003-11/msg00154.html +void test01() +{ + using namespace std; + bool test __attribute__((unused)) = true; + + wostringstream oss; + oss.imbue(locale(locale::classic(), new Ctype)); + const num_put<wchar_t>& np = use_facet<num_put<wchar_t> >(oss.getloc()); + + const wstring empty; + wstring result; + long inum = 123; + double fnum = 123.456; + + np.put(oss.rdbuf(), oss, '+', inum); + result = oss.str(); + VERIFY( result == L"XYZ" ); + + oss.clear(); + oss.str(empty); + np.put(oss.rdbuf(), oss, '+', fnum); + result = oss.str(); + VERIFY( result == L"XYZ.ABC" ); +} + +int main() +{ + test01(); +} diff --git a/libstdc++-v3/testsuite/24_iterators/istreambuf_iterator/1.cc b/libstdc++-v3/testsuite/24_iterators/istreambuf_iterator/1.cc new file mode 100644 index 00000000000..8c836e50e15 --- /dev/null +++ b/libstdc++-v3/testsuite/24_iterators/istreambuf_iterator/1.cc @@ -0,0 +1,52 @@ +// { dg-do compile } +// 1999-06-28 bkoz + +// Copyright (C) 1999, 2001, 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 24.5.3 template class istreambuf_iterator + +#include <sstream> +#include <iterator> +#include <testsuite_hooks.h> + +void test01() +{ + using namespace std; + + // Check for required base class. + typedef istreambuf_iterator<char> test_iterator; + typedef char_traits<char>::off_type off_type; + typedef iterator<input_iterator_tag, char, off_type, char*, char&> base_iterator; + + istringstream isstream("this tag"); + test_iterator r_it(isstream); + base_iterator* base __attribute__((unused)) = &r_it; + + // Check for required typedefs + typedef test_iterator::value_type value_type; + typedef test_iterator::difference_type difference_type; + typedef test_iterator::pointer pointer; + typedef test_iterator::reference reference; + typedef test_iterator::iterator_category iteratory_category; + + typedef test_iterator::char_type char_type; + typedef test_iterator::traits_type traits_type; + typedef test_iterator::istream_type istream_type; + typedef test_iterator::streambuf_type streambuf_type; +} diff --git a/libstdc++-v3/testsuite/24_iterators/istreambuf_iterator/2.cc b/libstdc++-v3/testsuite/24_iterators/istreambuf_iterator/2.cc new file mode 100644 index 00000000000..61c88ea65ab --- /dev/null +++ b/libstdc++-v3/testsuite/24_iterators/istreambuf_iterator/2.cc @@ -0,0 +1,117 @@ +// 1999-06-28 bkoz + +// Copyright (C) 1999, 2001, 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 24.5.3 template class istreambuf_iterator + +#include <sstream> +#include <iterator> +#include <testsuite_hooks.h> + +bool test02(void) +{ + + typedef std::istreambuf_iterator<char> cistreambuf_iter; + typedef cistreambuf_iter::streambuf_type cstreambuf_type; + bool test __attribute__((unused)) = true; + const char slit01[] = "playa hermosa, liberia, guanacaste"; + std::string str01(slit01); + std::istringstream istrs00(str01); + std::istringstream istrs01(str01); + + // ctor sanity checks + cistreambuf_iter istrb_it01(istrs00); + cistreambuf_iter istrb_it02; + std::string tmp(istrb_it01, istrb_it02); + VERIFY( tmp == str01 ); + + cistreambuf_iter istrb_it03(0); + cistreambuf_iter istrb_it04; + VERIFY( istrb_it03 == istrb_it04 ); + + cistreambuf_iter istrb_it05(istrs01); + cistreambuf_iter istrb_it06(istrs01.rdbuf()); + VERIFY( istrb_it05 == istrb_it06 ); + + // bool equal(istreambuf_iter& b) + cistreambuf_iter istrb_it07(0); + cistreambuf_iter istrb_it08; + VERIFY( istrb_it07.equal(istrb_it08) ); + cistreambuf_iter istrb_it09(0); + cistreambuf_iter istrb_it10; + VERIFY( istrb_it10.equal(istrb_it09) ); + + cistreambuf_iter istrb_it11(istrs01); + cistreambuf_iter istrb_it12(istrs01.rdbuf()); + VERIFY( istrb_it11.equal(istrb_it12) ); + cistreambuf_iter istrb_it13(istrs01); + cistreambuf_iter istrb_it14(istrs01.rdbuf()); + VERIFY( istrb_it14.equal(istrb_it13) ); + + cistreambuf_iter istrb_it15(istrs01); + cistreambuf_iter istrb_it16; + VERIFY( !(istrb_it15.equal(istrb_it16)) ); + cistreambuf_iter istrb_it17(istrs01); + cistreambuf_iter istrb_it18; + VERIFY( !(istrb_it18.equal(istrb_it17)) ); + + // bool operator==(const istreambuf_iterator&a, const istreambuf_iterator& b) + // bool operator!=(const istreambuf_iterator&a, const istreambuf_iterator& b) + cistreambuf_iter istrb_it19(0); + cistreambuf_iter istrb_it20; + VERIFY( istrb_it19 == istrb_it20 ); + + cistreambuf_iter istrb_it21(istrs01); + cistreambuf_iter istrb_it22(istrs01.rdbuf()); + VERIFY( istrb_it22 == istrb_it21 ); + + cistreambuf_iter istrb_it23(istrs01); + cistreambuf_iter istrb_it24; + VERIFY( istrb_it23 != istrb_it24 ); + + cistreambuf_iter istrb_it25(0); + cistreambuf_iter istrb_it26(istrs01.rdbuf()); + VERIFY( istrb_it25 != istrb_it26 ); + + // charT operator*() const + // istreambuf_iterator& operator++(); + // istreambuf_iterator& operator++(int); + cistreambuf_iter istrb_it27(istrs01.rdbuf()); + char c; + for (std::size_t i = 0; i < sizeof(slit01) - 2; ++i) + { + c = *istrb_it27++; + VERIFY( c == slit01[i] ); + } + + std::istringstream istrs02(str01); + cistreambuf_iter istrb_it28(istrs02); + for (std::size_t i = 0; i < sizeof(slit01) - 2;) + { + c = *++istrb_it28; + VERIFY( c == slit01[++i] ); + } + return test; +} + +int main() +{ + test02(); + return 0; +} diff --git a/libstdc++-v3/testsuite/24_iterators/istreambuf_iterator/2627.cc b/libstdc++-v3/testsuite/24_iterators/istreambuf_iterator/2627.cc new file mode 100644 index 00000000000..ad6d0393b6c --- /dev/null +++ b/libstdc++-v3/testsuite/24_iterators/istreambuf_iterator/2627.cc @@ -0,0 +1,67 @@ +// 1999-06-28 bkoz + +// Copyright (C) 1999, 2001, 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 24.5.3 template class istreambuf_iterator + +#include <sstream> +#include <iterator> +#include <testsuite_hooks.h> + +// libstdc++/2627 +void test03() +{ + bool test __attribute__((unused)) = true; + const std::string s("free the vieques"); + + // 1 + std::string res_postfix; + std::istringstream iss01(s); + std::istreambuf_iterator<char> isbufit01(iss01); + for (std::size_t j = 0; j < s.size(); ++j, isbufit01++) + res_postfix += *isbufit01; + + // 2 + std::string res_prefix; + std::istringstream iss02(s); + std::istreambuf_iterator<char> isbufit02(iss02); + for (std::size_t j = 0; j < s.size(); ++j, ++isbufit02) + res_prefix += *isbufit02; + + // 3 mixed + std::string res_mixed; + std::istringstream iss03(s); + std::istreambuf_iterator<char> isbufit03(iss03); + for (std::size_t j = 0; j < (s.size() / 2); ++j) + { + res_mixed += *isbufit03; + ++isbufit03; + res_mixed += *isbufit03; + isbufit03++; + } + + VERIFY ( res_postfix == res_prefix ); + VERIFY ( res_mixed == res_prefix ); +} + +int main() +{ + test03(); + return 0; +} diff --git a/libstdc++-v3/testsuite/24_iterators/ostreambuf_iterator/1.cc b/libstdc++-v3/testsuite/24_iterators/ostreambuf_iterator/1.cc new file mode 100644 index 00000000000..d654d600158 --- /dev/null +++ b/libstdc++-v3/testsuite/24_iterators/ostreambuf_iterator/1.cc @@ -0,0 +1,50 @@ +// { dg-do compile } +// 2001-04-30 Benjamin Kosnik <bkoz@redhat.com> + +// Copyright (C) 2001, 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 24.5.4 template class ostreambuf_iterator + +#include <sstream> +#include <iterator> +#include <testsuite_hooks.h> + +void test01() +{ + using namespace std; + + // Check for required base class. + typedef ostreambuf_iterator<char> test_iterator; + typedef iterator<output_iterator_tag, void, void, void, void> base_iterator; + ostringstream osstream("this tag"); + test_iterator r_it(osstream); + base_iterator* base __attribute__((unused)) = &r_it; + + // Check for required typedefs + typedef test_iterator::value_type value_type; + typedef test_iterator::difference_type difference_type; + typedef test_iterator::pointer pointer; + typedef test_iterator::reference reference; + typedef test_iterator::iterator_category iteratory_category; + + typedef test_iterator::char_type char_type; + typedef test_iterator::traits_type traits_type; + typedef test_iterator::ostream_type ostream_type; + typedef test_iterator::streambuf_type streambuf_type; +} diff --git a/libstdc++-v3/testsuite/24_iterators/ostreambuf_iterator/2.cc b/libstdc++-v3/testsuite/24_iterators/ostreambuf_iterator/2.cc new file mode 100644 index 00000000000..f294174e918 --- /dev/null +++ b/libstdc++-v3/testsuite/24_iterators/ostreambuf_iterator/2.cc @@ -0,0 +1,92 @@ +// 2001-04-30 Benjamin Kosnik <bkoz@redhat.com> + +// Copyright (C) 2001, 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 24.5.4 template class ostreambuf_iterator + +#include <sstream> +#include <iterator> +#include <testsuite_hooks.h> + +bool test02(void) +{ + typedef std::ostreambuf_iterator<char> costreambuf_iter; + typedef costreambuf_iter::streambuf_type cstreambuf_type; + bool test __attribute__((unused)) = true; + const char slit01[] = "playa hermosa, liberia, guanacaste"; + const char slit02[] = "bodega bay, lost coast, california"; + std::string str01(slit01); + std::string str02(slit02); + std::string tmp; + std::stringbuf strbuf01; + std::stringbuf strbuf02(str01); + std::ostringstream ostrs00(str01); + std::ostringstream ostrs01(str01); + + // ctor sanity checks + costreambuf_iter ostrb_it01(ostrs00); + VERIFY( !ostrb_it01.failed() ); + ostrb_it01++; + ++ostrb_it01; + VERIFY( !ostrb_it01.failed() ); + ostrb_it01 = 'a'; + VERIFY( !ostrb_it01.failed() ); + *ostrb_it01; + VERIFY( !ostrb_it01.failed() ); + + costreambuf_iter ostrb_it02(NULL); + VERIFY( ostrb_it02.failed() ); + ostrb_it02++; + ++ostrb_it02; + VERIFY( ostrb_it02.failed() ); + *ostrb_it02; + VERIFY( ostrb_it02.failed() ); + ostrb_it02 = 'a'; + VERIFY( ostrb_it02.failed() ); + + // charT operator*() const + // ostreambuf_iterator& operator++(); + // ostreambuf_iterator& operator++(int); + costreambuf_iter ostrb_it27(ostrs01); + VERIFY( !ostrb_it27.failed() ); + int j = str02.size(); + for (int i = 0; i < j; ++i) + ostrb_it27 = str02[i]; + VERIFY( !ostrb_it27.failed() ); + tmp = ostrs01.str(); + VERIFY ( tmp != str01 ); + VERIFY ( tmp == str02 ); + + costreambuf_iter ostrb_it28(ostrs00); + VERIFY( !ostrb_it28.failed() ); + j = ostrs00.str().size(); + for (int i = 0; i < j + 2; ++i) + ostrb_it28 = 'b'; + VERIFY( !ostrb_it28.failed() ); + tmp = ostrs00.str(); + VERIFY ( tmp != str01 ); + VERIFY ( tmp != str02 ); + return test; +} + +int main() +{ + test02(); + return 0; +} diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/12868.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/12868.cc new file mode 100644 index 00000000000..8e4484b1472 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/12868.cc @@ -0,0 +1,60 @@ +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 27.8.1.4 Overridden virtual functions + +#include <ostream> +#include <fstream> +#include <locale> +#include <string> +#include <testsuite_hooks.h> + +// libstdc++/12868 +void test01() +{ + using namespace std; + bool test __attribute__((unused)) = true; + + locale loc_is(__gnu_test::try_named_locale("is_IS")); + + { + wofstream out("tmp_12868"); + out << L"<? xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"; + out.imbue(loc_is); + VERIFY( out.rdbuf()->getloc() == loc_is ); + out << L"<greeting>Hall\u00f3 heimur</greeting>\n"; + } + + { + wifstream in("tmp_12868"); + wstring str; + getline(in, str); + if (str.find(L"encoding=\"UTF-8\"") != wstring::npos) + { + in.imbue(loc_is); + VERIFY( in.rdbuf()->getloc() == loc_is ); + } + getline(in, str); + VERIFY( str == L"<greeting>Hall\u00f3 heimur</greeting>" ); + } +} + +int main() +{ + test01(); +} diff --git a/libstdc++-v3/testsuite/performance/wchar_t_in.cc b/libstdc++-v3/testsuite/performance/wchar_t_in.cc new file mode 100644 index 00000000000..43e09e39a78 --- /dev/null +++ b/libstdc++-v3/testsuite/performance/wchar_t_in.cc @@ -0,0 +1,84 @@ +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// 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 <cstdio> +#include <cstring> +#include <fstream> +#include <langinfo.h> +#include <iconv.h> +#include <testsuite_performance.h> + +// libstdc++/11602 (do_in) +int main(int argc, char** argv) +{ + using namespace std; + using namespace __gnu_test; + + time_counter time; + resource_counter resource; + const int iters = 400000; + + wchar_t wbuf[1024]; + char cbuf[1024]; + + memset(cbuf, 'a', 1024); + + // C (iconv) + iconv_t cd = iconv_open("WCHAR_T", nl_langinfo(CODESET)); + start_counters(time, resource); + for (int i = 0; i < iters; ++i) + { + size_t inbytesleft = 1024; + size_t outbytesleft = 1024 * sizeof(wchar_t); + char* in = cbuf; + char* out = reinterpret_cast<char*>(wbuf); + iconv(cd, &in, &inbytesleft, &out, &outbytesleft); + } + stop_counters(time, resource); + iconv_close(cd); + report_performance(__FILE__, "C (iconv)", time, resource); + clear_counters(time, resource); + + // C++ (codecvt) + locale loc; + const codecvt<wchar_t, char, mbstate_t>& cvt = + use_facet<codecvt<wchar_t, char, mbstate_t> >(loc); + mbstate_t state; + memset(&state, 0, sizeof(state)); + start_counters(time, resource); + for (int i = 0; i < iters; ++i) + { + const char* from_next; + wchar_t* to_next; + cvt.in(state, cbuf, cbuf + 1024, from_next, + wbuf, wbuf + 1024, to_next); + } + stop_counters(time, resource); + report_performance(__FILE__, "C++ (codecvt)", time, resource); + + return 0; +} diff --git a/libstdc++-v3/testsuite/performance/wchar_t_out.cc b/libstdc++-v3/testsuite/performance/wchar_t_out.cc new file mode 100644 index 00000000000..4e5106817d0 --- /dev/null +++ b/libstdc++-v3/testsuite/performance/wchar_t_out.cc @@ -0,0 +1,84 @@ +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// 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 <cstdio> +#include <cstring> +#include <fstream> +#include <langinfo.h> +#include <iconv.h> +#include <testsuite_performance.h> + +// libstdc++/11602 +int main(int argc, char** argv) +{ + using namespace std; + using namespace __gnu_test; + + time_counter time; + resource_counter resource; + const int iters = 300000; + + wchar_t wbuf[1024]; + char cbuf[1024]; + + wmemset(wbuf, L'a', 1024); + + // C (iconv) + iconv_t cd = iconv_open(nl_langinfo(CODESET), "WCHAR_T"); + start_counters(time, resource); + for (int i = 0; i < iters; ++i) + { + size_t inbytesleft = 1024 * sizeof(wchar_t); + size_t outbytesleft = 1024; + char* in = reinterpret_cast<char*>(wbuf); + char* out = cbuf; + iconv(cd, &in, &inbytesleft, &out, &outbytesleft); + } + stop_counters(time, resource); + iconv_close(cd); + report_performance(__FILE__, "C (iconv)", time, resource); + clear_counters(time, resource); + + // C++ (codecvt) + locale loc; + const codecvt<wchar_t, char, mbstate_t>& cvt = + use_facet<codecvt<wchar_t, char, mbstate_t> >(loc); + mbstate_t state; + memset(&state, 0, sizeof(state)); + start_counters(time, resource); + for (int i = 0; i < iters; ++i) + { + const wchar_t* from_next; + char* to_next; + cvt.out(state, wbuf, wbuf + 1024, from_next, + cbuf, cbuf + 1024, to_next); + } + stop_counters(time, resource); + report_performance(__FILE__, "C++ (codecvt)", time, resource); + + return 0; +} |