1 /* This module exports the C API to such Pure Software Inc. (tm) (now
2 * called Pure Atria Corporation) products as Purify (tm) and Quantify
3 * (tm). Other packages could be added, but I didn't have those products
4 * and thus lack the API documentation.
6 * Currently supported: Quantify 2.x, Purify 3.x
8 * You need to decide which products you want to incorporate into the
9 * module when you compile this file. The way to do this is to edit
10 * <Python>/Modules/Setup to pass the appropriate flags to the compiler.
11 * -DWITH_PURIFY compiles in the Purify support, and -DWITH_QUANTIFY
12 * compiles in the Quantify support. -DWITH_ALL_PURE compiles in both.
13 * You can also build a Purify'd or Quantify'd interpreter by passing in
14 * the LINKCC variable to make. E.g. if you want to build a Purify'd
15 * interpreter and are using gcc, build Python with this command:
17 * make LINKCC='purify gcc'
19 * It would be nice (and probably easy) to provide this file as a shared
20 * library, however since it doesn't appear that Pure gives us shared
21 * libraries of the stubs, it doesn't really matter. For now, you have to
22 * link this file in statically.
24 * Major bogosity. The purify.h header file exports purify_exit(), but
25 * guess what? It is not defined in the libpurify_stubs.a file! I tried
26 * to fake one here, hoping the Pure linker would Do The Right Thing when
27 * instrumented for Purify, but it doesn't seem to, so I don't export
28 * purify_exit() to the Python layer. In Python you should raise a
29 * SystemExit exception anyway.
31 * The actual purify.h and quantify.h files which embody the APIs are
32 * copyrighted by Pure Software, Inc. and are only attainable through them.
33 * This module assumes you have legally installed licenses of their
34 * software. Contact them on the Web via <http://www.pureatria.com/>
36 * Author: Barry Warsaw <bwarsaw@python.org>
37 * <bwarsaw@cnri.reston.va.us>
42 #if defined(WITH_PURIFY) || defined(WITH_ALL_PURE)
44 # define HAS_PURIFY_EXIT 0 /* See note at top of file */
45 # define PURE_PURIFY_VERSION 3 /* not provided by purify.h */
47 #if defined(WITH_QUANTIFY) || defined(WITH_ALL_PURE)
48 # include <quantify.h>
49 # define PURE_QUANTIFY_VERSION 2 /* not provided by quantify.h */
51 #if defined(PURIFY_H) || defined(QUANTIFY_H)
52 # define COMMON_PURE_FUNCTIONS
53 #endif /* PURIFY_H || QUANTIFY_H */
55 typedef int (*VoidArgFunc
)(void);
56 typedef int (*StringArgFunc
)(char*);
57 typedef int (*PrintfishFunc
)(const char*, ...);
58 typedef int (*StringIntArgFunc
)(const char*, int);
63 call_voidarg_function(func
, self
, args
)
70 if (!PyArg_ParseTuple(args
, ""))
74 return Py_BuildValue("i", status
);
78 call_stringarg_function(func
, self
, args
)
86 if (!PyArg_ParseTuple(args
, "s", &stringarg
))
89 status
= func(stringarg
);
90 return Py_BuildValue("i", status
);
94 call_stringorint_function(func
, self
, args
)
103 /* according to the quantify.h file, the argument to
104 * quantify_*_recording_system_call can be an integer or a string,
105 * but the functions are prototyped as taking a single char*
108 if (PyArg_ParseTuple(args
, "i", &intarg
))
109 /* func is prototyped as int(*)(char*)
110 * better shut up the compiler
112 status
= func((char*)intarg
);
116 if (!PyArg_ParseTuple(args
, "s", &stringarg
))
119 status
= func(stringarg
);
121 return Py_BuildValue("i", status
);
125 call_printfish_function(func
, self
, args
)
130 /* we support the printf() style vararg functions by requiring the
131 * formatting be done in Python. At the C level we pass just a string
132 * to the printf() style function.
137 if (!PyArg_ParseTuple(args
, "s", &argstring
))
140 status
= func("%s", argstring
);
141 return Py_BuildValue("i", status
);
145 call_intasaddr_function(func
, self
, args
)
153 if (!PyArg_ParseTuple(args
, "l", &memrep
))
156 id
= func((char*)memrep
);
157 return Py_BuildValue("i", id
);
161 call_stringandint_function(func
, self
, args
)
162 StringIntArgFunc func
;
170 if (!PyArg_ParseTuple(args
, "li", &srcrep
, &size
))
173 status
= func((char*)srcrep
, size
);
174 return Py_BuildValue("i", status
);
179 /* functions common to all products
181 * N.B. These printf() style functions are a bit of a kludge. Since the
182 * API doesn't provide vprintf versions of them, we can't call them
183 * directly. They don't support all the standard printf % modifiers
184 * anyway. The way to use these is to use Python's % string operator to do
185 * the formatting. By the time these functions get the thing to print,
186 * it's already a string, and they just use "%s" as the format string.
189 #ifdef COMMON_PURE_FUNCTIONS
192 pure_pure_logfile_printf(PyObject
* self
, PyObject
* args
)
194 return call_printfish_function(pure_logfile_printf
, self
, args
);
198 pure_pure_printf(PyObject
* self
, PyObject
* args
)
200 return call_printfish_function(pure_printf
, self
, args
);
204 pure_pure_printf_with_banner(PyObject
* self
, PyObject
* args
)
206 return call_printfish_function(pure_printf_with_banner
, self
, args
);
210 #endif /* COMMON_PURE_FUNCTIONS */
216 * N.B. There are some interfaces described in the purify.h file that are
217 * not described in the manual.
219 * Unsigned longs purify_report_{address,number,type,result} are not
220 * accessible from the Python layer since they seem mostly useful when
221 * purify_stop_here() is called by the (C) debugger. The same is true of
222 * the purify_stop_here_internal() function so it isn't exported either.
223 * And purify_stop_here() should never be called directly.
225 * The header file says purify_{new,all,clear_new}_reports() are obsolete
226 * so they aren't exported.
228 * None of the custom dynamic loader functions are exported.
230 * purify_unsafe_memcpy() isn't exported.
232 * purify_{start,size}_of_block() aren't exported.
234 * The manual that I have says that the prototype for the second argument
235 * to purify_map_pool is:
239 * but the purify.h file declares it as:
241 * void (*fn)(char*, int, void*)
243 * and does not explain what the other arguments are for. I support the
244 * latter but I don't know if I do it right or usefully.
246 * The header file says that purify_describe() returns a char* which is the
247 * pointer passed to it. The manual says it returns an int, but I believe
253 pure_purify_all_inuse(self
, args
)
257 return call_voidarg_function(purify_all_inuse
, self
, args
);
260 pure_purify_all_leaks(self
, args
)
264 return call_voidarg_function(purify_all_leaks
, self
, args
);
267 pure_purify_new_inuse(self
, args
)
271 return call_voidarg_function(purify_new_inuse
, self
, args
);
274 pure_purify_new_leaks(self
, args
)
278 return call_voidarg_function(purify_new_leaks
, self
, args
);
281 pure_purify_clear_inuse(self
, args
)
285 return call_voidarg_function(purify_clear_inuse
, self
, args
);
288 pure_purify_clear_leaks(self
, args
)
292 return call_voidarg_function(purify_clear_leaks
, self
, args
);
295 pure_purify_all_fds_inuse(self
, args
)
299 return call_voidarg_function(purify_all_fds_inuse
, self
, args
);
302 pure_purify_new_fds_inuse(self
, args
)
306 return call_voidarg_function(purify_new_fds_inuse
, self
, args
);
309 pure_purify_printf_with_call_chain(self
, args
)
313 return call_printfish_function(purify_printf_with_call_chain
,
317 pure_purify_set_pool_id(self
, args
)
324 if (!PyArg_ParseTuple(args
, "li", &memrep
, &id
))
327 purify_set_pool_id((char*)memrep
, id
);
332 pure_purify_get_pool_id(self
, args
)
336 return call_intasaddr_function(purify_get_pool_id
, self
, args
);
339 pure_purify_set_user_data(self
, args
)
346 if (!PyArg_ParseTuple(args
, "ll", &memrep
, &datarep
))
349 purify_set_user_data((char*)memrep
, (void*)datarep
);
354 pure_purify_get_user_data(self
, args
)
358 /* can't use call_intasaddr_function() since purify_get_user_data()
364 if (!PyArg_ParseTuple(args
, "l", &memrep
))
367 data
= purify_get_user_data((char*)memrep
);
368 return Py_BuildValue("l", (long)data
);
372 /* this global variable is shared by both mapping functions:
373 * pure_purify_map_pool() and pure_purify_map_pool_id(). Since they cache
374 * this variable it should be safe in the face of recursion or cross
377 * Further note that the prototype for the callback function is wrong in
378 * the Purify manual. The manual says the function takes a single char*,
379 * but the header file says it takes an additional int and void*. I have
380 * no idea what these are for!
382 static PyObject
* MapCallable
= NULL
;
385 map_pool_callback(mem
, user_size
, user_aux_data
)
390 long memrep
= (long)mem
;
391 long user_aux_data_rep
= (long)user_aux_data
;
393 PyObject
* memobj
= Py_BuildValue("lil", memrep
, user_size
,
399 result
= PyEval_CallObject(MapCallable
, memobj
);
405 pure_purify_map_pool(self
, args
)
409 /* cache global variable in case of recursion */
410 PyObject
* saved_callable
= MapCallable
;
411 PyObject
* arg_callable
;
414 if (!PyArg_ParseTuple(args
, "iO", &id
, &arg_callable
))
417 if (!PyCallable_Check(arg_callable
)) {
418 PyErr_SetString(PyExc_TypeError
,
419 "Second argument must be callable");
422 MapCallable
= arg_callable
;
423 purify_map_pool(id
, map_pool_callback
);
424 MapCallable
= saved_callable
;
431 PurifyMapPoolIdCallback(id
)
435 PyObject
* intobj
= Py_BuildValue("i", id
);
440 result
= PyEval_CallObject(MapCallable
, intobj
);
446 pure_purify_map_pool_id(self
, args
)
450 /* cache global variable in case of recursion */
451 PyObject
* saved_callable
= MapCallable
;
452 PyObject
* arg_callable
;
454 if (!PyArg_ParseTuple(args
, "O", &arg_callable
))
457 if (!PyCallable_Check(arg_callable
)) {
458 PyErr_SetString(PyExc_TypeError
, "Argument must be callable.");
462 MapCallable
= arg_callable
;
463 purify_map_pool_id(PurifyMapPoolIdCallback
);
464 MapCallable
= saved_callable
;
473 pure_purify_new_messages(self
, args
)
477 return call_voidarg_function(purify_new_messages
, self
, args
);
480 pure_purify_all_messages(self
, args
)
484 return call_voidarg_function(purify_all_messages
, self
, args
);
487 pure_purify_clear_messages(self
, args
)
491 return call_voidarg_function(purify_clear_messages
, self
, args
);
494 pure_purify_clear_new_messages(self
, args
)
498 return call_voidarg_function(purify_clear_new_messages
, self
, args
);
501 pure_purify_start_batch(self
, args
)
505 return call_voidarg_function(purify_start_batch
, self
, args
);
508 pure_purify_start_batch_show_first(self
, args
)
512 return call_voidarg_function(purify_start_batch_show_first
,
516 pure_purify_stop_batch(self
, args
)
520 return call_voidarg_function(purify_stop_batch
, self
, args
);
523 pure_purify_name_thread(self
, args
)
527 /* can't strictly use call_stringarg_function since
528 * purify_name_thread takes a const char*, not a char*
533 if (!PyArg_ParseTuple(args
, "s", &stringarg
))
536 status
= purify_name_thread(stringarg
);
537 return Py_BuildValue("i", status
);
540 pure_purify_watch(self
, args
)
544 return call_intasaddr_function(purify_watch
, self
, args
);
547 pure_purify_watch_1(self
, args
)
551 return call_intasaddr_function(purify_watch_1
, self
, args
);
554 pure_purify_watch_2(self
, args
)
558 return call_intasaddr_function(purify_watch_2
, self
, args
);
561 pure_purify_watch_4(self
, args
)
565 return call_intasaddr_function(purify_watch_4
, self
, args
);
568 pure_purify_watch_8(self
, args
)
572 return call_intasaddr_function(purify_watch_8
, self
, args
);
575 pure_purify_watch_w_1(self
, args
)
579 return call_intasaddr_function(purify_watch_w_1
, self
, args
);
582 pure_purify_watch_w_2(self
, args
)
586 return call_intasaddr_function(purify_watch_w_2
, self
, args
);
589 pure_purify_watch_w_4(self
, args
)
593 return call_intasaddr_function(purify_watch_w_4
, self
, args
);
596 pure_purify_watch_w_8(self
, args
)
600 return call_intasaddr_function(purify_watch_w_8
, self
, args
);
603 pure_purify_watch_r_1(self
, args
)
607 return call_intasaddr_function(purify_watch_r_1
, self
, args
);
610 pure_purify_watch_r_2(self
, args
)
614 return call_intasaddr_function(purify_watch_r_2
, self
, args
);
617 pure_purify_watch_r_4(self
, args
)
621 return call_intasaddr_function(purify_watch_r_4
, self
, args
);
624 pure_purify_watch_r_8(self
, args
)
628 return call_intasaddr_function(purify_watch_r_8
, self
, args
);
631 pure_purify_watch_rw_1(self
, args
)
635 return call_intasaddr_function(purify_watch_rw_1
, self
, args
);
638 pure_purify_watch_rw_2(self
, args
)
642 return call_intasaddr_function(purify_watch_rw_2
, self
, args
);
645 pure_purify_watch_rw_4(self
, args
)
649 return call_intasaddr_function(purify_watch_rw_4
, self
, args
);
652 pure_purify_watch_rw_8(self
, args
)
656 return call_intasaddr_function(purify_watch_rw_8
, self
, args
);
660 pure_purify_watch_n(self
, args
)
669 if (!PyArg_ParseTuple(args
, "lis", &addrrep
, &size
, &type
))
672 status
= purify_watch_n((char*)addrrep
, size
, type
);
673 return Py_BuildValue("i", status
);
677 pure_purify_watch_info(self
, args
)
681 return call_voidarg_function(purify_watch_info
, self
, args
);
685 pure_purify_watch_remove(self
, args
)
692 if (!PyArg_ParseTuple(args
, "i", &watchno
))
695 status
= purify_watch_remove(watchno
);
696 return Py_BuildValue("i", status
);
700 pure_purify_watch_remove_all(self
, args
)
704 return call_voidarg_function(purify_watch_remove_all
, self
, args
);
707 pure_purify_describe(self
, args
)
714 if (!PyArg_ParseTuple(args
, "l", &addrrep
))
717 rtn
= purify_describe((char*)addrrep
);
718 return Py_BuildValue("l", (long)rtn
);
722 pure_purify_what_colors(self
, args
)
730 if (!PyArg_ParseTuple(args
, "li", &addrrep
, &size
))
733 status
= purify_what_colors((char*)addrrep
, size
);
734 return Py_BuildValue("i", status
);
738 pure_purify_is_running(self
, args
)
742 return call_voidarg_function(purify_is_running
, self
, args
);
746 pure_purify_assert_is_readable(self
, args
)
750 return call_stringandint_function(purify_assert_is_readable
,
754 pure_purify_assert_is_writable(self
, args
)
758 return call_stringandint_function(purify_assert_is_writable
,
764 /* I wish I could include this, but I can't. See the notes at the top of
769 pure_purify_exit(self
, args
)
775 if (!PyArg_ParseTuple(args
, "i", &status
))
778 /* purify_exit doesn't always act like exit(). See the manual */
783 #endif /* HAS_PURIFY_EXIT */
785 #endif /* PURIFY_H */
789 /* Quantify functions
791 * N.B. Some of these functions are only described in the quantify.h file,
792 * not in the version of the hardcopy manual that I had. If you're not
793 * sure what some of these do, check the header file, it is documented
796 * None of the custom dynamic loader functions are exported.
802 pure_quantify_is_running(self
, args
)
806 return call_voidarg_function(quantify_is_running
, self
, args
);
809 pure_quantify_help(self
, args
)
813 return call_voidarg_function(quantify_help
, self
, args
);
816 pure_quantify_print_recording_state(self
, args
)
820 return call_voidarg_function(quantify_print_recording_state
,
824 pure_quantify_start_recording_data(self
, args
)
828 return call_voidarg_function(quantify_start_recording_data
,
832 pure_quantify_stop_recording_data(self
, args
)
836 return call_voidarg_function(quantify_stop_recording_data
, self
, args
);
839 pure_quantify_is_recording_data(self
, args
)
843 return call_voidarg_function(quantify_is_recording_data
, self
, args
);
846 pure_quantify_start_recording_system_calls(self
, args
)
850 return call_voidarg_function(quantify_start_recording_system_calls
,
854 pure_quantify_stop_recording_system_calls(self
, args
)
858 return call_voidarg_function(quantify_stop_recording_system_calls
,
862 pure_quantify_is_recording_system_calls(self
, args
)
866 return call_voidarg_function(quantify_is_recording_system_calls
,
870 pure_quantify_start_recording_system_call(self
, args
)
874 return call_stringorint_function(quantify_start_recording_system_call
,
878 pure_quantify_stop_recording_system_call(self
, args
)
882 return call_stringorint_function(quantify_stop_recording_system_call
,
886 pure_quantify_is_recording_system_call(self
, args
)
890 return call_stringorint_function(quantify_is_recording_system_call
,
894 pure_quantify_start_recording_dynamic_library_data(self
, args
)
898 return call_voidarg_function(
899 quantify_start_recording_dynamic_library_data
,
903 pure_quantify_stop_recording_dynamic_library_data(self
, args
)
907 return call_voidarg_function(
908 quantify_stop_recording_dynamic_library_data
,
912 pure_quantify_is_recording_dynamic_library_data(self
, args
)
916 return call_voidarg_function(
917 quantify_is_recording_dynamic_library_data
,
921 pure_quantify_start_recording_register_window_traps(self
, args
)
925 return call_voidarg_function(
926 quantify_start_recording_register_window_traps
,
930 pure_quantify_stop_recording_register_window_traps(self
, args
)
934 return call_voidarg_function(
935 quantify_stop_recording_register_window_traps
,
939 pure_quantify_is_recording_register_window_traps(self
, args
)
943 return call_voidarg_function(
944 quantify_is_recording_register_window_traps
,
948 pure_quantify_disable_recording_data(self
, args
)
952 return call_voidarg_function(quantify_disable_recording_data
,
956 pure_quantify_clear_data(self
, args
)
960 return call_voidarg_function(quantify_clear_data
, self
, args
);
963 pure_quantify_save_data(self
, args
)
967 return call_voidarg_function(quantify_save_data
, self
, args
);
970 pure_quantify_save_data_to_file(self
, args
)
974 return call_stringarg_function(quantify_save_data_to_file
, self
, args
);
977 pure_quantify_add_annotation(self
, args
)
981 return call_stringarg_function(quantify_add_annotation
, self
, args
);
984 #endif /* QUANTIFY_H */
988 /* external interface
990 static struct PyMethodDef
992 #ifdef COMMON_PURE_FUNCTIONS
993 {"pure_logfile_printf", pure_pure_logfile_printf
, 1},
994 {"pure_printf", pure_pure_printf
, 1},
995 {"pure_printf_with_banner", pure_pure_printf_with_banner
, 1},
996 #endif /* COMMON_PURE_FUNCTIONS */
998 {"purify_all_inuse", pure_purify_all_inuse
, 1},
999 {"purify_all_leaks", pure_purify_all_leaks
, 1},
1000 {"purify_new_inuse", pure_purify_new_inuse
, 1},
1001 {"purify_new_leaks", pure_purify_new_leaks
, 1},
1002 {"purify_clear_inuse", pure_purify_clear_inuse
, 1},
1003 {"purify_clear_leaks", pure_purify_clear_leaks
, 1},
1004 {"purify_all_fds_inuse", pure_purify_all_fds_inuse
, 1},
1005 {"purify_new_fds_inuse", pure_purify_new_fds_inuse
, 1},
1007 {"purify_logfile_printf", pure_pure_logfile_printf
, 1},
1008 {"purify_printf", pure_pure_printf
, 1},
1009 {"purify_printf_with_banner", pure_pure_printf_with_banner
, 1},
1011 {"purify_printf_with_call_chain", pure_purify_printf_with_call_chain
, 1},
1012 {"purify_set_pool_id", pure_purify_set_pool_id
, 1},
1013 {"purify_get_pool_id", pure_purify_get_pool_id
, 1},
1014 {"purify_set_user_data", pure_purify_set_user_data
, 1},
1015 {"purify_get_user_data", pure_purify_get_user_data
, 1},
1016 {"purify_map_pool", pure_purify_map_pool
, 1},
1017 {"purify_map_pool_id", pure_purify_map_pool_id
, 1},
1018 {"purify_new_messages", pure_purify_new_messages
, 1},
1019 {"purify_all_messages", pure_purify_all_messages
, 1},
1020 {"purify_clear_messages", pure_purify_clear_messages
, 1},
1021 {"purify_clear_new_messages", pure_purify_clear_new_messages
, 1},
1022 {"purify_start_batch", pure_purify_start_batch
, 1},
1023 {"purify_start_batch_show_first", pure_purify_start_batch_show_first
, 1},
1024 {"purify_stop_batch", pure_purify_stop_batch
, 1},
1025 {"purify_name_thread", pure_purify_name_thread
, 1},
1026 {"purify_watch", pure_purify_watch
, 1},
1027 {"purify_watch_1", pure_purify_watch_1
, 1},
1028 {"purify_watch_2", pure_purify_watch_2
, 1},
1029 {"purify_watch_4", pure_purify_watch_4
, 1},
1030 {"purify_watch_8", pure_purify_watch_8
, 1},
1031 {"purify_watch_w_1", pure_purify_watch_w_1
, 1},
1032 {"purify_watch_w_2", pure_purify_watch_w_2
, 1},
1033 {"purify_watch_w_4", pure_purify_watch_w_4
, 1},
1034 {"purify_watch_w_8", pure_purify_watch_w_8
, 1},
1035 {"purify_watch_r_1", pure_purify_watch_r_1
, 1},
1036 {"purify_watch_r_2", pure_purify_watch_r_2
, 1},
1037 {"purify_watch_r_4", pure_purify_watch_r_4
, 1},
1038 {"purify_watch_r_8", pure_purify_watch_r_8
, 1},
1039 {"purify_watch_rw_1", pure_purify_watch_rw_1
, 1},
1040 {"purify_watch_rw_2", pure_purify_watch_rw_2
, 1},
1041 {"purify_watch_rw_4", pure_purify_watch_rw_4
, 1},
1042 {"purify_watch_rw_8", pure_purify_watch_rw_8
, 1},
1043 {"purify_watch_n", pure_purify_watch_n
, 1},
1044 {"purify_watch_info", pure_purify_watch_info
, 1},
1045 {"purify_watch_remove", pure_purify_watch_remove
, 1},
1046 {"purify_watch_remove_all", pure_purify_watch_remove_all
, 1},
1047 {"purify_describe", pure_purify_describe
, 1},
1048 {"purify_what_colors", pure_purify_what_colors
, 1},
1049 {"purify_is_running", pure_purify_is_running
, 1},
1050 {"purify_assert_is_readable", pure_purify_assert_is_readable
, 1},
1051 {"purify_assert_is_writable", pure_purify_assert_is_writable
, 1},
1053 /* I wish I could include this, but I can't. See the notes at the
1056 {"purify_exit", pure_purify_exit
, 1},
1057 #endif /* HAS_PURIFY_EXIT */
1058 #endif /* PURIFY_H */
1060 {"quantify_is_running", pure_quantify_is_running
, 1},
1061 {"quantify_help", pure_quantify_help
, 1},
1062 {"quantify_print_recording_state", pure_quantify_print_recording_state
, 1},
1063 {"quantify_start_recording_data", pure_quantify_start_recording_data
, 1},
1064 {"quantify_stop_recording_data", pure_quantify_stop_recording_data
, 1},
1065 {"quantify_is_recording_data", pure_quantify_is_recording_data
, 1},
1066 {"quantify_start_recording_system_calls",
1067 pure_quantify_start_recording_system_calls
, 1},
1068 {"quantify_stop_recording_system_calls",
1069 pure_quantify_stop_recording_system_calls
, 1},
1070 {"quantify_is_recording_system_calls",
1071 pure_quantify_is_recording_system_calls
, 1},
1072 {"quantify_start_recording_system_call",
1073 pure_quantify_start_recording_system_call
, 1},
1074 {"quantify_stop_recording_system_call",
1075 pure_quantify_stop_recording_system_call
, 1},
1076 {"quantify_is_recording_system_call",
1077 pure_quantify_is_recording_system_call
, 1},
1078 {"quantify_start_recording_dynamic_library_data",
1079 pure_quantify_start_recording_dynamic_library_data
, 1},
1080 {"quantify_stop_recording_dynamic_library_data",
1081 pure_quantify_stop_recording_dynamic_library_data
, 1},
1082 {"quantify_is_recording_dynamic_library_data",
1083 pure_quantify_is_recording_dynamic_library_data
, 1},
1084 {"quantify_start_recording_register_window_traps",
1085 pure_quantify_start_recording_register_window_traps
, 1},
1086 {"quantify_stop_recording_register_window_traps",
1087 pure_quantify_stop_recording_register_window_traps
, 1},
1088 {"quantify_is_recording_register_window_traps",
1089 pure_quantify_is_recording_register_window_traps
, 1},
1090 {"quantify_disable_recording_data",
1091 pure_quantify_disable_recording_data
, 1},
1092 {"quantify_clear_data", pure_quantify_clear_data
, 1},
1093 {"quantify_save_data", pure_quantify_save_data
, 1},
1094 {"quantify_save_data_to_file", pure_quantify_save_data_to_file
, 1},
1095 {"quantify_add_annotation", pure_quantify_add_annotation
, 1},
1096 #endif /* QUANTIFY_H */
1097 {NULL
, NULL
} /* sentinel */
1108 PyObject
*v
= PyInt_FromLong(val
);
1110 (void)PyDict_SetItemString(d
, name
, v
);
1121 m
= Py_InitModule("pure", pure_methods
);
1122 d
= PyModule_GetDict(m
);
1124 /* this is bogus because we should be able to find this information
1125 * out from the header files. Pure's current versions don't
1126 * include this information!
1128 #ifdef PURE_PURIFY_VERSION
1129 ins(d
, "PURIFY_VERSION", PURE_PURIFY_VERSION
);
1131 PyDict_SetItemString(d
, "PURIFY_VERSION", Py_None
);
1134 /* these aren't terribly useful because purify_exit() isn't
1135 * exported correctly. See the note at the top of the file.
1137 #ifdef PURIFY_EXIT_ERRORS
1138 ins(d
, "PURIFY_EXIT_ERRORS", PURIFY_EXIT_ERRORS
);
1140 #ifdef PURIFY_EXIT_LEAKS
1141 ins(d
, "PURIFY_EXIT_LEAKS", PURIFY_EXIT_LEAKS
);
1143 #ifdef PURIFY_EXIT_PLEAKS
1144 ins(d
, "PURIFY_EXIT_PLEAKS", PURIFY_EXIT_PLEAKS
);
1148 #ifdef PURE_QUANTIFY_VERSION
1149 ins(d
, "QUANTIFY_VERSION", PURE_QUANTIFY_VERSION
);
1151 PyDict_SetItemString(d
, "QUANTIFY_VERSION", Py_None
);
1153 if (PyErr_Occurred())
1154 Py_FatalError("couldn't initialize the pure module");