ruby-xslt 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/AUTHORS +23 -0
- data/COPYING +340 -0
- data/ChangeLog +64 -0
- data/README +137 -0
- data/debug/memwatch.c +2664 -0
- data/debug/memwatch.h +707 -0
- data/examples/commentary.dtd +34 -0
- data/examples/functions.xsl +51 -0
- data/examples/fuzface.rb +13 -0
- data/examples/fuzface.xml +154 -0
- data/examples/fuzface.xsl +4 -0
- data/examples/fuzface_REXML.rb +11 -0
- data/examples/fuzface_XML-Simple.rb +12 -0
- data/examples/fuzface_data.rb +13 -0
- data/examples/fuzface_error.rb +86 -0
- data/examples/fuzface_to_s.rb +9 -0
- data/examples/info.rb +19 -0
- data/examples/ramblings.xsl +46 -0
- data/examples/test.xml +5 -0
- data/examples/test.xsl +18 -0
- data/examples/test_functions.rb +18 -0
- data/examples/test_parameters.rb +13 -0
- data/extconf.rb +114 -0
- data/extfunc.c +216 -0
- data/extfunc.h +26 -0
- data/parameters.c +59 -0
- data/parameters.h +20 -0
- data/parser.c +228 -0
- data/parser.h +30 -0
- data/rb_utils.c +30 -0
- data/rb_utils.h +34 -0
- data/ruby-xslt.gemspec +19 -0
- data/tests/t.xml +2 -0
- data/tests/t.xsl +6 -0
- data/tests/test.rb +125 -0
- data/xslt.c +619 -0
- data/xslt.h +98 -0
- metadata +98 -0
data/debug/memwatch.h
ADDED
@@ -0,0 +1,707 @@
|
|
1
|
+
/*
|
2
|
+
** MEMWATCH.H
|
3
|
+
** Nonintrusive ANSI C memory leak / overwrite detection
|
4
|
+
** Copyright (C) 1992-2002 Johan Lindh
|
5
|
+
** All rights reserved.
|
6
|
+
** Version 2.71
|
7
|
+
**
|
8
|
+
************************************************************************
|
9
|
+
**
|
10
|
+
** PURPOSE:
|
11
|
+
**
|
12
|
+
** MEMWATCH has been written to allow guys and gals that like to
|
13
|
+
** program in C a public-domain memory error control product.
|
14
|
+
** I hope you'll find it's as advanced as most commercial packages.
|
15
|
+
** The idea is that you use it during the development phase and
|
16
|
+
** then remove the MEMWATCH define to produce your final product.
|
17
|
+
** MEMWATCH is distributed in source code form in order to allow
|
18
|
+
** you to compile it for your platform with your own compiler.
|
19
|
+
** It's aim is to be 100% ANSI C, but some compilers are more stingy
|
20
|
+
** than others. If it doesn't compile without warnings, please mail
|
21
|
+
** me the configuration of operating system and compiler you are using
|
22
|
+
** along with a description of how to modify the source, and the version
|
23
|
+
** number of MEMWATCH that you are using.
|
24
|
+
**
|
25
|
+
************************************************************************
|
26
|
+
|
27
|
+
This file is part of MEMWATCH.
|
28
|
+
|
29
|
+
MEMWATCH is free software; you can redistribute it and/or modify
|
30
|
+
it under the terms of the GNU General Public License as published by
|
31
|
+
the Free Software Foundation; either version 2 of the License, or
|
32
|
+
(at your option) any later version.
|
33
|
+
|
34
|
+
MEMWATCH is distributed in the hope that it will be useful,
|
35
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
36
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
37
|
+
GNU General Public License for more details.
|
38
|
+
|
39
|
+
You should have received a copy of the GNU General Public License
|
40
|
+
along with MEMWATCH; if not, write to the Free Software
|
41
|
+
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
42
|
+
|
43
|
+
************************************************************************
|
44
|
+
**
|
45
|
+
** REVISION HISTORY:
|
46
|
+
**
|
47
|
+
** 920810 JLI [1.00]
|
48
|
+
** 920830 JLI [1.10 double-free detection]
|
49
|
+
** 920912 JLI [1.15 mwPuts, mwGrab/Drop, mwLimit]
|
50
|
+
** 921022 JLI [1.20 ASSERT and VERIFY]
|
51
|
+
** 921105 JLI [1.30 C++ support and TRACE]
|
52
|
+
** 921116 JLI [1.40 mwSetOutFunc]
|
53
|
+
** 930215 JLI [1.50 modified ASSERT/VERIFY]
|
54
|
+
** 930327 JLI [1.51 better auto-init & PC-lint support]
|
55
|
+
** 930506 JLI [1.55 MemWatch class, improved C++ support]
|
56
|
+
** 930507 JLI [1.60 mwTest & CHECK()]
|
57
|
+
** 930809 JLI [1.65 Abort/Retry/Ignore]
|
58
|
+
** 930820 JLI [1.70 data dump when unfreed]
|
59
|
+
** 931016 JLI [1.72 modified C++ new/delete handling]
|
60
|
+
** 931108 JLI [1.77 mwSetAssertAction() & some small changes]
|
61
|
+
** 940110 JLI [1.80 no-mans-land alloc/checking]
|
62
|
+
** 940328 JLI [2.00 version 2.0 rewrite]
|
63
|
+
** Improved NML (no-mans-land) support.
|
64
|
+
** Improved performance (especially for free()ing!).
|
65
|
+
** Support for 'read-only' buffers (checksums)
|
66
|
+
** ^^ NOTE: I never did this... maybe I should?
|
67
|
+
** FBI (free'd block info) tagged before freed blocks
|
68
|
+
** Exporting of the mwCounter variable
|
69
|
+
** mwBreakOut() localizes debugger support
|
70
|
+
** Allocation statistics (global, per-module, per-line)
|
71
|
+
** Self-repair ability with relinking
|
72
|
+
** 950913 JLI [2.10 improved garbage handling]
|
73
|
+
** 951201 JLI [2.11 improved auto-free in emergencies]
|
74
|
+
** 960125 JLI [X.01 implemented auto-checking using mwAutoCheck()]
|
75
|
+
** 960514 JLI [2.12 undefining of existing macros]
|
76
|
+
** 960515 JLI [2.13 possibility to use default new() & delete()]
|
77
|
+
** 960516 JLI [2.20 suppression of file flushing on unfreed msgs]
|
78
|
+
** 960516 JLI [2.21 better support for using MEMWATCH with DLL's]
|
79
|
+
** 960710 JLI [X.02 multiple logs and mwFlushNow()]
|
80
|
+
** 960801 JLI [2.22 merged X.01 version with current]
|
81
|
+
** 960805 JLI [2.30 mwIsXXXXAddr() to avoid unneeded GP's]
|
82
|
+
** 960805 JLI [2.31 merged X.02 version with current]
|
83
|
+
** 961002 JLI [2.32 support for realloc() + fixed STDERR bug]
|
84
|
+
** 961222 JLI [2.40 added mwMark() & mwUnmark()]
|
85
|
+
** 970101 JLI [2.41 added over/underflow checking after failed ASSERT/VERIFY]
|
86
|
+
** 970113 JLI [2.42 added support for PC-Lint 7.00g]
|
87
|
+
** 970207 JLI [2.43 added support for strdup()]
|
88
|
+
** 970209 JLI [2.44 changed default filename to lowercase]
|
89
|
+
** 970405 JLI [2.45 fixed bug related with atexit() and some C++ compilers]
|
90
|
+
** 970723 JLI [2.46 added MW_ARI_NULLREAD flag]
|
91
|
+
** 970813 JLI [2.47 stabilized marker handling]
|
92
|
+
** 980317 JLI [2.48 ripped out C++ support; wasn't working good anyway]
|
93
|
+
** 980318 JLI [2.50 improved self-repair facilities & SIGSEGV support]
|
94
|
+
** 980417 JLI [2.51 more checks for invalid addresses]
|
95
|
+
** 980512 JLI [2.52 moved MW_ARI_NULLREAD to occur before aborting]
|
96
|
+
** 990112 JLI [2.53 added check for empty heap to mwIsOwned]
|
97
|
+
** 990217 JLI [2.55 improved the emergency repairs diagnostics and NML]
|
98
|
+
** 990224 JLI [2.56 changed ordering of members in structures]
|
99
|
+
** 990303 JLI [2.57 first maybe-fixit-for-hpux test]
|
100
|
+
** 990516 JLI [2.58 added 'static' to the definition of mwAutoInit]
|
101
|
+
** 990517 JLI [2.59 fixed some high-sensitivity warnings]
|
102
|
+
** 990610 JLI [2.60 fixed some more high-sensitivity warnings]
|
103
|
+
** 990715 JLI [2.61 changed TRACE/ASSERT/VERIFY macro names]
|
104
|
+
** 991001 JLI [2.62 added CHECK_BUFFER() and mwTestBuffer()]
|
105
|
+
** 991007 JLI [2.63 first shot at a 64-bit compatible version]
|
106
|
+
** 991009 JLI [2.64 undef's strdup() if defined, mwStrdup made const]
|
107
|
+
** 000704 JLI [2.65 added some more detection for 64-bits]
|
108
|
+
** 010502 JLI [2.66 incorporated some user fixes]
|
109
|
+
** [mwRelink() could print out garbage pointer (thanks mac@phobos.ca)]
|
110
|
+
** [added array destructor for C++ (thanks rdasilva@connecttel.com)]
|
111
|
+
** [added mutex support (thanks rdasilva@connecttel.com)]
|
112
|
+
** 010531 JLI [2.67 fix: mwMutexXXX() was declared even if MW_HAVE_MUTEX was not defined]
|
113
|
+
** 010619 JLI [2.68 fix: mwRealloc() could leave the mutex locked]
|
114
|
+
** 020918 JLI [2.69 changed to GPL, added C++ array allocation by Howard Cohen]
|
115
|
+
** 030212 JLI [2.70 mwMalloc() bug for very large allocations (4GB on 32bits)]
|
116
|
+
** 030520 JLI [2.71 added ULONG_LONG_MAX as a 64-bit detector (thanks Sami Salonen)]
|
117
|
+
**
|
118
|
+
** To use, simply include 'MEMWATCH.H' as a header file,
|
119
|
+
** and add MEMWATCH.C to your list of files, and define the macro
|
120
|
+
** 'MEMWATCH'. If this is not defined, MEMWATCH will disable itself.
|
121
|
+
**
|
122
|
+
** To call the standard C malloc / realloc / calloc / free; use mwMalloc_(),
|
123
|
+
** mwCalloc_() and mwFree_(). Note that mwFree_() will correctly
|
124
|
+
** free both malloc()'d memory as well as mwMalloc()'d.
|
125
|
+
**
|
126
|
+
** 980317: C++ support has been disabled.
|
127
|
+
** The code remains, but is not compiled.
|
128
|
+
**
|
129
|
+
** For use with C++, which allows use of inlining in header files
|
130
|
+
** and class specific new/delete, you must also define 'new' as
|
131
|
+
** 'mwNew' and 'delete' as 'mwDelete'. Do this *after* you include
|
132
|
+
** C++ header files from libraries, otherwise you can mess up their
|
133
|
+
** class definitions. If you don't define these, the C++ allocations
|
134
|
+
** will not have source file and line number information. Also note,
|
135
|
+
** most C++ class libraries implement their own C++ memory management,
|
136
|
+
** and don't allow anyone to override them. MFC belongs to this crew.
|
137
|
+
** In these cases, the only thing to do is to use MEMWATCH_NOCPP.
|
138
|
+
**
|
139
|
+
** You can capture output from MEMWATCH using mwSetOutFunc().
|
140
|
+
** Just give it the adress of a "void myOutFunc(int c)" function,
|
141
|
+
** and all characters to be output will be redirected there.
|
142
|
+
**
|
143
|
+
** A failing ASSERT() or VERIFY() will normally always abort your
|
144
|
+
** program. This can be changed using mwSetAriFunc(). Give it a
|
145
|
+
** pointer to a "int myAriFunc(const char *)" function. Your function
|
146
|
+
** must ask the user whether to Abort, Retry or Ignore the trap.
|
147
|
+
** Return 2 to Abort, 1 to Retry or 0 to Ignore. Beware retry; it
|
148
|
+
** causes the expression to be evaluated again! MEMWATCH has a
|
149
|
+
** default ARI handler. It's disabled by default, but you can enable
|
150
|
+
** it by calling 'mwDefaultAri()'. Note that this will STILL abort
|
151
|
+
** your program unless you define MEMWATCH_STDIO to allow MEMWATCH
|
152
|
+
** to use the standard C I/O streams. Also, setting the ARI function
|
153
|
+
** will cause MEMWATCH *NOT* to write the ARI error to stderr. The
|
154
|
+
** error string is passed to the ARI function instead, as the
|
155
|
+
** 'const char *' parameter.
|
156
|
+
**
|
157
|
+
** You can disable MEMWATCH's ASSERT/VERIFY and/or TRACE implementations.
|
158
|
+
** This can be useful if you're using a debug terminal or smart debugger.
|
159
|
+
** Disable them by defining MW_NOASSERT, MW_NOVERIFY or MW_NOTRACE.
|
160
|
+
**
|
161
|
+
** MEMWATCH fills all allocated memory with the byte 0xFE, so if
|
162
|
+
** you're looking at erroneous data which are all 0xFE:s, the
|
163
|
+
** data probably was not initialized by you. The exception is
|
164
|
+
** calloc(), which will fill with zero's. All freed buffers are
|
165
|
+
** zapped with 0xFD. If this is what you look at, you're using
|
166
|
+
** data that has been freed. If this is the case, be aware that
|
167
|
+
** MEMWATCH places a 'free'd block info' structure immediately
|
168
|
+
** before the freed data. This block contains info about where
|
169
|
+
** the block was freed. The information is in readable text,
|
170
|
+
** in the format "FBI<counter>filename(line)", for example:
|
171
|
+
** "FBI<267>test.c(12)". Using FBI's slows down free(), so it's
|
172
|
+
** disabled by default. Use mwFreeBufferInfo(1) to enable it.
|
173
|
+
**
|
174
|
+
** To aid in tracking down wild pointer writes, MEMWATCH can perform
|
175
|
+
** no-mans-land allocations. No-mans-land will contain the byte 0xFC.
|
176
|
+
** MEMWATCH will, when this is enabled, convert recently free'd memory
|
177
|
+
** into NML allocations.
|
178
|
+
**
|
179
|
+
** MEMWATCH protects it's own data buffers with checksums. If you
|
180
|
+
** get an internal error, it means you're overwriting wildly,
|
181
|
+
** or using an uninitialized pointer.
|
182
|
+
**
|
183
|
+
************************************************************************
|
184
|
+
**
|
185
|
+
** Note when compiling with Microsoft C:
|
186
|
+
** - MSC ignores fflush() by default. This is overridden, so that
|
187
|
+
** the disk log will always be current.
|
188
|
+
**
|
189
|
+
** This utility has been tested with:
|
190
|
+
** PC-lint 7.0k, passed as 100% ANSI C compatible
|
191
|
+
** Microsoft Visual C++ on Win16 and Win32
|
192
|
+
** Microsoft C on DOS
|
193
|
+
** SAS C on an Amiga 500
|
194
|
+
** Gnu C on a PC running Red Hat Linux
|
195
|
+
** ...and using an (to me) unknown compiler on an Atari machine.
|
196
|
+
**
|
197
|
+
************************************************************************
|
198
|
+
**
|
199
|
+
** Format of error messages in MEMWATCH.LOG:
|
200
|
+
** message: <sequence-number> filename(linenumber), information
|
201
|
+
**
|
202
|
+
** Errors caught by MemWatch, when they are detected, and any
|
203
|
+
** actions taken besides writing to the log file MEMWATCH.LOG:
|
204
|
+
**
|
205
|
+
** Double-freeing:
|
206
|
+
** A pointer that was recently freed and has not since been
|
207
|
+
** reused was freed again. The place where the previous free()
|
208
|
+
** was executed is displayed.
|
209
|
+
** Detect: delete or free() using the offending pointer.
|
210
|
+
** Action: The delete or free() is cancelled, execution continues.
|
211
|
+
** Underflow:
|
212
|
+
** You have written just ahead of the allocated memory.
|
213
|
+
** The size and place of the allocation is displayed.
|
214
|
+
** Detect: delete or free() of the damaged buffer.
|
215
|
+
** Action: The buffer is freed, but there may be secondary damage.
|
216
|
+
** Overflow:
|
217
|
+
** Like underflow, but you've written after the end of the buffer.
|
218
|
+
** Detect: see Underflow.
|
219
|
+
** Action: see Underflow.
|
220
|
+
** WILD free:
|
221
|
+
** An unrecognized pointer was passed to delete or free().
|
222
|
+
** The pointer may have been returned from a library function;
|
223
|
+
** in that case, use mwFree_() to force free() of it.
|
224
|
+
** Also, this may be a double-free, but the previous free was
|
225
|
+
** too long ago, causing MEMWATCH to 'forget' it.
|
226
|
+
** Detect: delete or free() of the offending pointer.
|
227
|
+
** Action: The delete or free() is cancelled, execution continues.
|
228
|
+
** NULL free:
|
229
|
+
** It's unclear to me whether or not freeing of NULL pointers
|
230
|
+
** is legal in ANSI C, therefore a warning is written to the log file,
|
231
|
+
** but the error counter remains the same. This is legal using C++,
|
232
|
+
** so the warning does not appear with delete.
|
233
|
+
** Detect: When you free(NULL).
|
234
|
+
** Action: The free() is cancelled.
|
235
|
+
** Failed:
|
236
|
+
** A request to allocate memory failed. If the allocation is
|
237
|
+
** small, this may be due to memory depletion, but is more likely
|
238
|
+
** to be memory fragmentation problems. The amount of memory
|
239
|
+
** allocated so far is displayed also.
|
240
|
+
** Detect: When you new, malloc(), realloc() or calloc() memory.
|
241
|
+
** Action: NULL is returned.
|
242
|
+
** Realloc:
|
243
|
+
** A request to re-allocate a memory buffer failed for reasons
|
244
|
+
** other than out-of-memory. The specific reason is shown.
|
245
|
+
** Detect: When you realloc()
|
246
|
+
** Action: realloc() is cancelled, NULL is returned
|
247
|
+
** Limit fail:
|
248
|
+
** A request to allocate memory failed since it would violate
|
249
|
+
** the limit set using mwLimit(). mwLimit() is used to stress-test
|
250
|
+
** your code under simulated low memory conditions.
|
251
|
+
** Detect: At new, malloc(), realloc() or calloc().
|
252
|
+
** Action: NULL is returned.
|
253
|
+
** Assert trap:
|
254
|
+
** An ASSERT() failed. The ASSERT() macro works like C's assert()
|
255
|
+
** macro/function, except that it's interactive. See your C manual.
|
256
|
+
** Detect: On the ASSERT().
|
257
|
+
** Action: Program ends with an advisory message to stderr, OR
|
258
|
+
** Program writes the ASSERT to the log and continues, OR
|
259
|
+
** Program asks Abort/Retry/Ignore? and takes that action.
|
260
|
+
** Verify trap:
|
261
|
+
** A VERIFY() failed. The VERIFY() macro works like ASSERT(),
|
262
|
+
** but if MEMWATCH is not defined, it still evaluates the
|
263
|
+
** expression, but it does not act upon the result.
|
264
|
+
** Detect: On the VERIFY().
|
265
|
+
** Action: Program ends with an advisory message to stderr, OR
|
266
|
+
** Program writes the VERIFY to the log and continues, OR
|
267
|
+
** Program asks Abort/Retry/Ignore? and takes that action.
|
268
|
+
** Wild pointer:
|
269
|
+
** A no-mans-land buffer has been written into. MEMWATCH can
|
270
|
+
** allocate and distribute chunks of memory solely for the
|
271
|
+
** purpose of trying to catch random writes into memory.
|
272
|
+
** Detect: Always on CHECK(), but can be detected in several places.
|
273
|
+
** Action: The error is logged, and if an ARI handler is installed,
|
274
|
+
** it is executed, otherwise, execution continues.
|
275
|
+
** Unfreed:
|
276
|
+
** A memory buffer you allocated has not been freed.
|
277
|
+
** You are informed where it was allocated, and whether any
|
278
|
+
** over or underflow has occured. MemWatch also displays up to
|
279
|
+
** 16 bytes of the data, as much as it can, in hex and text.
|
280
|
+
** Detect: When MemWatch terminates.
|
281
|
+
** Action: The buffer is freed.
|
282
|
+
** Check:
|
283
|
+
** An error was detected during a CHECK() operation.
|
284
|
+
** The associated pointer is displayed along with
|
285
|
+
** the file and line where the CHECK() was executed.
|
286
|
+
** Followed immediately by a normal error message.
|
287
|
+
** Detect: When you CHECK()
|
288
|
+
** Action: Depends on the error
|
289
|
+
** Relink:
|
290
|
+
** After a MEMWATCH internal control block has been trashed,
|
291
|
+
** MEMWATCH tries to repair the damage. If successful, program
|
292
|
+
** execution will continue instead of aborting. Some information
|
293
|
+
** about the block may be gone permanently, though.
|
294
|
+
** Detect: N/A
|
295
|
+
** Action: Relink successful: program continues.
|
296
|
+
** Relink fails: program aborts.
|
297
|
+
** Internal:
|
298
|
+
** An internal error is flagged by MEMWATCH when it's control
|
299
|
+
** structures have been damaged. You are likely using an uninitialized
|
300
|
+
** pointer somewhere in your program, or are zapping memory all over.
|
301
|
+
** The message may give you additional diagnostic information.
|
302
|
+
** If possible, MEMWATCH will recover and continue execution.
|
303
|
+
** Detect: Various actions.
|
304
|
+
** Action: Whatever is needed
|
305
|
+
** Mark:
|
306
|
+
** The program terminated without umarking all marked pointers. Marking
|
307
|
+
** can be used to track resources other than memory. mwMark(pointer,text,...)
|
308
|
+
** when the resource is allocated, and mwUnmark(pointer) when it's freed.
|
309
|
+
** The 'text' is displayed for still marked pointers when the program
|
310
|
+
** ends.
|
311
|
+
** Detect: When MemWatch terminates.
|
312
|
+
** Action: The error is logged.
|
313
|
+
**
|
314
|
+
**
|
315
|
+
************************************************************************
|
316
|
+
**
|
317
|
+
** The author may be reached by e-mail at the address below. If you
|
318
|
+
** mail me about source code changes in MEMWATCH, remember to include
|
319
|
+
** MW's version number.
|
320
|
+
**
|
321
|
+
** Johan Lindh
|
322
|
+
** johan@linkdata.se
|
323
|
+
**
|
324
|
+
** The latest version of MEMWATCH may be downloaded from
|
325
|
+
** http://www.linkdata.se/
|
326
|
+
*/
|
327
|
+
|
328
|
+
#ifndef __MEMWATCH_H
|
329
|
+
#define __MEMWATCH_H
|
330
|
+
|
331
|
+
/* Make sure that malloc(), realloc(), calloc() and free() are declared. */
|
332
|
+
/*lint -save -e537 */
|
333
|
+
#include <stdlib.h>
|
334
|
+
/*lint -restore */
|
335
|
+
|
336
|
+
#ifdef __cplusplus
|
337
|
+
extern "C" {
|
338
|
+
#endif
|
339
|
+
|
340
|
+
|
341
|
+
/*
|
342
|
+
** Constants used
|
343
|
+
** All MEMWATCH constants start with the prefix MW_, followed by
|
344
|
+
** a short mnemonic which indicates where the constant is used,
|
345
|
+
** followed by a descriptive text about it.
|
346
|
+
*/
|
347
|
+
|
348
|
+
#define MW_ARI_NULLREAD 0x10 /* Null read (to start debugger) */
|
349
|
+
#define MW_ARI_ABORT 0x04 /* ARI handler says: abort program! */
|
350
|
+
#define MW_ARI_RETRY 0x02 /* ARI handler says: retry action! */
|
351
|
+
#define MW_ARI_IGNORE 0x01 /* ARI handler says: ignore error! */
|
352
|
+
|
353
|
+
#define MW_VAL_NEW 0xFE /* value in newly allocated memory */
|
354
|
+
#define MW_VAL_DEL 0xFD /* value in newly deleted memory */
|
355
|
+
#define MW_VAL_NML 0xFC /* value in no-mans-land */
|
356
|
+
#define MW_VAL_GRB 0xFB /* value in grabbed memory */
|
357
|
+
|
358
|
+
#define MW_TEST_ALL 0xFFFF /* perform all tests */
|
359
|
+
#define MW_TEST_CHAIN 0x0001 /* walk the heap chain */
|
360
|
+
#define MW_TEST_ALLOC 0x0002 /* test allocations & NML guards */
|
361
|
+
#define MW_TEST_NML 0x0004 /* test all-NML areas for modifications */
|
362
|
+
|
363
|
+
#define MW_NML_NONE 0 /* no NML */
|
364
|
+
#define MW_NML_FREE 1 /* turn FREE'd memory into NML */
|
365
|
+
#define MW_NML_ALL 2 /* all unused memory is NML */
|
366
|
+
#define MW_NML_DEFAULT 0 /* the default NML setting */
|
367
|
+
|
368
|
+
#define MW_STAT_GLOBAL 0 /* only global statistics collected */
|
369
|
+
#define MW_STAT_MODULE 1 /* collect statistics on a module basis */
|
370
|
+
#define MW_STAT_LINE 2 /* collect statistics on a line basis */
|
371
|
+
#define MW_STAT_DEFAULT 0 /* the default statistics setting */
|
372
|
+
|
373
|
+
/*
|
374
|
+
** MemWatch internal constants
|
375
|
+
** You may change these and recompile MemWatch to change the limits
|
376
|
+
** of some parameters. Respect the recommended minimums!
|
377
|
+
*/
|
378
|
+
#define MW_TRACE_BUFFER 2048 /* (min 160) size of TRACE()'s output buffer */
|
379
|
+
#define MW_FREE_LIST 64 /* (min 4) number of free()'s to track */
|
380
|
+
|
381
|
+
/*
|
382
|
+
** Exported variables
|
383
|
+
** In case you have to remove the 'const' keyword because your compiler
|
384
|
+
** doesn't support it, be aware that changing the values may cause
|
385
|
+
** unpredictable behaviour.
|
386
|
+
** - mwCounter contains the current action count. You can use this to
|
387
|
+
** place breakpoints using a debugger, if you want.
|
388
|
+
*/
|
389
|
+
#ifndef __MEMWATCH_C
|
390
|
+
extern const unsigned long mwCounter;
|
391
|
+
#endif
|
392
|
+
|
393
|
+
/*
|
394
|
+
** System functions
|
395
|
+
** Normally, it is not nessecary to call any of these. MEMWATCH will
|
396
|
+
** automatically initialize itself on the first MEMWATCH function call,
|
397
|
+
** and set up a call to mwAbort() using atexit(). Some C++ implementations
|
398
|
+
** run the atexit() chain before the program has terminated, so you
|
399
|
+
** may have to use mwInit() or the MemWatch C++ class to get good
|
400
|
+
** behaviour.
|
401
|
+
** - mwInit() can be called to disable the atexit() usage. If mwInit()
|
402
|
+
** is called directly, you must call mwTerm() to end MemWatch, or
|
403
|
+
** mwAbort().
|
404
|
+
** - mwTerm() is usually not nessecary to call; but if called, it will
|
405
|
+
** call mwAbort() if it finds that it is cancelling the 'topmost'
|
406
|
+
** mwInit() call.
|
407
|
+
** - mwAbort() cleans up after MEMWATCH, reports unfreed buffers, etc.
|
408
|
+
*/
|
409
|
+
void mwInit( void );
|
410
|
+
void mwTerm( void );
|
411
|
+
void mwAbort( void );
|
412
|
+
|
413
|
+
/*
|
414
|
+
** Setup functions
|
415
|
+
** These functions control the operation of MEMWATCH's protective features.
|
416
|
+
** - mwFlushNow() causes MEMWATCH to flush it's buffers.
|
417
|
+
** - mwDoFlush() controls whether MEMWATCH flushes the disk buffers after
|
418
|
+
** writes. The default is smart flushing: MEMWATCH will not flush buffers
|
419
|
+
** explicitly until memory errors are detected. Then, all writes are
|
420
|
+
** flushed until program end or mwDoFlush(0) is called.
|
421
|
+
** - mwLimit() sets the allocation limit, an arbitrary limit on how much
|
422
|
+
** memory your program may allocate in bytes. Used to stress-test app.
|
423
|
+
** Also, in virtual-memory or multitasking environs, puts a limit on
|
424
|
+
** how much MW_NML_ALL can eat up.
|
425
|
+
** - mwGrab() grabs up X kilobytes of memory. Allocates actual memory,
|
426
|
+
** can be used to stress test app & OS both.
|
427
|
+
** - mwDrop() drops X kilobytes of grabbed memory.
|
428
|
+
** - mwNoMansLand() sets the behaviour of the NML logic. See the
|
429
|
+
** MW_NML_xxx for more information. The default is MW_NML_DEFAULT.
|
430
|
+
** - mwStatistics() sets the behaviour of the statistics collector. See
|
431
|
+
** the MW_STAT_xxx defines for more information. Default MW_STAT_DEFAULT.
|
432
|
+
** - mwFreeBufferInfo() enables or disables the tagging of free'd buffers
|
433
|
+
** with freeing information. This information is written in text form,
|
434
|
+
** using sprintf(), so it's pretty slow. Disabled by default.
|
435
|
+
** - mwAutoCheck() performs a CHECK() operation whenever a MemWatch function
|
436
|
+
** is used. Slows down performance, of course.
|
437
|
+
** - mwCalcCheck() calculates checksums for all data buffers. Slow!
|
438
|
+
** - mwDumpCheck() logs buffers where stored & calc'd checksums differ. Slow!!
|
439
|
+
** - mwMark() sets a generic marker. Returns the pointer given.
|
440
|
+
** - mwUnmark() removes a generic marker. If, at the end of execution, some
|
441
|
+
** markers are still in existence, these will be reported as leakage.
|
442
|
+
** returns the pointer given.
|
443
|
+
*/
|
444
|
+
void mwFlushNow( void );
|
445
|
+
void mwDoFlush( int onoff );
|
446
|
+
void mwLimit( long bytes );
|
447
|
+
unsigned mwGrab( unsigned kilobytes );
|
448
|
+
unsigned mwDrop( unsigned kilobytes );
|
449
|
+
void mwNoMansLand( int mw_nml_level );
|
450
|
+
void mwStatistics( int level );
|
451
|
+
void mwFreeBufferInfo( int onoff );
|
452
|
+
void mwAutoCheck( int onoff );
|
453
|
+
void mwCalcCheck( void );
|
454
|
+
void mwDumpCheck( void );
|
455
|
+
void * mwMark( void *p, const char *description, const char *file, unsigned line );
|
456
|
+
void * mwUnmark( void *p, const char *file, unsigned line );
|
457
|
+
|
458
|
+
/*
|
459
|
+
** Testing/verification/tracing
|
460
|
+
** All of these macros except VERIFY() evaluates to a null statement
|
461
|
+
** if MEMWATCH is not defined during compilation.
|
462
|
+
** - mwIsReadAddr() checks a memory area for read privilige.
|
463
|
+
** - mwIsSafeAddr() checks a memory area for both read & write privilige.
|
464
|
+
** This function and mwIsReadAddr() is highly system-specific and
|
465
|
+
** may not be implemented. If this is the case, they will default
|
466
|
+
** to returning nonzero for any non-NULL pointer.
|
467
|
+
** - CHECK() does a complete memory integrity test. Slow!
|
468
|
+
** - CHECK_THIS() checks only selected components.
|
469
|
+
** - CHECK_BUFFER() checks the indicated buffer for errors.
|
470
|
+
** - mwASSERT() or ASSERT() If the expression evaluates to nonzero, execution continues.
|
471
|
+
** Otherwise, the ARI handler is called, if present. If not present,
|
472
|
+
** the default ARI action is taken (set with mwSetAriAction()).
|
473
|
+
** ASSERT() can be disabled by defining MW_NOASSERT.
|
474
|
+
** - mwVERIFY() or VERIFY() works just like ASSERT(), but when compiling without
|
475
|
+
** MEMWATCH the macro evaluates to the expression.
|
476
|
+
** VERIFY() can be disabled by defining MW_NOVERIFY.
|
477
|
+
** - mwTRACE() or TRACE() writes some text and data to the log. Use like printf().
|
478
|
+
** TRACE() can be disabled by defining MW_NOTRACE.
|
479
|
+
*/
|
480
|
+
int mwIsReadAddr( const void *p, unsigned len );
|
481
|
+
int mwIsSafeAddr( void *p, unsigned len );
|
482
|
+
int mwTest( const char *file, int line, int mw_test_flags );
|
483
|
+
int mwTestBuffer( const char *file, int line, void *p );
|
484
|
+
int mwAssert( int, const char*, const char*, int );
|
485
|
+
int mwVerify( int, const char*, const char*, int );
|
486
|
+
|
487
|
+
/*
|
488
|
+
** User I/O functions
|
489
|
+
** - mwTrace() works like printf(), but dumps output either to the
|
490
|
+
** function specified with mwSetOutFunc(), or the log file.
|
491
|
+
** - mwPuts() works like puts(), dumps output like mwTrace().
|
492
|
+
** - mwSetOutFunc() allows you to give the adress of a function
|
493
|
+
** where all user output will go. (exeption: see mwSetAriFunc)
|
494
|
+
** Specifying NULL will direct output to the log file.
|
495
|
+
** - mwSetAriFunc() gives MEMWATCH the adress of a function to call
|
496
|
+
** when an 'Abort, Retry, Ignore' question is called for. The
|
497
|
+
** actual error message is NOT printed when you've set this adress,
|
498
|
+
** but instead it is passed as an argument. If you call with NULL
|
499
|
+
** for an argument, the ARI handler is disabled again. When the
|
500
|
+
** handler is disabled, MEMWATCH will automatically take the
|
501
|
+
** action specified by mwSetAriAction().
|
502
|
+
** - mwSetAriAction() sets the default ARI return value MEMWATCH should
|
503
|
+
** use if no ARI handler is specified. Defaults to MW_ARI_ABORT.
|
504
|
+
** - mwAriHandler() is an ANSI ARI handler you can use if you like. It
|
505
|
+
** dumps output to stderr, and expects input from stdin.
|
506
|
+
** - mwBreakOut() is called in certain cases when MEMWATCH feels it would
|
507
|
+
** be nice to break into a debugger. If you feel like MEMWATCH, place
|
508
|
+
** an execution breakpoint on this function.
|
509
|
+
*/
|
510
|
+
void mwTrace( const char* format_string, ... );
|
511
|
+
void mwPuts( const char* text );
|
512
|
+
void mwSetOutFunc( void (*func)(int) );
|
513
|
+
void mwSetAriFunc( int (*func)(const char*) );
|
514
|
+
void mwSetAriAction( int mw_ari_value );
|
515
|
+
int mwAriHandler( const char* cause );
|
516
|
+
void mwBreakOut( const char* cause );
|
517
|
+
|
518
|
+
/*
|
519
|
+
** Allocation/deallocation functions
|
520
|
+
** These functions are the ones actually to perform allocations
|
521
|
+
** when running MEMWATCH, for both C and C++ calls.
|
522
|
+
** - mwMalloc() debugging allocator
|
523
|
+
** - mwMalloc_() always resolves to a clean call of malloc()
|
524
|
+
** - mwRealloc() debugging re-allocator
|
525
|
+
** - mwRealloc_() always resolves to a clean call of realloc()
|
526
|
+
** - mwCalloc() debugging allocator, fills with zeros
|
527
|
+
** - mwCalloc_() always resolves to a clean call of calloc()
|
528
|
+
** - mwFree() debugging free. Can only free memory which has
|
529
|
+
** been allocated by MEMWATCH.
|
530
|
+
** - mwFree_() resolves to a) normal free() or b) debugging free.
|
531
|
+
** Can free memory allocated by MEMWATCH and malloc() both.
|
532
|
+
** Does not generate any runtime errors.
|
533
|
+
*/
|
534
|
+
void* mwMalloc( size_t, const char*, int );
|
535
|
+
void* mwMalloc_( size_t );
|
536
|
+
void* mwRealloc( void *, size_t, const char*, int );
|
537
|
+
void* mwRealloc_( void *, size_t );
|
538
|
+
void* mwCalloc( size_t, size_t, const char*, int );
|
539
|
+
void* mwCalloc_( size_t, size_t );
|
540
|
+
void mwFree( void*, const char*, int );
|
541
|
+
void mwFree_( void* );
|
542
|
+
char* mwStrdup( const char *, const char*, int );
|
543
|
+
|
544
|
+
/*
|
545
|
+
** Enable/disable precompiler block
|
546
|
+
** This block of defines and if(n)defs make sure that references
|
547
|
+
** to MEMWATCH is completely removed from the code if the MEMWATCH
|
548
|
+
** manifest constant is not defined.
|
549
|
+
*/
|
550
|
+
#ifndef __MEMWATCH_C
|
551
|
+
#ifdef MEMWATCH
|
552
|
+
|
553
|
+
#define mwASSERT(exp) while(mwAssert((int)(exp),#exp,__FILE__,__LINE__))
|
554
|
+
#ifndef MW_NOASSERT
|
555
|
+
#ifndef ASSERT
|
556
|
+
#define ASSERT mwASSERT
|
557
|
+
#endif /* !ASSERT */
|
558
|
+
#endif /* !MW_NOASSERT */
|
559
|
+
#define mwVERIFY(exp) while(mwVerify((int)(exp),#exp,__FILE__,__LINE__))
|
560
|
+
#ifndef MW_NOVERIFY
|
561
|
+
#ifndef VERIFY
|
562
|
+
#define VERIFY mwVERIFY
|
563
|
+
#endif /* !VERIFY */
|
564
|
+
#endif /* !MW_NOVERIFY */
|
565
|
+
#define mwTRACE mwTrace
|
566
|
+
#ifndef MW_NOTRACE
|
567
|
+
#ifndef TRACE
|
568
|
+
#define TRACE mwTRACE
|
569
|
+
#endif /* !TRACE */
|
570
|
+
#endif /* !MW_NOTRACE */
|
571
|
+
|
572
|
+
/* some compilers use a define and not a function */
|
573
|
+
/* for strdup(). */
|
574
|
+
#ifdef strdup
|
575
|
+
#undef strdup
|
576
|
+
#endif
|
577
|
+
|
578
|
+
#define malloc(n) mwMalloc(n,__FILE__,__LINE__)
|
579
|
+
#define strdup(p) mwStrdup(p,__FILE__,__LINE__)
|
580
|
+
#define realloc(p,n) mwRealloc(p,n,__FILE__,__LINE__)
|
581
|
+
#define calloc(n,m) mwCalloc(n,m,__FILE__,__LINE__)
|
582
|
+
#define free(p) mwFree(p,__FILE__,__LINE__)
|
583
|
+
#define CHECK() mwTest(__FILE__,__LINE__,MW_TEST_ALL)
|
584
|
+
#define CHECK_THIS(n) mwTest(__FILE__,__LINE__,n)
|
585
|
+
#define CHECK_BUFFER(b) mwTestBuffer(__FILE__,__LINE__,b)
|
586
|
+
#define MARK(p) mwMark(p,#p,__FILE__,__LINE__)
|
587
|
+
#define UNMARK(p) mwUnmark(p,__FILE__,__LINE__)
|
588
|
+
|
589
|
+
#else /* MEMWATCH */
|
590
|
+
|
591
|
+
#define mwASSERT(exp)
|
592
|
+
#ifndef MW_NOASSERT
|
593
|
+
#ifndef ASSERT
|
594
|
+
#define ASSERT mwASSERT
|
595
|
+
#endif /* !ASSERT */
|
596
|
+
#endif /* !MW_NOASSERT */
|
597
|
+
|
598
|
+
#define mwVERIFY(exp) exp
|
599
|
+
#ifndef MW_NOVERIFY
|
600
|
+
#ifndef VERIFY
|
601
|
+
#define VERIFY mwVERIFY
|
602
|
+
#endif /* !VERIFY */
|
603
|
+
#endif /* !MW_NOVERIFY */
|
604
|
+
|
605
|
+
/*lint -esym(773,mwTRACE) */
|
606
|
+
#define mwTRACE /*lint -save -e506 */ 1?(void)0:mwDummyTraceFunction /*lint -restore */
|
607
|
+
#ifndef MW_NOTRACE
|
608
|
+
#ifndef TRACE
|
609
|
+
/*lint -esym(773,TRACE) */
|
610
|
+
#define TRACE mwTRACE
|
611
|
+
#endif /* !TRACE */
|
612
|
+
#endif /* !MW_NOTRACE */
|
613
|
+
|
614
|
+
extern void mwDummyTraceFunction(const char *,...);
|
615
|
+
/*lint -save -e652 */
|
616
|
+
#define mwDoFlush(n)
|
617
|
+
#define mwPuts(s)
|
618
|
+
#define mwInit()
|
619
|
+
#define mwGrab(n)
|
620
|
+
#define mwDrop(n)
|
621
|
+
#define mwLimit(n)
|
622
|
+
#define mwTest(f,l)
|
623
|
+
#define mwSetOutFunc(f)
|
624
|
+
#define mwSetAriFunc(f)
|
625
|
+
#define mwDefaultAri()
|
626
|
+
#define mwNomansland()
|
627
|
+
#define mwStatistics(f)
|
628
|
+
#define mwMark(p,t,f,n) (p)
|
629
|
+
#define mwUnmark(p,f,n) (p)
|
630
|
+
#define mwMalloc(n,f,l) malloc(n)
|
631
|
+
#define mwStrdup(p,f,l) strdup(p)
|
632
|
+
#define mwRealloc(p,n,f,l) realloc(p,n)
|
633
|
+
#define mwCalloc(n,m,f,l) calloc(n,m)
|
634
|
+
#define mwFree(p) free(p)
|
635
|
+
#define mwMalloc_(n) malloc(n)
|
636
|
+
#define mwRealloc_(p,n) realloc(p,n)
|
637
|
+
#define mwCalloc_(n,m) calloc(n,m)
|
638
|
+
#define mwFree_(p) free(p)
|
639
|
+
#define mwAssert(e,es,f,l)
|
640
|
+
#define mwVerify(e,es,f,l) (e)
|
641
|
+
#define mwTrace mwDummyTrace
|
642
|
+
#define mwTestBuffer(f,l,b) (0)
|
643
|
+
#define CHECK()
|
644
|
+
#define CHECK_THIS(n)
|
645
|
+
#define CHECK_BUFFER(b)
|
646
|
+
#define MARK(p) (p)
|
647
|
+
#define UNMARK(p) (p)
|
648
|
+
/*lint -restore */
|
649
|
+
|
650
|
+
#endif /* MEMWATCH */
|
651
|
+
#endif /* !__MEMWATCH_C */
|
652
|
+
|
653
|
+
#ifdef __cplusplus
|
654
|
+
}
|
655
|
+
#endif
|
656
|
+
|
657
|
+
#if 0 /* 980317: disabled C++ */
|
658
|
+
|
659
|
+
/*
|
660
|
+
** C++ support section
|
661
|
+
** Implements the C++ support. Please note that in order to avoid
|
662
|
+
** messing up library classes, C++ support is disabled by default.
|
663
|
+
** You must NOT enable it until AFTER the inclusion of all header
|
664
|
+
** files belonging to code that are not compiled with MEMWATCH, and
|
665
|
+
** possibly for some that are! The reason for this is that a C++
|
666
|
+
** class may implement it's own new() function, and the preprocessor
|
667
|
+
** would substitute this crucial declaration for MEMWATCH new().
|
668
|
+
** You can forcibly deny C++ support by defining MEMWATCH_NOCPP.
|
669
|
+
** To enble C++ support, you must be compiling C++, MEMWATCH must
|
670
|
+
** be defined, MEMWATCH_NOCPP must not be defined, and finally,
|
671
|
+
** you must define 'new' to be 'mwNew', and 'delete' to be 'mwDelete'.
|
672
|
+
** Unlike C, C++ code can begin executing *way* before main(), for
|
673
|
+
** example if a global variable is created. For this reason, you can
|
674
|
+
** declare a global variable of the class 'MemWatch'. If this is
|
675
|
+
** is the first variable created, it will then check ALL C++ allocations
|
676
|
+
** and deallocations. Unfortunately, this evaluation order is not
|
677
|
+
** guaranteed by C++, though the compilers I've tried evaluates them
|
678
|
+
** in the order encountered.
|
679
|
+
*/
|
680
|
+
#ifdef __cplusplus
|
681
|
+
#ifndef __MEMWATCH_C
|
682
|
+
#ifdef MEMWATCH
|
683
|
+
#ifndef MEMWATCH_NOCPP
|
684
|
+
extern int mwNCur;
|
685
|
+
extern const char *mwNFile;
|
686
|
+
extern int mwNLine;
|
687
|
+
class MemWatch {
|
688
|
+
public:
|
689
|
+
MemWatch();
|
690
|
+
~MemWatch();
|
691
|
+
};
|
692
|
+
void * operator new(size_t);
|
693
|
+
void * operator new(size_t,const char *,int);
|
694
|
+
void * operator new[] (size_t,const char *,int); // hjc 07/16/02
|
695
|
+
void operator delete(void *);
|
696
|
+
#define mwNew new(__FILE__,__LINE__)
|
697
|
+
#define mwDelete (mwNCur=1,mwNFile=__FILE__,mwNLine=__LINE__),delete
|
698
|
+
#endif /* MEMWATCH_NOCPP */
|
699
|
+
#endif /* MEMWATCH */
|
700
|
+
#endif /* !__MEMWATCH_C */
|
701
|
+
#endif /* __cplusplus */
|
702
|
+
|
703
|
+
#endif /* 980317: disabled C++ */
|
704
|
+
|
705
|
+
#endif /* __MEMWATCH_H */
|
706
|
+
|
707
|
+
/* EOF MEMWATCH.H */
|