Edit File by line
/home/barbar84/public_h.../wp-conte.../plugins/sujqvwi/ExeBy/smexe_ro.../usr/include/python2....
File: pyfpe.h
#ifndef Py_PYFPE_H
[0] Fix | Delete
#define Py_PYFPE_H
[1] Fix | Delete
#ifdef __cplusplus
[2] Fix | Delete
extern "C" {
[3] Fix | Delete
#endif
[4] Fix | Delete
/*
[5] Fix | Delete
---------------------------------------------------------------------
[6] Fix | Delete
/ Copyright (c) 1996. \
[7] Fix | Delete
| The Regents of the University of California. |
[8] Fix | Delete
| All rights reserved. |
[9] Fix | Delete
| |
[10] Fix | Delete
| Permission to use, copy, modify, and distribute this software for |
[11] Fix | Delete
| any purpose without fee is hereby granted, provided that this en- |
[12] Fix | Delete
| tire notice is included in all copies of any software which is or |
[13] Fix | Delete
| includes a copy or modification of this software and in all |
[14] Fix | Delete
| copies of the supporting documentation for such software. |
[15] Fix | Delete
| |
[16] Fix | Delete
| This work was produced at the University of California, Lawrence |
[17] Fix | Delete
| Livermore National Laboratory under contract no. W-7405-ENG-48 |
[18] Fix | Delete
| between the U.S. Department of Energy and The Regents of the |
[19] Fix | Delete
| University of California for the operation of UC LLNL. |
[20] Fix | Delete
| |
[21] Fix | Delete
| DISCLAIMER |
[22] Fix | Delete
| |
[23] Fix | Delete
| This software was prepared as an account of work sponsored by an |
[24] Fix | Delete
| agency of the United States Government. Neither the United States |
[25] Fix | Delete
| Government nor the University of California nor any of their em- |
[26] Fix | Delete
| ployees, makes any warranty, express or implied, or assumes any |
[27] Fix | Delete
| liability or responsibility for the accuracy, completeness, or |
[28] Fix | Delete
| usefulness of any information, apparatus, product, or process |
[29] Fix | Delete
| disclosed, or represents that its use would not infringe |
[30] Fix | Delete
| privately-owned rights. Reference herein to any specific commer- |
[31] Fix | Delete
| cial products, process, or service by trade name, trademark, |
[32] Fix | Delete
| manufacturer, or otherwise, does not necessarily constitute or |
[33] Fix | Delete
| imply its endorsement, recommendation, or favoring by the United |
[34] Fix | Delete
| States Government or the University of California. The views and |
[35] Fix | Delete
| opinions of authors expressed herein do not necessarily state or |
[36] Fix | Delete
| reflect those of the United States Government or the University |
[37] Fix | Delete
| of California, and shall not be used for advertising or product |
[38] Fix | Delete
\ endorsement purposes. /
[39] Fix | Delete
---------------------------------------------------------------------
[40] Fix | Delete
*/
[41] Fix | Delete
[42] Fix | Delete
/*
[43] Fix | Delete
* Define macros for handling SIGFPE.
[44] Fix | Delete
* Lee Busby, LLNL, November, 1996
[45] Fix | Delete
* busby1@llnl.gov
[46] Fix | Delete
*
[47] Fix | Delete
*********************************************
[48] Fix | Delete
* Overview of the system for handling SIGFPE:
[49] Fix | Delete
*
[50] Fix | Delete
* This file (Include/pyfpe.h) defines a couple of "wrapper" macros for
[51] Fix | Delete
* insertion into your Python C code of choice. Their proper use is
[52] Fix | Delete
* discussed below. The file Python/pyfpe.c defines a pair of global
[53] Fix | Delete
* variables PyFPE_jbuf and PyFPE_counter which are used by the signal
[54] Fix | Delete
* handler for SIGFPE to decide if a particular exception was protected
[55] Fix | Delete
* by the macros. The signal handler itself, and code for enabling the
[56] Fix | Delete
* generation of SIGFPE in the first place, is in a (new) Python module
[57] Fix | Delete
* named fpectl. This module is standard in every respect. It can be loaded
[58] Fix | Delete
* either statically or dynamically as you choose, and like any other
[59] Fix | Delete
* Python module, has no effect until you import it.
[60] Fix | Delete
*
[61] Fix | Delete
* In the general case, there are three steps toward handling SIGFPE in any
[62] Fix | Delete
* Python code:
[63] Fix | Delete
*
[64] Fix | Delete
* 1) Add the *_PROTECT macros to your C code as required to protect
[65] Fix | Delete
* dangerous floating point sections.
[66] Fix | Delete
*
[67] Fix | Delete
* 2) Turn on the inclusion of the code by adding the ``--with-fpectl''
[68] Fix | Delete
* flag at the time you run configure. If the fpectl or other modules
[69] Fix | Delete
* which use the *_PROTECT macros are to be dynamically loaded, be
[70] Fix | Delete
* sure they are compiled with WANT_SIGFPE_HANDLER defined.
[71] Fix | Delete
*
[72] Fix | Delete
* 3) When python is built and running, import fpectl, and execute
[73] Fix | Delete
* fpectl.turnon_sigfpe(). This sets up the signal handler and enables
[74] Fix | Delete
* generation of SIGFPE whenever an exception occurs. From this point
[75] Fix | Delete
* on, any properly trapped SIGFPE should result in the Python
[76] Fix | Delete
* FloatingPointError exception.
[77] Fix | Delete
*
[78] Fix | Delete
* Step 1 has been done already for the Python kernel code, and should be
[79] Fix | Delete
* done soon for the NumPy array package. Step 2 is usually done once at
[80] Fix | Delete
* python install time. Python's behavior with respect to SIGFPE is not
[81] Fix | Delete
* changed unless you also do step 3. Thus you can control this new
[82] Fix | Delete
* facility at compile time, or run time, or both.
[83] Fix | Delete
*
[84] Fix | Delete
********************************
[85] Fix | Delete
* Using the macros in your code:
[86] Fix | Delete
*
[87] Fix | Delete
* static PyObject *foobar(PyObject *self,PyObject *args)
[88] Fix | Delete
* {
[89] Fix | Delete
* ....
[90] Fix | Delete
* PyFPE_START_PROTECT("Error in foobar", return 0)
[91] Fix | Delete
* result = dangerous_op(somearg1, somearg2, ...);
[92] Fix | Delete
* PyFPE_END_PROTECT(result)
[93] Fix | Delete
* ....
[94] Fix | Delete
* }
[95] Fix | Delete
*
[96] Fix | Delete
* If a floating point error occurs in dangerous_op, foobar returns 0 (NULL),
[97] Fix | Delete
* after setting the associated value of the FloatingPointError exception to
[98] Fix | Delete
* "Error in foobar". ``Dangerous_op'' can be a single operation, or a block
[99] Fix | Delete
* of code, function calls, or any combination, so long as no alternate
[100] Fix | Delete
* return is possible before the PyFPE_END_PROTECT macro is reached.
[101] Fix | Delete
*
[102] Fix | Delete
* The macros can only be used in a function context where an error return
[103] Fix | Delete
* can be recognized as signaling a Python exception. (Generally, most
[104] Fix | Delete
* functions that return a PyObject * will qualify.)
[105] Fix | Delete
*
[106] Fix | Delete
* Guido's original design suggestion for PyFPE_START_PROTECT and
[107] Fix | Delete
* PyFPE_END_PROTECT had them open and close a local block, with a locally
[108] Fix | Delete
* defined jmp_buf and jmp_buf pointer. This would allow recursive nesting
[109] Fix | Delete
* of the macros. The Ansi C standard makes it clear that such local
[110] Fix | Delete
* variables need to be declared with the "volatile" type qualifier to keep
[111] Fix | Delete
* setjmp from corrupting their values. Some current implementations seem
[112] Fix | Delete
* to be more restrictive. For example, the HPUX man page for setjmp says
[113] Fix | Delete
*
[114] Fix | Delete
* Upon the return from a setjmp() call caused by a longjmp(), the
[115] Fix | Delete
* values of any non-static local variables belonging to the routine
[116] Fix | Delete
* from which setjmp() was called are undefined. Code which depends on
[117] Fix | Delete
* such values is not guaranteed to be portable.
[118] Fix | Delete
*
[119] Fix | Delete
* I therefore decided on a more limited form of nesting, using a counter
[120] Fix | Delete
* variable (PyFPE_counter) to keep track of any recursion. If an exception
[121] Fix | Delete
* occurs in an ``inner'' pair of macros, the return will apparently
[122] Fix | Delete
* come from the outermost level.
[123] Fix | Delete
*
[124] Fix | Delete
*/
[125] Fix | Delete
[126] Fix | Delete
#ifdef WANT_SIGFPE_HANDLER
[127] Fix | Delete
#include <signal.h>
[128] Fix | Delete
#include <setjmp.h>
[129] Fix | Delete
#include <math.h>
[130] Fix | Delete
extern jmp_buf PyFPE_jbuf;
[131] Fix | Delete
extern int PyFPE_counter;
[132] Fix | Delete
extern double PyFPE_dummy(void *);
[133] Fix | Delete
[134] Fix | Delete
#define PyFPE_START_PROTECT(err_string, leave_stmt) \
[135] Fix | Delete
if (!PyFPE_counter++ && setjmp(PyFPE_jbuf)) { \
[136] Fix | Delete
PyErr_SetString(PyExc_FloatingPointError, err_string); \
[137] Fix | Delete
PyFPE_counter = 0; \
[138] Fix | Delete
leave_stmt; \
[139] Fix | Delete
}
[140] Fix | Delete
[141] Fix | Delete
/*
[142] Fix | Delete
* This (following) is a heck of a way to decrement a counter. However,
[143] Fix | Delete
* unless the macro argument is provided, code optimizers will sometimes move
[144] Fix | Delete
* this statement so that it gets executed *before* the unsafe expression
[145] Fix | Delete
* which we're trying to protect. That pretty well messes things up,
[146] Fix | Delete
* of course.
[147] Fix | Delete
*
[148] Fix | Delete
* If the expression(s) you're trying to protect don't happen to return a
[149] Fix | Delete
* value, you will need to manufacture a dummy result just to preserve the
[150] Fix | Delete
* correct ordering of statements. Note that the macro passes the address
[151] Fix | Delete
* of its argument (so you need to give it something which is addressable).
[152] Fix | Delete
* If your expression returns multiple results, pass the last such result
[153] Fix | Delete
* to PyFPE_END_PROTECT.
[154] Fix | Delete
*
[155] Fix | Delete
* Note that PyFPE_dummy returns a double, which is cast to int.
[156] Fix | Delete
* This seeming insanity is to tickle the Floating Point Unit (FPU).
[157] Fix | Delete
* If an exception has occurred in a preceding floating point operation,
[158] Fix | Delete
* some architectures (notably Intel 80x86) will not deliver the interrupt
[159] Fix | Delete
* until the *next* floating point operation. This is painful if you've
[160] Fix | Delete
* already decremented PyFPE_counter.
[161] Fix | Delete
*/
[162] Fix | Delete
#define PyFPE_END_PROTECT(v) PyFPE_counter -= (int)PyFPE_dummy(&(v));
[163] Fix | Delete
[164] Fix | Delete
#else
[165] Fix | Delete
[166] Fix | Delete
#define PyFPE_START_PROTECT(err_string, leave_stmt)
[167] Fix | Delete
#define PyFPE_END_PROTECT(v)
[168] Fix | Delete
[169] Fix | Delete
#endif
[170] Fix | Delete
[171] Fix | Delete
#ifdef __cplusplus
[172] Fix | Delete
}
[173] Fix | Delete
#endif
[174] Fix | Delete
#endif /* !Py_PYFPE_H */
[175] Fix | Delete
[176] Fix | Delete
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function