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