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