]> git.lyx.org Git - lyx.git/blob - boost/libs/regex/src/regex_debug.cpp
update
[lyx.git] / boost / libs / regex / src / regex_debug.cpp
1 /*
2  *
3  * Copyright (c) 1998-2002
4  * Dr John Maddock
5  *
6  * Permission to use, copy, modify, distribute and sell this software
7  * and its documentation for any purpose is hereby granted without fee,
8  * provided that the above copyright notice appear in all copies and
9  * that both that copyright notice and this permission notice appear
10  * in supporting documentation.  Dr John Maddock makes no representations
11  * about the suitability of this software for any purpose.
12  * It is provided "as is" without express or implied warranty.
13  *
14  */
15
16  /*
17   *   LOCATION:    see http://www.boost.org for most recent version.
18   *   FILE:        regex_debug.cpp
19   *   VERSION:     see <boost/version.hpp>
20   *   DESCRIPTION: Misc. debugging helpers.
21   */
22
23
24 #define BOOST_REGEX_SOURCE
25
26 #include <boost/regex/config.hpp>
27
28 #ifdef BOOST_REGEX_DEBUG
29
30 #ifdef BOOST_MSVC
31 #include <crtdbg.h>
32 #endif
33
34 #include <boost/regex/detail/regex_raw_buffer.hpp>
35 #include <boost/regex.hpp>
36
37 #ifndef BOOST_RE_OLD_IOSTREAM
38 #include <ostream>
39 #else 
40 #include <ostream.h>
41 #endif
42
43 namespace boost { namespace re_detail {
44 std::ostream& operator<<(std::ostream& s, syntax_element_type x)
45 {
46     return s << static_cast<unsigned long>(x);
47 }
48 }} // namespace boost::re_detail
49
50
51 namespace {
52
53 char b1[32] = {0,};
54 char guard_pattern[32] 
55 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
56 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, };
57 char b2[32] = {0,};
58
59 static const int guard_size = 32;
60
61 bool check_pattern(void* p)
62 {
63    return p ? memcmp(p, guard_pattern, guard_size) : 0;
64 }
65
66 inline unsigned maxi(unsigned i, unsigned j)
67 {
68    return i < j ? j : i;
69 }
70
71 unsigned int allocated = 0;
72
73 struct init
74 {
75    init();
76    ~init();
77 };
78
79 init::init()
80
81 #ifdef BOOST_MSVC
82    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_CRTDBG_DELAY_FREE_MEM_DF|_CRTDBG_LEAK_CHECK_DF);
83 #endif
84 }
85
86 init::~init() 
87
88 }
89
90
91 init i;
92
93 void* get_mem(size_t n)
94 {
95    ++allocated;
96    char* p = (char*)malloc(n + guard_size * 2 + maxi(sizeof(int) + sizeof(void*), boost::re_detail::padding_size) + boost::re_detail::padding_size);
97    char* base = p;
98    p = (char*)((std::ptrdiff_t)(p + boost::re_detail::padding_mask) & ~boost::re_detail::padding_mask);
99    std::memcpy(p + maxi(sizeof(int) + sizeof(void*), boost::re_detail::padding_size), guard_pattern, guard_size);
100    std::memcpy(p + maxi(sizeof(int) + sizeof(void*), boost::re_detail::padding_size) + guard_size + n, guard_pattern, guard_size);
101    *(int*)p = n;
102    *(void**)(p + sizeof(int)) = base;
103    return p + guard_size + maxi(sizeof(int) + sizeof(void*), boost::re_detail::padding_size);
104 }
105
106 void free_mem(void* b)
107 {
108    if(b)
109    {
110       char* p = (char*)b;
111       p -= (guard_size + maxi(sizeof(int) + sizeof(void*), boost::re_detail::padding_size));
112       if(check_pattern(p + maxi(sizeof(int) + sizeof(void*), boost::re_detail::padding_size)) || check_pattern(p + maxi(sizeof(int) + sizeof(void*), boost::re_detail::padding_size) + guard_size + *(int*)p))
113       {
114          cerr << "Error: freed memory has been written past end..." << endl;
115       }
116       free(*(void**)(p + sizeof(int)));
117       --allocated;
118    }
119 }
120
121 } // namespace
122
123 void* operator new(size_t n)
124 {
125    return get_mem(n);
126 }
127
128 void* operator new[](size_t n)
129 {
130    return get_mem(n);
131 }
132
133 void operator delete(void* p)
134 {
135    free_mem(p);
136 }
137
138 void operator delete[](void* p)
139 {
140    free_mem(p);
141 }
142
143 #include <set>
144
145 namespace boost{
146    namespace re_detail{
147
148 std::set<debug_guard*, std::less<debug_guard*> >* patterns = 0;
149
150 int pattern_count = 0;
151
152 void check_patterns(const char* f, int l)
153 {
154    if(pattern_count)
155    {
156       std::set<debug_guard*, std::less<debug_guard*> >::iterator i, j;
157       i = patterns->begin();
158       j = patterns->end();
159       while(i != j)
160       {
161          if(check_pattern((void*)(*i)->g1) || check_pattern((*i)->g2) || check_pattern((void*)(*i)->pc) || check_pattern((*i)->pnc))
162          {
163             cerr << "Error: static memory corruption at " << hex << *i << dec << " in " << (*i)->file << "@" << (*i)->line << " called from " << f << "@" << l << endl;
164          }
165          ++i;
166       }
167    }
168 }
169
170 debug_guard::debug_guard(const char* f, int l, const char* p1, char* p2)
171 {
172    if(++pattern_count == 1)
173       patterns = new std::set<debug_guard*, std::less<debug_guard*> >;
174    file = f;
175    line = l;
176    std::memcpy(g1, guard_pattern, guard_size);
177    std::memcpy(g2, guard_pattern, guard_size);
178    if(p1)
179    {
180       pc = p1;
181    }
182    else
183       pc = 0;
184    if(p2)
185    {
186       pnc = p2;
187       std::memcpy(pnc, guard_pattern, guard_size);
188    }
189    else
190       pnc = 0;
191    patterns->insert(this);
192 }
193
194 debug_guard::~debug_guard()
195 {
196    check_patterns(file, line);
197    if(check_pattern(g1) || check_pattern(g2))
198    {
199       cerr << "Error: memory corruption " << file << "@" << line << endl;
200    }
201    patterns->erase(this);
202    if(--pattern_count == 0)
203    {
204       delete patterns;
205       patterns = 0;
206    }
207 }
208
209    } // namespace re_detail
210
211 } // namespace boost
212
213
214
215 #endif
216
217
218