blob: 22dc63be888b8d8fff6a6acf685807af04945ced [file] [log] [blame]
--- cdecimal3.c 2011-06-15 17:48:40.000000000 +0200
+++ cdecimal3_failapi.c 2011-06-15 17:48:33.000000000 +0200
@@ -142,6 +142,103 @@
/* 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;
+static Py_complex _cfail = {-1, -1};
+
+#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},
@@ -232,7 +329,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) \
@@ -241,7 +338,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) \
@@ -288,20 +385,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;
}
}
@@ -320,13 +417,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;
}
}
@@ -380,7 +477,7 @@
}
for (cm = signal_map; cm->name != NULL; cm++) {
- if ((b = PyDict_GetItemWithError(val, cm->dec_cond)) == NULL) {
+ if ((b = PFUNC(PyDict_GetItemWithError(val, cm->dec_cond))) == NULL) {
if (!PyErr_Occurred()) {
PyErr_SetString(PyExc_TypeError,
"invalid signal dict.");
@@ -388,7 +485,7 @@
return UINT32_MAX;
}
- if ((x = PyObject_IsTrue(b)) < 0) {
+ if ((x = IFUNC(PyObject_IsTrue(b))) < 0) {
return UINT32_MAX;
}
if (x == 1) {
@@ -404,7 +501,7 @@
{
long x;
- x = PyLong_AsLong(v);
+ x = IFUNC(PyLong_AsLong(v));
if (PyErr_Occurred()) {
return UINT32_MAX;
}
@@ -427,7 +524,7 @@
return MPD_SSIZE_MAX;
}
- x = _PyLong_AsMpdSsize(v);
+ x = IFUNC(_PyLong_AsMpdSsize(v));
if (PyErr_Occurred()) {
return MPD_SSIZE_MAX;
}
@@ -440,6 +537,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;
@@ -468,7 +571,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;
}
@@ -488,7 +591,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;
}
}
@@ -504,7 +607,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;
}
}
@@ -521,19 +624,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;
@@ -546,7 +649,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 PyObject *
@@ -562,7 +665,7 @@
return NULL;
}
}
- return PyDict_Type.tp_richcompare(a, b, op);
+ return PFUNC(PyDict_Type.tp_richcompare(a, b, op));
}
static int
@@ -571,7 +674,7 @@
if (signaldict_update(self) < 0) {
return -1;
}
- return PyDict_Contains(self, key);
+ return IFUNC(PyDict_Contains(self, key));
}
static PyObject *
@@ -580,25 +683,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 *
@@ -608,8 +711,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 *
@@ -618,7 +721,7 @@
if (signaldict_update(self) < 0) {
return NULL;
}
- return PyDict_Items(self);
+ return PFUNC(PyDict_Items(self));
}
static PyObject *
@@ -627,7 +730,7 @@
if (signaldict_update(self) < 0) {
return NULL;
}
- return PyDict_Type.tp_iter(self);
+ return PFUNC(PyDict_Type.tp_iter(self));
}
static PyObject *
@@ -636,7 +739,7 @@
if (signaldict_update(self) < 0) {
return NULL;
}
- return PyDict_Keys(self);
+ return PFUNC(PyDict_Keys(self));
}
static Py_ssize_t
@@ -645,7 +748,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
@@ -663,7 +766,7 @@
if (signaldict_update(self) < 0) {
return NULL;
}
- return PyDict_Type.tp_repr(self);
+ return PFUNC(PyDict_Type.tp_repr(self));
}
static PyObject *
@@ -689,7 +792,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 *
@@ -698,7 +801,7 @@
if (signaldict_update(self) < 0) {
return NULL;
}
- return PyDict_Values(self);
+ return PFUNC(PyDict_Values(self));
}
@@ -785,7 +888,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 *
@@ -794,7 +897,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 *
@@ -803,7 +906,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 *
@@ -812,7 +915,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 *
@@ -821,7 +924,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 *
@@ -830,13 +933,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 *
@@ -845,7 +948,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 *
@@ -854,7 +957,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 *
@@ -863,7 +966,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 *
@@ -872,7 +975,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
@@ -1032,7 +1135,7 @@
}
ctx = CTX(self);
- if (!mpd_qsettraps(ctx, flags)) {
+ if (!FFUNC_NOEX(0, mpd_qsettraps(ctx, flags))) {
INTERNAL_ERROR_INT("context_settraps");
}
@@ -1051,7 +1154,7 @@
}
ctx = CTX(self);
- if (!mpd_qsettraps(ctx, flags)) {
+ if (!FFUNC_NOEX(0, mpd_qsettraps(ctx, flags))) {
INTERNAL_ERROR_INT("context_settraps_list");
}
@@ -1070,7 +1173,7 @@
}
ctx = CTX(self);
- if (!mpd_qsettraps(ctx, flags)) {
+ if (!FFUNC_NOEX(0, mpd_qsettraps(ctx, flags))) {
INTERNAL_ERROR_INT("context_settraps_dict");
}
@@ -1089,7 +1192,7 @@
}
ctx = CTX(self);
- if (!mpd_qsetstatus(ctx, flags)) {
+ if (!FFUNC_NOEX(0, mpd_qsetstatus(ctx, flags))) {
INTERNAL_ERROR_INT("context_setstatus");
}
@@ -1108,7 +1211,7 @@
}
ctx = CTX(self);
- if (!mpd_qsetstatus(ctx, flags)) {
+ if (!FFUNC_NOEX(0, mpd_qsetstatus(ctx, flags))) {
INTERNAL_ERROR_INT("context_setstatus_list");
}
@@ -1127,7 +1230,7 @@
}
ctx = CTX(self);
- if (!mpd_qsetstatus(ctx, flags)) {
+ if (!FFUNC_NOEX(0, mpd_qsetstatus(ctx, flags))) {
INTERNAL_ERROR_INT("context_setstatus_dict");
}
@@ -1256,18 +1359,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;
@@ -1310,7 +1413,7 @@
int i;
if (PyLong_Check(v)) {
- x = PyLong_AsLong(v);
+ x = IFUNC(PyLong_AsLong(v));
if (PyErr_Occurred()) {
return -1;
}
@@ -1349,13 +1452,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) {
@@ -1427,32 +1530,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 PyUnicode_FromString(s);
+ return PFUNC(PyUnicode_FromString(s));
error:
INTERNAL_ERROR_PTR("context_repr");
@@ -1502,7 +1605,7 @@
goto error;
}
- context = PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL);
+ context = PFUNC(PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL));
if (context == NULL) {
return NULL;
}
@@ -1523,7 +1626,7 @@
{
PyObject *copy;
- copy = PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL);
+ copy = PFUNC(PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL));
if (copy == NULL) {
return NULL;
}
@@ -1553,13 +1656,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);
@@ -1698,14 +1801,14 @@
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;
}
- tl_context = PyDict_GetItemWithError(dict, tls_context_key);
+ tl_context = PFUNC(PyDict_GetItemWithError(dict, tls_context_key));
if (tl_context != NULL) {
/* We already have a thread local context and
* return a borrowed reference. */
@@ -1721,7 +1824,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;
}
@@ -1768,9 +1871,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;
}
@@ -1788,7 +1891,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;
}
@@ -1810,13 +1913,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;
}
@@ -1864,6 +1967,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);
@@ -1921,10 +2037,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;
@@ -1933,7 +2049,7 @@
MPD(dec) = mpd_qnew();
if (MPD(dec) == NULL) {
Py_DECREF(dec);
- PyErr_NoMemory();
+ PyErr_SetString(FailAPIException, "failapi");
return NULL;
}
@@ -2015,14 +2131,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;
}
@@ -2050,8 +2166,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);
@@ -2143,7 +2259,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;
@@ -2166,7 +2282,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;
@@ -2303,7 +2419,7 @@
return NULL;
}
- x = PyFloat_AsDouble(v);
+ x = IFUNC(PyFloat_AsDouble(v));
if (x == -1.0 && PyErr_Occurred()) {
return NULL;
}
@@ -2326,13 +2442,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;
@@ -2340,7 +2456,7 @@
n = PyTuple_GET_ITEM(n_d, 0);
d = PyTuple_GET_ITEM(n_d, 1);
- tmp = PyObject_CallMethod(d, "bit_length", NULL);
+ tmp = PFUNC(PyObject_CallMethod(d, "bit_length", NULL));
if (tmp == NULL) {
Py_DECREF(n_d);
return NULL;
@@ -2362,14 +2478,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;
}
@@ -2448,7 +2564,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;
}
@@ -2504,15 +2620,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;
}
@@ -2529,7 +2645,7 @@
"coefficient must be a tuple of digits.");
goto error;
}
- l = PyLong_AsLong(tmp);
+ l = IFUNC(PyLong_AsLong(tmp));
if (PyErr_Occurred()) {
goto error;
}
@@ -2545,9 +2661,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;
}
@@ -2688,13 +2804,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;
@@ -2799,7 +2915,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);
@@ -2812,7 +2928,7 @@
{
PyObject *v = NULL;
- if (!PyArg_ParseTuple(args, "|O", &v)) {
+ if (!FFUNC(0, PyArg_ParseTuple(args, "|O", &v))) {
return NULL;
}
@@ -2936,7 +3052,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;
}
@@ -2949,7 +3065,7 @@
vv = mpd_qncopy(MPD(v));
if (vv == NULL) {
Py_DECREF(denom);
- PyErr_NoMemory();
+ PyErr_SetString(FailAPIException, "failapi");
return NULL;
}
result = dec_alloc();
@@ -2989,7 +3105,7 @@
{
PyObject *tmp, *num;
- tmp = PyObject_GetAttrString(r, "numerator");
+ tmp = PFUNC(PyObject_GetAttrString(r, "numerator"));
if (tmp == NULL) {
return NULL;
}
@@ -3037,12 +3153,12 @@
}
#if PY_VERSION_HEX >= 0x03020000
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;
}
@@ -3102,11 +3218,11 @@
CURRENT_CONTEXT(c);
res = mpd_to_sci(MPD(dec), CtxCaps(c));
if (res == NULL) {
- PyErr_NoMemory();
+ PyErr_SetString(FailAPIException, "failapi");
return NULL;
}
- s = PyUnicode_FromString(res);
+ s = PFUNC(PyUnicode_FromString(res));
mpd_free(res);
return s;
@@ -3127,16 +3243,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;
}
@@ -3146,7 +3264,7 @@
cp[declen+dtaglen+1] = ')';
cp[declen+dtaglen+2] = '\0';
- s = PyUnicode_FromString(cp);
+ s = PFUNC(PyUnicode_FromString(cp));
mpd_free(cp);
return s;
@@ -3173,12 +3291,12 @@
CURRENT_CONTEXT(context);
- if (!PyArg_ParseTuple(args, "O|O", &fmtarg, &override)) {
+ if (!FFUNC(0, PyArg_ParseTuple(args, "O|O", &fmtarg, &override))) {
return NULL;
}
if (PyUnicode_Check(fmtarg)) {
- if ((fmt = PyUnicode_AsUTF8String(fmtarg)) == NULL) {
+ if ((fmt = PFUNC(PyUnicode_AsUTF8String(fmtarg))) == NULL) {
return NULL;
}
}
@@ -3201,19 +3319,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);
@@ -3222,17 +3340,17 @@
else {
n = strlen(spec.dot);
if (n > 1 || (n == 1 && !isascii((uchar)spec.dot[0]))) {
- n = mbstowcs(buf, spec.dot, 2);
+ n = FFUNC_NOEX((size_t)-1, mbstowcs(buf, spec.dot, 2));
if (n != 1) {
- PyErr_SetString(PyExc_ValueError,
+ PyErr_SetString(FailAPIException,
"invalid decimal point or unsupported "
"combination of LC_CTYPE and LC_NUMERIC.");
goto finish;
}
- if ((tmp = PyUnicode_FromWideChar(buf, n)) == NULL) {
+ if ((tmp = PFUNC(PyUnicode_FromWideChar(buf, n))) == NULL) {
goto finish;
}
- if ((dot = PyUnicode_AsUTF8String(tmp)) == NULL) {
+ if ((dot = PFUNC(PyUnicode_AsUTF8String(tmp))) == NULL) {
Py_DECREF(tmp);
goto finish;
}
@@ -3241,17 +3359,17 @@
}
n = strlen(spec.sep);
if (n > 1 || (n == 1 && !isascii((uchar)spec.sep[0]))) {
- n = mbstowcs(buf, spec.sep, 2);
+ n = FFUNC_NOEX((size_t)-1, mbstowcs(buf, spec.sep, 2));
if (n != 1) {
- PyErr_SetString(PyExc_ValueError,
+ PyErr_SetString(FailAPIException,
"invalid thousands separator or unsupported "
"combination of LC_CTYPE and LC_NUMERIC.");
goto finish;
}
- if ((tmp = PyUnicode_FromWideChar(buf, n)) == NULL) {
+ if ((tmp = PFUNC(PyUnicode_FromWideChar(buf, n))) == NULL) {
goto finish;
}
- if ((sep = PyUnicode_AsUTF8String(tmp)) == NULL) {
+ if ((sep = PFUNC(PyUnicode_AsUTF8String(tmp))) == NULL) {
Py_DECREF(tmp);
goto finish;
}
@@ -3266,7 +3384,7 @@
dec_addstatus(context, status);
goto finish;
}
- result = PyUnicode_DecodeUTF8(decstring, strlen(decstring), NULL);
+ result = PFUNC(PyUnicode_DecodeUTF8(decstring, strlen(decstring), NULL));
finish:
@@ -3303,24 +3421,24 @@
}
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;
}
- 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;
}
@@ -3364,8 +3482,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);
@@ -3381,7 +3499,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;
@@ -3401,8 +3519,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);
@@ -3452,7 +3570,7 @@
CURRENT_CONTEXT(context);
- if (!PyArg_ParseTuple(args, "|O", &x)) {
+ if (!FFUNC(0, PyArg_ParseTuple(args, "|O", &x))) {
return NULL;
}
@@ -3505,28 +3623,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;
@@ -3539,30 +3657,30 @@
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;
}
}
}
- result = PyObject_CallFunctionObjArgs(DecimalTuple,
- sign, coeff, expt, NULL);
+ result = PFUNC(PyObject_CallFunctionObjArgs(DecimalTuple,
+ sign, coeff, expt, NULL));
out:
if (x) mpd_del(x);
@@ -3647,7 +3765,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); \
@@ -3666,7 +3784,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); \
@@ -3695,7 +3813,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); \
@@ -3729,7 +3847,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); \
@@ -3759,7 +3877,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); \
@@ -3848,7 +3966,7 @@
return NULL;
}
- ret = Py_BuildValue("(OO)", q, r);
+ ret = PFUNC(Py_BuildValue("(OO)", q, r));
Py_DECREF(r);
Py_DECREF(q);
return ret;
@@ -3963,7 +4081,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
@@ -3974,7 +4092,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);
@@ -3994,7 +4112,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;
@@ -4015,7 +4133,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;
@@ -4047,7 +4165,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)) {
@@ -4073,13 +4191,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 *
@@ -4106,7 +4224,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);
@@ -4133,7 +4251,7 @@
return NULL;
}
- ret = Py_BuildValue("(OO)", q, r);
+ ret = PFUNC(Py_BuildValue("(OO)", q, r));
Py_DECREF(r);
Py_DECREF(q);
return ret;
@@ -4151,8 +4269,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);
@@ -4204,7 +4322,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);
@@ -4221,7 +4339,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 *
@@ -4232,18 +4350,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 = PyUnicode_FromString(s);
+ result = PFUNC(PyUnicode_FromString(s));
mpd_free(s);
return result;
@@ -4257,18 +4375,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 = PyUnicode_FromString(s);
+ result = PFUNC(PyUnicode_FromString(s));
mpd_free(s);
return result;
@@ -4359,11 +4477,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;
}
@@ -4393,8 +4511,8 @@
}
mpd_maxcontext(&maxcontext);
- if ((tmp = mpd_qnew()) == NULL) {
- PyErr_NoMemory();
+ if ((tmp = PFUNC_NOEX(mpd_qnew())) == NULL) {
+ PyErr_SetString(FailAPIException, "failapi");
result = -1;
goto finish;
}
@@ -4404,7 +4522,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)) {
@@ -4436,12 +4554,12 @@
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;
@@ -4539,7 +4657,7 @@
}
/* hash = (int(v) * exp_hash) % p */
- if (!mpd_qcopy(tmp, MPD(v), &status)) {
+ if (!FFUNC_NOEX(0, mpd_qcopy(tmp, MPD(v), &status))) {
goto malloc_error;
}
tmp->exp = 0;
@@ -4566,7 +4684,7 @@
return result;
malloc_error:
- PyErr_NoMemory();
+ PyErr_SetString(FailAPIException, "failapi");
result = -1;
goto finish;
}
@@ -4581,7 +4699,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;
@@ -4620,17 +4738,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 *
@@ -4918,7 +5036,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; \
} \
\
@@ -4953,7 +5071,7 @@
PyObject *a, *b; \
PyObject *result; \
\
- if (!PyArg_ParseTuple(args, "OO", &v, &w)) { \
+ if (!FFUNC(0, PyArg_ParseTuple(args, "OO", &v, &w))) { \
return NULL; \
} \
\
@@ -4982,7 +5100,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; \
} \
\
@@ -5075,7 +5193,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);
@@ -5111,7 +5229,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);
@@ -5135,7 +5253,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;
}
@@ -5147,7 +5265,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)) {
@@ -5202,7 +5320,7 @@
cp = mpd_class(MPD(a), CTX(context));
Py_DECREF(a);
- return Py_BuildValue("s", cp);
+ return PFUNC(Py_BuildValue("s", cp));
}
static PyObject *
@@ -5214,7 +5332,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;
}
@@ -5241,7 +5359,7 @@
return NULL;
}
- ret = Py_BuildValue("(OO)", q, r);
+ ret = PFUNC(Py_BuildValue("(OO)", q, r));
Py_DECREF(r);
Py_DECREF(q);
return ret;
@@ -5259,11 +5377,11 @@
s = mpd_to_sci(MPD(a), CtxCaps(context));
Py_DECREF(a);
if (s == NULL) {
- PyErr_NoMemory();
+ PyErr_SetString(FailAPIException, "failapi");
return NULL;
}
- result = PyUnicode_FromString(s);
+ result = PFUNC(PyUnicode_FromString(s));
mpd_free(s);
return result;
@@ -5281,11 +5399,11 @@
s = mpd_to_eng(MPD(a), CtxCaps(context));
Py_DECREF(a);
if (s == NULL) {
- PyErr_NoMemory();
+ PyErr_SetString(FailAPIException, "failapi");
return NULL;
}
- result = PyUnicode_FromString(s);
+ result = PFUNC(PyUnicode_FromString(s));
mpd_free(s);
return result;
@@ -5304,7 +5422,7 @@
PyObject *a, *b;
PyObject *result;
- if (!PyArg_ParseTuple(args, "OO", &v, &w)) {
+ if (!FFUNC(0, PyArg_ParseTuple(args, "OO", &v, &w))) {
return NULL;
}
@@ -5482,6 +5600,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 }
};
@@ -5571,9 +5693,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);
@@ -5636,8 +5762,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++) {