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