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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libstdc++-v3/] [src/] [debug.cc] - Blame information for rev 18

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 18 jlechner
// Debugging mode support code -*- C++ -*-
2
 
3
// Copyright (C) 2003, 2004, 2005
4
// 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 2, 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
// You should have received a copy of the GNU General Public License along
18
// with this library; see the file COPYING.  If not, write to the Free
19
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20
// USA.
21
 
22
// As a special exception, you may use this file as part of a free software
23
// library without restriction.  Specifically, if other files instantiate
24
// templates or use macros or inline functions from this file, or you compile
25
// this file and link it with other files to produce an executable, this
26
// file does not by itself cause the resulting executable to be covered by
27
// the GNU General Public License.  This exception does not however
28
// invalidate any other reasons why the executable file might be covered by
29
// the GNU General Public License.
30
 
31
#include <debug/debug.h>
32
#include <debug/safe_sequence.h>
33
#include <debug/safe_iterator.h>
34
#include <algorithm>
35
#include <cassert>
36
#include <cstring>
37
#include <cctype>
38
#include <bits/concurrence.h>
39
 
40
using namespace std;
41
 
42
namespace __gnu_internal
43
{
44
  static __glibcxx_mutex_define_initialized(iterator_base_mutex);
45
} // namespace __gnu_internal
46
 
47
namespace __gnu_debug
48
{
49
  const char* _S_debug_messages[] =
50
  {
51
    "function requires a valid iterator range [%1.name;, %2.name;)",
52
    "attempt to insert into container with a singular iterator",
53
    "attempt to insert into container with an iterator"
54
    " from a different container",
55
    "attempt to erase from container with a %2.state; iterator",
56
    "attempt to erase from container with an iterator"
57
    " from a different container",
58
    "attempt to subscript container with out-of-bounds index %2;,"
59
    " but container only holds %3; elements",
60
    "attempt to access an element in an empty container",
61
    "elements in iterator range [%1.name;, %2.name;)"
62
    " are not partitioned by the value %3;",
63
    "elements in iterator range [%1.name;, %2.name;)"
64
    " are not partitioned by the predicate %3; and value %4;",
65
    "elements in iterator range [%1.name;, %2.name;) are not sorted",
66
    "elements in iterator range [%1.name;, %2.name;)"
67
    " are not sorted according to the predicate %3;",
68
    "elements in iterator range [%1.name;, %2.name;) do not form a heap",
69
    "elements in iterator range [%1.name;, %2.name;)"
70
    " do not form a heap with respect to the predicate %3;",
71
    "attempt to write through a singular bitset reference",
72
    "attempt to read from a singular bitset reference",
73
    "attempt to flip a singular bitset reference",
74
    "attempt to splice a list into itself",
75
    "attempt to splice lists with inequal allocators",
76
    "attempt to splice elements referenced by a %1.state; iterator",
77
    "attempt to splice an iterator from a different container",
78
    "splice destination %1.name;"
79
    " occurs within source range [%2.name;, %3.name;)",
80
    "attempt to initialize an iterator that will immediately become singular",
81
    "attempt to copy-construct an iterator from a singular iterator",
82
    "attempt to construct a constant iterator"
83
    " from a singular mutable iterator",
84
    "attempt to copy from a singular iterator",
85
    "attempt to dereference a %1.state; iterator",
86
    "attempt to increment a %1.state; iterator",
87
    "attempt to decrement a %1.state; iterator",
88
    "attempt to subscript a %1.state; iterator %2; step from"
89
    " its current position, which falls outside its dereferenceable range",
90
    "attempt to advance a %1.state; iterator %2; steps,"
91
    " which falls outside its valid range",
92
    "attempt to retreat a %1.state; iterator %2; steps,"
93
    " which falls outside its valid range",
94
    "attempt to compare a %1.state; iterator to a %2.state; iterator",
95
    "attempt to compare iterators from different sequences",
96
    "attempt to order a %1.state; iterator to a %2.state; iterator",
97
    "attempt to order iterators from different sequences",
98
    "attempt to compute the difference between a %1.state;"
99
    " iterator to a %2.state; iterator",
100
    "attempt to compute the different between two iterators"
101
    " from different sequences",
102
    "attempt to dereference an end-of-stream istream_iterator",
103
    "attempt to increment an end-of-stream istream_iterator",
104
    "attempt to output via an ostream_iterator with no associated stream",
105
    "attempt to dereference an end-of-stream istreambuf_iterator"
106
    " (this is a GNU extension)",
107
    "attempt to increment an end-of-stream istreambuf_iterator"
108
  };
109
 
110
  void
111
  _Safe_sequence_base::
112
  _M_detach_all()
113
  {
114
    for (_Safe_iterator_base* __iter = _M_iterators; __iter; )
115
      {
116
        _Safe_iterator_base* __old = __iter;
117
        __iter = __iter->_M_next;
118
        __old->_M_attach(0, false);
119
      }
120
 
121
    for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2; )
122
      {
123
        _Safe_iterator_base* __old = __iter2;
124
        __iter2 = __iter2->_M_next;
125
        __old->_M_attach(0, true);
126
      }
127
  }
128
 
129
  void
130
  _Safe_sequence_base::
131
  _M_detach_singular()
132
  {
133
    for (_Safe_iterator_base* __iter = _M_iterators; __iter; )
134
      {
135
        _Safe_iterator_base* __old = __iter;
136
        __iter = __iter->_M_next;
137
        if (__old->_M_singular())
138
          __old->_M_attach(0, false);
139
      }
140
 
141
    for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2; )
142
      {
143
        _Safe_iterator_base* __old = __iter2;
144
        __iter2 = __iter2->_M_next;
145
        if (__old->_M_singular())
146
          __old->_M_attach(0, true);
147
      }
148
  }
149
 
150
  void
151
  _Safe_sequence_base::
152
  _M_revalidate_singular()
153
  {
154
    _Safe_iterator_base* __iter;
155
    for (__iter = _M_iterators; __iter; __iter = __iter->_M_next)
156
      {
157
        __iter->_M_version = _M_version;
158
        __iter = __iter->_M_next;
159
      }
160
 
161
    for (__iter = _M_const_iterators; __iter; __iter = __iter->_M_next)
162
      {
163
        __iter->_M_version = _M_version;
164
        __iter = __iter->_M_next;
165
      }
166
  }
167
 
168
  void
169
  _Safe_sequence_base::
170
  _M_swap(_Safe_sequence_base& __x)
171
  {
172
    swap(_M_iterators, __x._M_iterators);
173
    swap(_M_const_iterators, __x._M_const_iterators);
174
    swap(_M_version, __x._M_version);
175
    _Safe_iterator_base* __iter;
176
    for (__iter = _M_iterators; __iter; __iter = __iter->_M_next)
177
      __iter->_M_sequence = this;
178
    for (__iter = __x._M_iterators; __iter; __iter = __iter->_M_next)
179
      __iter->_M_sequence = &__x;
180
    for (__iter = _M_const_iterators; __iter; __iter = __iter->_M_next)
181
      __iter->_M_sequence = this;
182
    for (__iter = __x._M_const_iterators; __iter; __iter = __iter->_M_next)
183
      __iter->_M_sequence = &__x;
184
  }
185
 
186
  void
187
  _Safe_iterator_base::
188
  _M_attach(_Safe_sequence_base* __seq, bool __constant)
189
  {
190
    _M_detach();
191
 
192
    // Attach to the new sequence (if there is one)
193
    if (__seq)
194
      {
195
        __gnu_cxx::lock sentry(__gnu_internal::iterator_base_mutex);
196
        _M_sequence = __seq;
197
        _M_version = _M_sequence->_M_version;
198
        _M_prior = 0;
199
        if (__constant)
200
          {
201
            _M_next = _M_sequence->_M_const_iterators;
202
            if (_M_next)
203
              _M_next->_M_prior = this;
204
            _M_sequence->_M_const_iterators = this;
205
          }
206
        else
207
          {
208
            _M_next = _M_sequence->_M_iterators;
209
            if (_M_next)
210
              _M_next->_M_prior = this;
211
            _M_sequence->_M_iterators = this;
212
          }
213
      }
214
  }
215
 
216
  void
217
  _Safe_iterator_base::
218
  _M_detach()
219
  {
220
    __gnu_cxx::lock sentry(__gnu_internal::iterator_base_mutex);
221
    if (_M_sequence)
222
      {
223
        // Remove us from this sequence's list
224
        if (_M_prior)
225
          _M_prior->_M_next = _M_next;
226
        if (_M_next)
227
          _M_next->_M_prior = _M_prior;
228
 
229
        if (_M_sequence->_M_const_iterators == this)
230
          _M_sequence->_M_const_iterators = _M_next;
231
        if (_M_sequence->_M_iterators == this)
232
          _M_sequence->_M_iterators = _M_next;
233
      }
234
 
235
    _M_sequence = 0;
236
    _M_version = 0;
237
    _M_prior = 0;
238
    _M_next = 0;
239
  }
240
 
241
  bool
242
  _Safe_iterator_base::
243
  _M_singular() const
244
  { return !_M_sequence || _M_version != _M_sequence->_M_version; }
245
 
246
  bool
247
  _Safe_iterator_base::
248
  _M_can_compare(const _Safe_iterator_base& __x) const
249
  {
250
    return (!_M_singular() && !__x._M_singular()
251
            && _M_sequence == __x._M_sequence);
252
  }
253
 
254
  void
255
  _Error_formatter::_Parameter::
256
  _M_print_field(const _Error_formatter* __formatter, const char* __name) const
257
  {
258
    assert(this->_M_kind != _Parameter::__unused_param);
259
    const int __bufsize = 64;
260
    char __buf[__bufsize];
261
 
262
    if (_M_kind == __iterator)
263
      {
264
        if (strcmp(__name, "name") == 0)
265
          {
266
            assert(_M_variant._M_iterator._M_name);
267
            __formatter->_M_print_word(_M_variant._M_iterator._M_name);
268
          }
269
        else if (strcmp(__name, "address") == 0)
270
          {
271
            __formatter->_M_format_word(__buf, __bufsize, "%p",
272
                                        _M_variant._M_iterator._M_address);
273
            __formatter->_M_print_word(__buf);
274
          }
275
        else if (strcmp(__name, "type") == 0)
276
          {
277
            assert(_M_variant._M_iterator._M_type);
278
            // TBD: demangle!
279
            __formatter->_M_print_word(_M_variant._M_iterator._M_type->name());
280
          }
281
        else if (strcmp(__name, "constness") == 0)
282
          {
283
            static const char* __constness_names[__last_constness] =
284
              {
285
                "<unknown>",
286
                "constant",
287
                "mutable"
288
              };
289
            __formatter->_M_print_word(__constness_names[_M_variant._M_iterator._M_constness]);
290
          }
291
        else if (strcmp(__name, "state") == 0)
292
          {
293
            static const char* __state_names[__last_state] =
294
              {
295
                "<unknown>",
296
                "singular",
297
                "dereferenceable (start-of-sequence)",
298
                "dereferenceable",
299
                "past-the-end"
300
              };
301
            __formatter->_M_print_word(__state_names[_M_variant._M_iterator._M_state]);
302
          }
303
        else if (strcmp(__name, "sequence") == 0)
304
          {
305
            assert(_M_variant._M_iterator._M_sequence);
306
            __formatter->_M_format_word(__buf, __bufsize, "%p",
307
                                        _M_variant._M_iterator._M_sequence);
308
            __formatter->_M_print_word(__buf);
309
          }
310
        else if (strcmp(__name, "seq_type") == 0)
311
          {
312
            // TBD: demangle!
313
            assert(_M_variant._M_iterator._M_seq_type);
314
            __formatter->_M_print_word(_M_variant._M_iterator._M_seq_type->name());
315
          }
316
        else
317
          assert(false);
318
      }
319
    else if (_M_kind == __sequence)
320
      {
321
        if (strcmp(__name, "name") == 0)
322
          {
323
            assert(_M_variant._M_sequence._M_name);
324
            __formatter->_M_print_word(_M_variant._M_sequence._M_name);
325
          }
326
        else if (strcmp(__name, "address") == 0)
327
          {
328
            assert(_M_variant._M_sequence._M_address);
329
            __formatter->_M_format_word(__buf, __bufsize, "%p",
330
                                        _M_variant._M_sequence._M_address);
331
            __formatter->_M_print_word(__buf);
332
          }
333
        else if (strcmp(__name, "type") == 0)
334
          {
335
            // TBD: demangle!
336
            assert(_M_variant._M_sequence._M_type);
337
            __formatter->_M_print_word(_M_variant._M_sequence._M_type->name());
338
          }
339
        else
340
          assert(false);
341
      }
342
    else if (_M_kind == __integer)
343
      {
344
        if (strcmp(__name, "name") == 0)
345
          {
346
            assert(_M_variant._M_integer._M_name);
347
            __formatter->_M_print_word(_M_variant._M_integer._M_name);
348
          }
349
        else
350
        assert(false);
351
      }
352
    else if (_M_kind == __string)
353
      {
354
        if (strcmp(__name, "name") == 0)
355
          {
356
            assert(_M_variant._M_string._M_name);
357
            __formatter->_M_print_word(_M_variant._M_string._M_name);
358
          }
359
        else
360
          assert(false);
361
      }
362
    else
363
      {
364
        assert(false);
365
      }
366
  }
367
 
368
  void
369
  _Error_formatter::_Parameter::
370
  _M_print_description(const _Error_formatter* __formatter) const
371
  {
372
    const int __bufsize = 128;
373
    char __buf[__bufsize];
374
 
375
    if (_M_kind == __iterator)
376
      {
377
        __formatter->_M_print_word("iterator ");
378
        if (_M_variant._M_iterator._M_name)
379
          {
380
            __formatter->_M_format_word(__buf, __bufsize, "\"%s\" ",
381
                                        _M_variant._M_iterator._M_name);
382
            __formatter->_M_print_word(__buf);
383
          }
384
 
385
        __formatter->_M_format_word(__buf, __bufsize, "@ 0x%p {\n",
386
                                    _M_variant._M_iterator._M_address);
387
        __formatter->_M_print_word(__buf);
388
        if (_M_variant._M_iterator._M_type)
389
          {
390
            __formatter->_M_print_word("type = ");
391
            _M_print_field(__formatter, "type");
392
 
393
            if (_M_variant._M_iterator._M_constness != __unknown_constness)
394
              {
395
                __formatter->_M_print_word(" (");
396
                _M_print_field(__formatter, "constness");
397
                __formatter->_M_print_word(" iterator)");
398
              }
399
            __formatter->_M_print_word(";\n");
400
          }
401
 
402
        if (_M_variant._M_iterator._M_state != __unknown_state)
403
          {
404
            __formatter->_M_print_word("  state = ");
405
            _M_print_field(__formatter, "state");
406
            __formatter->_M_print_word(";\n");
407
          }
408
 
409
        if (_M_variant._M_iterator._M_sequence)
410
          {
411
            __formatter->_M_print_word("  references sequence ");
412
            if (_M_variant._M_iterator._M_seq_type)
413
              {
414
                __formatter->_M_print_word("with type `");
415
                _M_print_field(__formatter, "seq_type");
416
                __formatter->_M_print_word("' ");
417
              }
418
 
419
            __formatter->_M_format_word(__buf, __bufsize, "@ 0x%p\n",
420
                                        _M_variant._M_sequence._M_address);
421
            __formatter->_M_print_word(__buf);
422
          }
423
        __formatter->_M_print_word("}\n");
424
      }
425
    else if (_M_kind == __sequence)
426
      {
427
        __formatter->_M_print_word("sequence ");
428
        if (_M_variant._M_sequence._M_name)
429
          {
430
            __formatter->_M_format_word(__buf, __bufsize, "\"%s\" ",
431
                                        _M_variant._M_sequence._M_name);
432
            __formatter->_M_print_word(__buf);
433
          }
434
 
435
        __formatter->_M_format_word(__buf, __bufsize, "@ 0x%p {\n",
436
                                    _M_variant._M_sequence._M_address);
437
        __formatter->_M_print_word(__buf);
438
 
439
        if (_M_variant._M_sequence._M_type)
440
          {
441
            __formatter->_M_print_word("  type = ");
442
            _M_print_field(__formatter, "type");
443
            __formatter->_M_print_word(";\n");
444
          }
445
        __formatter->_M_print_word("}\n");
446
      }
447
  }
448
 
449
  const _Error_formatter&
450
  _Error_formatter::_M_message(_Debug_msg_id __id) const
451
  { return this->_M_message(_S_debug_messages[__id]); }
452
 
453
  void
454
  _Error_formatter::_M_error() const
455
  {
456
    const int __bufsize = 128;
457
    char __buf[__bufsize];
458
 
459
    // Emit file & line number information
460
    _M_column = 1;
461
    _M_wordwrap = false;
462
    if (_M_file)
463
      {
464
        _M_format_word(__buf, __bufsize, "%s:", _M_file);
465
        _M_print_word(__buf);
466
        _M_column += strlen(__buf);
467
      }
468
 
469
    if (_M_line > 0)
470
      {
471
        _M_format_word(__buf, __bufsize, "%u:", _M_line);
472
        _M_print_word(__buf);
473
        _M_column += strlen(__buf);
474
      }
475
 
476
    _M_wordwrap = true;
477
    _M_print_word("error: ");
478
 
479
    // Print the error message
480
    assert(_M_text);
481
    _M_print_string(_M_text);
482
    _M_print_word(".\n");
483
 
484
    // Emit descriptions of the objects involved in the operation
485
    _M_wordwrap = false;
486
    bool __has_noninteger_parameters = false;
487
    for (unsigned int __i = 0; __i < _M_num_parameters; ++__i)
488
      {
489
        if (_M_parameters[__i]._M_kind == _Parameter::__iterator
490
            || _M_parameters[__i]._M_kind == _Parameter::__sequence)
491
          {
492
            if (!__has_noninteger_parameters)
493
              {
494
                _M_first_line = true;
495
                _M_print_word("\nObjects involved in the operation:\n");
496
                __has_noninteger_parameters = true;
497
              }
498
            _M_parameters[__i]._M_print_description(this);
499
          }
500
      }
501
 
502
    abort();
503
  }
504
 
505
  template<typename _Tp>
506
    void
507
    _Error_formatter::_M_format_word(char* __buf,
508
                                     int __n __attribute__ ((__unused__)),
509
                                     const char* __fmt, _Tp __s) const
510
    {
511
#ifdef _GLIBCXX_USE_C99
512
      std::snprintf(__buf, __n, __fmt, __s);
513
#else
514
      std::sprintf(__buf, __fmt, __s);
515
#endif
516
    }
517
 
518
 
519
  void
520
  _Error_formatter::_M_print_word(const char* __word) const
521
  {
522
    if (!_M_wordwrap)
523
      {
524
        fprintf(stderr, "%s", __word);
525
        return;
526
      }
527
 
528
    size_t __length = strlen(__word);
529
    if (__length == 0)
530
      return;
531
 
532
    if ((_M_column + __length < _M_max_length)
533
        || (__length >= _M_max_length && _M_column == 1))
534
      {
535
        // If this isn't the first line, indent
536
        if (_M_column == 1 && !_M_first_line)
537
          {
538
            char __spacing[_M_indent + 1];
539
            for (int i = 0; i < _M_indent; ++i)
540
              __spacing[i] = ' ';
541
            __spacing[_M_indent] = '\0';
542
            fprintf(stderr, "%s", __spacing);
543
            _M_column += _M_indent;
544
          }
545
 
546
        fprintf(stderr, "%s", __word);
547
        _M_column += __length;
548
 
549
        if (__word[__length - 1] == '\n')
550
          {
551
            _M_first_line = false;
552
            _M_column = 1;
553
          }
554
      }
555
    else
556
      {
557
        _M_column = 1;
558
        _M_print_word("\n");
559
        _M_print_word(__word);
560
      }
561
  }
562
 
563
  void
564
  _Error_formatter::
565
  _M_print_string(const char* __string) const
566
  {
567
    const char* __start = __string;
568
    const char* __end = __start;
569
    const int __bufsize = 128;
570
    char __buf[__bufsize];
571
 
572
    while (*__start)
573
      {
574
        if (*__start != '%')
575
          {
576
            // [__start, __end) denotes the next word
577
            __end = __start;
578
            while (isalnum(*__end))
579
              ++__end;
580
            if (__start == __end)
581
              ++__end;
582
            if (isspace(*__end))
583
              ++__end;
584
 
585
            const ptrdiff_t __len = __end - __start;
586
            assert(__len < __bufsize);
587
            memcpy(__buf, __start, __len);
588
            __buf[__len] = '\0';
589
            _M_print_word(__buf);
590
            __start = __end;
591
 
592
            // Skip extra whitespace
593
            while (*__start == ' ')
594
              ++__start;
595
 
596
            continue;
597
          }
598
 
599
        ++__start;
600
        assert(*__start);
601
        if (*__start == '%')
602
          {
603
            _M_print_word("%");
604
            ++__start;
605
            continue;
606
          }
607
 
608
        // Get the parameter number
609
        assert(*__start >= '1' && *__start <= '9');
610
        size_t __param = *__start - '0';
611
        --__param;
612
        assert(__param < _M_num_parameters);
613
 
614
        // '.' separates the parameter number from the field
615
        // name, if there is one.
616
        ++__start;
617
        if (*__start != '.')
618
          {
619
            assert(*__start == ';');
620
            ++__start;
621
            __buf[0] = '\0';
622
            if (_M_parameters[__param]._M_kind == _Parameter::__integer)
623
              {
624
                _M_format_word(__buf, __bufsize, "%ld",
625
                               _M_parameters[__param]._M_variant._M_integer._M_value);
626
                _M_print_word(__buf);
627
              }
628
            else if (_M_parameters[__param]._M_kind == _Parameter::__string)
629
              _M_print_string(_M_parameters[__param]._M_variant._M_string._M_value);
630
            continue;
631
          }
632
 
633
        // Extract the field name we want
634
        enum { __max_field_len = 16 };
635
        char __field[__max_field_len];
636
        int __field_idx = 0;
637
        ++__start;
638
        while (*__start != ';')
639
          {
640
            assert(*__start);
641
            assert(__field_idx < __max_field_len-1);
642
            __field[__field_idx++] = *__start++;
643
          }
644
        ++__start;
645
        __field[__field_idx] = 0;
646
 
647
        _M_parameters[__param]._M_print_field(this, __field);
648
      }
649
  }
650
 
651
  // Instantiations.
652
  template
653
    void
654
    _Error_formatter::_M_format_word(char*, int, const char*,
655
                                     const void*) const;
656
 
657
  template
658
    void
659
    _Error_formatter::_M_format_word(char*, int, const char*, long) const;
660
 
661
  template
662
    void
663
    _Error_formatter::_M_format_word(char*, int, const char*,
664
                                     std::size_t) const;
665
 
666
  template
667
    void
668
    _Error_formatter::_M_format_word(char*, int, const char*,
669
                                     const char*) const;
670
} // namespace __gnu_debug

powered by: WebSVN 2.1.0

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