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