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