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