OSDN Git Service

PR fortran/31546
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / src / debug.cc
index a86367a..0391368 100644 (file)
@@ -1,6 +1,6 @@
 // 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
 #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;)",
@@ -118,68 +108,67 @@ namespace __gnu_debug
     "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);
@@ -193,17 +182,29 @@ namespace __gnu_debug
     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;
@@ -224,11 +225,18 @@ namespace __gnu_debug
       }
   }
 
-  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
@@ -248,7 +256,7 @@ namespace __gnu_debug
     _M_prior = 0;
     _M_next = 0;
   }
-  
+
   bool
   _Safe_iterator_base::
   _M_singular() const
@@ -258,10 +266,15 @@ namespace __gnu_debug
   _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
@@ -484,7 +497,8 @@ namespace __gnu_debug
        _M_column += strlen(__buf);
       }
     
-    _M_wordwrap = true;
+    if (_M_max_length)
+      _M_wordwrap = true;
     _M_print_word("error: ");
     
     // Print the error message
@@ -576,7 +590,7 @@ namespace __gnu_debug
   _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];
 
@@ -584,21 +598,21 @@ namespace __gnu_debug
       {
        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 == ' ') 
@@ -659,6 +673,19 @@ namespace __gnu_debug
       }
   }
 
+  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