blob: ee80a2f107e56a80ecc267436cdcb59fc2992b77 [file] [log] [blame]
Barry Warsawe886ea91997-01-17 00:01:33 +00001/* 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.
5 *
6 * Currently supported: Quantify 2.x, Purify 3.x
7 *
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:
16 *
17 * make LINKCC='purify gcc'
18 *
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.
23 *
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.
30 *
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/>
35 *
36 * Author: Barry Warsaw <bwarsaw@python.org>
37 * <bwarsaw@cnri.reston.va.us>
38 */
39
40#include "Python.h"
41
42#if defined(WITH_PURIFY) || defined(WITH_ALL_PURE)
43# include <purify.h>
44# define HAS_PURIFY_EXIT 0 /* See note at top of file */
45# define PURE_PURIFY_VERSION 3 /* not provided by purify.h */
46#endif
47#if defined(WITH_QUANTIFY) || defined(WITH_ALL_PURE)
48# include <quantify.h>
49# define PURE_QUANTIFY_VERSION 2 /* not provided by quantify.h */
50#endif
51#if defined(PURIFY_H) || defined(QUANTIFY_H)
52# define COMMON_PURE_FUNCTIONS
53#endif /* PURIFY_H || QUANTIFY_H */
54
55typedef int (*VoidArgFunc)(void);
56typedef int (*StringArgFunc)(char*);
57typedef int (*PrintfishFunc)(const char*, ...);
58typedef int (*StringIntArgFunc)(const char*, int);
59
60
61
62static PyObject*
63call_voidarg_function(func, self, args)
64 VoidArgFunc func;
65 PyObject *self;
66 PyObject *args;
67{
68 int status;
69
70 if (!PyArg_ParseTuple(args, ""))
71 return NULL;
72
73 status = func();
74 return Py_BuildValue("i", status);
75}
76
77static PyObject*
78call_stringarg_function(func, self, args)
79 StringArgFunc func;
80 PyObject *self;
81 PyObject *args;
82{
83 int status;
84 char* stringarg;
85
86 if (!PyArg_ParseTuple(args, "s", &stringarg))
87 return NULL;
88
89 status = func(stringarg);
90 return Py_BuildValue("i", status);
91}
92
93static PyObject*
94call_stringorint_function(func, self, args)
95 StringArgFunc func;
96 PyObject *self;
97 PyObject *args;
98{
99 int status;
100 int intarg;
101 char* stringarg;
102
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*
106 * argument. Yikes!
107 */
108 if (PyArg_ParseTuple(args, "i", &intarg))
109 /* func is prototyped as int(*)(char*)
110 * better shut up the compiler
111 */
112 status = func((char*)intarg);
113
114 else {
115 PyErr_Clear();
116 if (!PyArg_ParseTuple(args, "s", &stringarg))
117 return NULL;
118 else
119 status = func(stringarg);
120 }
121 return Py_BuildValue("i", status);
122}
123
124static PyObject*
125call_printfish_function(func, self, args)
126 PrintfishFunc func;
127 PyObject *self;
128 PyObject *args;
129{
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.
133 */
134 int status;
135 char* argstring;
136
137 if (!PyArg_ParseTuple(args, "s", &argstring))
138 return NULL;
139
140 status = func("%s", argstring);
141 return Py_BuildValue("i", status);
142}
143
144static PyObject*
145call_intasaddr_function(func, self, args)
146 StringArgFunc func;
147 PyObject *self;
148 PyObject *args;
149{
150 long memrep;
151 int id;
152
153 if (!PyArg_ParseTuple(args, "l", &memrep))
154 return NULL;
155
156 id = func((char*)memrep);
157 return Py_BuildValue("i", id);
158}
159
160static PyObject*
161call_stringandint_function(func, self, args)
162 StringIntArgFunc func;
163 PyObject *self;
164 PyObject *args;
165{
166 long srcrep;
167 int size;
168 int status;
169
170 if (!PyArg_ParseTuple(args, "li", &srcrep, &size))
171 return NULL;
172
173 status = func((char*)srcrep, size);
174 return Py_BuildValue("i", status);
175}
176
177
178
179/* functions common to all products
180 *
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.
187 */
188
189#ifdef COMMON_PURE_FUNCTIONS
190
191static PyObject*
192pure_pure_logfile_printf(PyObject* self, PyObject* args)
193{
194 return call_printfish_function(pure_logfile_printf, self, args);
195}
196
197static PyObject*
198pure_pure_printf(PyObject* self, PyObject* args)
199{
200 return call_printfish_function(pure_printf, self, args);
201}
202
203static PyObject*
204pure_pure_printf_with_banner(PyObject* self, PyObject* args)
205{
206 return call_printfish_function(pure_printf_with_banner, self, args);
207}
208
209
210#endif /* COMMON_PURE_FUNCTIONS */
211
212
213
214/* Purify functions
215 *
216 * N.B. There are some interfaces described in the purify.h file that are
217 * not described in the manual.
218 *
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.
224 *
225 * The header file says purify_{new,all,clear_new}_reports() are obsolete
226 * so they aren't exported.
227 *
228 * None of the custom dynamic loader functions are exported.
229 *
230 * purify_unsafe_memcpy() isn't exported.
231 *
232 * purify_{start,size}_of_block() aren't exported.
233 *
234 * The manual that I have says that the prototype for the second argument
235 * to purify_map_pool is:
236 *
237 * void (*fn)(char*)
238 *
239 * but the purify.h file declares it as:
240 *
241 * void (*fn)(char*, int, void*)
242 *
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.
245 *
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
248 * that is a typo.
249 */
250#ifdef PURIFY_H
251
252static PyObject*
253pure_purify_all_inuse(self, args)
254 PyObject *self;
255 PyObject *args;
256{
257 return call_voidarg_function(purify_all_inuse, self, args);
258}
259static PyObject*
260pure_purify_all_leaks(self, args)
261 PyObject *self;
262 PyObject *args;
263{
264 return call_voidarg_function(purify_all_leaks, self, args);
265}
266static PyObject*
267pure_purify_new_inuse(self, args)
268 PyObject *self;
269 PyObject *args;
270{
271 return call_voidarg_function(purify_new_inuse, self, args);
272}
273static PyObject*
274pure_purify_new_leaks(self, args)
275 PyObject *self;
276 PyObject *args;
277{
278 return call_voidarg_function(purify_new_leaks, self, args);
279}
280static PyObject*
281pure_purify_clear_inuse(self, args)
282 PyObject *self;
283 PyObject *args;
284{
285 return call_voidarg_function(purify_clear_inuse, self, args);
286}
287static PyObject*
288pure_purify_clear_leaks(self, args)
289 PyObject *self;
290 PyObject *args;
291{
292 return call_voidarg_function(purify_clear_leaks, self, args);
293}
294static PyObject*
295pure_purify_all_fds_inuse(self, args)
296 PyObject *self;
297 PyObject *args;
298{
299 return call_voidarg_function(purify_all_fds_inuse, self, args);
300}
301static PyObject*
302pure_purify_new_fds_inuse(self, args)
303 PyObject *self;
304 PyObject *args;
305{
306 return call_voidarg_function(purify_new_fds_inuse, self, args);
307}
308static PyObject*
309pure_purify_printf_with_call_chain(self, args)
310 PyObject *self;
311 PyObject *args;
312{
313 return call_printfish_function(purify_printf_with_call_chain,
314 self, args);
315}
316static PyObject*
317pure_purify_set_pool_id(self, args)
318 PyObject *self;
319 PyObject *args;
320{
321 long memrep;
322 int id;
323
324 if (!PyArg_ParseTuple(args, "li", &memrep, &id))
325 return NULL;
326
327 purify_set_pool_id((char*)memrep, id);
328 Py_INCREF(Py_None);
329 return Py_None;
330}
331static PyObject*
332pure_purify_get_pool_id(self, args)
333 PyObject *self;
334 PyObject *args;
335{
336 return call_intasaddr_function(purify_get_pool_id, self, args);
337}
338static PyObject*
339pure_purify_set_user_data(self, args)
340 PyObject *self;
341 PyObject *args;
342{
343 long memrep;
344 long datarep;
345
346 if (!PyArg_ParseTuple(args, "ll", &memrep, &datarep))
347 return NULL;
348
349 purify_set_user_data((char*)memrep, (void*)datarep);
350 Py_INCREF(Py_None);
351 return Py_None;
352}
353static PyObject*
354pure_purify_get_user_data(self, args)
355 PyObject *self;
356 PyObject *args;
357{
358 /* can't use call_intasaddr_function() since purify_get_user_data()
359 * returns a void*
360 */
361 long memrep;
362 void* data;
363
364 if (!PyArg_ParseTuple(args, "l", &memrep))
365 return NULL;
366
367 data = purify_get_user_data((char*)memrep);
368 return Py_BuildValue("l", (long)data);
369}
370
371
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
375 * calling.
376 *
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!
381 */
382static PyObject* MapCallable = NULL;
383
384static void
385map_pool_callback(mem, user_size, user_aux_data)
386 char* mem;
387 int user_size;
388 void *user_aux_data;
389{
390 long memrep = (long)mem;
391 long user_aux_data_rep = (long)user_aux_data;
392 PyObject* result;
393 PyObject* memobj = Py_BuildValue("lil", memrep, user_size,
394 user_aux_data_rep);
395
396 if (memobj == NULL)
397 return;
398
399 result = PyEval_CallObject(MapCallable, memobj);
400 Py_DECREF(result);
401 Py_DECREF(memobj);
402}
403
404static PyObject*
405pure_purify_map_pool(self, args)
406 PyObject *self;
407 PyObject *args;
408{
409 /* cache global variable in case of recursion */
410 PyObject* saved_callable = MapCallable;
411 PyObject* arg_callable;
412 int id;
413
414 if (!PyArg_ParseTuple(args, "iO", &id, &arg_callable))
415 return NULL;
416
417 if (!PyCallable_Check(arg_callable)) {
418 PyErr_SetString(PyExc_TypeError,
419 "Second argument must be callable");
420 return NULL;
421 }
422 MapCallable = arg_callable;
423 purify_map_pool(id, map_pool_callback);
424 MapCallable = saved_callable;
425
426 Py_INCREF(Py_None);
427 return Py_None;
428}
429
430static void
431PurifyMapPoolIdCallback(id)
432 int id;
433{
434 PyObject* result;
435 PyObject* intobj = Py_BuildValue("i", id);
436
437 if (intobj == NULL)
438 return;
439
440 result = PyEval_CallObject(MapCallable, intobj);
441 Py_DECREF(result);
442 Py_DECREF(intobj);
443}
444
445static PyObject*
446pure_purify_map_pool_id(self, args)
447 PyObject *self;
448 PyObject *args;
449{
450 /* cache global variable in case of recursion */
451 PyObject* saved_callable = MapCallable;
452 PyObject* arg_callable;
453
454 if (!PyArg_ParseTuple(args, "O", &arg_callable))
455 return NULL;
456
457 if (!PyCallable_Check(arg_callable)) {
458 PyErr_SetString(PyExc_TypeError, "Argument must be callable.");
459 return NULL;
460 }
461
462 MapCallable = arg_callable;
463 purify_map_pool_id(PurifyMapPoolIdCallback);
464 MapCallable = saved_callable;
465
466 Py_INCREF(Py_None);
467 return Py_None;
468}
469
470
471
472static PyObject*
473pure_purify_new_messages(self, args)
474 PyObject *self;
475 PyObject *args;
476{
477 return call_voidarg_function(purify_new_messages, self, args);
478}
479static PyObject*
480pure_purify_all_messages(self, args)
481 PyObject *self;
482 PyObject *args;
483{
484 return call_voidarg_function(purify_all_messages, self, args);
485}
486static PyObject*
487pure_purify_clear_messages(self, args)
488 PyObject *self;
489 PyObject *args;
490{
491 return call_voidarg_function(purify_clear_messages, self, args);
492}
493static PyObject*
494pure_purify_clear_new_messages(self, args)
495 PyObject *self;
496 PyObject *args;
497{
498 return call_voidarg_function(purify_clear_new_messages, self, args);
499}
500static PyObject*
501pure_purify_start_batch(self, args)
502 PyObject *self;
503 PyObject *args;
504{
505 return call_voidarg_function(purify_start_batch, self, args);
506}
507static PyObject*
508pure_purify_start_batch_show_first(self, args)
509 PyObject *self;
510 PyObject *args;
511{
512 return call_voidarg_function(purify_start_batch_show_first,
513 self, args);
514}
515static PyObject*
516pure_purify_stop_batch(self, args)
517 PyObject *self;
518 PyObject *args;
519{
520 return call_voidarg_function(purify_stop_batch, self, args);
521}
522static PyObject*
523pure_purify_name_thread(self, args)
524 PyObject *self;
525 PyObject *args;
526{
527 /* can't strictly use call_stringarg_function since
528 * purify_name_thread takes a const char*, not a char*
529 */
530 int status;
531 char* stringarg;
532
533 if (!PyArg_ParseTuple(args, "s", &stringarg))
534 return NULL;
535
536 status = purify_name_thread(stringarg);
537 return Py_BuildValue("i", status);
538}
539static PyObject*
540pure_purify_watch(self, args)
541 PyObject *self;
542 PyObject *args;
543{
544 return call_intasaddr_function(purify_watch, self, args);
545}
546static PyObject*
547pure_purify_watch_1(self, args)
548 PyObject *self;
549 PyObject *args;
550{
551 return call_intasaddr_function(purify_watch_1, self, args);
552}
553static PyObject*
554pure_purify_watch_2(self, args)
555 PyObject *self;
556 PyObject *args;
557{
558 return call_intasaddr_function(purify_watch_2, self, args);
559}
560static PyObject*
561pure_purify_watch_4(self, args)
562 PyObject *self;
563 PyObject *args;
564{
565 return call_intasaddr_function(purify_watch_4, self, args);
566}
567static PyObject*
568pure_purify_watch_8(self, args)
569 PyObject *self;
570 PyObject *args;
571{
572 return call_intasaddr_function(purify_watch_8, self, args);
573}
574static PyObject*
575pure_purify_watch_w_1(self, args)
576 PyObject *self;
577 PyObject *args;
578{
579 return call_intasaddr_function(purify_watch_w_1, self, args);
580}
581static PyObject*
582pure_purify_watch_w_2(self, args)
583 PyObject *self;
584 PyObject *args;
585{
586 return call_intasaddr_function(purify_watch_w_2, self, args);
587}
588static PyObject*
589pure_purify_watch_w_4(self, args)
590 PyObject *self;
591 PyObject *args;
592{
593 return call_intasaddr_function(purify_watch_w_4, self, args);
594}
595static PyObject*
596pure_purify_watch_w_8(self, args)
597 PyObject *self;
598 PyObject *args;
599{
600 return call_intasaddr_function(purify_watch_w_8, self, args);
601}
602static PyObject*
603pure_purify_watch_r_1(self, args)
604 PyObject *self;
605 PyObject *args;
606{
607 return call_intasaddr_function(purify_watch_r_1, self, args);
608}
609static PyObject*
610pure_purify_watch_r_2(self, args)
611 PyObject *self;
612 PyObject *args;
613{
614 return call_intasaddr_function(purify_watch_r_2, self, args);
615}
616static PyObject*
617pure_purify_watch_r_4(self, args)
618 PyObject *self;
619 PyObject *args;
620{
621 return call_intasaddr_function(purify_watch_r_4, self, args);
622}
623static PyObject*
624pure_purify_watch_r_8(self, args)
625 PyObject *self;
626 PyObject *args;
627{
628 return call_intasaddr_function(purify_watch_r_8, self, args);
629}
630static PyObject*
631pure_purify_watch_rw_1(self, args)
632 PyObject *self;
633 PyObject *args;
634{
635 return call_intasaddr_function(purify_watch_rw_1, self, args);
636}
637static PyObject*
638pure_purify_watch_rw_2(self, args)
639 PyObject *self;
640 PyObject *args;
641{
642 return call_intasaddr_function(purify_watch_rw_2, self, args);
643}
644static PyObject*
645pure_purify_watch_rw_4(self, args)
646 PyObject *self;
647 PyObject *args;
648{
649 return call_intasaddr_function(purify_watch_rw_4, self, args);
650}
651static PyObject*
652pure_purify_watch_rw_8(self, args)
653 PyObject *self;
654 PyObject *args;
655{
656 return call_intasaddr_function(purify_watch_rw_8, self, args);
657}
658
659static PyObject*
660pure_purify_watch_n(self, args)
661 PyObject *self;
662 PyObject *args;
663{
664 long addrrep;
665 unsigned int size;
666 char* type;
667 int status;
668
669 if (!PyArg_ParseTuple(args, "lis", &addrrep, &size, &type))
670 return NULL;
671
672 status = purify_watch_n((char*)addrrep, size, type);
673 return Py_BuildValue("i", status);
674}
675
676static PyObject*
677pure_purify_watch_info(self, args)
678 PyObject *self;
679 PyObject *args;
680{
681 return call_voidarg_function(purify_watch_info, self, args);
682}
683
684static PyObject*
685pure_purify_watch_remove(self, args)
686 PyObject *self;
687 PyObject *args;
688{
689 int watchno;
690 int status;
691
692 if (!PyArg_ParseTuple(args, "i", &watchno))
693 return NULL;
694
695 status = purify_watch_remove(watchno);
696 return Py_BuildValue("i", status);
697}
698
699static PyObject*
700pure_purify_watch_remove_all(self, args)
701 PyObject *self;
702 PyObject *args;
703{
704 return call_voidarg_function(purify_watch_remove_all, self, args);
705}
706static PyObject*
707pure_purify_describe(self, args)
708 PyObject *self;
709 PyObject *args;
710{
711 long addrrep;
712 char* rtn;
713
714 if (!PyArg_ParseTuple(args, "l", &addrrep))
715 return NULL;
716
717 rtn = purify_describe((char*)addrrep);
718 return Py_BuildValue("l", (long)rtn);
719}
720
721static PyObject*
722pure_purify_what_colors(self, args)
723 PyObject *self;
724 PyObject *args;
725{
726 long addrrep;
727 unsigned int size;
728 int status;
729
730 if (!PyArg_ParseTuple(args, "li", &addrrep, &size))
731 return NULL;
732
733 status = purify_what_colors((char*)addrrep, size);
734 return Py_BuildValue("i", status);
735}
736
737static PyObject*
738pure_purify_is_running(self, args)
739 PyObject *self;
740 PyObject *args;
741{
742 return call_voidarg_function(purify_is_running, self, args);
743}
744
745static PyObject*
746pure_purify_assert_is_readable(self, args)
747 PyObject *self;
748 PyObject *args;
749{
750 return call_stringandint_function(purify_assert_is_readable,
751 self, args);
752}
753static PyObject*
754pure_purify_assert_is_writable(self, args)
755 PyObject *self;
756 PyObject *args;
757{
758 return call_stringandint_function(purify_assert_is_writable,
759 self, args);
760}
761
762#if HAS_PURIFY_EXIT
763
764/* I wish I could include this, but I can't. See the notes at the top of
765 * the file.
766 */
767
768static PyObject*
769pure_purify_exit(self, args)
770 PyObject *self;
771 PyObject *args;
772{
773 int status;
774
775 if (!PyArg_ParseTuple(args, "i", &status))
776 return NULL;
777
778 /* purify_exit doesn't always act like exit(). See the manual */
779 purify_exit(status);
780 Py_INCREF(Py_None);
781 return Py_None;
782}
783#endif /* HAS_PURIFY_EXIT */
784
785#endif /* PURIFY_H */
786
787
788
789/* Quantify functions
790 *
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
794 * fairly well.
795 *
796 * None of the custom dynamic loader functions are exported.
797 *
798 */
799#ifdef QUANTIFY_H
800
801static PyObject*
802pure_quantify_is_running(self, args)
803 PyObject *self;
804 PyObject *args;
805{
806 return call_voidarg_function(quantify_is_running, self, args);
807}
808static PyObject*
809pure_quantify_help(self, args)
810 PyObject *self;
811 PyObject *args;
812{
813 return call_voidarg_function(quantify_help, self, args);
814}
815static PyObject*
816pure_quantify_print_recording_state(self, args)
817 PyObject *self;
818 PyObject *args;
819{
820 return call_voidarg_function(quantify_print_recording_state,
821 self, args);
822}
823static PyObject*
824pure_quantify_start_recording_data(self, args)
825 PyObject *self;
826 PyObject *args;
827{
828 return call_voidarg_function(quantify_start_recording_data,
829 self, args);
830}
831static PyObject*
832pure_quantify_stop_recording_data(self, args)
833 PyObject *self;
834 PyObject *args;
835{
836 return call_voidarg_function(quantify_stop_recording_data, self, args);
837}
838static PyObject*
839pure_quantify_is_recording_data(self, args)
840 PyObject *self;
841 PyObject *args;
842{
843 return call_voidarg_function(quantify_is_recording_data, self, args);
844}
845static PyObject*
846pure_quantify_start_recording_system_calls(self, args)
847 PyObject *self;
848 PyObject *args;
849{
850 return call_voidarg_function(quantify_start_recording_system_calls,
851 self, args);
852}
853static PyObject*
854pure_quantify_stop_recording_system_calls(self, args)
855 PyObject *self;
856 PyObject *args;
857{
858 return call_voidarg_function(quantify_stop_recording_system_calls,
859 self, args);
860}
861static PyObject*
862pure_quantify_is_recording_system_calls(self, args)
863 PyObject *self;
864 PyObject *args;
865{
866 return call_voidarg_function(quantify_is_recording_system_calls,
867 self, args);
868}
869static PyObject*
870pure_quantify_start_recording_system_call(self, args)
871 PyObject *self;
872 PyObject *args;
873{
874 return call_stringorint_function(quantify_start_recording_system_call,
875 self, args);
876}
877static PyObject*
878pure_quantify_stop_recording_system_call(self, args)
879 PyObject *self;
880 PyObject *args;
881{
882 return call_stringorint_function(quantify_stop_recording_system_call,
883 self, args);
884}
885static PyObject*
886pure_quantify_is_recording_system_call(self, args)
887 PyObject *self;
888 PyObject *args;
889{
890 return call_stringorint_function(quantify_is_recording_system_call,
891 self, args);
892}
893static PyObject*
894pure_quantify_start_recording_dynamic_library_data(self, args)
895 PyObject *self;
896 PyObject *args;
897{
898 return call_voidarg_function(
899 quantify_start_recording_dynamic_library_data,
900 self, args);
901}
902static PyObject*
903pure_quantify_stop_recording_dynamic_library_data(self, args)
904 PyObject *self;
905 PyObject *args;
906{
907 return call_voidarg_function(
908 quantify_stop_recording_dynamic_library_data,
909 self, args);
910}
911static PyObject*
912pure_quantify_is_recording_dynamic_library_data(self, args)
913 PyObject *self;
914 PyObject *args;
915{
916 return call_voidarg_function(
917 quantify_is_recording_dynamic_library_data,
918 self, args);
919}
920static PyObject*
921pure_quantify_start_recording_register_window_traps(self, args)
922 PyObject *self;
923 PyObject *args;
924{
925 return call_voidarg_function(
926 quantify_start_recording_register_window_traps,
927 self, args);
928}
929static PyObject*
930pure_quantify_stop_recording_register_window_traps(self, args)
931 PyObject *self;
932 PyObject *args;
933{
934 return call_voidarg_function(
935 quantify_stop_recording_register_window_traps,
936 self, args);
937}
938static PyObject*
939pure_quantify_is_recording_register_window_traps(self, args)
940 PyObject *self;
941 PyObject *args;
942{
943 return call_voidarg_function(
944 quantify_is_recording_register_window_traps,
945 self, args);
946}
947static PyObject*
948pure_quantify_disable_recording_data(self, args)
949 PyObject *self;
950 PyObject *args;
951{
952 return call_voidarg_function(quantify_disable_recording_data,
953 self, args);
954}
955static PyObject*
956pure_quantify_clear_data(self, args)
957 PyObject *self;
958 PyObject *args;
959{
960 return call_voidarg_function(quantify_clear_data, self, args);
961}
962static PyObject*
963pure_quantify_save_data(self, args)
964 PyObject *self;
965 PyObject *args;
966{
967 return call_voidarg_function(quantify_save_data, self, args);
968}
969static PyObject*
970pure_quantify_save_data_to_file(self, args)
971 PyObject *self;
972 PyObject *args;
973{
974 return call_stringarg_function(quantify_save_data_to_file, self, args);
975}
976static PyObject*
977pure_quantify_add_annotation(self, args)
978 PyObject *self;
979 PyObject *args;
980{
981 return call_stringarg_function(quantify_add_annotation, self, args);
982}
983
984#endif /* QUANTIFY_H */
985
986
987
988/* external interface
989 */
990static struct PyMethodDef
991pure_methods[] = {
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 */
997#ifdef PURIFY_H
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},
1006 /* see purify.h */
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},
1010 /**/
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},
1052#if HAS_PURIFY_EXIT
1053 /* I wish I could include this, but I can't. See the notes at the
1054 * top of the file.
1055 */
1056 {"purify_exit", pure_purify_exit, 1},
1057#endif /* HAS_PURIFY_EXIT */
1058#endif /* PURIFY_H */
1059#ifdef QUANTIFY_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 */
1098};
1099
1100
1101
1102static void
1103ins(d, name, val)
1104 PyObject *d;
1105 char* name;
1106 long val;
1107{
1108 PyObject *v = PyInt_FromLong(val);
1109 if (v) {
1110 (void)PyDict_SetItemString(d, name, v);
1111 Py_DECREF(v);
1112 }
1113}
1114
1115
1116void
1117initpure()
1118{
1119 PyObject *m, *d;
1120
1121 m = Py_InitModule("pure", pure_methods);
1122 d = PyModule_GetDict(m);
1123
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!
1127 */
1128#ifdef PURE_PURIFY_VERSION
1129 ins(d, "PURIFY_VERSION", PURE_PURIFY_VERSION);
1130#else
1131 PyDict_SetItemString(d, "PURIFY_VERSION", Py_None);
1132#endif
1133
1134 /* these aren't terribly useful because purify_exit() isn't
1135 * exported correctly. See the note at the top of the file.
1136 */
1137#ifdef PURIFY_EXIT_ERRORS
1138 ins(d, "PURIFY_EXIT_ERRORS", PURIFY_EXIT_ERRORS);
1139#endif
1140#ifdef PURIFY_EXIT_LEAKS
1141 ins(d, "PURIFY_EXIT_LEAKS", PURIFY_EXIT_LEAKS);
1142#endif
1143#ifdef PURIFY_EXIT_PLEAKS
1144 ins(d, "PURIFY_EXIT_PLEAKS", PURIFY_EXIT_PLEAKS);
1145#endif
1146
1147
1148#ifdef PURE_QUANTIFY_VERSION
1149 ins(d, "QUANTIFY_VERSION", PURE_QUANTIFY_VERSION);
1150#else
1151 PyDict_SetItemString(d, "QUANTIFY_VERSION", Py_None);
1152#endif
1153 if (PyErr_Occurred())
1154 Py_FatalError("couldn't initialize the pure module");
1155}