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