// Debugging mode support code -*- C++ -*-
-// Copyright (C) 2003, 2004, 2005
+// Copyright (C) 2003, 2004, 2005, 2006, 2007
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// 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,
+// 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
#include <debug/safe_sequence.h>
#include <debug/safe_iterator.h>
#include <algorithm>
-#include <cstdlib>
#include <cassert>
#include <cstring>
-#include <cstdio>
#include <cctype>
-#include <bits/concurrence.h>
+#include <cstdio>
+#include <cstdlib>
using namespace std;
-namespace __gnu_internal
+namespace
{
- __glibcxx_mutex_define_initialized(iterator_base_mutex);
-} // namespace __gnu_internal
+ __gnu_cxx::__mutex safe_base_mutex;
+} // anonymous namespace
namespace __gnu_debug
{
- void
- __fancy_abort(const char* __file, int __line, const char* __function,
- const char* __condition)
- {
- printf("%s:%d: %s: Assertion '%s' failed.\n", __file, __line,
- __function, __condition);
- abort();
- }
-
const char* _S_debug_messages[] =
{
"function requires a valid iterator range [%1.name;, %2.name;)",
"attempt to increment an end-of-stream istreambuf_iterator"
};
- void
+ void
_Safe_sequence_base::
_M_detach_all()
{
- for (_Safe_iterator_base* __iter = _M_iterators; __iter; )
+ __gnu_cxx::__scoped_lock sentry(safe_base_mutex);
+ for (_Safe_iterator_base* __iter = _M_iterators; __iter;)
{
_Safe_iterator_base* __old = __iter;
__iter = __iter->_M_next;
- __old->_M_attach(0, false);
+ __old->_M_detach_single();
}
- for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2; )
+ for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2;)
{
_Safe_iterator_base* __old = __iter2;
__iter2 = __iter2->_M_next;
- __old->_M_attach(0, true);
+ __old->_M_detach_single();
}
}
- void
+ void
_Safe_sequence_base::
_M_detach_singular()
{
- for (_Safe_iterator_base* __iter = _M_iterators; __iter; )
+ __gnu_cxx::__scoped_lock sentry(safe_base_mutex);
+ 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);
+ __old->_M_detach_single();
}
- for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2; )
+ for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2;)
{
_Safe_iterator_base* __old = __iter2;
__iter2 = __iter2->_M_next;
if (__old->_M_singular())
- __old->_M_attach(0, true);
+ __old->_M_detach_single();
}
}
-
- void
+
+ 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;
- }
+ __gnu_cxx::__scoped_lock sentry(safe_base_mutex);
+ for (_Safe_iterator_base* __iter = _M_iterators; __iter;
+ __iter = __iter->_M_next)
+ __iter->_M_version = _M_version;
+
+ for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2;
+ __iter2 = __iter2->_M_next)
+ __iter2->_M_version = _M_version;
}
- void
+ void
_Safe_sequence_base::
_M_swap(_Safe_sequence_base& __x)
{
+ __gnu_cxx::__scoped_lock sentry(safe_base_mutex);
swap(_M_iterators, __x._M_iterators);
swap(_M_const_iterators, __x._M_const_iterators);
swap(_M_version, __x._M_version);
for (__iter = __x._M_const_iterators; __iter; __iter = __iter->_M_next)
__iter->_M_sequence = &__x;
}
-
- void
+
+ __gnu_cxx::__mutex&
+ _Safe_sequence_base::
+ _M_get_mutex()
+ { return safe_base_mutex; }
+
+ void
_Safe_iterator_base::
_M_attach(_Safe_sequence_base* __seq, bool __constant)
{
- _M_detach();
+ __gnu_cxx::__scoped_lock sentry(safe_base_mutex);
+ _M_attach_single(__seq, __constant);
+ }
+
+ void
+ _Safe_iterator_base::
+ _M_attach_single(_Safe_sequence_base* __seq, bool __constant)
+ {
+ _M_detach_single();
// Attach to the new sequence (if there is one)
if (__seq)
{
- __gnu_cxx::lock sentry(__gnu_internal::iterator_base_mutex);
_M_sequence = __seq;
_M_version = _M_sequence->_M_version;
_M_prior = 0;
}
}
- void
+ void
_Safe_iterator_base::
_M_detach()
{
- __gnu_cxx::lock sentry(__gnu_internal::iterator_base_mutex);
+ __gnu_cxx::__scoped_lock sentry(safe_base_mutex);
+ _M_detach_single();
+ }
+
+ void
+ _Safe_iterator_base::
+ _M_detach_single()
+ {
if (_M_sequence)
{
// Remove us from this sequence's list
_M_prior = 0;
_M_next = 0;
}
-
+
bool
_Safe_iterator_base::
_M_singular() const
_Safe_iterator_base::
_M_can_compare(const _Safe_iterator_base& __x) const
{
- return (!_M_singular() && !__x._M_singular()
- && _M_sequence == __x._M_sequence);
+ return (!_M_singular()
+ && !__x._M_singular() && _M_sequence == __x._M_sequence);
}
+ __gnu_cxx::__mutex&
+ _Safe_iterator_base::
+ _M_get_mutex()
+ { return safe_base_mutex; }
+
void
_Error_formatter::_Parameter::
_M_print_field(const _Error_formatter* __formatter, const char* __name) const
_M_column += strlen(__buf);
}
- _M_wordwrap = true;
+ if (_M_max_length)
+ _M_wordwrap = true;
_M_print_word("error: ");
// Print the error message
_M_print_string(const char* __string) const
{
const char* __start = __string;
- const char* __end = __start;
+ const char* __finish = __start;
const int __bufsize = 128;
char __buf[__bufsize];
{
if (*__start != '%')
{
- // [__start, __end) denotes the next word
- __end = __start;
- while (isalnum(*__end))
- ++__end;
- if (__start == __end)
- ++__end;
- if (isspace(*__end))
- ++__end;
+ // [__start, __finish) denotes the next word
+ __finish = __start;
+ while (isalnum(*__finish))
+ ++__finish;
+ if (__start == __finish)
+ ++__finish;
+ if (isspace(*__finish))
+ ++__finish;
- const ptrdiff_t __len = __end - __start;
+ const ptrdiff_t __len = __finish - __start;
assert(__len < __bufsize);
memcpy(__buf, __start, __len);
__buf[__len] = '\0';
_M_print_word(__buf);
- __start = __end;
+ __start = __finish;
// Skip extra whitespace
while (*__start == ' ')
}
}
+ void
+ _Error_formatter::_M_get_max_length() const
+ {
+ const char* __nptr = std::getenv("GLIBCXX_DEBUG_MESSAGE_LENGTH");
+ if (__nptr)
+ {
+ char* __endptr;
+ const unsigned long __ret = std::strtoul(__nptr, &__endptr, 0);
+ if (*__nptr != '\0' && *__endptr == '\0')
+ _M_max_length = __ret;
+ }
+ }
+
// Instantiations.
template
void