OSDN Git Service

PR fortran/31546
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / src / debug.cc
index a00a250..0391368 100644 (file)
@@ -1,6 +1,6 @@
 // Debugging mode support code -*- C++ -*-
 
-// Copyright (C) 2003
+// 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
@@ -16,7 +16,7 @@
 
 // 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 <cstdio>
+#include <cstdlib>
 
 using namespace std;
 
+namespace
+{
+  __gnu_cxx::__mutex safe_base_mutex;
+} // anonymous namespace
+
 namespace __gnu_debug
 {
   const char* _S_debug_messages[] = 
@@ -103,87 +108,99 @@ 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);
+       _Safe_iterator_base* __old = __iter;
+       __iter = __iter->_M_next;
+       __old->_M_detach_single();
       }
     
-    for (_Safe_iterator_base* iter = _M_const_iterators; iter; )
+    for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2;)
       {
-       _Safe_iterator_base* old = iter;
-       iter = iter->_M_next;
-       old->_M_attach(0, true);
+       _Safe_iterator_base* __old = __iter2;
+       __iter2 = __iter2->_M_next;
+       __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);
+       _Safe_iterator_base* __old = __iter;
+       __iter = __iter->_M_next;
+       if (__old->_M_singular())
+         __old->_M_detach_single();
       }
 
-    for (_Safe_iterator_base* iter = _M_const_iterators; iter; )
+    for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2;)
       {
-       _Safe_iterator_base* old = iter;
-       iter = iter->_M_next;
-       if (old->_M_singular())
-         old->_M_attach(0, true);
+       _Safe_iterator_base* __old = __iter2;
+       __iter2 = __iter2->_M_next;
+       if (__old->_M_singular())
+         __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);
-    _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;
+    _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 
+
+  __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)
@@ -208,10 +225,18 @@ namespace __gnu_debug
       }
   }
 
-  void 
+  void
   _Safe_iterator_base::
   _M_detach()
   {
+    __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
@@ -231,7 +256,7 @@ namespace __gnu_debug
     _M_prior = 0;
     _M_next = 0;
   }
-  
+
   bool
   _Safe_iterator_base::
   _M_singular() const
@@ -241,17 +266,22 @@ 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
   {
     assert(this->_M_kind != _Parameter::__unused_param);
-    const int bufsize = 64;
-    char buf[bufsize];
+    const int __bufsize = 64;
+    char __buf[__bufsize];
     
     if (_M_kind == __iterator)
       {
@@ -262,9 +292,9 @@ namespace __gnu_debug
          }
        else if (strcmp(__name, "address") == 0)
          {
-           __formatter->_M_format_word(buf, bufsize, "%p", 
+           __formatter->_M_format_word(__buf, __bufsize, "%p", 
                                        _M_variant._M_iterator._M_address);
-           __formatter->_M_print_word(buf);
+           __formatter->_M_print_word(__buf);
          }
        else if (strcmp(__name, "type") == 0)
          {
@@ -297,9 +327,9 @@ namespace __gnu_debug
        else if (strcmp(__name, "sequence") == 0)
          {
            assert(_M_variant._M_iterator._M_sequence);
-           __formatter->_M_format_word(buf, bufsize, "%p", 
+           __formatter->_M_format_word(__buf, __bufsize, "%p", 
                                        _M_variant._M_iterator._M_sequence);
-           __formatter->_M_print_word(buf);
+           __formatter->_M_print_word(__buf);
          }
        else if (strcmp(__name, "seq_type") == 0)
          {
@@ -320,9 +350,9 @@ namespace __gnu_debug
        else if (strcmp(__name, "address") == 0)
          {
            assert(_M_variant._M_sequence._M_address);
-           __formatter->_M_format_word(buf, bufsize, "%p", 
+           __formatter->_M_format_word(__buf, __bufsize, "%p", 
                                        _M_variant._M_sequence._M_address);
-           __formatter->_M_print_word(buf);
+           __formatter->_M_print_word(__buf);
          }
        else if (strcmp(__name, "type") == 0)
          {
@@ -363,22 +393,22 @@ namespace __gnu_debug
   _Error_formatter::_Parameter::
   _M_print_description(const _Error_formatter* __formatter) const
   {
-    const int bufsize = 128;
-    char buf[bufsize];
+    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\" ", 
+           __formatter->_M_format_word(__buf, __bufsize, "\"%s\" ", 
                                        _M_variant._M_iterator._M_name);
-           __formatter->_M_print_word(buf);
+           __formatter->_M_print_word(__buf);
          }
        
-       __formatter->_M_format_word(buf, bufsize, "@ 0x%p {\n", 
+       __formatter->_M_format_word(__buf, __bufsize, "@ 0x%p {\n", 
                                    _M_variant._M_iterator._M_address);
-       __formatter->_M_print_word(buf);
+       __formatter->_M_print_word(__buf);
        if (_M_variant._M_iterator._M_type)
          {
            __formatter->_M_print_word("type = ");
@@ -410,9 +440,9 @@ namespace __gnu_debug
                __formatter->_M_print_word("' ");
              }
            
-           __formatter->_M_format_word(buf, bufsize, "@ 0x%p\n", 
+           __formatter->_M_format_word(__buf, __bufsize, "@ 0x%p\n", 
                                        _M_variant._M_sequence._M_address);
-           __formatter->_M_print_word(buf);
+           __formatter->_M_print_word(__buf);
          }
        __formatter->_M_print_word("}\n");
       }
@@ -421,14 +451,14 @@ namespace __gnu_debug
        __formatter->_M_print_word("sequence ");
        if (_M_variant._M_sequence._M_name)
          {
-           __formatter->_M_format_word(buf, bufsize, "\"%s\" ", 
+           __formatter->_M_format_word(__buf, __bufsize, "\"%s\" ", 
                                        _M_variant._M_sequence._M_name);
-           __formatter->_M_print_word(buf);
+           __formatter->_M_print_word(__buf);
          }
        
-       __formatter->_M_format_word(buf, bufsize, "@ 0x%p {\n", 
+       __formatter->_M_format_word(__buf, __bufsize, "@ 0x%p {\n", 
                                    _M_variant._M_sequence._M_address);
-       __formatter->_M_print_word(buf);
+       __formatter->_M_print_word(__buf);
        
        if (_M_variant._M_sequence._M_type)
          {
@@ -447,27 +477,28 @@ namespace __gnu_debug
   void
   _Error_formatter::_M_error() const
   {
-    const int bufsize = 128;
-    char buf[bufsize];
+    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);
+       _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_format_word(__buf, __bufsize, "%u:", _M_line);
+       _M_print_word(__buf);
+       _M_column += strlen(__buf);
       }
     
-    _M_wordwrap = true;
+    if (_M_max_length)
+      _M_wordwrap = true;
     _M_print_word("error: ");
     
     // Print the error message
@@ -477,30 +508,30 @@ namespace __gnu_debug
     
     // 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)
+    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 (_M_parameters[__i]._M_kind == _Parameter::__iterator
+           || _M_parameters[__i]._M_kind == _Parameter::__sequence)
          {
-           if (!has_noninteger_parameters)
+           if (!__has_noninteger_parameters)
              {
                _M_first_line = true;
                _M_print_word("\nObjects involved in the operation:\n");
-               has_noninteger_parameters = true;
+               __has_noninteger_parameters = true;
              }
-           _M_parameters[i]._M_print_description(this);
+           _M_parameters[__i]._M_print_description(this);
          }
       }
     
     abort();
   }
 
-  template<typename _T>
+  template<typename _Tp>
     void
     _Error_formatter::_M_format_word(char* __buf, 
-                                    int __n __attribute__((__unused__)), 
-                                    const char* __fmt, _T __s) const
+                                    int __n __attribute__ ((__unused__)), 
+                                    const char* __fmt, _Tp __s) const
     {
 #ifdef _GLIBCXX_USE_C99
       std::snprintf(__buf, __n, __fmt, __s);
@@ -529,11 +560,11 @@ namespace __gnu_debug
        // If this isn't the first line, indent
        if (_M_column == 1 && !_M_first_line)
          {
-           char spacing[_M_indent + 1];
+           char __spacing[_M_indent + 1];
            for (int i = 0; i < _M_indent; ++i)
-             spacing[i] = ' ';
-           spacing[_M_indent] = '\0';
-           fprintf(stderr, "%s", spacing);
+             __spacing[i] = ' ';
+           __spacing[_M_indent] = '\0';
+           fprintf(stderr, "%s", __spacing);
            _M_column += _M_indent;
          }
        
@@ -559,24 +590,29 @@ namespace __gnu_debug
   _M_print_string(const char* __string) const
   {
     const char* __start = __string;
-    const char* __end = __start;
-    const int bufsize = 128;
-    char buf[bufsize];
+    const char* __finish = __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;
+           // [__start, __finish) denotes the next word
+           __finish = __start;
+           while (isalnum(*__finish))
+             ++__finish;
+           if (__start == __finish)
+             ++__finish;
+           if (isspace(*__finish))
+             ++__finish;
            
-           assert(__end - __start + 1< bufsize);
-           _M_format_word(buf, __end - __start + 1, "%s", __start);
-           _M_print_word(buf);
-           __start = __end;
+           const ptrdiff_t __len = __finish - __start;
+           assert(__len < __bufsize);
+           memcpy(__buf, __start, __len);
+           __buf[__len] = '\0';
+           _M_print_word(__buf);
+           __start = __finish;
            
            // Skip extra whitespace
            while (*__start == ' ') 
@@ -585,76 +621,88 @@ namespace __gnu_debug
            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);
+       ++__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 == ';');
+       // '.' separates the parameter number from the field
+       // name, if there is one.
        ++__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;
+       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);             
       }
-      
-      // Extract the field name we want
-      enum { max_field_len = 16 };
-      char field[max_field_len];
-      int field_idx = 0;
-      ++__start;
-      while (*__start != ';')
+  }
+
+  void
+  _Error_formatter::_M_get_max_length() const
+  {
+    const char* __nptr = std::getenv("GLIBCXX_DEBUG_MESSAGE_LENGTH");
+    if (__nptr)
       {
-       assert(*__start);
-       assert(field_idx < max_field_len-1);
-       field[field_idx++] = *__start++;
+       char* __endptr;
+       const unsigned long __ret = std::strtoul(__nptr, &__endptr, 0);
+       if (*__nptr != '\0' && *__endptr == '\0')
+         _M_max_length = __ret;
       }
-      ++__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;
+    _Error_formatter::_M_format_word(char*, int, const char*
+                                    const void*) const;
 
   template
     void
-    _Error_formatter::_M_format_word(char* __buf, int __n, const char* __fmt, 
-                                    long __s) const;
+    _Error_formatter::_M_format_word(char*, int, const char*, long) const;
 
   template
     void
-    _Error_formatter::_M_format_word(char* __buf, int __n, const char* __fmt
-                                    unsigned int __s) const;
+    _Error_formatter::_M_format_word(char*, int, const char*
+                                    std::size_t) const;
 
   template
     void
-    _Error_formatter::_M_format_word(char* __buf, int __n, const char* __fmt
-                                    const char* __s) const;
+    _Error_formatter::_M_format_word(char*, int, const char*
+                                    const char*) const;
 } // namespace __gnu_debug