symbian-qemu-0.9.1-12/python-2.6.1/Modules/puremodule.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     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,            METH_VARARGS},
       
   827     {"pure_printf",                    pure_pure_printf,                    METH_VARARGS},
       
   828     {"pure_printf_with_banner",        pure_pure_printf_with_banner,        METH_VARARGS},
       
   829 #endif /* COMMON_PURE_FUNCTIONS */
       
   830 #ifdef PURIFY_H
       
   831     {"purify_all_inuse",               pure_purify_all_inuse,               METH_VARARGS},
       
   832     {"purify_all_leaks",               pure_purify_all_leaks,               METH_VARARGS},
       
   833     {"purify_new_inuse",               pure_purify_new_inuse,               METH_VARARGS},
       
   834     {"purify_new_leaks",               pure_purify_new_leaks,               METH_VARARGS},
       
   835     {"purify_clear_inuse",             pure_purify_clear_inuse,             METH_VARARGS},
       
   836     {"purify_clear_leaks",             pure_purify_clear_leaks,             METH_VARARGS},
       
   837     {"purify_all_fds_inuse",           pure_purify_all_fds_inuse,           METH_VARARGS},
       
   838     {"purify_new_fds_inuse",           pure_purify_new_fds_inuse,           METH_VARARGS},
       
   839     /* see purify.h */
       
   840     {"purify_logfile_printf",          pure_pure_logfile_printf,            METH_VARARGS},
       
   841     {"purify_printf",                  pure_pure_printf,                    METH_VARARGS},
       
   842     {"purify_printf_with_banner",      pure_pure_printf_with_banner,        METH_VARARGS},
       
   843     /**/
       
   844     {"purify_printf_with_call_chain",  pure_purify_printf_with_call_chain,  METH_VARARGS},
       
   845     {"purify_set_pool_id",             pure_purify_set_pool_id,             METH_VARARGS},
       
   846     {"purify_get_pool_id",             pure_purify_get_pool_id,             METH_VARARGS},
       
   847     {"purify_set_user_data",           pure_purify_set_user_data,           METH_VARARGS},
       
   848     {"purify_get_user_data",           pure_purify_get_user_data,           METH_VARARGS},
       
   849     {"purify_map_pool",                pure_purify_map_pool,                METH_VARARGS},
       
   850     {"purify_map_pool_id",             pure_purify_map_pool_id,             METH_VARARGS},
       
   851     {"purify_new_messages",            pure_purify_new_messages,            METH_VARARGS},
       
   852     {"purify_all_messages",            pure_purify_all_messages,            METH_VARARGS},
       
   853     {"purify_clear_messages",          pure_purify_clear_messages,          METH_VARARGS},
       
   854     {"purify_clear_new_messages",      pure_purify_clear_new_messages,      METH_VARARGS},
       
   855     {"purify_start_batch",             pure_purify_start_batch,             METH_VARARGS},
       
   856     {"purify_start_batch_show_first",  pure_purify_start_batch_show_first,  METH_VARARGS},
       
   857     {"purify_stop_batch",              pure_purify_stop_batch,              METH_VARARGS},
       
   858     {"purify_name_thread",             pure_purify_name_thread,             METH_VARARGS},
       
   859     {"purify_watch",                   pure_purify_watch,                   METH_VARARGS},
       
   860     {"purify_watch_1",                 pure_purify_watch_1,                 METH_VARARGS},
       
   861     {"purify_watch_2",                 pure_purify_watch_2,                 METH_VARARGS},
       
   862     {"purify_watch_4",                 pure_purify_watch_4,                 METH_VARARGS},
       
   863     {"purify_watch_8",                 pure_purify_watch_8,                 METH_VARARGS},
       
   864     {"purify_watch_w_1",               pure_purify_watch_w_1,               METH_VARARGS},
       
   865     {"purify_watch_w_2",               pure_purify_watch_w_2,               METH_VARARGS},
       
   866     {"purify_watch_w_4",               pure_purify_watch_w_4,               METH_VARARGS},
       
   867     {"purify_watch_w_8",               pure_purify_watch_w_8,               METH_VARARGS},
       
   868     {"purify_watch_r_1",               pure_purify_watch_r_1,               METH_VARARGS},
       
   869     {"purify_watch_r_2",               pure_purify_watch_r_2,               METH_VARARGS},
       
   870     {"purify_watch_r_4",               pure_purify_watch_r_4,               METH_VARARGS},
       
   871     {"purify_watch_r_8",               pure_purify_watch_r_8,               METH_VARARGS},
       
   872     {"purify_watch_rw_1",              pure_purify_watch_rw_1,              METH_VARARGS},
       
   873     {"purify_watch_rw_2",              pure_purify_watch_rw_2,              METH_VARARGS},
       
   874     {"purify_watch_rw_4",              pure_purify_watch_rw_4,              METH_VARARGS},
       
   875     {"purify_watch_rw_8",              pure_purify_watch_rw_8,              METH_VARARGS},
       
   876     {"purify_watch_n",                 pure_purify_watch_n,                 METH_VARARGS},
       
   877     {"purify_watch_info",              pure_purify_watch_info,              METH_VARARGS},
       
   878     {"purify_watch_remove",            pure_purify_watch_remove,            METH_VARARGS},
       
   879     {"purify_watch_remove_all",        pure_purify_watch_remove_all,        METH_VARARGS},
       
   880     {"purify_describe",                pure_purify_describe,                METH_VARARGS},
       
   881     {"purify_what_colors",             pure_purify_what_colors,             METH_VARARGS},
       
   882     {"purify_is_running",              pure_purify_is_running,              METH_VARARGS},
       
   883     {"purify_assert_is_readable",      pure_purify_assert_is_readable,      METH_VARARGS},
       
   884     {"purify_assert_is_writable",      pure_purify_assert_is_writable,      METH_VARARGS},
       
   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,                    METH_VARARGS},
       
   890 #endif /* HAS_PURIFY_EXIT */
       
   891 #endif /* PURIFY_H */
       
   892 #ifdef QUANTIFY_H
       
   893     {"quantify_is_running",            pure_quantify_is_running,            METH_VARARGS},
       
   894     {"quantify_help",                  pure_quantify_help,                  METH_VARARGS},
       
   895     {"quantify_print_recording_state", pure_quantify_print_recording_state, METH_VARARGS},
       
   896     {"quantify_start_recording_data",  pure_quantify_start_recording_data,  METH_VARARGS},
       
   897     {"quantify_stop_recording_data",   pure_quantify_stop_recording_data,   METH_VARARGS},
       
   898     {"quantify_is_recording_data",     pure_quantify_is_recording_data,  METH_VARARGS},
       
   899     {"quantify_start_recording_system_calls",
       
   900      pure_quantify_start_recording_system_calls, METH_VARARGS},
       
   901     {"quantify_stop_recording_system_calls",
       
   902      pure_quantify_stop_recording_system_calls, METH_VARARGS},
       
   903     {"quantify_is_recording_system_calls",
       
   904      pure_quantify_is_recording_system_calls, METH_VARARGS},
       
   905     {"quantify_start_recording_system_call",
       
   906      pure_quantify_start_recording_system_call, METH_VARARGS},
       
   907     {"quantify_stop_recording_system_call",
       
   908      pure_quantify_stop_recording_system_call, METH_VARARGS},
       
   909     {"quantify_is_recording_system_call",
       
   910      pure_quantify_is_recording_system_call, METH_VARARGS},
       
   911     {"quantify_start_recording_dynamic_library_data",
       
   912      pure_quantify_start_recording_dynamic_library_data, METH_VARARGS},
       
   913     {"quantify_stop_recording_dynamic_library_data",
       
   914      pure_quantify_stop_recording_dynamic_library_data, METH_VARARGS},
       
   915     {"quantify_is_recording_dynamic_library_data",
       
   916      pure_quantify_is_recording_dynamic_library_data, METH_VARARGS},
       
   917     {"quantify_start_recording_register_window_traps",
       
   918      pure_quantify_start_recording_register_window_traps, METH_VARARGS},
       
   919     {"quantify_stop_recording_register_window_traps",
       
   920      pure_quantify_stop_recording_register_window_traps, METH_VARARGS},
       
   921     {"quantify_is_recording_register_window_traps",
       
   922      pure_quantify_is_recording_register_window_traps, METH_VARARGS},
       
   923     {"quantify_disable_recording_data",
       
   924      pure_quantify_disable_recording_data, METH_VARARGS},
       
   925     {"quantify_clear_data",        pure_quantify_clear_data,        METH_VARARGS},
       
   926     {"quantify_save_data",         pure_quantify_save_data,         METH_VARARGS},
       
   927     {"quantify_save_data_to_file", pure_quantify_save_data_to_file, METH_VARARGS},
       
   928     {"quantify_add_annotation",    pure_quantify_add_annotation,    METH_VARARGS},
       
   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 	if (PyErr_WarnPy3k("the pure module has been removed in "
       
   955 	                   "Python 3.0", 2) < 0)
       
   956 	    return;	
       
   957 
       
   958 	m = Py_InitModule("pure", pure_methods);
       
   959 	if (m == NULL)
       
   960     		return;
       
   961 	d = PyModule_GetDict(m);
       
   962 
       
   963         /* this is bogus because we should be able to find this information
       
   964          * out from the header files.  Pure's current versions don't
       
   965          * include this information!
       
   966          */
       
   967 #ifdef PURE_PURIFY_VERSION
       
   968 	ins(d, "PURIFY_VERSION", PURE_PURIFY_VERSION);
       
   969 #else
       
   970 	PyDict_SetItemString(d, "PURIFY_VERSION", Py_None);
       
   971 #endif
       
   972 
       
   973         /* these aren't terribly useful because purify_exit() isn't
       
   974          * exported correctly.  See the note at the top of the file.
       
   975          */
       
   976 #ifdef PURIFY_EXIT_ERRORS
       
   977 	ins(d, "PURIFY_EXIT_ERRORS", PURIFY_EXIT_ERRORS);
       
   978 #endif
       
   979 #ifdef PURIFY_EXIT_LEAKS
       
   980 	ins(d, "PURIFY_EXIT_LEAKS",  PURIFY_EXIT_LEAKS);
       
   981 #endif
       
   982 #ifdef PURIFY_EXIT_PLEAKS
       
   983 	ins(d, "PURIFY_EXIT_PLEAKS", PURIFY_EXIT_PLEAKS);
       
   984 #endif
       
   985 
       
   986 
       
   987 #ifdef PURE_QUANTIFY_VERSION
       
   988 	ins(d, "QUANTIFY_VERSION", PURE_QUANTIFY_VERSION);
       
   989 #else
       
   990 	PyDict_SetItemString(d, "QUANTIFY_VERSION", Py_None);
       
   991 #endif
       
   992 }