OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libstdc++-v3/] [src/] [c++11/] [debug.cc] - Blame information for rev 746

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 742 jeremybenn
// Debugging mode support code -*- C++ -*-
2
 
3
// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
4
// 2011 Free Software Foundation, Inc.
5
//
6
// This file is part of the GNU ISO C++ Library.  This library is free
7
// software; you can redistribute it and/or modify it under the
8
// terms of the GNU General Public License as published by the
9
// Free Software Foundation; either version 3, or (at your option)
10
// any later version.
11
 
12
// This library is distributed in the hope that it will be useful,
13
// but WITHOUT ANY WARRANTY; without even the implied warranty of
14
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
// GNU General Public License for more details.
16
 
17
// Under Section 7 of GPL version 3, you are granted additional
18
// permissions described in the GCC Runtime Library Exception, version
19
// 3.1, as published by the Free Software Foundation.
20
 
21
// You should have received a copy of the GNU General Public License and
22
// a copy of the GCC Runtime Library Exception along with this program;
23
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24
// <http://www.gnu.org/licenses/>.
25
 
26
#include <debug/debug.h>
27
#include <debug/safe_sequence.h>
28
#include <debug/safe_unordered_container.h>
29
#include <debug/safe_iterator.h>
30
#include <debug/safe_local_iterator.h>
31
#include <algorithm>
32
#include <cassert>
33
#include <cstring>
34
#include <cctype>
35
#include <cstdio>
36
#include <cstdlib>
37
#include <functional>
38
 
39
using namespace std;
40
 
41
namespace
42
{
43
  /** Returns different instances of __mutex depending on the passed address
44
   *  in order to limit contention without breaking current library binary
45
   *  compatibility. */
46
  __gnu_cxx::__mutex&
47
  get_safe_base_mutex(void* __address)
48
  {
49
    const size_t mask = 0xf;
50
    static __gnu_cxx::__mutex safe_base_mutex[mask + 1];
51
    const size_t index = _Hash_impl::hash(__address) & mask;
52
    return safe_base_mutex[index];
53
  }
54
 
55
  void
56
  swap_its(__gnu_debug::_Safe_sequence_base& __lhs,
57
           __gnu_debug::_Safe_iterator_base*& __lhs_its,
58
           __gnu_debug::_Safe_sequence_base& __rhs,
59
           __gnu_debug::_Safe_iterator_base*& __rhs_its)
60
  {
61
    swap(__lhs_its, __rhs_its);
62
    __gnu_debug::_Safe_iterator_base* __iter;
63
    for (__iter = __rhs_its; __iter; __iter = __iter->_M_next)
64
      __iter->_M_sequence = &__rhs;
65
    for (__iter = __lhs_its; __iter; __iter = __iter->_M_next)
66
      __iter->_M_sequence = &__lhs;
67
  }
68
 
69
  void
70
  swap_seq(__gnu_debug::_Safe_sequence_base& __lhs,
71
           __gnu_debug::_Safe_sequence_base& __rhs)
72
  {
73
    swap(__lhs._M_version, __rhs._M_version);
74
    swap_its(__lhs, __lhs._M_iterators,
75
             __rhs, __rhs._M_iterators);
76
    swap_its(__lhs, __lhs._M_const_iterators,
77
             __rhs, __rhs._M_const_iterators);
78
  }
79
 
80
  void
81
  swap_ucont(__gnu_debug::_Safe_unordered_container_base& __lhs,
82
            __gnu_debug::_Safe_unordered_container_base& __rhs)
83
  {
84
    swap_seq(__lhs, __rhs);
85
    swap_its(__lhs, __lhs._M_local_iterators,
86
             __rhs, __rhs._M_local_iterators);
87
    swap_its(__lhs, __lhs._M_const_local_iterators,
88
             __rhs, __rhs._M_const_local_iterators);
89
  }
90
 
91
  void
92
  detach_all(__gnu_debug::_Safe_iterator_base* __iter)
93
  {
94
    for (; __iter;)
95
      {
96
        __gnu_debug::_Safe_iterator_base* __old = __iter;
97
        __iter = __iter->_M_next;
98
        __old->_M_reset();
99
      }
100
  }
101
} // anonymous namespace
102
 
103
namespace __gnu_debug
104
{
105
  const char* _S_debug_messages[] =
106
  {
107
    // General Checks
108
    "function requires a valid iterator range [%1.name;, %2.name;)",
109
    "attempt to insert into container with a singular iterator",
110
    "attempt to insert into container with an iterator"
111
    " from a different container",
112
    "attempt to erase from container with a %2.state; iterator",
113
    "attempt to erase from container with an iterator"
114
    " from a different container",
115
    "attempt to subscript container with out-of-bounds index %2;,"
116
    " but container only holds %3; elements",
117
    "attempt to access an element in an empty container",
118
    "elements in iterator range [%1.name;, %2.name;)"
119
    " are not partitioned by the value %3;",
120
    "elements in iterator range [%1.name;, %2.name;)"
121
    " are not partitioned by the predicate %3; and value %4;",
122
    "elements in iterator range [%1.name;, %2.name;) are not sorted",
123
    "elements in iterator range [%1.name;, %2.name;)"
124
    " are not sorted according to the predicate %3;",
125
    "elements in iterator range [%1.name;, %2.name;) do not form a heap",
126
    "elements in iterator range [%1.name;, %2.name;)"
127
    " do not form a heap with respect to the predicate %3;",
128
    // std::bitset checks
129
    "attempt to write through a singular bitset reference",
130
    "attempt to read from a singular bitset reference",
131
    "attempt to flip a singular bitset reference",
132
    // std::list checks
133
    "attempt to splice a list into itself",
134
    "attempt to splice lists with inequal allocators",
135
    "attempt to splice elements referenced by a %1.state; iterator",
136
    "attempt to splice an iterator from a different container",
137
    "splice destination %1.name;"
138
    " occurs within source range [%2.name;, %3.name;)",
139
    // iterator checks
140
    "attempt to initialize an iterator that will immediately become singular",
141
    "attempt to copy-construct an iterator from a singular iterator",
142
    "attempt to construct a constant iterator"
143
    " from a singular mutable iterator",
144
    "attempt to copy from a singular iterator",
145
    "attempt to dereference a %1.state; iterator",
146
    "attempt to increment a %1.state; iterator",
147
    "attempt to decrement a %1.state; iterator",
148
    "attempt to subscript a %1.state; iterator %2; step from"
149
    " its current position, which falls outside its dereferenceable range",
150
    "attempt to advance a %1.state; iterator %2; steps,"
151
    " which falls outside its valid range",
152
    "attempt to retreat a %1.state; iterator %2; steps,"
153
    " which falls outside its valid range",
154
    "attempt to compare a %1.state; iterator to a %2.state; iterator",
155
    "attempt to compare iterators from different sequences",
156
    "attempt to order a %1.state; iterator to a %2.state; iterator",
157
    "attempt to order iterators from different sequences",
158
    "attempt to compute the difference between a %1.state;"
159
    " iterator to a %2.state; iterator",
160
    "attempt to compute the different between two iterators"
161
    " from different sequences",
162
    // istream_iterator
163
    "attempt to dereference an end-of-stream istream_iterator",
164
    "attempt to increment an end-of-stream istream_iterator",
165
    // ostream_iterator
166
    "attempt to output via an ostream_iterator with no associated stream",
167
    // istreambuf_iterator
168
    "attempt to dereference an end-of-stream istreambuf_iterator"
169
    " (this is a GNU extension)",
170
    "attempt to increment an end-of-stream istreambuf_iterator",
171
    // std::forward_list
172
    "attempt to insert into container after an end iterator",
173
    "attempt to erase from container after a %2.state; iterator not followed"
174
    " by a dereferenceable one",
175
    "function requires a valid iterator range (%2.name;, %3.name;)"
176
    ", \"%2.name;\" shall be before and not equal to \"%3.name;\"",
177
    // std::unordered_container::local_iterator
178
    "attempt to compare local iterators from different unordered container"
179
    " buckets",
180
    "function requires a non-empty iterator range [%1.name;, %2.name;)"
181
  };
182
 
183
  void
184
  _Safe_sequence_base::
185
  _M_detach_all()
186
  {
187
    __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
188
    detach_all(_M_iterators);
189
    _M_iterators = 0;
190
 
191
    detach_all(_M_const_iterators);
192
    _M_const_iterators = 0;
193
  }
194
 
195
  void
196
  _Safe_sequence_base::
197
  _M_detach_singular()
198
  {
199
    __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
200
    for (_Safe_iterator_base* __iter = _M_iterators; __iter;)
201
      {
202
        _Safe_iterator_base* __old = __iter;
203
        __iter = __iter->_M_next;
204
        if (__old->_M_singular())
205
          __old->_M_detach_single();
206
      }
207
 
208
    for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2;)
209
      {
210
        _Safe_iterator_base* __old = __iter2;
211
        __iter2 = __iter2->_M_next;
212
        if (__old->_M_singular())
213
          __old->_M_detach_single();
214
      }
215
  }
216
 
217
  void
218
  _Safe_sequence_base::
219
  _M_revalidate_singular()
220
  {
221
    __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
222
    for (_Safe_iterator_base* __iter = _M_iterators; __iter;
223
         __iter = __iter->_M_next)
224
      __iter->_M_version = _M_version;
225
 
226
    for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2;
227
         __iter2 = __iter2->_M_next)
228
      __iter2->_M_version = _M_version;
229
  }
230
 
231
  void
232
  _Safe_sequence_base::
233
  _M_swap(_Safe_sequence_base& __x)
234
  {
235
    // We need to lock both sequences to swap
236
    using namespace __gnu_cxx;
237
    __mutex *__this_mutex = &_M_get_mutex();
238
    __mutex *__x_mutex = &__x._M_get_mutex();
239
    if (__this_mutex == __x_mutex)
240
      {
241
        __scoped_lock __lock(*__this_mutex);
242
        swap_seq(*this, __x);
243
      }
244
    else
245
      {
246
        __scoped_lock __l1(__this_mutex < __x_mutex
247
                             ? *__this_mutex : *__x_mutex);
248
        __scoped_lock __l2(__this_mutex < __x_mutex
249
                             ? *__x_mutex : *__this_mutex);
250
        swap_seq(*this, __x);
251
      }
252
  }
253
 
254
  __gnu_cxx::__mutex&
255
  _Safe_sequence_base::
256
  _M_get_mutex() throw ()
257
  { return get_safe_base_mutex(this); }
258
 
259
  void
260
  _Safe_sequence_base::
261
  _M_attach(_Safe_iterator_base* __it, bool __constant)
262
  {
263
    __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
264
    _M_attach_single(__it, __constant);
265
  }
266
 
267
  void
268
  _Safe_sequence_base::
269
  _M_attach_single(_Safe_iterator_base* __it, bool __constant) throw ()
270
  {
271
    _Safe_iterator_base*& __its =
272
      __constant ? _M_const_iterators : _M_iterators;
273
    __it->_M_next = __its;
274
    if (__it->_M_next)
275
      __it->_M_next->_M_prior = __it;
276
    __its = __it;
277
  }
278
 
279
  void
280
  _Safe_sequence_base::
281
  _M_detach(_Safe_iterator_base* __it)
282
  {
283
    // Remove __it from this sequence's list
284
    __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
285
    _M_detach_single(__it);
286
  }
287
 
288
  void
289
  _Safe_sequence_base::
290
  _M_detach_single(_Safe_iterator_base* __it) throw ()
291
  {
292
    // Remove __it from this sequence's list
293
    __it->_M_unlink();
294
    if (_M_const_iterators == __it)
295
      _M_const_iterators = __it->_M_next;
296
    if (_M_iterators == __it)
297
      _M_iterators = __it->_M_next;
298
  }
299
 
300
  void
301
  _Safe_iterator_base::
302
  _M_attach(_Safe_sequence_base* __seq, bool __constant)
303
  {
304
    _M_detach();
305
 
306
    // Attach to the new sequence (if there is one)
307
    if (__seq)
308
      {
309
        _M_sequence = __seq;
310
        _M_version = _M_sequence->_M_version;
311
        _M_sequence->_M_attach(this, __constant);
312
      }
313
  }
314
 
315
  void
316
  _Safe_iterator_base::
317
  _M_attach_single(_Safe_sequence_base* __seq, bool __constant) throw ()
318
  {
319
    _M_detach_single();
320
 
321
    // Attach to the new sequence (if there is one)
322
    if (__seq)
323
      {
324
        _M_sequence = __seq;
325
        _M_version = _M_sequence->_M_version;
326
        _M_sequence->_M_attach_single(this, __constant);
327
      }
328
  }
329
 
330
  void
331
  _Safe_iterator_base::
332
  _M_detach()
333
  {
334
    if (_M_sequence)
335
      _M_sequence->_M_detach(this);
336
 
337
    _M_reset();
338
  }
339
 
340
  void
341
  _Safe_iterator_base::
342
  _M_detach_single() throw ()
343
  {
344
    if (_M_sequence)
345
      _M_sequence->_M_detach_single(this);
346
 
347
    _M_reset();
348
  }
349
 
350
  void
351
  _Safe_iterator_base::
352
  _M_reset() throw ()
353
  {
354
    _M_sequence = 0;
355
    _M_version = 0;
356
    _M_prior = 0;
357
    _M_next = 0;
358
  }
359
 
360
  bool
361
  _Safe_iterator_base::
362
  _M_singular() const throw ()
363
  { return !_M_sequence || _M_version != _M_sequence->_M_version; }
364
 
365
  bool
366
  _Safe_iterator_base::
367
  _M_can_compare(const _Safe_iterator_base& __x) const throw ()
368
  {
369
    return (!_M_singular()
370
            && !__x._M_singular() && _M_sequence == __x._M_sequence);
371
  }
372
 
373
  __gnu_cxx::__mutex&
374
  _Safe_iterator_base::
375
  _M_get_mutex() throw ()
376
  { return get_safe_base_mutex(_M_sequence); }
377
 
378
  _Safe_unordered_container_base*
379
  _Safe_local_iterator_base::
380
  _M_get_container() const _GLIBCXX_NOEXCEPT
381
  { return static_cast<_Safe_unordered_container_base*>(_M_sequence); }
382
 
383
  void
384
  _Safe_local_iterator_base::
385
  _M_attach(_Safe_sequence_base* __cont, bool __constant)
386
  {
387
    _M_detach();
388
 
389
    // Attach to the new container (if there is one)
390
    if (__cont)
391
      {
392
        _M_sequence = __cont;
393
        _M_version = _M_sequence->_M_version;
394
        _M_get_container()->_M_attach_local(this, __constant);
395
      }
396
  }
397
 
398
  void
399
  _Safe_local_iterator_base::
400
  _M_attach_single(_Safe_sequence_base* __cont, bool __constant) throw ()
401
  {
402
    _M_detach_single();
403
 
404
    // Attach to the new container (if there is one)
405
    if (__cont)
406
      {
407
        _M_sequence = __cont;
408
        _M_version = _M_sequence->_M_version;
409
        _M_get_container()->_M_attach_local_single(this, __constant);
410
      }
411
  }
412
 
413
  void
414
  _Safe_local_iterator_base::
415
  _M_detach()
416
  {
417
    if (_M_sequence)
418
      _M_get_container()->_M_detach_local(this);
419
 
420
    _M_reset();
421
  }
422
 
423
  void
424
  _Safe_local_iterator_base::
425
  _M_detach_single() throw ()
426
  {
427
    if (_M_sequence)
428
      _M_get_container()->_M_detach_local_single(this);
429
 
430
    _M_reset();
431
  }
432
 
433
  void
434
  _Safe_unordered_container_base::
435
  _M_detach_all()
436
  {
437
    __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
438
    detach_all(_M_iterators);
439
    _M_iterators = 0;
440
 
441
    detach_all(_M_const_iterators);
442
    _M_const_iterators = 0;
443
 
444
    detach_all(_M_local_iterators);
445
    _M_local_iterators = 0;
446
 
447
    detach_all(_M_const_local_iterators);
448
    _M_const_local_iterators = 0;
449
  }
450
 
451
  void
452
  _Safe_unordered_container_base::
453
  _M_swap(_Safe_unordered_container_base& __x)
454
  {
455
    // We need to lock both containers to swap
456
    using namespace __gnu_cxx;
457
    __mutex *__this_mutex = &_M_get_mutex();
458
    __mutex *__x_mutex = &__x._M_get_mutex();
459
    if (__this_mutex == __x_mutex)
460
      {
461
        __scoped_lock __lock(*__this_mutex);
462
        swap_ucont(*this, __x);
463
      }
464
    else
465
      {
466
        __scoped_lock __l1(__this_mutex < __x_mutex
467
                             ? *__this_mutex : *__x_mutex);
468
        __scoped_lock __l2(__this_mutex < __x_mutex
469
                             ? *__x_mutex : *__this_mutex);
470
        swap_ucont(*this, __x);
471
      }
472
  }
473
 
474
  void
475
  _Safe_unordered_container_base::
476
  _M_attach_local(_Safe_iterator_base* __it, bool __constant)
477
  {
478
    __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
479
    _M_attach_local_single(__it, __constant);
480
  }
481
 
482
  void
483
  _Safe_unordered_container_base::
484
  _M_attach_local_single(_Safe_iterator_base* __it, bool __constant) throw ()
485
  {
486
    _Safe_iterator_base*& __its =
487
      __constant ? _M_const_local_iterators : _M_local_iterators;
488
    __it->_M_next = __its;
489
    if (__it->_M_next)
490
      __it->_M_next->_M_prior = __it;
491
    __its = __it;
492
  }
493
 
494
  void
495
  _Safe_unordered_container_base::
496
  _M_detach_local(_Safe_iterator_base* __it)
497
  {
498
    // Remove __it from this container's list
499
    __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
500
    _M_detach_local_single(__it);
501
  }
502
 
503
  void
504
  _Safe_unordered_container_base::
505
  _M_detach_local_single(_Safe_iterator_base* __it) throw ()
506
  {
507
    // Remove __it from this container's list
508
    __it->_M_unlink();
509
    if (_M_const_local_iterators == __it)
510
      _M_const_local_iterators = __it->_M_next;
511
    if (_M_local_iterators == __it)
512
      _M_local_iterators = __it->_M_next;
513
  }
514
 
515
  void
516
  _Error_formatter::_Parameter::
517
  _M_print_field(const _Error_formatter* __formatter, const char* __name) const
518
  {
519
    assert(this->_M_kind != _Parameter::__unused_param);
520
    const int __bufsize = 64;
521
    char __buf[__bufsize];
522
 
523
    if (_M_kind == __iterator)
524
      {
525
        if (strcmp(__name, "name") == 0)
526
          {
527
            assert(_M_variant._M_iterator._M_name);
528
            __formatter->_M_print_word(_M_variant._M_iterator._M_name);
529
          }
530
        else if (strcmp(__name, "address") == 0)
531
          {
532
            __formatter->_M_format_word(__buf, __bufsize, "%p",
533
                                        _M_variant._M_iterator._M_address);
534
            __formatter->_M_print_word(__buf);
535
          }
536
        else if (strcmp(__name, "type") == 0)
537
          {
538
            if (!_M_variant._M_iterator._M_type)
539
              __formatter->_M_print_word("<unknown type>");
540
            else
541
              // TBD: demangle!
542
              __formatter->_M_print_word(_M_variant._M_iterator.
543
                                         _M_type->name());
544
          }
545
        else if (strcmp(__name, "constness") == 0)
546
          {
547
            static const char* __constness_names[__last_constness] =
548
              {
549
                "<unknown>",
550
                "constant",
551
                "mutable"
552
              };
553
            __formatter->_M_print_word(__constness_names[_M_variant.
554
                                                         _M_iterator.
555
                                                         _M_constness]);
556
          }
557
        else if (strcmp(__name, "state") == 0)
558
          {
559
            static const char* __state_names[__last_state] =
560
              {
561
                "<unknown>",
562
                "singular",
563
                "dereferenceable (start-of-sequence)",
564
                "dereferenceable",
565
                "past-the-end",
566
                "before-begin"
567
              };
568
            __formatter->_M_print_word(__state_names[_M_variant.
569
                                                     _M_iterator._M_state]);
570
          }
571
        else if (strcmp(__name, "sequence") == 0)
572
          {
573
            assert(_M_variant._M_iterator._M_sequence);
574
            __formatter->_M_format_word(__buf, __bufsize, "%p",
575
                                        _M_variant._M_iterator._M_sequence);
576
            __formatter->_M_print_word(__buf);
577
          }
578
        else if (strcmp(__name, "seq_type") == 0)
579
          {
580
            if (!_M_variant._M_iterator._M_seq_type)
581
              __formatter->_M_print_word("<unknown seq_type>");
582
            else
583
              // TBD: demangle!
584
              __formatter->_M_print_word(_M_variant._M_iterator.
585
                                         _M_seq_type->name());
586
          }
587
        else
588
          assert(false);
589
      }
590
    else if (_M_kind == __sequence)
591
      {
592
        if (strcmp(__name, "name") == 0)
593
          {
594
            assert(_M_variant._M_sequence._M_name);
595
            __formatter->_M_print_word(_M_variant._M_sequence._M_name);
596
          }
597
        else if (strcmp(__name, "address") == 0)
598
          {
599
            assert(_M_variant._M_sequence._M_address);
600
            __formatter->_M_format_word(__buf, __bufsize, "%p",
601
                                        _M_variant._M_sequence._M_address);
602
            __formatter->_M_print_word(__buf);
603
          }
604
        else if (strcmp(__name, "type") == 0)
605
          {
606
            if (!_M_variant._M_sequence._M_type)
607
              __formatter->_M_print_word("<unknown type>");
608
            else
609
              // TBD: demangle!
610
              __formatter->_M_print_word(_M_variant._M_sequence.
611
                                         _M_type->name());
612
          }
613
        else
614
          assert(false);
615
      }
616
    else if (_M_kind == __integer)
617
      {
618
        if (strcmp(__name, "name") == 0)
619
          {
620
            assert(_M_variant._M_integer._M_name);
621
            __formatter->_M_print_word(_M_variant._M_integer._M_name);
622
          }
623
        else
624
        assert(false);
625
      }
626
    else if (_M_kind == __string)
627
      {
628
        if (strcmp(__name, "name") == 0)
629
          {
630
            assert(_M_variant._M_string._M_name);
631
            __formatter->_M_print_word(_M_variant._M_string._M_name);
632
          }
633
        else
634
          assert(false);
635
      }
636
    else
637
      {
638
        assert(false);
639
      }
640
  }
641
 
642
  void
643
  _Error_formatter::_Parameter::
644
  _M_print_description(const _Error_formatter* __formatter) const
645
  {
646
    const int __bufsize = 128;
647
    char __buf[__bufsize];
648
 
649
    if (_M_kind == __iterator)
650
      {
651
        __formatter->_M_print_word("iterator ");
652
        if (_M_variant._M_iterator._M_name)
653
          {
654
            __formatter->_M_format_word(__buf, __bufsize, "\"%s\" ",
655
                                        _M_variant._M_iterator._M_name);
656
            __formatter->_M_print_word(__buf);
657
          }
658
 
659
        __formatter->_M_format_word(__buf, __bufsize, "@ 0x%p {\n",
660
                                    _M_variant._M_iterator._M_address);
661
        __formatter->_M_print_word(__buf);
662
        if (_M_variant._M_iterator._M_type)
663
          {
664
            __formatter->_M_print_word("type = ");
665
            _M_print_field(__formatter, "type");
666
 
667
            if (_M_variant._M_iterator._M_constness != __unknown_constness)
668
              {
669
                __formatter->_M_print_word(" (");
670
                _M_print_field(__formatter, "constness");
671
                __formatter->_M_print_word(" iterator)");
672
              }
673
            __formatter->_M_print_word(";\n");
674
          }
675
 
676
        if (_M_variant._M_iterator._M_state != __unknown_state)
677
          {
678
            __formatter->_M_print_word("  state = ");
679
            _M_print_field(__formatter, "state");
680
            __formatter->_M_print_word(";\n");
681
          }
682
 
683
        if (_M_variant._M_iterator._M_sequence)
684
          {
685
            __formatter->_M_print_word("  references sequence ");
686
            if (_M_variant._M_iterator._M_seq_type)
687
              {
688
                __formatter->_M_print_word("with type `");
689
                _M_print_field(__formatter, "seq_type");
690
                __formatter->_M_print_word("' ");
691
              }
692
 
693
            __formatter->_M_format_word(__buf, __bufsize, "@ 0x%p\n",
694
                                        _M_variant._M_sequence._M_address);
695
            __formatter->_M_print_word(__buf);
696
          }
697
        __formatter->_M_print_word("}\n");
698
      }
699
    else if (_M_kind == __sequence)
700
      {
701
        __formatter->_M_print_word("sequence ");
702
        if (_M_variant._M_sequence._M_name)
703
          {
704
            __formatter->_M_format_word(__buf, __bufsize, "\"%s\" ",
705
                                        _M_variant._M_sequence._M_name);
706
            __formatter->_M_print_word(__buf);
707
          }
708
 
709
        __formatter->_M_format_word(__buf, __bufsize, "@ 0x%p {\n",
710
                                    _M_variant._M_sequence._M_address);
711
        __formatter->_M_print_word(__buf);
712
 
713
        if (_M_variant._M_sequence._M_type)
714
          {
715
            __formatter->_M_print_word("  type = ");
716
            _M_print_field(__formatter, "type");
717
            __formatter->_M_print_word(";\n");
718
          }
719
        __formatter->_M_print_word("}\n");
720
      }
721
  }
722
 
723
  const _Error_formatter&
724
  _Error_formatter::_M_message(_Debug_msg_id __id) const throw ()
725
  { return this->_M_message(_S_debug_messages[__id]); }
726
 
727
  void
728
  _Error_formatter::_M_error() const
729
  {
730
    const int __bufsize = 128;
731
    char __buf[__bufsize];
732
 
733
    // Emit file & line number information
734
    _M_column = 1;
735
    _M_wordwrap = false;
736
    if (_M_file)
737
      {
738
        _M_format_word(__buf, __bufsize, "%s:", _M_file);
739
        _M_print_word(__buf);
740
        _M_column += strlen(__buf);
741
      }
742
 
743
    if (_M_line > 0)
744
      {
745
        _M_format_word(__buf, __bufsize, "%u:", _M_line);
746
        _M_print_word(__buf);
747
        _M_column += strlen(__buf);
748
      }
749
 
750
    if (_M_max_length)
751
      _M_wordwrap = true;
752
    _M_print_word("error: ");
753
 
754
    // Print the error message
755
    assert(_M_text);
756
    _M_print_string(_M_text);
757
    _M_print_word(".\n");
758
 
759
    // Emit descriptions of the objects involved in the operation
760
    _M_wordwrap = false;
761
    bool __has_noninteger_parameters = false;
762
    for (unsigned int __i = 0; __i < _M_num_parameters; ++__i)
763
      {
764
        if (_M_parameters[__i]._M_kind == _Parameter::__iterator
765
            || _M_parameters[__i]._M_kind == _Parameter::__sequence)
766
          {
767
            if (!__has_noninteger_parameters)
768
              {
769
                _M_first_line = true;
770
                _M_print_word("\nObjects involved in the operation:\n");
771
                __has_noninteger_parameters = true;
772
              }
773
            _M_parameters[__i]._M_print_description(this);
774
          }
775
      }
776
 
777
    abort();
778
  }
779
 
780
  template<typename _Tp>
781
    void
782
    _Error_formatter::_M_format_word(char* __buf,
783
                                     int __n __attribute__ ((__unused__)),
784
                                     const char* __fmt, _Tp __s) const throw ()
785
    {
786
#ifdef _GLIBCXX_USE_C99
787
      std::snprintf(__buf, __n, __fmt, __s);
788
#else
789
      std::sprintf(__buf, __fmt, __s);
790
#endif
791
    }
792
 
793
 
794
  void
795
  _Error_formatter::_M_print_word(const char* __word) const
796
  {
797
    if (!_M_wordwrap)
798
      {
799
        fprintf(stderr, "%s", __word);
800
        return;
801
      }
802
 
803
    size_t __length = strlen(__word);
804
    if (__length == 0)
805
      return;
806
 
807
    if ((_M_column + __length < _M_max_length)
808
        || (__length >= _M_max_length && _M_column == 1))
809
      {
810
        // If this isn't the first line, indent
811
        if (_M_column == 1 && !_M_first_line)
812
          {
813
            char __spacing[_M_indent + 1];
814
            for (int i = 0; i < _M_indent; ++i)
815
              __spacing[i] = ' ';
816
            __spacing[_M_indent] = '\0';
817
            fprintf(stderr, "%s", __spacing);
818
            _M_column += _M_indent;
819
          }
820
 
821
        fprintf(stderr, "%s", __word);
822
        _M_column += __length;
823
 
824
        if (__word[__length - 1] == '\n')
825
          {
826
            _M_first_line = false;
827
            _M_column = 1;
828
          }
829
      }
830
    else
831
      {
832
        _M_column = 1;
833
        _M_print_word("\n");
834
        _M_print_word(__word);
835
      }
836
  }
837
 
838
  void
839
  _Error_formatter::
840
  _M_print_string(const char* __string) const
841
  {
842
    const char* __start = __string;
843
    const char* __finish = __start;
844
    const int __bufsize = 128;
845
    char __buf[__bufsize];
846
 
847
    while (*__start)
848
      {
849
        if (*__start != '%')
850
          {
851
            // [__start, __finish) denotes the next word
852
            __finish = __start;
853
            while (isalnum(*__finish))
854
              ++__finish;
855
            if (__start == __finish)
856
              ++__finish;
857
            if (isspace(*__finish))
858
              ++__finish;
859
 
860
            const ptrdiff_t __len = __finish - __start;
861
            assert(__len < __bufsize);
862
            memcpy(__buf, __start, __len);
863
            __buf[__len] = '\0';
864
            _M_print_word(__buf);
865
            __start = __finish;
866
 
867
            // Skip extra whitespace
868
            while (*__start == ' ')
869
              ++__start;
870
 
871
            continue;
872
          }
873
 
874
        ++__start;
875
        assert(*__start);
876
        if (*__start == '%')
877
          {
878
            _M_print_word("%");
879
            ++__start;
880
            continue;
881
          }
882
 
883
        // Get the parameter number
884
        assert(*__start >= '1' && *__start <= '9');
885
        size_t __param = *__start - '0';
886
        --__param;
887
        assert(__param < _M_num_parameters);
888
 
889
        // '.' separates the parameter number from the field
890
        // name, if there is one.
891
        ++__start;
892
        if (*__start != '.')
893
          {
894
            assert(*__start == ';');
895
            ++__start;
896
            __buf[0] = '\0';
897
            if (_M_parameters[__param]._M_kind == _Parameter::__integer)
898
              {
899
                _M_format_word(__buf, __bufsize, "%ld",
900
                               _M_parameters[__param]._M_variant._M_integer._M_value);
901
                _M_print_word(__buf);
902
              }
903
            else if (_M_parameters[__param]._M_kind == _Parameter::__string)
904
              _M_print_string(_M_parameters[__param]._M_variant._M_string._M_value);
905
            continue;
906
          }
907
 
908
        // Extract the field name we want
909
        enum { __max_field_len = 16 };
910
        char __field[__max_field_len];
911
        int __field_idx = 0;
912
        ++__start;
913
        while (*__start != ';')
914
          {
915
            assert(*__start);
916
            assert(__field_idx < __max_field_len-1);
917
            __field[__field_idx++] = *__start++;
918
          }
919
        ++__start;
920
        __field[__field_idx] = 0;
921
 
922
        _M_parameters[__param]._M_print_field(this, __field);
923
      }
924
  }
925
 
926
  void
927
  _Error_formatter::_M_get_max_length() const throw ()
928
  {
929
    const char* __nptr = std::getenv("GLIBCXX_DEBUG_MESSAGE_LENGTH");
930
    if (__nptr)
931
      {
932
        char* __endptr;
933
        const unsigned long __ret = std::strtoul(__nptr, &__endptr, 0);
934
        if (*__nptr != '\0' && *__endptr == '\0')
935
          _M_max_length = __ret;
936
      }
937
  }
938
 
939
  // Instantiations.
940
  template
941
    void
942
    _Error_formatter::_M_format_word(char*, int, const char*,
943
                                     const void*) const;
944
 
945
  template
946
    void
947
    _Error_formatter::_M_format_word(char*, int, const char*, long) const;
948
 
949
  template
950
    void
951
    _Error_formatter::_M_format_word(char*, int, const char*,
952
                                     std::size_t) const;
953
 
954
  template
955
    void
956
    _Error_formatter::_M_format_word(char*, int, const char*,
957
                                     const char*) const;
958
} // namespace __gnu_debug

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.