1 /*
2  * Copyright (c) 2008-2012 Stefan Krah. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 
29 #include <Python.h>
30 #include "longintrepr.h"
31 #include "pythread.h"
32 #include "structmember.h"
33 #include "complexobject.h"
34 #include "mpdecimal.h"
35 
36 #include <stdlib.h>
37 
38 #include "docstrings.h"
39 
40 
41 #if !defined(MPD_VERSION_HEX) || MPD_VERSION_HEX < 0x02040100
42   #error "libmpdec version >= 2.4.1 required"
43 #endif
44 
45 
46 /*
47  * Type sizes with assertions in mpdecimal.h and pyport.h:
48  *    sizeof(size_t) == sizeof(Py_ssize_t)
49  *    sizeof(size_t) == sizeof(mpd_uint_t) == sizeof(mpd_ssize_t)
50  */
51 
52 #ifdef TEST_COVERAGE
53   #undef Py_LOCAL_INLINE
54   #define Py_LOCAL_INLINE Py_LOCAL
55 #endif
56 
57 #define MPD_Float_operation MPD_Not_implemented
58 
59 #define BOUNDS_CHECK(x, MIN, MAX) x = (x < MIN || MAX < x) ? MAX : x
60 
61 #if defined(__GNUC__) && !defined(__INTEL_COMPILER)
62   #define UNUSED __attribute__((unused))
63 #else
64   #define UNUSED
65 #endif
66 
67 /* _Py_DEC_MINALLOC >= MPD_MINALLOC */
68 #define _Py_DEC_MINALLOC 4
69 
70 typedef struct {
71     PyObject_HEAD
72     Py_hash_t hash;
73     mpd_t dec;
74     mpd_uint_t data[_Py_DEC_MINALLOC];
75 } PyDecObject;
76 
77 typedef struct {
78     PyObject_HEAD
79     uint32_t *flags;
80 } PyDecSignalDictObject;
81 
82 typedef struct {
83     PyObject_HEAD
84     mpd_context_t ctx;
85     PyObject *traps;
86     PyObject *flags;
87     int capitals;
88     PyThreadState *tstate;
89 } PyDecContextObject;
90 
91 typedef struct {
92     PyObject_HEAD
93     PyObject *local;
94     PyObject *global;
95 } PyDecContextManagerObject;
96 
97 
98 #undef MPD
99 #undef CTX
100 static PyTypeObject PyDec_Type;
101 static PyTypeObject *PyDecSignalDict_Type;
102 static PyTypeObject PyDecContext_Type;
103 static PyTypeObject PyDecContextManager_Type;
104 #define PyDec_CheckExact(v) (Py_TYPE(v) == &PyDec_Type)
105 #define PyDec_Check(v) PyObject_TypeCheck(v, &PyDec_Type)
106 #define PyDecSignalDict_Check(v) (Py_TYPE(v) == PyDecSignalDict_Type)
107 #define PyDecContext_Check(v) PyObject_TypeCheck(v, &PyDecContext_Type)
108 #define MPD(v) (&((PyDecObject *)v)->dec)
109 #define SdFlagAddr(v) (((PyDecSignalDictObject *)v)->flags)
110 #define SdFlags(v) (*((PyDecSignalDictObject *)v)->flags)
111 #define CTX(v) (&((PyDecContextObject *)v)->ctx)
112 #define CtxCaps(v) (((PyDecContextObject *)v)->capitals)
113 
114 
115 Py_LOCAL_INLINE(PyObject *)
incr_true(void)116 incr_true(void)
117 {
118     Py_INCREF(Py_True);
119     return Py_True;
120 }
121 
122 Py_LOCAL_INLINE(PyObject *)
incr_false(void)123 incr_false(void)
124 {
125     Py_INCREF(Py_False);
126     return Py_False;
127 }
128 
129 
130 #ifndef WITH_DECIMAL_CONTEXTVAR
131 /* Key for thread state dictionary */
132 static PyObject *tls_context_key = NULL;
133 /* Invariant: NULL or the most recently accessed thread local context */
134 static PyDecContextObject *cached_context = NULL;
135 #else
136 static PyObject *current_context_var = NULL;
137 #endif
138 
139 /* Template for creating new thread contexts, calling Context() without
140  * arguments and initializing the module_context on first access. */
141 static PyObject *default_context_template = NULL;
142 /* Basic and extended context templates */
143 static PyObject *basic_context_template = NULL;
144 static PyObject *extended_context_template = NULL;
145 
146 
147 /* Error codes for functions that return signals or conditions */
148 #define DEC_INVALID_SIGNALS (MPD_Max_status+1U)
149 #define DEC_ERR_OCCURRED (DEC_INVALID_SIGNALS<<1)
150 #define DEC_ERRORS (DEC_INVALID_SIGNALS|DEC_ERR_OCCURRED)
151 
152 typedef struct {
153     const char *name;   /* condition or signal name */
154     const char *fqname; /* fully qualified name */
155     uint32_t flag;      /* libmpdec flag */
156     PyObject *ex;       /* corresponding exception */
157 } DecCondMap;
158 
159 /* Top level Exception; inherits from ArithmeticError */
160 static PyObject *DecimalException = NULL;
161 
162 /* Exceptions that correspond to IEEE signals */
163 #define SUBNORMAL 5
164 #define INEXACT 6
165 #define ROUNDED 7
166 #define SIGNAL_MAP_LEN 9
167 static DecCondMap signal_map[] = {
168   {"InvalidOperation", "decimal.InvalidOperation", MPD_IEEE_Invalid_operation, NULL},
169   {"FloatOperation", "decimal.FloatOperation", MPD_Float_operation, NULL},
170   {"DivisionByZero", "decimal.DivisionByZero", MPD_Division_by_zero, NULL},
171   {"Overflow", "decimal.Overflow", MPD_Overflow, NULL},
172   {"Underflow", "decimal.Underflow", MPD_Underflow, NULL},
173   {"Subnormal", "decimal.Subnormal", MPD_Subnormal, NULL},
174   {"Inexact", "decimal.Inexact", MPD_Inexact, NULL},
175   {"Rounded", "decimal.Rounded", MPD_Rounded, NULL},
176   {"Clamped", "decimal.Clamped", MPD_Clamped, NULL},
177   {NULL}
178 };
179 
180 /* Exceptions that inherit from InvalidOperation */
181 static DecCondMap cond_map[] = {
182   {"InvalidOperation", "decimal.InvalidOperation", MPD_Invalid_operation, NULL},
183   {"ConversionSyntax", "decimal.ConversionSyntax", MPD_Conversion_syntax, NULL},
184   {"DivisionImpossible", "decimal.DivisionImpossible", MPD_Division_impossible, NULL},
185   {"DivisionUndefined", "decimal.DivisionUndefined", MPD_Division_undefined, NULL},
186   {"InvalidContext", "decimal.InvalidContext", MPD_Invalid_context, NULL},
187 #ifdef EXTRA_FUNCTIONALITY
188   {"MallocError", "decimal.MallocError", MPD_Malloc_error, NULL},
189 #endif
190   {NULL}
191 };
192 
193 static const char *dec_signal_string[MPD_NUM_FLAGS] = {
194     "Clamped",
195     "InvalidOperation",
196     "DivisionByZero",
197     "InvalidOperation",
198     "InvalidOperation",
199     "InvalidOperation",
200     "Inexact",
201     "InvalidOperation",
202     "InvalidOperation",
203     "InvalidOperation",
204     "FloatOperation",
205     "Overflow",
206     "Rounded",
207     "Subnormal",
208     "Underflow",
209 };
210 
211 #ifdef EXTRA_FUNCTIONALITY
212   #define _PY_DEC_ROUND_GUARD MPD_ROUND_GUARD
213 #else
214   #define _PY_DEC_ROUND_GUARD (MPD_ROUND_GUARD-1)
215 #endif
216 static PyObject *round_map[_PY_DEC_ROUND_GUARD];
217 
218 static const char *invalid_rounding_err =
219 "valid values for rounding are:\n\
220   [ROUND_CEILING, ROUND_FLOOR, ROUND_UP, ROUND_DOWN,\n\
221    ROUND_HALF_UP, ROUND_HALF_DOWN, ROUND_HALF_EVEN,\n\
222    ROUND_05UP]";
223 
224 static const char *invalid_signals_err =
225 "valid values for signals are:\n\
226   [InvalidOperation, FloatOperation, DivisionByZero,\n\
227    Overflow, Underflow, Subnormal, Inexact, Rounded,\n\
228    Clamped]";
229 
230 #ifdef EXTRA_FUNCTIONALITY
231 static const char *invalid_flags_err =
232 "valid values for _flags or _traps are:\n\
233   signals:\n\
234     [DecIEEEInvalidOperation, DecFloatOperation, DecDivisionByZero,\n\
235      DecOverflow, DecUnderflow, DecSubnormal, DecInexact, DecRounded,\n\
236      DecClamped]\n\
237   conditions which trigger DecIEEEInvalidOperation:\n\
238     [DecInvalidOperation, DecConversionSyntax, DecDivisionImpossible,\n\
239      DecDivisionUndefined, DecFpuError, DecInvalidContext, DecMallocError]";
240 #endif
241 
242 static int
value_error_int(const char * mesg)243 value_error_int(const char *mesg)
244 {
245     PyErr_SetString(PyExc_ValueError, mesg);
246     return -1;
247 }
248 
249 #ifdef CONFIG_32
250 static PyObject *
value_error_ptr(const char * mesg)251 value_error_ptr(const char *mesg)
252 {
253     PyErr_SetString(PyExc_ValueError, mesg);
254     return NULL;
255 }
256 #endif
257 
258 static int
type_error_int(const char * mesg)259 type_error_int(const char *mesg)
260 {
261     PyErr_SetString(PyExc_TypeError, mesg);
262     return -1;
263 }
264 
265 static int
runtime_error_int(const char * mesg)266 runtime_error_int(const char *mesg)
267 {
268     PyErr_SetString(PyExc_RuntimeError, mesg);
269     return -1;
270 }
271 #define INTERNAL_ERROR_INT(funcname) \
272     return runtime_error_int("internal error in " funcname)
273 
274 static PyObject *
runtime_error_ptr(const char * mesg)275 runtime_error_ptr(const char *mesg)
276 {
277     PyErr_SetString(PyExc_RuntimeError, mesg);
278     return NULL;
279 }
280 #define INTERNAL_ERROR_PTR(funcname) \
281     return runtime_error_ptr("internal error in " funcname)
282 
283 static void
dec_traphandler(mpd_context_t * ctx UNUSED)284 dec_traphandler(mpd_context_t *ctx UNUSED) /* GCOV_NOT_REACHED */
285 { /* GCOV_NOT_REACHED */
286     return; /* GCOV_NOT_REACHED */
287 }
288 
289 static PyObject *
flags_as_exception(uint32_t flags)290 flags_as_exception(uint32_t flags)
291 {
292     DecCondMap *cm;
293 
294     for (cm = signal_map; cm->name != NULL; cm++) {
295         if (flags&cm->flag) {
296             return cm->ex;
297         }
298     }
299 
300     INTERNAL_ERROR_PTR("flags_as_exception"); /* GCOV_NOT_REACHED */
301 }
302 
303 Py_LOCAL_INLINE(uint32_t)
exception_as_flag(PyObject * ex)304 exception_as_flag(PyObject *ex)
305 {
306     DecCondMap *cm;
307 
308     for (cm = signal_map; cm->name != NULL; cm++) {
309         if (cm->ex == ex) {
310             return cm->flag;
311         }
312     }
313 
314     PyErr_SetString(PyExc_KeyError, invalid_signals_err);
315     return DEC_INVALID_SIGNALS;
316 }
317 
318 static PyObject *
flags_as_list(uint32_t flags)319 flags_as_list(uint32_t flags)
320 {
321     PyObject *list;
322     DecCondMap *cm;
323 
324     list = PyList_New(0);
325     if (list == NULL) {
326         return NULL;
327     }
328 
329     for (cm = cond_map; cm->name != NULL; cm++) {
330         if (flags&cm->flag) {
331             if (PyList_Append(list, cm->ex) < 0) {
332                 goto error;
333             }
334         }
335     }
336     for (cm = signal_map+1; cm->name != NULL; cm++) {
337         if (flags&cm->flag) {
338             if (PyList_Append(list, cm->ex) < 0) {
339                 goto error;
340             }
341         }
342     }
343 
344     return list;
345 
346 error:
347     Py_DECREF(list);
348     return NULL;
349 }
350 
351 static PyObject *
signals_as_list(uint32_t flags)352 signals_as_list(uint32_t flags)
353 {
354     PyObject *list;
355     DecCondMap *cm;
356 
357     list = PyList_New(0);
358     if (list == NULL) {
359         return NULL;
360     }
361 
362     for (cm = signal_map; cm->name != NULL; cm++) {
363         if (flags&cm->flag) {
364             if (PyList_Append(list, cm->ex) < 0) {
365                 Py_DECREF(list);
366                 return NULL;
367             }
368         }
369     }
370 
371     return list;
372 }
373 
374 static uint32_t
list_as_flags(PyObject * list)375 list_as_flags(PyObject *list)
376 {
377     PyObject *item;
378     uint32_t flags, x;
379     Py_ssize_t n, j;
380 
381     assert(PyList_Check(list));
382 
383     n = PyList_Size(list);
384     flags = 0;
385     for (j = 0; j < n; j++) {
386         item = PyList_GetItem(list, j);
387         x = exception_as_flag(item);
388         if (x & DEC_ERRORS) {
389             return x;
390         }
391         flags |= x;
392     }
393 
394     return flags;
395 }
396 
397 static PyObject *
flags_as_dict(uint32_t flags)398 flags_as_dict(uint32_t flags)
399 {
400     DecCondMap *cm;
401     PyObject *dict;
402 
403     dict = PyDict_New();
404     if (dict == NULL) {
405         return NULL;
406     }
407 
408     for (cm = signal_map; cm->name != NULL; cm++) {
409         PyObject *b = flags&cm->flag ? Py_True : Py_False;
410         if (PyDict_SetItem(dict, cm->ex, b) < 0) {
411             Py_DECREF(dict);
412             return NULL;
413         }
414     }
415 
416     return dict;
417 }
418 
419 static uint32_t
dict_as_flags(PyObject * val)420 dict_as_flags(PyObject *val)
421 {
422     PyObject *b;
423     DecCondMap *cm;
424     uint32_t flags = 0;
425     int x;
426 
427     if (!PyDict_Check(val)) {
428         PyErr_SetString(PyExc_TypeError,
429             "argument must be a signal dict");
430         return DEC_INVALID_SIGNALS;
431     }
432 
433     if (PyDict_Size(val) != SIGNAL_MAP_LEN) {
434         PyErr_SetString(PyExc_KeyError,
435             "invalid signal dict");
436         return DEC_INVALID_SIGNALS;
437     }
438 
439     for (cm = signal_map; cm->name != NULL; cm++) {
440         b = PyDict_GetItemWithError(val, cm->ex);
441         if (b == NULL) {
442             if (PyErr_Occurred()) {
443                 return DEC_ERR_OCCURRED;
444             }
445             PyErr_SetString(PyExc_KeyError,
446                 "invalid signal dict");
447             return DEC_INVALID_SIGNALS;
448         }
449 
450         x = PyObject_IsTrue(b);
451         if (x < 0) {
452             return DEC_ERR_OCCURRED;
453         }
454         if (x == 1) {
455             flags |= cm->flag;
456         }
457     }
458 
459     return flags;
460 }
461 
462 #ifdef EXTRA_FUNCTIONALITY
463 static uint32_t
long_as_flags(PyObject * v)464 long_as_flags(PyObject *v)
465 {
466     long x;
467 
468     x = PyLong_AsLong(v);
469     if (x == -1 && PyErr_Occurred()) {
470         return DEC_ERR_OCCURRED;
471     }
472     if (x < 0 || x > (long)MPD_Max_status) {
473         PyErr_SetString(PyExc_TypeError, invalid_flags_err);
474         return DEC_INVALID_SIGNALS;
475     }
476 
477     return x;
478 }
479 #endif
480 
481 static int
dec_addstatus(PyObject * context,uint32_t status)482 dec_addstatus(PyObject *context, uint32_t status)
483 {
484     mpd_context_t *ctx = CTX(context);
485 
486     ctx->status |= status;
487     if (status & (ctx->traps|MPD_Malloc_error)) {
488         PyObject *ex, *siglist;
489 
490         if (status & MPD_Malloc_error) {
491             PyErr_NoMemory();
492             return 1;
493         }
494 
495         ex = flags_as_exception(ctx->traps&status);
496         if (ex == NULL) {
497             return 1; /* GCOV_NOT_REACHED */
498         }
499         siglist = flags_as_list(ctx->traps&status);
500         if (siglist == NULL) {
501             return 1;
502         }
503 
504         PyErr_SetObject(ex, siglist);
505         Py_DECREF(siglist);
506         return 1;
507     }
508     return 0;
509 }
510 
511 static int
getround(PyObject * v)512 getround(PyObject *v)
513 {
514     int i;
515 
516     if (PyUnicode_Check(v)) {
517         for (i = 0; i < _PY_DEC_ROUND_GUARD; i++) {
518             if (v == round_map[i]) {
519                 return i;
520             }
521         }
522         for (i = 0; i < _PY_DEC_ROUND_GUARD; i++) {
523             if (PyUnicode_Compare(v, round_map[i]) == 0) {
524                 return i;
525             }
526         }
527     }
528 
529     return type_error_int(invalid_rounding_err);
530 }
531 
532 
533 /******************************************************************************/
534 /*                            SignalDict Object                               */
535 /******************************************************************************/
536 
537 /* The SignalDict is a MutableMapping that provides access to the
538    mpd_context_t flags, which reside in the context object. When a
539    new context is created, context.traps and context.flags are
540    initialized to new SignalDicts. Once a SignalDict is tied to
541    a context, it cannot be deleted. */
542 
543 static int
signaldict_init(PyObject * self,PyObject * args UNUSED,PyObject * kwds UNUSED)544 signaldict_init(PyObject *self, PyObject *args UNUSED, PyObject *kwds UNUSED)
545 {
546     SdFlagAddr(self) = NULL;
547     return 0;
548 }
549 
550 static Py_ssize_t
signaldict_len(PyObject * self UNUSED)551 signaldict_len(PyObject *self UNUSED)
552 {
553     return SIGNAL_MAP_LEN;
554 }
555 
556 static PyObject *SignalTuple;
557 static PyObject *
signaldict_iter(PyObject * self UNUSED)558 signaldict_iter(PyObject *self UNUSED)
559 {
560     return PyTuple_Type.tp_iter(SignalTuple);
561 }
562 
563 static PyObject *
signaldict_getitem(PyObject * self,PyObject * key)564 signaldict_getitem(PyObject *self, PyObject *key)
565 {
566     uint32_t flag;
567 
568     flag = exception_as_flag(key);
569     if (flag & DEC_ERRORS) {
570         return NULL;
571     }
572 
573     return SdFlags(self)&flag ? incr_true() : incr_false();
574 }
575 
576 static int
signaldict_setitem(PyObject * self,PyObject * key,PyObject * value)577 signaldict_setitem(PyObject *self, PyObject *key, PyObject *value)
578 {
579     uint32_t flag;
580     int x;
581 
582     if (value == NULL) {
583         return value_error_int("signal keys cannot be deleted");
584     }
585 
586     flag = exception_as_flag(key);
587     if (flag & DEC_ERRORS) {
588         return -1;
589     }
590 
591     x = PyObject_IsTrue(value);
592     if (x < 0) {
593         return -1;
594     }
595 
596     if (x == 1) {
597         SdFlags(self) |= flag;
598     }
599     else {
600         SdFlags(self) &= ~flag;
601     }
602 
603     return 0;
604 }
605 
606 static PyObject *
signaldict_repr(PyObject * self)607 signaldict_repr(PyObject *self)
608 {
609     DecCondMap *cm;
610     const char *n[SIGNAL_MAP_LEN]; /* name */
611     const char *b[SIGNAL_MAP_LEN]; /* bool */
612     int i;
613 
614     assert(SIGNAL_MAP_LEN == 9);
615 
616     for (cm=signal_map, i=0; cm->name != NULL; cm++, i++) {
617         n[i] = cm->fqname;
618         b[i] = SdFlags(self)&cm->flag ? "True" : "False";
619     }
620     return PyUnicode_FromFormat(
621         "{<class '%s'>:%s, <class '%s'>:%s, <class '%s'>:%s, "
622          "<class '%s'>:%s, <class '%s'>:%s, <class '%s'>:%s, "
623          "<class '%s'>:%s, <class '%s'>:%s, <class '%s'>:%s}",
624             n[0], b[0], n[1], b[1], n[2], b[2],
625             n[3], b[3], n[4], b[4], n[5], b[5],
626             n[6], b[6], n[7], b[7], n[8], b[8]);
627 }
628 
629 static PyObject *
signaldict_richcompare(PyObject * v,PyObject * w,int op)630 signaldict_richcompare(PyObject *v, PyObject *w, int op)
631 {
632     PyObject *res = Py_NotImplemented;
633 
634     assert(PyDecSignalDict_Check(v));
635 
636     if (op == Py_EQ || op == Py_NE) {
637         if (PyDecSignalDict_Check(w)) {
638             res = (SdFlags(v)==SdFlags(w)) ^ (op==Py_NE) ? Py_True : Py_False;
639         }
640         else if (PyDict_Check(w)) {
641             uint32_t flags = dict_as_flags(w);
642             if (flags & DEC_ERRORS) {
643                 if (flags & DEC_INVALID_SIGNALS) {
644                     /* non-comparable: Py_NotImplemented */
645                     PyErr_Clear();
646                 }
647                 else {
648                     return NULL;
649                 }
650             }
651             else {
652                 res = (SdFlags(v)==flags) ^ (op==Py_NE) ? Py_True : Py_False;
653             }
654         }
655     }
656 
657     Py_INCREF(res);
658     return res;
659 }
660 
661 static PyObject *
signaldict_copy(PyObject * self,PyObject * args UNUSED)662 signaldict_copy(PyObject *self, PyObject *args UNUSED)
663 {
664     return flags_as_dict(SdFlags(self));
665 }
666 
667 
668 static PyMappingMethods signaldict_as_mapping = {
669     (lenfunc)signaldict_len,          /* mp_length */
670     (binaryfunc)signaldict_getitem,   /* mp_subscript */
671     (objobjargproc)signaldict_setitem /* mp_ass_subscript */
672 };
673 
674 static PyMethodDef signaldict_methods[] = {
675     { "copy", (PyCFunction)signaldict_copy, METH_NOARGS, NULL},
676     {NULL, NULL}
677 };
678 
679 
680 static PyTypeObject PyDecSignalDictMixin_Type =
681 {
682     PyVarObject_HEAD_INIT(0, 0)
683     "decimal.SignalDictMixin",                /* tp_name */
684     sizeof(PyDecSignalDictObject),            /* tp_basicsize */
685     0,                                        /* tp_itemsize */
686     0,                                        /* tp_dealloc */
687     0,                                        /* tp_print */
688     (getattrfunc) 0,                          /* tp_getattr */
689     (setattrfunc) 0,                          /* tp_setattr */
690     0,                                        /* tp_reserved */
691     (reprfunc) signaldict_repr,               /* tp_repr */
692     0,                                        /* tp_as_number */
693     0,                                        /* tp_as_sequence */
694     &signaldict_as_mapping,                   /* tp_as_mapping */
695     PyObject_HashNotImplemented,              /* tp_hash */
696     0,                                        /* tp_call */
697     (reprfunc) 0,                             /* tp_str */
698     PyObject_GenericGetAttr,                  /* tp_getattro */
699     (setattrofunc) 0,                         /* tp_setattro */
700     (PyBufferProcs *) 0,                      /* tp_as_buffer */
701     Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|
702     Py_TPFLAGS_HAVE_GC,                       /* tp_flags */
703     0,                                        /* tp_doc */
704     0,                                        /* tp_traverse */
705     0,                                        /* tp_clear */
706     signaldict_richcompare,                   /* tp_richcompare */
707     0,                                        /* tp_weaklistoffset */
708     (getiterfunc)signaldict_iter,             /* tp_iter */
709     0,                                        /* tp_iternext */
710     signaldict_methods,                       /* tp_methods */
711     0,                                        /* tp_members */
712     0,                                        /* tp_getset */
713     0,                                        /* tp_base */
714     0,                                        /* tp_dict */
715     0,                                        /* tp_descr_get */
716     0,                                        /* tp_descr_set */
717     0,                                        /* tp_dictoffset */
718     (initproc)signaldict_init,                /* tp_init */
719     0,                                        /* tp_alloc */
720     PyType_GenericNew,                        /* tp_new */
721 };
722 
723 
724 /******************************************************************************/
725 /*                         Context Object, Part 1                             */
726 /******************************************************************************/
727 
728 #define Dec_CONTEXT_GET_SSIZE(mem) \
729 static PyObject *                                       \
730 context_get##mem(PyObject *self, void *closure UNUSED)  \
731 {                                                       \
732     return PyLong_FromSsize_t(mpd_get##mem(CTX(self))); \
733 }
734 
735 #define Dec_CONTEXT_GET_ULONG(mem) \
736 static PyObject *                                            \
737 context_get##mem(PyObject *self, void *closure UNUSED)       \
738 {                                                            \
739     return PyLong_FromUnsignedLong(mpd_get##mem(CTX(self))); \
740 }
741 
742 Dec_CONTEXT_GET_SSIZE(prec)
Dec_CONTEXT_GET_SSIZE(emax)743 Dec_CONTEXT_GET_SSIZE(emax)
744 Dec_CONTEXT_GET_SSIZE(emin)
745 Dec_CONTEXT_GET_SSIZE(clamp)
746 
747 #ifdef EXTRA_FUNCTIONALITY
748 Dec_CONTEXT_GET_ULONG(traps)
749 Dec_CONTEXT_GET_ULONG(status)
750 #endif
751 
752 static PyObject *
753 context_getround(PyObject *self, void *closure UNUSED)
754 {
755     int i = mpd_getround(CTX(self));
756 
757     Py_INCREF(round_map[i]);
758     return round_map[i];
759 }
760 
761 static PyObject *
context_getcapitals(PyObject * self,void * closure UNUSED)762 context_getcapitals(PyObject *self, void *closure UNUSED)
763 {
764     return PyLong_FromLong(CtxCaps(self));
765 }
766 
767 #ifdef EXTRA_FUNCTIONALITY
768 static PyObject *
context_getallcr(PyObject * self,void * closure UNUSED)769 context_getallcr(PyObject *self, void *closure UNUSED)
770 {
771     return PyLong_FromLong(mpd_getcr(CTX(self)));
772 }
773 #endif
774 
775 static PyObject *
context_getetiny(PyObject * self,PyObject * dummy UNUSED)776 context_getetiny(PyObject *self, PyObject *dummy UNUSED)
777 {
778     return PyLong_FromSsize_t(mpd_etiny(CTX(self)));
779 }
780 
781 static PyObject *
context_getetop(PyObject * self,PyObject * dummy UNUSED)782 context_getetop(PyObject *self, PyObject *dummy UNUSED)
783 {
784     return PyLong_FromSsize_t(mpd_etop(CTX(self)));
785 }
786 
787 static int
context_setprec(PyObject * self,PyObject * value,void * closure UNUSED)788 context_setprec(PyObject *self, PyObject *value, void *closure UNUSED)
789 {
790     mpd_context_t *ctx;
791     mpd_ssize_t x;
792 
793     x = PyLong_AsSsize_t(value);
794     if (x == -1 && PyErr_Occurred()) {
795         return -1;
796     }
797 
798     ctx = CTX(self);
799     if (!mpd_qsetprec(ctx, x)) {
800         return value_error_int(
801             "valid range for prec is [1, MAX_PREC]");
802     }
803 
804     return 0;
805 }
806 
807 static int
context_setemin(PyObject * self,PyObject * value,void * closure UNUSED)808 context_setemin(PyObject *self, PyObject *value, void *closure UNUSED)
809 {
810     mpd_context_t *ctx;
811     mpd_ssize_t x;
812 
813     x = PyLong_AsSsize_t(value);
814     if (x == -1 && PyErr_Occurred()) {
815         return -1;
816     }
817 
818     ctx = CTX(self);
819     if (!mpd_qsetemin(ctx, x)) {
820         return value_error_int(
821             "valid range for Emin is [MIN_EMIN, 0]");
822     }
823 
824     return 0;
825 }
826 
827 static int
context_setemax(PyObject * self,PyObject * value,void * closure UNUSED)828 context_setemax(PyObject *self, PyObject *value, void *closure UNUSED)
829 {
830     mpd_context_t *ctx;
831     mpd_ssize_t x;
832 
833     x = PyLong_AsSsize_t(value);
834     if (x == -1 && PyErr_Occurred()) {
835         return -1;
836     }
837 
838     ctx = CTX(self);
839     if (!mpd_qsetemax(ctx, x)) {
840         return value_error_int(
841             "valid range for Emax is [0, MAX_EMAX]");
842     }
843 
844     return 0;
845 }
846 
847 #ifdef CONFIG_32
848 static PyObject *
context_unsafe_setprec(PyObject * self,PyObject * value)849 context_unsafe_setprec(PyObject *self, PyObject *value)
850 {
851     mpd_context_t *ctx = CTX(self);
852     mpd_ssize_t x;
853 
854     x = PyLong_AsSsize_t(value);
855     if (x == -1 && PyErr_Occurred()) {
856         return NULL;
857     }
858 
859     if (x < 1 || x > 1070000000L) {
860         return value_error_ptr(
861             "valid range for unsafe prec is [1, 1070000000]");
862     }
863 
864     ctx->prec = x;
865     Py_RETURN_NONE;
866 }
867 
868 static PyObject *
context_unsafe_setemin(PyObject * self,PyObject * value)869 context_unsafe_setemin(PyObject *self, PyObject *value)
870 {
871     mpd_context_t *ctx = CTX(self);
872     mpd_ssize_t x;
873 
874     x = PyLong_AsSsize_t(value);
875     if (x == -1 && PyErr_Occurred()) {
876         return NULL;
877     }
878 
879     if (x < -1070000000L || x > 0) {
880         return value_error_ptr(
881             "valid range for unsafe emin is [-1070000000, 0]");
882     }
883 
884     ctx->emin = x;
885     Py_RETURN_NONE;
886 }
887 
888 static PyObject *
context_unsafe_setemax(PyObject * self,PyObject * value)889 context_unsafe_setemax(PyObject *self, PyObject *value)
890 {
891     mpd_context_t *ctx = CTX(self);
892     mpd_ssize_t x;
893 
894     x = PyLong_AsSsize_t(value);
895     if (x == -1 && PyErr_Occurred()) {
896         return NULL;
897     }
898 
899     if (x < 0 || x > 1070000000L) {
900         return value_error_ptr(
901             "valid range for unsafe emax is [0, 1070000000]");
902     }
903 
904     ctx->emax = x;
905     Py_RETURN_NONE;
906 }
907 #endif
908 
909 static int
context_setround(PyObject * self,PyObject * value,void * closure UNUSED)910 context_setround(PyObject *self, PyObject *value, void *closure UNUSED)
911 {
912     mpd_context_t *ctx;
913     int x;
914 
915     x = getround(value);
916     if (x == -1) {
917         return -1;
918     }
919 
920     ctx = CTX(self);
921     if (!mpd_qsetround(ctx, x)) {
922         INTERNAL_ERROR_INT("context_setround"); /* GCOV_NOT_REACHED */
923     }
924 
925     return 0;
926 }
927 
928 static int
context_setcapitals(PyObject * self,PyObject * value,void * closure UNUSED)929 context_setcapitals(PyObject *self, PyObject *value, void *closure UNUSED)
930 {
931     mpd_ssize_t x;
932 
933     x = PyLong_AsSsize_t(value);
934     if (x == -1 && PyErr_Occurred()) {
935         return -1;
936     }
937 
938     if (x != 0 && x != 1) {
939         return value_error_int(
940             "valid values for capitals are 0 or 1");
941     }
942     CtxCaps(self) = (int)x;
943 
944     return 0;
945 }
946 
947 #ifdef EXTRA_FUNCTIONALITY
948 static int
context_settraps(PyObject * self,PyObject * value,void * closure UNUSED)949 context_settraps(PyObject *self, PyObject *value, void *closure UNUSED)
950 {
951     mpd_context_t *ctx;
952     uint32_t flags;
953 
954     flags = long_as_flags(value);
955     if (flags & DEC_ERRORS) {
956         return -1;
957     }
958 
959     ctx = CTX(self);
960     if (!mpd_qsettraps(ctx, flags)) {
961         INTERNAL_ERROR_INT("context_settraps");
962     }
963 
964     return 0;
965 }
966 #endif
967 
968 static int
context_settraps_list(PyObject * self,PyObject * value)969 context_settraps_list(PyObject *self, PyObject *value)
970 {
971     mpd_context_t *ctx;
972     uint32_t flags;
973 
974     flags = list_as_flags(value);
975     if (flags & DEC_ERRORS) {
976         return -1;
977     }
978 
979     ctx = CTX(self);
980     if (!mpd_qsettraps(ctx, flags)) {
981         INTERNAL_ERROR_INT("context_settraps_list");
982     }
983 
984     return 0;
985 }
986 
987 static int
context_settraps_dict(PyObject * self,PyObject * value)988 context_settraps_dict(PyObject *self, PyObject *value)
989 {
990     mpd_context_t *ctx;
991     uint32_t flags;
992 
993     if (PyDecSignalDict_Check(value)) {
994         flags = SdFlags(value);
995     }
996     else {
997         flags = dict_as_flags(value);
998         if (flags & DEC_ERRORS) {
999             return -1;
1000         }
1001     }
1002 
1003     ctx = CTX(self);
1004     if (!mpd_qsettraps(ctx, flags)) {
1005         INTERNAL_ERROR_INT("context_settraps_dict");
1006     }
1007 
1008     return 0;
1009 }
1010 
1011 #ifdef EXTRA_FUNCTIONALITY
1012 static int
context_setstatus(PyObject * self,PyObject * value,void * closure UNUSED)1013 context_setstatus(PyObject *self, PyObject *value, void *closure UNUSED)
1014 {
1015     mpd_context_t *ctx;
1016     uint32_t flags;
1017 
1018     flags = long_as_flags(value);
1019     if (flags & DEC_ERRORS) {
1020         return -1;
1021     }
1022 
1023     ctx = CTX(self);
1024     if (!mpd_qsetstatus(ctx, flags)) {
1025         INTERNAL_ERROR_INT("context_setstatus");
1026     }
1027 
1028     return 0;
1029 }
1030 #endif
1031 
1032 static int
context_setstatus_list(PyObject * self,PyObject * value)1033 context_setstatus_list(PyObject *self, PyObject *value)
1034 {
1035     mpd_context_t *ctx;
1036     uint32_t flags;
1037 
1038     flags = list_as_flags(value);
1039     if (flags & DEC_ERRORS) {
1040         return -1;
1041     }
1042 
1043     ctx = CTX(self);
1044     if (!mpd_qsetstatus(ctx, flags)) {
1045         INTERNAL_ERROR_INT("context_setstatus_list");
1046     }
1047 
1048     return 0;
1049 }
1050 
1051 static int
context_setstatus_dict(PyObject * self,PyObject * value)1052 context_setstatus_dict(PyObject *self, PyObject *value)
1053 {
1054     mpd_context_t *ctx;
1055     uint32_t flags;
1056 
1057     if (PyDecSignalDict_Check(value)) {
1058         flags = SdFlags(value);
1059     }
1060     else {
1061         flags = dict_as_flags(value);
1062         if (flags & DEC_ERRORS) {
1063             return -1;
1064         }
1065     }
1066 
1067     ctx = CTX(self);
1068     if (!mpd_qsetstatus(ctx, flags)) {
1069         INTERNAL_ERROR_INT("context_setstatus_dict");
1070     }
1071 
1072     return 0;
1073 }
1074 
1075 static int
context_setclamp(PyObject * self,PyObject * value,void * closure UNUSED)1076 context_setclamp(PyObject *self, PyObject *value, void *closure UNUSED)
1077 {
1078     mpd_context_t *ctx;
1079     mpd_ssize_t x;
1080 
1081     x = PyLong_AsSsize_t(value);
1082     if (x == -1 && PyErr_Occurred()) {
1083         return -1;
1084     }
1085     BOUNDS_CHECK(x, INT_MIN, INT_MAX);
1086 
1087     ctx = CTX(self);
1088     if (!mpd_qsetclamp(ctx, (int)x)) {
1089         return value_error_int("valid values for clamp are 0 or 1");
1090     }
1091 
1092     return 0;
1093 }
1094 
1095 #ifdef EXTRA_FUNCTIONALITY
1096 static int
context_setallcr(PyObject * self,PyObject * value,void * closure UNUSED)1097 context_setallcr(PyObject *self, PyObject *value, void *closure UNUSED)
1098 {
1099     mpd_context_t *ctx;
1100     mpd_ssize_t x;
1101 
1102     x = PyLong_AsSsize_t(value);
1103     if (x == -1 && PyErr_Occurred()) {
1104         return -1;
1105     }
1106     BOUNDS_CHECK(x, INT_MIN, INT_MAX);
1107 
1108     ctx = CTX(self);
1109     if (!mpd_qsetcr(ctx, (int)x)) {
1110         return value_error_int("valid values for _allcr are 0 or 1");
1111     }
1112 
1113     return 0;
1114 }
1115 #endif
1116 
1117 static PyObject *
context_getattr(PyObject * self,PyObject * name)1118 context_getattr(PyObject *self, PyObject *name)
1119 {
1120     PyObject *retval;
1121 
1122     if (PyUnicode_Check(name)) {
1123         if (PyUnicode_CompareWithASCIIString(name, "traps") == 0) {
1124             retval = ((PyDecContextObject *)self)->traps;
1125             Py_INCREF(retval);
1126             return retval;
1127         }
1128         if (PyUnicode_CompareWithASCIIString(name, "flags") == 0) {
1129             retval = ((PyDecContextObject *)self)->flags;
1130             Py_INCREF(retval);
1131             return retval;
1132         }
1133     }
1134 
1135     return PyObject_GenericGetAttr(self, name);
1136 }
1137 
1138 static int
context_setattr(PyObject * self,PyObject * name,PyObject * value)1139 context_setattr(PyObject *self, PyObject *name, PyObject *value)
1140 {
1141     if (value == NULL) {
1142         PyErr_SetString(PyExc_AttributeError,
1143             "context attributes cannot be deleted");
1144         return -1;
1145     }
1146 
1147     if (PyUnicode_Check(name)) {
1148         if (PyUnicode_CompareWithASCIIString(name, "traps") == 0) {
1149             return context_settraps_dict(self, value);
1150         }
1151         if (PyUnicode_CompareWithASCIIString(name, "flags") == 0) {
1152             return context_setstatus_dict(self, value);
1153         }
1154     }
1155 
1156     return PyObject_GenericSetAttr(self, name, value);
1157 }
1158 
1159 static PyObject *
context_clear_traps(PyObject * self,PyObject * dummy UNUSED)1160 context_clear_traps(PyObject *self, PyObject *dummy UNUSED)
1161 {
1162     CTX(self)->traps = 0;
1163     Py_RETURN_NONE;
1164 }
1165 
1166 static PyObject *
context_clear_flags(PyObject * self,PyObject * dummy UNUSED)1167 context_clear_flags(PyObject *self, PyObject *dummy UNUSED)
1168 {
1169     CTX(self)->status = 0;
1170     Py_RETURN_NONE;
1171 }
1172 
1173 #define DEC_DFLT_EMAX 999999
1174 #define DEC_DFLT_EMIN -999999
1175 
1176 static mpd_context_t dflt_ctx = {
1177   28, DEC_DFLT_EMAX, DEC_DFLT_EMIN,
1178   MPD_IEEE_Invalid_operation|MPD_Division_by_zero|MPD_Overflow,
1179   0, 0, MPD_ROUND_HALF_EVEN, 0, 1
1180 };
1181 
1182 static PyObject *
context_new(PyTypeObject * type,PyObject * args UNUSED,PyObject * kwds UNUSED)1183 context_new(PyTypeObject *type, PyObject *args UNUSED, PyObject *kwds UNUSED)
1184 {
1185     PyDecContextObject *self = NULL;
1186     mpd_context_t *ctx;
1187 
1188     if (type == &PyDecContext_Type) {
1189         self = PyObject_New(PyDecContextObject, &PyDecContext_Type);
1190     }
1191     else {
1192         self = (PyDecContextObject *)type->tp_alloc(type, 0);
1193     }
1194 
1195     if (self == NULL) {
1196         return NULL;
1197     }
1198 
1199     self->traps = PyObject_CallObject((PyObject *)PyDecSignalDict_Type, NULL);
1200     if (self->traps == NULL) {
1201         self->flags = NULL;
1202         Py_DECREF(self);
1203         return NULL;
1204     }
1205     self->flags = PyObject_CallObject((PyObject *)PyDecSignalDict_Type, NULL);
1206     if (self->flags == NULL) {
1207         Py_DECREF(self);
1208         return NULL;
1209     }
1210 
1211     ctx = CTX(self);
1212 
1213     if (default_context_template) {
1214         *ctx = *CTX(default_context_template);
1215     }
1216     else {
1217         *ctx = dflt_ctx;
1218     }
1219 
1220     SdFlagAddr(self->traps) = &ctx->traps;
1221     SdFlagAddr(self->flags) = &ctx->status;
1222 
1223     CtxCaps(self) = 1;
1224     self->tstate = NULL;
1225 
1226     return (PyObject *)self;
1227 }
1228 
1229 static void
context_dealloc(PyDecContextObject * self)1230 context_dealloc(PyDecContextObject *self)
1231 {
1232 #ifndef WITH_DECIMAL_CONTEXTVAR
1233     if (self == cached_context) {
1234         cached_context = NULL;
1235     }
1236 #endif
1237 
1238     Py_XDECREF(self->traps);
1239     Py_XDECREF(self->flags);
1240     Py_TYPE(self)->tp_free(self);
1241 }
1242 
1243 static int
context_init(PyObject * self,PyObject * args,PyObject * kwds)1244 context_init(PyObject *self, PyObject *args, PyObject *kwds)
1245 {
1246     static char *kwlist[] = {
1247       "prec", "rounding", "Emin", "Emax", "capitals", "clamp",
1248       "flags", "traps", NULL
1249     };
1250     PyObject *prec = Py_None;
1251     PyObject *rounding = Py_None;
1252     PyObject *emin = Py_None;
1253     PyObject *emax = Py_None;
1254     PyObject *capitals = Py_None;
1255     PyObject *clamp = Py_None;
1256     PyObject *status = Py_None;
1257     PyObject *traps = Py_None;
1258     int ret;
1259 
1260     assert(PyTuple_Check(args));
1261 
1262     if (!PyArg_ParseTupleAndKeywords(
1263             args, kwds,
1264             "|OOOOOOOO", kwlist,
1265             &prec, &rounding, &emin, &emax, &capitals, &clamp, &status, &traps
1266          )) {
1267         return -1;
1268     }
1269 
1270     if (prec != Py_None && context_setprec(self, prec, NULL) < 0) {
1271         return -1;
1272     }
1273     if (rounding != Py_None && context_setround(self, rounding, NULL) < 0) {
1274         return -1;
1275     }
1276     if (emin != Py_None && context_setemin(self, emin, NULL) < 0) {
1277         return -1;
1278     }
1279     if (emax != Py_None && context_setemax(self, emax, NULL) < 0) {
1280         return -1;
1281     }
1282     if (capitals != Py_None && context_setcapitals(self, capitals, NULL) < 0) {
1283         return -1;
1284     }
1285     if (clamp != Py_None && context_setclamp(self, clamp, NULL) < 0) {
1286        return -1;
1287     }
1288 
1289     if (traps != Py_None) {
1290         if (PyList_Check(traps)) {
1291             ret = context_settraps_list(self, traps);
1292         }
1293 #ifdef EXTRA_FUNCTIONALITY
1294         else if (PyLong_Check(traps)) {
1295             ret = context_settraps(self, traps, NULL);
1296         }
1297 #endif
1298         else {
1299             ret = context_settraps_dict(self, traps);
1300         }
1301         if (ret < 0) {
1302             return ret;
1303         }
1304     }
1305     if (status != Py_None) {
1306         if (PyList_Check(status)) {
1307             ret = context_setstatus_list(self, status);
1308         }
1309 #ifdef EXTRA_FUNCTIONALITY
1310         else if (PyLong_Check(status)) {
1311             ret = context_setstatus(self, status, NULL);
1312         }
1313 #endif
1314         else {
1315             ret = context_setstatus_dict(self, status);
1316         }
1317         if (ret < 0) {
1318             return ret;
1319         }
1320     }
1321 
1322     return 0;
1323 }
1324 
1325 static PyObject *
context_repr(PyDecContextObject * self)1326 context_repr(PyDecContextObject *self)
1327 {
1328     mpd_context_t *ctx;
1329     char flags[MPD_MAX_SIGNAL_LIST];
1330     char traps[MPD_MAX_SIGNAL_LIST];
1331     int n, mem;
1332 
1333     assert(PyDecContext_Check(self));
1334     ctx = CTX(self);
1335 
1336     mem = MPD_MAX_SIGNAL_LIST;
1337     n = mpd_lsnprint_signals(flags, mem, ctx->status, dec_signal_string);
1338     if (n < 0 || n >= mem) {
1339         INTERNAL_ERROR_PTR("context_repr");
1340     }
1341 
1342     n = mpd_lsnprint_signals(traps, mem, ctx->traps, dec_signal_string);
1343     if (n < 0 || n >= mem) {
1344         INTERNAL_ERROR_PTR("context_repr");
1345     }
1346 
1347     return PyUnicode_FromFormat(
1348         "Context(prec=%zd, rounding=%s, Emin=%zd, Emax=%zd, "
1349                 "capitals=%d, clamp=%d, flags=%s, traps=%s)",
1350          ctx->prec, mpd_round_string[ctx->round], ctx->emin, ctx->emax,
1351          self->capitals, ctx->clamp, flags, traps);
1352 }
1353 
1354 static void
init_basic_context(PyObject * v)1355 init_basic_context(PyObject *v)
1356 {
1357     mpd_context_t ctx = dflt_ctx;
1358 
1359     ctx.prec = 9;
1360     ctx.traps |= (MPD_Underflow|MPD_Clamped);
1361     ctx.round = MPD_ROUND_HALF_UP;
1362 
1363     *CTX(v) = ctx;
1364     CtxCaps(v) = 1;
1365 }
1366 
1367 static void
init_extended_context(PyObject * v)1368 init_extended_context(PyObject *v)
1369 {
1370     mpd_context_t ctx = dflt_ctx;
1371 
1372     ctx.prec = 9;
1373     ctx.traps = 0;
1374 
1375     *CTX(v) = ctx;
1376     CtxCaps(v) = 1;
1377 }
1378 
1379 #ifdef EXTRA_FUNCTIONALITY
1380 /* Factory function for creating IEEE interchange format contexts */
1381 static PyObject *
ieee_context(PyObject * dummy UNUSED,PyObject * v)1382 ieee_context(PyObject *dummy UNUSED, PyObject *v)
1383 {
1384     PyObject *context;
1385     mpd_ssize_t bits;
1386     mpd_context_t ctx;
1387 
1388     bits = PyLong_AsSsize_t(v);
1389     if (bits == -1 && PyErr_Occurred()) {
1390         return NULL;
1391     }
1392     if (bits <= 0 || bits > INT_MAX) {
1393         goto error;
1394     }
1395     if (mpd_ieee_context(&ctx, (int)bits) < 0) {
1396         goto error;
1397     }
1398 
1399     context = PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL);
1400     if (context == NULL) {
1401         return NULL;
1402     }
1403     *CTX(context) = ctx;
1404 
1405     return context;
1406 
1407 error:
1408     PyErr_Format(PyExc_ValueError,
1409         "argument must be a multiple of 32, with a maximum of %d",
1410         MPD_IEEE_CONTEXT_MAX_BITS);
1411 
1412     return NULL;
1413 }
1414 #endif
1415 
1416 static PyObject *
context_copy(PyObject * self,PyObject * args UNUSED)1417 context_copy(PyObject *self, PyObject *args UNUSED)
1418 {
1419     PyObject *copy;
1420 
1421     copy = PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL);
1422     if (copy == NULL) {
1423         return NULL;
1424     }
1425 
1426     *CTX(copy) = *CTX(self);
1427     CTX(copy)->newtrap = 0;
1428     CtxCaps(copy) = CtxCaps(self);
1429 
1430     return copy;
1431 }
1432 
1433 static PyObject *
context_reduce(PyObject * self,PyObject * args UNUSED)1434 context_reduce(PyObject *self, PyObject *args UNUSED)
1435 {
1436     PyObject *flags;
1437     PyObject *traps;
1438     PyObject *ret;
1439     mpd_context_t *ctx;
1440 
1441     ctx = CTX(self);
1442 
1443     flags = signals_as_list(ctx->status);
1444     if (flags == NULL) {
1445         return NULL;
1446     }
1447     traps = signals_as_list(ctx->traps);
1448     if (traps == NULL) {
1449         Py_DECREF(flags);
1450         return NULL;
1451     }
1452 
1453     ret = Py_BuildValue(
1454             "O(nsnniiOO)",
1455             Py_TYPE(self),
1456             ctx->prec, mpd_round_string[ctx->round], ctx->emin, ctx->emax,
1457             CtxCaps(self), ctx->clamp, flags, traps
1458     );
1459 
1460     Py_DECREF(flags);
1461     Py_DECREF(traps);
1462     return ret;
1463 }
1464 
1465 
1466 static PyGetSetDef context_getsets [] =
1467 {
1468   { "prec", (getter)context_getprec, (setter)context_setprec, NULL, NULL},
1469   { "Emax", (getter)context_getemax, (setter)context_setemax, NULL, NULL},
1470   { "Emin", (getter)context_getemin, (setter)context_setemin, NULL, NULL},
1471   { "rounding", (getter)context_getround, (setter)context_setround, NULL, NULL},
1472   { "capitals", (getter)context_getcapitals, (setter)context_setcapitals, NULL, NULL},
1473   { "clamp", (getter)context_getclamp, (setter)context_setclamp, NULL, NULL},
1474 #ifdef EXTRA_FUNCTIONALITY
1475   { "_allcr", (getter)context_getallcr, (setter)context_setallcr, NULL, NULL},
1476   { "_traps", (getter)context_gettraps, (setter)context_settraps, NULL, NULL},
1477   { "_flags", (getter)context_getstatus, (setter)context_setstatus, NULL, NULL},
1478 #endif
1479   {NULL}
1480 };
1481 
1482 
1483 #define CONTEXT_CHECK(obj) \
1484     if (!PyDecContext_Check(obj)) {        \
1485         PyErr_SetString(PyExc_TypeError,   \
1486             "argument must be a context"); \
1487         return NULL;                       \
1488     }
1489 
1490 #define CONTEXT_CHECK_VA(obj) \
1491     if (obj == Py_None) {                           \
1492         CURRENT_CONTEXT(obj);                       \
1493     }                                               \
1494     else if (!PyDecContext_Check(obj)) {            \
1495         PyErr_SetString(PyExc_TypeError,            \
1496             "optional argument must be a context"); \
1497         return NULL;                                \
1498     }
1499 
1500 
1501 /******************************************************************************/
1502 /*                Global, thread local and temporary contexts                 */
1503 /******************************************************************************/
1504 
1505 /*
1506  * Thread local storage currently has a speed penalty of about 4%.
1507  * All functions that map Python's arithmetic operators to mpdecimal
1508  * functions have to look up the current context for each and every
1509  * operation.
1510  */
1511 
1512 #ifndef WITH_DECIMAL_CONTEXTVAR
1513 /* Get the context from the thread state dictionary. */
1514 static PyObject *
current_context_from_dict(void)1515 current_context_from_dict(void)
1516 {
1517     PyObject *dict;
1518     PyObject *tl_context;
1519     PyThreadState *tstate;
1520 
1521     dict = PyThreadState_GetDict();
1522     if (dict == NULL) {
1523         PyErr_SetString(PyExc_RuntimeError,
1524             "cannot get thread state");
1525         return NULL;
1526     }
1527 
1528     tl_context = PyDict_GetItemWithError(dict, tls_context_key);
1529     if (tl_context != NULL) {
1530         /* We already have a thread local context. */
1531         CONTEXT_CHECK(tl_context);
1532     }
1533     else {
1534         if (PyErr_Occurred()) {
1535             return NULL;
1536         }
1537 
1538         /* Set up a new thread local context. */
1539         tl_context = context_copy(default_context_template, NULL);
1540         if (tl_context == NULL) {
1541             return NULL;
1542         }
1543         CTX(tl_context)->status = 0;
1544 
1545         if (PyDict_SetItem(dict, tls_context_key, tl_context) < 0) {
1546             Py_DECREF(tl_context);
1547             return NULL;
1548         }
1549         Py_DECREF(tl_context);
1550     }
1551 
1552     /* Cache the context of the current thread, assuming that it
1553      * will be accessed several times before a thread switch. */
1554     tstate = PyThreadState_GET();
1555     if (tstate) {
1556         cached_context = (PyDecContextObject *)tl_context;
1557         cached_context->tstate = tstate;
1558     }
1559 
1560     /* Borrowed reference with refcount==1 */
1561     return tl_context;
1562 }
1563 
1564 /* Return borrowed reference to thread local context. */
1565 static PyObject *
current_context(void)1566 current_context(void)
1567 {
1568     PyThreadState *tstate;
1569 
1570     tstate = PyThreadState_GET();
1571     if (cached_context && cached_context->tstate == tstate) {
1572         return (PyObject *)cached_context;
1573     }
1574 
1575     return current_context_from_dict();
1576 }
1577 
1578 /* ctxobj := borrowed reference to the current context */
1579 #define CURRENT_CONTEXT(ctxobj) \
1580     ctxobj = current_context(); \
1581     if (ctxobj == NULL) {       \
1582         return NULL;            \
1583     }
1584 
1585 /* Return a new reference to the current context */
1586 static PyObject *
PyDec_GetCurrentContext(PyObject * self UNUSED,PyObject * args UNUSED)1587 PyDec_GetCurrentContext(PyObject *self UNUSED, PyObject *args UNUSED)
1588 {
1589     PyObject *context;
1590 
1591     context = current_context();
1592     if (context == NULL) {
1593         return NULL;
1594     }
1595 
1596     Py_INCREF(context);
1597     return context;
1598 }
1599 
1600 /* Set the thread local context to a new context, decrement old reference */
1601 static PyObject *
PyDec_SetCurrentContext(PyObject * self UNUSED,PyObject * v)1602 PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v)
1603 {
1604     PyObject *dict;
1605 
1606     CONTEXT_CHECK(v);
1607 
1608     dict = PyThreadState_GetDict();
1609     if (dict == NULL) {
1610         PyErr_SetString(PyExc_RuntimeError,
1611             "cannot get thread state");
1612         return NULL;
1613     }
1614 
1615     /* If the new context is one of the templates, make a copy.
1616      * This is the current behavior of decimal.py. */
1617     if (v == default_context_template ||
1618         v == basic_context_template ||
1619         v == extended_context_template) {
1620         v = context_copy(v, NULL);
1621         if (v == NULL) {
1622             return NULL;
1623         }
1624         CTX(v)->status = 0;
1625     }
1626     else {
1627         Py_INCREF(v);
1628     }
1629 
1630     cached_context = NULL;
1631     if (PyDict_SetItem(dict, tls_context_key, v) < 0) {
1632         Py_DECREF(v);
1633         return NULL;
1634     }
1635 
1636     Py_DECREF(v);
1637     Py_RETURN_NONE;
1638 }
1639 #else
1640 static PyObject *
init_current_context(void)1641 init_current_context(void)
1642 {
1643     PyObject *tl_context = context_copy(default_context_template, NULL);
1644     if (tl_context == NULL) {
1645         return NULL;
1646     }
1647     CTX(tl_context)->status = 0;
1648 
1649     PyObject *tok = PyContextVar_Set(current_context_var, tl_context);
1650     if (tok == NULL) {
1651         Py_DECREF(tl_context);
1652         return NULL;
1653     }
1654     Py_DECREF(tok);
1655 
1656     return tl_context;
1657 }
1658 
1659 static inline PyObject *
current_context(void)1660 current_context(void)
1661 {
1662     PyObject *tl_context;
1663     if (PyContextVar_Get(current_context_var, NULL, &tl_context) < 0) {
1664         return NULL;
1665     }
1666 
1667     if (tl_context != NULL) {
1668         return tl_context;
1669     }
1670 
1671     return init_current_context();
1672 }
1673 
1674 /* ctxobj := borrowed reference to the current context */
1675 #define CURRENT_CONTEXT(ctxobj) \
1676     ctxobj = current_context(); \
1677     if (ctxobj == NULL) {       \
1678         return NULL;            \
1679     }                           \
1680     Py_DECREF(ctxobj);
1681 
1682 /* Return a new reference to the current context */
1683 static PyObject *
PyDec_GetCurrentContext(PyObject * self UNUSED,PyObject * args UNUSED)1684 PyDec_GetCurrentContext(PyObject *self UNUSED, PyObject *args UNUSED)
1685 {
1686     return current_context();
1687 }
1688 
1689 /* Set the thread local context to a new context, decrement old reference */
1690 static PyObject *
PyDec_SetCurrentContext(PyObject * self UNUSED,PyObject * v)1691 PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v)
1692 {
1693     CONTEXT_CHECK(v);
1694 
1695     /* If the new context is one of the templates, make a copy.
1696      * This is the current behavior of decimal.py. */
1697     if (v == default_context_template ||
1698         v == basic_context_template ||
1699         v == extended_context_template) {
1700         v = context_copy(v, NULL);
1701         if (v == NULL) {
1702             return NULL;
1703         }
1704         CTX(v)->status = 0;
1705     }
1706     else {
1707         Py_INCREF(v);
1708     }
1709 
1710     PyObject *tok = PyContextVar_Set(current_context_var, v);
1711     Py_DECREF(v);
1712     if (tok == NULL) {
1713         return NULL;
1714     }
1715     Py_DECREF(tok);
1716 
1717     Py_RETURN_NONE;
1718 }
1719 #endif
1720 
1721 /* Context manager object for the 'with' statement. The manager
1722  * owns one reference to the global (outer) context and one
1723  * to the local (inner) context. */
1724 static PyObject *
ctxmanager_new(PyTypeObject * type UNUSED,PyObject * args,PyObject * kwds)1725 ctxmanager_new(PyTypeObject *type UNUSED, PyObject *args, PyObject *kwds)
1726 {
1727     static char *kwlist[] = {"ctx", NULL};
1728     PyDecContextManagerObject *self;
1729     PyObject *local = Py_None;
1730     PyObject *global;
1731 
1732     CURRENT_CONTEXT(global);
1733     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, &local)) {
1734         return NULL;
1735     }
1736     if (local == Py_None) {
1737         local = global;
1738     }
1739     else if (!PyDecContext_Check(local)) {
1740         PyErr_SetString(PyExc_TypeError,
1741             "optional argument must be a context");
1742         return NULL;
1743     }
1744 
1745     self = PyObject_New(PyDecContextManagerObject,
1746                         &PyDecContextManager_Type);
1747     if (self == NULL) {
1748         return NULL;
1749     }
1750 
1751     self->local = context_copy(local, NULL);
1752     if (self->local == NULL) {
1753         self->global = NULL;
1754         Py_DECREF(self);
1755         return NULL;
1756     }
1757     self->global = global;
1758     Py_INCREF(self->global);
1759 
1760     return (PyObject *)self;
1761 }
1762 
1763 static void
ctxmanager_dealloc(PyDecContextManagerObject * self)1764 ctxmanager_dealloc(PyDecContextManagerObject *self)
1765 {
1766     Py_XDECREF(self->local);
1767     Py_XDECREF(self->global);
1768     PyObject_Del(self);
1769 }
1770 
1771 static PyObject *
ctxmanager_set_local(PyDecContextManagerObject * self,PyObject * args UNUSED)1772 ctxmanager_set_local(PyDecContextManagerObject *self, PyObject *args UNUSED)
1773 {
1774     PyObject *ret;
1775 
1776     ret = PyDec_SetCurrentContext(NULL, self->local);
1777     if (ret == NULL) {
1778         return NULL;
1779     }
1780     Py_DECREF(ret);
1781 
1782     Py_INCREF(self->local);
1783     return self->local;
1784 }
1785 
1786 static PyObject *
ctxmanager_restore_global(PyDecContextManagerObject * self,PyObject * args UNUSED)1787 ctxmanager_restore_global(PyDecContextManagerObject *self,
1788                           PyObject *args UNUSED)
1789 {
1790     PyObject *ret;
1791 
1792     ret = PyDec_SetCurrentContext(NULL, self->global);
1793     if (ret == NULL) {
1794         return NULL;
1795     }
1796     Py_DECREF(ret);
1797 
1798     Py_RETURN_NONE;
1799 }
1800 
1801 
1802 static PyMethodDef ctxmanager_methods[] = {
1803   {"__enter__", (PyCFunction)ctxmanager_set_local, METH_NOARGS, NULL},
1804   {"__exit__", (PyCFunction)ctxmanager_restore_global, METH_VARARGS, NULL},
1805   {NULL, NULL}
1806 };
1807 
1808 static PyTypeObject PyDecContextManager_Type =
1809 {
1810     PyVarObject_HEAD_INIT(NULL, 0)
1811     "decimal.ContextManager",               /* tp_name */
1812     sizeof(PyDecContextManagerObject),      /* tp_basicsize */
1813     0,                                      /* tp_itemsize */
1814     (destructor) ctxmanager_dealloc,        /* tp_dealloc */
1815     0,                                      /* tp_print */
1816     (getattrfunc) 0,                        /* tp_getattr */
1817     (setattrfunc) 0,                        /* tp_setattr */
1818     0,                                      /* tp_reserved */
1819     (reprfunc) 0,                           /* tp_repr */
1820     0,                                      /* tp_as_number */
1821     0,                                      /* tp_as_sequence */
1822     0,                                      /* tp_as_mapping */
1823     0,                                      /* tp_hash */
1824     0,                                      /* tp_call */
1825     0,                                      /* tp_str */
1826     (getattrofunc) PyObject_GenericGetAttr, /* tp_getattro */
1827     (setattrofunc) 0,                       /* tp_setattro */
1828     (PyBufferProcs *) 0,                    /* tp_as_buffer */
1829     Py_TPFLAGS_DEFAULT,                     /* tp_flags */
1830     0,                                      /* tp_doc */
1831     0,                                      /* tp_traverse */
1832     0,                                      /* tp_clear */
1833     0,                                      /* tp_richcompare */
1834     0,                                      /* tp_weaklistoffset */
1835     0,                                      /* tp_iter */
1836     0,                                      /* tp_iternext */
1837     ctxmanager_methods,                     /* tp_methods */
1838 };
1839 
1840 
1841 /******************************************************************************/
1842 /*                           New Decimal Object                               */
1843 /******************************************************************************/
1844 
1845 static PyObject *
PyDecType_New(PyTypeObject * type)1846 PyDecType_New(PyTypeObject *type)
1847 {
1848     PyDecObject *dec;
1849 
1850     if (type == &PyDec_Type) {
1851         dec = PyObject_New(PyDecObject, &PyDec_Type);
1852     }
1853     else {
1854         dec = (PyDecObject *)type->tp_alloc(type, 0);
1855     }
1856     if (dec == NULL) {
1857         return NULL;
1858     }
1859 
1860     dec->hash = -1;
1861 
1862     MPD(dec)->flags = MPD_STATIC|MPD_STATIC_DATA;
1863     MPD(dec)->exp = 0;
1864     MPD(dec)->digits = 0;
1865     MPD(dec)->len = 0;
1866     MPD(dec)->alloc = _Py_DEC_MINALLOC;
1867     MPD(dec)->data = dec->data;
1868 
1869     return (PyObject *)dec;
1870 }
1871 #define dec_alloc() PyDecType_New(&PyDec_Type)
1872 
1873 static void
dec_dealloc(PyObject * dec)1874 dec_dealloc(PyObject *dec)
1875 {
1876     mpd_del(MPD(dec));
1877     Py_TYPE(dec)->tp_free(dec);
1878 }
1879 
1880 
1881 /******************************************************************************/
1882 /*                           Conversions to Decimal                           */
1883 /******************************************************************************/
1884 
1885 Py_LOCAL_INLINE(int)
is_space(enum PyUnicode_Kind kind,void * data,Py_ssize_t pos)1886 is_space(enum PyUnicode_Kind kind, void *data, Py_ssize_t pos)
1887 {
1888     Py_UCS4 ch = PyUnicode_READ(kind, data, pos);
1889     return Py_UNICODE_ISSPACE(ch);
1890 }
1891 
1892 /* Return the ASCII representation of a numeric Unicode string. The numeric
1893    string may contain ascii characters in the range [1, 127], any Unicode
1894    space and any unicode digit. If strip_ws is true, leading and trailing
1895    whitespace is stripped. If ignore_underscores is true, underscores are
1896    ignored.
1897 
1898    Return NULL if malloc fails and an empty string if invalid characters
1899    are found. */
1900 static char *
numeric_as_ascii(const PyObject * u,int strip_ws,int ignore_underscores)1901 numeric_as_ascii(const PyObject *u, int strip_ws, int ignore_underscores)
1902 {
1903     enum PyUnicode_Kind kind;
1904     void *data;
1905     Py_UCS4 ch;
1906     char *res, *cp;
1907     Py_ssize_t j, len;
1908     int d;
1909 
1910     if (PyUnicode_READY(u) == -1) {
1911         return NULL;
1912     }
1913 
1914     kind = PyUnicode_KIND(u);
1915     data = PyUnicode_DATA(u);
1916     len =  PyUnicode_GET_LENGTH(u);
1917 
1918     cp = res = PyMem_Malloc(len+1);
1919     if (res == NULL) {
1920         PyErr_NoMemory();
1921         return NULL;
1922     }
1923 
1924     j = 0;
1925     if (strip_ws) {
1926         while (len > 0 && is_space(kind, data, len-1)) {
1927             len--;
1928         }
1929         while (j < len && is_space(kind, data, j)) {
1930             j++;
1931         }
1932     }
1933 
1934     for (; j < len; j++) {
1935         ch = PyUnicode_READ(kind, data, j);
1936         if (ignore_underscores && ch == '_') {
1937             continue;
1938         }
1939         if (0 < ch && ch <= 127) {
1940             *cp++ = ch;
1941             continue;
1942         }
1943         if (Py_UNICODE_ISSPACE(ch)) {
1944             *cp++ = ' ';
1945             continue;
1946         }
1947         d = Py_UNICODE_TODECIMAL(ch);
1948         if (d < 0) {
1949             /* empty string triggers ConversionSyntax */
1950             *res = '\0';
1951             return res;
1952         }
1953         *cp++ = '0' + d;
1954     }
1955     *cp = '\0';
1956     return res;
1957 }
1958 
1959 /* Return a new PyDecObject or a subtype from a C string. Use the context
1960    during conversion. */
1961 static PyObject *
PyDecType_FromCString(PyTypeObject * type,const char * s,PyObject * context)1962 PyDecType_FromCString(PyTypeObject *type, const char *s,
1963                       PyObject *context)
1964 {
1965     PyObject *dec;
1966     uint32_t status = 0;
1967 
1968     dec = PyDecType_New(type);
1969     if (dec == NULL) {
1970         return NULL;
1971     }
1972 
1973     mpd_qset_string(MPD(dec), s, CTX(context), &status);
1974     if (dec_addstatus(context, status)) {
1975         Py_DECREF(dec);
1976         return NULL;
1977     }
1978     return dec;
1979 }
1980 
1981 /* Return a new PyDecObject or a subtype from a C string. Attempt exact
1982    conversion. If the operand cannot be converted exactly, set
1983    InvalidOperation. */
1984 static PyObject *
PyDecType_FromCStringExact(PyTypeObject * type,const char * s,PyObject * context)1985 PyDecType_FromCStringExact(PyTypeObject *type, const char *s,
1986                            PyObject *context)
1987 {
1988     PyObject *dec;
1989     uint32_t status = 0;
1990     mpd_context_t maxctx;
1991 
1992     dec = PyDecType_New(type);
1993     if (dec == NULL) {
1994         return NULL;
1995     }
1996 
1997     mpd_maxcontext(&maxctx);
1998 
1999     mpd_qset_string(MPD(dec), s, &maxctx, &status);
2000     if (status & (MPD_Inexact|MPD_Rounded|MPD_Clamped)) {
2001         /* we want exact results */
2002         mpd_seterror(MPD(dec), MPD_Invalid_operation, &status);
2003     }
2004     status &= MPD_Errors;
2005     if (dec_addstatus(context, status)) {
2006         Py_DECREF(dec);
2007         return NULL;
2008     }
2009 
2010     return dec;
2011 }
2012 
2013 /* Return a new PyDecObject or a subtype from a PyUnicodeObject. */
2014 static PyObject *
PyDecType_FromUnicode(PyTypeObject * type,const PyObject * u,PyObject * context)2015 PyDecType_FromUnicode(PyTypeObject *type, const PyObject *u,
2016                       PyObject *context)
2017 {
2018     PyObject *dec;
2019     char *s;
2020 
2021     s = numeric_as_ascii(u, 0, 0);
2022     if (s == NULL) {
2023         return NULL;
2024     }
2025 
2026     dec = PyDecType_FromCString(type, s, context);
2027     PyMem_Free(s);
2028     return dec;
2029 }
2030 
2031 /* Return a new PyDecObject or a subtype from a PyUnicodeObject. Attempt exact
2032  * conversion. If the conversion is not exact, fail with InvalidOperation.
2033  * Allow leading and trailing whitespace in the input operand. */
2034 static PyObject *
PyDecType_FromUnicodeExactWS(PyTypeObject * type,const PyObject * u,PyObject * context)2035 PyDecType_FromUnicodeExactWS(PyTypeObject *type, const PyObject *u,
2036                              PyObject *context)
2037 {
2038     PyObject *dec;
2039     char *s;
2040 
2041     s = numeric_as_ascii(u, 1, 1);
2042     if (s == NULL) {
2043         return NULL;
2044     }
2045 
2046     dec = PyDecType_FromCStringExact(type, s, context);
2047     PyMem_Free(s);
2048     return dec;
2049 }
2050 
2051 /* Set PyDecObject from triple without any error checking. */
2052 Py_LOCAL_INLINE(void)
_dec_settriple(PyObject * dec,uint8_t sign,uint32_t v,mpd_ssize_t exp)2053 _dec_settriple(PyObject *dec, uint8_t sign, uint32_t v, mpd_ssize_t exp)
2054 {
2055 
2056 #ifdef CONFIG_64
2057     MPD(dec)->data[0] = v;
2058     MPD(dec)->len = 1;
2059 #else
2060     uint32_t q, r;
2061     q = v / MPD_RADIX;
2062     r = v - q * MPD_RADIX;
2063     MPD(dec)->data[1] = q;
2064     MPD(dec)->data[0] = r;
2065     MPD(dec)->len = q ? 2 : 1;
2066 #endif
2067     mpd_set_flags(MPD(dec), sign);
2068     MPD(dec)->exp = exp;
2069     mpd_setdigits(MPD(dec));
2070 }
2071 
2072 /* Return a new PyDecObject from an mpd_ssize_t. */
2073 static PyObject *
PyDecType_FromSsize(PyTypeObject * type,mpd_ssize_t v,PyObject * context)2074 PyDecType_FromSsize(PyTypeObject *type, mpd_ssize_t v, PyObject *context)
2075 {
2076     PyObject *dec;
2077     uint32_t status = 0;
2078 
2079     dec = PyDecType_New(type);
2080     if (dec == NULL) {
2081         return NULL;
2082     }
2083 
2084     mpd_qset_ssize(MPD(dec), v, CTX(context), &status);
2085     if (dec_addstatus(context, status)) {
2086         Py_DECREF(dec);
2087         return NULL;
2088     }
2089     return dec;
2090 }
2091 
2092 /* Return a new PyDecObject from an mpd_ssize_t. Conversion is exact. */
2093 static PyObject *
PyDecType_FromSsizeExact(PyTypeObject * type,mpd_ssize_t v,PyObject * context)2094 PyDecType_FromSsizeExact(PyTypeObject *type, mpd_ssize_t v, PyObject *context)
2095 {
2096     PyObject *dec;
2097     uint32_t status = 0;
2098     mpd_context_t maxctx;
2099 
2100     dec = PyDecType_New(type);
2101     if (dec == NULL) {
2102         return NULL;
2103     }
2104 
2105     mpd_maxcontext(&maxctx);
2106 
2107     mpd_qset_ssize(MPD(dec), v, &maxctx, &status);
2108     if (dec_addstatus(context, status)) {
2109         Py_DECREF(dec);
2110         return NULL;
2111     }
2112     return dec;
2113 }
2114 
2115 /* Convert from a PyLongObject. The context is not modified; flags set
2116    during conversion are accumulated in the status parameter. */
2117 static PyObject *
dec_from_long(PyTypeObject * type,const PyObject * v,const mpd_context_t * ctx,uint32_t * status)2118 dec_from_long(PyTypeObject *type, const PyObject *v,
2119               const mpd_context_t *ctx, uint32_t *status)
2120 {
2121     PyObject *dec;
2122     PyLongObject *l = (PyLongObject *)v;
2123     Py_ssize_t ob_size;
2124     size_t len;
2125     uint8_t sign;
2126 
2127     dec = PyDecType_New(type);
2128     if (dec == NULL) {
2129         return NULL;
2130     }
2131 
2132     ob_size = Py_SIZE(l);
2133     if (ob_size == 0) {
2134         _dec_settriple(dec, MPD_POS, 0, 0);
2135         return dec;
2136     }
2137 
2138     if (ob_size < 0) {
2139         len = -ob_size;
2140         sign = MPD_NEG;
2141     }
2142     else {
2143         len = ob_size;
2144         sign = MPD_POS;
2145     }
2146 
2147     if (len == 1) {
2148         _dec_settriple(dec, sign, *l->ob_digit, 0);
2149         mpd_qfinalize(MPD(dec), ctx, status);
2150         return dec;
2151     }
2152 
2153 #if PYLONG_BITS_IN_DIGIT == 30
2154     mpd_qimport_u32(MPD(dec), l->ob_digit, len, sign, PyLong_BASE,
2155                     ctx, status);
2156 #elif PYLONG_BITS_IN_DIGIT == 15
2157     mpd_qimport_u16(MPD(dec), l->ob_digit, len, sign, PyLong_BASE,
2158                     ctx, status);
2159 #else
2160   #error "PYLONG_BITS_IN_DIGIT should be 15 or 30"
2161 #endif
2162 
2163     return dec;
2164 }
2165 
2166 /* Return a new PyDecObject from a PyLongObject. Use the context for
2167    conversion. */
2168 static PyObject *
PyDecType_FromLong(PyTypeObject * type,const PyObject * v,PyObject * context)2169 PyDecType_FromLong(PyTypeObject *type, const PyObject *v, PyObject *context)
2170 {
2171     PyObject *dec;
2172     uint32_t status = 0;
2173 
2174     if (!PyLong_Check(v)) {
2175         PyErr_SetString(PyExc_TypeError, "argument must be an integer");
2176         return NULL;
2177     }
2178 
2179     dec = dec_from_long(type, v, CTX(context), &status);
2180     if (dec == NULL) {
2181         return NULL;
2182     }
2183 
2184     if (dec_addstatus(context, status)) {
2185         Py_DECREF(dec);
2186         return NULL;
2187     }
2188 
2189     return dec;
2190 }
2191 
2192 /* Return a new PyDecObject from a PyLongObject. Use a maximum context
2193    for conversion. If the conversion is not exact, set InvalidOperation. */
2194 static PyObject *
PyDecType_FromLongExact(PyTypeObject * type,const PyObject * v,PyObject * context)2195 PyDecType_FromLongExact(PyTypeObject *type, const PyObject *v,
2196                         PyObject *context)
2197 {
2198     PyObject *dec;
2199     uint32_t status = 0;
2200     mpd_context_t maxctx;
2201 
2202     if (!PyLong_Check(v)) {
2203         PyErr_SetString(PyExc_TypeError, "argument must be an integer");
2204         return NULL;
2205     }
2206 
2207     mpd_maxcontext(&maxctx);
2208     dec = dec_from_long(type, v, &maxctx, &status);
2209     if (dec == NULL) {
2210         return NULL;
2211     }
2212 
2213     if (status & (MPD_Inexact|MPD_Rounded|MPD_Clamped)) {
2214         /* we want exact results */
2215         mpd_seterror(MPD(dec), MPD_Invalid_operation, &status);
2216     }
2217     status &= MPD_Errors;
2218     if (dec_addstatus(context, status)) {
2219         Py_DECREF(dec);
2220         return NULL;
2221     }
2222 
2223     return dec;
2224 }
2225 
2226 /* External C-API functions */
2227 static binaryfunc _py_long_multiply;
2228 static binaryfunc _py_long_floor_divide;
2229 static ternaryfunc _py_long_power;
2230 static unaryfunc _py_float_abs;
2231 static PyCFunction _py_long_bit_length;
2232 static PyCFunction _py_float_as_integer_ratio;
2233 
2234 /* Return a PyDecObject or a subtype from a PyFloatObject.
2235    Conversion is exact. */
2236 static PyObject *
PyDecType_FromFloatExact(PyTypeObject * type,PyObject * v,PyObject * context)2237 PyDecType_FromFloatExact(PyTypeObject *type, PyObject *v,
2238                          PyObject *context)
2239 {
2240     PyObject *dec, *tmp;
2241     PyObject *n, *d, *n_d;
2242     mpd_ssize_t k;
2243     double x;
2244     int sign;
2245     mpd_t *d1, *d2;
2246     uint32_t status = 0;
2247     mpd_context_t maxctx;
2248 
2249 
2250     assert(PyType_IsSubtype(type, &PyDec_Type));
2251 
2252     if (PyLong_Check(v)) {
2253         return PyDecType_FromLongExact(type, v, context);
2254     }
2255     if (!PyFloat_Check(v)) {
2256         PyErr_SetString(PyExc_TypeError,
2257             "argument must be int or float");
2258         return NULL;
2259     }
2260 
2261     x = PyFloat_AsDouble(v);
2262     if (x == -1.0 && PyErr_Occurred()) {
2263         return NULL;
2264     }
2265     sign = (copysign(1.0, x) == 1.0) ? 0 : 1;
2266 
2267     if (Py_IS_NAN(x) || Py_IS_INFINITY(x)) {
2268         dec = PyDecType_New(type);
2269         if (dec == NULL) {
2270             return NULL;
2271         }
2272         if (Py_IS_NAN(x)) {
2273             /* decimal.py calls repr(float(+-nan)),
2274              * which always gives a positive result. */
2275             mpd_setspecial(MPD(dec), MPD_POS, MPD_NAN);
2276         }
2277         else {
2278             mpd_setspecial(MPD(dec), sign, MPD_INF);
2279         }
2280         return dec;
2281     }
2282 
2283     /* absolute value of the float */
2284     tmp = _py_float_abs(v);
2285     if (tmp == NULL) {
2286         return NULL;
2287     }
2288 
2289     /* float as integer ratio: numerator/denominator */
2290     n_d = _py_float_as_integer_ratio(tmp, NULL);
2291     Py_DECREF(tmp);
2292     if (n_d == NULL) {
2293         return NULL;
2294     }
2295     n = PyTuple_GET_ITEM(n_d, 0);
2296     d = PyTuple_GET_ITEM(n_d, 1);
2297 
2298     tmp = _py_long_bit_length(d, NULL);
2299     if (tmp == NULL) {
2300         Py_DECREF(n_d);
2301         return NULL;
2302     }
2303     k = PyLong_AsSsize_t(tmp);
2304     Py_DECREF(tmp);
2305     if (k == -1 && PyErr_Occurred()) {
2306         Py_DECREF(n_d);
2307         return NULL;
2308     }
2309     k--;
2310 
2311     dec = PyDecType_FromLongExact(type, n, context);
2312     Py_DECREF(n_d);
2313     if (dec == NULL) {
2314         return NULL;
2315     }
2316 
2317     d1 = mpd_qnew();
2318     if (d1 == NULL) {
2319         Py_DECREF(dec);
2320         PyErr_NoMemory();
2321         return NULL;
2322     }
2323     d2 = mpd_qnew();
2324     if (d2 == NULL) {
2325         mpd_del(d1);
2326         Py_DECREF(dec);
2327         PyErr_NoMemory();
2328         return NULL;
2329     }
2330 
2331     mpd_maxcontext(&maxctx);
2332     mpd_qset_uint(d1, 5, &maxctx, &status);
2333     mpd_qset_ssize(d2, k, &maxctx, &status);
2334     mpd_qpow(d1, d1, d2, &maxctx, &status);
2335     if (dec_addstatus(context, status)) {
2336         mpd_del(d1);
2337         mpd_del(d2);
2338         Py_DECREF(dec);
2339         return NULL;
2340     }
2341 
2342     /* result = n * 5**k */
2343     mpd_qmul(MPD(dec), MPD(dec), d1, &maxctx, &status);
2344     mpd_del(d1);
2345     mpd_del(d2);
2346     if (dec_addstatus(context, status)) {
2347         Py_DECREF(dec);
2348         return NULL;
2349     }
2350     /* result = +- n * 5**k * 10**-k */
2351     mpd_set_sign(MPD(dec), sign);
2352     MPD(dec)->exp = -k;
2353 
2354     return dec;
2355 }
2356 
2357 static PyObject *
PyDecType_FromFloat(PyTypeObject * type,PyObject * v,PyObject * context)2358 PyDecType_FromFloat(PyTypeObject *type, PyObject *v,
2359                     PyObject *context)
2360 {
2361     PyObject *dec;
2362     uint32_t status = 0;
2363 
2364     dec = PyDecType_FromFloatExact(type, v, context);
2365     if (dec == NULL) {
2366         return NULL;
2367     }
2368 
2369     mpd_qfinalize(MPD(dec), CTX(context), &status);
2370     if (dec_addstatus(context, status)) {
2371         Py_DECREF(dec);
2372         return NULL;
2373     }
2374 
2375     return dec;
2376 }
2377 
2378 /* Return a new PyDecObject or a subtype from a Decimal. */
2379 static PyObject *
PyDecType_FromDecimalExact(PyTypeObject * type,PyObject * v,PyObject * context)2380 PyDecType_FromDecimalExact(PyTypeObject *type, PyObject *v, PyObject *context)
2381 {
2382     PyObject *dec;
2383     uint32_t status = 0;
2384 
2385     if (type == &PyDec_Type && PyDec_CheckExact(v)) {
2386         Py_INCREF(v);
2387         return v;
2388     }
2389 
2390     dec = PyDecType_New(type);
2391     if (dec == NULL) {
2392         return NULL;
2393     }
2394 
2395     mpd_qcopy(MPD(dec), MPD(v), &status);
2396     if (dec_addstatus(context, status)) {
2397         Py_DECREF(dec);
2398         return NULL;
2399     }
2400 
2401     return dec;
2402 }
2403 
2404 static PyObject *
sequence_as_tuple(PyObject * v,PyObject * ex,const char * mesg)2405 sequence_as_tuple(PyObject *v, PyObject *ex, const char *mesg)
2406 {
2407     if (PyTuple_Check(v)) {
2408         Py_INCREF(v);
2409         return v;
2410     }
2411     if (PyList_Check(v)) {
2412         return PyList_AsTuple(v);
2413     }
2414 
2415     PyErr_SetString(ex, mesg);
2416     return NULL;
2417 }
2418 
2419 /* Return a new C string representation of a DecimalTuple. */
2420 static char *
dectuple_as_str(PyObject * dectuple)2421 dectuple_as_str(PyObject *dectuple)
2422 {
2423     PyObject *digits = NULL, *tmp;
2424     char *decstring = NULL;
2425     char sign_special[6];
2426     char *cp;
2427     long sign, l;
2428     mpd_ssize_t exp = 0;
2429     Py_ssize_t i, mem, tsize;
2430     int is_infinite = 0;
2431     int n;
2432 
2433     assert(PyTuple_Check(dectuple));
2434 
2435     if (PyTuple_Size(dectuple) != 3) {
2436         PyErr_SetString(PyExc_ValueError,
2437             "argument must be a sequence of length 3");
2438         goto error;
2439     }
2440 
2441     /* sign */
2442     tmp = PyTuple_GET_ITEM(dectuple, 0);
2443     if (!PyLong_Check(tmp)) {
2444         PyErr_SetString(PyExc_ValueError,
2445             "sign must be an integer with the value 0 or 1");
2446         goto error;
2447     }
2448     sign = PyLong_AsLong(tmp);
2449     if (sign == -1 && PyErr_Occurred()) {
2450         goto error;
2451     }
2452     if (sign != 0 && sign != 1) {
2453         PyErr_SetString(PyExc_ValueError,
2454             "sign must be an integer with the value 0 or 1");
2455         goto error;
2456     }
2457     sign_special[0] = sign ? '-' : '+';
2458     sign_special[1] = '\0';
2459 
2460     /* exponent or encoding for a special number */
2461     tmp = PyTuple_GET_ITEM(dectuple, 2);
2462     if (PyUnicode_Check(tmp)) {
2463         /* special */
2464         if (PyUnicode_CompareWithASCIIString(tmp, "F") == 0) {
2465             strcat(sign_special, "Inf");
2466             is_infinite = 1;
2467         }
2468         else if (PyUnicode_CompareWithASCIIString(tmp, "n") == 0) {
2469             strcat(sign_special, "NaN");
2470         }
2471         else if (PyUnicode_CompareWithASCIIString(tmp, "N") == 0) {
2472             strcat(sign_special, "sNaN");
2473         }
2474         else {
2475             PyErr_SetString(PyExc_ValueError,
2476                 "string argument in the third position "
2477                 "must be 'F', 'n' or 'N'");
2478             goto error;
2479         }
2480     }
2481     else {
2482         /* exponent */
2483         if (!PyLong_Check(tmp)) {
2484             PyErr_SetString(PyExc_ValueError,
2485                 "exponent must be an integer");
2486             goto error;
2487         }
2488         exp = PyLong_AsSsize_t(tmp);
2489         if (exp == -1 && PyErr_Occurred()) {
2490             goto error;
2491         }
2492     }
2493 
2494     /* coefficient */
2495     digits = sequence_as_tuple(PyTuple_GET_ITEM(dectuple, 1), PyExc_ValueError,
2496                                "coefficient must be a tuple of digits");
2497     if (digits == NULL) {
2498         goto error;
2499     }
2500 
2501     tsize = PyTuple_Size(digits);
2502     /* [sign][coeffdigits+1][E][-][expdigits+1]['\0'] */
2503     mem = 1 + tsize + 3 + MPD_EXPDIGITS + 2;
2504     cp = decstring = PyMem_Malloc(mem);
2505     if (decstring == NULL) {
2506         PyErr_NoMemory();
2507         goto error;
2508     }
2509 
2510     n = snprintf(cp, mem, "%s", sign_special);
2511     if (n < 0 || n >= mem) {
2512         PyErr_SetString(PyExc_RuntimeError,
2513             "internal error in dec_sequence_as_str");
2514         goto error;
2515     }
2516     cp += n;
2517 
2518     if (tsize == 0 && sign_special[1] == '\0') {
2519         /* empty tuple: zero coefficient, except for special numbers */
2520         *cp++ = '0';
2521     }
2522     for (i = 0; i < tsize; i++) {
2523         tmp = PyTuple_GET_ITEM(digits, i);
2524         if (!PyLong_Check(tmp)) {
2525             PyErr_SetString(PyExc_ValueError,
2526                 "coefficient must be a tuple of digits");
2527             goto error;
2528         }
2529         l = PyLong_AsLong(tmp);
2530         if (l == -1 && PyErr_Occurred()) {
2531             goto error;
2532         }
2533         if (l < 0 || l > 9) {
2534             PyErr_SetString(PyExc_ValueError,
2535                 "coefficient must be a tuple of digits");
2536             goto error;
2537         }
2538         if (is_infinite) {
2539             /* accept but ignore any well-formed coefficient for compatibility
2540                with decimal.py */
2541             continue;
2542         }
2543         *cp++ = (char)l + '0';
2544     }
2545     *cp = '\0';
2546 
2547     if (sign_special[1] == '\0') {
2548         /* not a special number */
2549         *cp++ = 'E';
2550         n = snprintf(cp, MPD_EXPDIGITS+2, "%" PRI_mpd_ssize_t, exp);
2551         if (n < 0 || n >= MPD_EXPDIGITS+2) {
2552             PyErr_SetString(PyExc_RuntimeError,
2553                 "internal error in dec_sequence_as_str");
2554             goto error;
2555         }
2556     }
2557 
2558     Py_XDECREF(digits);
2559     return decstring;
2560 
2561 
2562 error:
2563     Py_XDECREF(digits);
2564     if (decstring) PyMem_Free(decstring);
2565     return NULL;
2566 }
2567 
2568 /* Currently accepts tuples and lists. */
2569 static PyObject *
PyDecType_FromSequence(PyTypeObject * type,PyObject * v,PyObject * context)2570 PyDecType_FromSequence(PyTypeObject *type, PyObject *v,
2571                        PyObject *context)
2572 {
2573     PyObject *dectuple;
2574     PyObject *dec;
2575     char *s;
2576 
2577     dectuple = sequence_as_tuple(v, PyExc_TypeError,
2578                                  "argument must be a tuple or list");
2579     if (dectuple == NULL) {
2580         return NULL;
2581     }
2582 
2583     s = dectuple_as_str(dectuple);
2584     Py_DECREF(dectuple);
2585     if (s == NULL) {
2586         return NULL;
2587     }
2588 
2589     dec = PyDecType_FromCString(type, s, context);
2590 
2591     PyMem_Free(s);
2592     return dec;
2593 }
2594 
2595 /* Currently accepts tuples and lists. */
2596 static PyObject *
PyDecType_FromSequenceExact(PyTypeObject * type,PyObject * v,PyObject * context)2597 PyDecType_FromSequenceExact(PyTypeObject *type, PyObject *v,
2598                             PyObject *context)
2599 {
2600     PyObject *dectuple;
2601     PyObject *dec;
2602     char *s;
2603 
2604     dectuple = sequence_as_tuple(v, PyExc_TypeError,
2605                    "argument must be a tuple or list");
2606     if (dectuple == NULL) {
2607         return NULL;
2608     }
2609 
2610     s = dectuple_as_str(dectuple);
2611     Py_DECREF(dectuple);
2612     if (s == NULL) {
2613         return NULL;
2614     }
2615 
2616     dec = PyDecType_FromCStringExact(type, s, context);
2617 
2618     PyMem_Free(s);
2619     return dec;
2620 }
2621 
2622 #define PyDec_FromCString(str, context) \
2623         PyDecType_FromCString(&PyDec_Type, str, context)
2624 #define PyDec_FromCStringExact(str, context) \
2625         PyDecType_FromCStringExact(&PyDec_Type, str, context)
2626 
2627 #define PyDec_FromUnicode(unicode, context) \
2628         PyDecType_FromUnicode(&PyDec_Type, unicode, context)
2629 #define PyDec_FromUnicodeExact(unicode, context) \
2630         PyDecType_FromUnicodeExact(&PyDec_Type, unicode, context)
2631 #define PyDec_FromUnicodeExactWS(unicode, context) \
2632         PyDecType_FromUnicodeExactWS(&PyDec_Type, unicode, context)
2633 
2634 #define PyDec_FromSsize(v, context) \
2635         PyDecType_FromSsize(&PyDec_Type, v, context)
2636 #define PyDec_FromSsizeExact(v, context) \
2637         PyDecType_FromSsizeExact(&PyDec_Type, v, context)
2638 
2639 #define PyDec_FromLong(pylong, context) \
2640         PyDecType_FromLong(&PyDec_Type, pylong, context)
2641 #define PyDec_FromLongExact(pylong, context) \
2642         PyDecType_FromLongExact(&PyDec_Type, pylong, context)
2643 
2644 #define PyDec_FromFloat(pyfloat, context) \
2645         PyDecType_FromFloat(&PyDec_Type, pyfloat, context)
2646 #define PyDec_FromFloatExact(pyfloat, context) \
2647         PyDecType_FromFloatExact(&PyDec_Type, pyfloat, context)
2648 
2649 #define PyDec_FromSequence(sequence, context) \
2650         PyDecType_FromSequence(&PyDec_Type, sequence, context)
2651 #define PyDec_FromSequenceExact(sequence, context) \
2652         PyDecType_FromSequenceExact(&PyDec_Type, sequence, context)
2653 
2654 /* class method */
2655 static PyObject *
dec_from_float(PyObject * type,PyObject * pyfloat)2656 dec_from_float(PyObject *type, PyObject *pyfloat)
2657 {
2658     PyObject *context;
2659     PyObject *result;
2660 
2661     CURRENT_CONTEXT(context);
2662     result = PyDecType_FromFloatExact(&PyDec_Type, pyfloat, context);
2663     if (type != (PyObject *)&PyDec_Type && result != NULL) {
2664         Py_SETREF(result, PyObject_CallFunctionObjArgs(type, result, NULL));
2665     }
2666 
2667     return result;
2668 }
2669 
2670 /* create_decimal_from_float */
2671 static PyObject *
ctx_from_float(PyObject * context,PyObject * v)2672 ctx_from_float(PyObject *context, PyObject *v)
2673 {
2674     return PyDec_FromFloat(v, context);
2675 }
2676 
2677 /* Apply the context to the input operand. Return a new PyDecObject. */
2678 static PyObject *
dec_apply(PyObject * v,PyObject * context)2679 dec_apply(PyObject *v, PyObject *context)
2680 {
2681     PyObject *result;
2682     uint32_t status = 0;
2683 
2684     result = dec_alloc();
2685     if (result == NULL) {
2686         return NULL;
2687     }
2688 
2689     mpd_qcopy(MPD(result), MPD(v), &status);
2690     if (dec_addstatus(context, status)) {
2691         Py_DECREF(result);
2692         return NULL;
2693     }
2694 
2695     mpd_qfinalize(MPD(result), CTX(context), &status);
2696     if (dec_addstatus(context, status)) {
2697         Py_DECREF(result);
2698         return NULL;
2699     }
2700 
2701     return result;
2702 }
2703 
2704 /* 'v' can have any type accepted by the Decimal constructor. Attempt
2705    an exact conversion. If the result does not meet the restrictions
2706    for an mpd_t, fail with InvalidOperation. */
2707 static PyObject *
PyDecType_FromObjectExact(PyTypeObject * type,PyObject * v,PyObject * context)2708 PyDecType_FromObjectExact(PyTypeObject *type, PyObject *v, PyObject *context)
2709 {
2710     if (v == NULL) {
2711         return PyDecType_FromSsizeExact(type, 0, context);
2712     }
2713     else if (PyDec_Check(v)) {
2714         return PyDecType_FromDecimalExact(type, v, context);
2715     }
2716     else if (PyUnicode_Check(v)) {
2717         return PyDecType_FromUnicodeExactWS(type, v, context);
2718     }
2719     else if (PyLong_Check(v)) {
2720         return PyDecType_FromLongExact(type, v, context);
2721     }
2722     else if (PyTuple_Check(v) || PyList_Check(v)) {
2723         return PyDecType_FromSequenceExact(type, v, context);
2724     }
2725     else if (PyFloat_Check(v)) {
2726         if (dec_addstatus(context, MPD_Float_operation)) {
2727             return NULL;
2728         }
2729         return PyDecType_FromFloatExact(type, v, context);
2730     }
2731     else {
2732         PyErr_Format(PyExc_TypeError,
2733             "conversion from %s to Decimal is not supported",
2734             v->ob_type->tp_name);
2735         return NULL;
2736     }
2737 }
2738 
2739 /* The context is used during conversion. This function is the
2740    equivalent of context.create_decimal(). */
2741 static PyObject *
PyDec_FromObject(PyObject * v,PyObject * context)2742 PyDec_FromObject(PyObject *v, PyObject *context)
2743 {
2744     if (v == NULL) {
2745         return PyDec_FromSsize(0, context);
2746     }
2747     else if (PyDec_Check(v)) {
2748         mpd_context_t *ctx = CTX(context);
2749         if (mpd_isnan(MPD(v)) &&
2750             MPD(v)->digits > ctx->prec - ctx->clamp) {
2751             /* Special case: too many NaN payload digits */
2752             PyObject *result;
2753             if (dec_addstatus(context, MPD_Conversion_syntax)) {
2754                 return NULL;
2755             }
2756             result = dec_alloc();
2757             if (result == NULL) {
2758                 return NULL;
2759             }
2760             mpd_setspecial(MPD(result), MPD_POS, MPD_NAN);
2761             return result;
2762         }
2763         return dec_apply(v, context);
2764     }
2765     else if (PyUnicode_Check(v)) {
2766         return PyDec_FromUnicode(v, context);
2767     }
2768     else if (PyLong_Check(v)) {
2769         return PyDec_FromLong(v, context);
2770     }
2771     else if (PyTuple_Check(v) || PyList_Check(v)) {
2772         return PyDec_FromSequence(v, context);
2773     }
2774     else if (PyFloat_Check(v)) {
2775         if (dec_addstatus(context, MPD_Float_operation)) {
2776             return NULL;
2777         }
2778         return PyDec_FromFloat(v, context);
2779     }
2780     else {
2781         PyErr_Format(PyExc_TypeError,
2782             "conversion from %s to Decimal is not supported",
2783             v->ob_type->tp_name);
2784         return NULL;
2785     }
2786 }
2787 
2788 static PyObject *
dec_new(PyTypeObject * type,PyObject * args,PyObject * kwds)2789 dec_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2790 {
2791     static char *kwlist[] = {"value", "context", NULL};
2792     PyObject *v = NULL;
2793     PyObject *context = Py_None;
2794 
2795     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO", kwlist,
2796                                      &v, &context)) {
2797         return NULL;
2798     }
2799     CONTEXT_CHECK_VA(context);
2800 
2801     return PyDecType_FromObjectExact(type, v, context);
2802 }
2803 
2804 static PyObject *
ctx_create_decimal(PyObject * context,PyObject * args)2805 ctx_create_decimal(PyObject *context, PyObject *args)
2806 {
2807     PyObject *v = NULL;
2808 
2809     if (!PyArg_ParseTuple(args, "|O", &v)) {
2810         return NULL;
2811     }
2812 
2813     return PyDec_FromObject(v, context);
2814 }
2815 
2816 
2817 /******************************************************************************/
2818 /*                        Implicit conversions to Decimal                     */
2819 /******************************************************************************/
2820 
2821 /* Try to convert PyObject v to a new PyDecObject conv. If the conversion
2822    fails, set conv to NULL (exception is set). If the conversion is not
2823    implemented, set conv to Py_NotImplemented. */
2824 #define NOT_IMPL 0
2825 #define TYPE_ERR 1
2826 Py_LOCAL_INLINE(int)
convert_op(int type_err,PyObject ** conv,PyObject * v,PyObject * context)2827 convert_op(int type_err, PyObject **conv, PyObject *v, PyObject *context)
2828 {
2829 
2830     if (PyDec_Check(v)) {
2831         *conv = v;
2832         Py_INCREF(v);
2833         return 1;
2834     }
2835     if (PyLong_Check(v)) {
2836         *conv = PyDec_FromLongExact(v, context);
2837         if (*conv == NULL) {
2838             return 0;
2839         }
2840         return 1;
2841     }
2842 
2843     if (type_err) {
2844         PyErr_Format(PyExc_TypeError,
2845             "conversion from %s to Decimal is not supported",
2846             v->ob_type->tp_name);
2847     }
2848     else {
2849         Py_INCREF(Py_NotImplemented);
2850         *conv = Py_NotImplemented;
2851     }
2852     return 0;
2853 }
2854 
2855 /* Return NotImplemented for unsupported types. */
2856 #define CONVERT_OP(a, v, context) \
2857     if (!convert_op(NOT_IMPL, a, v, context)) { \
2858         return *(a);                            \
2859     }
2860 
2861 #define CONVERT_BINOP(a, b, v, w, context) \
2862     if (!convert_op(NOT_IMPL, a, v, context)) { \
2863         return *(a);                            \
2864     }                                           \
2865     if (!convert_op(NOT_IMPL, b, w, context)) { \
2866         Py_DECREF(*(a));                        \
2867         return *(b);                            \
2868     }
2869 
2870 #define CONVERT_TERNOP(a, b, c, v, w, x, context) \
2871     if (!convert_op(NOT_IMPL, a, v, context)) {   \
2872         return *(a);                              \
2873     }                                             \
2874     if (!convert_op(NOT_IMPL, b, w, context)) {   \
2875         Py_DECREF(*(a));                          \
2876         return *(b);                              \
2877     }                                             \
2878     if (!convert_op(NOT_IMPL, c, x, context)) {   \
2879         Py_DECREF(*(a));                          \
2880         Py_DECREF(*(b));                          \
2881         return *(c);                              \
2882     }
2883 
2884 /* Raise TypeError for unsupported types. */
2885 #define CONVERT_OP_RAISE(a, v, context) \
2886     if (!convert_op(TYPE_ERR, a, v, context)) { \
2887         return NULL;                            \
2888     }
2889 
2890 #define CONVERT_BINOP_RAISE(a, b, v, w, context) \
2891     if (!convert_op(TYPE_ERR, a, v, context)) {  \
2892         return NULL;                             \
2893     }                                            \
2894     if (!convert_op(TYPE_ERR, b, w, context)) {  \
2895         Py_DECREF(*(a));                         \
2896         return NULL;                             \
2897     }
2898 
2899 #define CONVERT_TERNOP_RAISE(a, b, c, v, w, x, context) \
2900     if (!convert_op(TYPE_ERR, a, v, context)) {         \
2901         return NULL;                                    \
2902     }                                                   \
2903     if (!convert_op(TYPE_ERR, b, w, context)) {         \
2904         Py_DECREF(*(a));                                \
2905         return NULL;                                    \
2906     }                                                   \
2907     if (!convert_op(TYPE_ERR, c, x, context)) {         \
2908         Py_DECREF(*(a));                                \
2909         Py_DECREF(*(b));                                \
2910         return NULL;                                    \
2911     }
2912 
2913 
2914 /******************************************************************************/
2915 /*              Implicit conversions to Decimal for comparison                */
2916 /******************************************************************************/
2917 
2918 /* Convert rationals for comparison */
2919 static PyObject *Rational = NULL;
2920 static PyObject *
multiply_by_denominator(PyObject * v,PyObject * r,PyObject * context)2921 multiply_by_denominator(PyObject *v, PyObject *r, PyObject *context)
2922 {
2923     PyObject *result;
2924     PyObject *tmp = NULL;
2925     PyObject *denom = NULL;
2926     uint32_t status = 0;
2927     mpd_context_t maxctx;
2928     mpd_ssize_t exp;
2929     mpd_t *vv;
2930 
2931     /* v is not special, r is a rational */
2932     tmp = PyObject_GetAttrString(r, "denominator");
2933     if (tmp == NULL) {
2934         return NULL;
2935     }
2936     denom = PyDec_FromLongExact(tmp, context);
2937     Py_DECREF(tmp);
2938     if (denom == NULL) {
2939         return NULL;
2940     }
2941 
2942     vv = mpd_qncopy(MPD(v));
2943     if (vv == NULL) {
2944         Py_DECREF(denom);
2945         PyErr_NoMemory();
2946         return NULL;
2947     }
2948     result = dec_alloc();
2949     if (result == NULL) {
2950         Py_DECREF(denom);
2951         mpd_del(vv);
2952         return NULL;
2953     }
2954 
2955     mpd_maxcontext(&maxctx);
2956     /* Prevent Overflow in the following multiplication. The result of
2957        the multiplication is only used in mpd_qcmp, which can handle
2958        values that are technically out of bounds, like (for 32-bit)
2959        99999999999999999999...99999999e+425000000. */
2960     exp = vv->exp;
2961     vv->exp = 0;
2962     mpd_qmul(MPD(result), vv, MPD(denom), &maxctx, &status);
2963     MPD(result)->exp = exp;
2964 
2965     Py_DECREF(denom);
2966     mpd_del(vv);
2967     /* If any status has been accumulated during the multiplication,
2968        the result is invalid. This is very unlikely, since even the
2969        32-bit version supports 425000000 digits. */
2970     if (status) {
2971         PyErr_SetString(PyExc_ValueError,
2972             "exact conversion for comparison failed");
2973         Py_DECREF(result);
2974         return NULL;
2975     }
2976 
2977     return result;
2978 }
2979 
2980 static PyObject *
numerator_as_decimal(PyObject * r,PyObject * context)2981 numerator_as_decimal(PyObject *r, PyObject *context)
2982 {
2983     PyObject *tmp, *num;
2984 
2985     tmp = PyObject_GetAttrString(r, "numerator");
2986     if (tmp == NULL) {
2987         return NULL;
2988     }
2989 
2990     num = PyDec_FromLongExact(tmp, context);
2991     Py_DECREF(tmp);
2992     return num;
2993 }
2994 
2995 /* Convert v and w for comparison. v is a Decimal. If w is a Rational, both
2996    v and w have to be transformed. Return 1 for success, with new references
2997    to the converted objects in vcmp and wcmp. Return 0 for failure. In that
2998    case wcmp is either NULL or Py_NotImplemented (new reference) and vcmp
2999    is undefined. */
3000 static int
convert_op_cmp(PyObject ** vcmp,PyObject ** wcmp,PyObject * v,PyObject * w,int op,PyObject * context)3001 convert_op_cmp(PyObject **vcmp, PyObject **wcmp, PyObject *v, PyObject *w,
3002                int op, PyObject *context)
3003 {
3004     mpd_context_t *ctx = CTX(context);
3005 
3006     *vcmp = v;
3007 
3008     if (PyDec_Check(w)) {
3009         Py_INCREF(w);
3010         *wcmp = w;
3011     }
3012     else if (PyLong_Check(w)) {
3013         *wcmp = PyDec_FromLongExact(w, context);
3014     }
3015     else if (PyFloat_Check(w)) {
3016         if (op != Py_EQ && op != Py_NE &&
3017             dec_addstatus(context, MPD_Float_operation)) {
3018             *wcmp = NULL;
3019         }
3020         else {
3021             ctx->status |= MPD_Float_operation;
3022             *wcmp = PyDec_FromFloatExact(w, context);
3023         }
3024     }
3025     else if (PyComplex_Check(w) && (op == Py_EQ || op == Py_NE)) {
3026         Py_complex c = PyComplex_AsCComplex(w);
3027         if (c.real == -1.0 && PyErr_Occurred()) {
3028             *wcmp = NULL;
3029         }
3030         else if (c.imag == 0.0) {
3031             PyObject *tmp = PyFloat_FromDouble(c.real);
3032             if (tmp == NULL) {
3033                 *wcmp = NULL;
3034             }
3035             else {
3036                 ctx->status |= MPD_Float_operation;
3037                 *wcmp = PyDec_FromFloatExact(tmp, context);
3038                 Py_DECREF(tmp);
3039             }
3040         }
3041         else {
3042             Py_INCREF(Py_NotImplemented);
3043             *wcmp = Py_NotImplemented;
3044         }
3045     }
3046     else {
3047         int is_rational = PyObject_IsInstance(w, Rational);
3048         if (is_rational < 0) {
3049             *wcmp = NULL;
3050         }
3051         else if (is_rational > 0) {
3052             *wcmp = numerator_as_decimal(w, context);
3053             if (*wcmp && !mpd_isspecial(MPD(v))) {
3054                 *vcmp = multiply_by_denominator(v, w, context);
3055                 if (*vcmp == NULL) {
3056                     Py_CLEAR(*wcmp);
3057                 }
3058             }
3059         }
3060         else {
3061             Py_INCREF(Py_NotImplemented);
3062             *wcmp = Py_NotImplemented;
3063         }
3064     }
3065 
3066     if (*wcmp == NULL || *wcmp == Py_NotImplemented) {
3067         return 0;
3068     }
3069     if (*vcmp == v) {
3070         Py_INCREF(v);
3071     }
3072     return 1;
3073 }
3074 
3075 #define CONVERT_BINOP_CMP(vcmp, wcmp, v, w, op, ctx) \
3076     if (!convert_op_cmp(vcmp, wcmp, v, w, op, ctx)) {  \
3077         return *(wcmp);                                \
3078     }                                                  \
3079 
3080 
3081 /******************************************************************************/
3082 /*                          Conversions from decimal                          */
3083 /******************************************************************************/
3084 
3085 static PyObject *
unicode_fromascii(const char * s,Py_ssize_t size)3086 unicode_fromascii(const char *s, Py_ssize_t size)
3087 {
3088     PyObject *res;
3089 
3090     res = PyUnicode_New(size, 127);
3091     if (res == NULL) {
3092         return NULL;
3093     }
3094 
3095     memcpy(PyUnicode_1BYTE_DATA(res), s, size);
3096     return res;
3097 }
3098 
3099 /* PyDecObject as a string. The default module context is only used for
3100    the value of 'capitals'. */
3101 static PyObject *
dec_str(PyObject * dec)3102 dec_str(PyObject *dec)
3103 {
3104     PyObject *res, *context;
3105     mpd_ssize_t size;
3106     char *cp;
3107 
3108     CURRENT_CONTEXT(context);
3109     size = mpd_to_sci_size(&cp, MPD(dec), CtxCaps(context));
3110     if (size < 0) {
3111         PyErr_NoMemory();
3112         return NULL;
3113     }
3114 
3115     res = unicode_fromascii(cp, size);
3116     mpd_free(cp);
3117     return res;
3118 }
3119 
3120 /* Representation of a PyDecObject. */
3121 static PyObject *
dec_repr(PyObject * dec)3122 dec_repr(PyObject *dec)
3123 {
3124     PyObject *res, *context;
3125     char *cp;
3126 
3127     CURRENT_CONTEXT(context);
3128     cp = mpd_to_sci(MPD(dec), CtxCaps(context));
3129     if (cp == NULL) {
3130         PyErr_NoMemory();
3131         return NULL;
3132     }
3133 
3134     res = PyUnicode_FromFormat("Decimal('%s')", cp);
3135     mpd_free(cp);
3136     return res;
3137 }
3138 
3139 /* Return a duplicate of src, copy embedded null characters. */
3140 static char *
dec_strdup(const char * src,Py_ssize_t size)3141 dec_strdup(const char *src, Py_ssize_t size)
3142 {
3143     char *dest = PyMem_Malloc(size+1);
3144     if (dest == NULL) {
3145         PyErr_NoMemory();
3146         return NULL;
3147     }
3148 
3149     memcpy(dest, src, size);
3150     dest[size] = '\0';
3151     return dest;
3152 }
3153 
3154 static void
dec_replace_fillchar(char * dest)3155 dec_replace_fillchar(char *dest)
3156 {
3157      while (*dest != '\0') {
3158          if (*dest == '\xff') *dest = '\0';
3159          dest++;
3160      }
3161 }
3162 
3163 /* Convert decimal_point or thousands_sep, which may be multibyte or in
3164    the range [128, 255], to a UTF8 string. */
3165 static PyObject *
dotsep_as_utf8(const char * s)3166 dotsep_as_utf8(const char *s)
3167 {
3168     PyObject *utf8;
3169     PyObject *tmp;
3170     wchar_t buf[2];
3171     size_t n;
3172 
3173     n = mbstowcs(buf, s, 2);
3174     if (n != 1) { /* Issue #7442 */
3175         PyErr_SetString(PyExc_ValueError,
3176             "invalid decimal point or unsupported "
3177             "combination of LC_CTYPE and LC_NUMERIC");
3178         return NULL;
3179     }
3180     tmp = PyUnicode_FromWideChar(buf, n);
3181     if (tmp == NULL) {
3182         return NULL;
3183     }
3184     utf8 = PyUnicode_AsUTF8String(tmp);
3185     Py_DECREF(tmp);
3186     return utf8;
3187 }
3188 
3189 /* Formatted representation of a PyDecObject. */
3190 static PyObject *
dec_format(PyObject * dec,PyObject * args)3191 dec_format(PyObject *dec, PyObject *args)
3192 {
3193     PyObject *result = NULL;
3194     PyObject *override = NULL;
3195     PyObject *dot = NULL;
3196     PyObject *sep = NULL;
3197     PyObject *grouping = NULL;
3198     PyObject *fmtarg;
3199     PyObject *context;
3200     mpd_spec_t spec;
3201     char *fmt;
3202     char *decstring = NULL;
3203     uint32_t status = 0;
3204     int replace_fillchar = 0;
3205     Py_ssize_t size;
3206 
3207 
3208     CURRENT_CONTEXT(context);
3209     if (!PyArg_ParseTuple(args, "O|O", &fmtarg, &override)) {
3210         return NULL;
3211     }
3212 
3213     if (PyUnicode_Check(fmtarg)) {
3214         fmt = (char *)PyUnicode_AsUTF8AndSize(fmtarg, &size);
3215         if (fmt == NULL) {
3216             return NULL;
3217         }
3218         if (size > 0 && fmt[0] == '\0') {
3219             /* NUL fill character: must be replaced with a valid UTF-8 char
3220                before calling mpd_parse_fmt_str(). */
3221             replace_fillchar = 1;
3222             fmt = dec_strdup(fmt, size);
3223             if (fmt == NULL) {
3224                 return NULL;
3225             }
3226             fmt[0] = '_';
3227         }
3228     }
3229     else {
3230         PyErr_SetString(PyExc_TypeError,
3231             "format arg must be str");
3232         return NULL;
3233     }
3234 
3235     if (!mpd_parse_fmt_str(&spec, fmt, CtxCaps(context))) {
3236         PyErr_SetString(PyExc_ValueError,
3237             "invalid format string");
3238         goto finish;
3239     }
3240     if (replace_fillchar) {
3241         /* In order to avoid clobbering parts of UTF-8 thousands separators or
3242            decimal points when the substitution is reversed later, the actual
3243            placeholder must be an invalid UTF-8 byte. */
3244         spec.fill[0] = '\xff';
3245         spec.fill[1] = '\0';
3246     }
3247 
3248     if (override) {
3249         /* Values for decimal_point, thousands_sep and grouping can
3250            be explicitly specified in the override dict. These values
3251            take precedence over the values obtained from localeconv()
3252            in mpd_parse_fmt_str(). The feature is not documented and
3253            is only used in test_decimal. */
3254         if (!PyDict_Check(override)) {
3255             PyErr_SetString(PyExc_TypeError,
3256                 "optional argument must be a dict");
3257             goto finish;
3258         }
3259         if ((dot = PyDict_GetItemString(override, "decimal_point"))) {
3260             if ((dot = PyUnicode_AsUTF8String(dot)) == NULL) {
3261                 goto finish;
3262             }
3263             spec.dot = PyBytes_AS_STRING(dot);
3264         }
3265         if ((sep = PyDict_GetItemString(override, "thousands_sep"))) {
3266             if ((sep = PyUnicode_AsUTF8String(sep)) == NULL) {
3267                 goto finish;
3268             }
3269             spec.sep = PyBytes_AS_STRING(sep);
3270         }
3271         if ((grouping = PyDict_GetItemString(override, "grouping"))) {
3272             if ((grouping = PyUnicode_AsUTF8String(grouping)) == NULL) {
3273                 goto finish;
3274             }
3275             spec.grouping = PyBytes_AS_STRING(grouping);
3276         }
3277         if (mpd_validate_lconv(&spec) < 0) {
3278             PyErr_SetString(PyExc_ValueError,
3279                 "invalid override dict");
3280             goto finish;
3281         }
3282     }
3283     else {
3284         size_t n = strlen(spec.dot);
3285         if (n > 1 || (n == 1 && !isascii((unsigned char)spec.dot[0]))) {
3286             /* fix locale dependent non-ascii characters */
3287             dot = dotsep_as_utf8(spec.dot);
3288             if (dot == NULL) {
3289                 goto finish;
3290             }
3291             spec.dot = PyBytes_AS_STRING(dot);
3292         }
3293         n = strlen(spec.sep);
3294         if (n > 1 || (n == 1 && !isascii((unsigned char)spec.sep[0]))) {
3295             /* fix locale dependent non-ascii characters */
3296             sep = dotsep_as_utf8(spec.sep);
3297             if (sep == NULL) {
3298                 goto finish;
3299             }
3300             spec.sep = PyBytes_AS_STRING(sep);
3301         }
3302     }
3303 
3304 
3305     decstring = mpd_qformat_spec(MPD(dec), &spec, CTX(context), &status);
3306     if (decstring == NULL) {
3307         if (status & MPD_Malloc_error) {
3308             PyErr_NoMemory();
3309         }
3310         else {
3311             PyErr_SetString(PyExc_ValueError,
3312                 "format specification exceeds internal limits of _decimal");
3313         }
3314         goto finish;
3315     }
3316     size = strlen(decstring);
3317     if (replace_fillchar) {
3318         dec_replace_fillchar(decstring);
3319     }
3320 
3321     result = PyUnicode_DecodeUTF8(decstring, size, NULL);
3322 
3323 
3324 finish:
3325     Py_XDECREF(grouping);
3326     Py_XDECREF(sep);
3327     Py_XDECREF(dot);
3328     if (replace_fillchar) PyMem_Free(fmt);
3329     if (decstring) mpd_free(decstring);
3330     return result;
3331 }
3332 
3333 /* Return a PyLongObject from a PyDecObject, using the specified rounding
3334  * mode. The context precision is not observed. */
3335 static PyObject *
dec_as_long(PyObject * dec,PyObject * context,int round)3336 dec_as_long(PyObject *dec, PyObject *context, int round)
3337 {
3338     PyLongObject *pylong;
3339     digit *ob_digit;
3340     size_t n;
3341     Py_ssize_t i;
3342     mpd_t *x;
3343     mpd_context_t workctx;
3344     uint32_t status = 0;
3345 
3346     if (mpd_isspecial(MPD(dec))) {
3347         if (mpd_isnan(MPD(dec))) {
3348             PyErr_SetString(PyExc_ValueError,
3349                 "cannot convert NaN to integer");
3350         }
3351         else {
3352             PyErr_SetString(PyExc_OverflowError,
3353                 "cannot convert Infinity to integer");
3354         }
3355         return NULL;
3356     }
3357 
3358     x = mpd_qnew();
3359     if (x == NULL) {
3360         PyErr_NoMemory();
3361         return NULL;
3362     }
3363     workctx = *CTX(context);
3364     workctx.round = round;
3365     mpd_qround_to_int(x, MPD(dec), &workctx, &status);
3366     if (dec_addstatus(context, status)) {
3367         mpd_del(x);
3368         return NULL;
3369     }
3370 
3371     status = 0;
3372     ob_digit = NULL;
3373 #if PYLONG_BITS_IN_DIGIT == 30
3374     n = mpd_qexport_u32(&ob_digit, 0, PyLong_BASE, x, &status);
3375 #elif PYLONG_BITS_IN_DIGIT == 15
3376     n = mpd_qexport_u16(&ob_digit, 0, PyLong_BASE, x, &status);
3377 #else
3378     #error "PYLONG_BITS_IN_DIGIT should be 15 or 30"
3379 #endif
3380 
3381     if (n == SIZE_MAX) {
3382         PyErr_NoMemory();
3383         mpd_del(x);
3384         return NULL;
3385     }
3386 
3387     assert(n > 0);
3388     pylong = _PyLong_New(n);
3389     if (pylong == NULL) {
3390         mpd_free(ob_digit);
3391         mpd_del(x);
3392         return NULL;
3393     }
3394 
3395     memcpy(pylong->ob_digit, ob_digit, n * sizeof(digit));
3396     mpd_free(ob_digit);
3397 
3398     i = n;
3399     while ((i > 0) && (pylong->ob_digit[i-1] == 0)) {
3400         i--;
3401     }
3402 
3403     Py_SIZE(pylong) = i;
3404     if (mpd_isnegative(x) && !mpd_iszero(x)) {
3405         Py_SIZE(pylong) = -i;
3406     }
3407 
3408     mpd_del(x);
3409     return (PyObject *) pylong;
3410 }
3411 
3412 /* Convert a Decimal to its exact integer ratio representation. */
3413 static PyObject *
dec_as_integer_ratio(PyObject * self,PyObject * args UNUSED)3414 dec_as_integer_ratio(PyObject *self, PyObject *args UNUSED)
3415 {
3416     PyObject *numerator = NULL;
3417     PyObject *denominator = NULL;
3418     PyObject *exponent = NULL;
3419     PyObject *result = NULL;
3420     PyObject *tmp;
3421     mpd_ssize_t exp;
3422     PyObject *context;
3423     uint32_t status = 0;
3424 
3425     if (mpd_isspecial(MPD(self))) {
3426         if (mpd_isnan(MPD(self))) {
3427             PyErr_SetString(PyExc_ValueError,
3428                 "cannot convert NaN to integer ratio");
3429         }
3430         else {
3431             PyErr_SetString(PyExc_OverflowError,
3432                 "cannot convert Infinity to integer ratio");
3433         }
3434         return NULL;
3435     }
3436 
3437     CURRENT_CONTEXT(context);
3438 
3439     tmp = dec_alloc();
3440     if (tmp == NULL) {
3441         return NULL;
3442     }
3443 
3444     if (!mpd_qcopy(MPD(tmp), MPD(self), &status)) {
3445         Py_DECREF(tmp);
3446         PyErr_NoMemory();
3447         return NULL;
3448     }
3449 
3450     exp = mpd_iszero(MPD(tmp)) ? 0 : MPD(tmp)->exp;
3451     MPD(tmp)->exp = 0;
3452 
3453     /* context and rounding are unused here: the conversion is exact */
3454     numerator = dec_as_long(tmp, context, MPD_ROUND_FLOOR);
3455     Py_DECREF(tmp);
3456     if (numerator == NULL) {
3457         goto error;
3458     }
3459 
3460     exponent = PyLong_FromSsize_t(exp < 0 ? -exp : exp);
3461     if (exponent == NULL) {
3462         goto error;
3463     }
3464 
3465     tmp = PyLong_FromLong(10);
3466     if (tmp == NULL) {
3467         goto error;
3468     }
3469 
3470     Py_SETREF(exponent, _py_long_power(tmp, exponent, Py_None));
3471     Py_DECREF(tmp);
3472     if (exponent == NULL) {
3473         goto error;
3474     }
3475 
3476     if (exp >= 0) {
3477         Py_SETREF(numerator, _py_long_multiply(numerator, exponent));
3478         if (numerator == NULL) {
3479             goto error;
3480         }
3481         denominator = PyLong_FromLong(1);
3482         if (denominator == NULL) {
3483             goto error;
3484         }
3485     }
3486     else {
3487         denominator = exponent;
3488         exponent = NULL;
3489         tmp = _PyLong_GCD(numerator, denominator);
3490         if (tmp == NULL) {
3491             goto error;
3492         }
3493         Py_SETREF(numerator, _py_long_floor_divide(numerator, tmp));
3494         Py_SETREF(denominator, _py_long_floor_divide(denominator, tmp));
3495         Py_DECREF(tmp);
3496         if (numerator == NULL || denominator == NULL) {
3497             goto error;
3498         }
3499     }
3500 
3501     result = PyTuple_Pack(2, numerator, denominator);
3502 
3503 
3504 error:
3505     Py_XDECREF(exponent);
3506     Py_XDECREF(denominator);
3507     Py_XDECREF(numerator);
3508     return result;
3509 }
3510 
3511 static PyObject *
PyDec_ToIntegralValue(PyObject * dec,PyObject * args,PyObject * kwds)3512 PyDec_ToIntegralValue(PyObject *dec, PyObject *args, PyObject *kwds)
3513 {
3514     static char *kwlist[] = {"rounding", "context", NULL};
3515     PyObject *result;
3516     PyObject *rounding = Py_None;
3517     PyObject *context = Py_None;
3518     uint32_t status = 0;
3519     mpd_context_t workctx;
3520 
3521     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO", kwlist,
3522                                      &rounding, &context)) {
3523         return NULL;
3524     }
3525     CONTEXT_CHECK_VA(context);
3526 
3527     workctx = *CTX(context);
3528     if (rounding != Py_None) {
3529         int round = getround(rounding);
3530         if (round < 0) {
3531             return NULL;
3532         }
3533         if (!mpd_qsetround(&workctx, round)) {
3534             INTERNAL_ERROR_PTR("PyDec_ToIntegralValue"); /* GCOV_NOT_REACHED */
3535         }
3536     }
3537 
3538     result = dec_alloc();
3539     if (result == NULL) {
3540         return NULL;
3541     }
3542 
3543     mpd_qround_to_int(MPD(result), MPD(dec), &workctx, &status);
3544     if (dec_addstatus(context, status)) {
3545         Py_DECREF(result);
3546         return NULL;
3547     }
3548 
3549     return result;
3550 }
3551 
3552 static PyObject *
PyDec_ToIntegralExact(PyObject * dec,PyObject * args,PyObject * kwds)3553 PyDec_ToIntegralExact(PyObject *dec, PyObject *args, PyObject *kwds)
3554 {
3555     static char *kwlist[] = {"rounding", "context", NULL};
3556     PyObject *result;
3557     PyObject *rounding = Py_None;
3558     PyObject *context = Py_None;
3559     uint32_t status = 0;
3560     mpd_context_t workctx;
3561 
3562     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO", kwlist,
3563                                      &rounding, &context)) {
3564         return NULL;
3565     }
3566     CONTEXT_CHECK_VA(context);
3567 
3568     workctx = *CTX(context);
3569     if (rounding != Py_None) {
3570         int round = getround(rounding);
3571         if (round < 0) {
3572             return NULL;
3573         }
3574         if (!mpd_qsetround(&workctx, round)) {
3575             INTERNAL_ERROR_PTR("PyDec_ToIntegralExact"); /* GCOV_NOT_REACHED */
3576         }
3577     }
3578 
3579     result = dec_alloc();
3580     if (result == NULL) {
3581         return NULL;
3582     }
3583 
3584     mpd_qround_to_intx(MPD(result), MPD(dec), &workctx, &status);
3585     if (dec_addstatus(context, status)) {
3586         Py_DECREF(result);
3587         return NULL;
3588     }
3589 
3590     return result;
3591 }
3592 
3593 static PyObject *
PyDec_AsFloat(PyObject * dec)3594 PyDec_AsFloat(PyObject *dec)
3595 {
3596     PyObject *f, *s;
3597 
3598     if (mpd_isnan(MPD(dec))) {
3599         if (mpd_issnan(MPD(dec))) {
3600             PyErr_SetString(PyExc_ValueError,
3601                 "cannot convert signaling NaN to float");
3602             return NULL;
3603         }
3604         if (mpd_isnegative(MPD(dec))) {
3605             s = PyUnicode_FromString("-nan");
3606         }
3607         else {
3608             s = PyUnicode_FromString("nan");
3609         }
3610     }
3611     else {
3612         s = dec_str(dec);
3613     }
3614 
3615     if (s == NULL) {
3616         return NULL;
3617     }
3618 
3619     f = PyFloat_FromString(s);
3620     Py_DECREF(s);
3621 
3622     return f;
3623 }
3624 
3625 static PyObject *
PyDec_Round(PyObject * dec,PyObject * args)3626 PyDec_Round(PyObject *dec, PyObject *args)
3627 {
3628     PyObject *result;
3629     PyObject *x = NULL;
3630     uint32_t status = 0;
3631     PyObject *context;
3632 
3633 
3634     CURRENT_CONTEXT(context);
3635     if (!PyArg_ParseTuple(args, "|O", &x)) {
3636         return NULL;
3637     }
3638 
3639     if (x) {
3640         mpd_uint_t dq[1] = {1};
3641         mpd_t q = {MPD_STATIC|MPD_CONST_DATA,0,1,1,1,dq};
3642         mpd_ssize_t y;
3643 
3644         if (!PyLong_Check(x)) {
3645             PyErr_SetString(PyExc_TypeError,
3646                 "optional arg must be an integer");
3647             return NULL;
3648         }
3649 
3650         y = PyLong_AsSsize_t(x);
3651         if (y == -1 && PyErr_Occurred()) {
3652             return NULL;
3653         }
3654         result = dec_alloc();
3655         if (result == NULL) {
3656             return NULL;
3657         }
3658 
3659         q.exp = (y == MPD_SSIZE_MIN) ? MPD_SSIZE_MAX : -y;
3660         mpd_qquantize(MPD(result), MPD(dec), &q, CTX(context), &status);
3661         if (dec_addstatus(context, status)) {
3662             Py_DECREF(result);
3663             return NULL;
3664         }
3665 
3666         return result;
3667     }
3668     else {
3669         return dec_as_long(dec, context, MPD_ROUND_HALF_EVEN);
3670     }
3671 }
3672 
3673 static PyTypeObject *DecimalTuple = NULL;
3674 /* Return the DecimalTuple representation of a PyDecObject. */
3675 static PyObject *
PyDec_AsTuple(PyObject * dec,PyObject * dummy UNUSED)3676 PyDec_AsTuple(PyObject *dec, PyObject *dummy UNUSED)
3677 {
3678     PyObject *result = NULL;
3679     PyObject *sign = NULL;
3680     PyObject *coeff = NULL;
3681     PyObject *expt = NULL;
3682     PyObject *tmp = NULL;
3683     mpd_t *x = NULL;
3684     char *intstring = NULL;
3685     Py_ssize_t intlen, i;
3686 
3687 
3688     x = mpd_qncopy(MPD(dec));
3689     if (x == NULL) {
3690         PyErr_NoMemory();
3691         goto out;
3692     }
3693 
3694     sign = PyLong_FromUnsignedLong(mpd_sign(MPD(dec)));
3695     if (sign == NULL) {
3696         goto out;
3697     }
3698 
3699     if (mpd_isinfinite(x)) {
3700         expt = PyUnicode_FromString("F");
3701         if (expt == NULL) {
3702             goto out;
3703         }
3704         /* decimal.py has non-compliant infinity payloads. */
3705         coeff = Py_BuildValue("(i)", 0);
3706         if (coeff == NULL) {
3707             goto out;
3708         }
3709     }
3710     else {
3711         if (mpd_isnan(x)) {
3712             expt = PyUnicode_FromString(mpd_isqnan(x)?"n":"N");
3713         }
3714         else {
3715             expt = PyLong_FromSsize_t(MPD(dec)->exp);
3716         }
3717         if (expt == NULL) {
3718             goto out;
3719         }
3720 
3721         /* coefficient is defined */
3722         if (x->len > 0) {
3723 
3724             /* make an integer */
3725             x->exp = 0;
3726             /* clear NaN and sign */
3727             mpd_clear_flags(x);
3728             intstring = mpd_to_sci(x, 1);
3729             if (intstring == NULL) {
3730                 PyErr_NoMemory();
3731                 goto out;
3732             }
3733 
3734             intlen = strlen(intstring);
3735             coeff = PyTuple_New(intlen);
3736             if (coeff == NULL) {
3737                 goto out;
3738             }
3739 
3740             for (i = 0; i < intlen; i++) {
3741                 tmp = PyLong_FromLong(intstring[i]-'0');
3742                 if (tmp == NULL) {
3743                     goto out;
3744                 }
3745                 PyTuple_SET_ITEM(coeff, i, tmp);
3746             }
3747         }
3748         else {
3749             coeff = PyTuple_New(0);
3750             if (coeff == NULL) {
3751                 goto out;
3752             }
3753         }
3754     }
3755 
3756     result = PyObject_CallFunctionObjArgs((PyObject *)DecimalTuple,
3757                                           sign, coeff, expt, NULL);
3758 
3759 out:
3760     if (x) mpd_del(x);
3761     if (intstring) mpd_free(intstring);
3762     Py_XDECREF(sign);
3763     Py_XDECREF(coeff);
3764     Py_XDECREF(expt);
3765     return result;
3766 }
3767 
3768 
3769 /******************************************************************************/
3770 /*         Macros for converting mpdecimal functions to Decimal methods       */
3771 /******************************************************************************/
3772 
3773 /* Unary number method that uses the default module context. */
3774 #define Dec_UnaryNumberMethod(MPDFUNC) \
3775 static PyObject *                                           \
3776 nm_##MPDFUNC(PyObject *self)                                \
3777 {                                                           \
3778     PyObject *result;                                       \
3779     PyObject *context;                                      \
3780     uint32_t status = 0;                                    \
3781                                                             \
3782     CURRENT_CONTEXT(context);                               \
3783     if ((result = dec_alloc()) == NULL) {                   \
3784         return NULL;                                        \
3785     }                                                       \
3786                                                             \
3787     MPDFUNC(MPD(result), MPD(self), CTX(context), &status); \
3788     if (dec_addstatus(context, status)) {                   \
3789         Py_DECREF(result);                                  \
3790         return NULL;                                        \
3791     }                                                       \
3792                                                             \
3793     return result;                                          \
3794 }
3795 
3796 /* Binary number method that uses default module context. */
3797 #define Dec_BinaryNumberMethod(MPDFUNC) \
3798 static PyObject *                                                \
3799 nm_##MPDFUNC(PyObject *self, PyObject *other)                    \
3800 {                                                                \
3801     PyObject *a, *b;                                             \
3802     PyObject *result;                                            \
3803     PyObject *context;                                           \
3804     uint32_t status = 0;                                         \
3805                                                                  \
3806     CURRENT_CONTEXT(context) ;                                   \
3807     CONVERT_BINOP(&a, &b, self, other, context);                 \
3808                                                                  \
3809     if ((result = dec_alloc()) == NULL) {                        \
3810         Py_DECREF(a);                                            \
3811         Py_DECREF(b);                                            \
3812         return NULL;                                             \
3813     }                                                            \
3814                                                                  \
3815     MPDFUNC(MPD(result), MPD(a), MPD(b), CTX(context), &status); \
3816     Py_DECREF(a);                                                \
3817     Py_DECREF(b);                                                \
3818     if (dec_addstatus(context, status)) {                        \
3819         Py_DECREF(result);                                       \
3820         return NULL;                                             \
3821     }                                                            \
3822                                                                  \
3823     return result;                                               \
3824 }
3825 
3826 /* Boolean function without a context arg. */
3827 #define Dec_BoolFunc(MPDFUNC) \
3828 static PyObject *                                           \
3829 dec_##MPDFUNC(PyObject *self, PyObject *dummy UNUSED)       \
3830 {                                                           \
3831     return MPDFUNC(MPD(self)) ? incr_true() : incr_false(); \
3832 }
3833 
3834 /* Boolean function with an optional context arg. */
3835 #define Dec_BoolFuncVA(MPDFUNC) \
3836 static PyObject *                                                         \
3837 dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds)             \
3838 {                                                                         \
3839     static char *kwlist[] = {"context", NULL};                            \
3840     PyObject *context = Py_None;                                          \
3841                                                                           \
3842     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist,            \
3843                                      &context)) {                         \
3844         return NULL;                                                      \
3845     }                                                                     \
3846     CONTEXT_CHECK_VA(context);                                            \
3847                                                                           \
3848     return MPDFUNC(MPD(self), CTX(context)) ? incr_true() : incr_false(); \
3849 }
3850 
3851 /* Unary function with an optional context arg. */
3852 #define Dec_UnaryFuncVA(MPDFUNC) \
3853 static PyObject *                                              \
3854 dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds)  \
3855 {                                                              \
3856     static char *kwlist[] = {"context", NULL};                 \
3857     PyObject *result;                                          \
3858     PyObject *context = Py_None;                               \
3859     uint32_t status = 0;                                       \
3860                                                                \
3861     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, \
3862                                      &context)) {              \
3863         return NULL;                                           \
3864     }                                                          \
3865     CONTEXT_CHECK_VA(context);                                 \
3866                                                                \
3867     if ((result = dec_alloc()) == NULL) {                      \
3868         return NULL;                                           \
3869     }                                                          \
3870                                                                \
3871     MPDFUNC(MPD(result), MPD(self), CTX(context), &status);    \
3872     if (dec_addstatus(context, status)) {                      \
3873         Py_DECREF(result);                                     \
3874         return NULL;                                           \
3875     }                                                          \
3876                                                                \
3877     return result;                                             \
3878 }
3879 
3880 /* Binary function with an optional context arg. */
3881 #define Dec_BinaryFuncVA(MPDFUNC) \
3882 static PyObject *                                                \
3883 dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds)    \
3884 {                                                                \
3885     static char *kwlist[] = {"other", "context", NULL};          \
3886     PyObject *other;                                             \
3887     PyObject *a, *b;                                             \
3888     PyObject *result;                                            \
3889     PyObject *context = Py_None;                                 \
3890     uint32_t status = 0;                                         \
3891                                                                  \
3892     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist,  \
3893                                      &other, &context)) {        \
3894         return NULL;                                             \
3895     }                                                            \
3896     CONTEXT_CHECK_VA(context);                                   \
3897     CONVERT_BINOP_RAISE(&a, &b, self, other, context);           \
3898                                                                  \
3899     if ((result = dec_alloc()) == NULL) {                        \
3900         Py_DECREF(a);                                            \
3901         Py_DECREF(b);                                            \
3902         return NULL;                                             \
3903     }                                                            \
3904                                                                  \
3905     MPDFUNC(MPD(result), MPD(a), MPD(b), CTX(context), &status); \
3906     Py_DECREF(a);                                                \
3907     Py_DECREF(b);                                                \
3908     if (dec_addstatus(context, status)) {                        \
3909         Py_DECREF(result);                                       \
3910         return NULL;                                             \
3911     }                                                            \
3912                                                                  \
3913     return result;                                               \
3914 }
3915 
3916 /* Binary function with an optional context arg. Actual MPDFUNC does
3917    NOT take a context. The context is used to record InvalidOperation
3918    if the second operand cannot be converted exactly. */
3919 #define Dec_BinaryFuncVA_NO_CTX(MPDFUNC) \
3920 static PyObject *                                               \
3921 dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds)   \
3922 {                                                               \
3923     static char *kwlist[] = {"other", "context", NULL};         \
3924     PyObject *context = Py_None;                                \
3925     PyObject *other;                                            \
3926     PyObject *a, *b;                                            \
3927     PyObject *result;                                           \
3928                                                                 \
3929     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist, \
3930                                      &other, &context)) {       \
3931         return NULL;                                            \
3932     }                                                           \
3933     CONTEXT_CHECK_VA(context);                                  \
3934     CONVERT_BINOP_RAISE(&a, &b, self, other, context);          \
3935                                                                 \
3936     if ((result = dec_alloc()) == NULL) {                       \
3937         Py_DECREF(a);                                           \
3938         Py_DECREF(b);                                           \
3939         return NULL;                                            \
3940     }                                                           \
3941                                                                 \
3942     MPDFUNC(MPD(result), MPD(a), MPD(b));                       \
3943     Py_DECREF(a);                                               \
3944     Py_DECREF(b);                                               \
3945                                                                 \
3946     return result;                                              \
3947 }
3948 
3949 /* Ternary function with an optional context arg. */
3950 #define Dec_TernaryFuncVA(MPDFUNC) \
3951 static PyObject *                                                        \
3952 dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds)            \
3953 {                                                                        \
3954     static char *kwlist[] = {"other", "third", "context", NULL};         \
3955     PyObject *other, *third;                                             \
3956     PyObject *a, *b, *c;                                                 \
3957     PyObject *result;                                                    \
3958     PyObject *context = Py_None;                                         \
3959     uint32_t status = 0;                                                 \
3960                                                                          \
3961     if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|O", kwlist,         \
3962                                      &other, &third, &context)) {        \
3963         return NULL;                                                     \
3964     }                                                                    \
3965     CONTEXT_CHECK_VA(context);                                           \
3966     CONVERT_TERNOP_RAISE(&a, &b, &c, self, other, third, context);       \
3967                                                                          \
3968     if ((result = dec_alloc()) == NULL) {                                \
3969         Py_DECREF(a);                                                    \
3970         Py_DECREF(b);                                                    \
3971         Py_DECREF(c);                                                    \
3972         return NULL;                                                     \
3973     }                                                                    \
3974                                                                          \
3975     MPDFUNC(MPD(result), MPD(a), MPD(b), MPD(c), CTX(context), &status); \
3976     Py_DECREF(a);                                                        \
3977     Py_DECREF(b);                                                        \
3978     Py_DECREF(c);                                                        \
3979     if (dec_addstatus(context, status)) {                                \
3980         Py_DECREF(result);                                               \
3981         return NULL;                                                     \
3982     }                                                                    \
3983                                                                          \
3984     return result;                                                       \
3985 }
3986 
3987 
3988 /**********************************************/
3989 /*              Number methods                */
3990 /**********************************************/
3991 
3992 Dec_UnaryNumberMethod(mpd_qminus)
Dec_UnaryNumberMethod(mpd_qplus)3993 Dec_UnaryNumberMethod(mpd_qplus)
3994 Dec_UnaryNumberMethod(mpd_qabs)
3995 
3996 Dec_BinaryNumberMethod(mpd_qadd)
3997 Dec_BinaryNumberMethod(mpd_qsub)
3998 Dec_BinaryNumberMethod(mpd_qmul)
3999 Dec_BinaryNumberMethod(mpd_qdiv)
4000 Dec_BinaryNumberMethod(mpd_qrem)
4001 Dec_BinaryNumberMethod(mpd_qdivint)
4002 
4003 static PyObject *
4004 nm_dec_as_long(PyObject *dec)
4005 {
4006     PyObject *context;
4007 
4008     CURRENT_CONTEXT(context);
4009     return dec_as_long(dec, context, MPD_ROUND_DOWN);
4010 }
4011 
4012 static int
nm_nonzero(PyObject * v)4013 nm_nonzero(PyObject *v)
4014 {
4015     return !mpd_iszero(MPD(v));
4016 }
4017 
4018 static PyObject *
nm_mpd_qdivmod(PyObject * v,PyObject * w)4019 nm_mpd_qdivmod(PyObject *v, PyObject *w)
4020 {
4021     PyObject *a, *b;
4022     PyObject *q, *r;
4023     PyObject *context;
4024     uint32_t status = 0;
4025     PyObject *ret;
4026 
4027     CURRENT_CONTEXT(context);
4028     CONVERT_BINOP(&a, &b, v, w, context);
4029 
4030     q = dec_alloc();
4031     if (q == NULL) {
4032         Py_DECREF(a);
4033         Py_DECREF(b);
4034         return NULL;
4035     }
4036     r = dec_alloc();
4037     if (r == NULL) {
4038         Py_DECREF(a);
4039         Py_DECREF(b);
4040         Py_DECREF(q);
4041         return NULL;
4042     }
4043 
4044     mpd_qdivmod(MPD(q), MPD(r), MPD(a), MPD(b), CTX(context), &status);
4045     Py_DECREF(a);
4046     Py_DECREF(b);
4047     if (dec_addstatus(context, status)) {
4048         Py_DECREF(r);
4049         Py_DECREF(q);
4050         return NULL;
4051     }
4052 
4053     ret = Py_BuildValue("(OO)", q, r);
4054     Py_DECREF(r);
4055     Py_DECREF(q);
4056     return ret;
4057 }
4058 
4059 static PyObject *
nm_mpd_qpow(PyObject * base,PyObject * exp,PyObject * mod)4060 nm_mpd_qpow(PyObject *base, PyObject *exp, PyObject *mod)
4061 {
4062     PyObject *a, *b, *c = NULL;
4063     PyObject *result;
4064     PyObject *context;
4065     uint32_t status = 0;
4066 
4067     CURRENT_CONTEXT(context);
4068     CONVERT_BINOP(&a, &b, base, exp, context);
4069 
4070     if (mod != Py_None) {
4071         if (!convert_op(NOT_IMPL, &c, mod, context)) {
4072             Py_DECREF(a);
4073             Py_DECREF(b);
4074             return c;
4075         }
4076     }
4077 
4078     result = dec_alloc();
4079     if (result == NULL) {
4080         Py_DECREF(a);
4081         Py_DECREF(b);
4082         Py_XDECREF(c);
4083         return NULL;
4084     }
4085 
4086     if (c == NULL) {
4087         mpd_qpow(MPD(result), MPD(a), MPD(b),
4088                  CTX(context), &status);
4089     }
4090     else {
4091         mpd_qpowmod(MPD(result), MPD(a), MPD(b), MPD(c),
4092                     CTX(context), &status);
4093         Py_DECREF(c);
4094     }
4095     Py_DECREF(a);
4096     Py_DECREF(b);
4097     if (dec_addstatus(context, status)) {
4098         Py_DECREF(result);
4099         return NULL;
4100     }
4101 
4102     return result;
4103 }
4104 
4105 
4106 /******************************************************************************/
4107 /*                             Decimal Methods                                */
4108 /******************************************************************************/
4109 
4110 /* Unary arithmetic functions, optional context arg */
4111 Dec_UnaryFuncVA(mpd_qexp)
Dec_UnaryFuncVA(mpd_qln)4112 Dec_UnaryFuncVA(mpd_qln)
4113 Dec_UnaryFuncVA(mpd_qlog10)
4114 Dec_UnaryFuncVA(mpd_qnext_minus)
4115 Dec_UnaryFuncVA(mpd_qnext_plus)
4116 Dec_UnaryFuncVA(mpd_qreduce)
4117 Dec_UnaryFuncVA(mpd_qsqrt)
4118 
4119 /* Binary arithmetic functions, optional context arg */
4120 Dec_BinaryFuncVA(mpd_qcompare)
4121 Dec_BinaryFuncVA(mpd_qcompare_signal)
4122 Dec_BinaryFuncVA(mpd_qmax)
4123 Dec_BinaryFuncVA(mpd_qmax_mag)
4124 Dec_BinaryFuncVA(mpd_qmin)
4125 Dec_BinaryFuncVA(mpd_qmin_mag)
4126 Dec_BinaryFuncVA(mpd_qnext_toward)
4127 Dec_BinaryFuncVA(mpd_qrem_near)
4128 
4129 /* Ternary arithmetic functions, optional context arg */
4130 Dec_TernaryFuncVA(mpd_qfma)
4131 
4132 /* Boolean functions, no context arg */
4133 Dec_BoolFunc(mpd_iscanonical)
4134 Dec_BoolFunc(mpd_isfinite)
4135 Dec_BoolFunc(mpd_isinfinite)
4136 Dec_BoolFunc(mpd_isnan)
4137 Dec_BoolFunc(mpd_isqnan)
4138 Dec_BoolFunc(mpd_issnan)
4139 Dec_BoolFunc(mpd_issigned)
4140 Dec_BoolFunc(mpd_iszero)
4141 
4142 /* Boolean functions, optional context arg */
4143 Dec_BoolFuncVA(mpd_isnormal)
4144 Dec_BoolFuncVA(mpd_issubnormal)
4145 
4146 /* Unary functions, no context arg */
4147 static PyObject *
4148 dec_mpd_adjexp(PyObject *self, PyObject *dummy UNUSED)
4149 {
4150     mpd_ssize_t retval;
4151 
4152     if (mpd_isspecial(MPD(self))) {
4153         retval = 0;
4154     }
4155     else {
4156         retval = mpd_adjexp(MPD(self));
4157     }
4158 
4159     return PyLong_FromSsize_t(retval);
4160 }
4161 
4162 static PyObject *
dec_canonical(PyObject * self,PyObject * dummy UNUSED)4163 dec_canonical(PyObject *self, PyObject *dummy UNUSED)
4164 {
4165     Py_INCREF(self);
4166     return self;
4167 }
4168 
4169 static PyObject *
dec_conjugate(PyObject * self,PyObject * dummy UNUSED)4170 dec_conjugate(PyObject *self, PyObject *dummy UNUSED)
4171 {
4172     Py_INCREF(self);
4173     return self;
4174 }
4175 
4176 static PyObject *
dec_mpd_radix(PyObject * self UNUSED,PyObject * dummy UNUSED)4177 dec_mpd_radix(PyObject *self UNUSED, PyObject *dummy UNUSED)
4178 {
4179     PyObject *result;
4180 
4181     result = dec_alloc();
4182     if (result == NULL) {
4183         return NULL;
4184     }
4185 
4186     _dec_settriple(result, MPD_POS, 10, 0);
4187     return result;
4188 }
4189 
4190 static PyObject *
dec_mpd_qcopy_abs(PyObject * self,PyObject * dummy UNUSED)4191 dec_mpd_qcopy_abs(PyObject *self, PyObject *dummy UNUSED)
4192 {
4193     PyObject *result;
4194     uint32_t status = 0;
4195 
4196     if ((result = dec_alloc()) == NULL) {
4197         return NULL;
4198     }
4199 
4200     mpd_qcopy_abs(MPD(result), MPD(self), &status);
4201     if (status & MPD_Malloc_error) {
4202         Py_DECREF(result);
4203         PyErr_NoMemory();
4204         return NULL;
4205     }
4206 
4207     return result;
4208 }
4209 
4210 static PyObject *
dec_mpd_qcopy_negate(PyObject * self,PyObject * dummy UNUSED)4211 dec_mpd_qcopy_negate(PyObject *self, PyObject *dummy UNUSED)
4212 {
4213     PyObject *result;
4214     uint32_t status = 0;
4215 
4216     if ((result = dec_alloc()) == NULL) {
4217         return NULL;
4218     }
4219 
4220     mpd_qcopy_negate(MPD(result), MPD(self), &status);
4221     if (status & MPD_Malloc_error) {
4222         Py_DECREF(result);
4223         PyErr_NoMemory();
4224         return NULL;
4225     }
4226 
4227     return result;
4228 }
4229 
4230 /* Unary functions, optional context arg */
4231 Dec_UnaryFuncVA(mpd_qinvert)
Dec_UnaryFuncVA(mpd_qlogb)4232 Dec_UnaryFuncVA(mpd_qlogb)
4233 
4234 static PyObject *
4235 dec_mpd_class(PyObject *self, PyObject *args, PyObject *kwds)
4236 {
4237     static char *kwlist[] = {"context", NULL};
4238     PyObject *context = Py_None;
4239     const char *cp;
4240 
4241     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist,
4242                                      &context)) {
4243         return NULL;
4244     }
4245     CONTEXT_CHECK_VA(context);
4246 
4247     cp = mpd_class(MPD(self), CTX(context));
4248     return PyUnicode_FromString(cp);
4249 }
4250 
4251 static PyObject *
dec_mpd_to_eng(PyObject * self,PyObject * args,PyObject * kwds)4252 dec_mpd_to_eng(PyObject *self, PyObject *args, PyObject *kwds)
4253 {
4254     static char *kwlist[] = {"context", NULL};
4255     PyObject *result;
4256     PyObject *context = Py_None;
4257     mpd_ssize_t size;
4258     char *s;
4259 
4260     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist,
4261                                      &context)) {
4262         return NULL;
4263     }
4264     CONTEXT_CHECK_VA(context);
4265 
4266     size = mpd_to_eng_size(&s, MPD(self), CtxCaps(context));
4267     if (size < 0) {
4268         PyErr_NoMemory();
4269         return NULL;
4270     }
4271 
4272     result = unicode_fromascii(s, size);
4273     mpd_free(s);
4274 
4275     return result;
4276 }
4277 
4278 /* Binary functions, optional context arg for conversion errors */
4279 Dec_BinaryFuncVA_NO_CTX(mpd_compare_total)
Dec_BinaryFuncVA_NO_CTX(mpd_compare_total_mag)4280 Dec_BinaryFuncVA_NO_CTX(mpd_compare_total_mag)
4281 
4282 static PyObject *
4283 dec_mpd_qcopy_sign(PyObject *self, PyObject *args, PyObject *kwds)
4284 {
4285     static char *kwlist[] = {"other", "context", NULL};
4286     PyObject *other;
4287     PyObject *a, *b;
4288     PyObject *result;
4289     PyObject *context = Py_None;
4290     uint32_t status = 0;
4291 
4292     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist,
4293                                      &other, &context)) {
4294         return NULL;
4295     }
4296     CONTEXT_CHECK_VA(context);
4297     CONVERT_BINOP_RAISE(&a, &b, self, other, context);
4298 
4299     result = dec_alloc();
4300     if (result == NULL) {
4301         Py_DECREF(a);
4302         Py_DECREF(b);
4303         return NULL;
4304     }
4305 
4306     mpd_qcopy_sign(MPD(result), MPD(a), MPD(b), &status);
4307     Py_DECREF(a);
4308     Py_DECREF(b);
4309     if (dec_addstatus(context, status)) {
4310         Py_DECREF(result);
4311         return NULL;
4312     }
4313 
4314     return result;
4315 }
4316 
4317 static PyObject *
dec_mpd_same_quantum(PyObject * self,PyObject * args,PyObject * kwds)4318 dec_mpd_same_quantum(PyObject *self, PyObject *args, PyObject *kwds)
4319 {
4320     static char *kwlist[] = {"other", "context", NULL};
4321     PyObject *other;
4322     PyObject *a, *b;
4323     PyObject *result;
4324     PyObject *context = Py_None;
4325 
4326     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist,
4327                                      &other, &context)) {
4328         return NULL;
4329     }
4330     CONTEXT_CHECK_VA(context);
4331     CONVERT_BINOP_RAISE(&a, &b, self, other, context);
4332 
4333     result = mpd_same_quantum(MPD(a), MPD(b)) ? incr_true() : incr_false();
4334     Py_DECREF(a);
4335     Py_DECREF(b);
4336 
4337     return result;
4338 }
4339 
4340 /* Binary functions, optional context arg */
4341 Dec_BinaryFuncVA(mpd_qand)
Dec_BinaryFuncVA(mpd_qor)4342 Dec_BinaryFuncVA(mpd_qor)
4343 Dec_BinaryFuncVA(mpd_qxor)
4344 
4345 Dec_BinaryFuncVA(mpd_qrotate)
4346 Dec_BinaryFuncVA(mpd_qscaleb)
4347 Dec_BinaryFuncVA(mpd_qshift)
4348 
4349 static PyObject *
4350 dec_mpd_qquantize(PyObject *v, PyObject *args, PyObject *kwds)
4351 {
4352     static char *kwlist[] = {"exp", "rounding", "context", NULL};
4353     PyObject *rounding = Py_None;
4354     PyObject *context = Py_None;
4355     PyObject *w, *a, *b;
4356     PyObject *result;
4357     uint32_t status = 0;
4358     mpd_context_t workctx;
4359 
4360     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OO", kwlist,
4361                                      &w, &rounding, &context)) {
4362         return NULL;
4363     }
4364     CONTEXT_CHECK_VA(context);
4365 
4366     workctx = *CTX(context);
4367     if (rounding != Py_None) {
4368         int round = getround(rounding);
4369         if (round < 0) {
4370             return NULL;
4371         }
4372         if (!mpd_qsetround(&workctx, round)) {
4373             INTERNAL_ERROR_PTR("dec_mpd_qquantize"); /* GCOV_NOT_REACHED */
4374         }
4375     }
4376 
4377     CONVERT_BINOP_RAISE(&a, &b, v, w, context);
4378 
4379     result = dec_alloc();
4380     if (result == NULL) {
4381         Py_DECREF(a);
4382         Py_DECREF(b);
4383         return NULL;
4384     }
4385 
4386     mpd_qquantize(MPD(result), MPD(a), MPD(b), &workctx, &status);
4387     Py_DECREF(a);
4388     Py_DECREF(b);
4389     if (dec_addstatus(context, status)) {
4390         Py_DECREF(result);
4391         return NULL;
4392     }
4393 
4394     return result;
4395 }
4396 
4397 /* Special methods */
4398 static PyObject *
dec_richcompare(PyObject * v,PyObject * w,int op)4399 dec_richcompare(PyObject *v, PyObject *w, int op)
4400 {
4401     PyObject *a;
4402     PyObject *b;
4403     PyObject *context;
4404     uint32_t status = 0;
4405     int a_issnan, b_issnan;
4406     int r;
4407 
4408     assert(PyDec_Check(v));
4409 
4410     CURRENT_CONTEXT(context);
4411     CONVERT_BINOP_CMP(&a, &b, v, w, op, context);
4412 
4413     a_issnan = mpd_issnan(MPD(a));
4414     b_issnan = mpd_issnan(MPD(b));
4415 
4416     r = mpd_qcmp(MPD(a), MPD(b), &status);
4417     Py_DECREF(a);
4418     Py_DECREF(b);
4419     if (r == INT_MAX) {
4420         /* sNaNs or op={le,ge,lt,gt} always signal. */
4421         if (a_issnan || b_issnan || (op != Py_EQ && op != Py_NE)) {
4422             if (dec_addstatus(context, status)) {
4423                 return NULL;
4424             }
4425         }
4426         /* qNaN comparison with op={eq,ne} or comparison
4427          * with InvalidOperation disabled. */
4428         return (op == Py_NE) ? incr_true() : incr_false();
4429     }
4430 
4431     switch (op) {
4432     case Py_EQ:
4433         r = (r == 0);
4434         break;
4435     case Py_NE:
4436         r = (r != 0);
4437         break;
4438     case Py_LE:
4439         r = (r <= 0);
4440         break;
4441     case Py_GE:
4442         r = (r >= 0);
4443         break;
4444     case Py_LT:
4445         r = (r == -1);
4446         break;
4447     case Py_GT:
4448         r = (r == 1);
4449         break;
4450     }
4451 
4452     return PyBool_FromLong(r);
4453 }
4454 
4455 /* __ceil__ */
4456 static PyObject *
dec_ceil(PyObject * self,PyObject * dummy UNUSED)4457 dec_ceil(PyObject *self, PyObject *dummy UNUSED)
4458 {
4459     PyObject *context;
4460 
4461     CURRENT_CONTEXT(context);
4462     return dec_as_long(self, context, MPD_ROUND_CEILING);
4463 }
4464 
4465 /* __complex__ */
4466 static PyObject *
dec_complex(PyObject * self,PyObject * dummy UNUSED)4467 dec_complex(PyObject *self, PyObject *dummy UNUSED)
4468 {
4469     PyObject *f;
4470     double x;
4471 
4472     f = PyDec_AsFloat(self);
4473     if (f == NULL) {
4474         return NULL;
4475     }
4476 
4477     x = PyFloat_AsDouble(f);
4478     Py_DECREF(f);
4479     if (x == -1.0 && PyErr_Occurred()) {
4480         return NULL;
4481     }
4482 
4483     return PyComplex_FromDoubles(x, 0);
4484 }
4485 
4486 /* __copy__ and __deepcopy__ */
4487 static PyObject *
dec_copy(PyObject * self,PyObject * dummy UNUSED)4488 dec_copy(PyObject *self, PyObject *dummy UNUSED)
4489 {
4490     Py_INCREF(self);
4491     return self;
4492 }
4493 
4494 /* __floor__ */
4495 static PyObject *
dec_floor(PyObject * self,PyObject * dummy UNUSED)4496 dec_floor(PyObject *self, PyObject *dummy UNUSED)
4497 {
4498     PyObject *context;
4499 
4500     CURRENT_CONTEXT(context);
4501     return dec_as_long(self, context, MPD_ROUND_FLOOR);
4502 }
4503 
4504 /* Always uses the module context */
4505 static Py_hash_t
_dec_hash(PyDecObject * v)4506 _dec_hash(PyDecObject *v)
4507 {
4508 #if defined(CONFIG_64) && _PyHASH_BITS == 61
4509     /* 2**61 - 1 */
4510     mpd_uint_t p_data[1] = {2305843009213693951ULL};
4511     mpd_t p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA, 0, 19, 1, 1, p_data};
4512     /* Inverse of 10 modulo p */
4513     mpd_uint_t inv10_p_data[1] = {2075258708292324556ULL};
4514     mpd_t inv10_p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA,
4515                      0, 19, 1, 1, inv10_p_data};
4516 #elif defined(CONFIG_32) && _PyHASH_BITS == 31
4517     /* 2**31 - 1 */
4518     mpd_uint_t p_data[2] = {147483647UL, 2};
4519     mpd_t p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA, 0, 10, 2, 2, p_data};
4520     /* Inverse of 10 modulo p */
4521     mpd_uint_t inv10_p_data[2] = {503238553UL, 1};
4522     mpd_t inv10_p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA,
4523                      0, 10, 2, 2, inv10_p_data};
4524 #else
4525     #error "No valid combination of CONFIG_64, CONFIG_32 and _PyHASH_BITS"
4526 #endif
4527     const Py_hash_t py_hash_inf = 314159;
4528     const Py_hash_t py_hash_nan = 0;
4529     mpd_uint_t ten_data[1] = {10};
4530     mpd_t ten = {MPD_POS|MPD_STATIC|MPD_CONST_DATA,
4531                  0, 2, 1, 1, ten_data};
4532     Py_hash_t result;
4533     mpd_t *exp_hash = NULL;
4534     mpd_t *tmp = NULL;
4535     mpd_ssize_t exp;
4536     uint32_t status = 0;
4537     mpd_context_t maxctx;
4538 
4539 
4540     if (mpd_isspecial(MPD(v))) {
4541         if (mpd_issnan(MPD(v))) {
4542             PyErr_SetString(PyExc_TypeError,
4543                 "Cannot hash a signaling NaN value");
4544             return -1;
4545         }
4546         else if (mpd_isnan(MPD(v))) {
4547             return py_hash_nan;
4548         }
4549         else {
4550             return py_hash_inf * mpd_arith_sign(MPD(v));
4551         }
4552     }
4553 
4554     mpd_maxcontext(&maxctx);
4555     exp_hash = mpd_qnew();
4556     if (exp_hash == NULL) {
4557         goto malloc_error;
4558     }
4559     tmp = mpd_qnew();
4560     if (tmp == NULL) {
4561         goto malloc_error;
4562     }
4563 
4564     /*
4565      * exp(v): exponent of v
4566      * int(v): coefficient of v
4567      */
4568     exp = MPD(v)->exp;
4569     if (exp >= 0) {
4570         /* 10**exp(v) % p */
4571         mpd_qsset_ssize(tmp, exp, &maxctx, &status);
4572         mpd_qpowmod(exp_hash, &ten, tmp, &p, &maxctx, &status);
4573     }
4574     else {
4575         /* inv10_p**(-exp(v)) % p */
4576         mpd_qsset_ssize(tmp, -exp, &maxctx, &status);
4577         mpd_qpowmod(exp_hash, &inv10_p, tmp, &p, &maxctx, &status);
4578     }
4579 
4580     /* hash = (int(v) * exp_hash) % p */
4581     if (!mpd_qcopy(tmp, MPD(v), &status)) {
4582         goto malloc_error;
4583     }
4584     tmp->exp = 0;
4585     mpd_set_positive(tmp);
4586 
4587     maxctx.prec = MPD_MAX_PREC + 21;
4588     maxctx.emax = MPD_MAX_EMAX + 21;
4589     maxctx.emin = MPD_MIN_EMIN - 21;
4590 
4591     mpd_qmul(tmp, tmp, exp_hash, &maxctx, &status);
4592     mpd_qrem(tmp, tmp, &p, &maxctx, &status);
4593 
4594     result = mpd_qget_ssize(tmp, &status);
4595     result = mpd_ispositive(MPD(v)) ? result : -result;
4596     result = (result == -1) ? -2 : result;
4597 
4598     if (status != 0) {
4599         if (status & MPD_Malloc_error) {
4600             goto malloc_error;
4601         }
4602         else {
4603             PyErr_SetString(PyExc_RuntimeError, /* GCOV_NOT_REACHED */
4604                 "dec_hash: internal error: please report"); /* GCOV_NOT_REACHED */
4605         }
4606         result = -1; /* GCOV_NOT_REACHED */
4607     }
4608 
4609 
4610 finish:
4611     if (exp_hash) mpd_del(exp_hash);
4612     if (tmp) mpd_del(tmp);
4613     return result;
4614 
4615 malloc_error:
4616     PyErr_NoMemory();
4617     result = -1;
4618     goto finish;
4619 }
4620 
4621 static Py_hash_t
dec_hash(PyDecObject * self)4622 dec_hash(PyDecObject *self)
4623 {
4624     if (self->hash == -1) {
4625         self->hash = _dec_hash(self);
4626     }
4627 
4628     return self->hash;
4629 }
4630 
4631 /* __reduce__ */
4632 static PyObject *
dec_reduce(PyObject * self,PyObject * dummy UNUSED)4633 dec_reduce(PyObject *self, PyObject *dummy UNUSED)
4634 {
4635     PyObject *result, *str;
4636 
4637     str = dec_str(self);
4638     if (str == NULL) {
4639         return NULL;
4640     }
4641 
4642     result = Py_BuildValue("O(O)", Py_TYPE(self), str);
4643     Py_DECREF(str);
4644 
4645     return result;
4646 }
4647 
4648 /* __sizeof__ */
4649 static PyObject *
dec_sizeof(PyObject * v,PyObject * dummy UNUSED)4650 dec_sizeof(PyObject *v, PyObject *dummy UNUSED)
4651 {
4652     Py_ssize_t res;
4653 
4654     res = _PyObject_SIZE(Py_TYPE(v));
4655     if (mpd_isdynamic_data(MPD(v))) {
4656         res += MPD(v)->alloc * sizeof(mpd_uint_t);
4657     }
4658     return PyLong_FromSsize_t(res);
4659 }
4660 
4661 /* __trunc__ */
4662 static PyObject *
dec_trunc(PyObject * self,PyObject * dummy UNUSED)4663 dec_trunc(PyObject *self, PyObject *dummy UNUSED)
4664 {
4665     PyObject *context;
4666 
4667     CURRENT_CONTEXT(context);
4668     return dec_as_long(self, context, MPD_ROUND_DOWN);
4669 }
4670 
4671 /* real and imag */
4672 static PyObject *
dec_real(PyObject * self,void * closure UNUSED)4673 dec_real(PyObject *self, void *closure UNUSED)
4674 {
4675     Py_INCREF(self);
4676     return self;
4677 }
4678 
4679 static PyObject *
dec_imag(PyObject * self UNUSED,void * closure UNUSED)4680 dec_imag(PyObject *self UNUSED, void *closure UNUSED)
4681 {
4682     PyObject *result;
4683 
4684     result = dec_alloc();
4685     if (result == NULL) {
4686         return NULL;
4687     }
4688 
4689     _dec_settriple(result, MPD_POS, 0, 0);
4690     return result;
4691 }
4692 
4693 
4694 static PyGetSetDef dec_getsets [] =
4695 {
4696   { "real", (getter)dec_real, NULL, NULL, NULL},
4697   { "imag", (getter)dec_imag, NULL, NULL, NULL},
4698   {NULL}
4699 };
4700 
4701 static PyNumberMethods dec_number_methods =
4702 {
4703     (binaryfunc) nm_mpd_qadd,
4704     (binaryfunc) nm_mpd_qsub,
4705     (binaryfunc) nm_mpd_qmul,
4706     (binaryfunc) nm_mpd_qrem,
4707     (binaryfunc) nm_mpd_qdivmod,
4708     (ternaryfunc) nm_mpd_qpow,
4709     (unaryfunc) nm_mpd_qminus,
4710     (unaryfunc) nm_mpd_qplus,
4711     (unaryfunc) nm_mpd_qabs,
4712     (inquiry) nm_nonzero,
4713     (unaryfunc) 0,   /* no bit-complement */
4714     (binaryfunc) 0,  /* no shiftl */
4715     (binaryfunc) 0,  /* no shiftr */
4716     (binaryfunc) 0,  /* no bit-and */
4717     (binaryfunc) 0,  /* no bit-xor */
4718     (binaryfunc) 0,  /* no bit-ior */
4719     (unaryfunc) nm_dec_as_long,
4720     0,               /* nb_reserved */
4721     (unaryfunc) PyDec_AsFloat,
4722     0,               /* binaryfunc nb_inplace_add; */
4723     0,               /* binaryfunc nb_inplace_subtract; */
4724     0,               /* binaryfunc nb_inplace_multiply; */
4725     0,               /* binaryfunc nb_inplace_remainder; */
4726     0,               /* ternaryfunc nb_inplace_power; */
4727     0,               /* binaryfunc nb_inplace_lshift; */
4728     0,               /* binaryfunc nb_inplace_rshift; */
4729     0,               /* binaryfunc nb_inplace_and; */
4730     0,               /* binaryfunc nb_inplace_xor; */
4731     0,               /* binaryfunc nb_inplace_or; */
4732     (binaryfunc) nm_mpd_qdivint,  /* binaryfunc nb_floor_divide; */
4733     (binaryfunc) nm_mpd_qdiv,     /* binaryfunc nb_true_divide; */
4734     0,               /* binaryfunc nb_inplace_floor_divide; */
4735     0,               /* binaryfunc nb_inplace_true_divide; */
4736 };
4737 
4738 static PyMethodDef dec_methods [] =
4739 {
4740   /* Unary arithmetic functions, optional context arg */
4741   { "exp", (PyCFunction)dec_mpd_qexp, METH_VARARGS|METH_KEYWORDS, doc_exp },
4742   { "ln", (PyCFunction)dec_mpd_qln, METH_VARARGS|METH_KEYWORDS, doc_ln },
4743   { "log10", (PyCFunction)dec_mpd_qlog10, METH_VARARGS|METH_KEYWORDS, doc_log10 },
4744   { "next_minus", (PyCFunction)dec_mpd_qnext_minus, METH_VARARGS|METH_KEYWORDS, doc_next_minus },
4745   { "next_plus", (PyCFunction)dec_mpd_qnext_plus, METH_VARARGS|METH_KEYWORDS, doc_next_plus },
4746   { "normalize", (PyCFunction)dec_mpd_qreduce, METH_VARARGS|METH_KEYWORDS, doc_normalize },
4747   { "to_integral", (PyCFunction)PyDec_ToIntegralValue, METH_VARARGS|METH_KEYWORDS, doc_to_integral },
4748   { "to_integral_exact", (PyCFunction)PyDec_ToIntegralExact, METH_VARARGS|METH_KEYWORDS, doc_to_integral_exact },
4749   { "to_integral_value", (PyCFunction)PyDec_ToIntegralValue, METH_VARARGS|METH_KEYWORDS, doc_to_integral_value },
4750   { "sqrt", (PyCFunction)dec_mpd_qsqrt, METH_VARARGS|METH_KEYWORDS, doc_sqrt },
4751 
4752   /* Binary arithmetic functions, optional context arg */
4753   { "compare", (PyCFunction)dec_mpd_qcompare, METH_VARARGS|METH_KEYWORDS, doc_compare },
4754   { "compare_signal", (PyCFunction)dec_mpd_qcompare_signal, METH_VARARGS|METH_KEYWORDS, doc_compare_signal },
4755   { "max", (PyCFunction)dec_mpd_qmax, METH_VARARGS|METH_KEYWORDS, doc_max },
4756   { "max_mag", (PyCFunction)dec_mpd_qmax_mag, METH_VARARGS|METH_KEYWORDS, doc_max_mag },
4757   { "min", (PyCFunction)dec_mpd_qmin, METH_VARARGS|METH_KEYWORDS, doc_min },
4758   { "min_mag", (PyCFunction)dec_mpd_qmin_mag, METH_VARARGS|METH_KEYWORDS, doc_min_mag },
4759   { "next_toward", (PyCFunction)dec_mpd_qnext_toward, METH_VARARGS|METH_KEYWORDS, doc_next_toward },
4760   { "quantize", (PyCFunction)dec_mpd_qquantize, METH_VARARGS|METH_KEYWORDS, doc_quantize },
4761   { "remainder_near", (PyCFunction)dec_mpd_qrem_near, METH_VARARGS|METH_KEYWORDS, doc_remainder_near },
4762 
4763   /* Ternary arithmetic functions, optional context arg */
4764   { "fma", (PyCFunction)dec_mpd_qfma, METH_VARARGS|METH_KEYWORDS, doc_fma },
4765 
4766   /* Boolean functions, no context arg */
4767   { "is_canonical", dec_mpd_iscanonical, METH_NOARGS, doc_is_canonical },
4768   { "is_finite", dec_mpd_isfinite, METH_NOARGS, doc_is_finite },
4769   { "is_infinite", dec_mpd_isinfinite, METH_NOARGS, doc_is_infinite },
4770   { "is_nan", dec_mpd_isnan, METH_NOARGS, doc_is_nan },
4771   { "is_qnan", dec_mpd_isqnan, METH_NOARGS, doc_is_qnan },
4772   { "is_snan", dec_mpd_issnan, METH_NOARGS, doc_is_snan },
4773   { "is_signed", dec_mpd_issigned, METH_NOARGS, doc_is_signed },
4774   { "is_zero", dec_mpd_iszero, METH_NOARGS, doc_is_zero },
4775 
4776   /* Boolean functions, optional context arg */
4777   { "is_normal", (PyCFunction)dec_mpd_isnormal, METH_VARARGS|METH_KEYWORDS, doc_is_normal },
4778   { "is_subnormal", (PyCFunction)dec_mpd_issubnormal, METH_VARARGS|METH_KEYWORDS, doc_is_subnormal },
4779 
4780   /* Unary functions, no context arg */
4781   { "adjusted", dec_mpd_adjexp, METH_NOARGS, doc_adjusted },
4782   { "canonical", dec_canonical, METH_NOARGS, doc_canonical },
4783   { "conjugate", dec_conjugate, METH_NOARGS, doc_conjugate },
4784   { "radix", dec_mpd_radix, METH_NOARGS, doc_radix },
4785 
4786   /* Unary functions, optional context arg for conversion errors */
4787   { "copy_abs", dec_mpd_qcopy_abs, METH_NOARGS, doc_copy_abs },
4788   { "copy_negate", dec_mpd_qcopy_negate, METH_NOARGS, doc_copy_negate },
4789 
4790   /* Unary functions, optional context arg */
4791   { "logb", (PyCFunction)dec_mpd_qlogb, METH_VARARGS|METH_KEYWORDS, doc_logb },
4792   { "logical_invert", (PyCFunction)dec_mpd_qinvert, METH_VARARGS|METH_KEYWORDS, doc_logical_invert },
4793   { "number_class", (PyCFunction)dec_mpd_class, METH_VARARGS|METH_KEYWORDS, doc_number_class },
4794   { "to_eng_string", (PyCFunction)dec_mpd_to_eng, METH_VARARGS|METH_KEYWORDS, doc_to_eng_string },
4795 
4796   /* Binary functions, optional context arg for conversion errors */
4797   { "compare_total", (PyCFunction)dec_mpd_compare_total, METH_VARARGS|METH_KEYWORDS, doc_compare_total },
4798   { "compare_total_mag", (PyCFunction)dec_mpd_compare_total_mag, METH_VARARGS|METH_KEYWORDS, doc_compare_total_mag },
4799   { "copy_sign", (PyCFunction)dec_mpd_qcopy_sign, METH_VARARGS|METH_KEYWORDS, doc_copy_sign },
4800   { "same_quantum", (PyCFunction)dec_mpd_same_quantum, METH_VARARGS|METH_KEYWORDS, doc_same_quantum },
4801 
4802   /* Binary functions, optional context arg */
4803   { "logical_and", (PyCFunction)dec_mpd_qand, METH_VARARGS|METH_KEYWORDS, doc_logical_and },
4804   { "logical_or", (PyCFunction)dec_mpd_qor, METH_VARARGS|METH_KEYWORDS, doc_logical_or },
4805   { "logical_xor", (PyCFunction)dec_mpd_qxor, METH_VARARGS|METH_KEYWORDS, doc_logical_xor },
4806   { "rotate", (PyCFunction)dec_mpd_qrotate, METH_VARARGS|METH_KEYWORDS, doc_rotate },
4807   { "scaleb", (PyCFunction)dec_mpd_qscaleb, METH_VARARGS|METH_KEYWORDS, doc_scaleb },
4808   { "shift", (PyCFunction)dec_mpd_qshift, METH_VARARGS|METH_KEYWORDS, doc_shift },
4809 
4810   /* Miscellaneous */
4811   { "from_float", dec_from_float, METH_O|METH_CLASS, doc_from_float },
4812   { "as_tuple", PyDec_AsTuple, METH_NOARGS, doc_as_tuple },
4813   { "as_integer_ratio", dec_as_integer_ratio, METH_NOARGS, doc_as_integer_ratio },
4814 
4815   /* Special methods */
4816   { "__copy__", dec_copy, METH_NOARGS, NULL },
4817   { "__deepcopy__", dec_copy, METH_O, NULL },
4818   { "__format__", dec_format, METH_VARARGS, NULL },
4819   { "__reduce__", dec_reduce, METH_NOARGS, NULL },
4820   { "__round__", PyDec_Round, METH_VARARGS, NULL },
4821   { "__ceil__", dec_ceil, METH_NOARGS, NULL },
4822   { "__floor__", dec_floor, METH_NOARGS, NULL },
4823   { "__trunc__", dec_trunc, METH_NOARGS, NULL },
4824   { "__complex__", dec_complex, METH_NOARGS, NULL },
4825   { "__sizeof__", dec_sizeof, METH_NOARGS, NULL },
4826 
4827   { NULL, NULL, 1 }
4828 };
4829 
4830 static PyTypeObject PyDec_Type =
4831 {
4832     PyVarObject_HEAD_INIT(NULL, 0)
4833     "decimal.Decimal",                      /* tp_name */
4834     sizeof(PyDecObject),                    /* tp_basicsize */
4835     0,                                      /* tp_itemsize */
4836     (destructor) dec_dealloc,               /* tp_dealloc */
4837     0,                                      /* tp_print */
4838     (getattrfunc) 0,                        /* tp_getattr */
4839     (setattrfunc) 0,                        /* tp_setattr */
4840     0,                                      /* tp_reserved */
4841     (reprfunc) dec_repr,                    /* tp_repr */
4842     &dec_number_methods,                    /* tp_as_number */
4843     0,                                      /* tp_as_sequence */
4844     0,                                      /* tp_as_mapping */
4845     (hashfunc) dec_hash,                    /* tp_hash */
4846     0,                                      /* tp_call */
4847     (reprfunc) dec_str,                     /* tp_str */
4848     (getattrofunc) PyObject_GenericGetAttr, /* tp_getattro */
4849     (setattrofunc) 0,                       /* tp_setattro */
4850     (PyBufferProcs *) 0,                    /* tp_as_buffer */
4851     (Py_TPFLAGS_DEFAULT|
4852      Py_TPFLAGS_BASETYPE),                  /* tp_flags */
4853     doc_decimal,                            /* tp_doc */
4854     0,                                      /* tp_traverse */
4855     0,                                      /* tp_clear */
4856     dec_richcompare,                        /* tp_richcompare */
4857     0,                                      /* tp_weaklistoffset */
4858     0,                                      /* tp_iter */
4859     0,                                      /* tp_iternext */
4860     dec_methods,                            /* tp_methods */
4861     0,                                      /* tp_members */
4862     dec_getsets,                            /* tp_getset */
4863     0,                                      /* tp_base */
4864     0,                                      /* tp_dict */
4865     0,                                      /* tp_descr_get */
4866     0,                                      /* tp_descr_set */
4867     0,                                      /* tp_dictoffset */
4868     0,                                      /* tp_init */
4869     0,                                      /* tp_alloc */
4870     dec_new,                                /* tp_new */
4871     PyObject_Del,                           /* tp_free */
4872 };
4873 
4874 
4875 /******************************************************************************/
4876 /*                         Context Object, Part 2                             */
4877 /******************************************************************************/
4878 
4879 
4880 /************************************************************************/
4881 /*     Macros for converting mpdecimal functions to Context methods     */
4882 /************************************************************************/
4883 
4884 /* Boolean context method. */
4885 #define DecCtx_BoolFunc(MPDFUNC) \
4886 static PyObject *                                                     \
4887 ctx_##MPDFUNC(PyObject *context, PyObject *v)                         \
4888 {                                                                     \
4889     PyObject *ret;                                                    \
4890     PyObject *a;                                                      \
4891                                                                       \
4892     CONVERT_OP_RAISE(&a, v, context);                                 \
4893                                                                       \
4894     ret = MPDFUNC(MPD(a), CTX(context)) ? incr_true() : incr_false(); \
4895     Py_DECREF(a);                                                     \
4896     return ret;                                                       \
4897 }
4898 
4899 /* Boolean context method. MPDFUNC does NOT use a context. */
4900 #define DecCtx_BoolFunc_NO_CTX(MPDFUNC) \
4901 static PyObject *                                       \
4902 ctx_##MPDFUNC(PyObject *context, PyObject *v)           \
4903 {                                                       \
4904     PyObject *ret;                                      \
4905     PyObject *a;                                        \
4906                                                         \
4907     CONVERT_OP_RAISE(&a, v, context);                   \
4908                                                         \
4909     ret = MPDFUNC(MPD(a)) ? incr_true() : incr_false(); \
4910     Py_DECREF(a);                                       \
4911     return ret;                                         \
4912 }
4913 
4914 /* Unary context method. */
4915 #define DecCtx_UnaryFunc(MPDFUNC) \
4916 static PyObject *                                        \
4917 ctx_##MPDFUNC(PyObject *context, PyObject *v)            \
4918 {                                                        \
4919     PyObject *result, *a;                                \
4920     uint32_t status = 0;                                 \
4921                                                          \
4922     CONVERT_OP_RAISE(&a, v, context);                    \
4923                                                          \
4924     if ((result = dec_alloc()) == NULL) {                \
4925         Py_DECREF(a);                                    \
4926         return NULL;                                     \
4927     }                                                    \
4928                                                          \
4929     MPDFUNC(MPD(result), MPD(a), CTX(context), &status); \
4930     Py_DECREF(a);                                        \
4931     if (dec_addstatus(context, status)) {                \
4932         Py_DECREF(result);                               \
4933         return NULL;                                     \
4934     }                                                    \
4935                                                          \
4936     return result;                                       \
4937 }
4938 
4939 /* Binary context method. */
4940 #define DecCtx_BinaryFunc(MPDFUNC) \
4941 static PyObject *                                                \
4942 ctx_##MPDFUNC(PyObject *context, PyObject *args)                 \
4943 {                                                                \
4944     PyObject *v, *w;                                             \
4945     PyObject *a, *b;                                             \
4946     PyObject *result;                                            \
4947     uint32_t status = 0;                                         \
4948                                                                  \
4949     if (!PyArg_ParseTuple(args, "OO", &v, &w)) {                 \
4950         return NULL;                                             \
4951     }                                                            \
4952                                                                  \
4953     CONVERT_BINOP_RAISE(&a, &b, v, w, context);                  \
4954                                                                  \
4955     if ((result = dec_alloc()) == NULL) {                        \
4956         Py_DECREF(a);                                            \
4957         Py_DECREF(b);                                            \
4958         return NULL;                                             \
4959     }                                                            \
4960                                                                  \
4961     MPDFUNC(MPD(result), MPD(a), MPD(b), CTX(context), &status); \
4962     Py_DECREF(a);                                                \
4963     Py_DECREF(b);                                                \
4964     if (dec_addstatus(context, status)) {                        \
4965         Py_DECREF(result);                                       \
4966         return NULL;                                             \
4967     }                                                            \
4968                                                                  \
4969     return result;                                               \
4970 }
4971 
4972 /*
4973  * Binary context method. The context is only used for conversion.
4974  * The actual MPDFUNC does NOT take a context arg.
4975  */
4976 #define DecCtx_BinaryFunc_NO_CTX(MPDFUNC) \
4977 static PyObject *                                \
4978 ctx_##MPDFUNC(PyObject *context, PyObject *args) \
4979 {                                                \
4980     PyObject *v, *w;                             \
4981     PyObject *a, *b;                             \
4982     PyObject *result;                            \
4983                                                  \
4984     if (!PyArg_ParseTuple(args, "OO", &v, &w)) { \
4985         return NULL;                             \
4986     }                                            \
4987                                                  \
4988     CONVERT_BINOP_RAISE(&a, &b, v, w, context);  \
4989                                                  \
4990     if ((result = dec_alloc()) == NULL) {        \
4991         Py_DECREF(a);                            \
4992         Py_DECREF(b);                            \
4993         return NULL;                             \
4994     }                                            \
4995                                                  \
4996     MPDFUNC(MPD(result), MPD(a), MPD(b));        \
4997     Py_DECREF(a);                                \
4998     Py_DECREF(b);                                \
4999                                                  \
5000     return result;                               \
5001 }
5002 
5003 /* Ternary context method. */
5004 #define DecCtx_TernaryFunc(MPDFUNC) \
5005 static PyObject *                                                        \
5006 ctx_##MPDFUNC(PyObject *context, PyObject *args)                         \
5007 {                                                                        \
5008     PyObject *v, *w, *x;                                                 \
5009     PyObject *a, *b, *c;                                                 \
5010     PyObject *result;                                                    \
5011     uint32_t status = 0;                                                 \
5012                                                                          \
5013     if (!PyArg_ParseTuple(args, "OOO", &v, &w, &x)) {                    \
5014         return NULL;                                                     \
5015     }                                                                    \
5016                                                                          \
5017     CONVERT_TERNOP_RAISE(&a, &b, &c, v, w, x, context);                  \
5018                                                                          \
5019     if ((result = dec_alloc()) == NULL) {                                \
5020         Py_DECREF(a);                                                    \
5021         Py_DECREF(b);                                                    \
5022         Py_DECREF(c);                                                    \
5023         return NULL;                                                     \
5024     }                                                                    \
5025                                                                          \
5026     MPDFUNC(MPD(result), MPD(a), MPD(b), MPD(c), CTX(context), &status); \
5027     Py_DECREF(a);                                                        \
5028     Py_DECREF(b);                                                        \
5029     Py_DECREF(c);                                                        \
5030     if (dec_addstatus(context, status)) {                                \
5031         Py_DECREF(result);                                               \
5032         return NULL;                                                     \
5033     }                                                                    \
5034                                                                          \
5035     return result;                                                       \
5036 }
5037 
5038 
5039 /* Unary arithmetic functions */
5040 DecCtx_UnaryFunc(mpd_qabs)
DecCtx_UnaryFunc(mpd_qexp)5041 DecCtx_UnaryFunc(mpd_qexp)
5042 DecCtx_UnaryFunc(mpd_qln)
5043 DecCtx_UnaryFunc(mpd_qlog10)
5044 DecCtx_UnaryFunc(mpd_qminus)
5045 DecCtx_UnaryFunc(mpd_qnext_minus)
5046 DecCtx_UnaryFunc(mpd_qnext_plus)
5047 DecCtx_UnaryFunc(mpd_qplus)
5048 DecCtx_UnaryFunc(mpd_qreduce)
5049 DecCtx_UnaryFunc(mpd_qround_to_int)
5050 DecCtx_UnaryFunc(mpd_qround_to_intx)
5051 DecCtx_UnaryFunc(mpd_qsqrt)
5052 
5053 /* Binary arithmetic functions */
5054 DecCtx_BinaryFunc(mpd_qadd)
5055 DecCtx_BinaryFunc(mpd_qcompare)
5056 DecCtx_BinaryFunc(mpd_qcompare_signal)
5057 DecCtx_BinaryFunc(mpd_qdiv)
5058 DecCtx_BinaryFunc(mpd_qdivint)
5059 DecCtx_BinaryFunc(mpd_qmax)
5060 DecCtx_BinaryFunc(mpd_qmax_mag)
5061 DecCtx_BinaryFunc(mpd_qmin)
5062 DecCtx_BinaryFunc(mpd_qmin_mag)
5063 DecCtx_BinaryFunc(mpd_qmul)
5064 DecCtx_BinaryFunc(mpd_qnext_toward)
5065 DecCtx_BinaryFunc(mpd_qquantize)
5066 DecCtx_BinaryFunc(mpd_qrem)
5067 DecCtx_BinaryFunc(mpd_qrem_near)
5068 DecCtx_BinaryFunc(mpd_qsub)
5069 
5070 static PyObject *
5071 ctx_mpd_qdivmod(PyObject *context, PyObject *args)
5072 {
5073     PyObject *v, *w;
5074     PyObject *a, *b;
5075     PyObject *q, *r;
5076     uint32_t status = 0;
5077     PyObject *ret;
5078 
5079     if (!PyArg_ParseTuple(args, "OO", &v, &w)) {
5080         return NULL;
5081     }
5082 
5083     CONVERT_BINOP_RAISE(&a, &b, v, w, context);
5084 
5085     q = dec_alloc();
5086     if (q == NULL) {
5087         Py_DECREF(a);
5088         Py_DECREF(b);
5089         return NULL;
5090     }
5091     r = dec_alloc();
5092     if (r == NULL) {
5093         Py_DECREF(a);
5094         Py_DECREF(b);
5095         Py_DECREF(q);
5096         return NULL;
5097     }
5098 
5099     mpd_qdivmod(MPD(q), MPD(r), MPD(a), MPD(b), CTX(context), &status);
5100     Py_DECREF(a);
5101     Py_DECREF(b);
5102     if (dec_addstatus(context, status)) {
5103         Py_DECREF(r);
5104         Py_DECREF(q);
5105         return NULL;
5106     }
5107 
5108     ret = Py_BuildValue("(OO)", q, r);
5109     Py_DECREF(r);
5110     Py_DECREF(q);
5111     return ret;
5112 }
5113 
5114 /* Binary or ternary arithmetic functions */
5115 static PyObject *
ctx_mpd_qpow(PyObject * context,PyObject * args,PyObject * kwds)5116 ctx_mpd_qpow(PyObject *context, PyObject *args, PyObject *kwds)
5117 {
5118     static char *kwlist[] = {"a", "b", "modulo", NULL};
5119     PyObject *base, *exp, *mod = Py_None;
5120     PyObject *a, *b, *c = NULL;
5121     PyObject *result;
5122     uint32_t status = 0;
5123 
5124     if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|O", kwlist,
5125                                      &base, &exp, &mod)) {
5126         return NULL;
5127     }
5128 
5129     CONVERT_BINOP_RAISE(&a, &b, base, exp, context);
5130 
5131     if (mod != Py_None) {
5132         if (!convert_op(TYPE_ERR, &c, mod, context)) {
5133             Py_DECREF(a);
5134             Py_DECREF(b);
5135             return c;
5136         }
5137     }
5138 
5139     result = dec_alloc();
5140     if (result == NULL) {
5141         Py_DECREF(a);
5142         Py_DECREF(b);
5143         Py_XDECREF(c);
5144         return NULL;
5145     }
5146 
5147     if (c == NULL) {
5148         mpd_qpow(MPD(result), MPD(a), MPD(b),
5149                  CTX(context), &status);
5150     }
5151     else {
5152         mpd_qpowmod(MPD(result), MPD(a), MPD(b), MPD(c),
5153                     CTX(context), &status);
5154         Py_DECREF(c);
5155     }
5156     Py_DECREF(a);
5157     Py_DECREF(b);
5158     if (dec_addstatus(context, status)) {
5159         Py_DECREF(result);
5160         return NULL;
5161     }
5162 
5163     return result;
5164 }
5165 
5166 /* Ternary arithmetic functions */
DecCtx_TernaryFunc(mpd_qfma)5167 DecCtx_TernaryFunc(mpd_qfma)
5168 
5169 /* No argument */
5170 static PyObject *
5171 ctx_mpd_radix(PyObject *context, PyObject *dummy)
5172 {
5173     return dec_mpd_radix(context, dummy);
5174 }
5175 
5176 /* Boolean functions: single decimal argument */
5177 DecCtx_BoolFunc(mpd_isnormal)
DecCtx_BoolFunc(mpd_issubnormal)5178 DecCtx_BoolFunc(mpd_issubnormal)
5179 DecCtx_BoolFunc_NO_CTX(mpd_isfinite)
5180 DecCtx_BoolFunc_NO_CTX(mpd_isinfinite)
5181 DecCtx_BoolFunc_NO_CTX(mpd_isnan)
5182 DecCtx_BoolFunc_NO_CTX(mpd_isqnan)
5183 DecCtx_BoolFunc_NO_CTX(mpd_issigned)
5184 DecCtx_BoolFunc_NO_CTX(mpd_issnan)
5185 DecCtx_BoolFunc_NO_CTX(mpd_iszero)
5186 
5187 static PyObject *
5188 ctx_iscanonical(PyObject *context UNUSED, PyObject *v)
5189 {
5190     if (!PyDec_Check(v)) {
5191         PyErr_SetString(PyExc_TypeError,
5192             "argument must be a Decimal");
5193         return NULL;
5194     }
5195 
5196     return mpd_iscanonical(MPD(v)) ? incr_true() : incr_false();
5197 }
5198 
5199 /* Functions with a single decimal argument */
5200 static PyObject *
PyDecContext_Apply(PyObject * context,PyObject * v)5201 PyDecContext_Apply(PyObject *context, PyObject *v)
5202 {
5203     PyObject *result, *a;
5204 
5205     CONVERT_OP_RAISE(&a, v, context);
5206 
5207     result = dec_apply(a, context);
5208     Py_DECREF(a);
5209     return result;
5210 }
5211 
5212 static PyObject *
ctx_canonical(PyObject * context UNUSED,PyObject * v)5213 ctx_canonical(PyObject *context UNUSED, PyObject *v)
5214 {
5215     if (!PyDec_Check(v)) {
5216         PyErr_SetString(PyExc_TypeError,
5217             "argument must be a Decimal");
5218         return NULL;
5219     }
5220 
5221     Py_INCREF(v);
5222     return v;
5223 }
5224 
5225 static PyObject *
ctx_mpd_qcopy_abs(PyObject * context,PyObject * v)5226 ctx_mpd_qcopy_abs(PyObject *context, PyObject *v)
5227 {
5228     PyObject *result, *a;
5229     uint32_t status = 0;
5230 
5231     CONVERT_OP_RAISE(&a, v, context);
5232 
5233     result = dec_alloc();
5234     if (result == NULL) {
5235         Py_DECREF(a);
5236         return NULL;
5237     }
5238 
5239     mpd_qcopy_abs(MPD(result), MPD(a), &status);
5240     Py_DECREF(a);
5241     if (dec_addstatus(context, status)) {
5242         Py_DECREF(result);
5243         return NULL;
5244     }
5245 
5246     return result;
5247 }
5248 
5249 static PyObject *
ctx_copy_decimal(PyObject * context,PyObject * v)5250 ctx_copy_decimal(PyObject *context, PyObject *v)
5251 {
5252     PyObject *result;
5253 
5254     CONVERT_OP_RAISE(&result, v, context);
5255     return result;
5256 }
5257 
5258 static PyObject *
ctx_mpd_qcopy_negate(PyObject * context,PyObject * v)5259 ctx_mpd_qcopy_negate(PyObject *context, PyObject *v)
5260 {
5261     PyObject *result, *a;
5262     uint32_t status = 0;
5263 
5264     CONVERT_OP_RAISE(&a, v, context);
5265 
5266     result = dec_alloc();
5267     if (result == NULL) {
5268         Py_DECREF(a);
5269         return NULL;
5270     }
5271 
5272     mpd_qcopy_negate(MPD(result), MPD(a), &status);
5273     Py_DECREF(a);
5274     if (dec_addstatus(context, status)) {
5275         Py_DECREF(result);
5276         return NULL;
5277     }
5278 
5279     return result;
5280 }
5281 
5282 DecCtx_UnaryFunc(mpd_qlogb)
DecCtx_UnaryFunc(mpd_qinvert)5283 DecCtx_UnaryFunc(mpd_qinvert)
5284 
5285 static PyObject *
5286 ctx_mpd_class(PyObject *context, PyObject *v)
5287 {
5288     PyObject *a;
5289     const char *cp;
5290 
5291     CONVERT_OP_RAISE(&a, v, context);
5292 
5293     cp = mpd_class(MPD(a), CTX(context));
5294     Py_DECREF(a);
5295 
5296     return PyUnicode_FromString(cp);
5297 }
5298 
5299 static PyObject *
ctx_mpd_to_sci(PyObject * context,PyObject * v)5300 ctx_mpd_to_sci(PyObject *context, PyObject *v)
5301 {
5302     PyObject *result;
5303     PyObject *a;
5304     mpd_ssize_t size;
5305     char *s;
5306 
5307     CONVERT_OP_RAISE(&a, v, context);
5308 
5309     size = mpd_to_sci_size(&s, MPD(a), CtxCaps(context));
5310     Py_DECREF(a);
5311     if (size < 0) {
5312         PyErr_NoMemory();
5313         return NULL;
5314     }
5315 
5316     result = unicode_fromascii(s, size);
5317     mpd_free(s);
5318 
5319     return result;
5320 }
5321 
5322 static PyObject *
ctx_mpd_to_eng(PyObject * context,PyObject * v)5323 ctx_mpd_to_eng(PyObject *context, PyObject *v)
5324 {
5325     PyObject *result;
5326     PyObject *a;
5327     mpd_ssize_t size;
5328     char *s;
5329 
5330     CONVERT_OP_RAISE(&a, v, context);
5331 
5332     size = mpd_to_eng_size(&s, MPD(a), CtxCaps(context));
5333     Py_DECREF(a);
5334     if (size < 0) {
5335         PyErr_NoMemory();
5336         return NULL;
5337     }
5338 
5339     result = unicode_fromascii(s, size);
5340     mpd_free(s);
5341 
5342     return result;
5343 }
5344 
5345 /* Functions with two decimal arguments */
5346 DecCtx_BinaryFunc_NO_CTX(mpd_compare_total)
DecCtx_BinaryFunc_NO_CTX(mpd_compare_total_mag)5347 DecCtx_BinaryFunc_NO_CTX(mpd_compare_total_mag)
5348 
5349 static PyObject *
5350 ctx_mpd_qcopy_sign(PyObject *context, PyObject *args)
5351 {
5352     PyObject *v, *w;
5353     PyObject *a, *b;
5354     PyObject *result;
5355     uint32_t status = 0;
5356 
5357     if (!PyArg_ParseTuple(args, "OO", &v, &w)) {
5358         return NULL;
5359     }
5360 
5361     CONVERT_BINOP_RAISE(&a, &b, v, w, context);
5362 
5363     result = dec_alloc();
5364     if (result == NULL) {
5365         Py_DECREF(a);
5366         Py_DECREF(b);
5367         return NULL;
5368     }
5369 
5370     mpd_qcopy_sign(MPD(result), MPD(a), MPD(b), &status);
5371     Py_DECREF(a);
5372     Py_DECREF(b);
5373     if (dec_addstatus(context, status)) {
5374         Py_DECREF(result);
5375         return NULL;
5376     }
5377 
5378     return result;
5379 }
5380 
5381 DecCtx_BinaryFunc(mpd_qand)
DecCtx_BinaryFunc(mpd_qor)5382 DecCtx_BinaryFunc(mpd_qor)
5383 DecCtx_BinaryFunc(mpd_qxor)
5384 
5385 DecCtx_BinaryFunc(mpd_qrotate)
5386 DecCtx_BinaryFunc(mpd_qscaleb)
5387 DecCtx_BinaryFunc(mpd_qshift)
5388 
5389 static PyObject *
5390 ctx_mpd_same_quantum(PyObject *context, PyObject *args)
5391 {
5392     PyObject *v, *w;
5393     PyObject *a, *b;
5394     PyObject *result;
5395 
5396     if (!PyArg_ParseTuple(args, "OO", &v, &w)) {
5397         return NULL;
5398     }
5399 
5400     CONVERT_BINOP_RAISE(&a, &b, v, w, context);
5401 
5402     result = mpd_same_quantum(MPD(a), MPD(b)) ? incr_true() : incr_false();
5403     Py_DECREF(a);
5404     Py_DECREF(b);
5405 
5406     return result;
5407 }
5408 
5409 
5410 static PyMethodDef context_methods [] =
5411 {
5412   /* Unary arithmetic functions */
5413   { "abs", ctx_mpd_qabs, METH_O, doc_ctx_abs },
5414   { "exp", ctx_mpd_qexp, METH_O, doc_ctx_exp },
5415   { "ln", ctx_mpd_qln, METH_O, doc_ctx_ln },
5416   { "log10", ctx_mpd_qlog10, METH_O, doc_ctx_log10 },
5417   { "minus", ctx_mpd_qminus, METH_O, doc_ctx_minus },
5418   { "next_minus", ctx_mpd_qnext_minus, METH_O, doc_ctx_next_minus },
5419   { "next_plus", ctx_mpd_qnext_plus, METH_O, doc_ctx_next_plus },
5420   { "normalize", ctx_mpd_qreduce, METH_O, doc_ctx_normalize },
5421   { "plus", ctx_mpd_qplus, METH_O, doc_ctx_plus },
5422   { "to_integral", ctx_mpd_qround_to_int, METH_O, doc_ctx_to_integral },
5423   { "to_integral_exact", ctx_mpd_qround_to_intx, METH_O, doc_ctx_to_integral_exact },
5424   { "to_integral_value", ctx_mpd_qround_to_int, METH_O, doc_ctx_to_integral_value },
5425   { "sqrt", ctx_mpd_qsqrt, METH_O, doc_ctx_sqrt },
5426 
5427   /* Binary arithmetic functions */
5428   { "add", ctx_mpd_qadd, METH_VARARGS, doc_ctx_add },
5429   { "compare", ctx_mpd_qcompare, METH_VARARGS, doc_ctx_compare },
5430   { "compare_signal", ctx_mpd_qcompare_signal, METH_VARARGS, doc_ctx_compare_signal },
5431   { "divide", ctx_mpd_qdiv, METH_VARARGS, doc_ctx_divide },
5432   { "divide_int", ctx_mpd_qdivint, METH_VARARGS, doc_ctx_divide_int },
5433   { "divmod", ctx_mpd_qdivmod, METH_VARARGS, doc_ctx_divmod },
5434   { "max", ctx_mpd_qmax, METH_VARARGS, doc_ctx_max },
5435   { "max_mag", ctx_mpd_qmax_mag, METH_VARARGS, doc_ctx_max_mag },
5436   { "min", ctx_mpd_qmin, METH_VARARGS, doc_ctx_min },
5437   { "min_mag", ctx_mpd_qmin_mag, METH_VARARGS, doc_ctx_min_mag },
5438   { "multiply", ctx_mpd_qmul, METH_VARARGS, doc_ctx_multiply },
5439   { "next_toward", ctx_mpd_qnext_toward, METH_VARARGS, doc_ctx_next_toward },
5440   { "quantize", ctx_mpd_qquantize, METH_VARARGS, doc_ctx_quantize },
5441   { "remainder", ctx_mpd_qrem, METH_VARARGS, doc_ctx_remainder },
5442   { "remainder_near", ctx_mpd_qrem_near, METH_VARARGS, doc_ctx_remainder_near },
5443   { "subtract", ctx_mpd_qsub, METH_VARARGS, doc_ctx_subtract },
5444 
5445   /* Binary or ternary arithmetic functions */
5446   { "power", (PyCFunction)ctx_mpd_qpow, METH_VARARGS|METH_KEYWORDS, doc_ctx_power },
5447 
5448   /* Ternary arithmetic functions */
5449   { "fma", ctx_mpd_qfma, METH_VARARGS, doc_ctx_fma },
5450 
5451   /* No argument */
5452   { "Etiny", context_getetiny, METH_NOARGS, doc_ctx_Etiny },
5453   { "Etop", context_getetop, METH_NOARGS, doc_ctx_Etop },
5454   { "radix", ctx_mpd_radix, METH_NOARGS, doc_ctx_radix },
5455 
5456   /* Boolean functions */
5457   { "is_canonical", ctx_iscanonical, METH_O, doc_ctx_is_canonical },
5458   { "is_finite", ctx_mpd_isfinite, METH_O, doc_ctx_is_finite },
5459   { "is_infinite", ctx_mpd_isinfinite, METH_O, doc_ctx_is_infinite },
5460   { "is_nan", ctx_mpd_isnan, METH_O, doc_ctx_is_nan },
5461   { "is_normal", ctx_mpd_isnormal, METH_O, doc_ctx_is_normal },
5462   { "is_qnan", ctx_mpd_isqnan, METH_O, doc_ctx_is_qnan },
5463   { "is_signed", ctx_mpd_issigned, METH_O, doc_ctx_is_signed },
5464   { "is_snan", ctx_mpd_issnan, METH_O, doc_ctx_is_snan },
5465   { "is_subnormal", ctx_mpd_issubnormal, METH_O, doc_ctx_is_subnormal },
5466   { "is_zero", ctx_mpd_iszero, METH_O, doc_ctx_is_zero },
5467 
5468   /* Functions with a single decimal argument */
5469   { "_apply", PyDecContext_Apply, METH_O, NULL }, /* alias for apply */
5470 #ifdef EXTRA_FUNCTIONALITY
5471   { "apply", PyDecContext_Apply, METH_O, doc_ctx_apply },
5472 #endif
5473   { "canonical", ctx_canonical, METH_O, doc_ctx_canonical },
5474   { "copy_abs", ctx_mpd_qcopy_abs, METH_O, doc_ctx_copy_abs },
5475   { "copy_decimal", ctx_copy_decimal, METH_O, doc_ctx_copy_decimal },
5476   { "copy_negate", ctx_mpd_qcopy_negate, METH_O, doc_ctx_copy_negate },
5477   { "logb", ctx_mpd_qlogb, METH_O, doc_ctx_logb },
5478   { "logical_invert", ctx_mpd_qinvert, METH_O, doc_ctx_logical_invert },
5479   { "number_class", ctx_mpd_class, METH_O, doc_ctx_number_class },
5480   { "to_sci_string", ctx_mpd_to_sci, METH_O, doc_ctx_to_sci_string },
5481   { "to_eng_string", ctx_mpd_to_eng, METH_O, doc_ctx_to_eng_string },
5482 
5483   /* Functions with two decimal arguments */
5484   { "compare_total", ctx_mpd_compare_total, METH_VARARGS, doc_ctx_compare_total },
5485   { "compare_total_mag", ctx_mpd_compare_total_mag, METH_VARARGS, doc_ctx_compare_total_mag },
5486   { "copy_sign", ctx_mpd_qcopy_sign, METH_VARARGS, doc_ctx_copy_sign },
5487   { "logical_and", ctx_mpd_qand, METH_VARARGS, doc_ctx_logical_and },
5488   { "logical_or", ctx_mpd_qor, METH_VARARGS, doc_ctx_logical_or },
5489   { "logical_xor", ctx_mpd_qxor, METH_VARARGS, doc_ctx_logical_xor },
5490   { "rotate", ctx_mpd_qrotate, METH_VARARGS, doc_ctx_rotate },
5491   { "same_quantum", ctx_mpd_same_quantum, METH_VARARGS, doc_ctx_same_quantum },
5492   { "scaleb", ctx_mpd_qscaleb, METH_VARARGS, doc_ctx_scaleb },
5493   { "shift", ctx_mpd_qshift, METH_VARARGS, doc_ctx_shift },
5494 
5495   /* Set context values */
5496   { "clear_flags", context_clear_flags, METH_NOARGS, doc_ctx_clear_flags },
5497   { "clear_traps", context_clear_traps, METH_NOARGS, doc_ctx_clear_traps },
5498 
5499 #ifdef CONFIG_32
5500   /* Unsafe set functions with relaxed range checks */
5501   { "_unsafe_setprec", context_unsafe_setprec, METH_O, NULL },
5502   { "_unsafe_setemin", context_unsafe_setemin, METH_O, NULL },
5503   { "_unsafe_setemax", context_unsafe_setemax, METH_O, NULL },
5504 #endif
5505 
5506   /* Miscellaneous */
5507   { "__copy__", (PyCFunction)context_copy, METH_NOARGS, NULL },
5508   { "__reduce__", context_reduce, METH_NOARGS, NULL },
5509   { "copy", (PyCFunction)context_copy, METH_NOARGS, doc_ctx_copy },
5510   { "create_decimal", ctx_create_decimal, METH_VARARGS, doc_ctx_create_decimal },
5511   { "create_decimal_from_float", ctx_from_float, METH_O, doc_ctx_create_decimal_from_float },
5512 
5513   { NULL, NULL, 1 }
5514 };
5515 
5516 static PyTypeObject PyDecContext_Type =
5517 {
5518     PyVarObject_HEAD_INIT(NULL, 0)
5519     "decimal.Context",                         /* tp_name */
5520     sizeof(PyDecContextObject),                /* tp_basicsize */
5521     0,                                         /* tp_itemsize */
5522     (destructor) context_dealloc,              /* tp_dealloc */
5523     0,                                         /* tp_print */
5524     (getattrfunc) 0,                           /* tp_getattr */
5525     (setattrfunc) 0,                           /* tp_setattr */
5526     0,                                         /* tp_reserved */
5527     (reprfunc) context_repr,                   /* tp_repr */
5528     0,                                         /* tp_as_number */
5529     0,                                         /* tp_as_sequence */
5530     0,                                         /* tp_as_mapping */
5531     (hashfunc) 0,                              /* tp_hash */
5532     0,                                         /* tp_call */
5533     (reprfunc) context_repr,                   /* tp_str */
5534     (getattrofunc) context_getattr,            /* tp_getattro */
5535     (setattrofunc) context_setattr,            /* tp_setattro */
5536     (PyBufferProcs *) 0,                       /* tp_as_buffer */
5537     Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,    /* tp_flags */
5538     doc_context,                               /* tp_doc */
5539     0,                                         /* tp_traverse */
5540     0,                                         /* tp_clear */
5541     0,                                         /* tp_richcompare */
5542     0,                                         /* tp_weaklistoffset */
5543     0,                                         /* tp_iter */
5544     0,                                         /* tp_iternext */
5545     context_methods,                           /* tp_methods */
5546     0,                                         /* tp_members */
5547     context_getsets,                           /* tp_getset */
5548     0,                                         /* tp_base */
5549     0,                                         /* tp_dict */
5550     0,                                         /* tp_descr_get */
5551     0,                                         /* tp_descr_set */
5552     0,                                         /* tp_dictoffset */
5553     context_init,                              /* tp_init */
5554     0,                                         /* tp_alloc */
5555     context_new,                               /* tp_new */
5556     PyObject_Del,                              /* tp_free */
5557 };
5558 
5559 
5560 static PyMethodDef _decimal_methods [] =
5561 {
5562   { "getcontext", (PyCFunction)PyDec_GetCurrentContext, METH_NOARGS, doc_getcontext},
5563   { "setcontext", (PyCFunction)PyDec_SetCurrentContext, METH_O, doc_setcontext},
5564   { "localcontext", (PyCFunction)ctxmanager_new, METH_VARARGS|METH_KEYWORDS, doc_localcontext},
5565 #ifdef EXTRA_FUNCTIONALITY
5566   { "IEEEContext", (PyCFunction)ieee_context, METH_O, doc_ieee_context},
5567 #endif
5568   { NULL, NULL, 1, NULL }
5569 };
5570 
5571 static struct PyModuleDef _decimal_module = {
5572     PyModuleDef_HEAD_INIT,
5573     "decimal",
5574     doc__decimal,
5575     -1,
5576     _decimal_methods,
5577     NULL,
5578     NULL,
5579     NULL,
5580     NULL
5581 };
5582 
5583 struct ssize_constmap { const char *name; mpd_ssize_t val; };
5584 static struct ssize_constmap ssize_constants [] = {
5585     {"MAX_PREC", MPD_MAX_PREC},
5586     {"MAX_EMAX", MPD_MAX_EMAX},
5587     {"MIN_EMIN",  MPD_MIN_EMIN},
5588     {"MIN_ETINY", MPD_MIN_ETINY},
5589     {NULL}
5590 };
5591 
5592 struct int_constmap { const char *name; int val; };
5593 static struct int_constmap int_constants [] = {
5594     /* int constants */
5595 #ifdef EXTRA_FUNCTIONALITY
5596     {"DECIMAL32", MPD_DECIMAL32},
5597     {"DECIMAL64", MPD_DECIMAL64},
5598     {"DECIMAL128", MPD_DECIMAL128},
5599     {"IEEE_CONTEXT_MAX_BITS", MPD_IEEE_CONTEXT_MAX_BITS},
5600     /* int condition flags */
5601     {"DecClamped", MPD_Clamped},
5602     {"DecConversionSyntax", MPD_Conversion_syntax},
5603     {"DecDivisionByZero", MPD_Division_by_zero},
5604     {"DecDivisionImpossible", MPD_Division_impossible},
5605     {"DecDivisionUndefined", MPD_Division_undefined},
5606     {"DecFpuError", MPD_Fpu_error},
5607     {"DecInexact", MPD_Inexact},
5608     {"DecInvalidContext", MPD_Invalid_context},
5609     {"DecInvalidOperation", MPD_Invalid_operation},
5610     {"DecIEEEInvalidOperation", MPD_IEEE_Invalid_operation},
5611     {"DecMallocError", MPD_Malloc_error},
5612     {"DecFloatOperation", MPD_Float_operation},
5613     {"DecOverflow", MPD_Overflow},
5614     {"DecRounded", MPD_Rounded},
5615     {"DecSubnormal", MPD_Subnormal},
5616     {"DecUnderflow", MPD_Underflow},
5617     {"DecErrors", MPD_Errors},
5618     {"DecTraps", MPD_Traps},
5619 #endif
5620     {NULL}
5621 };
5622 
5623 
5624 #define CHECK_INT(expr) \
5625     do { if ((expr) < 0) goto error; } while (0)
5626 #define ASSIGN_PTR(result, expr) \
5627     do { result = (expr); if (result == NULL) goto error; } while (0)
5628 #define CHECK_PTR(expr) \
5629     do { if ((expr) == NULL) goto error; } while (0)
5630 
5631 
5632 static PyCFunction
cfunc_noargs(PyTypeObject * t,const char * name)5633 cfunc_noargs(PyTypeObject *t, const char *name)
5634 {
5635     struct PyMethodDef *m;
5636 
5637     if (t->tp_methods == NULL) {
5638         goto error;
5639     }
5640 
5641     for (m = t->tp_methods; m->ml_name != NULL; m++) {
5642         if (strcmp(name, m->ml_name) == 0) {
5643             if (!(m->ml_flags & METH_NOARGS)) {
5644                 goto error;
5645             }
5646             return m->ml_meth;
5647         }
5648     }
5649 
5650 error:
5651     PyErr_Format(PyExc_RuntimeError,
5652         "internal error: could not find method %s", name);
5653     return NULL;
5654 }
5655 
5656 
5657 PyMODINIT_FUNC
PyInit__decimal(void)5658 PyInit__decimal(void)
5659 {
5660     PyObject *m = NULL;
5661     PyObject *numbers = NULL;
5662     PyObject *Number = NULL;
5663     PyObject *collections = NULL;
5664     PyObject *collections_abc = NULL;
5665     PyObject *MutableMapping = NULL;
5666     PyObject *obj = NULL;
5667     DecCondMap *cm;
5668     struct ssize_constmap *ssize_cm;
5669     struct int_constmap *int_cm;
5670     int i;
5671 
5672 
5673     /* Init libmpdec */
5674     mpd_traphandler = dec_traphandler;
5675     mpd_mallocfunc = PyMem_Malloc;
5676     mpd_reallocfunc = PyMem_Realloc;
5677     mpd_callocfunc = mpd_callocfunc_em;
5678     mpd_free = PyMem_Free;
5679     mpd_setminalloc(_Py_DEC_MINALLOC);
5680 
5681 
5682     /* Init external C-API functions */
5683     _py_long_multiply = PyLong_Type.tp_as_number->nb_multiply;
5684     _py_long_floor_divide = PyLong_Type.tp_as_number->nb_floor_divide;
5685     _py_long_power = PyLong_Type.tp_as_number->nb_power;
5686     _py_float_abs = PyFloat_Type.tp_as_number->nb_absolute;
5687     ASSIGN_PTR(_py_float_as_integer_ratio, cfunc_noargs(&PyFloat_Type,
5688                                                         "as_integer_ratio"));
5689     ASSIGN_PTR(_py_long_bit_length, cfunc_noargs(&PyLong_Type, "bit_length"));
5690 
5691 
5692     /* Init types */
5693     PyDec_Type.tp_base = &PyBaseObject_Type;
5694     PyDecContext_Type.tp_base = &PyBaseObject_Type;
5695     PyDecContextManager_Type.tp_base = &PyBaseObject_Type;
5696     PyDecSignalDictMixin_Type.tp_base = &PyBaseObject_Type;
5697 
5698     CHECK_INT(PyType_Ready(&PyDec_Type));
5699     CHECK_INT(PyType_Ready(&PyDecContext_Type));
5700     CHECK_INT(PyType_Ready(&PyDecSignalDictMixin_Type));
5701     CHECK_INT(PyType_Ready(&PyDecContextManager_Type));
5702 
5703     ASSIGN_PTR(obj, PyUnicode_FromString("decimal"));
5704     CHECK_INT(PyDict_SetItemString(PyDec_Type.tp_dict, "__module__", obj));
5705     CHECK_INT(PyDict_SetItemString(PyDecContext_Type.tp_dict,
5706                                    "__module__", obj));
5707     Py_CLEAR(obj);
5708 
5709 
5710     /* Numeric abstract base classes */
5711     ASSIGN_PTR(numbers, PyImport_ImportModule("numbers"));
5712     ASSIGN_PTR(Number, PyObject_GetAttrString(numbers, "Number"));
5713     /* Register Decimal with the Number abstract base class */
5714     ASSIGN_PTR(obj, PyObject_CallMethod(Number, "register", "(O)",
5715                                         (PyObject *)&PyDec_Type));
5716     Py_CLEAR(obj);
5717     /* Rational is a global variable used for fraction comparisons. */
5718     ASSIGN_PTR(Rational, PyObject_GetAttrString(numbers, "Rational"));
5719     /* Done with numbers, Number */
5720     Py_CLEAR(numbers);
5721     Py_CLEAR(Number);
5722 
5723     /* DecimalTuple */
5724     ASSIGN_PTR(collections, PyImport_ImportModule("collections"));
5725     ASSIGN_PTR(DecimalTuple, (PyTypeObject *)PyObject_CallMethod(collections,
5726                                  "namedtuple", "(ss)", "DecimalTuple",
5727                                  "sign digits exponent"));
5728 
5729     ASSIGN_PTR(obj, PyUnicode_FromString("decimal"));
5730     CHECK_INT(PyDict_SetItemString(DecimalTuple->tp_dict, "__module__", obj));
5731     Py_CLEAR(obj);
5732 
5733     /* MutableMapping */
5734     ASSIGN_PTR(collections_abc, PyImport_ImportModule("collections.abc"));
5735     ASSIGN_PTR(MutableMapping, PyObject_GetAttrString(collections_abc,
5736                                                       "MutableMapping"));
5737     /* Create SignalDict type */
5738     ASSIGN_PTR(PyDecSignalDict_Type,
5739                    (PyTypeObject *)PyObject_CallFunction(
5740                    (PyObject *)&PyType_Type, "s(OO){}",
5741                    "SignalDict", &PyDecSignalDictMixin_Type,
5742                    MutableMapping));
5743 
5744     /* Done with collections, MutableMapping */
5745     Py_CLEAR(collections);
5746     Py_CLEAR(collections_abc);
5747     Py_CLEAR(MutableMapping);
5748 
5749 
5750     /* Create the module */
5751     ASSIGN_PTR(m, PyModule_Create(&_decimal_module));
5752 
5753 
5754     /* Add types to the module */
5755     Py_INCREF(&PyDec_Type);
5756     CHECK_INT(PyModule_AddObject(m, "Decimal", (PyObject *)&PyDec_Type));
5757     Py_INCREF(&PyDecContext_Type);
5758     CHECK_INT(PyModule_AddObject(m, "Context",
5759                                  (PyObject *)&PyDecContext_Type));
5760     Py_INCREF(DecimalTuple);
5761     CHECK_INT(PyModule_AddObject(m, "DecimalTuple", (PyObject *)DecimalTuple));
5762 
5763 
5764     /* Create top level exception */
5765     ASSIGN_PTR(DecimalException, PyErr_NewException(
5766                                      "decimal.DecimalException",
5767                                      PyExc_ArithmeticError, NULL));
5768     Py_INCREF(DecimalException);
5769     CHECK_INT(PyModule_AddObject(m, "DecimalException", DecimalException));
5770 
5771     /* Create signal tuple */
5772     ASSIGN_PTR(SignalTuple, PyTuple_New(SIGNAL_MAP_LEN));
5773 
5774     /* Add exceptions that correspond to IEEE signals */
5775     for (i = SIGNAL_MAP_LEN-1; i >= 0; i--) {
5776         PyObject *base;
5777 
5778         cm = signal_map + i;
5779 
5780         switch (cm->flag) {
5781         case MPD_Float_operation:
5782             base = PyTuple_Pack(2, DecimalException, PyExc_TypeError);
5783             break;
5784         case MPD_Division_by_zero:
5785             base = PyTuple_Pack(2, DecimalException, PyExc_ZeroDivisionError);
5786             break;
5787         case MPD_Overflow:
5788             base = PyTuple_Pack(2, signal_map[INEXACT].ex,
5789                                    signal_map[ROUNDED].ex);
5790             break;
5791         case MPD_Underflow:
5792             base = PyTuple_Pack(3, signal_map[INEXACT].ex,
5793                                    signal_map[ROUNDED].ex,
5794                                    signal_map[SUBNORMAL].ex);
5795             break;
5796         default:
5797             base = PyTuple_Pack(1, DecimalException);
5798             break;
5799         }
5800 
5801         if (base == NULL) {
5802             goto error; /* GCOV_NOT_REACHED */
5803         }
5804 
5805         ASSIGN_PTR(cm->ex, PyErr_NewException(cm->fqname, base, NULL));
5806         Py_DECREF(base);
5807 
5808         /* add to module */
5809         Py_INCREF(cm->ex);
5810         CHECK_INT(PyModule_AddObject(m, cm->name, cm->ex));
5811 
5812         /* add to signal tuple */
5813         Py_INCREF(cm->ex);
5814         PyTuple_SET_ITEM(SignalTuple, i, cm->ex);
5815     }
5816 
5817     /*
5818      * Unfortunately, InvalidOperation is a signal that comprises
5819      * several conditions, including InvalidOperation! Naming the
5820      * signal IEEEInvalidOperation would prevent the confusion.
5821      */
5822     cond_map[0].ex = signal_map[0].ex;
5823 
5824     /* Add remaining exceptions, inherit from InvalidOperation */
5825     for (cm = cond_map+1; cm->name != NULL; cm++) {
5826         PyObject *base;
5827         if (cm->flag == MPD_Division_undefined) {
5828             base = PyTuple_Pack(2, signal_map[0].ex, PyExc_ZeroDivisionError);
5829         }
5830         else {
5831             base = PyTuple_Pack(1, signal_map[0].ex);
5832         }
5833         if (base == NULL) {
5834             goto error; /* GCOV_NOT_REACHED */
5835         }
5836 
5837         ASSIGN_PTR(cm->ex, PyErr_NewException(cm->fqname, base, NULL));
5838         Py_DECREF(base);
5839 
5840         Py_INCREF(cm->ex);
5841         CHECK_INT(PyModule_AddObject(m, cm->name, cm->ex));
5842     }
5843 
5844 
5845     /* Init default context template first */
5846     ASSIGN_PTR(default_context_template,
5847                PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL));
5848     Py_INCREF(default_context_template);
5849     CHECK_INT(PyModule_AddObject(m, "DefaultContext",
5850                                  default_context_template));
5851 
5852 #ifndef WITH_DECIMAL_CONTEXTVAR
5853     ASSIGN_PTR(tls_context_key, PyUnicode_FromString("___DECIMAL_CTX__"));
5854     Py_INCREF(Py_False);
5855     CHECK_INT(PyModule_AddObject(m, "HAVE_CONTEXTVAR", Py_False));
5856 #else
5857     ASSIGN_PTR(current_context_var, PyContextVar_New("decimal_context", NULL));
5858     Py_INCREF(Py_True);
5859     CHECK_INT(PyModule_AddObject(m, "HAVE_CONTEXTVAR", Py_True));
5860 #endif
5861     Py_INCREF(Py_True);
5862     CHECK_INT(PyModule_AddObject(m, "HAVE_THREADS", Py_True));
5863 
5864     /* Init basic context template */
5865     ASSIGN_PTR(basic_context_template,
5866                PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL));
5867     init_basic_context(basic_context_template);
5868     Py_INCREF(basic_context_template);
5869     CHECK_INT(PyModule_AddObject(m, "BasicContext",
5870                                  basic_context_template));
5871 
5872     /* Init extended context template */
5873     ASSIGN_PTR(extended_context_template,
5874                PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL));
5875     init_extended_context(extended_context_template);
5876     Py_INCREF(extended_context_template);
5877     CHECK_INT(PyModule_AddObject(m, "ExtendedContext",
5878                                  extended_context_template));
5879 
5880 
5881     /* Init mpd_ssize_t constants */
5882     for (ssize_cm = ssize_constants; ssize_cm->name != NULL; ssize_cm++) {
5883         ASSIGN_PTR(obj, PyLong_FromSsize_t(ssize_cm->val));
5884         CHECK_INT(PyModule_AddObject(m, ssize_cm->name, obj));
5885         obj = NULL;
5886     }
5887 
5888     /* Init int constants */
5889     for (int_cm = int_constants; int_cm->name != NULL; int_cm++) {
5890         CHECK_INT(PyModule_AddIntConstant(m, int_cm->name,
5891                                           int_cm->val));
5892     }
5893 
5894     /* Init string constants */
5895     for (i = 0; i < _PY_DEC_ROUND_GUARD; i++) {
5896         ASSIGN_PTR(round_map[i], PyUnicode_InternFromString(mpd_round_string[i]));
5897         Py_INCREF(round_map[i]);
5898         CHECK_INT(PyModule_AddObject(m, mpd_round_string[i], round_map[i]));
5899     }
5900 
5901     /* Add specification version number */
5902     CHECK_INT(PyModule_AddStringConstant(m, "__version__", "1.70"));
5903     CHECK_INT(PyModule_AddStringConstant(m, "__libmpdec_version__", mpd_version()));
5904 
5905 
5906     return m;
5907 
5908 
5909 error:
5910     Py_CLEAR(obj); /* GCOV_NOT_REACHED */
5911     Py_CLEAR(numbers); /* GCOV_NOT_REACHED */
5912     Py_CLEAR(Number); /* GCOV_NOT_REACHED */
5913     Py_CLEAR(Rational); /* GCOV_NOT_REACHED */
5914     Py_CLEAR(collections); /* GCOV_NOT_REACHED */
5915     Py_CLEAR(collections_abc); /* GCOV_NOT_REACHED */
5916     Py_CLEAR(MutableMapping); /* GCOV_NOT_REACHED */
5917     Py_CLEAR(SignalTuple); /* GCOV_NOT_REACHED */
5918     Py_CLEAR(DecimalTuple); /* GCOV_NOT_REACHED */
5919     Py_CLEAR(default_context_template); /* GCOV_NOT_REACHED */
5920 #ifndef WITH_DECIMAL_CONTEXTVAR
5921     Py_CLEAR(tls_context_key); /* GCOV_NOT_REACHED */
5922 #else
5923     Py_CLEAR(current_context_var); /* GCOV_NOT_REACHED */
5924 #endif
5925     Py_CLEAR(basic_context_template); /* GCOV_NOT_REACHED */
5926     Py_CLEAR(extended_context_template); /* GCOV_NOT_REACHED */
5927     Py_CLEAR(m); /* GCOV_NOT_REACHED */
5928 
5929     return NULL; /* GCOV_NOT_REACHED */
5930 }
5931 
5932 
5933