ยปCore Development>Code coverage>Modules/_decimal/_decimal.c

Python code coverage for Modules/_decimal/_decimal.c

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