00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include <debug/debug.h>
00032 #include <debug/safe_sequence.h>
00033 #include <debug/safe_iterator.h>
00034 #include <algorithm>
00035 #include <cstdlib>
00036 #include <cassert>
00037 #include <cstring>
00038 #include <cstdio>
00039 #include <cctype>
00040 #include <bits/concurrence.h>
00041
00042 using namespace std;
00043
00044 namespace __gnu_internal
00045 {
00046 __glibcxx_mutex_define_initialized(iterator_base_mutex);
00047 }
00048
00049 namespace __gnu_debug
00050 {
00051 const char* _S_debug_messages[] =
00052 {
00053 "function requires a valid iterator range [%1.name;, %2.name;)",
00054 "attempt to insert into container with a singular iterator",
00055 "attempt to insert into container with an iterator"
00056 " from a different container",
00057 "attempt to erase from container with a %2.state; iterator",
00058 "attempt to erase from container with an iterator"
00059 " from a different container",
00060 "attempt to subscript container with out-of-bounds index %2;,"
00061 " but container only holds %3; elements",
00062 "attempt to access an element in an empty container",
00063 "elements in iterator range [%1.name;, %2.name;)"
00064 " are not partitioned by the value %3;",
00065 "elements in iterator range [%1.name;, %2.name;)"
00066 " are not partitioned by the predicate %3; and value %4;",
00067 "elements in iterator range [%1.name;, %2.name;) are not sorted",
00068 "elements in iterator range [%1.name;, %2.name;)"
00069 " are not sorted according to the predicate %3;",
00070 "elements in iterator range [%1.name;, %2.name;) do not form a heap",
00071 "elements in iterator range [%1.name;, %2.name;)"
00072 " do not form a heap with respect to the predicate %3;",
00073 "attempt to write through a singular bitset reference",
00074 "attempt to read from a singular bitset reference",
00075 "attempt to flip a singular bitset reference",
00076 "attempt to splice a list into itself",
00077 "attempt to splice lists with inequal allocators",
00078 "attempt to splice elements referenced by a %1.state; iterator",
00079 "attempt to splice an iterator from a different container",
00080 "splice destination %1.name;"
00081 " occurs within source range [%2.name;, %3.name;)",
00082 "attempt to initialize an iterator that will immediately become singular",
00083 "attempt to copy-construct an iterator from a singular iterator",
00084 "attempt to construct a constant iterator"
00085 " from a singular mutable iterator",
00086 "attempt to copy from a singular iterator",
00087 "attempt to dereference a %1.state; iterator",
00088 "attempt to increment a %1.state; iterator",
00089 "attempt to decrement a %1.state; iterator",
00090 "attempt to subscript a %1.state; iterator %2; step from"
00091 " its current position, which falls outside its dereferenceable range",
00092 "attempt to advance a %1.state; iterator %2; steps,"
00093 " which falls outside its valid range",
00094 "attempt to retreat a %1.state; iterator %2; steps,"
00095 " which falls outside its valid range",
00096 "attempt to compare a %1.state; iterator to a %2.state; iterator",
00097 "attempt to compare iterators from different sequences",
00098 "attempt to order a %1.state; iterator to a %2.state; iterator",
00099 "attempt to order iterators from different sequences",
00100 "attempt to compute the difference between a %1.state;"
00101 " iterator to a %2.state; iterator",
00102 "attempt to compute the different between two iterators"
00103 " from different sequences",
00104 "attempt to dereference an end-of-stream istream_iterator",
00105 "attempt to increment an end-of-stream istream_iterator",
00106 "attempt to output via an ostream_iterator with no associated stream",
00107 "attempt to dereference an end-of-stream istreambuf_iterator"
00108 " (this is a GNU extension)",
00109 "attempt to increment an end-of-stream istreambuf_iterator"
00110 };
00111
00112 void
00113 _Safe_sequence_base::
00114 _M_detach_all()
00115 {
00116 for (_Safe_iterator_base* __iter = _M_iterators; __iter; )
00117 {
00118 _Safe_iterator_base* __old = __iter;
00119 __iter = __iter->_M_next;
00120 __old->_M_attach(0, false);
00121 }
00122
00123 for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2; )
00124 {
00125 _Safe_iterator_base* __old = __iter2;
00126 __iter2 = __iter2->_M_next;
00127 __old->_M_attach(0, true);
00128 }
00129 }
00130
00131 void
00132 _Safe_sequence_base::
00133 _M_detach_singular()
00134 {
00135 for (_Safe_iterator_base* __iter = _M_iterators; __iter; )
00136 {
00137 _Safe_iterator_base* __old = __iter;
00138 __iter = __iter->_M_next;
00139 if (__old->_M_singular())
00140 __old->_M_attach(0, false);
00141 }
00142
00143 for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2; )
00144 {
00145 _Safe_iterator_base* __old = __iter2;
00146 __iter2 = __iter2->_M_next;
00147 if (__old->_M_singular())
00148 __old->_M_attach(0, true);
00149 }
00150 }
00151
00152 void
00153 _Safe_sequence_base::
00154 _M_revalidate_singular()
00155 {
00156 _Safe_iterator_base* __iter;
00157 for (__iter = _M_iterators; __iter; __iter = __iter->_M_next)
00158 {
00159 __iter->_M_version = _M_version;
00160 __iter = __iter->_M_next;
00161 }
00162
00163 for (__iter = _M_const_iterators; __iter; __iter = __iter->_M_next)
00164 {
00165 __iter->_M_version = _M_version;
00166 __iter = __iter->_M_next;
00167 }
00168 }
00169
00170 void
00171 _Safe_sequence_base::
00172 _M_swap(_Safe_sequence_base& __x)
00173 {
00174 swap(_M_iterators, __x._M_iterators);
00175 swap(_M_const_iterators, __x._M_const_iterators);
00176 swap(_M_version, __x._M_version);
00177 _Safe_iterator_base* __iter;
00178 for (__iter = _M_iterators; __iter; __iter = __iter->_M_next)
00179 __iter->_M_sequence = this;
00180 for (__iter = __x._M_iterators; __iter; __iter = __iter->_M_next)
00181 __iter->_M_sequence = &__x;
00182 for (__iter = _M_const_iterators; __iter; __iter = __iter->_M_next)
00183 __iter->_M_sequence = this;
00184 for (__iter = __x._M_const_iterators; __iter; __iter = __iter->_M_next)
00185 __iter->_M_sequence = &__x;
00186 }
00187
00188 void
00189 _Safe_iterator_base::
00190 _M_attach(_Safe_sequence_base* __seq, bool __constant)
00191 {
00192 _M_detach();
00193
00194
00195 if (__seq)
00196 {
00197 __gnu_cxx::lock sentry(__gnu_internal::iterator_base_mutex);
00198 _M_sequence = __seq;
00199 _M_version = _M_sequence->_M_version;
00200 _M_prior = 0;
00201 if (__constant)
00202 {
00203 _M_next = _M_sequence->_M_const_iterators;
00204 if (_M_next)
00205 _M_next->_M_prior = this;
00206 _M_sequence->_M_const_iterators = this;
00207 }
00208 else
00209 {
00210 _M_next = _M_sequence->_M_iterators;
00211 if (_M_next)
00212 _M_next->_M_prior = this;
00213 _M_sequence->_M_iterators = this;
00214 }
00215 }
00216 }
00217
00218 void
00219 _Safe_iterator_base::
00220 _M_detach()
00221 {
00222 __gnu_cxx::lock sentry(__gnu_internal::iterator_base_mutex);
00223 if (_M_sequence)
00224 {
00225
00226 if (_M_prior)
00227 _M_prior->_M_next = _M_next;
00228 if (_M_next)
00229 _M_next->_M_prior = _M_prior;
00230
00231 if (_M_sequence->_M_const_iterators == this)
00232 _M_sequence->_M_const_iterators = _M_next;
00233 if (_M_sequence->_M_iterators == this)
00234 _M_sequence->_M_iterators = _M_next;
00235 }
00236
00237 _M_sequence = 0;
00238 _M_version = 0;
00239 _M_prior = 0;
00240 _M_next = 0;
00241 }
00242
00243 bool
00244 _Safe_iterator_base::
00245 _M_singular() const
00246 { return !_M_sequence || _M_version != _M_sequence->_M_version; }
00247
00248 bool
00249 _Safe_iterator_base::
00250 _M_can_compare(const _Safe_iterator_base& __x) const
00251 {
00252 return (!_M_singular() && !__x._M_singular()
00253 && _M_sequence == __x._M_sequence);
00254 }
00255
00256 void
00257 _Error_formatter::_Parameter::
00258 _M_print_field(const _Error_formatter* __formatter, const char* __name) const
00259 {
00260 assert(this->_M_kind != _Parameter::__unused_param);
00261 const int __bufsize = 64;
00262 char __buf[__bufsize];
00263
00264 if (_M_kind == __iterator)
00265 {
00266 if (strcmp(__name, "name") == 0)
00267 {
00268 assert(_M_variant._M_iterator._M_name);
00269 __formatter->_M_print_word(_M_variant._M_iterator._M_name);
00270 }
00271 else if (strcmp(__name, "address") == 0)
00272 {
00273 __formatter->_M_format_word(__buf, __bufsize, "%p",
00274 _M_variant._M_iterator._M_address);
00275 __formatter->_M_print_word(__buf);
00276 }
00277 else if (strcmp(__name, "type") == 0)
00278 {
00279 assert(_M_variant._M_iterator._M_type);
00280
00281 __formatter->_M_print_word(_M_variant._M_iterator._M_type->name());
00282 }
00283 else if (strcmp(__name, "constness") == 0)
00284 {
00285 static const char* __constness_names[__last_constness] =
00286 {
00287 "<unknown>",
00288 "constant",
00289 "mutable"
00290 };
00291 __formatter->_M_print_word(__constness_names[_M_variant._M_iterator._M_constness]);
00292 }
00293 else if (strcmp(__name, "state") == 0)
00294 {
00295 static const char* __state_names[__last_state] =
00296 {
00297 "<unknown>",
00298 "singular",
00299 "dereferenceable (start-of-sequence)",
00300 "dereferenceable",
00301 "past-the-end"
00302 };
00303 __formatter->_M_print_word(__state_names[_M_variant._M_iterator._M_state]);
00304 }
00305 else if (strcmp(__name, "sequence") == 0)
00306 {
00307 assert(_M_variant._M_iterator._M_sequence);
00308 __formatter->_M_format_word(__buf, __bufsize, "%p",
00309 _M_variant._M_iterator._M_sequence);
00310 __formatter->_M_print_word(__buf);
00311 }
00312 else if (strcmp(__name, "seq_type") == 0)
00313 {
00314
00315 assert(_M_variant._M_iterator._M_seq_type);
00316 __formatter->_M_print_word(_M_variant._M_iterator._M_seq_type->name());
00317 }
00318 else
00319 assert(false);
00320 }
00321 else if (_M_kind == __sequence)
00322 {
00323 if (strcmp(__name, "name") == 0)
00324 {
00325 assert(_M_variant._M_sequence._M_name);
00326 __formatter->_M_print_word(_M_variant._M_sequence._M_name);
00327 }
00328 else if (strcmp(__name, "address") == 0)
00329 {
00330 assert(_M_variant._M_sequence._M_address);
00331 __formatter->_M_format_word(__buf, __bufsize, "%p",
00332 _M_variant._M_sequence._M_address);
00333 __formatter->_M_print_word(__buf);
00334 }
00335 else if (strcmp(__name, "type") == 0)
00336 {
00337
00338 assert(_M_variant._M_sequence._M_type);
00339 __formatter->_M_print_word(_M_variant._M_sequence._M_type->name());
00340 }
00341 else
00342 assert(false);
00343 }
00344 else if (_M_kind == __integer)
00345 {
00346 if (strcmp(__name, "name") == 0)
00347 {
00348 assert(_M_variant._M_integer._M_name);
00349 __formatter->_M_print_word(_M_variant._M_integer._M_name);
00350 }
00351 else
00352 assert(false);
00353 }
00354 else if (_M_kind == __string)
00355 {
00356 if (strcmp(__name, "name") == 0)
00357 {
00358 assert(_M_variant._M_string._M_name);
00359 __formatter->_M_print_word(_M_variant._M_string._M_name);
00360 }
00361 else
00362 assert(false);
00363 }
00364 else
00365 {
00366 assert(false);
00367 }
00368 }
00369
00370 void
00371 _Error_formatter::_Parameter::
00372 _M_print_description(const _Error_formatter* __formatter) const
00373 {
00374 const int __bufsize = 128;
00375 char __buf[__bufsize];
00376
00377 if (_M_kind == __iterator)
00378 {
00379 __formatter->_M_print_word("iterator ");
00380 if (_M_variant._M_iterator._M_name)
00381 {
00382 __formatter->_M_format_word(__buf, __bufsize, "\"%s\" ",
00383 _M_variant._M_iterator._M_name);
00384 __formatter->_M_print_word(__buf);
00385 }
00386
00387 __formatter->_M_format_word(__buf, __bufsize, "@ 0x%p {\n",
00388 _M_variant._M_iterator._M_address);
00389 __formatter->_M_print_word(__buf);
00390 if (_M_variant._M_iterator._M_type)
00391 {
00392 __formatter->_M_print_word("type = ");
00393 _M_print_field(__formatter, "type");
00394
00395 if (_M_variant._M_iterator._M_constness != __unknown_constness)
00396 {
00397 __formatter->_M_print_word(" (");
00398 _M_print_field(__formatter, "constness");
00399 __formatter->_M_print_word(" iterator)");
00400 }
00401 __formatter->_M_print_word(";\n");
00402 }
00403
00404 if (_M_variant._M_iterator._M_state != __unknown_state)
00405 {
00406 __formatter->_M_print_word(" state = ");
00407 _M_print_field(__formatter, "state");
00408 __formatter->_M_print_word(";\n");
00409 }
00410
00411 if (_M_variant._M_iterator._M_sequence)
00412 {
00413 __formatter->_M_print_word(" references sequence ");
00414 if (_M_variant._M_iterator._M_seq_type)
00415 {
00416 __formatter->_M_print_word("with type `");
00417 _M_print_field(__formatter, "seq_type");
00418 __formatter->_M_print_word("' ");
00419 }
00420
00421 __formatter->_M_format_word(__buf, __bufsize, "@ 0x%p\n",
00422 _M_variant._M_sequence._M_address);
00423 __formatter->_M_print_word(__buf);
00424 }
00425 __formatter->_M_print_word("}\n");
00426 }
00427 else if (_M_kind == __sequence)
00428 {
00429 __formatter->_M_print_word("sequence ");
00430 if (_M_variant._M_sequence._M_name)
00431 {
00432 __formatter->_M_format_word(__buf, __bufsize, "\"%s\" ",
00433 _M_variant._M_sequence._M_name);
00434 __formatter->_M_print_word(__buf);
00435 }
00436
00437 __formatter->_M_format_word(__buf, __bufsize, "@ 0x%p {\n",
00438 _M_variant._M_sequence._M_address);
00439 __formatter->_M_print_word(__buf);
00440
00441 if (_M_variant._M_sequence._M_type)
00442 {
00443 __formatter->_M_print_word(" type = ");
00444 _M_print_field(__formatter, "type");
00445 __formatter->_M_print_word(";\n");
00446 }
00447 __formatter->_M_print_word("}\n");
00448 }
00449 }
00450
00451 const _Error_formatter&
00452 _Error_formatter::_M_message(_Debug_msg_id __id) const
00453 { return this->_M_message(_S_debug_messages[__id]); }
00454
00455 void
00456 _Error_formatter::_M_error() const
00457 {
00458 const int __bufsize = 128;
00459 char __buf[__bufsize];
00460
00461
00462 _M_column = 1;
00463 _M_wordwrap = false;
00464 if (_M_file)
00465 {
00466 _M_format_word(__buf, __bufsize, "%s:", _M_file);
00467 _M_print_word(__buf);
00468 _M_column += strlen(__buf);
00469 }
00470
00471 if (_M_line > 0)
00472 {
00473 _M_format_word(__buf, __bufsize, "%u:", _M_line);
00474 _M_print_word(__buf);
00475 _M_column += strlen(__buf);
00476 }
00477
00478 _M_wordwrap = true;
00479 _M_print_word("error: ");
00480
00481
00482 assert(_M_text);
00483 _M_print_string(_M_text);
00484 _M_print_word(".\n");
00485
00486
00487 _M_wordwrap = false;
00488 bool __has_noninteger_parameters = false;
00489 for (unsigned int __i = 0; __i < _M_num_parameters; ++__i)
00490 {
00491 if (_M_parameters[__i]._M_kind == _Parameter::__iterator
00492 || _M_parameters[__i]._M_kind == _Parameter::__sequence)
00493 {
00494 if (!__has_noninteger_parameters)
00495 {
00496 _M_first_line = true;
00497 _M_print_word("\nObjects involved in the operation:\n");
00498 __has_noninteger_parameters = true;
00499 }
00500 _M_parameters[__i]._M_print_description(this);
00501 }
00502 }
00503
00504 abort();
00505 }
00506
00507 template<typename _Tp>
00508 void
00509 _Error_formatter::_M_format_word(char* __buf,
00510 int __n __attribute__((__unused__)),
00511 const char* __fmt, _Tp __s) const
00512 {
00513 #ifdef _GLIBCXX_USE_C99
00514 std::snprintf(__buf, __n, __fmt, __s);
00515 #else
00516 std::sprintf(__buf, __fmt, __s);
00517 #endif
00518 }
00519
00520
00521 void
00522 _Error_formatter::_M_print_word(const char* __word) const
00523 {
00524 if (!_M_wordwrap)
00525 {
00526 fprintf(stderr, "%s", __word);
00527 return;
00528 }
00529
00530 size_t __length = strlen(__word);
00531 if (__length == 0)
00532 return;
00533
00534 if ((_M_column + __length < _M_max_length)
00535 || (__length >= _M_max_length && _M_column == 1))
00536 {
00537
00538 if (_M_column == 1 && !_M_first_line)
00539 {
00540 char __spacing[_M_indent + 1];
00541 for (int i = 0; i < _M_indent; ++i)
00542 __spacing[i] = ' ';
00543 __spacing[_M_indent] = '\0';
00544 fprintf(stderr, "%s", __spacing);
00545 _M_column += _M_indent;
00546 }
00547
00548 fprintf(stderr, "%s", __word);
00549 _M_column += __length;
00550
00551 if (__word[__length - 1] == '\n')
00552 {
00553 _M_first_line = false;
00554 _M_column = 1;
00555 }
00556 }
00557 else
00558 {
00559 _M_column = 1;
00560 _M_print_word("\n");
00561 _M_print_word(__word);
00562 }
00563 }
00564
00565 void
00566 _Error_formatter::
00567 _M_print_string(const char* __string) const
00568 {
00569 const char* __start = __string;
00570 const char* __end = __start;
00571 const int __bufsize = 128;
00572 char __buf[__bufsize];
00573
00574 while (*__start)
00575 {
00576 if (*__start != '%')
00577 {
00578
00579 __end = __start;
00580 while (isalnum(*__end))
00581 ++__end;
00582 if (__start == __end)
00583 ++__end;
00584 if (isspace(*__end))
00585 ++__end;
00586
00587 const ptrdiff_t __len = __end - __start;
00588 assert(__len < __bufsize);
00589 memcpy(__buf, __start, __len);
00590 __buf[__len] = '\0';
00591 _M_print_word(__buf);
00592 __start = __end;
00593
00594
00595 while (*__start == ' ')
00596 ++__start;
00597
00598 continue;
00599 }
00600
00601 ++__start;
00602 assert(*__start);
00603 if (*__start == '%')
00604 {
00605 _M_print_word("%");
00606 ++__start;
00607 continue;
00608 }
00609
00610
00611 assert(*__start >= '1' && *__start <= '9');
00612 size_t __param = *__start - '0';
00613 --__param;
00614 assert(__param < _M_num_parameters);
00615
00616
00617
00618 ++__start;
00619 if (*__start != '.')
00620 {
00621 assert(*__start == ';');
00622 ++__start;
00623 __buf[0] = '\0';
00624 if (_M_parameters[__param]._M_kind == _Parameter::__integer)
00625 {
00626 _M_format_word(__buf, __bufsize, "%ld",
00627 _M_parameters[__param]._M_variant._M_integer._M_value);
00628 _M_print_word(__buf);
00629 }
00630 else if (_M_parameters[__param]._M_kind == _Parameter::__string)
00631 _M_print_string(_M_parameters[__param]._M_variant._M_string._M_value);
00632 continue;
00633 }
00634
00635
00636 enum { __max_field_len = 16 };
00637 char __field[__max_field_len];
00638 int __field_idx = 0;
00639 ++__start;
00640 while (*__start != ';')
00641 {
00642 assert(*__start);
00643 assert(__field_idx < __max_field_len-1);
00644 __field[__field_idx++] = *__start++;
00645 }
00646 ++__start;
00647 __field[__field_idx] = 0;
00648
00649 _M_parameters[__param]._M_print_field(this, __field);
00650 }
00651 }
00652
00653
00654 template
00655 void
00656 _Error_formatter::_M_format_word(char* __buf, int __n, const char* __fmt,
00657 const void* __s) const;
00658
00659 template
00660 void
00661 _Error_formatter::_M_format_word(char* __buf, int __n, const char* __fmt,
00662 long __s) const;
00663
00664 template
00665 void
00666 _Error_formatter::_M_format_word(char* __buf, int __n, const char* __fmt,
00667 std::size_t __s) const;
00668
00669 template
00670 void
00671 _Error_formatter::_M_format_word(char* __buf, int __n, const char* __fmt,
00672 const char* __s) const;
00673 }