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