2015-08-24 François Dumont <fdumont@gcc.gnu.org>
[official-gcc.git] / libstdc++-v3 / src / c++11 / debug.cc
blob997c0f33de06ef8a3080124f2d263c84542610c2
1 // Debugging mode support code -*- C++ -*-
3 // Copyright (C) 2003-2015 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
25 #include <debug/debug.h>
26 #include <debug/safe_base.h>
27 #include <debug/safe_unordered_base.h>
28 #include <debug/safe_iterator.h>
29 #include <debug/safe_local_iterator.h>
30 #include <algorithm>
31 #include <cassert>
32 #include <cstring>
33 #include <cctype>
34 #include <cstdio>
35 #include <cstdlib>
36 #include <functional>
38 #include <cxxabi.h> // for __cxa_demangle
40 using namespace std;
42 namespace
44 /** Returns different instances of __mutex depending on the passed address
45 * in order to limit contention without breaking current library binary
46 * compatibility. */
47 __gnu_cxx::__mutex&
48 get_safe_base_mutex(void* __address)
50 const size_t mask = 0xf;
51 static __gnu_cxx::__mutex safe_base_mutex[mask + 1];
52 const size_t index = _Hash_impl::hash(__address) & mask;
53 return safe_base_mutex[index];
56 void
57 swap_its(__gnu_debug::_Safe_sequence_base& __lhs,
58 __gnu_debug::_Safe_iterator_base*& __lhs_its,
59 __gnu_debug::_Safe_sequence_base& __rhs,
60 __gnu_debug::_Safe_iterator_base*& __rhs_its)
62 swap(__lhs_its, __rhs_its);
63 __gnu_debug::_Safe_iterator_base* __iter;
64 for (__iter = __rhs_its; __iter; __iter = __iter->_M_next)
65 __iter->_M_sequence = &__rhs;
66 for (__iter = __lhs_its; __iter; __iter = __iter->_M_next)
67 __iter->_M_sequence = &__lhs;
70 void
71 swap_seq(__gnu_debug::_Safe_sequence_base& __lhs,
72 __gnu_debug::_Safe_sequence_base& __rhs)
74 swap(__lhs._M_version, __rhs._M_version);
75 swap_its(__lhs, __lhs._M_iterators,
76 __rhs, __rhs._M_iterators);
77 swap_its(__lhs, __lhs._M_const_iterators,
78 __rhs, __rhs._M_const_iterators);
81 void
82 swap_ucont(__gnu_debug::_Safe_unordered_container_base& __lhs,
83 __gnu_debug::_Safe_unordered_container_base& __rhs)
85 swap_seq(__lhs, __rhs);
86 swap_its(__lhs, __lhs._M_local_iterators,
87 __rhs, __rhs._M_local_iterators);
88 swap_its(__lhs, __lhs._M_const_local_iterators,
89 __rhs, __rhs._M_const_local_iterators);
92 void
93 detach_all(__gnu_debug::_Safe_iterator_base* __iter)
95 for (; __iter;)
97 __gnu_debug::_Safe_iterator_base* __old = __iter;
98 __iter = __iter->_M_next;
99 __old->_M_reset();
102 } // anonymous namespace
104 namespace __gnu_debug
106 const char* _S_debug_messages[] =
108 // General Checks
109 "function requires a valid iterator range [%1.name;, %2.name;)",
110 "attempt to insert into container with a singular iterator",
111 "attempt to insert into container with an iterator"
112 " from a different container",
113 "attempt to erase from container with a %2.state; iterator",
114 "attempt to erase from container with an iterator"
115 " from a different container",
116 "attempt to subscript container with out-of-bounds index %2;,"
117 " but container only holds %3; elements",
118 "attempt to access an element in an empty container",
119 "elements in iterator range [%1.name;, %2.name;)"
120 " are not partitioned by the value %3;",
121 "elements in iterator range [%1.name;, %2.name;)"
122 " are not partitioned by the predicate %3; and value %4;",
123 "elements in iterator range [%1.name;, %2.name;) are not sorted",
124 "elements in iterator range [%1.name;, %2.name;)"
125 " are not sorted according to the predicate %3;",
126 "elements in iterator range [%1.name;, %2.name;) do not form a heap",
127 "elements in iterator range [%1.name;, %2.name;)"
128 " do not form a heap with respect to the predicate %3;",
129 // std::bitset checks
130 "attempt to write through a singular bitset reference",
131 "attempt to read from a singular bitset reference",
132 "attempt to flip a singular bitset reference",
133 // std::list checks
134 "attempt to splice a list into itself",
135 "attempt to splice lists with unequal allocators",
136 "attempt to splice elements referenced by a %1.state; iterator",
137 "attempt to splice an iterator from a different container",
138 "splice destination %1.name;"
139 " occurs within source range [%2.name;, %3.name;)",
140 // iterator checks
141 "attempt to initialize an iterator that will immediately become singular",
142 "attempt to copy-construct an iterator from a singular iterator",
143 "attempt to construct a constant iterator"
144 " from a singular mutable iterator",
145 "attempt to copy from a singular iterator",
146 "attempt to dereference a %1.state; iterator",
147 "attempt to increment a %1.state; iterator",
148 "attempt to decrement a %1.state; iterator",
149 "attempt to subscript a %1.state; iterator %2; step from"
150 " its current position, which falls outside its dereferenceable range",
151 "attempt to advance a %1.state; iterator %2; steps,"
152 " which falls outside its valid range",
153 "attempt to retreat a %1.state; iterator %2; steps,"
154 " which falls outside its valid range",
155 "attempt to compare a %1.state; iterator to a %2.state; iterator",
156 "attempt to compare iterators from different sequences",
157 "attempt to order a %1.state; iterator to a %2.state; iterator",
158 "attempt to order iterators from different sequences",
159 "attempt to compute the difference between a %1.state;"
160 " iterator to a %2.state; iterator",
161 "attempt to compute the different between two iterators"
162 " from different sequences",
163 // istream_iterator
164 "attempt to dereference an end-of-stream istream_iterator",
165 "attempt to increment an end-of-stream istream_iterator",
166 // ostream_iterator
167 "attempt to output via an ostream_iterator with no associated stream",
168 // istreambuf_iterator
169 "attempt to dereference an end-of-stream istreambuf_iterator"
170 " (this is a GNU extension)",
171 "attempt to increment an end-of-stream istreambuf_iterator",
172 // std::forward_list
173 "attempt to insert into container after an end iterator",
174 "attempt to erase from container after a %2.state; iterator not followed"
175 " by a dereferenceable one",
176 "function requires a valid iterator range (%2.name;, %3.name;)"
177 ", \"%2.name;\" shall be before and not equal to \"%3.name;\"",
178 // std::unordered_container::local_iterator
179 "attempt to compare local iterators from different unordered container"
180 " buckets",
181 "function requires a non-empty iterator range [%1.name;, %2.name;)",
182 "attempt to self move assign",
183 "attempt to access container with out-of-bounds bucket index %2;,"
184 " container only holds %3; buckets",
185 "load factor shall be positive",
186 "allocators must be equal",
187 "attempt to insert with an iterator range [%1.name;, %2.name;) from this"
188 " container",
189 "comparison doesn't meet irreflexive requirements, assert(!(a < a))"
192 void
193 _Safe_sequence_base::
194 _M_detach_all()
196 __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
197 detach_all(_M_iterators);
198 _M_iterators = 0;
200 detach_all(_M_const_iterators);
201 _M_const_iterators = 0;
204 void
205 _Safe_sequence_base::
206 _M_detach_singular()
208 __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
209 for (_Safe_iterator_base* __iter = _M_iterators; __iter;)
211 _Safe_iterator_base* __old = __iter;
212 __iter = __iter->_M_next;
213 if (__old->_M_singular())
214 __old->_M_detach_single();
217 for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2;)
219 _Safe_iterator_base* __old = __iter2;
220 __iter2 = __iter2->_M_next;
221 if (__old->_M_singular())
222 __old->_M_detach_single();
226 void
227 _Safe_sequence_base::
228 _M_revalidate_singular()
230 __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
231 for (_Safe_iterator_base* __iter = _M_iterators; __iter;
232 __iter = __iter->_M_next)
233 __iter->_M_version = _M_version;
235 for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2;
236 __iter2 = __iter2->_M_next)
237 __iter2->_M_version = _M_version;
240 void
241 _Safe_sequence_base::
242 _M_swap(_Safe_sequence_base& __x) noexcept
244 // We need to lock both sequences to swap
245 using namespace __gnu_cxx;
246 __mutex *__this_mutex = &_M_get_mutex();
247 __mutex *__x_mutex = &__x._M_get_mutex();
248 if (__this_mutex == __x_mutex)
250 __scoped_lock __lock(*__this_mutex);
251 swap_seq(*this, __x);
253 else
255 __scoped_lock __l1(__this_mutex < __x_mutex
256 ? *__this_mutex : *__x_mutex);
257 __scoped_lock __l2(__this_mutex < __x_mutex
258 ? *__x_mutex : *__this_mutex);
259 swap_seq(*this, __x);
263 __gnu_cxx::__mutex&
264 _Safe_sequence_base::
265 _M_get_mutex() throw ()
266 { return get_safe_base_mutex(this); }
268 void
269 _Safe_sequence_base::
270 _M_attach(_Safe_iterator_base* __it, bool __constant)
272 __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
273 _M_attach_single(__it, __constant);
276 void
277 _Safe_sequence_base::
278 _M_attach_single(_Safe_iterator_base* __it, bool __constant) throw ()
280 _Safe_iterator_base*& __its =
281 __constant ? _M_const_iterators : _M_iterators;
282 __it->_M_next = __its;
283 if (__it->_M_next)
284 __it->_M_next->_M_prior = __it;
285 __its = __it;
288 void
289 _Safe_sequence_base::
290 _M_detach(_Safe_iterator_base* __it)
292 // Remove __it from this sequence's list
293 __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
294 _M_detach_single(__it);
297 void
298 _Safe_sequence_base::
299 _M_detach_single(_Safe_iterator_base* __it) throw ()
301 // Remove __it from this sequence's list
302 __it->_M_unlink();
303 if (_M_const_iterators == __it)
304 _M_const_iterators = __it->_M_next;
305 if (_M_iterators == __it)
306 _M_iterators = __it->_M_next;
309 void
310 _Safe_iterator_base::
311 _M_attach(_Safe_sequence_base* __seq, bool __constant)
313 _M_detach();
315 // Attach to the new sequence (if there is one)
316 if (__seq)
318 _M_sequence = __seq;
319 _M_version = _M_sequence->_M_version;
320 _M_sequence->_M_attach(this, __constant);
324 void
325 _Safe_iterator_base::
326 _M_attach_single(_Safe_sequence_base* __seq, bool __constant) throw ()
328 _M_detach_single();
330 // Attach to the new sequence (if there is one)
331 if (__seq)
333 _M_sequence = __seq;
334 _M_version = _M_sequence->_M_version;
335 _M_sequence->_M_attach_single(this, __constant);
339 void
340 _Safe_iterator_base::
341 _M_detach()
343 if (_M_sequence)
344 _M_sequence->_M_detach(this);
346 _M_reset();
349 void
350 _Safe_iterator_base::
351 _M_detach_single() throw ()
353 if (_M_sequence)
354 _M_sequence->_M_detach_single(this);
356 _M_reset();
359 void
360 _Safe_iterator_base::
361 _M_reset() throw ()
363 _M_sequence = 0;
364 _M_version = 0;
365 _M_prior = 0;
366 _M_next = 0;
369 bool
370 _Safe_iterator_base::
371 _M_singular() const throw ()
372 { return !_M_sequence || _M_version != _M_sequence->_M_version; }
374 bool
375 _Safe_iterator_base::
376 _M_can_compare(const _Safe_iterator_base& __x) const throw ()
378 return (!_M_singular()
379 && !__x._M_singular() && _M_sequence == __x._M_sequence);
382 __gnu_cxx::__mutex&
383 _Safe_iterator_base::
384 _M_get_mutex() throw ()
385 { return get_safe_base_mutex(_M_sequence); }
387 _Safe_unordered_container_base*
388 _Safe_local_iterator_base::
389 _M_get_container() const noexcept
390 { return static_cast<_Safe_unordered_container_base*>(_M_sequence); }
392 void
393 _Safe_local_iterator_base::
394 _M_attach(_Safe_sequence_base* __cont, bool __constant)
396 _M_detach();
398 // Attach to the new container (if there is one)
399 if (__cont)
401 _M_sequence = __cont;
402 _M_version = _M_sequence->_M_version;
403 _M_get_container()->_M_attach_local(this, __constant);
407 void
408 _Safe_local_iterator_base::
409 _M_attach_single(_Safe_sequence_base* __cont, bool __constant) throw ()
411 _M_detach_single();
413 // Attach to the new container (if there is one)
414 if (__cont)
416 _M_sequence = __cont;
417 _M_version = _M_sequence->_M_version;
418 _M_get_container()->_M_attach_local_single(this, __constant);
422 void
423 _Safe_local_iterator_base::
424 _M_detach()
426 if (_M_sequence)
427 _M_get_container()->_M_detach_local(this);
429 _M_reset();
432 void
433 _Safe_local_iterator_base::
434 _M_detach_single() throw ()
436 if (_M_sequence)
437 _M_get_container()->_M_detach_local_single(this);
439 _M_reset();
442 void
443 _Safe_unordered_container_base::
444 _M_detach_all()
446 __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
447 detach_all(_M_iterators);
448 _M_iterators = 0;
450 detach_all(_M_const_iterators);
451 _M_const_iterators = 0;
453 detach_all(_M_local_iterators);
454 _M_local_iterators = 0;
456 detach_all(_M_const_local_iterators);
457 _M_const_local_iterators = 0;
460 void
461 _Safe_unordered_container_base::
462 _M_swap(_Safe_unordered_container_base& __x) noexcept
464 // We need to lock both containers to swap
465 using namespace __gnu_cxx;
466 __mutex *__this_mutex = &_M_get_mutex();
467 __mutex *__x_mutex = &__x._M_get_mutex();
468 if (__this_mutex == __x_mutex)
470 __scoped_lock __lock(*__this_mutex);
471 swap_ucont(*this, __x);
473 else
475 __scoped_lock __l1(__this_mutex < __x_mutex
476 ? *__this_mutex : *__x_mutex);
477 __scoped_lock __l2(__this_mutex < __x_mutex
478 ? *__x_mutex : *__this_mutex);
479 swap_ucont(*this, __x);
483 void
484 _Safe_unordered_container_base::
485 _M_attach_local(_Safe_iterator_base* __it, bool __constant)
487 __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
488 _M_attach_local_single(__it, __constant);
491 void
492 _Safe_unordered_container_base::
493 _M_attach_local_single(_Safe_iterator_base* __it, bool __constant) throw ()
495 _Safe_iterator_base*& __its =
496 __constant ? _M_const_local_iterators : _M_local_iterators;
497 __it->_M_next = __its;
498 if (__it->_M_next)
499 __it->_M_next->_M_prior = __it;
500 __its = __it;
503 void
504 _Safe_unordered_container_base::
505 _M_detach_local(_Safe_iterator_base* __it)
507 // Remove __it from this container's list
508 __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
509 _M_detach_local_single(__it);
512 void
513 _Safe_unordered_container_base::
514 _M_detach_local_single(_Safe_iterator_base* __it) throw ()
516 // Remove __it from this container's list
517 __it->_M_unlink();
518 if (_M_const_local_iterators == __it)
519 _M_const_local_iterators = __it->_M_next;
520 if (_M_local_iterators == __it)
521 _M_local_iterators = __it->_M_next;
525 namespace
527 void
528 print_type(const __gnu_debug::_Error_formatter* __formatter,
529 const type_info* __info,
530 const char* __unknown_name)
532 if (!__info)
533 __formatter->_M_print_word(__unknown_name);
534 else
536 int __status;
537 char* __demangled_name =
538 __cxxabiv1::__cxa_demangle(__info->name(), NULL, NULL, &__status);
539 __formatter->_M_print_word(__status == 0
540 ? __demangled_name : __info->name());
541 free(__demangled_name);
545 bool
546 print_field(
547 const __gnu_debug::_Error_formatter* __formatter,
548 const char* __name,
549 const __gnu_debug::_Error_formatter::_Parameter::_Type& __variant)
551 if (strcmp(__name, "name") == 0)
553 assert(__variant._M_name);
554 __formatter->_M_print_word(__variant._M_name);
556 else if (strcmp(__name, "type") == 0)
557 print_type(__formatter, __variant._M_type, "<unknown type>");
558 else
559 return false;
561 return true;
564 bool
565 print_field(
566 const __gnu_debug::_Error_formatter* __formatter,
567 const char* __name,
568 const __gnu_debug::_Error_formatter::_Parameter::_Instance& __variant)
570 const __gnu_debug::_Error_formatter::_Parameter::_Type& __type = __variant;
571 if (print_field(__formatter, __name, __type))
573 else if (strcmp(__name, "address") == 0)
575 const int __bufsize = 64;
576 char __buf[__bufsize];
577 __formatter->_M_format_word(__buf, __bufsize, "%p",
578 __variant._M_address);
579 __formatter->_M_print_word(__buf);
581 else
582 return false;
584 return true;
587 void
588 print_description(
589 const __gnu_debug::_Error_formatter* __formatter,
590 const __gnu_debug::_Error_formatter::_Parameter::_Type& __variant)
592 if (__variant._M_name)
594 const int __bufsize = 64;
595 char __buf[__bufsize];
596 __formatter->_M_format_word(__buf, __bufsize, "\"%s\"",
597 __variant._M_name);
598 __formatter->_M_print_word(__buf);
601 __formatter->_M_print_word(" {\n");
603 if (__variant._M_type)
605 __formatter->_M_print_word(" type = ");
606 print_type(__formatter, __variant._M_type, "<unknown type>");
607 __formatter->_M_print_word(";\n");
612 void
613 print_description(
614 const __gnu_debug::_Error_formatter* __formatter,
615 const __gnu_debug::_Error_formatter::_Parameter::_Instance& __variant)
617 const int __bufsize = 64;
618 char __buf[__bufsize];
620 if (__variant._M_name)
622 __formatter->_M_format_word(__buf, __bufsize, "\"%s\" ",
623 __variant._M_name);
624 __formatter->_M_print_word(__buf);
627 __formatter->_M_format_word(__buf, __bufsize, "@ 0x%p {\n",
628 __variant._M_address);
629 __formatter->_M_print_word(__buf);
631 if (__variant._M_type)
633 __formatter->_M_print_word(" type = ");
634 print_type(__formatter, __variant._M_type, "<unknown type>");
639 namespace __gnu_debug
641 void
642 _Error_formatter::_Parameter::
643 _M_print_field(const _Error_formatter* __formatter, const char* __name) const
645 assert(this->_M_kind != _Parameter::__unused_param);
646 const int __bufsize = 64;
647 char __buf[__bufsize];
649 switch (_M_kind)
651 case __iterator:
652 if (print_field(__formatter, __name, _M_variant._M_iterator))
654 else if (strcmp(__name, "constness") == 0)
656 static const char* __constness_names[__last_constness] =
658 "<unknown>",
659 "constant",
660 "mutable"
662 __formatter->_M_print_word(__constness_names[_M_variant.
663 _M_iterator.
664 _M_constness]);
666 else if (strcmp(__name, "state") == 0)
668 static const char* __state_names[__last_state] =
670 "<unknown>",
671 "singular",
672 "dereferenceable (start-of-sequence)",
673 "dereferenceable",
674 "past-the-end",
675 "before-begin"
677 __formatter->_M_print_word(__state_names[_M_variant.
678 _M_iterator._M_state]);
680 else if (strcmp(__name, "sequence") == 0)
682 assert(_M_variant._M_iterator._M_sequence);
683 __formatter->_M_format_word(__buf, __bufsize, "%p",
684 _M_variant._M_iterator._M_sequence);
685 __formatter->_M_print_word(__buf);
687 else if (strcmp(__name, "seq_type") == 0)
688 print_type(__formatter, _M_variant._M_iterator._M_seq_type,
689 "<unknown seq_type>");
690 else
691 assert(false);
692 break;
693 case __sequence:
694 if (!print_field(__formatter, __name, _M_variant._M_sequence))
695 assert(false);
696 break;
697 case __integer:
698 if (strcmp(__name, "name") == 0)
700 assert(_M_variant._M_integer._M_name);
701 __formatter->_M_print_word(_M_variant._M_integer._M_name);
703 else
704 assert(false);
705 break;
706 case __string:
707 if (strcmp(__name, "name") == 0)
709 assert(_M_variant._M_string._M_name);
710 __formatter->_M_print_word(_M_variant._M_string._M_name);
712 else
713 assert(false);
714 break;
715 case __instance:
716 if (!print_field(__formatter, __name, _M_variant._M_instance))
717 assert(false);
718 break;
719 case __iterator_value_type:
720 if (!print_field(__formatter, __name, _M_variant._M_iterator_value_type))
721 assert(false);
722 break;
723 default:
724 assert(false);
725 break;
729 void
730 _Error_formatter::_Parameter::
731 _M_print_description(const _Error_formatter* __formatter) const
733 const int __bufsize = 128;
734 char __buf[__bufsize];
736 switch (_M_kind)
738 case __iterator:
739 __formatter->_M_print_word("iterator ");
740 print_description(__formatter, _M_variant._M_iterator);
742 if (_M_variant._M_iterator._M_type)
744 if (_M_variant._M_iterator._M_constness != __unknown_constness)
746 __formatter->_M_print_word(" (");
747 _M_print_field(__formatter, "constness");
748 __formatter->_M_print_word(" iterator)");
750 __formatter->_M_print_word(";\n");
753 if (_M_variant._M_iterator._M_state != __unknown_state)
755 __formatter->_M_print_word(" state = ");
756 _M_print_field(__formatter, "state");
757 __formatter->_M_print_word(";\n");
760 if (_M_variant._M_iterator._M_sequence)
762 __formatter->_M_print_word(" references sequence ");
763 if (_M_variant._M_iterator._M_seq_type)
765 __formatter->_M_print_word("with type `");
766 _M_print_field(__formatter, "seq_type");
767 __formatter->_M_print_word("' ");
770 __formatter->_M_format_word(__buf, __bufsize, "@ 0x%p\n",
771 _M_variant._M_iterator._M_sequence);
772 __formatter->_M_print_word(__buf);
775 __formatter->_M_print_word("}\n");
776 break;
777 case __sequence:
778 __formatter->_M_print_word("sequence ");
779 print_description(__formatter, _M_variant._M_sequence);
781 if (_M_variant._M_sequence._M_type)
782 __formatter->_M_print_word(";\n");
784 __formatter->_M_print_word("}\n");
785 break;
786 case __instance:
787 __formatter->_M_print_word("instance ");
788 print_description(__formatter, _M_variant._M_instance);
790 if (_M_variant._M_instance._M_type)
791 __formatter->_M_print_word(";\n");
793 __formatter->_M_print_word("}\n");
794 break;
795 case __iterator_value_type:
796 __formatter->_M_print_word("iterator::value_type ");
797 print_description(__formatter, _M_variant._M_iterator_value_type);
798 __formatter->_M_print_word("}\n");
799 break;
800 default:
801 break;
805 const _Error_formatter&
806 _Error_formatter::_M_message(_Debug_msg_id __id) const throw ()
807 { return this->_M_message(_S_debug_messages[__id]); }
809 void
810 _Error_formatter::_M_error() const
812 const int __bufsize = 128;
813 char __buf[__bufsize];
815 // Emit file & line number information
816 _M_column = 1;
817 _M_wordwrap = false;
818 if (_M_file)
820 _M_format_word(__buf, __bufsize, "%s:", _M_file);
821 _M_print_word(__buf);
822 _M_column += strlen(__buf);
825 if (_M_line > 0)
827 _M_format_word(__buf, __bufsize, "%u:", _M_line);
828 _M_print_word(__buf);
829 _M_column += strlen(__buf);
832 if (_M_max_length)
833 _M_wordwrap = true;
834 _M_print_word("error: ");
836 // Print the error message
837 assert(_M_text);
838 _M_print_string(_M_text);
839 _M_print_word(".\n");
841 // Emit descriptions of the objects involved in the operation
842 _M_wordwrap = false;
843 bool __has_noninteger_parameters = false;
844 for (unsigned int __i = 0; __i < _M_num_parameters; ++__i)
846 switch (_M_parameters[__i]._M_kind)
848 case _Parameter::__iterator:
849 case _Parameter::__sequence:
850 case _Parameter::__instance:
851 case _Parameter::__iterator_value_type:
852 if (!__has_noninteger_parameters)
854 _M_first_line = true;
855 _M_print_word("\nObjects involved in the operation:\n");
856 __has_noninteger_parameters = true;
858 _M_parameters[__i]._M_print_description(this);
859 break;
860 default:
861 break;
865 abort();
868 template<typename _Tp>
869 void
870 _Error_formatter::_M_format_word(char* __buf,
871 int __n __attribute__ ((__unused__)),
872 const char* __fmt, _Tp __s) const throw ()
874 #ifdef _GLIBCXX_USE_C99
875 std::snprintf(__buf, __n, __fmt, __s);
876 #else
877 std::sprintf(__buf, __fmt, __s);
878 #endif
881 void
882 _Error_formatter::_M_print_word(const char* __word) const
884 if (!_M_wordwrap)
886 fprintf(stderr, "%s", __word);
887 return;
890 size_t __length = strlen(__word);
891 if (__length == 0)
892 return;
894 size_t __visual_length
895 = __word[__length - 1] == '\n' ? __length - 1 : __length;
896 if (__visual_length == 0
897 || (_M_column + __visual_length < _M_max_length)
898 || (__visual_length >= _M_max_length && _M_column == 1))
900 // If this isn't the first line, indent
901 if (_M_column == 1 && !_M_first_line)
903 char __spacing[_M_indent + 1];
904 for (int i = 0; i < _M_indent; ++i)
905 __spacing[i] = ' ';
906 __spacing[_M_indent] = '\0';
907 fprintf(stderr, "%s", __spacing);
908 _M_column += _M_indent;
911 fprintf(stderr, "%s", __word);
913 if (__word[__length - 1] == '\n')
915 _M_first_line = false;
916 _M_column = 1;
918 else
919 _M_column += __length;
921 else
923 _M_print_word("\n");
924 _M_print_word(__word);
928 void
929 _Error_formatter::
930 _M_print_string(const char* __string) const
932 const char* __start = __string;
933 const char* __finish = __start;
934 const int __bufsize = 128;
935 char __buf[__bufsize];
937 while (*__start)
939 if (*__start != '%')
941 // [__start, __finish) denotes the next word
942 __finish = __start;
943 while (isalnum(*__finish))
944 ++__finish;
945 if (__start == __finish)
946 ++__finish;
947 if (isspace(*__finish))
948 ++__finish;
950 const ptrdiff_t __len = __finish - __start;
951 assert(__len < __bufsize);
952 memcpy(__buf, __start, __len);
953 __buf[__len] = '\0';
954 _M_print_word(__buf);
955 __start = __finish;
957 // Skip extra whitespace
958 while (*__start == ' ')
959 ++__start;
961 continue;
964 ++__start;
965 assert(*__start);
966 if (*__start == '%')
968 _M_print_word("%");
969 ++__start;
970 continue;
973 // Get the parameter number
974 assert(*__start >= '1' && *__start <= '9');
975 size_t __param_index = *__start - '0' - 1;
976 assert(__param_index < _M_num_parameters);
977 const auto& __param = _M_parameters[__param_index];
979 // '.' separates the parameter number from the field
980 // name, if there is one.
981 ++__start;
982 if (*__start != '.')
984 assert(*__start == ';');
985 ++__start;
986 __buf[0] = '\0';
987 if (__param._M_kind == _Parameter::__integer)
989 _M_format_word(__buf, __bufsize, "%ld",
990 __param._M_variant._M_integer._M_value);
991 _M_print_word(__buf);
993 else if (__param._M_kind == _Parameter::__string)
994 _M_print_string(__param._M_variant._M_string._M_value);
995 continue;
998 // Extract the field name we want
999 enum { __max_field_len = 16 };
1000 char __field[__max_field_len];
1001 int __field_idx = 0;
1002 ++__start;
1003 while (*__start != ';')
1005 assert(*__start);
1006 assert(__field_idx < __max_field_len-1);
1007 __field[__field_idx++] = *__start++;
1009 ++__start;
1010 __field[__field_idx] = 0;
1012 __param._M_print_field(this, __field);
1016 void
1017 _Error_formatter::_M_get_max_length() const throw ()
1019 const char* __nptr = std::getenv("GLIBCXX_DEBUG_MESSAGE_LENGTH");
1020 if (__nptr)
1022 char* __endptr;
1023 const unsigned long __ret = std::strtoul(__nptr, &__endptr, 0);
1024 if (*__nptr != '\0' && *__endptr == '\0')
1025 _M_max_length = __ret;
1029 // Instantiations.
1030 template
1031 void
1032 _Error_formatter::_M_format_word(char*, int, const char*,
1033 const void*) const;
1035 template
1036 void
1037 _Error_formatter::_M_format_word(char*, int, const char*, long) const;
1039 template
1040 void
1041 _Error_formatter::_M_format_word(char*, int, const char*,
1042 std::size_t) const;
1044 template
1045 void
1046 _Error_formatter::_M_format_word(char*, int, const char*,
1047 const char*) const;
1048 } // namespace __gnu_debug