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