home *** CD-ROM | disk | FTP | other *** search
/ linuxmafia.com 2016 / linuxmafia.com.tar / linuxmafia.com / pub / palmos / pippy-0.6beta-src.tar.gz / pippy-0.6beta-src.tar / pippy-0.6beta-src / src / Modules / puremodule.c < prev    next >
C/C++ Source or Header  |  2000-12-21  |  32KB  |  1,156 lines

  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.
  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.  
  55. typedef int (*VoidArgFunc)(void);
  56. typedef int (*StringArgFunc)(char*);
  57. typedef int (*PrintfishFunc)(const char*, ...);
  58. typedef int (*StringIntArgFunc)(const char*, int);
  59.  
  60.  
  61.  
  62. static PyObject*
  63. call_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.  
  77. static PyObject*
  78. call_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.  
  93. static PyObject*
  94. call_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.  
  124. static PyObject*
  125. call_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.  
  144. static PyObject*
  145. call_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.  
  160. static PyObject*
  161. call_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.  
  191. static PyObject*
  192. pure_pure_logfile_printf(PyObject* self, PyObject* args)
  193. {
  194.     return call_printfish_function(pure_logfile_printf, self, args);
  195. }
  196.  
  197. static PyObject*
  198. pure_pure_printf(PyObject* self, PyObject* args)
  199. {
  200.     return call_printfish_function(pure_printf, self, args);
  201. }
  202.  
  203. static PyObject*
  204. pure_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.  
  252. static PyObject*
  253. pure_purify_all_inuse(self, args)
  254.     PyObject *self;
  255.     PyObject *args;
  256. {
  257.     return call_voidarg_function(purify_all_inuse, self, args);
  258. }
  259. static PyObject*
  260. pure_purify_all_leaks(self, args)
  261.     PyObject *self;
  262.     PyObject *args;
  263. {
  264.     return call_voidarg_function(purify_all_leaks, self, args);
  265. }
  266. static PyObject*
  267. pure_purify_new_inuse(self, args)
  268.     PyObject *self;
  269.     PyObject *args;
  270. {
  271.     return call_voidarg_function(purify_new_inuse, self, args);
  272. }
  273. static PyObject*
  274. pure_purify_new_leaks(self, args)
  275.     PyObject *self;
  276.     PyObject *args;
  277. {
  278.     return call_voidarg_function(purify_new_leaks, self, args);
  279. }
  280. static PyObject*
  281. pure_purify_clear_inuse(self, args)
  282.     PyObject *self;
  283.     PyObject *args;
  284. {
  285.     return call_voidarg_function(purify_clear_inuse, self, args);
  286. }
  287. static PyObject*
  288. pure_purify_clear_leaks(self, args)
  289.     PyObject *self;
  290.     PyObject *args;
  291. {
  292.     return call_voidarg_function(purify_clear_leaks, self, args);
  293. }
  294. static PyObject*
  295. pure_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. }
  301. static PyObject*
  302. pure_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. }
  308. static PyObject*
  309. pure_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. }
  316. static PyObject*
  317. pure_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:purify_set_pool_id", &memrep, &id))
  325.         return NULL;
  326.  
  327.     purify_set_pool_id((char*)memrep, id);
  328.     Py_INCREF(Py_None);
  329.     return Py_None;
  330. }
  331. static PyObject*
  332. pure_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. }
  338. static PyObject*
  339. pure_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:purify_set_user_data", &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. }
  353. static PyObject*
  354. pure_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:purify_get_user_data", &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.  */
  382. static PyObject* MapCallable = NULL;
  383.  
  384. static void
  385. map_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.  
  404. static PyObject*
  405. pure_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:purify_map_pool", &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.  
  430. static void
  431. PurifyMapPoolIdCallback(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.  
  445. static PyObject*
  446. pure_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:purify_map_pool_id", &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.  
  472. static PyObject*
  473. pure_purify_new_messages(self, args)
  474.     PyObject *self;
  475.     PyObject *args;
  476. {
  477.     return call_voidarg_function(purify_new_messages, self, args);
  478. }
  479. static PyObject*
  480. pure_purify_all_messages(self, args)
  481.     PyObject *self;
  482.     PyObject *args;
  483. {
  484.     return call_voidarg_function(purify_all_messages, self, args);
  485. }
  486. static PyObject*
  487. pure_purify_clear_messages(self, args)
  488.     PyObject *self;
  489.     PyObject *args;
  490. {
  491.     return call_voidarg_function(purify_clear_messages, self, args);
  492. }
  493. static PyObject*
  494. pure_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. }
  500. static PyObject*
  501. pure_purify_start_batch(self, args)
  502.     PyObject *self;
  503.     PyObject *args;
  504. {
  505.     return call_voidarg_function(purify_start_batch, self, args);
  506. }
  507. static PyObject*
  508. pure_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. }
  515. static PyObject*
  516. pure_purify_stop_batch(self, args)
  517.     PyObject *self;
  518.     PyObject *args;
  519. {
  520.     return call_voidarg_function(purify_stop_batch, self, args);
  521. }
  522. static PyObject*
  523. pure_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:purify_name_thread", &stringarg))
  534.         return NULL;
  535.  
  536.     status = purify_name_thread(stringarg);
  537.     return Py_BuildValue("i", status);
  538. }
  539. static PyObject*
  540. pure_purify_watch(self, args)
  541.     PyObject *self;
  542.     PyObject *args;
  543. {
  544.     return call_intasaddr_function(purify_watch, self, args);
  545. }
  546. static PyObject*
  547. pure_purify_watch_1(self, args)
  548.     PyObject *self;
  549.     PyObject *args;
  550. {
  551.     return call_intasaddr_function(purify_watch_1, self, args);
  552. }
  553. static PyObject*
  554. pure_purify_watch_2(self, args)
  555.     PyObject *self;
  556.     PyObject *args;
  557. {
  558.     return call_intasaddr_function(purify_watch_2, self, args);
  559. }
  560. static PyObject*
  561. pure_purify_watch_4(self, args)
  562.     PyObject *self;
  563.     PyObject *args;
  564. {
  565.     return call_intasaddr_function(purify_watch_4, self, args);
  566. }
  567. static PyObject*
  568. pure_purify_watch_8(self, args)
  569.     PyObject *self;
  570.     PyObject *args;
  571. {
  572.     return call_intasaddr_function(purify_watch_8, self, args);
  573. }
  574. static PyObject*
  575. pure_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. }
  581. static PyObject*
  582. pure_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. }
  588. static PyObject*
  589. pure_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. }
  595. static PyObject*
  596. pure_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. }
  602. static PyObject*
  603. pure_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. }
  609. static PyObject*
  610. pure_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. }
  616. static PyObject*
  617. pure_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. }
  623. static PyObject*
  624. pure_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. }
  630. static PyObject*
  631. pure_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. }
  637. static PyObject*
  638. pure_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. }
  644. static PyObject*
  645. pure_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. }
  651. static PyObject*
  652. pure_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.  
  659. static PyObject*
  660. pure_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:purify_watch_n", &addrrep, &size, &type))
  670.         return NULL;
  671.  
  672.     status = purify_watch_n((char*)addrrep, size, type);
  673.     return Py_BuildValue("i", status);
  674. }
  675.  
  676. static PyObject*
  677. pure_purify_watch_info(self, args)
  678.     PyObject *self;
  679.     PyObject *args;
  680. {
  681.     return call_voidarg_function(purify_watch_info, self, args);
  682. }
  683.  
  684. static PyObject*
  685. pure_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:purify_watch_remove", &watchno))
  693.         return NULL;
  694.  
  695.     status = purify_watch_remove(watchno);
  696.     return Py_BuildValue("i", status);
  697. }
  698.  
  699. static PyObject*
  700. pure_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. }
  706. static PyObject*
  707. pure_purify_describe(self, args)
  708.     PyObject *self;
  709.     PyObject *args;
  710. {
  711.     long addrrep;
  712.     char* rtn;
  713.  
  714.     if (!PyArg_ParseTuple(args, "l:purify_describe", &addrrep))
  715.         return NULL;
  716.  
  717.     rtn = purify_describe((char*)addrrep);
  718.     return Py_BuildValue("l", (long)rtn);
  719. }
  720.  
  721. static PyObject*
  722. pure_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:purify_what_colors", &addrrep, &size))
  731.         return NULL;
  732.  
  733.     status = purify_what_colors((char*)addrrep, size);
  734.     return Py_BuildValue("i", status);
  735. }
  736.  
  737. static PyObject*
  738. pure_purify_is_running(self, args)
  739.     PyObject *self;
  740.     PyObject *args;
  741. {
  742.     return call_voidarg_function(purify_is_running, self, args);
  743. }
  744.  
  745. static PyObject*
  746. pure_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. }
  753. static PyObject*
  754. pure_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.  
  768. static PyObject*
  769. pure_purify_exit(self, args)
  770.     PyObject *self;
  771.     PyObject *args;
  772. {
  773.     int status;
  774.  
  775.     if (!PyArg_ParseTuple(args, "i:purify_exit", &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.  
  801. static PyObject*
  802. pure_quantify_is_running(self, args)
  803.     PyObject *self;
  804.     PyObject *args;
  805. {
  806.     return call_voidarg_function(quantify_is_running, self, args);
  807. }
  808. static PyObject*
  809. pure_quantify_help(self, args)
  810.     PyObject *self;
  811.     PyObject *args;
  812. {
  813.     return call_voidarg_function(quantify_help, self, args);
  814. }
  815. static PyObject*
  816. pure_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. }
  823. static PyObject*
  824. pure_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. }
  831. static PyObject*
  832. pure_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. }
  838. static PyObject*
  839. pure_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. }
  845. static PyObject*
  846. pure_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. }
  853. static PyObject*
  854. pure_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. }
  861. static PyObject*
  862. pure_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. }
  869. static PyObject*
  870. pure_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. }
  877. static PyObject*
  878. pure_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. }
  885. static PyObject*
  886. pure_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. }
  893. static PyObject*
  894. pure_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. }
  902. static PyObject*
  903. pure_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. }
  911. static PyObject*
  912. pure_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. }
  920. static PyObject*
  921. pure_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. }
  929. static PyObject*
  930. pure_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. }
  938. static PyObject*
  939. pure_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. }
  947. static PyObject*
  948. pure_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. }
  955. static PyObject*
  956. pure_quantify_clear_data(self, args)
  957.     PyObject *self;
  958.     PyObject *args;
  959. {
  960.     return call_voidarg_function(quantify_clear_data, self, args);
  961. }
  962. static PyObject*
  963. pure_quantify_save_data(self, args)
  964.     PyObject *self;
  965.     PyObject *args;
  966. {
  967.     return call_voidarg_function(quantify_save_data, self, args);
  968. }
  969. static PyObject*
  970. pure_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. }
  976. static PyObject*
  977. pure_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.  */
  990. static struct PyMethodDef
  991. pure_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.  
  1102. static void
  1103. ins(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.  
  1116. void
  1117. initpure()
  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. }
  1156.