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