home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 15 / AACD15.ISO / AACD / Programming / Python2 / Python20_source / Modules / puremodule.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-10-25  |  29.7 KB  |  987 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(VoidArgFunc func, PyObject *self, PyObject *args)
  64. {
  65.     int status;
  66.  
  67.     if (!PyArg_ParseTuple(args, ""))
  68.         return NULL;
  69.  
  70.     status = func();
  71.     return Py_BuildValue("i", status);
  72. }
  73.  
  74. static PyObject*
  75. call_stringarg_function(StringArgFunc func, PyObject *self, PyObject *args)
  76. {
  77.     int status;
  78.     char* stringarg;
  79.  
  80.     if (!PyArg_ParseTuple(args, "s", &stringarg))
  81.         return NULL;
  82.  
  83.     status = func(stringarg);
  84.     return Py_BuildValue("i", status);
  85. }
  86.  
  87. static PyObject*
  88. call_stringorint_function(StringArgFunc func, PyObject *self, PyObject *args)
  89. {
  90.     int status;
  91.     int intarg;
  92.     char* stringarg;
  93.  
  94.         /* according to the quantify.h file, the argument to
  95.          * quantify_*_recording_system_call can be an integer or a string,
  96.      * but the functions are prototyped as taking a single char*
  97.      * argument. Yikes!
  98.          */
  99.     if (PyArg_ParseTuple(args, "i", &intarg))
  100.         /* func is prototyped as int(*)(char*)
  101.          * better shut up the compiler
  102.          */
  103.         status = func((char*)intarg);
  104.  
  105.     else {
  106.         PyErr_Clear();
  107.         if (!PyArg_ParseTuple(args, "s", &stringarg))
  108.             return NULL;
  109.         else
  110.             status = func(stringarg);
  111.     }
  112.     return Py_BuildValue("i", status);
  113. }
  114.  
  115. static PyObject*
  116. call_printfish_function(PrintfishFunc func, PyObject *self, PyObject *args)
  117. {
  118.     /* we support the printf() style vararg functions by requiring the
  119.          * formatting be done in Python.  At the C level we pass just a string
  120.          * to the printf() style function.
  121.          */
  122.     int status;
  123.     char* argstring;
  124.  
  125.     if (!PyArg_ParseTuple(args, "s", &argstring))
  126.         return NULL;
  127.  
  128.     status = func("%s", argstring);
  129.     return Py_BuildValue("i", status);
  130. }
  131.  
  132. static PyObject*
  133. call_intasaddr_function(StringArgFunc func, PyObject *self, PyObject *args)
  134. {
  135.     long memrep;
  136.     int id;
  137.  
  138.     if (!PyArg_ParseTuple(args, "l", &memrep))
  139.         return NULL;
  140.  
  141.     id = func((char*)memrep);
  142.     return Py_BuildValue("i", id);
  143. }
  144.  
  145. static PyObject*
  146. call_stringandint_function(StringIntArgFunc func, PyObject *self,
  147.                PyObject *args)
  148. {
  149.     long srcrep;
  150.     int size;
  151.     int status;
  152.  
  153.     if (!PyArg_ParseTuple(args, "li", &srcrep, &size))
  154.         return NULL;
  155.  
  156.     status = func((char*)srcrep, size);
  157.     return Py_BuildValue("i", status);
  158. }
  159.  
  160.  
  161.  
  162. /* functions common to all products
  163.  *
  164.  * N.B. These printf() style functions are a bit of a kludge.  Since the
  165.  * API doesn't provide vprintf versions of them, we can't call them
  166.  * directly.  They don't support all the standard printf % modifiers
  167.  * anyway.  The way to use these is to use Python's % string operator to do
  168.  * the formatting.  By the time these functions get the thing to print,
  169.  * it's already a string, and they just use "%s" as the format string.
  170.  */
  171.  
  172. #ifdef COMMON_PURE_FUNCTIONS
  173.  
  174. static PyObject*
  175. pure_pure_logfile_printf(PyObject* self, PyObject* args)
  176. {
  177.     return call_printfish_function(pure_logfile_printf, self, args);
  178. }
  179.  
  180. static PyObject*
  181. pure_pure_printf(PyObject* self, PyObject* args)
  182. {
  183.     return call_printfish_function(pure_printf, self, args);
  184. }
  185.  
  186. static PyObject*
  187. pure_pure_printf_with_banner(PyObject* self, PyObject* args)
  188. {
  189.     return call_printfish_function(pure_printf_with_banner, self, args);
  190. }
  191.  
  192.  
  193. #endif /* COMMON_PURE_FUNCTIONS */
  194.  
  195.  
  196.  
  197. /* Purify functions
  198.  *
  199.  * N.B. There are some interfaces described in the purify.h file that are
  200.  * not described in the manual.
  201.  *
  202.  * Unsigned longs purify_report_{address,number,type,result} are not
  203.  * accessible from the Python layer since they seem mostly useful when
  204.  * purify_stop_here() is called by the (C) debugger.  The same is true of
  205.  * the purify_stop_here_internal() function so it isn't exported either.
  206.  * And purify_stop_here() should never be called directly.
  207.  *
  208.  * The header file says purify_{new,all,clear_new}_reports() are obsolete
  209.  * so they aren't exported.
  210.  *
  211.  * None of the custom dynamic loader functions are exported.
  212.  *
  213.  * purify_unsafe_memcpy() isn't exported.
  214.  *
  215.  * purify_{start,size}_of_block() aren't exported.
  216.  *
  217.  * The manual that I have says that the prototype for the second argument
  218.  * to purify_map_pool is:
  219.  *
  220.  *    void (*fn)(char*)
  221.  *
  222.  * but the purify.h file declares it as:
  223.  *
  224.  *    void (*fn)(char*, int, void*)
  225.  *
  226.  * and does not explain what the other arguments are for.  I support the
  227.  * latter but I don't know if I do it right or usefully.
  228.  *
  229.  * The header file says that purify_describe() returns a char* which is the
  230.  * pointer passed to it.  The manual says it returns an int, but I believe
  231.  * that is a typo.
  232.  */
  233. #ifdef PURIFY_H
  234.  
  235. static PyObject*
  236. pure_purify_all_inuse(PyObject *self, PyObject *args)
  237. {
  238.     return call_voidarg_function(purify_all_inuse, self, args);
  239. }
  240. static PyObject*
  241. pure_purify_all_leaks(PyObject *self, PyObject *args)
  242. {
  243.     return call_voidarg_function(purify_all_leaks, self, args);
  244. }
  245. static PyObject*
  246. pure_purify_new_inuse(PyObject *self, PyObject *args)
  247. {
  248.     return call_voidarg_function(purify_new_inuse, self, args);
  249. }
  250. static PyObject*
  251. pure_purify_new_leaks(PyObject *self, PyObject *args)
  252. {
  253.     return call_voidarg_function(purify_new_leaks, self, args);
  254. }
  255. static PyObject*
  256. pure_purify_clear_inuse(PyObject *self, PyObject *args)
  257. {
  258.     return call_voidarg_function(purify_clear_inuse, self, args);
  259. }
  260. static PyObject*
  261. pure_purify_clear_leaks(PyObject *self, PyObject *args)
  262. {
  263.     return call_voidarg_function(purify_clear_leaks, self, args);
  264. }
  265. static PyObject*
  266. pure_purify_all_fds_inuse(PyObject *self, PyObject *args)
  267. {
  268.     return call_voidarg_function(purify_all_fds_inuse, self, args);
  269. }
  270. static PyObject*
  271. pure_purify_new_fds_inuse(PyObject *self, PyObject *args)
  272. {
  273.     return call_voidarg_function(purify_new_fds_inuse, self, args);
  274. }
  275. static PyObject*
  276. pure_purify_printf_with_call_chain(PyObject *self, PyObject *args)
  277. {
  278.     return call_printfish_function(purify_printf_with_call_chain,
  279.                        self, args);
  280. }
  281. static PyObject*
  282. pure_purify_set_pool_id(PyObject *self, PyObject *args)
  283. {
  284.     long memrep;
  285.     int id;
  286.  
  287.     if (!PyArg_ParseTuple(args, "li:purify_set_pool_id", &memrep, &id))
  288.         return NULL;
  289.  
  290.     purify_set_pool_id((char*)memrep, id);
  291.     Py_INCREF(Py_None);
  292.     return Py_None;
  293. }
  294. static PyObject*
  295. pure_purify_get_pool_id(PyObject *self, PyObject *args)
  296. {
  297.     return call_intasaddr_function(purify_get_pool_id, self, args);
  298. }
  299. static PyObject*
  300. pure_purify_set_user_data(PyObject *self, PyObject *args)
  301. {
  302.     long memrep;
  303.     long datarep;
  304.  
  305.     if (!PyArg_ParseTuple(args, "ll:purify_set_user_data", &memrep, &datarep))
  306.         return NULL;
  307.  
  308.     purify_set_user_data((char*)memrep, (void*)datarep);
  309.     Py_INCREF(Py_None);
  310.     return Py_None;
  311. }
  312. static PyObject*
  313. pure_purify_get_user_data(PyObject *self, PyObject *args)
  314. {
  315.         /* can't use call_intasaddr_function() since purify_get_user_data()
  316.          * returns a void*
  317.          */
  318.     long memrep;
  319.     void* data;
  320.  
  321.     if (!PyArg_ParseTuple(args, "l:purify_get_user_data", &memrep))
  322.         return NULL;
  323.  
  324.     data = purify_get_user_data((char*)memrep);
  325.     return Py_BuildValue("l", (long)data);
  326. }
  327.  
  328.  
  329. /* this global variable is shared by both mapping functions:
  330.  * pure_purify_map_pool() and pure_purify_map_pool_id().  Since they cache
  331.  * this variable it should be safe in the face of recursion or cross
  332.  * calling.
  333.  *
  334.  * Further note that the prototype for the callback function is wrong in
  335.  * the Purify manual.  The manual says the function takes a single char*,
  336.  * but the header file says it takes an additional int and void*.  I have
  337.  * no idea what these are for!
  338.  */
  339. static PyObject* MapCallable = NULL;
  340.  
  341. static void
  342. map_pool_callback(char* mem, int user_size, void *user_aux_data)
  343. {
  344.     long memrep = (long)mem;
  345.     long user_aux_data_rep = (long)user_aux_data;
  346.     PyObject* result;
  347.     PyObject* memobj = Py_BuildValue("lil", memrep, user_size,
  348.                      user_aux_data_rep);
  349.  
  350.     if (memobj == NULL)
  351.         return;
  352.  
  353.     result = PyEval_CallObject(MapCallable, memobj);
  354.     Py_DECREF(result);
  355.     Py_DECREF(memobj);
  356. }
  357.  
  358. static PyObject*
  359. pure_purify_map_pool(PyObject *self, PyObject *args)
  360. {
  361.         /* cache global variable in case of recursion */
  362.     PyObject* saved_callable = MapCallable;
  363.     PyObject* arg_callable;
  364.     int id;
  365.  
  366.     if (!PyArg_ParseTuple(args, "iO:purify_map_pool", &id, &arg_callable))
  367.         return NULL;
  368.  
  369.     if (!PyCallable_Check(arg_callable)) {
  370.         PyErr_SetString(PyExc_TypeError,
  371.                 "Second argument must be callable");
  372.         return NULL;
  373.     }
  374.     MapCallable = arg_callable;
  375.     purify_map_pool(id, map_pool_callback);
  376.     MapCallable = saved_callable;
  377.  
  378.     Py_INCREF(Py_None);
  379.     return Py_None;
  380. }
  381.  
  382. static void
  383. PurifyMapPoolIdCallback(int id)
  384. {
  385.     PyObject* result;
  386.     PyObject* intobj = Py_BuildValue("i", id);
  387.  
  388.     if (intobj == NULL)
  389.         return;
  390.  
  391.     result = PyEval_CallObject(MapCallable, intobj);
  392.     Py_DECREF(result);
  393.     Py_DECREF(intobj);
  394. }
  395.  
  396. static PyObject*
  397. pure_purify_map_pool_id(PyObject *self, PyObject *args)
  398. {
  399.         /* cache global variable in case of recursion */
  400.     PyObject* saved_callable = MapCallable;
  401.     PyObject* arg_callable;
  402.  
  403.     if (!PyArg_ParseTuple(args, "O:purify_map_pool_id", &arg_callable))
  404.         return NULL;
  405.  
  406.     if (!PyCallable_Check(arg_callable)) {
  407.         PyErr_SetString(PyExc_TypeError, "Argument must be callable.");
  408.         return NULL;
  409.     }
  410.  
  411.     MapCallable = arg_callable;
  412.     purify_map_pool_id(PurifyMapPoolIdCallback);
  413.     MapCallable = saved_callable;
  414.  
  415.     Py_INCREF(Py_None);
  416.     return Py_None;
  417. }
  418.  
  419.  
  420.  
  421. static PyObject*
  422. pure_purify_new_messages(PyObject *self, PyObject *args)
  423. {
  424.     return call_voidarg_function(purify_new_messages, self, args);
  425. }
  426. static PyObject*
  427. pure_purify_all_messages(PyObject *self, PyObject *args)
  428. {
  429.     return call_voidarg_function(purify_all_messages, self, args);
  430. }
  431. static PyObject*
  432. pure_purify_clear_messages(PyObject *self, PyObject *args)
  433. {
  434.     return call_voidarg_function(purify_clear_messages, self, args);
  435. }
  436. static PyObject*
  437. pure_purify_clear_new_messages(PyObject *self, PyObject *args)
  438. {
  439.     return call_voidarg_function(purify_clear_new_messages, self, args);
  440. }
  441. static PyObject*
  442. pure_purify_start_batch(PyObject *self, PyObject *args)
  443. {
  444.     return call_voidarg_function(purify_start_batch, self, args);
  445. }
  446. static PyObject*
  447. pure_purify_start_batch_show_first(PyObject *self, PyObject *args)
  448. {
  449.     return call_voidarg_function(purify_start_batch_show_first,
  450.                      self, args);
  451. }
  452. static PyObject*
  453. pure_purify_stop_batch(PyObject *self, PyObject *args)
  454. {
  455.     return call_voidarg_function(purify_stop_batch, self, args);
  456. }
  457. static PyObject*
  458. pure_purify_name_thread(PyObject *self, PyObject *args)
  459. {
  460.         /* can't strictly use call_stringarg_function since
  461.          * purify_name_thread takes a const char*, not a char*
  462.          */
  463.     int status;
  464.     char* stringarg;
  465.  
  466.     if (!PyArg_ParseTuple(args, "s:purify_name_thread", &stringarg))
  467.         return NULL;
  468.  
  469.     status = purify_name_thread(stringarg);
  470.     return Py_BuildValue("i", status);
  471. }
  472. static PyObject*
  473. pure_purify_watch(PyObject *self, PyObject *args)
  474. {
  475.     return call_intasaddr_function(purify_watch, self, args);
  476. }
  477. static PyObject*
  478. pure_purify_watch_1(PyObject *self, PyObject *args)
  479. {
  480.     return call_intasaddr_function(purify_watch_1, self, args);
  481. }
  482. static PyObject*
  483. pure_purify_watch_2(PyObject *self, PyObject *args)
  484. {
  485.     return call_intasaddr_function(purify_watch_2, self, args);
  486. }
  487. static PyObject*
  488. pure_purify_watch_4(PyObject *self, PyObject *args)
  489. {
  490.     return call_intasaddr_function(purify_watch_4, self, args);
  491. }
  492. static PyObject*
  493. pure_purify_watch_8(PyObject *self, PyObject *args)
  494. {
  495.     return call_intasaddr_function(purify_watch_8, self, args);
  496. }
  497. static PyObject*
  498. pure_purify_watch_w_1(PyObject *self, PyObject *args)
  499. {
  500.     return call_intasaddr_function(purify_watch_w_1, self, args);
  501. }
  502. static PyObject*
  503. pure_purify_watch_w_2(PyObject *self, PyObject *args)
  504. {
  505.     return call_intasaddr_function(purify_watch_w_2, self, args);
  506. }
  507. static PyObject*
  508. pure_purify_watch_w_4(PyObject *self, PyObject *args)
  509. {
  510.     return call_intasaddr_function(purify_watch_w_4, self, args);
  511. }
  512. static PyObject*
  513. pure_purify_watch_w_8(PyObject *self, PyObject *args)
  514. {
  515.     return call_intasaddr_function(purify_watch_w_8, self, args);
  516. }
  517. static PyObject*
  518. pure_purify_watch_r_1(PyObject *self, PyObject *args)
  519. {
  520.     return call_intasaddr_function(purify_watch_r_1, self, args);
  521. }
  522. static PyObject*
  523. pure_purify_watch_r_2(PyObject *self, PyObject *args)
  524. {
  525.     return call_intasaddr_function(purify_watch_r_2, self, args);
  526. }
  527. static PyObject*
  528. pure_purify_watch_r_4(PyObject *self, PyObject *args)
  529. {
  530.     return call_intasaddr_function(purify_watch_r_4, self, args);
  531. }
  532. static PyObject*
  533. pure_purify_watch_r_8(PyObject *self, PyObject *args)
  534. {
  535.     return call_intasaddr_function(purify_watch_r_8, self, args);
  536. }
  537. static PyObject*
  538. pure_purify_watch_rw_1(PyObject *self, PyObject *args)
  539. {
  540.     return call_intasaddr_function(purify_watch_rw_1, self, args);
  541. }
  542. static PyObject*
  543. pure_purify_watch_rw_2(PyObject *self, PyObject *args)
  544. {
  545.     return call_intasaddr_function(purify_watch_rw_2, self, args);
  546. }
  547. static PyObject*
  548. pure_purify_watch_rw_4(PyObject *self, PyObject *args)
  549. {
  550.     return call_intasaddr_function(purify_watch_rw_4, self, args);
  551. }
  552. static PyObject*
  553. pure_purify_watch_rw_8(PyObject *self, PyObject *args)
  554. {
  555.     return call_intasaddr_function(purify_watch_rw_8, self, args);
  556. }
  557.  
  558. static PyObject*
  559. pure_purify_watch_n(PyObject *self, PyObject *args)
  560. {
  561.     long addrrep;
  562.     unsigned int size;
  563.     char* type;
  564.     int status;
  565.  
  566.     if (!PyArg_ParseTuple(args, "lis:purify_watch_n", &addrrep, &size, &type))
  567.         return NULL;
  568.  
  569.     status = purify_watch_n((char*)addrrep, size, type);
  570.     return Py_BuildValue("i", status);
  571. }
  572.  
  573. static PyObject*
  574. pure_purify_watch_info(PyObject *self, PyObject *args)
  575. {
  576.     return call_voidarg_function(purify_watch_info, self, args);
  577. }
  578.  
  579. static PyObject*
  580. pure_purify_watch_remove(PyObject *self, PyObject *args)
  581. {
  582.     int watchno;
  583.     int status;
  584.  
  585.     if (!PyArg_ParseTuple(args, "i:purify_watch_remove", &watchno))
  586.         return NULL;
  587.  
  588.     status = purify_watch_remove(watchno);
  589.     return Py_BuildValue("i", status);
  590. }
  591.  
  592. static PyObject*
  593. pure_purify_watch_remove_all(PyObject *self, PyObject *args)
  594. {
  595.     return call_voidarg_function(purify_watch_remove_all, self, args);
  596. }
  597. static PyObject*
  598. pure_purify_describe(PyObject *self, PyObject *args)
  599. {
  600.     long addrrep;
  601.     char* rtn;
  602.  
  603.     if (!PyArg_ParseTuple(args, "l:purify_describe", &addrrep))
  604.         return NULL;
  605.  
  606.     rtn = purify_describe((char*)addrrep);
  607.     return Py_BuildValue("l", (long)rtn);
  608. }
  609.  
  610. static PyObject*
  611. pure_purify_what_colors(PyObject *self, PyObject *args)
  612. {
  613.     long addrrep;
  614.     unsigned int size;
  615.     int status;
  616.     
  617.     if (!PyArg_ParseTuple(args, "li:purify_what_colors", &addrrep, &size))
  618.         return NULL;
  619.  
  620.     status = purify_what_colors((char*)addrrep, size);
  621.     return Py_BuildValue("i", status);
  622. }
  623.  
  624. static PyObject*
  625. pure_purify_is_running(PyObject *self, PyObject *args)
  626. {
  627.     return call_voidarg_function(purify_is_running, self, args);
  628. }
  629.  
  630. static PyObject*
  631. pure_purify_assert_is_readable(PyObject *self, PyObject *args)
  632. {
  633.     return call_stringandint_function(purify_assert_is_readable,
  634.                       self, args);
  635. }
  636. static PyObject*
  637. pure_purify_assert_is_writable(PyObject *self, PyObject *args)
  638. {
  639.     return call_stringandint_function(purify_assert_is_writable,
  640.                       self, args);
  641. }
  642.  
  643. #if HAS_PURIFY_EXIT
  644.  
  645. /* I wish I could include this, but I can't.  See the notes at the top of
  646.  * the file.
  647.  */
  648.  
  649. static PyObject*
  650. pure_purify_exit(PyObject *self, PyObject *args)
  651. {
  652.     int status;
  653.  
  654.     if (!PyArg_ParseTuple(args, "i:purify_exit", &status))
  655.         return NULL;
  656.  
  657.         /* purify_exit doesn't always act like exit(). See the manual */
  658.     purify_exit(status);
  659.     Py_INCREF(Py_None);
  660.     return Py_None;
  661. }
  662. #endif /* HAS_PURIFY_EXIT */
  663.  
  664. #endif /* PURIFY_H */
  665.  
  666.  
  667.  
  668. /* Quantify functions
  669.  *
  670.  * N.B. Some of these functions are only described in the quantify.h file,
  671.  * not in the version of the hardcopy manual that I had.  If you're not
  672.  * sure what some of these do, check the header file, it is documented
  673.  * fairly well.
  674.  *
  675.  * None of the custom dynamic loader functions are exported.
  676.  *
  677.  */
  678. #ifdef QUANTIFY_H
  679.  
  680. static PyObject*
  681. pure_quantify_is_running(PyObject *self, PyObject *args)
  682. {
  683.     return call_voidarg_function(quantify_is_running, self, args);
  684. }
  685. static PyObject*
  686. pure_quantify_help(PyObject *self, PyObject *args)
  687. {
  688.     return call_voidarg_function(quantify_help, self, args);
  689. }
  690. static PyObject*
  691. pure_quantify_print_recording_state(PyObject *self, PyObject *args)
  692. {
  693.     return call_voidarg_function(quantify_print_recording_state,
  694.                      self, args);
  695. }
  696. static PyObject*
  697. pure_quantify_start_recording_data(PyObject *self, PyObject *args)
  698. {
  699.     return call_voidarg_function(quantify_start_recording_data,
  700.                      self, args);
  701. }
  702. static PyObject*
  703. pure_quantify_stop_recording_data(PyObject *self, PyObject *args)
  704. {
  705.     return call_voidarg_function(quantify_stop_recording_data, self, args);
  706. }
  707. static PyObject*
  708. pure_quantify_is_recording_data(PyObject *self, PyObject *args)
  709. {
  710.     return call_voidarg_function(quantify_is_recording_data, self, args);
  711. }
  712. static PyObject*
  713. pure_quantify_start_recording_system_calls(PyObject *self, PyObject *args)
  714. {
  715.     return call_voidarg_function(quantify_start_recording_system_calls,
  716.                      self, args);
  717. }
  718. static PyObject*
  719. pure_quantify_stop_recording_system_calls(PyObject *self, PyObject *args)
  720. {
  721.     return call_voidarg_function(quantify_stop_recording_system_calls,
  722.                      self, args);
  723. }
  724. static PyObject*
  725. pure_quantify_is_recording_system_calls(PyObject *self, PyObject *args)
  726. {
  727.     return call_voidarg_function(quantify_is_recording_system_calls,
  728.                      self, args);
  729. }
  730. static PyObject*
  731. pure_quantify_start_recording_system_call(PyObject *self, PyObject *args)
  732. {
  733.     return call_stringorint_function(quantify_start_recording_system_call,
  734.                        self, args);
  735. }
  736. static PyObject*
  737. pure_quantify_stop_recording_system_call(PyObject *self, PyObject *args)
  738. {
  739.     return call_stringorint_function(quantify_stop_recording_system_call,
  740.                      self, args);
  741. }
  742. static PyObject*
  743. pure_quantify_is_recording_system_call(PyObject *self, PyObject *args)
  744. {
  745.     return call_stringorint_function(quantify_is_recording_system_call,
  746.                      self, args);
  747. }
  748. static PyObject*
  749. pure_quantify_start_recording_dynamic_library_data(PyObject *self, PyObject *args)
  750. {
  751.     return call_voidarg_function(
  752.         quantify_start_recording_dynamic_library_data,
  753.         self, args);
  754. }
  755. static PyObject*
  756. pure_quantify_stop_recording_dynamic_library_data(PyObject *self, PyObject *args)
  757. {
  758.     return call_voidarg_function(
  759.         quantify_stop_recording_dynamic_library_data,
  760.         self, args);
  761. }
  762. static PyObject*
  763. pure_quantify_is_recording_dynamic_library_data(PyObject *self, PyObject *args)
  764. {
  765.     return call_voidarg_function(
  766.         quantify_is_recording_dynamic_library_data,
  767.         self, args);
  768. }
  769. static PyObject*
  770. pure_quantify_start_recording_register_window_traps(PyObject *self, PyObject *args)
  771. {
  772.     return call_voidarg_function(
  773.         quantify_start_recording_register_window_traps,
  774.         self, args);
  775. }
  776. static PyObject*
  777. pure_quantify_stop_recording_register_window_traps(PyObject *self, PyObject *args)
  778. {
  779.     return call_voidarg_function(
  780.         quantify_stop_recording_register_window_traps,
  781.         self, args);
  782. }
  783. static PyObject*
  784. pure_quantify_is_recording_register_window_traps(PyObject *self, PyObject *args)
  785. {
  786.     return call_voidarg_function(
  787.         quantify_is_recording_register_window_traps,
  788.         self, args);
  789. }
  790. static PyObject*
  791. pure_quantify_disable_recording_data(PyObject *self, PyObject *args)
  792. {
  793.     return call_voidarg_function(quantify_disable_recording_data,
  794.                      self, args);
  795. }
  796. static PyObject*
  797. pure_quantify_clear_data(PyObject *self, PyObject *args)
  798. {
  799.     return call_voidarg_function(quantify_clear_data, self, args);
  800. }
  801. static PyObject*
  802. pure_quantify_save_data(PyObject *self, PyObject *args)
  803. {
  804.     return call_voidarg_function(quantify_save_data, self, args);
  805. }
  806. static PyObject*
  807. pure_quantify_save_data_to_file(PyObject *self, PyObject *args)
  808. {
  809.     return call_stringarg_function(quantify_save_data_to_file, self, args);
  810. }
  811. static PyObject*
  812. pure_quantify_add_annotation(PyObject *self, PyObject *args)
  813. {
  814.     return call_stringarg_function(quantify_add_annotation, self, args);
  815. }
  816.  
  817. #endif /* QUANTIFY_H */
  818.  
  819.  
  820.  
  821. /* external interface
  822.  */
  823. static struct PyMethodDef
  824. pure_methods[] = {
  825. #ifdef COMMON_PURE_FUNCTIONS
  826.     {"pure_logfile_printf",            pure_pure_logfile_printf,            1},
  827.     {"pure_printf",                    pure_pure_printf,                    1},
  828.     {"pure_printf_with_banner",        pure_pure_printf_with_banner,        1},
  829. #endif /* COMMON_PURE_FUNCTIONS */
  830. #ifdef PURIFY_H
  831.     {"purify_all_inuse",               pure_purify_all_inuse,               1},
  832.     {"purify_all_leaks",               pure_purify_all_leaks,               1},
  833.     {"purify_new_inuse",               pure_purify_new_inuse,               1},
  834.     {"purify_new_leaks",               pure_purify_new_leaks,               1},
  835.     {"purify_clear_inuse",             pure_purify_clear_inuse,             1},
  836.     {"purify_clear_leaks",             pure_purify_clear_leaks,             1},
  837.     {"purify_all_fds_inuse",           pure_purify_all_fds_inuse,           1},
  838.     {"purify_new_fds_inuse",           pure_purify_new_fds_inuse,           1},
  839.     /* see purify.h */
  840.     {"purify_logfile_printf",          pure_pure_logfile_printf,            1},
  841.     {"purify_printf",                  pure_pure_printf,                    1},
  842.     {"purify_printf_with_banner",      pure_pure_printf_with_banner,        1},
  843.     /**/
  844.     {"purify_printf_with_call_chain",  pure_purify_printf_with_call_chain,  1},
  845.     {"purify_set_pool_id",             pure_purify_set_pool_id,             1},
  846.     {"purify_get_pool_id",             pure_purify_get_pool_id,             1},
  847.     {"purify_set_user_data",           pure_purify_set_user_data,           1},
  848.     {"purify_get_user_data",           pure_purify_get_user_data,           1},
  849.     {"purify_map_pool",                pure_purify_map_pool,                1},
  850.     {"purify_map_pool_id",             pure_purify_map_pool_id,             1},
  851.     {"purify_new_messages",            pure_purify_new_messages,            1},
  852.     {"purify_all_messages",            pure_purify_all_messages,            1},
  853.     {"purify_clear_messages",          pure_purify_clear_messages,          1},
  854.     {"purify_clear_new_messages",      pure_purify_clear_new_messages,      1},
  855.     {"purify_start_batch",             pure_purify_start_batch,             1},
  856.     {"purify_start_batch_show_first",  pure_purify_start_batch_show_first,  1},
  857.     {"purify_stop_batch",              pure_purify_stop_batch,              1},
  858.     {"purify_name_thread",             pure_purify_name_thread,             1},
  859.     {"purify_watch",                   pure_purify_watch,                   1},
  860.     {"purify_watch_1",                 pure_purify_watch_1,                 1},
  861.     {"purify_watch_2",                 pure_purify_watch_2,                 1},
  862.     {"purify_watch_4",                 pure_purify_watch_4,                 1},
  863.     {"purify_watch_8",                 pure_purify_watch_8,                 1},
  864.     {"purify_watch_w_1",               pure_purify_watch_w_1,               1},
  865.     {"purify_watch_w_2",               pure_purify_watch_w_2,               1},
  866.     {"purify_watch_w_4",               pure_purify_watch_w_4,               1},
  867.     {"purify_watch_w_8",               pure_purify_watch_w_8,               1},
  868.     {"purify_watch_r_1",               pure_purify_watch_r_1,               1},
  869.     {"purify_watch_r_2",               pure_purify_watch_r_2,               1},
  870.     {"purify_watch_r_4",               pure_purify_watch_r_4,               1},
  871.     {"purify_watch_r_8",               pure_purify_watch_r_8,               1},
  872.     {"purify_watch_rw_1",              pure_purify_watch_rw_1,              1},
  873.     {"purify_watch_rw_2",              pure_purify_watch_rw_2,              1},
  874.     {"purify_watch_rw_4",              pure_purify_watch_rw_4,              1},
  875.     {"purify_watch_rw_8",              pure_purify_watch_rw_8,              1},
  876.     {"purify_watch_n",                 pure_purify_watch_n,                 1},
  877.     {"purify_watch_info",              pure_purify_watch_info,              1},
  878.     {"purify_watch_remove",            pure_purify_watch_remove,            1},
  879.     {"purify_watch_remove_all",        pure_purify_watch_remove_all,        1},
  880.     {"purify_describe",                pure_purify_describe,                1},
  881.     {"purify_what_colors",             pure_purify_what_colors,             1},
  882.     {"purify_is_running",              pure_purify_is_running,              1},
  883.     {"purify_assert_is_readable",      pure_purify_assert_is_readable,      1},
  884.     {"purify_assert_is_writable",      pure_purify_assert_is_writable,      1},
  885. #if HAS_PURIFY_EXIT
  886.     /* I wish I could include this, but I can't.  See the notes at the
  887.      * top of the file.
  888.      */
  889.     {"purify_exit",                    pure_purify_exit,                    1},
  890. #endif /* HAS_PURIFY_EXIT */
  891. #endif /* PURIFY_H */
  892. #ifdef QUANTIFY_H
  893.     {"quantify_is_running",            pure_quantify_is_running,            1},
  894.     {"quantify_help",                  pure_quantify_help,                  1},
  895.     {"quantify_print_recording_state", pure_quantify_print_recording_state, 1},
  896.     {"quantify_start_recording_data",  pure_quantify_start_recording_data,  1},
  897.     {"quantify_stop_recording_data",   pure_quantify_stop_recording_data,   1},
  898.     {"quantify_is_recording_data",     pure_quantify_is_recording_data,  1},
  899.     {"quantify_start_recording_system_calls",
  900.      pure_quantify_start_recording_system_calls, 1},
  901.     {"quantify_stop_recording_system_calls",
  902.      pure_quantify_stop_recording_system_calls, 1},
  903.     {"quantify_is_recording_system_calls",
  904.      pure_quantify_is_recording_system_calls, 1},
  905.     {"quantify_start_recording_system_call",
  906.      pure_quantify_start_recording_system_call, 1},
  907.     {"quantify_stop_recording_system_call",
  908.      pure_quantify_stop_recording_system_call, 1},
  909.     {"quantify_is_recording_system_call",
  910.      pure_quantify_is_recording_system_call, 1},
  911.     {"quantify_start_recording_dynamic_library_data",
  912.      pure_quantify_start_recording_dynamic_library_data, 1},
  913.     {"quantify_stop_recording_dynamic_library_data",
  914.      pure_quantify_stop_recording_dynamic_library_data, 1},
  915.     {"quantify_is_recording_dynamic_library_data",
  916.      pure_quantify_is_recording_dynamic_library_data, 1},
  917.     {"quantify_start_recording_register_window_traps",
  918.      pure_quantify_start_recording_register_window_traps, 1},
  919.     {"quantify_stop_recording_register_window_traps",
  920.      pure_quantify_stop_recording_register_window_traps, 1},
  921.     {"quantify_is_recording_register_window_traps",
  922.      pure_quantify_is_recording_register_window_traps, 1},
  923.     {"quantify_disable_recording_data",
  924.      pure_quantify_disable_recording_data, 1},
  925.     {"quantify_clear_data",        pure_quantify_clear_data,        1},
  926.     {"quantify_save_data",         pure_quantify_save_data,         1},
  927.     {"quantify_save_data_to_file", pure_quantify_save_data_to_file, 1},
  928.     {"quantify_add_annotation",    pure_quantify_add_annotation,    1},
  929. #endif /* QUANTIFY_H */
  930.     {NULL,  NULL}                 /* sentinel */
  931. };
  932.  
  933.  
  934.  
  935. static void
  936. ins(d, name, val)
  937.     PyObject *d;
  938.     char* name;
  939.     long val;
  940. {
  941.     PyObject *v = PyInt_FromLong(val);
  942.     if (v) {
  943.         (void)PyDict_SetItemString(d, name, v);
  944.         Py_DECREF(v);
  945.     }
  946. }
  947.  
  948.  
  949. void
  950. initpure()
  951. {
  952.     PyObject *m, *d;
  953.  
  954.     m = Py_InitModule("pure", pure_methods);
  955.     d = PyModule_GetDict(m);
  956.  
  957.         /* this is bogus because we should be able to find this information
  958.          * out from the header files.  Pure's current versions don't
  959.          * include this information!
  960.          */
  961. #ifdef PURE_PURIFY_VERSION
  962.     ins(d, "PURIFY_VERSION", PURE_PURIFY_VERSION);
  963. #else
  964.     PyDict_SetItemString(d, "PURIFY_VERSION", Py_None);
  965. #endif
  966.  
  967.         /* these aren't terribly useful because purify_exit() isn't
  968.          * exported correctly.  See the note at the top of the file.
  969.          */
  970. #ifdef PURIFY_EXIT_ERRORS
  971.     ins(d, "PURIFY_EXIT_ERRORS", PURIFY_EXIT_ERRORS);
  972. #endif
  973. #ifdef PURIFY_EXIT_LEAKS
  974.     ins(d, "PURIFY_EXIT_LEAKS",  PURIFY_EXIT_LEAKS);
  975. #endif
  976. #ifdef PURIFY_EXIT_PLEAKS
  977.     ins(d, "PURIFY_EXIT_PLEAKS", PURIFY_EXIT_PLEAKS);
  978. #endif
  979.  
  980.  
  981. #ifdef PURE_QUANTIFY_VERSION
  982.     ins(d, "QUANTIFY_VERSION", PURE_QUANTIFY_VERSION);
  983. #else
  984.     PyDict_SetItemString(d, "QUANTIFY_VERSION", Py_None);
  985. #endif
  986. }
  987.