blob: d2adbb1ebd82f21eb1478c7c06ec6f437c8567ee [file] [log] [blame]
--- cdecimal2.c 2011-06-14 20:23:19.000000000 +0200
+++ cdecimal2_failapi.c 2011-06-14 20:33:44.000000000 +0200
@@ -161,6 +161,105 @@
/* Top level Exception; inherits from ArithmeticError */
static PyObject *DecimalException = NULL;
+/* FailAPI */
+static PyObject *FailAPIException = NULL;
+
+static unsigned long counter = 0;
+static unsigned long apicalls = 0;
+static unsigned long failpoint = 0;
+#if PY_VERSION_HEX >= 0x02080000
+static Py_complex _cfail = {-1, -1};
+#endif
+
+#define FFUNC(ret, funcall) (\
+ (++counter, ++apicalls == failpoint) \
+ ? (PyErr_SetString(FailAPIException, "failapi"), ret) \
+ : funcall)
+
+#define FFUNC_NOEX(ret, funcall) (\
+ (++counter, ++apicalls == failpoint) ? ret : funcall)
+
+#define IFUNC(funcall) (\
+ (++counter, ++apicalls == failpoint) \
+ ? (PyErr_SetString(FailAPIException, "failapi"), -1) \
+ : funcall)
+
+#define PFUNC(funcall) (\
+ (++counter, ++apicalls == failpoint) \
+ ? (PyErr_SetString(FailAPIException, "failapi"), NULL) \
+ : funcall)
+
+#define PFUNC_NOEX(funcall) (\
+ (++counter, ++apicalls == failpoint) ? NULL : funcall)
+
+#define SFUNC(func, result, ...) do { \
+ if (++counter, ++apicalls == failpoint) \
+ mpd_seterror(result, MPD_Malloc_error, &status); \
+ else \
+ func(result, __VA_ARGS__); \
+ } while (0)
+
+static PyObject *
+get_failpoint(PyObject *self UNUSED, PyObject *dummy UNUSED)
+{
+ return Py_BuildValue("k", failpoint);
+}
+
+static PyObject *
+get_apicalls(PyObject *self UNUSED, PyObject *dummy UNUSED)
+{
+ return Py_BuildValue("k", apicalls);
+}
+
+static PyObject *
+set_failpoint(PyObject *self UNUSED, PyObject *value)
+{
+ failpoint = PyLong_AsUnsignedLong(value);
+ if (PyErr_Occurred()) {
+ return NULL; /* GCOV_NOT_REACHED */
+ }
+ Py_RETURN_NONE;
+}
+
+static PyObject *
+set_apicalls(PyObject *self UNUSED, PyObject *value)
+{
+ apicalls = PyLong_AsUnsignedLong(value);
+ if (PyErr_Occurred()) {
+ return NULL; /* GCOV_NOT_REACHED */
+ }
+ Py_RETURN_NONE;
+}
+
+void *
+mpd_malloc_fail(size_t size)
+{
+
+ if (++apicalls == failpoint) {
+ return NULL;
+ }
+ return PyMem_Malloc(size);
+}
+
+void *
+mpd_calloc_fail(size_t nmemb, size_t size)
+{
+ if (++apicalls == failpoint) {
+ return NULL;
+ }
+ return mpd_callocfunc_em(nmemb, size);
+}
+
+void *
+mpd_realloc_fail(void *ptr, size_t size)
+{
+ if (++apicalls == failpoint) {
+ return NULL;
+ }
+ return PyMem_Realloc(ptr, size);
+}
+/* End FailAPI */
+
/* Exceptions that correspond to IEEE signals; inherit from DecimalException */
static DecCondMap signal_map[] = {
{"InvalidOperation", "cdecimal.InvalidOperation", MPD_IEEE_Invalid_operation, NULL},
@@ -251,7 +350,7 @@
static int
runtime_error_int(const char *mesg)
{
- PyErr_SetString(PyExc_RuntimeError, mesg);
+ PyErr_SetString(FailAPIException, mesg);
return -1;
}
#define INTERNAL_ERROR_INT(funcname) \
@@ -260,7 +359,7 @@
static PyObject *
runtime_error_ptr(const char *mesg)
{
- PyErr_SetString(PyExc_RuntimeError, mesg);
+ PyErr_SetString(FailAPIException, mesg);
return NULL;
}
#define INTERNAL_ERROR_PTR(funcname) \
@@ -307,20 +406,20 @@
PyObject *list;
DecCondMap *cm;
- if ((list = PyList_New(0)) == NULL) {
+ if ((list = PFUNC(PyList_New(0))) == NULL) {
return NULL;
}
for (cm = cond_map; cm->name != NULL; cm++) {
if (flags&cm->mpd_cond) {
- if (PyList_Append(list, cm->dec_cond) < 0) {
+ if (IFUNC(PyList_Append(list, cm->dec_cond)) < 0) {
goto error;
}
}
}
for (cm = signal_map+1; cm->name != NULL; cm++) {
if (flags&cm->mpd_cond) {
- if (PyList_Append(list, cm->dec_cond) < 0) {
+ if (IFUNC(PyList_Append(list, cm->dec_cond)) < 0) {
goto error;
}
}
@@ -339,13 +438,13 @@
PyObject *list;
DecCondMap *cm;
- if ((list = PyList_New(0)) == NULL) {
+ if ((list = PFUNC(PyList_New(0))) == NULL) {
return NULL;
}
for (cm = signal_map; cm->name != NULL; cm++) {
if (flags&cm->mpd_cond) {
- if (PyList_Append(list, cm->dec_cond) < 0) {
+ if (IFUNC(PyList_Append(list, cm->dec_cond)) < 0) {
goto error;
}
}
@@ -405,7 +504,7 @@
return UINT32_MAX;
}
- if ((x = PyObject_IsTrue(b)) < 0) {
+ if ((x = IFUNC(PyObject_IsTrue(b))) < 0) {
return UINT32_MAX;
}
if (x == 1) {
@@ -422,10 +521,10 @@
long x;
if (PyInt_Check(v)) {
- x = PyInt_AsLong(v);
+ x = IFUNC(PyInt_AsLong(v));
}
else if (PyLong_Check(v)) {
- x = PyLong_AsLong(v);
+ x = IFUNC(PyLong_AsLong(v));
}
else {
PyErr_SetString(PyExc_TypeError,
@@ -450,10 +549,10 @@
mpd_ssize_t x;
if (PyInt_Check(v)) {
- x = PyInt_AsLong(v);
+ x = IFUNC(PyInt_AsLong(v));
}
else if (PyLong_Check(v)) {
- x = _PyLong_AsMpdSsize(v);
+ x = IFUNC(_PyLong_AsMpdSsize(v));
}
else {
PyErr_SetString(PyExc_TypeError,
@@ -473,6 +572,12 @@
{
mpd_context_t *ctx = CTX(context);
+ if (status&MPD_Malloc_error) {
+ /* Translate MemoryError to FailAPIException */
+ PyErr_SetString(FailAPIException, "failapi");
+ return 1;
+ }
+
ctx->status |= status;
if (ctx->traps&status) {
PyObject *ex, *siglist;
@@ -501,7 +606,7 @@
static int
signaldict_init(PyObject *self, PyObject *args, PyObject *kwds)
{
- if (PyDict_Type.tp_init(self, args, kwds) < 0) {
+ if (IFUNC(PyDict_Type.tp_init(self, args, kwds)) < 0) {
return -1;
}
@@ -521,7 +626,7 @@
for (cm = signal_map; cm->name != NULL; cm++) {
b = (flags&cm->mpd_cond) ? Py_True : Py_False;
- if (PyDict_SetItem(self, cm->dec_cond, b) < 0) {
+ if (IFUNC(PyDict_SetItem(self, cm->dec_cond, b)) < 0) {
return -1;
}
}
@@ -537,7 +642,7 @@
SdFlags(self) = 0;
for (cm = signal_map; cm->name != NULL; cm++) {
- if (PyDict_SetItem(self, cm->dec_cond, Py_False) < 0) {
+ if (IFUNC(PyDict_SetItem(self, cm->dec_cond, Py_False)) < 0) {
return -1;
}
}
@@ -554,19 +659,19 @@
return -1;
}
- if ((x = PyObject_IsTrue(value)) < 0) {
+ if ((x = IFUNC(PyObject_IsTrue(value))) < 0) {
return -1;
}
if (x == 1) {
SdFlags(self) |= flag;
- if (PyDict_SetItem(self, key, Py_True) < 0) {
+ if (IFUNC(PyDict_SetItem(self, key, Py_True)) < 0) {
return -1;
}
return 0;
}
else {
SdFlags(self) &= ~flag;
- if (PyDict_SetItem(self, key, Py_False) < 0) {
+ if (IFUNC(PyDict_SetItem(self, key, Py_False)) < 0) {
return -1;
}
return 0;
@@ -579,7 +684,7 @@
if (signaldict_update(self) < 0) {
return NULL;
}
- return PyObject_CallMethod((PyObject *)&PyDict_Type, name, "O", self);
+ return PFUNC(PyObject_CallMethod((PyObject *)&PyDict_Type, name, "O", self));
}
static int
@@ -595,7 +700,7 @@
return -1;
}
}
- return PyDict_Type.tp_compare(a, b);
+ return IFUNC(PyDict_Type.tp_compare(a, b));
}
static int
@@ -604,7 +709,7 @@
if (signaldict_update(self) < 0) {
return -1;
}
- return PyDict_Contains(self, key);
+ return IFUNC(PyDict_Contains(self, key));
}
static PyObject *
@@ -613,25 +718,25 @@
if (signaldict_update(self) < 0) {
return NULL;
}
- return PyDict_Copy(self);
+ return PFUNC(PyDict_Copy(self));
}
static PyObject *
signaldict_get(PyObject *self, PyObject *args)
{
PyObject *key = NULL, *failobj = NULL;
- if (!PyArg_ParseTuple(args, "O|O", &key, &failobj)) {
+ if (!FFUNC(0, PyArg_ParseTuple(args, "O|O", &key, &failobj))) {
return NULL; /* GCOV_NOT_REACHED (why?) */
}
if (signaldict_update(self) < 0) {
return NULL;
}
if (failobj) {
- return PyObject_CallMethod((PyObject *)&PyDict_Type, "get",
- "OOO", self, key, failobj);
+ return PFUNC(PyObject_CallMethod((PyObject *)&PyDict_Type, "get",
+ "OOO", self, key, failobj));
}
- return PyObject_CallMethod((PyObject *)&PyDict_Type, "get",
- "OO", self, key);
+ return PFUNC(PyObject_CallMethod((PyObject *)&PyDict_Type, "get",
+ "OO", self, key));
}
static PyObject *
@@ -641,8 +746,8 @@
if (signaldict_update(self) < 0) {
return NULL;
}
- ret = PyDict_Contains(self, key);
- return ret < 0 ? NULL : PyBool_FromLong(ret);
+ ret = IFUNC(PyDict_Contains(self, key));
+ return ret < 0 ? NULL : PFUNC(PyBool_FromLong(ret));
}
static PyObject *
@@ -651,7 +756,7 @@
if (signaldict_update(self) < 0) {
return NULL;
}
- return PyDict_Items(self);
+ return PFUNC(PyDict_Items(self));
}
static PyObject *
@@ -660,7 +765,7 @@
if (signaldict_update(self) < 0) {
return NULL;
}
- return PyDict_Type.tp_iter(self);
+ return PFUNC(PyDict_Type.tp_iter(self));
}
static PyObject *
@@ -687,7 +792,7 @@
if (signaldict_update(self) < 0) {
return NULL;
}
- return PyDict_Keys(self);
+ return PFUNC(PyDict_Keys(self));
}
static Py_ssize_t
@@ -696,7 +801,7 @@
if (signaldict_update(self) < 0) {
return -1;
}
- return PyDict_Type.tp_as_mapping->mp_length(self);
+ return IFUNC(PyDict_Type.tp_as_mapping->mp_length(self));
}
static int
@@ -714,7 +819,7 @@
if (signaldict_update(self) < 0) {
return NULL;
}
- return PyDict_Type.tp_repr(self);
+ return PFUNC(PyDict_Type.tp_repr(self));
}
static PyObject *
@@ -740,7 +845,7 @@
if (signaldict_update(self) < 0) {
return NULL;
}
- return PyDict_Type.tp_as_mapping->mp_subscript(self, key);
+ return PFUNC(PyDict_Type.tp_as_mapping->mp_subscript(self, key));
}
static PyObject *
@@ -749,7 +854,7 @@
if (signaldict_update(self) < 0) {
return NULL;
}
- return PyDict_Values(self);
+ return PFUNC(PyDict_Values(self));
}
@@ -844,7 +949,7 @@
mpd_context_t *ctx;
ctx = CTX(self);
- return Py_BuildValue(CONV_mpd_ssize_t, mpd_getprec(ctx));
+ return PFUNC(Py_BuildValue(CONV_mpd_ssize_t, mpd_getprec(ctx)));
}
static PyObject *
@@ -853,7 +958,7 @@
mpd_context_t *ctx;
ctx = CTX(self);
- return Py_BuildValue(CONV_mpd_ssize_t, mpd_getemax(ctx));
+ return PFUNC(Py_BuildValue(CONV_mpd_ssize_t, mpd_getemax(ctx)));
}
static PyObject *
@@ -862,7 +967,7 @@
mpd_context_t *ctx;
ctx = CTX(self);
- return Py_BuildValue(CONV_mpd_ssize_t, mpd_getemin(ctx));
+ return PFUNC(Py_BuildValue(CONV_mpd_ssize_t, mpd_getemin(ctx)));
}
static PyObject *
@@ -871,7 +976,7 @@
mpd_context_t *ctx;
ctx = CTX(self);
- return Py_BuildValue(CONV_mpd_ssize_t, mpd_etiny(ctx));
+ return PFUNC(Py_BuildValue(CONV_mpd_ssize_t, mpd_etiny(ctx)));
}
static PyObject *
@@ -880,7 +985,7 @@
mpd_context_t *ctx;
ctx = CTX(self);
- return Py_BuildValue(CONV_mpd_ssize_t, mpd_etop(ctx));
+ return PFUNC(Py_BuildValue(CONV_mpd_ssize_t, mpd_etop(ctx)));
}
static PyObject *
@@ -889,13 +994,13 @@
mpd_context_t *ctx;
ctx = CTX(self);
- return Py_BuildValue("i", mpd_getround(ctx));
+ return PFUNC(Py_BuildValue("i", mpd_getround(ctx)));
}
static PyObject *
context_getcapitals(PyObject *self, void *closure UNUSED)
{
- return Py_BuildValue("i", CtxCaps(self));
+ return PFUNC(Py_BuildValue("i", CtxCaps(self)));
}
static PyObject *
@@ -904,7 +1009,7 @@
mpd_context_t *ctx;
ctx = CTX(self);
- return Py_BuildValue("i", mpd_gettraps(ctx));
+ return PFUNC(Py_BuildValue("i", mpd_gettraps(ctx)));
}
static PyObject *
@@ -913,7 +1018,7 @@
mpd_context_t *ctx;
ctx = CTX(self);
- return Py_BuildValue("i", mpd_getstatus(ctx));
+ return PFUNC(Py_BuildValue("i", mpd_getstatus(ctx)));
}
static PyObject *
@@ -922,7 +1027,7 @@
mpd_context_t *ctx;
ctx = CTX(self);
- return Py_BuildValue("i", mpd_getclamp(ctx));
+ return PFUNC(Py_BuildValue("i", mpd_getclamp(ctx)));
}
static PyObject *
@@ -931,7 +1036,7 @@
mpd_context_t *ctx;
ctx = CTX(self);
- return Py_BuildValue("i", mpd_getcr(ctx));
+ return PFUNC(Py_BuildValue("i", mpd_getcr(ctx)));
}
static int
@@ -1091,7 +1196,7 @@
}
ctx = CTX(self);
- if (!mpd_qsettraps(ctx, flags)) {
+ if (!FFUNC_NOEX(0, mpd_qsettraps(ctx, flags))) {
INTERNAL_ERROR_INT("context_settraps");
}
@@ -1110,7 +1215,7 @@
}
ctx = CTX(self);
- if (!mpd_qsettraps(ctx, flags)) {
+ if (!FFUNC_NOEX(0, mpd_qsettraps(ctx, flags))) {
INTERNAL_ERROR_INT("context_settraps_list");
}
@@ -1129,7 +1234,7 @@
}
ctx = CTX(self);
- if (!mpd_qsettraps(ctx, flags)) {
+ if (!FFUNC_NOEX(0, mpd_qsettraps(ctx, flags))) {
INTERNAL_ERROR_INT("context_settraps_dict");
}
@@ -1148,7 +1253,7 @@
}
ctx = CTX(self);
- if (!mpd_qsetstatus(ctx, flags)) {
+ if (!FFUNC_NOEX(0, mpd_qsetstatus(ctx, flags))) {
INTERNAL_ERROR_INT("context_setstatus");
}
@@ -1167,7 +1272,7 @@
}
ctx = CTX(self);
- if (!mpd_qsetstatus(ctx, flags)) {
+ if (!FFUNC_NOEX(0, mpd_qsetstatus(ctx, flags))) {
INTERNAL_ERROR_INT("context_setstatus_list");
}
@@ -1186,7 +1291,7 @@
}
ctx = CTX(self);
- if (!mpd_qsetstatus(ctx, flags)) {
+ if (!FFUNC_NOEX(0, mpd_qsetstatus(ctx, flags))) {
INTERNAL_ERROR_INT("context_setstatus_dict");
}
@@ -1315,18 +1420,18 @@
PyDecContextObject *self = NULL;
mpd_context_t *ctx;
- self = PyObject_New(PyDecContextObject, &PyDecContext_Type);
+ self = PFUNC(PyObject_New(PyDecContextObject, &PyDecContext_Type));
if (self == NULL) {
return NULL;
}
- self->traps = PyObject_CallObject((PyObject *)&PyDecSignalDict_Type, NULL);
+ self->traps = PFUNC(PyObject_CallObject((PyObject *)&PyDecSignalDict_Type, NULL));
if (self->traps == NULL) {
self->flags = NULL;
Py_DECREF(self);
return NULL;
}
- self->flags = PyObject_CallObject((PyObject *)&PyDecSignalDict_Type, NULL);
+ self->flags = PFUNC(PyObject_CallObject((PyObject *)&PyDecSignalDict_Type, NULL));
if (self->flags == NULL) {
Py_DECREF(self);
return NULL;
@@ -1369,7 +1474,7 @@
int i;
if (PyInt_Check(v) || PyLong_Check(v)) {
- x = PyLong_AsLong(v);
+ x = IFUNC(PyLong_AsLong(v));
if (PyErr_Occurred()) {
return -1;
}
@@ -1408,13 +1513,13 @@
if (default_context_template) {
t = *CTX(default_context_template);
}
- if (!PyArg_ParseTupleAndKeywords(
+ if (!FFUNC(0, PyArg_ParseTupleAndKeywords(
args, kwds,
"|" CONV_mpd_ssize_t "O" CONV_mpd_ssize_t CONV_mpd_ssize_t "ii"
"OOi", kwlist,
&t.prec, &rounding, &t.emin, &t.emax, &capitals, &t.clamp,
&status, &traps, &t.allcr
- )) {
+ ))) {
return -1;
}
if (rounding != NULL) {
@@ -1487,32 +1592,32 @@
ctx = CTX(self);
cp = s; mem = FD_CTX_LEN;
- n = snprintf(cp, mem,
+ n = FFUNC_NOEX(-1, snprintf(cp, mem,
"Context(prec=%"PRI_mpd_ssize_t", rounding=%s, "
"Emin=%"PRI_mpd_ssize_t", Emax=%"PRI_mpd_ssize_t", "
"capitals=%d, clamp=%d, flags=",
ctx->prec, mpd_round_string[ctx->round],
ctx->emin, ctx->emax,
- self->capitals, ctx->clamp);
+ self->capitals, ctx->clamp));
if (n < 0 || n >= mem) goto error;
cp += n; mem -= n;
- n = mpd_lsnprint_signals(cp, mem, ctx->status, dec_signal_string);
+ n = FFUNC_NOEX(-1, mpd_lsnprint_signals(cp, mem, ctx->status, dec_signal_string));
if (n < 0 || n >= mem) goto error;
cp += n; mem -= n;
- n = snprintf(cp, mem, ", traps=");
+ n = FFUNC_NOEX(-1, snprintf(cp, mem, ", traps="));
if (n < 0 || n >= mem) goto error;
cp += n; mem -= n;
- n = mpd_lsnprint_signals(cp, mem, ctx->traps, dec_signal_string);
+ n = FFUNC_NOEX(-1, mpd_lsnprint_signals(cp, mem, ctx->traps, dec_signal_string));
if (n < 0 || n >= mem) goto error;
cp += n; mem -= n;
- n = snprintf(cp, mem, ")");
+ n = FFUNC_NOEX(-1, snprintf(cp, mem, ")"));
if (n < 0 || n >= mem) goto error;
- return PyString_FromString(s);
+ return PFUNC(PyString_FromString(s));
error:
INTERNAL_ERROR_PTR("context_repr");
@@ -1562,7 +1667,7 @@
goto error;
}
- context = PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL);
+ context = PFUNC(PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL));
if (context == NULL) {
return NULL;
}
@@ -1583,7 +1688,7 @@
{
PyObject *copy;
- copy = PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL);
+ copy = PFUNC(PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL));
if (copy == NULL) {
return NULL;
}
@@ -1613,13 +1718,13 @@
return NULL;
}
- ret = Py_BuildValue(
+ ret = PFUNC(Py_BuildValue(
"O(" CONV_mpd_ssize_t "s" CONV_mpd_ssize_t CONV_mpd_ssize_t
"iiOO)",
Py_TYPE(self),
ctx->prec, mpd_round_string[ctx->round], ctx->emin, ctx->emax,
CtxCaps(self), ctx->clamp, flags, traps
- );
+ ));
Py_DECREF(flags);
Py_DECREF(traps);
@@ -1758,9 +1863,9 @@
PyObject *dict = NULL;
PyObject *tl_context = NULL;
- dict = PyThreadState_GetDict();
+ dict = PFUNC_NOEX(PyThreadState_GetDict());
if (dict == NULL) {
- PyErr_SetString(PyExc_RuntimeError,
+ PyErr_SetString(FailAPIException,
"cannot get thread state.");
return NULL;
}
@@ -1778,7 +1883,7 @@
if (tl_context == NULL) {
return NULL;
}
- if (PyDict_SetItem(dict, tls_context_key, tl_context) < 0) {
+ if (IFUNC(PyDict_SetItem(dict, tls_context_key, tl_context)) < 0) {
Py_DECREF(tl_context);
return NULL;
}
@@ -1825,9 +1930,9 @@
CONTEXT_CHECK(v);
- dict = PyThreadState_GetDict();
+ dict = PFUNC_NOEX(PyThreadState_GetDict());
if (dict == NULL) {
- PyErr_SetString(PyExc_RuntimeError,
+ PyErr_SetString(FailAPIException,
"cannot get thread state.");
return NULL;
}
@@ -1845,7 +1950,7 @@
Py_INCREF(v);
}
- if (PyDict_SetItem(dict, tls_context_key, v) < 0) {
+ if (IFUNC(PyDict_SetItem(dict, tls_context_key, v)) < 0) {
Py_DECREF(v);
return NULL;
}
@@ -1867,13 +1972,13 @@
CURRENT_CONTEXT(global);
local = global;
- if (!PyArg_ParseTuple(args, "|O", &local)) {
+ if (!FFUNC(0, PyArg_ParseTuple(args, "|O", &local))) {
return NULL;
}
CONTEXT_CHECK_VA(local);
- self = PyObject_New(PyDecContextManagerObject,
- &PyDecContextManager_Type);
+ self = PFUNC(PyObject_New(PyDecContextManagerObject,
+ &PyDecContextManager_Type));
if (self == NULL) {
return NULL;
}
@@ -1921,6 +2026,19 @@
ret = PyDec_SetCurrentContext(NULL, self->global);
if (ret == NULL) {
+ /* This particular failpoint leaves the global state
+ undefined (global context is not restored, but the
+ exception is swallowed by the test suite). So we
+ make sure that the proper exception has occcurred,
+ restore the context and reraise the esception. */
+ assert(PyErr_Occurred() == FailAPIException);
+ PyErr_Clear();
+
+ ret = PyDec_SetCurrentContext(NULL, self->global);
+ PyErr_SetString(FailAPIException, "failapi");
+
+ assert(ret != NULL);
+ Py_DECREF(ret);
return NULL;
}
Py_DECREF(ret);
@@ -1979,10 +2097,10 @@
PyObject *dec;
if (type == &PyDec_Type) {
- dec = (PyObject *)PyObject_New(PyDecObject, &PyDec_Type);
+ dec = (PyObject *)PFUNC(PyObject_New(PyDecObject, &PyDec_Type));
}
else {
- dec = type->tp_alloc(type, 0);
+ dec = PFUNC(type->tp_alloc(type, 0));
}
if (dec == NULL) {
return NULL;
@@ -1991,7 +2109,7 @@
MPD(dec) = mpd_qnew();
if (MPD(dec) == NULL) {
Py_DECREF(dec);
- PyErr_NoMemory();
+ PyErr_SetString(FailAPIException, "failapi");
return NULL;
}
@@ -2073,14 +2191,14 @@
{
char *s;
- s = PyMem_Malloc(PyUnicode_GET_SIZE(u)+1);
+ s = PFUNC_NOEX(PyMem_Malloc(PyUnicode_GET_SIZE(u)+1));
if (s == NULL) {
- PyErr_NoMemory();
+ PyErr_SetString(FailAPIException, "failapi");
return NULL;
}
- if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(u),
+ if (IFUNC(PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(u),
PyUnicode_GET_SIZE(u),
- s, NULL)) {
+ s, NULL))) {
PyMem_Free(s);
return NULL;
}
@@ -2108,8 +2226,8 @@
if (s != x || t != y) {
n = t-s;
- if ((y = PyMem_Malloc(n+1)) == NULL) {
- PyErr_NoMemory();
+ if ((y = PFUNC_NOEX(PyMem_Malloc(n+1))) == NULL) {
+ PyErr_SetString(FailAPIException, "failapi");
return NULL;
}
strncpy(y, s, n);
@@ -2237,7 +2355,7 @@
return NULL;
}
- mpd_qset_ssize(MPD(dec), v, CTX(context), &status);
+ SFUNC(mpd_qset_ssize, MPD(dec), v, CTX(context), &status);
if (dec_addstatus(context, status)) {
Py_DECREF(dec);
return NULL;
@@ -2260,7 +2378,7 @@
mpd_maxcontext(&maxctx);
- mpd_qset_ssize(MPD(dec), v, &maxctx, &status);
+ SFUNC(mpd_qset_ssize, MPD(dec), v, &maxctx, &status);
if (dec_addstatus(context, status)) {
Py_DECREF(dec);
return NULL;
@@ -2275,7 +2393,7 @@
{
mpd_ssize_t x;
- x = _PyInt_AsMpdSsize(pyint);
+ x = IFUNC(_PyInt_AsMpdSsize(pyint));
if (PyErr_Occurred()) {
return NULL;
}
@@ -2291,7 +2409,7 @@
{
mpd_ssize_t x;
- x = _PyInt_AsMpdSsize(pyint);
+ x = IFUNC(_PyInt_AsMpdSsize(pyint));
if (PyErr_Occurred()) {
return NULL;
}
@@ -2432,7 +2550,7 @@
return NULL;
}
- x = PyFloat_AsDouble(v);
+ x = IFUNC(PyFloat_AsDouble(v));
if (x == -1.0 && PyErr_Occurred()) {
return NULL;
}
@@ -2455,13 +2573,13 @@
}
/* absolute value of the float */
- tmp = PyObject_CallMethod(v, "__abs__", NULL);
+ tmp = PFUNC(PyObject_CallMethod(v, "__abs__", NULL));
if (tmp == NULL) {
return NULL;
}
/* float as integer ratio: numerator/denominator */
- n_d = PyObject_CallMethod(tmp, "as_integer_ratio", NULL);
+ n_d = PFUNC(PyObject_CallMethod(tmp, "as_integer_ratio", NULL));
Py_DECREF(tmp);
if (n_d == NULL) {
return NULL;
@@ -2471,13 +2589,13 @@
/* slow but portable bit_length() */
if (PyInt_Check(d)) {
- if ((tmp = _PyInt_Format((PyIntObject *)d, 2, 0)) == NULL) {
+ if ((tmp = PFUNC(_PyInt_Format((PyIntObject *)d, 2, 0))) == NULL) {
Py_DECREF(n_d);
return NULL;
}
}
else {
- if ((tmp = _PyLong_Format(d, 2, 0, 0)) == NULL) {
+ if ((tmp = PFUNC(_PyLong_Format(d, 2, 0, 0))) == NULL) {
Py_DECREF(n_d);
return NULL;
}
@@ -2499,14 +2617,14 @@
d1 = mpd_qnew();
if (d1 == NULL) {
Py_DECREF(dec);
- PyErr_NoMemory();
+ PyErr_SetString(FailAPIException, "failapi");
return NULL;
}
d2 = mpd_qnew();
if (d2 == NULL) {
mpd_del(d1);
Py_DECREF(dec);
- PyErr_NoMemory();
+ PyErr_SetString(FailAPIException, "failapi");
return NULL;
}
@@ -2603,7 +2721,7 @@
"sign must be an integer with the value 0 or 1.");
goto error;
}
- sign = PyLong_AsLong(tmp);
+ sign = IFUNC(PyLong_AsLong(tmp));
if (PyErr_Occurred()) {
goto error;
}
@@ -2659,15 +2777,15 @@
tsize = PyTuple_Size(digits);
/* [sign][coeffdigits+1][E][-][expdigits+1]['\0'] */
mem = 1 + tsize + 3 + MPD_EXPDIGITS + 2;
- cp = decstring = PyMem_Malloc(mem);
+ cp = decstring = PFUNC_NOEX(PyMem_Malloc(mem));
if (decstring == NULL) {
- PyErr_NoMemory();
+ PyErr_SetString(FailAPIException, "failapi");
goto error;
}
- n = snprintf(cp, mem, "%s", sign_special);
+ n = FFUNC(-1, snprintf(cp, mem, "%s", sign_special));
if (n < 0 || n >= mem) {
- PyErr_SetString(PyExc_RuntimeError,
+ PyErr_SetString(FailAPIException,
"internal error in dec_sequence_as_str.");
goto error;
}
@@ -2684,7 +2802,7 @@
"coefficient must be a tuple of digits.");
goto error;
}
- l = PyLong_AsLong(tmp);
+ l = IFUNC(PyLong_AsLong(tmp));
if (PyErr_Occurred()) {
goto error;
}
@@ -2700,9 +2818,9 @@
if (sign_special[1] == '\0') {
/* not a special number */
*cp++ = 'E';
- n = snprintf(cp, MPD_EXPDIGITS+1, "%" PRI_mpd_ssize_t, exp);
+ n = FFUNC(-1, snprintf(cp, MPD_EXPDIGITS+1, "%" PRI_mpd_ssize_t, exp));
if (n < 0 || n >= MPD_EXPDIGITS+1) {
- PyErr_SetString(PyExc_RuntimeError,
+ PyErr_SetString(FailAPIException,
"internal error in dec_sequence_as_str.");
goto error;
}
@@ -2855,13 +2973,13 @@
return NULL;
}
- mpd_qcopy(MPD(result), MPD(v), &status);
+ SFUNC(mpd_qcopy, MPD(result), MPD(v), &status);
if (dec_addstatus(context, status)) {
Py_DECREF(result);
return NULL;
}
- mpd_qfinalize(MPD(result), CTX(context), &status);
+ SFUNC(mpd_qfinalize, MPD(result), CTX(context), &status);
if (dec_addstatus(context, status)) {
Py_DECREF(result);
return NULL;
@@ -2978,7 +3096,7 @@
PyObject *context;
CURRENT_CONTEXT(context);
- if (!PyArg_ParseTuple(args, "|OO", &v, &context)) {
+ if (!FFUNC(0, PyArg_ParseTuple(args, "|OO", &v, &context))) {
return NULL;
}
CONTEXT_CHECK_VA(context);
@@ -2991,7 +3109,7 @@
{
PyObject *v = NULL;
- if (!PyArg_ParseTuple(args, "|O", &v)) {
+ if (!FFUNC(0, PyArg_ParseTuple(args, "|O", &v))) {
return NULL;
}
@@ -3122,7 +3240,7 @@
mpd_t *vv;
/* v is not special, r is a rational */
- tmp = PyObject_GetAttrString(r, "denominator");
+ tmp = PFUNC(PyObject_GetAttrString(r, "denominator"));
if (tmp == NULL) {
return NULL;
}
@@ -3135,7 +3253,7 @@
vv = mpd_qncopy(MPD(v));
if (vv == NULL) {
Py_DECREF(denom);
- PyErr_NoMemory();
+ PyErr_SetString(FailAPIException, "failapi");
return NULL;
}
result = dec_alloc();
@@ -3175,7 +3293,7 @@
{
PyObject *tmp, *num;
- tmp = PyObject_GetAttrString(r, "numerator");
+ tmp = PFUNC(PyObject_GetAttrString(r, "numerator"));
if (tmp == NULL) {
return NULL;
}
@@ -3226,12 +3344,12 @@
}
#if PY_VERSION_HEX >= 0x02080000
else if (PyComplex_Check(w) && (op == Py_EQ || op == Py_NE)) {
- Py_complex c = PyComplex_AsCComplex(w);
+ Py_complex c = FFUNC(_cfail, PyComplex_AsCComplex(w));
if (PyErr_Occurred()) {
*wcmp = NULL;
}
else if (c.imag == 0.0) {
- PyObject *tmp = PyFloat_FromDouble(c.real);
+ PyObject *tmp = PFUNC(PyFloat_FromDouble(c.real));
if (tmp == NULL) {
*wcmp = NULL;
}
@@ -3291,11 +3409,11 @@
CURRENT_CONTEXT(c);
res = mpd_to_sci(MPD(dec), CtxCaps(c));
if (res == NULL) {
- PyErr_NoMemory();
+ PyErr_SetString(FailAPIException, "failapi");
return NULL;
}
- s = PyString_FromString(res);
+ s = PFUNC(PyString_FromString(res));
mpd_free(res);
return s;
@@ -3316,16 +3434,18 @@
CURRENT_CONTEXT(c);
cp = mpd_to_sci(MPD(dec), CtxCaps(c));
if (cp == NULL) {
- PyErr_NoMemory();
+ PyErr_SetString(FailAPIException, "failapi");
return NULL;
}
declen = strlen(cp);
err = 0;
+ mpd_reallocfunc = mpd_realloc_fail;
cp = mpd_realloc(cp, (mpd_size_t)(declen+dtaglen+3), sizeof *cp, &err);
+ mpd_reallocfunc = PyMem_Realloc;
if (err) {
mpd_free(cp);
- PyErr_NoMemory();
+ PyErr_SetString(FailAPIException, "failapi");
return NULL;
}
@@ -3335,7 +3455,7 @@
cp[declen+dtaglen+1] = ')';
cp[declen+dtaglen+2] = '\0';
- s = PyString_FromString(cp);
+ s = PFUNC(PyString_FromString(cp));
mpd_free(cp);
return s;
@@ -3360,7 +3480,7 @@
CURRENT_CONTEXT(context);
- if (!PyArg_ParseTuple(args, "O|O", &fmtarg, &override)) {
+ if (!FFUNC(0, PyArg_ParseTuple(args, "O|O", &fmtarg, &override))) {
return NULL;
}
@@ -3368,7 +3488,7 @@
fmt = fmtarg;
}
else if (PyUnicode_Check(fmtarg)) {
- if ((fmt = PyUnicode_AsUTF8String(fmtarg)) == NULL) {
+ if ((fmt = PFUNC(PyUnicode_AsUTF8String(fmtarg))) == NULL) {
return NULL;
}
}
@@ -3391,19 +3511,19 @@
goto finish;
}
if ((dot = PyDict_GetItemString(override, "decimal_point"))) {
- if ((dot = PyUnicode_AsUTF8String(dot)) == NULL) {
+ if ((dot = PFUNC(PyUnicode_AsUTF8String(dot))) == NULL) {
goto finish;
}
spec.dot = PyBytes_AS_STRING(dot);
}
if ((sep = PyDict_GetItemString(override, "thousands_sep"))) {
- if ((sep = PyUnicode_AsUTF8String(sep)) == NULL) {
+ if ((sep = PFUNC(PyUnicode_AsUTF8String(sep))) == NULL) {
goto finish;
}
spec.sep = PyBytes_AS_STRING(sep);
}
if ((grouping = PyDict_GetItemString(override, "grouping"))) {
- if ((grouping = PyUnicode_AsUTF8String(grouping)) == NULL) {
+ if ((grouping = PFUNC(PyUnicode_AsUTF8String(grouping))) == NULL) {
goto finish;
}
spec.grouping = PyBytes_AS_STRING(grouping);
@@ -3416,7 +3536,7 @@
dec_addstatus(context, status);
goto finish;
}
- result = Py_BuildValue("s", decstring);
+ result = PFUNC(Py_BuildValue("s", decstring));
finish:
@@ -3455,12 +3575,12 @@
}
if ((x = mpd_qnew()) == NULL) {
- PyErr_NoMemory();
+ PyErr_SetString(FailAPIException, "failapi");
return NULL;
}
workctx = *CTX(context);
workctx.round = round;
- mpd_qround_to_int(x, MPD(dec), &workctx, &status);
+ SFUNC(mpd_qround_to_int, x, MPD(dec), &workctx, &status);
if (dec_addstatus(context, status)) {
mpd_del(x);
return NULL;
@@ -3472,17 +3592,17 @@
l = mpd_qget_ssize(x, &status);
if (!(status&MPD_Invalid_operation)) {
mpd_del(x);
- return _PyInt_FromMpdSsize(l);
+ return PFUNC(_PyInt_FromMpdSsize(l));
}
}
- maxsize = mpd_sizeinbase(x, PyLong_BASE);
+ maxsize = FFUNC_NOEX((size_t)PY_SSIZE_T_MAX+1, mpd_sizeinbase(x, PyLong_BASE));
if (maxsize > PY_SSIZE_T_MAX) {
mpd_del(x);
- PyErr_NoMemory();
+ PyErr_SetString(FailAPIException, "failapi");
return NULL;
}
- if ((pylong = _PyLong_New(maxsize)) == NULL) {
+ if ((pylong = PFUNC(_PyLong_New(maxsize))) == NULL) {
mpd_del(x);
return NULL;
}
@@ -3526,8 +3646,8 @@
int round = -1;
CURRENT_CONTEXT(context);
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iO", kwlist,
- &round, &context)) {
+ if (!FFUNC(0, PyArg_ParseTupleAndKeywords(args, kwds, "|iO", kwlist,
+ &round, &context))) {
return NULL;
}
CONTEXT_CHECK_VA(context);
@@ -3543,7 +3663,7 @@
return NULL;
}
- mpd_qround_to_int(MPD(result), MPD(dec), &workctx, &status);
+ SFUNC(mpd_qround_to_int, MPD(result), MPD(dec), &workctx, &status);
if (dec_addstatus(context, status)) {
Py_DECREF(result);
return NULL;
@@ -3563,8 +3683,8 @@
int round = -1;
CURRENT_CONTEXT(context);
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iO", kwlist,
- &round, &context)) {
+ if (!FFUNC(0, PyArg_ParseTupleAndKeywords(args, kwds, "|iO", kwlist,
+ &round, &context))) {
return NULL;
}
CONTEXT_CHECK_VA(context);
@@ -3580,7 +3700,7 @@
return NULL;
}
- mpd_qround_to_intx(MPD(result), MPD(dec), &workctx, &status);
+ SFUNC(mpd_qround_to_intx, MPD(result), MPD(dec), &workctx, &status);
if (dec_addstatus(context, status)) {
Py_DECREF(result);
return NULL;
@@ -3614,7 +3734,7 @@
CURRENT_CONTEXT(context);
- if (!PyArg_ParseTuple(args, "|O", &x)) {
+ if (!FFUNC(0, PyArg_ParseTuple(args, "|O", &x))) {
return NULL;
}
@@ -3668,28 +3788,28 @@
if ((x = mpd_qncopy(MPD(dec))) == NULL) {
- PyErr_NoMemory();
+ PyErr_SetString(FailAPIException, "failapi");
goto out;
}
- sign = Py_BuildValue("i", mpd_sign(MPD(dec)));
+ sign = PFUNC(Py_BuildValue("i", mpd_sign(MPD(dec))));
if (sign == NULL) goto out;
if (mpd_isinfinite(x)) {
- if ((expt = Py_BuildValue("s", "F")) == NULL) {
+ if ((expt = PFUNC(Py_BuildValue("s", "F"))) == NULL) {
goto out;
}
/* decimal.py has non-compliant infinity payloads. */
- if ((coeff = Py_BuildValue("(i)", 0)) == NULL) {
+ if ((coeff = PFUNC(Py_BuildValue("(i)", 0))) == NULL) {
goto out;
}
}
else {
if (mpd_isnan(x)) {
- expt = Py_BuildValue("s", mpd_isqnan(x)?"n":"N");
+ expt = PFUNC(Py_BuildValue("s", mpd_isqnan(x)?"n":"N"));
}
else {
- expt = Py_BuildValue(CONV_mpd_ssize_t, MPD(dec)->exp);
+ expt = PFUNC(Py_BuildValue(CONV_mpd_ssize_t, MPD(dec)->exp));
}
if (expt == NULL) goto out;
@@ -3702,33 +3822,33 @@
mpd_clear_flags(x);
intstring = mpd_to_sci(x, 1);
if (intstring == NULL) {
- PyErr_NoMemory();
+ PyErr_SetString(FailAPIException, "failapi");
goto out;
}
intlen = strlen(intstring);
- if ((coeff = PyTuple_New(intlen)) == NULL) {
+ if ((coeff = PFUNC(PyTuple_New(intlen))) == NULL) {
goto out;
}
for (i = 0; i < intlen; i++) {
- tmp = Py_BuildValue("i", intstring[i]-'0');
+ tmp = PFUNC(Py_BuildValue("i", intstring[i]-'0'));
if (tmp == NULL) goto out;
PyTuple_SET_ITEM(coeff, i, tmp);
}
}
else {
- if ((coeff = PyTuple_New(0)) == NULL) {
+ if ((coeff = PFUNC(PyTuple_New(0))) == NULL) {
goto out;
}
}
}
#if PY_VERSION_HEX >= 0x02060000
- result = PyObject_CallFunctionObjArgs(DecimalTuple,
- sign, coeff, expt, NULL);
+ result = PFUNC(PyObject_CallFunctionObjArgs(DecimalTuple,
+ sign, coeff, expt, NULL));
#else
- result = Py_BuildValue("(OOO)", sign, coeff, expt);
+ result = PFUNC(Py_BuildValue("(OOO)", sign, coeff, expt));
#endif
out:
@@ -3814,7 +3934,7 @@
PyObject *context; \
\
CURRENT_CONTEXT(context); \
- if (!PyArg_ParseTuple(args, "|O", &context)) { \
+ if (!FFUNC(0, PyArg_ParseTuple(args, "|O", &context))) { \
return NULL; \
} \
CONTEXT_CHECK_VA(context); \
@@ -3833,7 +3953,7 @@
uint32_t status = 0; \
\
CURRENT_CONTEXT(context); \
- if (!PyArg_ParseTuple(args, "|O", &context)) { \
+ if (!FFUNC(0, PyArg_ParseTuple(args, "|O", &context))) { \
return NULL; \
} \
CONTEXT_CHECK_VA(context); \
@@ -3862,7 +3982,7 @@
uint32_t status = 0; \
\
CURRENT_CONTEXT(context); \
- if (!PyArg_ParseTuple(args, "O|O", &w, &context)) { \
+ if (!FFUNC(0, PyArg_ParseTuple(args, "O|O", &w, &context))) { \
return NULL; \
} \
CONTEXT_CHECK_VA(context); \
@@ -3896,7 +4016,7 @@
PyObject *result; \
\
CURRENT_CONTEXT(context); \
- if (!PyArg_ParseTuple(args, "O|O", &w, &context)) { \
+ if (!FFUNC(0, PyArg_ParseTuple(args, "O|O", &w, &context))) { \
return NULL; \
} \
CONTEXT_CHECK_VA(context); \
@@ -3926,7 +4046,7 @@
uint32_t status = 0; \
\
CURRENT_CONTEXT(context); \
- if (!PyArg_ParseTuple(args, "OO|O", &w, &x, &context)) { \
+ if (!FFUNC(0, PyArg_ParseTuple(args, "OO|O", &w, &x, &context))) { \
return NULL; \
} \
CONTEXT_CHECK_VA(context); \
@@ -4024,7 +4144,7 @@
return NULL;
}
- ret = Py_BuildValue("(OO)", q, r);
+ ret = PFUNC(Py_BuildValue("(OO)", q, r));
Py_DECREF(r);
Py_DECREF(q);
return ret;
@@ -4139,7 +4259,7 @@
retval = mpd_adjexp(MPD(self));
}
- return _PyLong_FromMpdSsize(retval);
+ return PFUNC(_PyLong_FromMpdSsize(retval));
}
/* Apply either the current context or the context provided as an optional
@@ -4150,7 +4270,7 @@
PyObject *context;
CURRENT_CONTEXT(context);
- if (!PyArg_ParseTuple(args, "|O", &context)) {
+ if (!FFUNC(0, PyArg_ParseTuple(args, "|O", &context))) {
return NULL;
}
CONTEXT_CHECK_VA(context);
@@ -4170,7 +4290,7 @@
return NULL;
}
- mpd_qcopy_abs(MPD(result), MPD(self), &status);
+ SFUNC(mpd_qcopy_abs, MPD(result), MPD(self), &status);
if (dec_addstatus(context, status)) {
Py_DECREF(result);
return NULL;
@@ -4191,7 +4311,7 @@
return NULL;
}
- mpd_qcopy_negate(MPD(result), MPD(self), &status);
+ SFUNC(mpd_qcopy_negate, MPD(result), MPD(self), &status);
if (dec_addstatus(context, status)) {
Py_DECREF(result);
return NULL;
@@ -4223,7 +4343,7 @@
return NULL;
}
- mpd_qcopy_sign(MPD(result), MPD(a), MPD(b), &status);
+ SFUNC(mpd_qcopy_sign, MPD(result), MPD(a), MPD(b), &status);
Py_DECREF(a);
Py_DECREF(b);
if (dec_addstatus(context, status)) {
@@ -4249,13 +4369,13 @@
const char *cp;
CURRENT_CONTEXT(context);
- if (!PyArg_ParseTuple(args, "|O", &context)) {
+ if (!FFUNC(0, PyArg_ParseTuple(args, "|O", &context))) {
return NULL;
}
CONTEXT_CHECK_VA(context);
cp = mpd_class(MPD(self), CTX(context));
- return Py_BuildValue("s", cp);
+ return PFUNC(Py_BuildValue("s", cp));
}
static PyObject *
@@ -4282,7 +4402,7 @@
PyObject *ret;
CURRENT_CONTEXT(context);
- if (!PyArg_ParseTuple(args, "O|O", &w, &context)) {
+ if (!FFUNC(0, PyArg_ParseTuple(args, "O|O", &w, &context))) {
return NULL;
}
CONTEXT_CHECK_VA(context);
@@ -4309,7 +4429,7 @@
return NULL;
}
- ret = Py_BuildValue("(OO)", q, r);
+ ret = PFUNC(Py_BuildValue("(OO)", q, r));
Py_DECREF(r);
Py_DECREF(q);
return ret;
@@ -4327,8 +4447,8 @@
int round = -1;
CURRENT_CONTEXT(context);
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|iO", kwlist,
- &w, &round, &context)) {
+ if (!FFUNC(0, PyArg_ParseTupleAndKeywords(args, kwds, "O|iO", kwlist,
+ &w, &round, &context))) {
return NULL;
}
CONTEXT_CHECK_VA(context);
@@ -4380,7 +4500,7 @@
PyObject *a, *b;
CURRENT_CONTEXT(context);
- if (!PyArg_ParseTuple(args, "O|O", &w, &context)) {
+ if (!FFUNC(0, PyArg_ParseTuple(args, "O|O", &w, &context))) {
return NULL;
}
CONTEXT_CHECK_VA(context);
@@ -4397,7 +4517,7 @@
static PyObject *
dec_mpd_sign(PyObject *self, PyObject *dummy UNUSED)
{
- return Py_BuildValue("i", mpd_arith_sign(MPD(self)));
+ return PFUNC(Py_BuildValue("i", mpd_arith_sign(MPD(self))));
}
static PyObject *
@@ -4408,18 +4528,18 @@
char *s;
CURRENT_CONTEXT(context);
- if (!PyArg_ParseTuple(args, "|O", &context)) {
+ if (!FFUNC(0, PyArg_ParseTuple(args, "|O", &context))) {
return NULL;
}
CONTEXT_CHECK_VA(context);
s = mpd_to_sci(MPD(self), CtxCaps(context));
if (s == NULL) {
- PyErr_NoMemory();
+ PyErr_SetString(FailAPIException, "failapi");
return NULL;
}
- result = PyString_FromString(s);
+ result = PFUNC(PyString_FromString(s));
mpd_free(s);
return result;
@@ -4433,18 +4553,18 @@
char *s;
CURRENT_CONTEXT(context);
- if (!PyArg_ParseTuple(args, "|O", &context)) {
+ if (!FFUNC(0, PyArg_ParseTuple(args, "|O", &context))) {
return NULL;
}
CONTEXT_CHECK_VA(context);
s = mpd_to_eng(MPD(self), CtxCaps(context));
if (s == NULL) {
- PyErr_NoMemory();
+ PyErr_SetString(FailAPIException, "failapi");
return NULL;
}
- result = PyString_FromString(s);
+ result = PFUNC(PyString_FromString(s));
mpd_free(s);
return result;
@@ -4536,11 +4656,11 @@
long result;
if ((a = dec_alloc()) == NULL) {
- PyErr_NoMemory();
+ PyErr_SetString(FailAPIException, "failapi");
return -1;
}
- if (!mpd_qcopy(MPD(a), MPD(v), &status)) {
- PyErr_NoMemory();
+ if (!FFUNC_NOEX(0, mpd_qcopy(MPD(a), MPD(v), &status))) {
+ PyErr_SetString(FailAPIException, "failapi");
result = -1;
goto finish;
}
@@ -4554,8 +4674,8 @@
mpd_maxcontext(&maxcontext);
#if PY_VERSION_HEX >= 0x02060000
- if ((tmp = mpd_qnew()) == NULL) {
- PyErr_NoMemory();
+ if ((tmp = PFUNC_NOEX(mpd_qnew())) == NULL) {
+ PyErr_SetString(FailAPIException, "failapi");
result = -1;
goto finish;
}
@@ -4565,7 +4685,7 @@
mpd_qset_ssize(tmp, MPD(a)->exp, &maxcontext, &status);
mpd_qpowmod(tmp, &ten, tmp, &two64m1, &maxcontext, &status);
MPD(a)->exp = 0;
- mpd_qmul(MPD(a), MPD(a), tmp, &maxcontext, &status);
+ SFUNC(mpd_qmul, MPD(a), MPD(a), tmp, &maxcontext, &status);
if (status&MPD_Errors) {
if (dec_addstatus(context, status)) {
@@ -4598,17 +4718,17 @@
cp = mpd_to_sci(MPD(a), 1);
if (cp == NULL) {
- PyErr_NoMemory();
+ PyErr_SetString(FailAPIException, "failapi");
result = -1;
goto finish;
}
- obj = Py_BuildValue("(i"CONV_mpd_ssize_t"s)", sign, exp, cp);
+ obj = PFUNC(Py_BuildValue("(i"CONV_mpd_ssize_t"s)", sign, exp, cp));
if (obj == NULL) {
result = -1;
goto finish;
}
- result = PyObject_Hash(obj);
+ result = IFUNC(PyObject_Hash(obj));
}
@@ -4635,7 +4755,7 @@
if (obj == NULL) {
return -1;
}
- result = PyObject_Hash(obj);
+ result = IFUNC(PyObject_Hash(obj));
Py_DECREF(obj);
return result;
}
@@ -4675,7 +4795,7 @@
}
}
- v_as_float = PyDec_AsFloat(v);
+ v_as_float = PFUNC(PyDec_AsFloat(v));
if (v_as_float == NULL) {
return -1;
}
@@ -4688,7 +4808,7 @@
if (!mpd_isspecial(MPD(roundtrip)) &&
mpd_qcmp(MPD(v), MPD(roundtrip), &status) == 0) {
- ret = PyObject_Hash(v_as_float);
+ ret = IFUNC(PyObject_Hash(v_as_float));
}
else {
ret = _dec_hash(v);
@@ -4709,7 +4829,7 @@
return NULL;
}
- result = Py_BuildValue("O(O)", Py_TYPE(self), str);
+ result = PFUNC(Py_BuildValue("O(O)", Py_TYPE(self), str));
Py_DECREF(str);
return result;
@@ -4748,17 +4868,17 @@
PyObject *f;
double x;
- if ((f = PyDec_AsFloat(self)) == NULL) {
+ if ((f = PFUNC(PyDec_AsFloat(self))) == NULL) {
return NULL;
}
- x = PyFloat_AsDouble(f);
+ x = IFUNC(PyFloat_AsDouble(f));
Py_DECREF(f);
if (PyErr_Occurred()) {
return NULL;
}
- return PyComplex_FromDoubles(x, 0);
+ return PFUNC(PyComplex_FromDoubles(x, 0));
}
static PyObject *
@@ -5055,7 +5175,7 @@
PyObject *result; \
uint32_t status = 0; \
\
- if (!PyArg_ParseTuple(args, "OO", &v, &w)) { \
+ if (!FFUNC(0, PyArg_ParseTuple(args, "OO", &v, &w))) { \
return NULL; \
} \
\
@@ -5090,7 +5210,7 @@
PyObject *a, *b; \
PyObject *result; \
\
- if (!PyArg_ParseTuple(args, "OO", &v, &w)) { \
+ if (!FFUNC(0, PyArg_ParseTuple(args, "OO", &v, &w))) { \
return NULL; \
} \
\
@@ -5119,7 +5239,7 @@
PyObject *result; \
uint32_t status = 0; \
\
- if (!PyArg_ParseTuple(args, "OOO", &v, &w, &x)) { \
+ if (!FFUNC(0, PyArg_ParseTuple(args, "OOO", &v, &w, &x))) { \
return NULL; \
} \
\
@@ -5212,7 +5332,7 @@
return NULL;
}
- mpd_qcopy_abs(MPD(result), MPD(a), &status);
+ SFUNC(mpd_qcopy_abs, MPD(result), MPD(a), &status);
Py_DECREF(a);
if (dec_addstatus(context, status)) {
Py_DECREF(result);
@@ -5248,7 +5368,7 @@
return NULL;
}
- mpd_qcopy_negate(MPD(result), MPD(a), &status);
+ SFUNC(mpd_qcopy_negate, MPD(result), MPD(a), &status);
Py_DECREF(a);
if (dec_addstatus(context, status)) {
Py_DECREF(result);
@@ -5272,7 +5392,7 @@
PyObject *result;
uint32_t status = 0;
- if (!PyArg_ParseTuple(args, "OO", &v, &w)) {
+ if (!FFUNC(0, PyArg_ParseTuple(args, "OO", &v, &w))) {
return NULL;
}
@@ -5284,7 +5404,7 @@
return NULL;
}
- mpd_qcopy_sign(MPD(result), MPD(a), MPD(b), &status);
+ SFUNC(mpd_qcopy_sign, MPD(result), MPD(a), MPD(b), &status);
Py_DECREF(a);
Py_DECREF(b);
if (dec_addstatus(context, status)) {
@@ -5339,7 +5459,7 @@
cp = mpd_class(MPD(a), CTX(context));
Py_DECREF(a);
- return Py_BuildValue("s", cp);
+ return PFUNC(Py_BuildValue("s", cp));
}
static PyObject *
@@ -5351,7 +5471,7 @@
uint32_t status = 0;
PyObject *ret;
- if (!PyArg_ParseTuple(args, "OO", &v, &w)) {
+ if (!FFUNC(0, PyArg_ParseTuple(args, "OO", &v, &w))) {
return NULL;
}
@@ -5378,7 +5498,7 @@
return NULL;
}
- ret = Py_BuildValue("(OO)", q, r);
+ ret = PFUNC(Py_BuildValue("(OO)", q, r));
Py_DECREF(r);
Py_DECREF(q);
return ret;
@@ -5396,11 +5516,11 @@
s = mpd_to_sci(MPD(a), CtxCaps(context));
Py_DECREF(a);
if (s == NULL) {
- PyErr_NoMemory();
+ PyErr_SetString(FailAPIException, "failapi");
return NULL;
}
- result = PyString_FromString(s);
+ result = PFUNC(PyString_FromString(s));
mpd_free(s);
return result;
@@ -5418,11 +5538,11 @@
s = mpd_to_eng(MPD(a), CtxCaps(context));
Py_DECREF(a);
if (s == NULL) {
- PyErr_NoMemory();
+ PyErr_SetString(FailAPIException, "failapi");
return NULL;
}
- result = PyString_FromString(s);
+ result = PFUNC(PyString_FromString(s));
mpd_free(s);
return result;
@@ -5441,7 +5561,7 @@
PyObject *a, *b;
PyObject *result;
- if (!PyArg_ParseTuple(args, "OO", &v, &w)) {
+ if (!FFUNC(0, PyArg_ParseTuple(args, "OO", &v, &w))) {
return NULL;
}
@@ -5620,6 +5740,10 @@
{ "setcontext", (PyCFunction)PyDec_SetCurrentContext, METH_O, doc_setcontext},
{ "localcontext", (PyCFunction)ctxmanager_new, METH_VARARGS, doc_localcontext},
{ "IEEEContext", (PyCFunction)ieee_context, METH_O, doc_ieee_context},
+ { "getfailpoint", get_failpoint, METH_NOARGS, NULL},
+ { "getapicalls", get_apicalls, METH_NOARGS, NULL},
+ { "setfailpoint", set_failpoint, METH_O, NULL},
+ { "setapicalls", set_apicalls, METH_O, NULL},
{ NULL, NULL, 1, NULL }
};
@@ -5699,9 +5823,13 @@
/* Init libmpdec */
mpd_traphandler = dec_traphandler;
- mpd_mallocfunc = PyMem_Malloc;
+ mpd_mallocfunc = mpd_malloc_fail;
+ /* If dec->alloc is greater that the requested size,
+ mpd_realloc uses the old memory area if the actual
+ call to realloc fails. This makes it difficult to
+ generate failures reliably. */
mpd_reallocfunc = PyMem_Realloc;
- mpd_callocfunc = mpd_callocfunc_em;
+ mpd_callocfunc = mpd_calloc_fail;
mpd_free = PyMem_Free;
mpd_setminalloc(4);
@@ -5768,8 +5896,13 @@
ASSIGN_PTR(DecimalException, PyErr_NewException(
"cdecimal.DecimalException",
PyExc_ArithmeticError, NULL));
+ ASSIGN_PTR(FailAPIException, PyErr_NewException(
+ "decimal.FailAPIException",
+ PyExc_BaseException, NULL));
Py_INCREF(DecimalException);
CHECK_INT(PyModule_AddObject(m, "DecimalException", DecimalException));
+ Py_INCREF(FailAPIException);
+ CHECK_INT(PyModule_AddObject(m, "FailAPIException", FailAPIException));
/* Add exceptions that correspond to IEEE signals */
for (cm = signal_map; cm->name != NULL; cm++) {