Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(125266)

Side by Side Diff: Modules/_decimal/_decimal.c

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