1132720Skan// Debugging mode support code -*- C++ -*- 2132720Skan 3169691Skan// Copyright (C) 2003, 2004, 2005, 2006 4132720Skan// Free Software Foundation, Inc. 5132720Skan// 6132720Skan// This file is part of the GNU ISO C++ Library. This library is free 7132720Skan// software; you can redistribute it and/or modify it under the 8132720Skan// terms of the GNU General Public License as published by the 9132720Skan// Free Software Foundation; either version 2, or (at your option) 10132720Skan// any later version. 11132720Skan 12132720Skan// This library is distributed in the hope that it will be useful, 13132720Skan// but WITHOUT ANY WARRANTY; without even the implied warranty of 14132720Skan// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15132720Skan// GNU General Public License for more details. 16132720Skan 17132720Skan// You should have received a copy of the GNU General Public License along 18132720Skan// with this library; see the file COPYING. If not, write to the Free 19169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 20132720Skan// USA. 21132720Skan 22132720Skan// As a special exception, you may use this file as part of a free software 23132720Skan// library without restriction. Specifically, if other files instantiate 24132720Skan// templates or use macros or inline functions from this file, or you compile 25132720Skan// this file and link it with other files to produce an executable, this 26132720Skan// file does not by itself cause the resulting executable to be covered by 27132720Skan// the GNU General Public License. This exception does not however 28132720Skan// invalidate any other reasons why the executable file might be covered by 29132720Skan// the GNU General Public License. 30132720Skan 31132720Skan#include <debug/debug.h> 32132720Skan#include <debug/safe_sequence.h> 33132720Skan#include <debug/safe_iterator.h> 34132720Skan#include <algorithm> 35132720Skan#include <cassert> 36132720Skan#include <cstring> 37132720Skan#include <cctype> 38132720Skan 39132720Skanusing namespace std; 40132720Skan 41169691Skannamespace 42146897Skan{ 43169691Skan __gnu_cxx::__mutex safe_base_mutex; 44169691Skan} // anonymous namespace 45146897Skan 46132720Skannamespace __gnu_debug 47132720Skan{ 48132720Skan const char* _S_debug_messages[] = 49132720Skan { 50132720Skan "function requires a valid iterator range [%1.name;, %2.name;)", 51132720Skan "attempt to insert into container with a singular iterator", 52132720Skan "attempt to insert into container with an iterator" 53132720Skan " from a different container", 54132720Skan "attempt to erase from container with a %2.state; iterator", 55132720Skan "attempt to erase from container with an iterator" 56132720Skan " from a different container", 57132720Skan "attempt to subscript container with out-of-bounds index %2;," 58132720Skan " but container only holds %3; elements", 59132720Skan "attempt to access an element in an empty container", 60132720Skan "elements in iterator range [%1.name;, %2.name;)" 61132720Skan " are not partitioned by the value %3;", 62132720Skan "elements in iterator range [%1.name;, %2.name;)" 63132720Skan " are not partitioned by the predicate %3; and value %4;", 64132720Skan "elements in iterator range [%1.name;, %2.name;) are not sorted", 65132720Skan "elements in iterator range [%1.name;, %2.name;)" 66132720Skan " are not sorted according to the predicate %3;", 67132720Skan "elements in iterator range [%1.name;, %2.name;) do not form a heap", 68132720Skan "elements in iterator range [%1.name;, %2.name;)" 69132720Skan " do not form a heap with respect to the predicate %3;", 70132720Skan "attempt to write through a singular bitset reference", 71132720Skan "attempt to read from a singular bitset reference", 72132720Skan "attempt to flip a singular bitset reference", 73132720Skan "attempt to splice a list into itself", 74132720Skan "attempt to splice lists with inequal allocators", 75132720Skan "attempt to splice elements referenced by a %1.state; iterator", 76132720Skan "attempt to splice an iterator from a different container", 77132720Skan "splice destination %1.name;" 78132720Skan " occurs within source range [%2.name;, %3.name;)", 79132720Skan "attempt to initialize an iterator that will immediately become singular", 80132720Skan "attempt to copy-construct an iterator from a singular iterator", 81132720Skan "attempt to construct a constant iterator" 82132720Skan " from a singular mutable iterator", 83132720Skan "attempt to copy from a singular iterator", 84132720Skan "attempt to dereference a %1.state; iterator", 85132720Skan "attempt to increment a %1.state; iterator", 86132720Skan "attempt to decrement a %1.state; iterator", 87132720Skan "attempt to subscript a %1.state; iterator %2; step from" 88132720Skan " its current position, which falls outside its dereferenceable range", 89132720Skan "attempt to advance a %1.state; iterator %2; steps," 90132720Skan " which falls outside its valid range", 91132720Skan "attempt to retreat a %1.state; iterator %2; steps," 92132720Skan " which falls outside its valid range", 93132720Skan "attempt to compare a %1.state; iterator to a %2.state; iterator", 94132720Skan "attempt to compare iterators from different sequences", 95132720Skan "attempt to order a %1.state; iterator to a %2.state; iterator", 96132720Skan "attempt to order iterators from different sequences", 97132720Skan "attempt to compute the difference between a %1.state;" 98132720Skan " iterator to a %2.state; iterator", 99132720Skan "attempt to compute the different between two iterators" 100132720Skan " from different sequences", 101132720Skan "attempt to dereference an end-of-stream istream_iterator", 102132720Skan "attempt to increment an end-of-stream istream_iterator", 103132720Skan "attempt to output via an ostream_iterator with no associated stream", 104132720Skan "attempt to dereference an end-of-stream istreambuf_iterator" 105132720Skan " (this is a GNU extension)", 106132720Skan "attempt to increment an end-of-stream istreambuf_iterator" 107132720Skan }; 108132720Skan 109169691Skan void 110132720Skan _Safe_sequence_base:: 111132720Skan _M_detach_all() 112132720Skan { 113169691Skan __gnu_cxx::__scoped_lock sentry(safe_base_mutex); 114169691Skan for (_Safe_iterator_base* __iter = _M_iterators; __iter;) 115132720Skan { 116132720Skan _Safe_iterator_base* __old = __iter; 117132720Skan __iter = __iter->_M_next; 118169691Skan __old->_M_detach_single(); 119132720Skan } 120132720Skan 121169691Skan for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2;) 122132720Skan { 123132720Skan _Safe_iterator_base* __old = __iter2; 124132720Skan __iter2 = __iter2->_M_next; 125169691Skan __old->_M_detach_single(); 126132720Skan } 127132720Skan } 128132720Skan 129169691Skan void 130132720Skan _Safe_sequence_base:: 131132720Skan _M_detach_singular() 132132720Skan { 133169691Skan __gnu_cxx::__scoped_lock sentry(safe_base_mutex); 134169691Skan for (_Safe_iterator_base* __iter = _M_iterators; __iter;) 135132720Skan { 136132720Skan _Safe_iterator_base* __old = __iter; 137132720Skan __iter = __iter->_M_next; 138132720Skan if (__old->_M_singular()) 139169691Skan __old->_M_detach_single(); 140132720Skan } 141132720Skan 142169691Skan for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2;) 143132720Skan { 144132720Skan _Safe_iterator_base* __old = __iter2; 145132720Skan __iter2 = __iter2->_M_next; 146132720Skan if (__old->_M_singular()) 147169691Skan __old->_M_detach_single(); 148132720Skan } 149132720Skan } 150169691Skan 151169691Skan void 152132720Skan _Safe_sequence_base:: 153132720Skan _M_revalidate_singular() 154132720Skan { 155169691Skan __gnu_cxx::__scoped_lock sentry(safe_base_mutex); 156169691Skan for (_Safe_iterator_base* __iter = _M_iterators; __iter; 157169691Skan __iter = __iter->_M_next) 158169691Skan __iter->_M_version = _M_version; 159169691Skan 160169691Skan for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2; 161169691Skan __iter2 = __iter2->_M_next) 162169691Skan __iter2->_M_version = _M_version; 163132720Skan } 164132720Skan 165169691Skan void 166132720Skan _Safe_sequence_base:: 167132720Skan _M_swap(_Safe_sequence_base& __x) 168132720Skan { 169169691Skan __gnu_cxx::__scoped_lock sentry(safe_base_mutex); 170132720Skan swap(_M_iterators, __x._M_iterators); 171132720Skan swap(_M_const_iterators, __x._M_const_iterators); 172132720Skan swap(_M_version, __x._M_version); 173132720Skan _Safe_iterator_base* __iter; 174132720Skan for (__iter = _M_iterators; __iter; __iter = __iter->_M_next) 175132720Skan __iter->_M_sequence = this; 176132720Skan for (__iter = __x._M_iterators; __iter; __iter = __iter->_M_next) 177132720Skan __iter->_M_sequence = &__x; 178132720Skan for (__iter = _M_const_iterators; __iter; __iter = __iter->_M_next) 179132720Skan __iter->_M_sequence = this; 180132720Skan for (__iter = __x._M_const_iterators; __iter; __iter = __iter->_M_next) 181132720Skan __iter->_M_sequence = &__x; 182132720Skan } 183169691Skan 184169691Skan __gnu_cxx::__mutex& 185169691Skan _Safe_sequence_base:: 186169691Skan _M_get_mutex() 187169691Skan { return safe_base_mutex; } 188169691Skan 189169691Skan void 190132720Skan _Safe_iterator_base:: 191132720Skan _M_attach(_Safe_sequence_base* __seq, bool __constant) 192132720Skan { 193169691Skan __gnu_cxx::__scoped_lock sentry(safe_base_mutex); 194169691Skan _M_attach_single(__seq, __constant); 195169691Skan } 196169691Skan 197169691Skan void 198169691Skan _Safe_iterator_base:: 199169691Skan _M_attach_single(_Safe_sequence_base* __seq, bool __constant) 200169691Skan { 201169691Skan _M_detach_single(); 202132720Skan 203132720Skan // Attach to the new sequence (if there is one) 204132720Skan if (__seq) 205132720Skan { 206132720Skan _M_sequence = __seq; 207132720Skan _M_version = _M_sequence->_M_version; 208132720Skan _M_prior = 0; 209132720Skan if (__constant) 210132720Skan { 211132720Skan _M_next = _M_sequence->_M_const_iterators; 212132720Skan if (_M_next) 213132720Skan _M_next->_M_prior = this; 214132720Skan _M_sequence->_M_const_iterators = this; 215132720Skan } 216132720Skan else 217132720Skan { 218132720Skan _M_next = _M_sequence->_M_iterators; 219132720Skan if (_M_next) 220132720Skan _M_next->_M_prior = this; 221132720Skan _M_sequence->_M_iterators = this; 222132720Skan } 223132720Skan } 224132720Skan } 225132720Skan 226169691Skan void 227132720Skan _Safe_iterator_base:: 228132720Skan _M_detach() 229132720Skan { 230169691Skan __gnu_cxx::__scoped_lock sentry(safe_base_mutex); 231169691Skan _M_detach_single(); 232169691Skan } 233169691Skan 234169691Skan void 235169691Skan _Safe_iterator_base:: 236169691Skan _M_detach_single() 237169691Skan { 238132720Skan if (_M_sequence) 239132720Skan { 240132720Skan // Remove us from this sequence's list 241132720Skan if (_M_prior) 242132720Skan _M_prior->_M_next = _M_next; 243132720Skan if (_M_next) 244132720Skan _M_next->_M_prior = _M_prior; 245132720Skan 246132720Skan if (_M_sequence->_M_const_iterators == this) 247132720Skan _M_sequence->_M_const_iterators = _M_next; 248132720Skan if (_M_sequence->_M_iterators == this) 249132720Skan _M_sequence->_M_iterators = _M_next; 250132720Skan } 251132720Skan 252132720Skan _M_sequence = 0; 253132720Skan _M_version = 0; 254132720Skan _M_prior = 0; 255132720Skan _M_next = 0; 256132720Skan } 257169691Skan 258132720Skan bool 259132720Skan _Safe_iterator_base:: 260132720Skan _M_singular() const 261132720Skan { return !_M_sequence || _M_version != _M_sequence->_M_version; } 262132720Skan 263132720Skan bool 264132720Skan _Safe_iterator_base:: 265132720Skan _M_can_compare(const _Safe_iterator_base& __x) const 266132720Skan { 267169691Skan return (!_M_singular() 268169691Skan && !__x._M_singular() && _M_sequence == __x._M_sequence); 269132720Skan } 270132720Skan 271169691Skan __gnu_cxx::__mutex& 272169691Skan _Safe_iterator_base:: 273169691Skan _M_get_mutex() 274169691Skan { return safe_base_mutex; } 275169691Skan 276132720Skan void 277132720Skan _Error_formatter::_Parameter:: 278132720Skan _M_print_field(const _Error_formatter* __formatter, const char* __name) const 279132720Skan { 280132720Skan assert(this->_M_kind != _Parameter::__unused_param); 281132720Skan const int __bufsize = 64; 282132720Skan char __buf[__bufsize]; 283132720Skan 284132720Skan if (_M_kind == __iterator) 285132720Skan { 286132720Skan if (strcmp(__name, "name") == 0) 287132720Skan { 288132720Skan assert(_M_variant._M_iterator._M_name); 289132720Skan __formatter->_M_print_word(_M_variant._M_iterator._M_name); 290132720Skan } 291132720Skan else if (strcmp(__name, "address") == 0) 292132720Skan { 293132720Skan __formatter->_M_format_word(__buf, __bufsize, "%p", 294132720Skan _M_variant._M_iterator._M_address); 295132720Skan __formatter->_M_print_word(__buf); 296132720Skan } 297132720Skan else if (strcmp(__name, "type") == 0) 298132720Skan { 299132720Skan assert(_M_variant._M_iterator._M_type); 300132720Skan // TBD: demangle! 301132720Skan __formatter->_M_print_word(_M_variant._M_iterator._M_type->name()); 302132720Skan } 303132720Skan else if (strcmp(__name, "constness") == 0) 304132720Skan { 305132720Skan static const char* __constness_names[__last_constness] = 306132720Skan { 307132720Skan "<unknown>", 308132720Skan "constant", 309132720Skan "mutable" 310132720Skan }; 311132720Skan __formatter->_M_print_word(__constness_names[_M_variant._M_iterator._M_constness]); 312132720Skan } 313132720Skan else if (strcmp(__name, "state") == 0) 314132720Skan { 315132720Skan static const char* __state_names[__last_state] = 316132720Skan { 317132720Skan "<unknown>", 318132720Skan "singular", 319132720Skan "dereferenceable (start-of-sequence)", 320132720Skan "dereferenceable", 321132720Skan "past-the-end" 322132720Skan }; 323132720Skan __formatter->_M_print_word(__state_names[_M_variant._M_iterator._M_state]); 324132720Skan } 325132720Skan else if (strcmp(__name, "sequence") == 0) 326132720Skan { 327132720Skan assert(_M_variant._M_iterator._M_sequence); 328132720Skan __formatter->_M_format_word(__buf, __bufsize, "%p", 329132720Skan _M_variant._M_iterator._M_sequence); 330132720Skan __formatter->_M_print_word(__buf); 331132720Skan } 332132720Skan else if (strcmp(__name, "seq_type") == 0) 333132720Skan { 334132720Skan // TBD: demangle! 335132720Skan assert(_M_variant._M_iterator._M_seq_type); 336132720Skan __formatter->_M_print_word(_M_variant._M_iterator._M_seq_type->name()); 337132720Skan } 338132720Skan else 339132720Skan assert(false); 340132720Skan } 341132720Skan else if (_M_kind == __sequence) 342132720Skan { 343132720Skan if (strcmp(__name, "name") == 0) 344132720Skan { 345132720Skan assert(_M_variant._M_sequence._M_name); 346132720Skan __formatter->_M_print_word(_M_variant._M_sequence._M_name); 347132720Skan } 348132720Skan else if (strcmp(__name, "address") == 0) 349132720Skan { 350132720Skan assert(_M_variant._M_sequence._M_address); 351132720Skan __formatter->_M_format_word(__buf, __bufsize, "%p", 352132720Skan _M_variant._M_sequence._M_address); 353132720Skan __formatter->_M_print_word(__buf); 354132720Skan } 355132720Skan else if (strcmp(__name, "type") == 0) 356132720Skan { 357132720Skan // TBD: demangle! 358132720Skan assert(_M_variant._M_sequence._M_type); 359132720Skan __formatter->_M_print_word(_M_variant._M_sequence._M_type->name()); 360132720Skan } 361132720Skan else 362132720Skan assert(false); 363132720Skan } 364132720Skan else if (_M_kind == __integer) 365132720Skan { 366132720Skan if (strcmp(__name, "name") == 0) 367132720Skan { 368132720Skan assert(_M_variant._M_integer._M_name); 369132720Skan __formatter->_M_print_word(_M_variant._M_integer._M_name); 370132720Skan } 371132720Skan else 372132720Skan assert(false); 373132720Skan } 374132720Skan else if (_M_kind == __string) 375132720Skan { 376132720Skan if (strcmp(__name, "name") == 0) 377132720Skan { 378132720Skan assert(_M_variant._M_string._M_name); 379132720Skan __formatter->_M_print_word(_M_variant._M_string._M_name); 380132720Skan } 381132720Skan else 382132720Skan assert(false); 383132720Skan } 384132720Skan else 385132720Skan { 386132720Skan assert(false); 387132720Skan } 388132720Skan } 389132720Skan 390132720Skan void 391132720Skan _Error_formatter::_Parameter:: 392132720Skan _M_print_description(const _Error_formatter* __formatter) const 393132720Skan { 394132720Skan const int __bufsize = 128; 395132720Skan char __buf[__bufsize]; 396132720Skan 397132720Skan if (_M_kind == __iterator) 398132720Skan { 399132720Skan __formatter->_M_print_word("iterator "); 400132720Skan if (_M_variant._M_iterator._M_name) 401132720Skan { 402132720Skan __formatter->_M_format_word(__buf, __bufsize, "\"%s\" ", 403132720Skan _M_variant._M_iterator._M_name); 404132720Skan __formatter->_M_print_word(__buf); 405132720Skan } 406132720Skan 407132720Skan __formatter->_M_format_word(__buf, __bufsize, "@ 0x%p {\n", 408132720Skan _M_variant._M_iterator._M_address); 409132720Skan __formatter->_M_print_word(__buf); 410132720Skan if (_M_variant._M_iterator._M_type) 411132720Skan { 412132720Skan __formatter->_M_print_word("type = "); 413132720Skan _M_print_field(__formatter, "type"); 414132720Skan 415132720Skan if (_M_variant._M_iterator._M_constness != __unknown_constness) 416132720Skan { 417132720Skan __formatter->_M_print_word(" ("); 418132720Skan _M_print_field(__formatter, "constness"); 419132720Skan __formatter->_M_print_word(" iterator)"); 420132720Skan } 421132720Skan __formatter->_M_print_word(";\n"); 422132720Skan } 423132720Skan 424132720Skan if (_M_variant._M_iterator._M_state != __unknown_state) 425132720Skan { 426132720Skan __formatter->_M_print_word(" state = "); 427132720Skan _M_print_field(__formatter, "state"); 428132720Skan __formatter->_M_print_word(";\n"); 429132720Skan } 430132720Skan 431132720Skan if (_M_variant._M_iterator._M_sequence) 432132720Skan { 433132720Skan __formatter->_M_print_word(" references sequence "); 434132720Skan if (_M_variant._M_iterator._M_seq_type) 435132720Skan { 436132720Skan __formatter->_M_print_word("with type `"); 437132720Skan _M_print_field(__formatter, "seq_type"); 438132720Skan __formatter->_M_print_word("' "); 439132720Skan } 440132720Skan 441132720Skan __formatter->_M_format_word(__buf, __bufsize, "@ 0x%p\n", 442132720Skan _M_variant._M_sequence._M_address); 443132720Skan __formatter->_M_print_word(__buf); 444132720Skan } 445132720Skan __formatter->_M_print_word("}\n"); 446132720Skan } 447132720Skan else if (_M_kind == __sequence) 448132720Skan { 449132720Skan __formatter->_M_print_word("sequence "); 450132720Skan if (_M_variant._M_sequence._M_name) 451132720Skan { 452132720Skan __formatter->_M_format_word(__buf, __bufsize, "\"%s\" ", 453132720Skan _M_variant._M_sequence._M_name); 454132720Skan __formatter->_M_print_word(__buf); 455132720Skan } 456132720Skan 457132720Skan __formatter->_M_format_word(__buf, __bufsize, "@ 0x%p {\n", 458132720Skan _M_variant._M_sequence._M_address); 459132720Skan __formatter->_M_print_word(__buf); 460132720Skan 461132720Skan if (_M_variant._M_sequence._M_type) 462132720Skan { 463132720Skan __formatter->_M_print_word(" type = "); 464132720Skan _M_print_field(__formatter, "type"); 465132720Skan __formatter->_M_print_word(";\n"); 466132720Skan } 467132720Skan __formatter->_M_print_word("}\n"); 468132720Skan } 469132720Skan } 470132720Skan 471132720Skan const _Error_formatter& 472132720Skan _Error_formatter::_M_message(_Debug_msg_id __id) const 473132720Skan { return this->_M_message(_S_debug_messages[__id]); } 474132720Skan 475132720Skan void 476132720Skan _Error_formatter::_M_error() const 477132720Skan { 478132720Skan const int __bufsize = 128; 479132720Skan char __buf[__bufsize]; 480132720Skan 481132720Skan // Emit file & line number information 482132720Skan _M_column = 1; 483132720Skan _M_wordwrap = false; 484132720Skan if (_M_file) 485132720Skan { 486132720Skan _M_format_word(__buf, __bufsize, "%s:", _M_file); 487132720Skan _M_print_word(__buf); 488132720Skan _M_column += strlen(__buf); 489132720Skan } 490132720Skan 491132720Skan if (_M_line > 0) 492132720Skan { 493132720Skan _M_format_word(__buf, __bufsize, "%u:", _M_line); 494132720Skan _M_print_word(__buf); 495132720Skan _M_column += strlen(__buf); 496132720Skan } 497132720Skan 498132720Skan _M_wordwrap = true; 499132720Skan _M_print_word("error: "); 500132720Skan 501132720Skan // Print the error message 502132720Skan assert(_M_text); 503132720Skan _M_print_string(_M_text); 504132720Skan _M_print_word(".\n"); 505132720Skan 506132720Skan // Emit descriptions of the objects involved in the operation 507132720Skan _M_wordwrap = false; 508132720Skan bool __has_noninteger_parameters = false; 509132720Skan for (unsigned int __i = 0; __i < _M_num_parameters; ++__i) 510132720Skan { 511132720Skan if (_M_parameters[__i]._M_kind == _Parameter::__iterator 512132720Skan || _M_parameters[__i]._M_kind == _Parameter::__sequence) 513132720Skan { 514132720Skan if (!__has_noninteger_parameters) 515132720Skan { 516132720Skan _M_first_line = true; 517132720Skan _M_print_word("\nObjects involved in the operation:\n"); 518132720Skan __has_noninteger_parameters = true; 519132720Skan } 520132720Skan _M_parameters[__i]._M_print_description(this); 521132720Skan } 522132720Skan } 523132720Skan 524132720Skan abort(); 525132720Skan } 526132720Skan 527132720Skan template<typename _Tp> 528132720Skan void 529132720Skan _Error_formatter::_M_format_word(char* __buf, 530169691Skan int __n __attribute__ ((__unused__)), 531132720Skan const char* __fmt, _Tp __s) const 532132720Skan { 533132720Skan#ifdef _GLIBCXX_USE_C99 534132720Skan std::snprintf(__buf, __n, __fmt, __s); 535132720Skan#else 536132720Skan std::sprintf(__buf, __fmt, __s); 537132720Skan#endif 538132720Skan } 539132720Skan 540132720Skan 541132720Skan void 542132720Skan _Error_formatter::_M_print_word(const char* __word) const 543132720Skan { 544132720Skan if (!_M_wordwrap) 545132720Skan { 546132720Skan fprintf(stderr, "%s", __word); 547132720Skan return; 548132720Skan } 549132720Skan 550132720Skan size_t __length = strlen(__word); 551132720Skan if (__length == 0) 552132720Skan return; 553132720Skan 554132720Skan if ((_M_column + __length < _M_max_length) 555132720Skan || (__length >= _M_max_length && _M_column == 1)) 556132720Skan { 557132720Skan // If this isn't the first line, indent 558132720Skan if (_M_column == 1 && !_M_first_line) 559132720Skan { 560132720Skan char __spacing[_M_indent + 1]; 561132720Skan for (int i = 0; i < _M_indent; ++i) 562132720Skan __spacing[i] = ' '; 563132720Skan __spacing[_M_indent] = '\0'; 564132720Skan fprintf(stderr, "%s", __spacing); 565132720Skan _M_column += _M_indent; 566132720Skan } 567132720Skan 568132720Skan fprintf(stderr, "%s", __word); 569132720Skan _M_column += __length; 570132720Skan 571132720Skan if (__word[__length - 1] == '\n') 572132720Skan { 573132720Skan _M_first_line = false; 574132720Skan _M_column = 1; 575132720Skan } 576132720Skan } 577132720Skan else 578132720Skan { 579132720Skan _M_column = 1; 580132720Skan _M_print_word("\n"); 581132720Skan _M_print_word(__word); 582132720Skan } 583132720Skan } 584132720Skan 585132720Skan void 586132720Skan _Error_formatter:: 587132720Skan _M_print_string(const char* __string) const 588132720Skan { 589132720Skan const char* __start = __string; 590169691Skan const char* __finish = __start; 591132720Skan const int __bufsize = 128; 592132720Skan char __buf[__bufsize]; 593132720Skan 594132720Skan while (*__start) 595132720Skan { 596132720Skan if (*__start != '%') 597132720Skan { 598169691Skan // [__start, __finish) denotes the next word 599169691Skan __finish = __start; 600169691Skan while (isalnum(*__finish)) 601169691Skan ++__finish; 602169691Skan if (__start == __finish) 603169691Skan ++__finish; 604169691Skan if (isspace(*__finish)) 605169691Skan ++__finish; 606132720Skan 607169691Skan const ptrdiff_t __len = __finish - __start; 608146897Skan assert(__len < __bufsize); 609146897Skan memcpy(__buf, __start, __len); 610146897Skan __buf[__len] = '\0'; 611132720Skan _M_print_word(__buf); 612169691Skan __start = __finish; 613132720Skan 614132720Skan // Skip extra whitespace 615132720Skan while (*__start == ' ') 616132720Skan ++__start; 617132720Skan 618132720Skan continue; 619132720Skan } 620132720Skan 621132720Skan ++__start; 622132720Skan assert(*__start); 623132720Skan if (*__start == '%') 624132720Skan { 625132720Skan _M_print_word("%"); 626132720Skan ++__start; 627132720Skan continue; 628132720Skan } 629132720Skan 630132720Skan // Get the parameter number 631132720Skan assert(*__start >= '1' && *__start <= '9'); 632132720Skan size_t __param = *__start - '0'; 633132720Skan --__param; 634132720Skan assert(__param < _M_num_parameters); 635132720Skan 636132720Skan // '.' separates the parameter number from the field 637132720Skan // name, if there is one. 638132720Skan ++__start; 639132720Skan if (*__start != '.') 640132720Skan { 641132720Skan assert(*__start == ';'); 642132720Skan ++__start; 643132720Skan __buf[0] = '\0'; 644132720Skan if (_M_parameters[__param]._M_kind == _Parameter::__integer) 645132720Skan { 646132720Skan _M_format_word(__buf, __bufsize, "%ld", 647132720Skan _M_parameters[__param]._M_variant._M_integer._M_value); 648132720Skan _M_print_word(__buf); 649132720Skan } 650132720Skan else if (_M_parameters[__param]._M_kind == _Parameter::__string) 651132720Skan _M_print_string(_M_parameters[__param]._M_variant._M_string._M_value); 652132720Skan continue; 653132720Skan } 654132720Skan 655132720Skan // Extract the field name we want 656132720Skan enum { __max_field_len = 16 }; 657132720Skan char __field[__max_field_len]; 658132720Skan int __field_idx = 0; 659132720Skan ++__start; 660132720Skan while (*__start != ';') 661132720Skan { 662132720Skan assert(*__start); 663132720Skan assert(__field_idx < __max_field_len-1); 664132720Skan __field[__field_idx++] = *__start++; 665132720Skan } 666132720Skan ++__start; 667132720Skan __field[__field_idx] = 0; 668132720Skan 669132720Skan _M_parameters[__param]._M_print_field(this, __field); 670132720Skan } 671132720Skan } 672132720Skan 673132720Skan // Instantiations. 674132720Skan template 675132720Skan void 676169691Skan _Error_formatter::_M_format_word(char*, int, const char*, 677169691Skan const void*) const; 678132720Skan 679132720Skan template 680132720Skan void 681169691Skan _Error_formatter::_M_format_word(char*, int, const char*, long) const; 682132720Skan 683132720Skan template 684132720Skan void 685169691Skan _Error_formatter::_M_format_word(char*, int, const char*, 686169691Skan std::size_t) const; 687132720Skan 688132720Skan template 689132720Skan void 690169691Skan _Error_formatter::_M_format_word(char*, int, const char*, 691169691Skan const char*) const; 692132720Skan} // namespace __gnu_debug 693