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