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