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