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

Delta Between Two Patch Sets: Modules/_decimal/_decimal.c

Issue 7652: Merge C version of decimal into py3k.
Left Patch Set: Created 7 years, 6 months ago
Right Patch Set: Created 7 years, 3 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « Misc/valgrind-python.supp ('k') | Modules/_decimal/docstrings.h » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 /* 1 /*
2 * Copyright (c) 2008-2010 Stefan Krah. All rights reserved. 2 * Copyright (c) 2008-2010 Stefan Krah. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 10 *
(...skipping 19 matching lines...) Expand all
30 #include "longintrepr.h" 30 #include "longintrepr.h"
31 #include "pythread.h" 31 #include "pythread.h"
32 #include "structmember.h" 32 #include "structmember.h"
33 #include "complexobject.h" 33 #include "complexobject.h"
34 #include "mpdecimal.h" 34 #include "mpdecimal.h"
35 35
36 #include <stdlib.h> 36 #include <stdlib.h>
37 37
38 #include "docstrings.h" 38 #include "docstrings.h"
39 #include "memory.h" 39 #include "memory.h"
40 #include "mptypes.h" 40
41 41
42 42 /*
43 #if defined(_MSC_VER) 43 * Type sizes with assertions in mpdecimal.h and pyport.h:
44 #define ALWAYS_INLINE __forceinline 44 * sizeof(size_t) == sizeof(Py_ssize_t)
45 #elif defined(LEGACY_COMPILER) 45 * sizeof(size_t) == sizeof(mpd_uint_t) == sizeof(mpd_ssize_t)
46 #define ALWAYS_INLINE 46 */
47 #undef inline 47
48 #define inline 48 #ifdef TEST_COVERAGE
49 #else 49 #undef Py_LOCAL_INLINE
50 #ifdef TEST_COVERAGE 50 #define Py_LOCAL_INLINE Py_LOCAL
51 #define ALWAYS_INLINE
52 #else
53 #define ALWAYS_INLINE inline __attribute__ ((always_inline))
54 #endif
55 #endif 51 #endif
56
57 #if defined(_MSC_VER) && defined (CONFIG_64)
58 #define _PyLong_AsMpdSsize PyLong_AsLongLong
59 #define _PyLong_FromMpdSsize PyLong_FromSsize_t
60 #else
61 #define _PyLong_AsMpdSsize PyLong_AsLong
62 #define _PyLong_FromMpdSsize PyLong_FromLong
63 #endif
64
65 #define Dec_INCREF_TRUE (Py_INCREF(Py_True), Py_True)
66 #define Dec_INCREF_FALSE (Py_INCREF(Py_False), Py_False)
67 52
68 #define MPD_Float_operation MPD_Not_implemented 53 #define MPD_Float_operation MPD_Not_implemented
69 54
70 #define BOUNDS_CHECK(x, MIN, MAX) x = (x < MIN || MAX < x) ? MAX : x 55 #define BOUNDS_CHECK(x, MIN, MAX) x = (x < MIN || MAX < x) ? MAX : x
71 56
72 57
73 typedef struct { 58 typedef struct {
74 PyObject_HEAD 59 PyObject_HEAD
75 mpd_t *dec; 60 mpd_t *dec;
76 } PyDecObject; 61 } PyDecObject;
77 62
78 typedef struct { 63 typedef struct {
79 » PyDictObject dict; 64 » PyObject_HEAD
80 uint32_t *flags; 65 uint32_t *flags;
81 } PyDecSignalDictObject; 66 } PyDecSignalDictObject;
82 67
83 typedef struct { 68 typedef struct {
84 PyObject_HEAD 69 PyObject_HEAD
85 mpd_context_t ctx; 70 mpd_context_t ctx;
86 PyObject *traps; 71 PyObject *traps;
87 PyObject *flags; 72 PyObject *flags;
88 int capitals; 73 int capitals;
89 } PyDecContextObject; 74 } PyDecContextObject;
90 75
91 typedef struct { 76 typedef struct {
92 PyObject_HEAD 77 PyObject_HEAD
93 PyObject *local; 78 PyObject *local;
94 PyObject *global; 79 PyObject *global;
95 } PyDecContextManagerObject; 80 } PyDecContextManagerObject;
96 81
97 82
98 #undef MPD 83 #undef MPD
99 #undef CTX 84 #undef CTX
100 static PyTypeObject PyDec_Type; 85 static PyTypeObject PyDec_Type;
101 static PyTypeObject PyDecSignalDict_Type; 86 static PyTypeObject *PyDecSignalDict_Type;
102 static PyTypeObject PyDecContext_Type; 87 static PyTypeObject PyDecContext_Type;
103 static PyTypeObject PyDecContextManager_Type; 88 static PyTypeObject PyDecContextManager_Type;
104 #define PyDec_CheckExact(v) (Py_TYPE(v) == &PyDec_Type) 89 #define PyDec_CheckExact(v) (Py_TYPE(v) == &PyDec_Type)
105 #define PyDec_Check(v) PyObject_TypeCheck(v, &PyDec_Type) 90 #define PyDec_Check(v) PyObject_TypeCheck(v, &PyDec_Type)
106 #define PyDecSignalDict_Check(v) (Py_TYPE(v) == &PyDecSignalDict_Type) 91 #define PyDecSignalDict_Check(v) (Py_TYPE(v) == PyDecSignalDict_Type)
107 #define PyDecContext_Check(v) (Py_TYPE(v) == &PyDecContext_Type) 92 #define PyDecContext_Check(v) (Py_TYPE(v) == &PyDecContext_Type)
108 #define MPD(v) (((PyDecObject *)v)->dec) 93 #define MPD(v) (((PyDecObject *)v)->dec)
109 #define SdFlagAddr(v) (((PyDecSignalDictObject *)v)->flags) 94 #define SdFlagAddr(v) (((PyDecSignalDictObject *)v)->flags)
110 #define SdFlags(v) (*((PyDecSignalDictObject *)v)->flags) 95 #define SdFlags(v) (*((PyDecSignalDictObject *)v)->flags)
111 #define CTX(v) (&((PyDecContextObject *)v)->ctx) 96 #define CTX(v) (&((PyDecContextObject *)v)->ctx)
112 #define CtxCaps(v) (((PyDecContextObject *)v)->capitals) 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 113
114 114
115 #ifdef WITHOUT_THREADS 115 #ifdef WITHOUT_THREADS
116 /* Default module context */ 116 /* Default module context */
117 static PyObject *module_context = NULL; 117 static PyObject *module_context = NULL;
118 #else 118 #else
119 /* Key for thread state dictionary */ 119 /* Key for thread state dictionary */
120 static PyObject *tls_context_key = NULL; 120 static PyObject *tls_context_key = NULL;
121 #endif 121 #endif
122 122
123 /* Template for creating new thread contexts, calling Context() without 123 /* Template for creating new thread contexts, calling Context() without
124 * arguments and initializing the module_context on first access. */ 124 * arguments and initializing the module_context on first access. */
125 static PyObject *default_context_template = NULL; 125 static PyObject *default_context_template = NULL;
126 /* Basic and extended context templates */ 126 /* Basic and extended context templates */
127 static PyObject *basic_context_template = NULL; 127 static PyObject *basic_context_template = NULL;
128 static PyObject *extended_context_template = NULL; 128 static PyObject *extended_context_template = NULL;
129 129
130 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
131 typedef struct { 136 typedef struct {
132 » const char *name; 137 » const char *name; /* condition or signal name */
133 » const char *fqname; 138 » const char *fqname; /* fully qualified name */
134 » uint32_t mpd_cond; 139 » uint32_t flag; /* libmpdec flag */
135 » PyObject *dec_cond; 140 » PyObject *ex; /* corresponding exception */
136 } DecCondMap; 141 } DecCondMap;
137 142
138 /* Top level Exception; inherits from ArithmeticError */ 143 /* Top level Exception; inherits from ArithmeticError */
139 static PyObject *DecimalException = NULL; 144 static PyObject *DecimalException = NULL;
140 145
141 /* Exceptions that correspond to IEEE signals; inherit from DecimalException */ 146 /* Exceptions that correspond to IEEE signals; inherit from DecimalException */
147 #define SIGNAL_MAP_LEN 9
142 static DecCondMap signal_map[] = { 148 static DecCondMap signal_map[] = {
143 {"InvalidOperation", "decimal.InvalidOperation", MPD_IEEE_Invalid_operation, N ULL}, 149 {"InvalidOperation", "decimal.InvalidOperation", MPD_IEEE_Invalid_operation, N ULL},
144 {"FloatOperation", "decimal.FloatOperation", MPD_Float_operation, NULL}, 150 {"FloatOperation", "decimal.FloatOperation", MPD_Float_operation, NULL},
145 {"DivisionByZero", "decimal.DivisionByZero", MPD_Division_by_zero, NULL}, 151 {"DivisionByZero", "decimal.DivisionByZero", MPD_Division_by_zero, NULL},
146 {"Overflow", "decimal.Overflow", MPD_Overflow, NULL}, 152 {"Overflow", "decimal.Overflow", MPD_Overflow, NULL},
147 {"Underflow", "decimal.Underflow", MPD_Underflow, NULL}, 153 {"Underflow", "decimal.Underflow", MPD_Underflow, NULL},
148 {"Subnormal", "decimal.Subnormal", MPD_Subnormal, NULL}, 154 {"Subnormal", "decimal.Subnormal", MPD_Subnormal, NULL},
149 {"Inexact", "decimal.Inexact", MPD_Inexact, NULL}, 155 {"Inexact", "decimal.Inexact", MPD_Inexact, NULL},
150 {"Rounded", "decimal.Rounded", MPD_Rounded, NULL}, 156 {"Rounded", "decimal.Rounded", MPD_Rounded, NULL},
151 {"Clamped", "decimal.Clamped", MPD_Clamped, NULL}, 157 {"Clamped", "decimal.Clamped", MPD_Clamped, NULL},
152 {NULL} 158 {NULL}
153 }; 159 };
154 160
155 /* Exceptions that inherit from InvalidOperation */ 161 /* Exceptions that inherit from InvalidOperation */
156 static DecCondMap cond_map[] = { 162 static DecCondMap cond_map[] = {
157 {"InvalidOperation", "decimal.InvalidOperation", MPD_Invalid_operation, NULL}, 163 {"InvalidOperation", "decimal.InvalidOperation", MPD_Invalid_operation, NULL},
158 {"ConversionSyntax", "decimal.ConversionSyntax", MPD_Conversion_syntax, NULL}, 164 {"ConversionSyntax", "decimal.ConversionSyntax", MPD_Conversion_syntax, NULL},
159 {"DivisionImpossible", "decimal.DivisionImpossible", MPD_Division_impossible, NULL}, 165 {"DivisionImpossible", "decimal.DivisionImpossible", MPD_Division_impossible, NULL},
160 {"DivisionUndefined", "decimal.DivisionUndefined", MPD_Division_undefined, NUL L}, 166 {"DivisionUndefined", "decimal.DivisionUndefined", MPD_Division_undefined, NUL L},
161 {"FpuError", "decimal.FpuError", MPD_Fpu_error, NULL},
162 {"InvalidContext", "decimal.InvalidContext", MPD_Invalid_context, NULL}, 167 {"InvalidContext", "decimal.InvalidContext", MPD_Invalid_context, NULL},
163 {"MallocError", "decimal.MallocError", MPD_Malloc_error, NULL}, 168 {"MallocError", "decimal.MallocError", MPD_Malloc_error, NULL},
164 {NULL} 169 {NULL}
165 }; 170 };
166 171
167 static const char *dec_signal_string[MPD_NUM_FLAGS] = { 172 static const char *dec_signal_string[MPD_NUM_FLAGS] = {
168 "Clamped", 173 "Clamped",
169 "InvalidOperation", 174 "InvalidOperation",
170 "DivisionByZero", 175 "DivisionByZero",
171 "InvalidOperation", 176 "InvalidOperation",
172 "InvalidOperation", 177 "InvalidOperation",
173 "InvalidOperation", 178 "InvalidOperation",
174 "Inexact", 179 "Inexact",
175 "InvalidOperation", 180 "InvalidOperation",
176 "InvalidOperation", 181 "InvalidOperation",
177 "InvalidOperation", 182 "InvalidOperation",
178 "FloatOperation", 183 "FloatOperation",
179 "Overflow", 184 "Overflow",
180 "Rounded", 185 "Rounded",
181 "Subnormal", 186 "Subnormal",
182 "Underflow", 187 "Underflow",
183 }; 188 };
184 189
185 static const char *invalid_rounding_err = 190 static const char *invalid_rounding_err =
186 "valid values for rounding are:\n\ 191 "valid values for rounding are:\n\
187 [ROUND_CEILING, ROUND_FLOOR, ROUND_UP, ROUND_DOWN,\n\ 192 [ROUND_CEILING, ROUND_FLOOR, ROUND_UP, ROUND_DOWN,\n\
188 ROUND_HALF_UP, ROUND_HALF_DOWN, ROUND_HALF_EVEN,\n\ 193 ROUND_HALF_UP, ROUND_HALF_DOWN, ROUND_HALF_EVEN,\n\
189 ROUND_05UP]."; 194 ROUND_05UP]";
190 195
191 static const char *invalid_signals_err = 196 static const char *invalid_signals_err =
192 "valid values for signals are:\n\ 197 "valid values for signals are:\n\
193 [InvalidOperation, FloatOperation, DivisionByZero,\n\ 198 [InvalidOperation, FloatOperation, DivisionByZero,\n\
194 Overflow, Underflow, Subnormal, Inexact, Rounded,\n\ 199 Overflow, Underflow, Subnormal, Inexact, Rounded,\n\
195 Clamped]."; 200 Clamped]";
196 201
202 #ifdef EXTRA_FUNCTIONALITY
197 static const char *invalid_flags_err = 203 static const char *invalid_flags_err =
198 "valid values for _flags or _traps are:\n\ 204 "valid values for _flags or _traps are:\n\
199 signals:\n\ 205 signals:\n\
200 [DecIEEEInvalidOperation, DecFloatOperation, DecDivisionByZero,\n\ 206 [DecIEEEInvalidOperation, DecFloatOperation, DecDivisionByZero,\n\
201 DecOverflow, DecUnderflow, DecSubnormal, DecInexact, DecRounded,\n\ 207 DecOverflow, DecUnderflow, DecSubnormal, DecInexact, DecRounded,\n\
202 DecClamped]\n\ 208 DecClamped]\n\
203 conditions which trigger DecIEEEInvalidOperation:\n\ 209 conditions which trigger DecIEEEInvalidOperation:\n\
204 [DecInvalidOperation, DecConversionSyntax, DecDivisionImpossible,\n\ 210 [DecInvalidOperation, DecConversionSyntax, DecDivisionImpossible,\n\
205 DecDivisionUndefined, DecFpuError, DecInvalidContext, DecMallocError]"; 211 DecDivisionUndefined, DecFpuError, DecInvalidContext, DecMallocError]";
212 #endif
206 213
207 static int 214 static int
208 value_error_int(const char *mesg) 215 value_error_int(const char *mesg)
209 { 216 {
210 PyErr_SetString(PyExc_ValueError, mesg); 217 PyErr_SetString(PyExc_ValueError, mesg);
211 return -1; 218 return -1;
212 } 219 }
213 220
221 static PyObject *
222 value_error_ptr(const char *mesg)
223 {
224 PyErr_SetString(PyExc_ValueError, mesg);
225 return NULL;
226 }
227
214 static int 228 static int
215 type_error_int(const char *mesg) 229 type_error_int(const char *mesg)
216 { 230 {
217 PyErr_SetString(PyExc_TypeError, mesg); 231 PyErr_SetString(PyExc_TypeError, mesg);
218 return -1; 232 return -1;
219 } 233 }
220 234
221 static PyObject * 235 static PyObject *
222 type_error_ptr(const char *mesg) 236 type_error_ptr(const char *mesg)
223 { 237 {
224 PyErr_SetString(PyExc_TypeError, mesg); 238 PyErr_SetString(PyExc_TypeError, mesg);
225 return NULL; 239 return NULL;
226 } 240 }
227 241
228 static int 242 static int
229 runtime_error_int(const char *mesg) 243 runtime_error_int(const char *mesg)
230 { 244 {
231 PyErr_SetString(PyExc_RuntimeError, mesg); 245 PyErr_SetString(PyExc_RuntimeError, mesg);
232 return -1; 246 return -1;
233 } 247 }
234 #define INTERNAL_ERROR_INT(funcname) \ 248 #define INTERNAL_ERROR_INT(funcname) \
235 return runtime_error_int("internal error in " funcname ".") 249 return runtime_error_int("internal error in " funcname)
236 250
237 static PyObject * 251 static PyObject *
238 runtime_error_ptr(const char *mesg) 252 runtime_error_ptr(const char *mesg)
239 { 253 {
240 PyErr_SetString(PyExc_RuntimeError, mesg); 254 PyErr_SetString(PyExc_RuntimeError, mesg);
241 return NULL; 255 return NULL;
242 } 256 }
243 #define INTERNAL_ERROR_PTR(funcname) \ 257 #define INTERNAL_ERROR_PTR(funcname) \
244 return runtime_error_ptr("internal error in " funcname ".") 258 return runtime_error_ptr("internal error in " funcname)
245 259
246 static void 260 static void
247 dec_traphandler(mpd_context_t *ctx UNUSED) /* GCOV_NOT_REACHED */ 261 dec_traphandler(mpd_context_t *ctx UNUSED) /* GCOV_NOT_REACHED */
248 { /* GCOV_NOT_REACHED */ 262 { /* GCOV_NOT_REACHED */
249 return; /* GCOV_NOT_REACHED */ 263 return; /* GCOV_NOT_REACHED */
250 } 264 }
251 265
252 static PyObject * 266 static PyObject *
253 flags_as_exception(uint32_t flags) 267 flags_as_exception(uint32_t flags)
254 { 268 {
255 DecCondMap *cm; 269 DecCondMap *cm;
256 270
257 for (cm = signal_map; cm->name != NULL; cm++) { 271 for (cm = signal_map; cm->name != NULL; cm++) {
258 » » if (flags&cm->mpd_cond) { 272 » » if (flags&cm->flag) {
259 » » » return cm->dec_cond; 273 » » » return cm->ex;
260 } 274 }
261 } 275 }
262 276
263 INTERNAL_ERROR_PTR("flags_as_exception"); /* GCOV_NOT_REACHED */ 277 INTERNAL_ERROR_PTR("flags_as_exception"); /* GCOV_NOT_REACHED */
264 } 278 }
265 279
266 static uint32_t 280 Py_LOCAL_INLINE(uint32_t)
267 exception_as_flags(PyObject *ex) 281 exception_as_flag(PyObject *ex)
268 { 282 {
269 DecCondMap *cm; 283 DecCondMap *cm;
270 284
271 for (cm = signal_map; cm->name != NULL; cm++) { 285 for (cm = signal_map; cm->name != NULL; cm++) {
272 » » if (cm->dec_cond == ex) { 286 » » if (cm->ex == ex) {
273 » » » return cm->mpd_cond; 287 » » » return cm->flag;
274 » » } 288 » » }
275 » } 289 » }
276 290
277 » PyErr_SetString(PyExc_TypeError, invalid_signals_err); 291 » PyErr_SetString(PyExc_KeyError, invalid_signals_err);
278 » return UINT32_MAX; 292 » return DEC_INVALID_SIGNALS;
279 } 293 }
280 294
281 static PyObject * 295 static PyObject *
282 flags_as_list(uint32_t flags) 296 flags_as_list(uint32_t flags)
283 { 297 {
284 PyObject *list; 298 PyObject *list;
285 DecCondMap *cm; 299 DecCondMap *cm;
286 300
287 » if ((list = PyList_New(0)) == NULL) { 301 » list = PyList_New(0);
302 » if (list == NULL) {
288 return NULL; 303 return NULL;
289 } 304 }
290 305
291 for (cm = cond_map; cm->name != NULL; cm++) { 306 for (cm = cond_map; cm->name != NULL; cm++) {
292 » » if (flags&cm->mpd_cond) { 307 » » if (flags&cm->flag) {
293 » » » if (PyList_Append(list, cm->dec_cond) < 0) { 308 » » » if (PyList_Append(list, cm->ex) < 0) {
294 goto error; 309 goto error;
295 } 310 }
296 } 311 }
297 } 312 }
298 for (cm = signal_map+1; cm->name != NULL; cm++) { 313 for (cm = signal_map+1; cm->name != NULL; cm++) {
299 » » if (flags&cm->mpd_cond) { 314 » » if (flags&cm->flag) {
300 » » » if (PyList_Append(list, cm->dec_cond) < 0) { 315 » » » if (PyList_Append(list, cm->ex) < 0) {
301 goto error; 316 goto error;
302 } 317 }
303 } 318 }
304 } 319 }
305 320
306 return list; 321 return list;
307 322
308 error: 323 error:
309 Py_DECREF(list); 324 Py_DECREF(list);
310 return NULL; 325 return NULL;
311 } 326 }
312 327
313 static PyObject * 328 static PyObject *
314 signals_as_list(uint32_t flags) 329 signals_as_list(uint32_t flags)
315 { 330 {
316 PyObject *list; 331 PyObject *list;
317 DecCondMap *cm; 332 DecCondMap *cm;
318 333
319 » if ((list = PyList_New(0)) == NULL) { 334 » list = PyList_New(0);
335 » if (list == NULL) {
320 return NULL; 336 return NULL;
321 } 337 }
322 338
323 for (cm = signal_map; cm->name != NULL; cm++) { 339 for (cm = signal_map; cm->name != NULL; cm++) {
324 » » if (flags&cm->mpd_cond) { 340 » » if (flags&cm->flag) {
325 » » » if (PyList_Append(list, cm->dec_cond) < 0) { 341 » » » if (PyList_Append(list, cm->ex) < 0) {
326 » » » » goto error; 342 » » » » Py_DECREF(list);
343 » » » » return NULL;
327 } 344 }
328 } 345 }
329 } 346 }
330 347
331 return list; 348 return list;
332
333 error:
334 Py_DECREF(list);
335 return NULL;
336 } 349 }
337 350
338 static uint32_t 351 static uint32_t
339 list_as_flags(PyObject *list) 352 list_as_flags(PyObject *list)
340 { 353 {
341 PyObject *item; 354 PyObject *item;
342 uint32_t flags, x; 355 uint32_t flags, x;
343 » ssize_t n, j; 356 » Py_ssize_t n, j;
344 357
345 » if (!PyList_Check(list)) { 358 » assert(PyList_Check(list));
346 » » PyErr_SetString(PyExc_TypeError,
347 » » "argument must be a list of signals.");
348 » » return UINT32_MAX;
349 » }
350 359
351 n = PyList_Size(list); 360 n = PyList_Size(list);
352 flags = 0; 361 flags = 0;
353 for (j = 0; j < n; j++) { 362 for (j = 0; j < n; j++) {
354 item = PyList_GetItem(list, j); 363 item = PyList_GetItem(list, j);
355 » » if ((x = exception_as_flags(item)) == UINT32_MAX) { 364 » » x = exception_as_flag(item);
356 » » » return UINT32_MAX; 365 » » if (x & DEC_ERRORS) {
366 » » » return x;
357 } 367 }
358 flags |= x; 368 flags |= x;
359 } 369 }
360 370
361 return flags; 371 return flags;
362 } 372 }
363 373
364 static int 374 static PyObject *
375 flags_as_dict(uint32_t flags)
376 {
377 » DecCondMap *cm;
378 » PyObject *dict;
379
380 » dict = PyDict_New();
381 » if (dict == NULL) {
382 » » return NULL;
383 » }
384
385 » for (cm = signal_map; cm->name != NULL; cm++) {
386 » » PyObject *b = flags&cm->flag ? Py_True : Py_False;
387 » » if (PyDict_SetItem(dict, cm->ex, b) < 0) {
388 » » » Py_DECREF(dict);
389 » » » return NULL;
390 » » }
391 » }
392
393 » return dict;
394 }
395
396 static uint32_t
365 dict_as_flags(PyObject *val) 397 dict_as_flags(PyObject *val)
366 { 398 {
367 PyObject *b; 399 PyObject *b;
368 DecCondMap *cm; 400 DecCondMap *cm;
369 uint32_t flags = 0; 401 uint32_t flags = 0;
370 int x; 402 int x;
371 403
372 if (!PyDict_Check(val)) { 404 if (!PyDict_Check(val)) {
373 PyErr_SetString(PyExc_TypeError, 405 PyErr_SetString(PyExc_TypeError,
374 » » "argument must be a signal dict."); 406 » » "argument must be a signal dict");
375 » » return -1; 407 » » return DEC_INVALID_SIGNALS;
376 } 408 }
377 409
378 for (cm = signal_map; cm->name != NULL; cm++) { 410 for (cm = signal_map; cm->name != NULL; cm++) {
379 » » if ((b = PyDict_GetItemWithError(val, cm->dec_cond)) == NULL) { 411 » » b = PyDict_GetItemWithError(val, cm->ex);
380 » » » if (!PyErr_Occurred()) { 412 » » if (b == NULL) {
381 » » » » PyErr_SetString(PyExc_TypeError, 413 » » » if (PyErr_Occurred()) {
382 » » » » "invalid signal dict."); 414 » » » » return DEC_ERR_OCCURRED;
383 } 415 }
384 » » » return UINT32_MAX; 416 » » » PyErr_SetString(PyExc_KeyError,
385 » » } 417 » » » "invalid signal dict");
386 418 » » » return DEC_INVALID_SIGNALS;
387 » » if ((x = PyObject_IsTrue(b)) < 0) { 419 » » }
388 » » » return UINT32_MAX; 420
421 » » x = PyObject_IsTrue(b);
422 » » if (x < 0) {
423 » » » return DEC_ERR_OCCURRED;
389 } 424 }
390 if (x == 1) { 425 if (x == 1) {
391 » » » flags |= cm->mpd_cond; 426 » » » flags |= cm->flag;
392 } 427 }
393 } 428 }
394 429
395 return flags; 430 return flags;
396 } 431 }
397 432
433 #ifdef EXTRA_FUNCTIONALITY
398 static uint32_t 434 static uint32_t
399 long_as_flags(PyObject *v) 435 long_as_flags(PyObject *v)
400 { 436 {
401 long x; 437 long x;
402 438
403 x = PyLong_AsLong(v); 439 x = PyLong_AsLong(v);
404 » if (PyErr_Occurred()) { 440 » if (x == -1 && PyErr_Occurred()) {
405 » » return UINT32_MAX; 441 » » return DEC_ERR_OCCURRED;
406 } 442 }
407 if (x < 0 || x > (long)MPD_Max_status) { 443 if (x < 0 || x > (long)MPD_Max_status) {
408 PyErr_SetString(PyExc_TypeError, invalid_flags_err); 444 PyErr_SetString(PyExc_TypeError, invalid_flags_err);
409 » » return UINT32_MAX; 445 » » return DEC_INVALID_SIGNALS;
410 } 446 }
411 447
412 return x; 448 return x;
413 } 449 }
414 450 #endif
415 static mpd_ssize_t
416 long_as_mpd_ssize(PyObject *v)
417 {
418 » mpd_ssize_t x;
419
420 » if (!PyLong_Check(v)) {
421 » » PyErr_SetString(PyExc_TypeError,
422 » » "integer argument required.");
423 » » return MPD_SSIZE_MAX;
424 » }
425
426 » x = _PyLong_AsMpdSsize(v);
427 » if (PyErr_Occurred()) {
428 » » return MPD_SSIZE_MAX;
429 » }
430
431 » return x;
432 }
433 451
434 static int 452 static int
435 dec_addstatus(PyObject *context, uint32_t status) 453 dec_addstatus(PyObject *context, uint32_t status)
436 { 454 {
437 mpd_context_t *ctx = CTX(context); 455 mpd_context_t *ctx = CTX(context);
438 456
439 ctx->status |= status; 457 ctx->status |= status;
440 if (ctx->traps&status) { 458 if (ctx->traps&status) {
441 PyObject *ex, *siglist; 459 PyObject *ex, *siglist;
442 460
(...skipping 11 matching lines...) Expand all
454 return 1; 472 return 1;
455 } 473 }
456 return 0; 474 return 0;
457 } 475 }
458 476
459 477
460 /******************************************************************************/ 478 /******************************************************************************/
461 /* SignalDict Object */ 479 /* SignalDict Object */
462 /******************************************************************************/ 480 /******************************************************************************/
463 481
482 /* The SignalDict is a MutableMapping that provides access to the
483 mpd_context_t flags, which reside in the context object. When a
484 new context is created, context.traps and context.flags are
485 initialized to new SignalDicts. Once a SignalDict is tied to
486 a context, it cannot be deleted. */
487
464 static int 488 static int
465 signaldict_init(PyObject *self, PyObject *args, PyObject *kwds) 489 signaldict_init(PyObject *self, PyObject *args UNUSED, PyObject *kwds UNUSED)
466 { 490 {
467 » if (PyDict_Type.tp_init(self, args, kwds) < 0) {
468 » » return -1;
469 » }
470
471 SdFlagAddr(self) = NULL; 491 SdFlagAddr(self) = NULL;
472 return 0; 492 return 0;
473 } 493 }
474 494
475 /* sync flags and dictionary, using the flags as the master */ 495 static Py_ssize_t
476 static int 496 signaldict_len(PyObject *self UNUSED)
477 signaldict_update(PyObject *self) 497 {
478 { 498 » return SIGNAL_MAP_LEN;
479 » PyObject *b; 499 }
480 » DecCondMap *cm; 500
481 » uint32_t flags; 501 static PyObject *SignalTuple;
482 502 static PyObject *
483 » flags = SdFlags(self); 503 signaldict_iter(PyObject *self UNUSED)
484 504 {
485 » for (cm = signal_map; cm->name != NULL; cm++) { 505 » return PyTuple_Type.tp_iter(SignalTuple);
486 » » b = (flags&cm->mpd_cond) ? Py_True : Py_False; 506 }
487 » » if (PyDict_SetItem(self, cm->dec_cond, b) < 0) { 507
488 » » » return -1; 508 static PyObject *
489 » » } 509 signaldict_getitem(PyObject *self, PyObject *key)
490 » } 510 {
491 » return 0; 511 » uint32_t flag;
492 } 512
493 513 » flag = exception_as_flag(key);
494 /* set all flags to false */ 514 » if (flag & DEC_ERRORS) {
495 static int 515 » » return NULL;
496 signaldict_clear_all(PyObject *self) 516 » }
497 { 517
498 » DecCondMap *cm; 518 » return SdFlags(self)&flag ? incr_true() : incr_false();
499
500 » SdFlags(self) = 0;
501
502 » for (cm = signal_map; cm->name != NULL; cm++) {
503 » » if (PyDict_SetItem(self, cm->dec_cond, Py_False) < 0) {
504 » » » return -1;
505 » » }
506 » }
507 » return 0;
508 } 519 }
509 520
510 static int 521 static int
511 signaldict_setitem(PyObject *self, PyObject *key, PyObject *value) 522 signaldict_setitem(PyObject *self, PyObject *key, PyObject *value)
512 { 523 {
513 uint32_t flag; 524 uint32_t flag;
514 int x; 525 int x;
515 526
516 » if ((flag = exception_as_flags(key)) == UINT_MAX) { 527 » if (value == NULL) {
528 » » return value_error_int("signal keys cannot be deleted");
529 » }
530
531 » flag = exception_as_flag(key);
532 » if (flag & DEC_ERRORS) {
517 return -1; 533 return -1;
518 } 534 }
519 535
520 » if ((x = PyObject_IsTrue(value)) < 0) { 536 » x = PyObject_IsTrue(value);
537 » if (x < 0) {
521 return -1; 538 return -1;
522 } 539 }
540
523 if (x == 1) { 541 if (x == 1) {
524 SdFlags(self) |= flag; 542 SdFlags(self) |= flag;
525 if (PyDict_SetItem(self, key, Py_True) < 0) {
526 return -1;
527 }
528 return 0;
529 } 543 }
530 else { 544 else {
531 SdFlags(self) &= ~flag; 545 SdFlags(self) &= ~flag;
532 » » if (PyDict_SetItem(self, key, Py_False) < 0) { 546 » }
533 » » » return -1; 547
534 » » } 548 » return 0;
535 » » return 0; 549 }
536 » } 550
537 } 551 static PyObject *
538 552 signaldict_repr(PyObject *self)
539 static PyObject * 553 {
540 signaldict_call_unary(PyObject *self, char *name) 554 » DecCondMap *cm;
541 { 555 » const char *n[SIGNAL_MAP_LEN]; /* name */
542 » if (signaldict_update(self) < 0) { 556 » const char *b[SIGNAL_MAP_LEN]; /* bool */
543 » » return NULL; 557 » int i;
544 » } 558
545 » return PyObject_CallMethod((PyObject *)&PyDict_Type, name, "O", self); 559 » assert(SIGNAL_MAP_LEN == 9);
546 } 560
547 561 » for (cm=signal_map, i=0; cm->name != NULL; cm++, i++) {
548 static PyObject * 562 » » n[i] = cm->fqname;
549 signaldict_richcompare(PyObject *a, PyObject *b, int op) 563 » » b[i] = SdFlags(self)&cm->flag ? "True" : "False";
550 { 564 » }
551 » if (PyDecSignalDict_Check(a)) { 565 » return PyUnicode_FromFormat(
552 » » if (signaldict_update(a) < 0) { 566 » "{<class '%s'>:%s, <class '%s'>:%s, <class '%s'>:%s, "
553 » » » return NULL; 567 » "<class '%s'>:%s, <class '%s'>:%s, <class '%s'>:%s, "
554 » » } 568 » "<class '%s'>:%s, <class '%s'>:%s, <class '%s'>:%s}",
555 » } 569 » n[0], b[0], n[1], b[1], n[2], b[2],
556 » if (PyDecSignalDict_Check(b)) { 570 » n[3], b[3], n[4], b[4], n[5], b[5],
557 » » if (signaldict_update(b) < 0) { 571 » n[6], b[6], n[7], b[7], n[8], b[8]);
558 » » » return NULL; 572 }
559 » » } 573
560 » } 574 static PyObject *
561 » return PyDict_Type.tp_richcompare(a, b, op); 575 signaldict_richcompare(PyObject *v, PyObject *w, int op)
562 } 576 {
563 577 » PyObject *res = Py_NotImplemented;
564 static int 578
565 signaldict_contains(PyObject *self, PyObject *key) 579 » assert(PyDecSignalDict_Check(v));
566 { 580
567 » if (signaldict_update(self) < 0) { 581 » if (op == Py_EQ || op == Py_NE) {
568 » » return -1; 582 » » if (PyDecSignalDict_Check(w)) {
569 » } 583 » » » res = (SdFlags(v)==SdFlags(w)) ^ (op==Py_NE) ? Py_True : Py_False;
570 » return PyDict_Contains(self, key); 584 » » }
585 » » else if (PyDict_Check(w)) {
586 » » » uint32_t flags = dict_as_flags(w);
587 » » » if (flags & DEC_ERRORS) {
588 » » » » if (flags & DEC_INVALID_SIGNALS) {
589 » » » » » /* non-comparable: Py_NotImplemented */
590 » » » » » PyErr_Clear();
591 » » » » }
592 » » » » else {
593 » » » » » return NULL;
594 » » » » }
595 » » » }
596 » » » else {
597 » » » » res = (SdFlags(v)==flags) ^ (op==Py_NE) ? Py_Tru e : Py_False;
598 » » » }
599 » » }
600 » }
601
602 » Py_INCREF(res);
603 » return res;
571 } 604 }
572 605
573 static PyObject * 606 static PyObject *
574 signaldict_copy(PyObject *self) 607 signaldict_copy(PyObject *self)
575 { 608 {
576 » if (signaldict_update(self) < 0) { 609 » return flags_as_dict(SdFlags(self));
577 » » return NULL;
578 » }
579 » return PyDict_Copy(self);
580 }
581
582 static PyObject *
583 signaldict_get(PyObject *self, PyObject *args)
584 {
585 » PyObject *key = NULL, *failobj = NULL;
586 » if (!PyArg_ParseTuple(args, "O|O", &key, &failobj)) {
587 » » return NULL; /* GCOV_NOT_REACHED (why?) */
588 » }
589 » if (signaldict_update(self) < 0) {
590 » » return NULL;
591 » }
592 » if (failobj) {
593 » » return PyObject_CallMethod((PyObject *)&PyDict_Type, "get",
594 » » "OOO", self, key, failobj);
595 » }
596 » return PyObject_CallMethod((PyObject *)&PyDict_Type, "get",
597 » "OO", self, key);
598 }
599
600 static PyObject *
601 signaldict_has_key(PyObject *self, PyObject *key)
602 {
603 » int ret;
604 » if (signaldict_update(self) < 0) {
605 » » return NULL;
606 » }
607 » ret = PyDict_Contains(self, key);
608 » return ret < 0 ? NULL : PyBool_FromLong(ret);
609 }
610
611 static PyObject *
612 signaldict_items(PyObject *self)
613 {
614 » if (signaldict_update(self) < 0) {
615 » » return NULL;
616 » }
617 » return PyDict_Items(self);
618 }
619
620 static PyObject *
621 signaldict_iter(PyObject *self)
622 {
623 » if (signaldict_update(self) < 0) {
624 » » return NULL;
625 » }
626 » return PyDict_Type.tp_iter(self);
627 }
628
629 static PyObject *
630 signaldict_keys(PyObject *self)
631 {
632 » if (signaldict_update(self) < 0) {
633 » » return NULL;
634 » }
635 » return PyDict_Keys(self);
636 }
637
638 static Py_ssize_t
639 signaldict_length(PyObject *self)
640 {
641 » if (signaldict_update(self) < 0) {
642 » » return -1;
643 » }
644 » return PyDict_Type.tp_as_mapping->mp_length(self);
645 }
646
647 static int
648 signaldict_print(PyObject *self, FILE *fp, int flags) /* GCOV_NOT_REACHED */
649 {
650 » if (signaldict_update(self) < 0) { /* GCOV_NOT_REACHED */
651 » » return -1; /* GCOV_NOT_REACHED */
652 » }
653 » return PyDict_Type.tp_print(self, fp, flags); /* GCOV_NOT_REACHED */
654 }
655
656 static PyObject *
657 signaldict_repr(PyObject *self)
658 {
659 » if (signaldict_update(self) < 0) {
660 » » return NULL;
661 » }
662 » return PyDict_Type.tp_repr(self);
663 }
664
665 static PyObject *
666 signaldict_sizeof(PyObject *self)
667 {
668 » return signaldict_call_unary(self, "__sizeof__");
669 }
670
671 static int
672 signaldict_ass_sub(PyObject *self, PyObject *v, PyObject *w)
673 {
674 » if (w == NULL) {
675 » » return value_error_int("signal keys cannot be deleted.");
676 » }
677 » else {
678 » » return signaldict_setitem(self, v, w);
679 » }
680 }
681
682 static PyObject *
683 signaldict_subscript(PyObject *self, PyObject *key)
684 {
685 » if (signaldict_update(self) < 0) {
686 » » return NULL;
687 » }
688 » return PyDict_Type.tp_as_mapping->mp_subscript(self, key);
689 }
690
691 static PyObject *
692 signaldict_values(PyObject *self)
693 {
694 » if (signaldict_update(self) < 0) {
695 » » return NULL;
696 » }
697 » return PyDict_Values(self);
698 } 610 }
699 611
700 612
701 static PyMappingMethods signaldict_as_mapping = { 613 static PyMappingMethods signaldict_as_mapping = {
702 » (lenfunc)signaldict_length, /*mp_length*/ 614 » (lenfunc)signaldict_len, /* mp_length */
703 » (binaryfunc)signaldict_subscript, /*mp_subscript*/ 615 » (binaryfunc)signaldict_getitem, /* mp_subscript */
704 » (objobjargproc)signaldict_ass_sub /*mp_ass_subscript*/ 616 » (objobjargproc)signaldict_setitem /* mp_ass_subscript */
705 }; 617 };
706 618
707 static PySequenceMethods signaldict_as_sequence = { 619 static PyMethodDef signaldict_methods[] = {
708 » 0, /* sq_length */ 620 » { "copy", (PyCFunction)signaldict_copy, METH_NOARGS, NULL},
709 » 0, /* sq_concat */ 621 » {NULL, NULL}
710 » 0, /* sq_repeat */
711 » 0, /* sq_item */
712 » 0, /* sq_slice */
713 » 0, /* sq_ass_item */
714 » 0, /* sq_ass_slice */
715 » signaldict_contains, /* sq_contains */
716 » 0, /* sq_inplace_concat */
717 » 0, /* sq_inplace_repeat */
718 }; 622 };
719 623
720 static PyMethodDef mapp_methods[] = { 624
721 {"__contains__", (PyCFunction)signaldict_contains, METH_O|METH_COEXIST, NULL }, 625 static PyTypeObject PyDecSignalDictMixin_Type =
722 {"__getitem__", (PyCFunction)signaldict_subscript, METH_O|METH_COEXIST, NULL },
723 {"__sizeof__", (PyCFunction)signaldict_sizeof, METH_NOARGS, NULL },
724 {"has_key", (PyCFunction)signaldict_has_key, METH_O, NULL },
725 {"get", (PyCFunction)signaldict_get, METH_VARARGS, NULL },
726 {"keys", (PyCFunction)signaldict_keys, METH_NOARGS, NULL },
727 {"items", (PyCFunction)signaldict_items, METH_NOARGS, NULL },
728 {"values", (PyCFunction)signaldict_values, METH_NOARGS, NULL },
729 {"copy", (PyCFunction)signaldict_copy, METH_NOARGS, NULL },
730 {NULL, NULL}
731 };
732
733 static PyTypeObject PyDecSignalDict_Type =
734 { 626 {
735 PyVarObject_HEAD_INIT(0, 0) 627 PyVarObject_HEAD_INIT(0, 0)
736 » "decimal.SignalDict", /* tp_name */ 628 » "decimal.SignalDictMixin", /* tp_name */
737 sizeof(PyDecSignalDictObject), /* tp_basicsize */ 629 sizeof(PyDecSignalDictObject), /* tp_basicsize */
738 0, /* tp_itemsize */ 630 0, /* tp_itemsize */
739 0, /* tp_dealloc */ 631 0, /* tp_dealloc */
740 » (printfunc)signaldict_print, /* tp_print */ 632 » 0, /* tp_print */
741 (getattrfunc) 0, /* tp_getattr */ 633 (getattrfunc) 0, /* tp_getattr */
742 (setattrfunc) 0, /* tp_setattr */ 634 (setattrfunc) 0, /* tp_setattr */
743 0, /* tp_reserved */ 635 0, /* tp_reserved */
744 (reprfunc) signaldict_repr, /* tp_repr */ 636 (reprfunc) signaldict_repr, /* tp_repr */
745 0, /* tp_as_number */ 637 0, /* tp_as_number */
746 » &signaldict_as_sequence, /* tp_as_sequence */ 638 » 0, /* tp_as_sequence */
747 &signaldict_as_mapping, /* tp_as_mapping */ 639 &signaldict_as_mapping, /* tp_as_mapping */
748 » (hashfunc) PyObject_HashNotImplemented, /* tp_hash */ 640 » PyObject_HashNotImplemented, /* tp_hash */
749 0, /* tp_call */ 641 0, /* tp_call */
750 (reprfunc) 0, /* tp_str */ 642 (reprfunc) 0, /* tp_str */
751 » (getattrofunc) PyObject_GenericGetAttr, /* tp_getattro */ 643 » PyObject_GenericGetAttr, /* tp_getattro */
752 (setattrofunc) 0, /* tp_setattro */ 644 (setattrofunc) 0, /* tp_setattro */
753 (PyBufferProcs *) 0, /* tp_as_buffer */ 645 (PyBufferProcs *) 0, /* tp_as_buffer */
754 » Py_TPFLAGS_DEFAULT, /* tp_flags */ 646 » Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|
647 » Py_TPFLAGS_HAVE_GC, /* tp_flags */
755 0, /* tp_doc */ 648 0, /* tp_doc */
756 0, /* tp_traverse */ 649 0, /* tp_traverse */
757 0, /* tp_clear */ 650 0, /* tp_clear */
758 signaldict_richcompare, /* tp_richcompare */ 651 signaldict_richcompare, /* tp_richcompare */
759 0, /* tp_weaklistoffset */ 652 0, /* tp_weaklistoffset */
760 (getiterfunc)signaldict_iter, /* tp_iter */ 653 (getiterfunc)signaldict_iter, /* tp_iter */
761 0, /* tp_iternext */ 654 0, /* tp_iternext */
762 » mapp_methods, /* tp_methods */ 655 » signaldict_methods, /* tp_methods */
763 0, /* tp_members */ 656 0, /* tp_members */
764 0, /* tp_getset */ 657 0, /* tp_getset */
765 0, /* tp_base */ 658 0, /* tp_base */
766 0, /* tp_dict */ 659 0, /* tp_dict */
767 0, /* tp_descr_get */ 660 0, /* tp_descr_get */
768 0, /* tp_descr_set */ 661 0, /* tp_descr_set */
769 0, /* tp_dictoffset */ 662 0, /* tp_dictoffset */
770 (initproc)signaldict_init, /* tp_init */ 663 (initproc)signaldict_init, /* tp_init */
664 0, /* tp_alloc */
665 PyType_GenericNew, /* tp_new */
771 }; 666 };
772 667
773 668
774 /******************************************************************************/ 669 /******************************************************************************/
775 /* Context Object, Part 1 */ 670 /* Context Object, Part 1 */
776 /******************************************************************************/ 671 /******************************************************************************/
777 672
778 static PyObject * 673 #define Dec_CONTEXT_GET_SSIZE(mem) \
779 context_getprec(PyObject *self, void *closure UNUSED) 674 static PyObject * \
780 { 675 context_get##mem(PyObject *self, void *closure UNUSED) \
781 » mpd_context_t *ctx; 676 { \
782 677 return PyLong_FromSsize_t(mpd_get##mem(CTX(self))); \
783 » ctx = CTX(self); 678 }
784 » return Py_BuildValue(CONV_mpd_ssize_t, mpd_getprec(ctx)); 679
785 } 680 #define Dec_CONTEXT_GET_ULONG(mem) \
786 681 static PyObject * \
787 static PyObject * 682 context_get##mem(PyObject *self, void *closure UNUSED) \
788 context_getemax(PyObject *self, void *closure UNUSED) 683 { \
789 { 684 return PyLong_FromUnsignedLong(mpd_get##mem(CTX(self))); \
790 » mpd_context_t *ctx; 685 }
791 686
792 » ctx = CTX(self); 687 Dec_CONTEXT_GET_SSIZE(prec)
793 » return Py_BuildValue(CONV_mpd_ssize_t, mpd_getemax(ctx)); 688 Dec_CONTEXT_GET_SSIZE(emax)
794 } 689 Dec_CONTEXT_GET_SSIZE(emin)
795 690 Dec_CONTEXT_GET_SSIZE(round)
796 static PyObject * 691 Dec_CONTEXT_GET_SSIZE(clamp)
797 context_getemin(PyObject *self, void *closure UNUSED) 692
798 { 693 #ifdef EXTRA_FUNCTIONALITY
799 » mpd_context_t *ctx; 694 Dec_CONTEXT_GET_ULONG(traps)
800 695 Dec_CONTEXT_GET_ULONG(status)
801 » ctx = CTX(self); 696 #endif
802 » return Py_BuildValue(CONV_mpd_ssize_t, mpd_getemin(ctx)); 697
803 } 698 static PyObject *
699 context_getcapitals(PyObject *self, void *closure UNUSED)
700 {
701 » return PyLong_FromLong(CtxCaps(self));
702 }
703
704 #ifdef EXTRA_FUNCTIONALITY
705 static PyObject *
706 context_getallcr(PyObject *self, void *closure UNUSED)
707 {
708 » return PyLong_FromLong(mpd_getcr(CTX(self)));
709 }
710 #endif
804 711
805 static PyObject * 712 static PyObject *
806 context_getetiny(PyObject *self, PyObject *dummy UNUSED) 713 context_getetiny(PyObject *self, PyObject *dummy UNUSED)
807 { 714 {
808 » mpd_context_t *ctx; 715 » return PyLong_FromSsize_t(mpd_etiny(CTX(self)));
809
810 » ctx = CTX(self);
811 » return Py_BuildValue(CONV_mpd_ssize_t, mpd_etiny(ctx));
812 } 716 }
813 717
814 static PyObject * 718 static PyObject *
815 context_getetop(PyObject *self, PyObject *dummy UNUSED) 719 context_getetop(PyObject *self, PyObject *dummy UNUSED)
816 { 720 {
817 » mpd_context_t *ctx; 721 » return PyLong_FromSsize_t(mpd_etop(CTX(self)));
818
819 » ctx = CTX(self);
820 » return Py_BuildValue(CONV_mpd_ssize_t, mpd_etop(ctx));
821 }
822
823 static PyObject *
824 context_getround(PyObject *self, void *closure UNUSED)
825 {
826 » mpd_context_t *ctx;
827
828 » ctx = CTX(self);
829 » return Py_BuildValue("i", mpd_getround(ctx));
830 }
831
832 static PyObject *
833 context_getcapitals(PyObject *self, void *closure UNUSED)
834 {
835 » return Py_BuildValue("i", CtxCaps(self));
836 }
837
838 static PyObject *
839 context_gettraps(PyObject *self, void *closure UNUSED)
840 {
841 » mpd_context_t *ctx;
842
843 » ctx = CTX(self);
844 » return Py_BuildValue("i", mpd_gettraps(ctx));
845 }
846
847 static PyObject *
848 context_getstatus(PyObject *self, void *closure UNUSED)
849 {
850 » mpd_context_t *ctx;
851
852 » ctx = CTX(self);
853 » return Py_BuildValue("i", mpd_getstatus(ctx));
854 }
855
856 static PyObject *
857 context_getclamp(PyObject *self, void *closure UNUSED)
858 {
859 » mpd_context_t *ctx;
860
861 » ctx = CTX(self);
862 » return Py_BuildValue("i", mpd_getclamp(ctx));
863 }
864
865 static PyObject *
866 context_getallcr(PyObject *self, void *closure UNUSED)
867 {
868 » mpd_context_t *ctx;
869
870 » ctx = CTX(self);
871 » return Py_BuildValue("i", mpd_getcr(ctx));
872 } 722 }
873 723
874 static int 724 static int
875 context_setprec(PyObject *self, PyObject *value, void *closure UNUSED) 725 context_setprec(PyObject *self, PyObject *value, void *closure UNUSED)
876 { 726 {
877 mpd_context_t *ctx; 727 mpd_context_t *ctx;
878 mpd_ssize_t x; 728 mpd_ssize_t x;
879 729
880 » x = long_as_mpd_ssize(value); 730 » x = PyLong_AsSsize_t(value);
881 » if (PyErr_Occurred()) { 731 » if (x == -1 && PyErr_Occurred()) {
882 return -1; 732 return -1;
883 } 733 }
884 734
885 ctx = CTX(self); 735 ctx = CTX(self);
886 if (!mpd_qsetprec(ctx, x)) { 736 if (!mpd_qsetprec(ctx, x)) {
887 return value_error_int( 737 return value_error_int(
888 » » "valid range for prec is [1, MAX_PREC]."); 738 » » "valid range for prec is [1, MAX_PREC]");
889 } 739 }
890 740
891 return 0; 741 return 0;
892 } 742 }
893 743
894 static int 744 static int
895 context_setemin(PyObject *self, PyObject *value, void *closure UNUSED) 745 context_setemin(PyObject *self, PyObject *value, void *closure UNUSED)
896 { 746 {
897 mpd_context_t *ctx; 747 mpd_context_t *ctx;
898 mpd_ssize_t x; 748 mpd_ssize_t x;
899 749
900 » x = long_as_mpd_ssize(value); 750 » x = PyLong_AsSsize_t(value);
901 » if (PyErr_Occurred()) { 751 » if (x == -1 && PyErr_Occurred()) {
902 return -1; 752 return -1;
903 } 753 }
904 754
905 ctx = CTX(self); 755 ctx = CTX(self);
906 if (!mpd_qsetemin(ctx, x)) { 756 if (!mpd_qsetemin(ctx, x)) {
907 return value_error_int( 757 return value_error_int(
908 » » "valid range for Emin is [MIN_EMIN, 0]."); 758 » » "valid range for Emin is [MIN_EMIN, 0]");
909 } 759 }
910 760
911 return 0; 761 return 0;
912 } 762 }
913 763
914 static int 764 static int
915 context_setemax(PyObject *self, PyObject *value, void *closure UNUSED) 765 context_setemax(PyObject *self, PyObject *value, void *closure UNUSED)
916 { 766 {
917 mpd_context_t *ctx; 767 mpd_context_t *ctx;
918 mpd_ssize_t x; 768 mpd_ssize_t x;
919 769
920 » x = long_as_mpd_ssize(value); 770 » x = PyLong_AsSsize_t(value);
921 » if (PyErr_Occurred()) { 771 » if (x == -1 && PyErr_Occurred()) {
922 return -1; 772 return -1;
923 } 773 }
924 774
925 ctx = CTX(self); 775 ctx = CTX(self);
926 if (!mpd_qsetemax(ctx, x)) { 776 if (!mpd_qsetemax(ctx, x)) {
927 return value_error_int( 777 return value_error_int(
928 » » "valid range for Emax is [0, MAX_EMAX]."); 778 » » "valid range for Emax is [0, MAX_EMAX]");
929 } 779 }
930 780
931 return 0; 781 return 0;
932 } 782 }
933 783
784 #ifdef CONFIG_32
934 static PyObject * 785 static PyObject *
935 context_unsafe_setprec(PyObject *self, PyObject *value) 786 context_unsafe_setprec(PyObject *self, PyObject *value)
936 { 787 {
937 mpd_context_t *ctx = CTX(self); 788 mpd_context_t *ctx = CTX(self);
938 mpd_ssize_t x; 789 mpd_ssize_t x;
939 790
940 » x = long_as_mpd_ssize(value); 791 » x = PyLong_AsSsize_t(value);
941 » if (PyErr_Occurred()) { 792 » if (x == -1 && PyErr_Occurred()) {
942 » » return NULL; 793 » » return NULL;
794 » }
795
796 » if (x < 1 || x > 1070000000L) {
797 » » return value_error_ptr(
798 » » "valid range for unsafe prec is [1, 1070000000]");
943 } 799 }
944 800
945 ctx->prec = x; 801 ctx->prec = x;
946 Py_RETURN_NONE; 802 Py_RETURN_NONE;
947 } 803 }
948 804
949 static PyObject * 805 static PyObject *
950 context_unsafe_setemin(PyObject *self, PyObject *value) 806 context_unsafe_setemin(PyObject *self, PyObject *value)
951 { 807 {
952 mpd_context_t *ctx = CTX(self); 808 mpd_context_t *ctx = CTX(self);
953 mpd_ssize_t x; 809 mpd_ssize_t x;
954 810
955 » x = long_as_mpd_ssize(value); 811 » x = PyLong_AsSsize_t(value);
956 » if (PyErr_Occurred()) { 812 » if (x == -1 && PyErr_Occurred()) {
957 » » return NULL; 813 » » return NULL;
814 » }
815
816 » if (x < -1070000000L || x > 0) {
817 » » return value_error_ptr(
818 » » "valid range for unsafe emin is [-1070000000, 0]");
958 } 819 }
959 820
960 ctx->emin = x; 821 ctx->emin = x;
961 Py_RETURN_NONE; 822 Py_RETURN_NONE;
962 } 823 }
963 824
964 static PyObject * 825 static PyObject *
965 context_unsafe_setemax(PyObject *self, PyObject *value) 826 context_unsafe_setemax(PyObject *self, PyObject *value)
966 { 827 {
967 mpd_context_t *ctx = CTX(self); 828 mpd_context_t *ctx = CTX(self);
968 mpd_ssize_t x; 829 mpd_ssize_t x;
969 830
970 » x = long_as_mpd_ssize(value); 831 » x = PyLong_AsSsize_t(value);
971 » if (PyErr_Occurred()) { 832 » if (x == -1 && PyErr_Occurred()) {
972 » » return NULL; 833 » » return NULL;
834 » }
835
836 » if (x < 0 || x > 1070000000L) {
837 » » return value_error_ptr(
838 » » "valid range for unsafe emax is [0, 1070000000]");
973 } 839 }
974 840
975 ctx->emax = x; 841 ctx->emax = x;
976 Py_RETURN_NONE; 842 Py_RETURN_NONE;
977 } 843 }
844 #endif
978 845
979 static int 846 static int
980 context_setround(PyObject *self, PyObject *value, void *closure UNUSED) 847 context_setround(PyObject *self, PyObject *value, void *closure UNUSED)
981 { 848 {
982 mpd_context_t *ctx; 849 mpd_context_t *ctx;
983 mpd_ssize_t x; 850 mpd_ssize_t x;
984 851
985 » x = long_as_mpd_ssize(value); 852 » x = PyLong_AsSsize_t(value);
986 » if (PyErr_Occurred()) { 853 » if (x == -1 && PyErr_Occurred()) {
987 return -1; 854 return -1;
988 } 855 }
989 BOUNDS_CHECK(x, INT_MIN, INT_MAX); 856 BOUNDS_CHECK(x, INT_MIN, INT_MAX);
990 857
991 ctx = CTX(self); 858 ctx = CTX(self);
992 if (!mpd_qsetround(ctx, (int)x)) { 859 if (!mpd_qsetround(ctx, (int)x)) {
993 return type_error_int(invalid_rounding_err); 860 return type_error_int(invalid_rounding_err);
994 } 861 }
995 862
996 return 0; 863 return 0;
997 } 864 }
998 865
999 static int 866 static int
1000 context_setcapitals(PyObject *self, PyObject *value, void *closure UNUSED) 867 context_setcapitals(PyObject *self, PyObject *value, void *closure UNUSED)
1001 { 868 {
1002 mpd_ssize_t x; 869 mpd_ssize_t x;
1003 870
1004 » x = long_as_mpd_ssize(value); 871 » x = PyLong_AsSsize_t(value);
1005 » if (PyErr_Occurred()) { 872 » if (x == -1 && PyErr_Occurred()) {
1006 return -1; 873 return -1;
1007 } 874 }
1008 BOUNDS_CHECK(x, INT_MIN, INT_MAX);
1009 875
1010 if (x != 0 && x != 1) { 876 if (x != 0 && x != 1) {
1011 return value_error_int( 877 return value_error_int(
1012 » » "valid values for capitals are 0 or 1."); 878 » » "valid values for capitals are 0 or 1");
1013 } 879 }
1014 CtxCaps(self) = (int)x; 880 CtxCaps(self) = (int)x;
1015 881
1016 return 0; 882 return 0;
1017 } 883 }
1018 884
885 #ifdef EXTRA_FUNCTIONALITY
1019 static int 886 static int
1020 context_settraps(PyObject *self, PyObject *value, void *closure UNUSED) 887 context_settraps(PyObject *self, PyObject *value, void *closure UNUSED)
1021 { 888 {
1022 mpd_context_t *ctx; 889 mpd_context_t *ctx;
1023 uint32_t flags; 890 uint32_t flags;
1024 891
1025 flags = long_as_flags(value); 892 flags = long_as_flags(value);
1026 » if (flags == UINT32_MAX) { 893 » if (flags & DEC_ERRORS) {
1027 return -1; 894 return -1;
1028 } 895 }
1029 896
1030 ctx = CTX(self); 897 ctx = CTX(self);
1031 if (!mpd_qsettraps(ctx, flags)) { 898 if (!mpd_qsettraps(ctx, flags)) {
1032 INTERNAL_ERROR_INT("context_settraps"); 899 INTERNAL_ERROR_INT("context_settraps");
1033 } 900 }
1034 901
1035 return 0; 902 return 0;
1036 } 903 }
904 #endif
1037 905
1038 static int 906 static int
1039 context_settraps_list(PyObject *self, PyObject *value) 907 context_settraps_list(PyObject *self, PyObject *value)
1040 { 908 {
1041 mpd_context_t *ctx; 909 mpd_context_t *ctx;
1042 uint32_t flags; 910 uint32_t flags;
1043 911
1044 flags = list_as_flags(value); 912 flags = list_as_flags(value);
1045 » if (flags == UINT32_MAX) { 913 » if (flags & DEC_ERRORS) {
1046 return -1; 914 return -1;
1047 } 915 }
1048 916
1049 ctx = CTX(self); 917 ctx = CTX(self);
1050 if (!mpd_qsettraps(ctx, flags)) { 918 if (!mpd_qsettraps(ctx, flags)) {
1051 INTERNAL_ERROR_INT("context_settraps_list"); 919 INTERNAL_ERROR_INT("context_settraps_list");
1052 } 920 }
1053 921
1054 return 0; 922 return 0;
1055 } 923 }
1056 924
1057 static int 925 static int
1058 context_settraps_dict(PyObject *self, PyObject *value) 926 context_settraps_dict(PyObject *self, PyObject *value)
1059 { 927 {
1060 mpd_context_t *ctx; 928 mpd_context_t *ctx;
1061 uint32_t flags; 929 uint32_t flags;
1062 930
1063 » flags = dict_as_flags(value); 931 » if (PyDecSignalDict_Check(value)) {
1064 » if (flags == UINT32_MAX) { 932 » » flags = SdFlags(value);
1065 » » return -1; 933 » }
934 » else {
935 » » flags = dict_as_flags(value);
936 » » if (flags & DEC_ERRORS) {
937 » » » return -1;
938 » » }
1066 } 939 }
1067 940
1068 ctx = CTX(self); 941 ctx = CTX(self);
1069 if (!mpd_qsettraps(ctx, flags)) { 942 if (!mpd_qsettraps(ctx, flags)) {
1070 INTERNAL_ERROR_INT("context_settraps_dict"); 943 INTERNAL_ERROR_INT("context_settraps_dict");
1071 } 944 }
1072 945
1073 return 0; 946 return 0;
1074 } 947 }
1075 948
949 #ifdef EXTRA_FUNCTIONALITY
1076 static int 950 static int
1077 context_setstatus(PyObject *self, PyObject *value, void *closure UNUSED) 951 context_setstatus(PyObject *self, PyObject *value, void *closure UNUSED)
1078 { 952 {
1079 mpd_context_t *ctx; 953 mpd_context_t *ctx;
1080 uint32_t flags; 954 uint32_t flags;
1081 955
1082 flags = long_as_flags(value); 956 flags = long_as_flags(value);
1083 » if (flags == UINT32_MAX) { 957 » if (flags & DEC_ERRORS) {
1084 return -1; 958 return -1;
1085 } 959 }
1086 960
1087 ctx = CTX(self); 961 ctx = CTX(self);
1088 if (!mpd_qsetstatus(ctx, flags)) { 962 if (!mpd_qsetstatus(ctx, flags)) {
1089 INTERNAL_ERROR_INT("context_setstatus"); 963 INTERNAL_ERROR_INT("context_setstatus");
1090 } 964 }
1091 965
1092 return 0; 966 return 0;
1093 } 967 }
968 #endif
1094 969
1095 static int 970 static int
1096 context_setstatus_list(PyObject *self, PyObject *value) 971 context_setstatus_list(PyObject *self, PyObject *value)
1097 { 972 {
1098 mpd_context_t *ctx; 973 mpd_context_t *ctx;
1099 uint32_t flags; 974 uint32_t flags;
1100 975
1101 flags = list_as_flags(value); 976 flags = list_as_flags(value);
1102 » if (flags == UINT32_MAX) { 977 » if (flags & DEC_ERRORS) {
1103 return -1; 978 return -1;
1104 } 979 }
1105 980
1106 ctx = CTX(self); 981 ctx = CTX(self);
1107 if (!mpd_qsetstatus(ctx, flags)) { 982 if (!mpd_qsetstatus(ctx, flags)) {
1108 INTERNAL_ERROR_INT("context_setstatus_list"); 983 INTERNAL_ERROR_INT("context_setstatus_list");
1109 } 984 }
1110 985
1111 return 0; 986 return 0;
1112 } 987 }
1113 988
1114 static int 989 static int
1115 context_setstatus_dict(PyObject *self, PyObject *value) 990 context_setstatus_dict(PyObject *self, PyObject *value)
1116 { 991 {
1117 mpd_context_t *ctx; 992 mpd_context_t *ctx;
1118 uint32_t flags; 993 uint32_t flags;
1119 994
1120 » flags = dict_as_flags(value); 995 » if (PyDecSignalDict_Check(value)) {
1121 » if (flags == UINT32_MAX) { 996 » » flags = SdFlags(value);
1122 » » return -1; 997 » }
998 » else {
999 » » flags = dict_as_flags(value);
1000 » » if (flags & DEC_ERRORS) {
1001 » » » return -1;
1002 » » }
1123 } 1003 }
1124 1004
1125 ctx = CTX(self); 1005 ctx = CTX(self);
1126 if (!mpd_qsetstatus(ctx, flags)) { 1006 if (!mpd_qsetstatus(ctx, flags)) {
1127 INTERNAL_ERROR_INT("context_setstatus_dict"); 1007 INTERNAL_ERROR_INT("context_setstatus_dict");
1128 } 1008 }
1129 1009
1130 return 0; 1010 return 0;
1131 } 1011 }
1132 1012
1133 static int 1013 static int
1134 context_setclamp(PyObject *self, PyObject *value, void *closure UNUSED) 1014 context_setclamp(PyObject *self, PyObject *value, void *closure UNUSED)
1135 { 1015 {
1136 mpd_context_t *ctx; 1016 mpd_context_t *ctx;
1137 mpd_ssize_t x; 1017 mpd_ssize_t x;
1138 1018
1139 » x = long_as_mpd_ssize(value); 1019 » x = PyLong_AsSsize_t(value);
1140 » if (PyErr_Occurred()) { 1020 » if (x == -1 && PyErr_Occurred()) {
1141 return -1; 1021 return -1;
1142 } 1022 }
1143 BOUNDS_CHECK(x, INT_MIN, INT_MAX); 1023 BOUNDS_CHECK(x, INT_MIN, INT_MAX);
1144 1024
1145 ctx = CTX(self); 1025 ctx = CTX(self);
1146 if (!mpd_qsetclamp(ctx, (int)x)) { 1026 if (!mpd_qsetclamp(ctx, (int)x)) {
1147 » » return value_error_int("valid values for clamp are 0 or 1."); 1027 » » return value_error_int("valid values for clamp are 0 or 1");
1148 } 1028 }
1149 1029
1150 return 0; 1030 return 0;
1151 } 1031 }
1152 1032
1033 #ifdef EXTRA_FUNCTIONALITY
1153 static int 1034 static int
1154 context_setallcr(PyObject *self, PyObject *value, void *closure UNUSED) 1035 context_setallcr(PyObject *self, PyObject *value, void *closure UNUSED)
1155 { 1036 {
1156 mpd_context_t *ctx; 1037 mpd_context_t *ctx;
1157 mpd_ssize_t x; 1038 mpd_ssize_t x;
1158 1039
1159 » x = long_as_mpd_ssize(value); 1040 » x = PyLong_AsSsize_t(value);
1160 » if (PyErr_Occurred()) { 1041 » if (x == -1 && PyErr_Occurred()) {
1161 return -1; 1042 return -1;
1162 } 1043 }
1163 BOUNDS_CHECK(x, INT_MIN, INT_MAX); 1044 BOUNDS_CHECK(x, INT_MIN, INT_MAX);
1164 1045
1165 ctx = CTX(self); 1046 ctx = CTX(self);
1166 if (!mpd_qsetcr(ctx, (int)x)) { 1047 if (!mpd_qsetcr(ctx, (int)x)) {
1167 » » return value_error_int("valid values for _allcr are 0 or 1."); 1048 » » return value_error_int("valid values for _allcr are 0 or 1");
1168 } 1049 }
1169 1050
1170 return 0; 1051 return 0;
1171 } 1052 }
1053 #endif
1172 1054
1173 static PyObject * 1055 static PyObject *
1174 context_getattr(PyObject *self, PyObject *name) 1056 context_getattr(PyObject *self, PyObject *name)
1175 { 1057 {
1176 PyObject *retval; 1058 PyObject *retval;
1177 1059
1178 » if (!PyUnicode_Check(name)) { 1060 » if (PyUnicode_Check(name)) {
1179 » » PyErr_Format(PyExc_TypeError, /* GCOV_NOT_REACHED (why?) */ 1061 » » if (PyUnicode_CompareWithASCIIString(name, "traps") == 0) {
1180 » » "attribute name must be string, not '%.200s'", 1062 » » » retval = ((PyDecContextObject *)self)->traps;
1181 » » name->ob_type->tp_name); /* GCOV_NOT_REACHED */ 1063 » » » Py_INCREF(retval);
1182 » » return NULL; /* GCOV_NOT_REACHED */ 1064 » » » return retval;
1183 » } 1065 » » }
1184 1066 » » if (PyUnicode_CompareWithASCIIString(name, "flags") == 0) {
1185 » if (PyUnicode_CompareWithASCIIString(name, "traps") == 0) { 1067 » » » retval = ((PyDecContextObject *)self)->flags;
1186 » » retval = ((PyDecContextObject *)self)->traps; 1068 » » » Py_INCREF(retval);
1187 » » Py_INCREF(retval); 1069 » » » return retval;
1188 » » return retval; 1070 » » }
1189 » } 1071 » }
1190 » else if (PyUnicode_CompareWithASCIIString(name, "flags") == 0) { 1072
1191 » » retval = ((PyDecContextObject *)self)->flags; 1073 » return PyObject_GenericGetAttr(self, name);
1192 » » Py_INCREF(retval);
1193 » » return retval;
1194 » }
1195 » else {
1196 » » return PyObject_GenericGetAttr(self, name);
1197 » }
1198 } 1074 }
1199 1075
1200 static int 1076 static int
1201 context_setattr(PyObject *self, PyObject *name, PyObject *value) 1077 context_setattr(PyObject *self, PyObject *name, PyObject *value)
1202 { 1078 {
1203 if (!PyUnicode_Check(name)) {
1204 PyErr_Format(PyExc_TypeError, /* GCOV_NOT_REACHED (why?) */
1205 "attribute name must be string, not '%.200s'",
1206 name->ob_type->tp_name); /* GCOV_NOT_REACHED */
1207 return -1; /* GCOV_NOT_REACHED */
1208 }
1209 if (value == NULL) { 1079 if (value == NULL) {
1210 PyErr_SetString(PyExc_AttributeError, 1080 PyErr_SetString(PyExc_AttributeError,
1211 » » "context attributes cannot be deleted."); 1081 » » "context attributes cannot be deleted");
1212 return -1; 1082 return -1;
1213 } 1083 }
1214 1084
1215 » if (PyUnicode_CompareWithASCIIString(name, "traps") == 0) { 1085 » if (PyUnicode_Check(name)) {
1216 » » return context_settraps_dict(self, value); 1086 » » if (PyUnicode_CompareWithASCIIString(name, "traps") == 0) {
1217 » } 1087 » » » return context_settraps_dict(self, value);
1218 » else if (PyUnicode_CompareWithASCIIString(name, "flags") == 0) { 1088 » » }
1219 » » return context_setstatus_dict(self, value); 1089 » » if (PyUnicode_CompareWithASCIIString(name, "flags") == 0) {
1220 » } 1090 » » » return context_setstatus_dict(self, value);
1221 » else { 1091 » » }
1222 » » return PyObject_GenericSetAttr(self, name, value); 1092 » }
1223 » } 1093
1094 » return PyObject_GenericSetAttr(self, name, value);
1224 } 1095 }
1225 1096
1226 static PyObject * 1097 static PyObject *
1227 context_clear_traps(PyObject *self, PyObject *dummy UNUSED) 1098 context_clear_traps(PyObject *self, PyObject *dummy UNUSED)
1228 { 1099 {
1229 » PyDecContextObject *decctx = (PyDecContextObject *)self; 1100 » CTX(self)->traps = 0;
1230
1231 » if (signaldict_clear_all(decctx->traps) < 0) {
1232 » » return NULL;
1233 » }
1234 Py_RETURN_NONE; 1101 Py_RETURN_NONE;
1235 } 1102 }
1236 1103
1237 static PyObject * 1104 static PyObject *
1238 context_clear_flags(PyObject *self, PyObject *dummy UNUSED) 1105 context_clear_flags(PyObject *self, PyObject *dummy UNUSED)
1239 { 1106 {
1240 » PyDecContextObject *decctx = (PyDecContextObject *)self; 1107 » CTX(self)->status = 0;
1241
1242 » if (signaldict_clear_all(decctx->flags) < 0) {
1243 » » return NULL;
1244 » }
1245 Py_RETURN_NONE; 1108 Py_RETURN_NONE;
1246 } 1109 }
1247 1110
1248 static PyObject * 1111 static PyObject *
1249 context_new(PyTypeObject *type UNUSED, PyObject *args UNUSED, 1112 context_new(PyTypeObject *type UNUSED, PyObject *args UNUSED,
1250 PyObject *kwds UNUSED) 1113 PyObject *kwds UNUSED)
1251 { 1114 {
1252 PyDecContextObject *self = NULL; 1115 PyDecContextObject *self = NULL;
1253 mpd_context_t *ctx; 1116 mpd_context_t *ctx;
1254 1117
1255 self = PyObject_New(PyDecContextObject, &PyDecContext_Type); 1118 self = PyObject_New(PyDecContextObject, &PyDecContext_Type);
1256 if (self == NULL) { 1119 if (self == NULL) {
1257 return NULL; 1120 return NULL;
1258 } 1121 }
1259 1122
1260 » self->traps = PyObject_CallObject((PyObject *)&PyDecSignalDict_Type, NUL L); 1123 » self->traps = PyObject_CallObject((PyObject *)PyDecSignalDict_Type, NULL );
1261 if (self->traps == NULL) { 1124 if (self->traps == NULL) {
1262 self->flags = NULL; 1125 self->flags = NULL;
1263 Py_DECREF(self); 1126 Py_DECREF(self);
1264 return NULL; 1127 return NULL;
1265 } 1128 }
1266 » self->flags = PyObject_CallObject((PyObject *)&PyDecSignalDict_Type, NUL L); 1129 » self->flags = PyObject_CallObject((PyObject *)PyDecSignalDict_Type, NULL );
1267 if (self->flags == NULL) { 1130 if (self->flags == NULL) {
1268 Py_DECREF(self); 1131 Py_DECREF(self);
1269 return NULL; 1132 return NULL;
1270 } 1133 }
1271 1134
1272 ctx = CTX(self); 1135 ctx = CTX(self);
1273 SdFlagAddr(self->traps) = &ctx->traps; 1136 SdFlagAddr(self->traps) = &ctx->traps;
1274 SdFlagAddr(self->flags) = &ctx->status; 1137 SdFlagAddr(self->flags) = &ctx->status;
1275 1138
1276 return (PyObject *)self; 1139 return (PyObject *)self;
(...skipping 23 matching lines...) Expand all
1300 1163
1301 static int 1164 static int
1302 getround(PyObject *v) 1165 getround(PyObject *v)
1303 { 1166 {
1304 const char *s; 1167 const char *s;
1305 long x; 1168 long x;
1306 int i; 1169 int i;
1307 1170
1308 if (PyLong_Check(v)) { 1171 if (PyLong_Check(v)) {
1309 x = PyLong_AsLong(v); 1172 x = PyLong_AsLong(v);
1310 » » if (PyErr_Occurred()) { 1173 » » if (x == -1 && PyErr_Occurred()) {
1311 return -1; 1174 return -1;
1312 } 1175 }
1313 BOUNDS_CHECK(x, 0, INT_MAX); 1176 BOUNDS_CHECK(x, 0, INT_MAX);
1314 return (int)x; 1177 return (int)x;
1315 } 1178 }
1316 else if (PyUnicode_Check(v)) { 1179 else if (PyUnicode_Check(v)) {
1317 for (i = 0; i < MPD_ROUND_GUARD; i++) { 1180 for (i = 0; i < MPD_ROUND_GUARD; i++) {
1318 s = mpd_round_string[i]; 1181 s = mpd_round_string[i];
1319 if (PyUnicode_CompareWithASCIIString(v, s) == 0) { 1182 if (PyUnicode_CompareWithASCIIString(v, s) == 0) {
1320 return i; 1183 return i;
1321 } 1184 }
1322 } 1185 }
1323 } 1186 }
1324 1187
1325 » return type_error_int("invalid rounding mode."); 1188 » return type_error_int("invalid rounding mode");
1326 } 1189 }
1327 1190
1328 static int 1191 static int
1329 context_init(PyObject *self, PyObject *args, PyObject *kwds) 1192 context_init(PyObject *self, PyObject *args, PyObject *kwds)
1330 { 1193 {
1331 static char *kwlist[] = { 1194 static char *kwlist[] = {
1332 "prec", "rounding", "Emin", "Emax", "capitals", "clamp", 1195 "prec", "rounding", "Emin", "Emax", "capitals", "clamp",
1333 "flags", "traps", "_allcr", NULL 1196 "flags", "traps", "_allcr", NULL
1334 }; 1197 };
1335 PyObject *rounding = NULL; 1198 PyObject *rounding = NULL;
1336 PyObject *traps = NULL; 1199 PyObject *traps = NULL;
1337 PyObject *status = NULL; 1200 PyObject *status = NULL;
1338 mpd_context_t *ctx, t=dflt_ctx; 1201 mpd_context_t *ctx, t=dflt_ctx;
1339 int capitals = 1; 1202 int capitals = 1;
1340 int ret; 1203 int ret;
1341 1204
1342 assert(PyTuple_Check(args)); 1205 assert(PyTuple_Check(args));
1343 ctx = CTX(self); 1206 ctx = CTX(self);
1344 1207
1345 if (default_context_template) { 1208 if (default_context_template) {
1346 t = *CTX(default_context_template); 1209 t = *CTX(default_context_template);
1347 } 1210 }
1348 if (!PyArg_ParseTupleAndKeywords( 1211 if (!PyArg_ParseTupleAndKeywords(
1349 args, kwds, 1212 args, kwds,
1350 » "|" CONV_mpd_ssize_t "O" CONV_mpd_ssize_t CONV_mpd_ssize_t "ii" 1213 » "|nOnniiOOi", kwlist,
1351 » "OOi", kwlist,
1352 &t.prec, &rounding, &t.emin, &t.emax, &capitals, &t.clamp, 1214 &t.prec, &rounding, &t.emin, &t.emax, &capitals, &t.clamp,
1353 &status, &traps, &t.allcr 1215 &status, &traps, &t.allcr
1354 )) { 1216 )) {
1355 return -1; 1217 return -1;
1356 } 1218 }
1357 if (rounding != NULL) { 1219 if (rounding != NULL) {
1358 » » if ((t.round = getround(rounding)) < 0) { 1220 » » t.round = getround(rounding);
1221 » » if (t.round < 0) {
1359 return -1; 1222 return -1;
1360 } 1223 }
1361 } 1224 }
1362 1225
1363 if (!mpd_qsetprec(ctx, t.prec) || 1226 if (!mpd_qsetprec(ctx, t.prec) ||
1364 !mpd_qsetemin(ctx, t.emin) || 1227 !mpd_qsetemin(ctx, t.emin) ||
1365 !mpd_qsetemax(ctx, t.emax) || 1228 !mpd_qsetemax(ctx, t.emax) ||
1366 !mpd_qsetclamp(ctx, t.clamp) || 1229 !mpd_qsetclamp(ctx, t.clamp) ||
1367 !mpd_qsetcr(ctx, t.allcr)) { 1230 !mpd_qsetcr(ctx, t.allcr)) {
1368 » » return value_error_int("invalid context."); 1231 » » return value_error_int("invalid context");
1369 } 1232 }
1370 if (!mpd_qsetround(ctx, t.round) || 1233 if (!mpd_qsetround(ctx, t.round) ||
1371 !mpd_qsettraps(ctx, t.traps) || 1234 !mpd_qsettraps(ctx, t.traps) ||
1372 !mpd_qsetstatus(ctx, t.status)) { 1235 !mpd_qsetstatus(ctx, t.status)) {
1373 » » return type_error_int("invalid context."); 1236 » » return type_error_int("invalid context");
1374 } 1237 }
1375 1238
1376 if (capitals != 0 && capitals != 1) { 1239 if (capitals != 0 && capitals != 1) {
1377 » » return value_error_int("invalid context."); 1240 » » return value_error_int("invalid context");
1378 } 1241 }
1379 CtxCaps(self) = capitals; 1242 CtxCaps(self) = capitals;
1380 1243
1381 if (traps != NULL) { 1244 if (traps != NULL) {
1382 » » if (PyLong_Check(traps)) { 1245 » » if (PyList_Check(traps)) {
1246 » » » ret = context_settraps_list(self, traps);
1247 » » }
1248 #ifdef EXTRA_FUNCTIONALITY
1249 » » else if (PyLong_Check(traps)) {
1383 ret = context_settraps(self, traps, NULL); 1250 ret = context_settraps(self, traps, NULL);
1384 } 1251 }
1385 » » else if (PyList_Check(traps)) { 1252 #endif
1386 » » » ret = context_settraps_list(self, traps);
1387 » » }
1388 else { 1253 else {
1389 ret = context_settraps_dict(self, traps); 1254 ret = context_settraps_dict(self, traps);
1390 } 1255 }
1391 if (ret < 0) { 1256 if (ret < 0) {
1392 return ret; 1257 return ret;
1393 } 1258 }
1394 } 1259 }
1395 if (status != NULL) { 1260 if (status != NULL) {
1396 » » if (PyLong_Check(status)) { 1261 » » if (PyList_Check(status)) {
1262 » » » ret = context_setstatus_list(self, status);
1263 » » }
1264 #ifdef EXTRA_FUNCTIONALITY
1265 » » else if (PyLong_Check(status)) {
1397 ret = context_setstatus(self, status, NULL); 1266 ret = context_setstatus(self, status, NULL);
1398 } 1267 }
1399 » » else if (PyList_Check(status)) { 1268 #endif
1400 » » » ret = context_setstatus_list(self, status);
1401 » » }
1402 else { 1269 else {
1403 ret = context_setstatus_dict(self, status); 1270 ret = context_setstatus_dict(self, status);
1404 } 1271 }
1405 if (ret < 0) { 1272 if (ret < 0) {
1406 return ret; 1273 return ret;
1407 } 1274 }
1408 } 1275 }
1409 1276
1410 return 0; 1277 return 0;
1411 } 1278 }
1412 1279
1413 #define FD_CTX_LEN 432
1414 static PyObject * 1280 static PyObject *
1415 context_repr(PyDecContextObject *self) 1281 context_repr(PyDecContextObject *self)
1416 { 1282 {
1417 mpd_context_t *ctx; 1283 mpd_context_t *ctx;
1418 » char s[FD_CTX_LEN]; 1284 » char flags[MPD_MAX_SIGNAL_LIST];
1419 » char *cp; 1285 » char traps[MPD_MAX_SIGNAL_LIST];
1420 int n, mem; 1286 int n, mem;
1421 1287
1422 assert(PyDecContext_Check(self)); 1288 assert(PyDecContext_Check(self));
1423 ctx = CTX(self); 1289 ctx = CTX(self);
1424 1290
1425 » cp = s; mem = FD_CTX_LEN; 1291 » mem = MPD_MAX_SIGNAL_LIST;
1426 » n = snprintf(cp, mem, 1292 » n = mpd_lsnprint_signals(flags, mem, ctx->status, dec_signal_string);
1427 » "Context(prec=%"PRI_mpd_ssize_t", rounding=%s, " 1293 » if (n < 0 || n >= mem) {
1428 » "Emin=%"PRI_mpd_ssize_t", Emax=%"PRI_mpd_ssize_t", " 1294 » » INTERNAL_ERROR_PTR("context_repr");
1429 » "capitals=%d, clamp=%d, flags=", 1295 » }
1430 » ctx->prec, mpd_round_string[ctx->round], 1296
1431 » ctx->emin, ctx->emax, 1297 » n = mpd_lsnprint_signals(traps, mem, ctx->traps, dec_signal_string);
1432 » self->capitals, ctx->clamp); 1298 » if (n < 0 || n >= mem) {
1433 » if (n < 0 || n >= mem) goto error; 1299 » » INTERNAL_ERROR_PTR("context_repr");
1434 » cp += n; mem -= n; 1300 » }
1435 1301
1436 » n = mpd_lsnprint_signals(cp, mem, ctx->status, dec_signal_string); 1302 » return PyUnicode_FromFormat(
1437 » if (n < 0 || n >= mem) goto error; 1303 » "Context(prec=%zd, rounding=%s, Emin=%zd, Emax=%zd, "
1438 » cp += n; mem -= n; 1304 » "capitals=%d, clamp=%d, flags=%s, traps=%s)",
1439 1305 » ctx->prec, mpd_round_string[ctx->round], ctx->emin, ctx->emax,
1440 » n = snprintf(cp, mem, ", traps="); 1306 » self->capitals, ctx->clamp, flags, traps);
1441 » if (n < 0 || n >= mem) goto error;
1442 » cp += n; mem -= n;
1443
1444 » n = mpd_lsnprint_signals(cp, mem, ctx->traps, dec_signal_string);
1445 » if (n < 0 || n >= mem) goto error;
1446 » cp += n; mem -= n;
1447
1448 » n = snprintf(cp, mem, ")");
1449 » if (n < 0 || n >= mem) goto error;
1450
1451 » return PyUnicode_FromString(s);
1452
1453 error:
1454 » INTERNAL_ERROR_PTR("context_repr");
1455 } 1307 }
1456 1308
1457 static void 1309 static void
1458 init_basic_context(PyObject *v) 1310 init_basic_context(PyObject *v)
1459 { 1311 {
1460 mpd_context_t ctx = dflt_ctx; 1312 mpd_context_t ctx = dflt_ctx;
1461 1313
1462 ctx.prec = 9; 1314 ctx.prec = 9;
1463 ctx.traps |= (MPD_Underflow|MPD_Clamped); 1315 ctx.traps |= (MPD_Underflow|MPD_Clamped);
1464 ctx.round = MPD_ROUND_HALF_UP; 1316 ctx.round = MPD_ROUND_HALF_UP;
1465 1317
1466 *CTX(v) = ctx; 1318 *CTX(v) = ctx;
1467 CtxCaps(v) = 1; 1319 CtxCaps(v) = 1;
1468 } 1320 }
1469 1321
1470 static void 1322 static void
1471 init_extended_context(PyObject *v) 1323 init_extended_context(PyObject *v)
1472 { 1324 {
1473 mpd_context_t ctx = dflt_ctx; 1325 mpd_context_t ctx = dflt_ctx;
1474 1326
1475 ctx.prec = 9; 1327 ctx.prec = 9;
1476 ctx.traps = 0; 1328 ctx.traps = 0;
1477 1329
1478 *CTX(v) = ctx; 1330 *CTX(v) = ctx;
1479 CtxCaps(v) = 1; 1331 CtxCaps(v) = 1;
1480 } 1332 }
1481 1333
1334 #ifdef EXTRA_FUNCTIONALITY
1482 /* Factory function for creating IEEE interchange format contexts */ 1335 /* Factory function for creating IEEE interchange format contexts */
1483 static PyObject * 1336 static PyObject *
1484 ieee_context(PyObject *dummy UNUSED, PyObject *v) 1337 ieee_context(PyObject *dummy UNUSED, PyObject *v)
1485 { 1338 {
1486 PyObject *context; 1339 PyObject *context;
1487 mpd_ssize_t bits; 1340 mpd_ssize_t bits;
1488 mpd_context_t ctx; 1341 mpd_context_t ctx;
1489 1342
1490 » bits = long_as_mpd_ssize(v); 1343 » bits = PyLong_AsSsize_t(v);
1491 » if (PyErr_Occurred()) { 1344 » if (bits == -1 && PyErr_Occurred()) {
1492 return NULL; 1345 return NULL;
1493 } 1346 }
1494 if (bits <= 0 || bits > INT_MAX) { 1347 if (bits <= 0 || bits > INT_MAX) {
1495 goto error; 1348 goto error;
1496 } 1349 }
1497 if (mpd_ieee_context(&ctx, (int)bits) < 0) { 1350 if (mpd_ieee_context(&ctx, (int)bits) < 0) {
1498 goto error; 1351 goto error;
1499 } 1352 }
1500 1353
1501 context = PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL); 1354 context = PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL);
1502 if (context == NULL) { 1355 if (context == NULL) {
1503 return NULL; 1356 return NULL;
1504 } 1357 }
1505 *CTX(context) = ctx; 1358 *CTX(context) = ctx;
1506 1359
1507 return context; 1360 return context;
1508 1361
1509 error: 1362 error:
1510 PyErr_Format(PyExc_ValueError, 1363 PyErr_Format(PyExc_ValueError,
1511 » "argument must be a multiple of 32, with a maximum of %d.", 1364 » "argument must be a multiple of 32, with a maximum of %d",
1512 MPD_IEEE_CONTEXT_MAX_BITS); 1365 MPD_IEEE_CONTEXT_MAX_BITS);
1513 1366
1514 return NULL; 1367 return NULL;
1515 } 1368 }
1369 #endif
1516 1370
1517 static PyObject * 1371 static PyObject *
1518 context_copy(PyObject *self) 1372 context_copy(PyObject *self)
1519 { 1373 {
1520 PyObject *copy; 1374 PyObject *copy;
1521 1375
1522 copy = PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL); 1376 copy = PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL);
1523 if (copy == NULL) { 1377 if (copy == NULL) {
1524 return NULL; 1378 return NULL;
1525 } 1379 }
1526 1380
1527 *CTX(copy) = *CTX(self); 1381 *CTX(copy) = *CTX(self);
1528 CTX(copy)->newtrap = 0; 1382 CTX(copy)->newtrap = 0;
1529 CtxCaps(copy) = CtxCaps(self); 1383 CtxCaps(copy) = CtxCaps(self);
1530 1384
1531 return copy; 1385 return copy;
1532 } 1386 }
1533 1387
1534 static PyObject * 1388 static PyObject *
1535 context_reduce(PyObject *self, PyObject *args UNUSED) 1389 context_reduce(PyObject *self, PyObject *args UNUSED)
1536 { 1390 {
1537 PyObject *flags; 1391 PyObject *flags;
1538 PyObject *traps; 1392 PyObject *traps;
1539 PyObject *ret; 1393 PyObject *ret;
1540 mpd_context_t *ctx; 1394 mpd_context_t *ctx;
1541 1395
1542 ctx = CTX(self); 1396 ctx = CTX(self);
1543 1397
1544 » if ((flags = signals_as_list(ctx->status)) == NULL) { 1398 » flags = signals_as_list(ctx->status);
1545 » » return NULL; 1399 » if (flags == NULL) {
1546 » } 1400 » » return NULL;
1547 » if ((traps = signals_as_list(ctx->traps)) == NULL) { 1401 » }
1402 » traps = signals_as_list(ctx->traps);
1403 » if (traps == NULL) {
1548 Py_DECREF(flags); 1404 Py_DECREF(flags);
1549 return NULL; 1405 return NULL;
1550 } 1406 }
1551 1407
1552 ret = Py_BuildValue( 1408 ret = Py_BuildValue(
1553 » "O(" CONV_mpd_ssize_t "s" CONV_mpd_ssize_t CONV_mpd_ssize_t 1409 » "O(nsnniiOO)",
1554 » "iiOO)",
1555 Py_TYPE(self), 1410 Py_TYPE(self),
1556 ctx->prec, mpd_round_string[ctx->round], ctx->emin, ctx->emax, 1411 ctx->prec, mpd_round_string[ctx->round], ctx->emin, ctx->emax,
1557 CtxCaps(self), ctx->clamp, flags, traps 1412 CtxCaps(self), ctx->clamp, flags, traps
1558 ); 1413 );
1559 1414
1560 Py_DECREF(flags); 1415 Py_DECREF(flags);
1561 Py_DECREF(traps); 1416 Py_DECREF(traps);
1562 return ret; 1417 return ret;
1563 }
1564
1565 static PyObject *
1566 PyDec_SetStatusFromList(PyObject *self, PyObject *value)
1567 {
1568 if (context_setstatus_list(self, value) < 0) {
1569 return NULL;
1570 }
1571 Py_RETURN_NONE;
1572 }
1573
1574 static PyObject *
1575 PyDec_SetTrapsFromList(PyObject *self, PyObject *value)
1576 {
1577 if (context_settraps_list(self, value) < 0) {
1578 return NULL;
1579 }
1580 Py_RETURN_NONE;
1581 } 1418 }
1582 1419
1583 1420
1584 static PyGetSetDef context_getsets [] = 1421 static PyGetSetDef context_getsets [] =
1585 { 1422 {
1586 { "prec", (getter)context_getprec, (setter)context_setprec, NULL, NULL}, 1423 { "prec", (getter)context_getprec, (setter)context_setprec, NULL, NULL},
1587 { "Emax", (getter)context_getemax, (setter)context_setemax, NULL, NULL}, 1424 { "Emax", (getter)context_getemax, (setter)context_setemax, NULL, NULL},
1588 { "Emin", (getter)context_getemin, (setter)context_setemin, NULL, NULL}, 1425 { "Emin", (getter)context_getemin, (setter)context_setemin, NULL, NULL},
1589 { "rounding", (getter)context_getround, (setter)context_setround, NULL, NULL}, 1426 { "rounding", (getter)context_getround, (setter)context_setround, NULL, NULL},
1590 { "capitals", (getter)context_getcapitals, (setter)context_setcapitals, NULL, NULL}, 1427 { "capitals", (getter)context_getcapitals, (setter)context_setcapitals, NULL, NULL},
1591 { "clamp", (getter)context_getclamp, (setter)context_setclamp, NULL, NULL}, 1428 { "clamp", (getter)context_getclamp, (setter)context_setclamp, NULL, NULL},
1592 { "_clamp", (getter)context_getclamp, (setter)context_setclamp, NULL, NULL}, 1429 #ifdef EXTRA_FUNCTIONALITY
1593 { "_allcr", (getter)context_getallcr, (setter)context_setallcr, NULL, NULL}, 1430 { "_allcr", (getter)context_getallcr, (setter)context_setallcr, NULL, NULL},
1594 { "_traps", (getter)context_gettraps, (setter)context_settraps, NULL, NULL}, 1431 { "_traps", (getter)context_gettraps, (setter)context_settraps, NULL, NULL},
1595 { "_flags", (getter)context_getstatus, (setter)context_setstatus, NULL, NULL}, 1432 { "_flags", (getter)context_getstatus, (setter)context_setstatus, NULL, NULL},
1433 #endif
1596 {NULL} 1434 {NULL}
1597 }; 1435 };
1598 1436
1599 1437
1600 #define CONTEXT_CHECK(obj) \ 1438 #define CONTEXT_CHECK(obj) \
1601 if (!PyDecContext_Check(obj)) { \ 1439 if (!PyDecContext_Check(obj)) { \
1602 PyErr_SetString(PyExc_TypeError, \ 1440 PyErr_SetString(PyExc_TypeError, \
1603 "argument must be a context."); \ 1441 "argument must be a context"); \
1604 return NULL; \ 1442 return NULL; \
1605 } 1443 }
1606 1444
1607 #define CONTEXT_CHECK_VA(obj) \ 1445 #define CONTEXT_CHECK_VA(obj) \
1608 if (!PyDecContext_Check(obj)) { \ 1446 if (!PyDecContext_Check(obj)) { \
1609 PyErr_SetString(PyExc_TypeError, \ 1447 PyErr_SetString(PyExc_TypeError, \
1610 "optional argument must be a context."); \ 1448 "optional argument must be a context"); \
1611 return NULL; \ 1449 return NULL; \
1612 } 1450 }
1613 1451
1614 1452
1615 /******************************************************************************/ 1453 /******************************************************************************/
1616 /* Global, thread local and temporary contexts */ 1454 /* Global, thread local and temporary contexts */
1617 /******************************************************************************/ 1455 /******************************************************************************/
1618 1456
1619 #ifdef WITHOUT_THREADS 1457 #ifdef WITHOUT_THREADS
1620 /* Return borrowed reference to the current context. When compiled 1458 /* Return borrowed reference to the current context. When compiled
1621 * without threads, this is always the module context. */ 1459 * without threads, this is always the module context. */
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1659 static PyObject * 1497 static PyObject *
1660 PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v) 1498 PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v)
1661 { 1499 {
1662 CONTEXT_CHECK(v); 1500 CONTEXT_CHECK(v);
1663 1501
1664 /* If the new context is one of the templates, make a copy. 1502 /* If the new context is one of the templates, make a copy.
1665 * This is the current behavior of decimal.py. */ 1503 * This is the current behavior of decimal.py. */
1666 if (v == default_context_template || 1504 if (v == default_context_template ||
1667 v == basic_context_template || 1505 v == basic_context_template ||
1668 v == extended_context_template) { 1506 v == extended_context_template) {
1669 » » if ((v = context_copy(v)) == NULL) { 1507 » » v = context_copy(v);
1508 » » if (v == NULL) {
1670 return NULL; 1509 return NULL;
1671 } 1510 }
1672 } 1511 }
1673 else { 1512 else {
1674 Py_INCREF(v); 1513 Py_INCREF(v);
1675 } 1514 }
1676 1515
1677 Py_XDECREF(module_context); 1516 Py_XDECREF(module_context);
1678 module_context = v; 1517 module_context = v;
1679 module_context_set = 1; 1518 module_context_set = 1;
(...skipping 10 matching lines...) Expand all
1690 /* Return borrowed reference to thread local context. */ 1529 /* Return borrowed reference to thread local context. */
1691 static PyObject * 1530 static PyObject *
1692 current_context(void) 1531 current_context(void)
1693 { 1532 {
1694 PyObject *dict = NULL; 1533 PyObject *dict = NULL;
1695 PyObject *tl_context = NULL; 1534 PyObject *tl_context = NULL;
1696 1535
1697 dict = PyThreadState_GetDict(); 1536 dict = PyThreadState_GetDict();
1698 if (dict == NULL) { 1537 if (dict == NULL) {
1699 PyErr_SetString(PyExc_RuntimeError, 1538 PyErr_SetString(PyExc_RuntimeError,
1700 » » "cannot get thread state."); 1539 » » "cannot get thread state");
1701 return NULL; 1540 return NULL;
1702 } 1541 }
1703 1542
1704 tl_context = PyDict_GetItemWithError(dict, tls_context_key); 1543 tl_context = PyDict_GetItemWithError(dict, tls_context_key);
1705 if (tl_context != NULL) { 1544 if (tl_context != NULL) {
1706 /* We already have a thread local context and 1545 /* We already have a thread local context and
1707 * return a borrowed reference. */ 1546 * return a borrowed reference. */
1708 CONTEXT_CHECK(tl_context); 1547 CONTEXT_CHECK(tl_context);
1709 return tl_context; 1548 return tl_context;
1710 } 1549 }
(...skipping 11 matching lines...) Expand all
1722 return NULL; 1561 return NULL;
1723 } 1562 }
1724 Py_DECREF(tl_context); 1563 Py_DECREF(tl_context);
1725 1564
1726 /* refcount is 1 */ 1565 /* refcount is 1 */
1727 return tl_context; 1566 return tl_context;
1728 } 1567 }
1729 1568
1730 /* ctxobj := borrowed reference to the current context */ 1569 /* ctxobj := borrowed reference to the current context */
1731 #define CURRENT_CONTEXT(ctxobj) \ 1570 #define CURRENT_CONTEXT(ctxobj) \
1732 if ((ctxobj = current_context()) == NULL) { \ 1571 ctxobj = current_context(); \
1733 return NULL; \ 1572 if (ctxobj == NULL) { \
1573 return NULL; \
1734 } 1574 }
1735 1575
1736 /* ctx := pointer to the mpd_context_t struct of the current context */ 1576 /* ctx := pointer to the mpd_context_t struct of the current context */
1737 #define CURRENT_CONTEXT_ADDR(ctx) { \ 1577 #define CURRENT_CONTEXT_ADDR(ctx) { \
1738 PyObject *_c_t_x_o_b_j = current_context(); \ 1578 PyObject *_c_t_x_o_b_j = current_context(); \
1739 if (_c_t_x_o_b_j == NULL) { \ 1579 if (_c_t_x_o_b_j == NULL) { \
1740 return NULL; \ 1580 return NULL; \
1741 } \ 1581 } \
1742 ctx = CTX(_c_t_x_o_b_j); \ 1582 ctx = CTX(_c_t_x_o_b_j); \
1743 } 1583 }
1744 1584
1745 /* Return current context, increment reference */ 1585 /* Return current context, increment reference */
1746 static PyObject * 1586 static PyObject *
1747 PyDec_GetCurrentContext(void) 1587 PyDec_GetCurrentContext(void)
1748 { 1588 {
1749 » PyObject *obj; 1589 » PyObject *context;
1750 1590
1751 » if ((obj = current_context()) == NULL) { 1591 » context = current_context();
1752 » » return NULL; 1592 » if (context == NULL) {
1753 » } 1593 » » return NULL;
1754 1594 » }
1755 » Py_INCREF(obj); 1595
1756 » return obj; 1596 » Py_INCREF(context);
1597 » return context;
1757 } 1598 }
1758 1599
1759 /* Set the thread local context to a new context, decrement old reference */ 1600 /* Set the thread local context to a new context, decrement old reference */
1760 static PyObject * 1601 static PyObject *
1761 PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v) 1602 PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v)
1762 { 1603 {
1763 PyObject *dict; 1604 PyObject *dict;
1764 1605
1765 CONTEXT_CHECK(v); 1606 CONTEXT_CHECK(v);
1766 1607
1767 dict = PyThreadState_GetDict(); 1608 dict = PyThreadState_GetDict();
1768 if (dict == NULL) { 1609 if (dict == NULL) {
1769 PyErr_SetString(PyExc_RuntimeError, 1610 PyErr_SetString(PyExc_RuntimeError,
1770 » » "cannot get thread state."); 1611 » » "cannot get thread state");
1771 return NULL; 1612 return NULL;
1772 } 1613 }
1773 1614
1774 /* If the new context is one of the templates, make a copy. 1615 /* If the new context is one of the templates, make a copy.
1775 * This is the current behavior of decimal.py. */ 1616 * This is the current behavior of decimal.py. */
1776 if (v == default_context_template || 1617 if (v == default_context_template ||
1777 v == basic_context_template || 1618 v == basic_context_template ||
1778 v == extended_context_template) { 1619 v == extended_context_template) {
1779 » » if ((v = context_copy(v)) == NULL) { 1620 » » v = context_copy(v);
1621 » » if (v == NULL) {
1780 return NULL; 1622 return NULL;
1781 } 1623 }
1782 } 1624 }
1783 else { 1625 else {
1784 Py_INCREF(v); 1626 Py_INCREF(v);
1785 } 1627 }
1786 1628
1787 if (PyDict_SetItem(dict, tls_context_key, v) < 0) { 1629 if (PyDict_SetItem(dict, tls_context_key, v) < 0) {
1788 Py_DECREF(v); 1630 Py_DECREF(v);
1789 return NULL; 1631 return NULL;
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
1944 mpd_del(MPD(dec)); 1786 mpd_del(MPD(dec));
1945 } 1787 }
1946 Py_TYPE(dec)->tp_free(dec); 1788 Py_TYPE(dec)->tp_free(dec);
1947 } 1789 }
1948 1790
1949 1791
1950 /******************************************************************************/ 1792 /******************************************************************************/
1951 /* Conversions to Decimal */ 1793 /* Conversions to Decimal */
1952 /******************************************************************************/ 1794 /******************************************************************************/
1953 1795
1796 Py_LOCAL_INLINE(int)
1797 is_space(enum PyUnicode_Kind kind, void *data, Py_ssize_t pos)
1798 {
1799 Py_UCS4 ch = PyUnicode_READ(kind, data, pos);
1800 return Py_UNICODE_ISSPACE(ch);
1801 }
1802
1803 /* Return the ASCII representation of a numeric Unicode string. The numeric
1804 string may contain ascii characters in the range [1, 127], any Unicode
1805 space and any unicode digit. If strip_ws is true, leading and trailing
1806 whitespace is stripped.
1807
1808 Return NULL if malloc fails and an empty string if invalid characters
1809 are found. */
1810 static char *
1811 numeric_as_ascii(const PyObject *u, int strip_ws)
1812 {
1813 enum PyUnicode_Kind kind;
1814 void *data;
1815 Py_UCS4 ch;
1816 char *res, *cp;
1817 Py_ssize_t j, len;
1818 int d;
1819
1820 assert(PyUnicode_IS_READY(u));
1821
1822 kind = PyUnicode_KIND(u);
1823 data = PyUnicode_DATA(u);
1824 len = PyUnicode_GET_LENGTH(u);
1825
1826 cp = res = PyMem_Malloc(len+1);
1827 if (res == NULL) {
1828 PyErr_NoMemory();
1829 return NULL;
1830 }
1831
1832 j = 0;
1833 if (strip_ws) {
1834 while (len > 0 && is_space(kind, data, len-1)) {
1835 len--;
1836 }
1837 while (j < len && is_space(kind, data, j)) {
1838 j++;
1839 }
1840 }
1841
1842 for (; j < len; j++) {
1843 ch = PyUnicode_READ(kind, data, j);
1844 if (0 < ch && ch <= 127) {
1845 *cp++ = ch;
1846 continue;
1847 }
1848 if (Py_UNICODE_ISSPACE(ch)) {
1849 *cp++ = ' ';
1850 continue;
1851 }
1852 d = Py_UNICODE_TODECIMAL(ch);
1853 if (d < 0) {
1854 /* empty string triggers ConversionSyntax */
1855 *res = '\0';
1856 return res;
1857 }
1858 *cp++ = '0' + d;
1859 }
1860 *cp = '\0';
1861 return res;
1862 }
1863
1954 /* Return a new PyDecObject or a subtype from a C string. Use the context 1864 /* Return a new PyDecObject or a subtype from a C string. Use the context
1955 during conversion. */ 1865 during conversion. */
1956 static PyObject * 1866 static PyObject *
1957 PyDecType_FromCString(PyTypeObject *type, const char *s, 1867 PyDecType_FromCString(PyTypeObject *type, const char *s,
1958 PyObject *context) 1868 PyObject *context)
1959 { 1869 {
1960 PyObject *dec; 1870 PyObject *dec;
1961 uint32_t status = 0; 1871 uint32_t status = 0;
1962 1872
1963 dec = PyDecType_New(type); 1873 dec = PyDecType_New(type);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1998 } 1908 }
1999 status &= MPD_Errors; 1909 status &= MPD_Errors;
2000 if (dec_addstatus(context, status)) { 1910 if (dec_addstatus(context, status)) {
2001 Py_DECREF(dec); 1911 Py_DECREF(dec);
2002 return NULL; 1912 return NULL;
2003 } 1913 }
2004 1914
2005 return dec; 1915 return dec;
2006 } 1916 }
2007 1917
2008 /* Wrap PyUnicode_EncodeDecimal. */
2009 static char *
2010 dec_unicode_as_str(const PyObject *u)
2011 {
2012 char *s;
2013
2014 s = PyMem_Malloc(PyUnicode_GET_SIZE(u)+1);
2015 if (s == NULL) {
2016 PyErr_NoMemory();
2017 return NULL;
2018 }
2019 if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(u),
2020 PyUnicode_GET_SIZE(u),
2021 s, NULL)) {
2022 PyMem_Free(s);
2023 return NULL;
2024 }
2025
2026 return s;
2027 }
2028
2029 /* Strip leading and trailing whitespace. Return x unchanged if no
2030 whitespace is found, otherwise return a newly allocated string
2031 with whitespace stripped. */
2032 static char *
2033 strip_ws(const char *x)
2034 {
2035 char *s, *t;
2036 char *y;
2037 size_t n;
2038
2039 s = (char *)x;
2040 while (isspace((unsigned char)*s))
2041 s++;
2042
2043 t = y = s+strlen(s);
2044 while (t > s && isspace((unsigned char)*(t-1)))
2045 t--;
2046
2047 if (s != x || t != y) {
2048 n = t-s;
2049 if ((y = PyMem_Malloc(n+1)) == NULL) {
2050 PyErr_NoMemory();
2051 return NULL;
2052 }
2053 strncpy(y, s, n);
2054 y[n] = '\0';
2055 return y;
2056 }
2057
2058 return (char *)x;
2059 }
2060
2061 /* Return a new PyDecObject or a subtype from a PyUnicodeObject. */ 1918 /* Return a new PyDecObject or a subtype from a PyUnicodeObject. */
2062 static PyObject * 1919 static PyObject *
2063 PyDecType_FromUnicode(PyTypeObject *type, const PyObject *u, 1920 PyDecType_FromUnicode(PyTypeObject *type, const PyObject *u,
2064 PyObject *context) 1921 PyObject *context)
2065 { 1922 {
2066 PyObject *dec; 1923 PyObject *dec;
2067 char *s; 1924 char *s;
2068 1925
2069 » s = dec_unicode_as_str(u); 1926 » s = numeric_as_ascii(u, 0);
2070 if (s == NULL) { 1927 if (s == NULL) {
2071 return NULL; 1928 return NULL;
2072 } 1929 }
2073 1930
2074 dec = PyDecType_FromCString(type, s, context); 1931 dec = PyDecType_FromCString(type, s, context);
2075 PyMem_Free(s); 1932 PyMem_Free(s);
2076 return dec; 1933 return dec;
2077 } 1934 }
2078 1935
2079 /* Return a new PyDecObject or a subtype from a PyUnicodeObject. Attempt exact 1936 /* Return a new PyDecObject or a subtype from a PyUnicodeObject. Attempt exact
2080 * conversion. If the conversion is not exact, fail with InvalidOperation. 1937 * conversion. If the conversion is not exact, fail with InvalidOperation.
2081 * Allow leading and trailing whitespace in the input operand. */ 1938 * Allow leading and trailing whitespace in the input operand. */
2082 static PyObject * 1939 static PyObject *
2083 PyDecType_FromUnicodeExactWS(PyTypeObject *type, const PyObject *u, 1940 PyDecType_FromUnicodeExactWS(PyTypeObject *type, const PyObject *u,
2084 PyObject *context) 1941 PyObject *context)
2085 { 1942 {
2086 PyObject *dec; 1943 PyObject *dec;
2087 » char *s, *stripped; 1944 » char *s;
2088 1945
2089 » s = dec_unicode_as_str(u); 1946 » s = numeric_as_ascii(u, 1);
2090 if (s == NULL) { 1947 if (s == NULL) {
2091 return NULL; 1948 return NULL;
2092 } 1949 }
2093 1950
2094 » stripped = strip_ws(s); 1951 » dec = PyDecType_FromCStringExact(type, s, context);
2095 » if (stripped == NULL) {
2096 » » PyMem_Free(s);
2097 » » return NULL;
2098 » }
2099
2100 » dec = PyDecType_FromCStringExact(type, stripped, context);
2101 » if (stripped != s) {
2102 » » PyMem_Free(stripped);
2103 » }
2104 PyMem_Free(s); 1952 PyMem_Free(s);
2105
2106 return dec; 1953 return dec;
2107 } 1954 }
2108 1955
2109 /* Set PyDecObject from triple without any error checking. */ 1956 /* Set PyDecObject from triple without any error checking. */
2110 static ALWAYS_INLINE void 1957 Py_LOCAL_INLINE(void)
2111 _dec_settriple(PyObject *dec, uint8_t sign, uint32_t v, mpd_ssize_t exp) 1958 _dec_settriple(PyObject *dec, uint8_t sign, uint32_t v, mpd_ssize_t exp)
2112 { 1959 {
2113 1960
2114 #ifdef CONFIG_64 1961 #ifdef CONFIG_64
2115 MPD(dec)->data[0] = v; 1962 MPD(dec)->data[0] = v;
2116 MPD(dec)->len = 1; 1963 MPD(dec)->len = 1;
2117 #else 1964 #else
2118 uint32_t q, r; 1965 uint32_t q, r;
2119 q = v / MPD_RADIX; 1966 q = v / MPD_RADIX;
2120 r = v - q * MPD_RADIX; 1967 r = v - q * MPD_RADIX;
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
2208 return dec; 2055 return dec;
2209 } 2056 }
2210 2057
2211 #if PYLONG_BITS_IN_DIGIT == 30 2058 #if PYLONG_BITS_IN_DIGIT == 30
2212 mpd_qimport_u32(MPD(dec), l->ob_digit, len, sign, PyLong_BASE, 2059 mpd_qimport_u32(MPD(dec), l->ob_digit, len, sign, PyLong_BASE,
2213 ctx, status); 2060 ctx, status);
2214 #elif PYLONG_BITS_IN_DIGIT == 15 2061 #elif PYLONG_BITS_IN_DIGIT == 15
2215 mpd_qimport_u16(MPD(dec), l->ob_digit, len, sign, PyLong_BASE, 2062 mpd_qimport_u16(MPD(dec), l->ob_digit, len, sign, PyLong_BASE,
2216 ctx, status); 2063 ctx, status);
2217 #else 2064 #else
2218 #error "PYLONG_BITS_IN_DIGIT should be 15 or 30." 2065 #error "PYLONG_BITS_IN_DIGIT should be 15 or 30"
2219 #endif 2066 #endif
2220 2067
2221 return dec; 2068 return dec;
2222 } 2069 }
2223 2070
2224 /* Return a new PyDecObject from a PyLongObject. Use the context for 2071 /* Return a new PyDecObject from a PyLongObject. Use the context for
2225 conversion. */ 2072 conversion. */
2226 static PyObject * 2073 static PyObject *
2227 PyDecType_FromLong(PyTypeObject *type, const PyObject *pylong, 2074 PyDecType_FromLong(PyTypeObject *type, const PyObject *pylong,
2228 PyObject *context) 2075 PyObject *context)
(...skipping 25 matching lines...) Expand all
2254 mpd_context_t maxctx; 2101 mpd_context_t maxctx;
2255 2102
2256 mpd_maxcontext(&maxctx); 2103 mpd_maxcontext(&maxctx);
2257 dec = dec_from_long(type, pylong, &maxctx, &status); 2104 dec = dec_from_long(type, pylong, &maxctx, &status);
2258 if (dec == NULL) { 2105 if (dec == NULL) {
2259 return NULL; 2106 return NULL;
2260 } 2107 }
2261 2108
2262 if (status & (MPD_Inexact|MPD_Rounded)) { 2109 if (status & (MPD_Inexact|MPD_Rounded)) {
2263 /* we want exact results */ 2110 /* we want exact results */
2264 » » mpd_seterror(MPD(dec), MPD_Invalid_operation, &status); /* GCOV_ NOT_REACHED */ 2111 » » mpd_seterror(MPD(dec), MPD_Invalid_operation, &status);
2265 } 2112 }
2266 status &= MPD_Errors; 2113 status &= MPD_Errors;
2267 if (dec_addstatus(context, status)) { 2114 if (dec_addstatus(context, status)) {
2268 Py_DECREF(dec); 2115 Py_DECREF(dec);
2269 return NULL; 2116 return NULL;
2270 } 2117 }
2271 2118
2272 return dec; 2119 return dec;
2273 } 2120 }
2274 2121
(...skipping 13 matching lines...) Expand all
2288 mpd_context_t maxctx; 2135 mpd_context_t maxctx;
2289 2136
2290 2137
2291 assert(PyType_IsSubtype(type, &PyDec_Type)); 2138 assert(PyType_IsSubtype(type, &PyDec_Type));
2292 2139
2293 if (PyLong_Check(v)) { 2140 if (PyLong_Check(v)) {
2294 return PyDecType_FromLongExact(type, v, context); 2141 return PyDecType_FromLongExact(type, v, context);
2295 } 2142 }
2296 if (!PyFloat_Check(v)) { 2143 if (!PyFloat_Check(v)) {
2297 PyErr_SetString(PyExc_TypeError, 2144 PyErr_SetString(PyExc_TypeError,
2298 » » "argument must be int of float."); 2145 » » "argument must be int of float");
2299 return NULL; 2146 return NULL;
2300 } 2147 }
2301 2148
2302 x = PyFloat_AsDouble(v); 2149 x = PyFloat_AsDouble(v);
2303 if (x == -1.0 && PyErr_Occurred()) { 2150 if (x == -1.0 && PyErr_Occurred()) {
2304 return NULL; 2151 return NULL;
2305 } 2152 }
2306 sign = (copysign(1.0, x) == 1.0) ? 0 : 1; 2153 sign = (copysign(1.0, x) == 1.0) ? 0 : 1;
2307 2154
2308 if (Py_IS_NAN(x) || Py_IS_INFINITY(x)) { 2155 if (Py_IS_NAN(x) || Py_IS_INFINITY(x)) {
(...skipping 25 matching lines...) Expand all
2334 return NULL; 2181 return NULL;
2335 } 2182 }
2336 n = PyTuple_GET_ITEM(n_d, 0); 2183 n = PyTuple_GET_ITEM(n_d, 0);
2337 d = PyTuple_GET_ITEM(n_d, 1); 2184 d = PyTuple_GET_ITEM(n_d, 1);
2338 2185
2339 tmp = PyObject_CallMethod(d, "bit_length", NULL); 2186 tmp = PyObject_CallMethod(d, "bit_length", NULL);
2340 if (tmp == NULL) { 2187 if (tmp == NULL) {
2341 Py_DECREF(n_d); 2188 Py_DECREF(n_d);
2342 return NULL; 2189 return NULL;
2343 } 2190 }
2344 » k = long_as_mpd_ssize(tmp); 2191 » k = PyLong_AsSsize_t(tmp);
2345 Py_DECREF(tmp); 2192 Py_DECREF(tmp);
2346 » if (k == MPD_SSIZE_MAX) { 2193 » if (k == -1 && PyErr_Occurred()) {
2347 Py_DECREF(n_d); 2194 Py_DECREF(n_d);
2348 return NULL; 2195 return NULL;
2349 } 2196 }
2350 k--; 2197 k--;
2351 2198
2352 dec = PyDecType_FromLongExact(type, n, context); 2199 dec = PyDecType_FromLongExact(type, n, context);
2353 Py_DECREF(n_d); 2200 Py_DECREF(n_d);
2354 if (dec == NULL) { 2201 if (dec == NULL) {
2355 return NULL; 2202 return NULL;
2356 } 2203 }
(...skipping 10 matching lines...) Expand all
2367 Py_DECREF(dec); 2214 Py_DECREF(dec);
2368 PyErr_NoMemory(); 2215 PyErr_NoMemory();
2369 return NULL; 2216 return NULL;
2370 } 2217 }
2371 2218
2372 mpd_maxcontext(&maxctx); 2219 mpd_maxcontext(&maxctx);
2373 mpd_qset_uint(d1, 5, &maxctx, &status); 2220 mpd_qset_uint(d1, 5, &maxctx, &status);
2374 mpd_qset_ssize(d2, k, &maxctx, &status); 2221 mpd_qset_ssize(d2, k, &maxctx, &status);
2375 mpd_qpow(d1, d1, d2, &maxctx, &status); 2222 mpd_qpow(d1, d1, d2, &maxctx, &status);
2376 if (dec_addstatus(context, status)) { 2223 if (dec_addstatus(context, status)) {
2377 » » mpd_del(d1); /* GCOV_NOT_REACHED */ 2224 » » mpd_del(d1);
2378 » » mpd_del(d2); /* GCOV_NOT_REACHED */ 2225 » » mpd_del(d2);
2379 » » Py_DECREF(dec); /* GCOV_NOT_REACHED */ 2226 » » Py_DECREF(dec);
2380 » » return NULL; /* GCOV_NOT_REACHED */ 2227 » » return NULL;
2381 } 2228 }
2382 2229
2383 /* result = n * 5**k */ 2230 /* result = n * 5**k */
2384 mpd_qmul(MPD(dec), MPD(dec), d1, &maxctx, &status); 2231 mpd_qmul(MPD(dec), MPD(dec), d1, &maxctx, &status);
2385 mpd_del(d1); 2232 mpd_del(d1);
2386 mpd_del(d2); 2233 mpd_del(d2);
2387 if (dec_addstatus(context, status)) { 2234 if (dec_addstatus(context, status)) {
2388 » » Py_DECREF(dec); /* GCOV_NOT_REACHED */ 2235 » » Py_DECREF(dec);
2389 » » return NULL; /* GCOV_NOT_REACHED */ 2236 » » return NULL;
2390 } 2237 }
2391 /* result = +- n * 5**k * 10**-k */ 2238 /* result = +- n * 5**k * 10**-k */
2392 mpd_set_sign(MPD(dec), sign); 2239 mpd_set_sign(MPD(dec), sign);
2393 MPD(dec)->exp = -k; 2240 MPD(dec)->exp = -k;
2394 2241
2395 return dec; 2242 return dec;
2396 } 2243 }
2397 2244
2398 static PyObject * 2245 static PyObject *
2399 PyDecType_FromFloat(PyTypeObject *type, PyObject *v, 2246 PyDecType_FromFloat(PyTypeObject *type, PyObject *v,
2400 PyObject *context) 2247 PyObject *context)
2401 { 2248 {
2402 PyObject *dec; 2249 PyObject *dec;
2403 uint32_t status = 0; 2250 uint32_t status = 0;
2404 2251
2405 dec = PyDecType_FromFloatExact(type, v, context); 2252 dec = PyDecType_FromFloatExact(type, v, context);
2406 if (dec == NULL) { 2253 if (dec == NULL) {
2407 return NULL; 2254 return NULL;
2408 } 2255 }
2409 2256
2410 mpd_qfinalize(MPD(dec), CTX(context), &status); 2257 mpd_qfinalize(MPD(dec), CTX(context), &status);
2411 if (dec_addstatus(context, status)) { 2258 if (dec_addstatus(context, status)) {
2412 Py_DECREF(dec); 2259 Py_DECREF(dec);
2413 return NULL; 2260 return NULL;
2414 } 2261 }
2415 2262
2416 return dec; 2263 return dec;
2417 } 2264 }
2418 2265
2266 static PyObject *
2267 sequence_as_tuple(PyObject *v, PyObject *ex, const char *mesg)
2268 {
2269 if (PyTuple_Check(v)) {
2270 Py_INCREF(v);
2271 return v;
2272 }
2273 if (PyList_Check(v)) {
2274 return PyList_AsTuple(v);
2275 }
2276
2277 PyErr_SetString(ex, mesg);
2278 return NULL;
2279 }
2280
2419 /* Return a new C string representation of a DecimalTuple. */ 2281 /* Return a new C string representation of a DecimalTuple. */
2420 static char * 2282 static char *
2421 dectuple_as_str(PyObject *dectuple) 2283 dectuple_as_str(PyObject *dectuple)
2422 { 2284 {
2423 » PyObject *digits, *tmp; 2285 » PyObject *digits = NULL, *tmp;
2424 char *decstring = NULL; 2286 char *decstring = NULL;
2425 char sign_special[6]; 2287 char sign_special[6];
2426 char *cp; 2288 char *cp;
2427 long sign, l; 2289 long sign, l;
2428 mpd_ssize_t exp = 0; 2290 mpd_ssize_t exp = 0;
2429 Py_ssize_t i, mem, tsize; 2291 Py_ssize_t i, mem, tsize;
2430 int n; 2292 int n;
2431 2293
2432 assert(PyTuple_Check(dectuple)); 2294 assert(PyTuple_Check(dectuple));
2433 2295
2434 if (PyTuple_Size(dectuple) != 3) { 2296 if (PyTuple_Size(dectuple) != 3) {
2435 PyErr_SetString(PyExc_ValueError, 2297 PyErr_SetString(PyExc_ValueError,
2436 » » "argument must be a sequence of length 3."); 2298 » » "argument must be a sequence of length 3");
2437 goto error; 2299 goto error;
2438 } 2300 }
2439 2301
2440 /* sign */ 2302 /* sign */
2441 tmp = PyTuple_GET_ITEM(dectuple, 0); 2303 tmp = PyTuple_GET_ITEM(dectuple, 0);
2442 if (!PyLong_Check(tmp)) { 2304 if (!PyLong_Check(tmp)) {
2443 PyErr_SetString(PyExc_ValueError, 2305 PyErr_SetString(PyExc_ValueError,
2444 » » "sign must be an integer with the value 0 or 1."); 2306 » » "sign must be an integer with the value 0 or 1");
2445 goto error; 2307 goto error;
2446 } 2308 }
2447 sign = PyLong_AsLong(tmp); 2309 sign = PyLong_AsLong(tmp);
2448 » if (PyErr_Occurred()) { 2310 » if (sign == -1 && PyErr_Occurred()) {
2449 goto error; 2311 goto error;
2450 } 2312 }
2451 if (sign != 0 && sign != 1) { 2313 if (sign != 0 && sign != 1) {
2452 PyErr_SetString(PyExc_ValueError, 2314 PyErr_SetString(PyExc_ValueError,
2453 » » "sign must be an integer with the value 0 or 1."); 2315 » » "sign must be an integer with the value 0 or 1");
2454 goto error; 2316 goto error;
2455 } 2317 }
2456 sign_special[0] = sign ? '-' : '+'; 2318 sign_special[0] = sign ? '-' : '+';
2457 sign_special[1] = '\0'; 2319 sign_special[1] = '\0';
2458 2320
2459 /* exponent or encoding for a special number */ 2321 /* exponent or encoding for a special number */
2460 tmp = PyTuple_GET_ITEM(dectuple, 2); 2322 tmp = PyTuple_GET_ITEM(dectuple, 2);
2461 if (PyUnicode_Check(tmp)) { 2323 if (PyUnicode_Check(tmp)) {
2462 /* special */ 2324 /* special */
2463 if (PyUnicode_CompareWithASCIIString(tmp, "F") == 0) { 2325 if (PyUnicode_CompareWithASCIIString(tmp, "F") == 0) {
2464 strcat(sign_special, "Inf"); 2326 strcat(sign_special, "Inf");
2465 } 2327 }
2466 else if (PyUnicode_CompareWithASCIIString(tmp, "n") == 0) { 2328 else if (PyUnicode_CompareWithASCIIString(tmp, "n") == 0) {
2467 strcat(sign_special, "NaN"); 2329 strcat(sign_special, "NaN");
2468 } 2330 }
2469 else if (PyUnicode_CompareWithASCIIString(tmp, "N") == 0) { 2331 else if (PyUnicode_CompareWithASCIIString(tmp, "N") == 0) {
2470 strcat(sign_special, "sNaN"); 2332 strcat(sign_special, "sNaN");
2471 } 2333 }
2472 else { 2334 else {
2473 PyErr_SetString(PyExc_ValueError, 2335 PyErr_SetString(PyExc_ValueError,
2474 "string argument in the third position " 2336 "string argument in the third position "
2475 » » » "must be 'F', 'n' or 'N'."); 2337 » » » "must be 'F', 'n' or 'N'");
2476 goto error; 2338 goto error;
2477 } 2339 }
2478 } 2340 }
2479 else { 2341 else {
2480 /* exponent */ 2342 /* exponent */
2481 if (!PyLong_Check(tmp)) { 2343 if (!PyLong_Check(tmp)) {
2482 PyErr_SetString(PyExc_ValueError, 2344 PyErr_SetString(PyExc_ValueError,
2483 » » » "exponent must be an integer."); 2345 » » » "exponent must be an integer");
2484 goto error; 2346 goto error;
2485 } 2347 }
2486 » » exp = long_as_mpd_ssize(tmp); 2348 » » exp = PyLong_AsSsize_t(tmp);
2487 » » if (PyErr_Occurred()) { 2349 » » if (exp == -1 && PyErr_Occurred()) {
2488 goto error; 2350 goto error;
2489 } 2351 }
2490 } 2352 }
2491 2353
2492 /* coefficient */ 2354 /* coefficient */
2493 » digits = PyTuple_GET_ITEM(dectuple, 1); 2355 » digits = sequence_as_tuple(PyTuple_GET_ITEM(dectuple, 1),
2494 » if (!PyTuple_Check(digits)) { 2356 PyExc_ValueError, "coefficient must be a tuple of digits");
2495 » » PyErr_SetString(PyExc_ValueError, 2357 » if (digits == NULL) {
2496 » » "coefficient must be a tuple of digits.");
2497 goto error; 2358 goto error;
2498 } 2359 }
2499 2360
2500 tsize = PyTuple_Size(digits); 2361 tsize = PyTuple_Size(digits);
2501 /* [sign][coeffdigits+1][E][-][expdigits+1]['\0'] */ 2362 /* [sign][coeffdigits+1][E][-][expdigits+1]['\0'] */
2502 mem = 1 + tsize + 3 + MPD_EXPDIGITS + 2; 2363 mem = 1 + tsize + 3 + MPD_EXPDIGITS + 2;
2503 cp = decstring = PyMem_Malloc(mem); 2364 cp = decstring = PyMem_Malloc(mem);
2504 if (decstring == NULL) { 2365 if (decstring == NULL) {
2505 PyErr_NoMemory(); 2366 PyErr_NoMemory();
2506 goto error; 2367 goto error;
2507 } 2368 }
2508 2369
2509 n = snprintf(cp, mem, "%s", sign_special); 2370 n = snprintf(cp, mem, "%s", sign_special);
2510 if (n < 0 || n >= mem) { 2371 if (n < 0 || n >= mem) {
2511 PyErr_SetString(PyExc_RuntimeError, 2372 PyErr_SetString(PyExc_RuntimeError,
2512 » » "internal error in dec_sequence_as_str."); 2373 » » "internal error in dec_sequence_as_str");
2513 goto error; 2374 goto error;
2514 } 2375 }
2515 cp += n; 2376 cp += n;
2516 2377
2517 if (tsize == 0 && sign_special[1] == '\0') { 2378 if (tsize == 0 && sign_special[1] == '\0') {
2518 /* empty tuple: zero coefficient, except for special numbers */ 2379 /* empty tuple: zero coefficient, except for special numbers */
2519 *cp++ = '0'; 2380 *cp++ = '0';
2520 } 2381 }
2521 for (i = 0; i < tsize; i++) { 2382 for (i = 0; i < tsize; i++) {
2522 tmp = PyTuple_GET_ITEM(digits, i); 2383 tmp = PyTuple_GET_ITEM(digits, i);
2523 if (!PyLong_Check(tmp)) { 2384 if (!PyLong_Check(tmp)) {
2524 PyErr_SetString(PyExc_ValueError, 2385 PyErr_SetString(PyExc_ValueError,
2525 » » » "coefficient must be a tuple of digits."); 2386 » » » "coefficient must be a tuple of digits");
2526 goto error; 2387 goto error;
2527 } 2388 }
2528 l = PyLong_AsLong(tmp); 2389 l = PyLong_AsLong(tmp);
2529 » » if (PyErr_Occurred()) { 2390 » » if (l == -1 && PyErr_Occurred()) {
2530 goto error; 2391 goto error;
2531 } 2392 }
2532 if (l < 0 || l > 9) { 2393 if (l < 0 || l > 9) {
2533 PyErr_SetString(PyExc_ValueError, 2394 PyErr_SetString(PyExc_ValueError,
2534 » » » "coefficient must be a tuple of digits."); 2395 » » » "coefficient must be a tuple of digits");
2535 goto error; 2396 goto error;
2536 } 2397 }
2537 *cp++ = (char)l + '0'; 2398 *cp++ = (char)l + '0';
2538 } 2399 }
2539 *cp = '\0'; 2400 *cp = '\0';
2540 2401
2541 if (sign_special[1] == '\0') { 2402 if (sign_special[1] == '\0') {
2542 /* not a special number */ 2403 /* not a special number */
2543 *cp++ = 'E'; 2404 *cp++ = 'E';
2544 n = snprintf(cp, MPD_EXPDIGITS+1, "%" PRI_mpd_ssize_t, exp); 2405 n = snprintf(cp, MPD_EXPDIGITS+1, "%" PRI_mpd_ssize_t, exp);
2545 if (n < 0 || n >= MPD_EXPDIGITS+1) { 2406 if (n < 0 || n >= MPD_EXPDIGITS+1) {
2546 PyErr_SetString(PyExc_RuntimeError, 2407 PyErr_SetString(PyExc_RuntimeError,
2547 » » » "internal error in dec_sequence_as_str."); 2408 » » » "internal error in dec_sequence_as_str");
2548 goto error; 2409 goto error;
2549 } 2410 }
2550 } 2411 }
2551 2412
2413 Py_XDECREF(digits);
2552 return decstring; 2414 return decstring;
2553 2415
2554 2416
2555 error: 2417 error:
2418 Py_XDECREF(digits);
2556 if (decstring) PyMem_Free(decstring); 2419 if (decstring) PyMem_Free(decstring);
2557 return NULL; 2420 return NULL;
2558 }
2559
2560 static PyObject *
2561 sequence_as_tuple(PyObject *v)
2562 {
2563 if (PyTuple_Check(v)) {
2564 Py_INCREF(v);
2565 return v;
2566 }
2567 if (PyList_Check(v)) {
2568 return PyList_AsTuple(v);
2569 }
2570
2571 return type_error_ptr("argument must be tuple or list."); /* GCOV_NOT_RE ACHED */
2572 } 2421 }
2573 2422
2574 /* Currently accepts tuples and lists. */ 2423 /* Currently accepts tuples and lists. */
2575 static PyObject * 2424 static PyObject *
2576 PyDecType_FromSequence(PyTypeObject *type, PyObject *v, 2425 PyDecType_FromSequence(PyTypeObject *type, PyObject *v,
2577 PyObject *context) 2426 PyObject *context)
2578 { 2427 {
2579 PyObject *dectuple; 2428 PyObject *dectuple;
2580 PyObject *dec; 2429 PyObject *dec;
2581 char *s; 2430 char *s;
2582 2431
2583 » dectuple = sequence_as_tuple(v); 2432 » dectuple = sequence_as_tuple(v, PyExc_TypeError,
2433 » "argument must be a tuple or list");
2584 if (dectuple == NULL) { 2434 if (dectuple == NULL) {
2585 return NULL; 2435 return NULL;
2586 } 2436 }
2587 2437
2588 s = dectuple_as_str(dectuple); 2438 s = dectuple_as_str(dectuple);
2589 Py_DECREF(dectuple); 2439 Py_DECREF(dectuple);
2590 if (s == NULL) { 2440 if (s == NULL) {
2591 return NULL; 2441 return NULL;
2592 } 2442 }
2593 2443
2594 dec = PyDecType_FromCString(type, s, context); 2444 dec = PyDecType_FromCString(type, s, context);
2595 2445
2596 PyMem_Free(s); 2446 PyMem_Free(s);
2597 return dec; 2447 return dec;
2598 } 2448 }
2599 2449
2600 /* Currently accepts tuples and lists. */ 2450 /* Currently accepts tuples and lists. */
2601 static PyObject * 2451 static PyObject *
2602 PyDecType_FromSequenceExact(PyTypeObject *type, PyObject *v, 2452 PyDecType_FromSequenceExact(PyTypeObject *type, PyObject *v,
2603 PyObject *context) 2453 PyObject *context)
2604 { 2454 {
2605 PyObject *dectuple; 2455 PyObject *dectuple;
2606 PyObject *dec; 2456 PyObject *dec;
2607 char *s; 2457 char *s;
2608 2458
2609 » dectuple = sequence_as_tuple(v); 2459 » dectuple = sequence_as_tuple(v, PyExc_TypeError,
2460 » "argument must be a tuple or list");
2610 if (dectuple == NULL) { 2461 if (dectuple == NULL) {
2611 return NULL; 2462 return NULL;
2612 } 2463 }
2613 2464
2614 s = dectuple_as_str(dectuple); 2465 s = dectuple_as_str(dectuple);
2615 Py_DECREF(dectuple); 2466 Py_DECREF(dectuple);
2616 if (s == NULL) { 2467 if (s == NULL) {
2617 return NULL; 2468 return NULL;
2618 } 2469 }
2619 2470
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
2722 return PyDecType_FromSequenceExact(type, v, context); 2573 return PyDecType_FromSequenceExact(type, v, context);
2723 } 2574 }
2724 else if (PyFloat_Check(v)) { 2575 else if (PyFloat_Check(v)) {
2725 if (dec_addstatus(context, MPD_Float_operation)) { 2576 if (dec_addstatus(context, MPD_Float_operation)) {
2726 return NULL; 2577 return NULL;
2727 } 2578 }
2728 return PyDecType_FromFloatExact(type, v, context); 2579 return PyDecType_FromFloatExact(type, v, context);
2729 } 2580 }
2730 else { 2581 else {
2731 PyErr_Format(PyExc_TypeError, 2582 PyErr_Format(PyExc_TypeError,
2732 » » "conversion from %s to Decimal is not supported.", 2583 » » "conversion from %s to Decimal is not supported",
2733 v->ob_type->tp_name); 2584 v->ob_type->tp_name);
2734 return NULL; 2585 return NULL;
2735 } 2586 }
2736 } 2587 }
2737 2588
2738 /* The context is used during conversion. This function is the 2589 /* The context is used during conversion. This function is the
2739 equivalent of context.create_decimal(). */ 2590 equivalent of context.create_decimal(). */
2740 static PyObject * 2591 static PyObject *
2741 PyDec_FromObject(PyObject *v, PyObject *context) 2592 PyDec_FromObject(PyObject *v, PyObject *context)
2742 { 2593 {
(...skipping 28 matching lines...) Expand all
2771 return PyDec_FromSequence(v, context); 2622 return PyDec_FromSequence(v, context);
2772 } 2623 }
2773 else if (PyFloat_Check(v)) { 2624 else if (PyFloat_Check(v)) {
2774 if (dec_addstatus(context, MPD_Float_operation)) { 2625 if (dec_addstatus(context, MPD_Float_operation)) {
2775 return NULL; 2626 return NULL;
2776 } 2627 }
2777 return PyDec_FromFloat(v, context); 2628 return PyDec_FromFloat(v, context);
2778 } 2629 }
2779 else { 2630 else {
2780 PyErr_Format(PyExc_TypeError, 2631 PyErr_Format(PyExc_TypeError,
2781 » » "conversion from %s to Decimal is not supported.", 2632 » » "conversion from %s to Decimal is not supported",
2782 v->ob_type->tp_name); 2633 v->ob_type->tp_name);
2783 return NULL; 2634 return NULL;
2784 } 2635 }
2785 } 2636 }
2786 2637
2787 static PyObject * 2638 static PyObject *
2788 dec_new(PyTypeObject *type, PyObject *args, PyObject *kwds UNUSED) 2639 dec_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2789 { 2640 {
2641 » static char *kwlist[] = {"value", "context", NULL};
2790 PyObject *v = NULL; 2642 PyObject *v = NULL;
2791 PyObject *context; 2643 PyObject *context;
2792 2644
2793 CURRENT_CONTEXT(context); 2645 CURRENT_CONTEXT(context);
2794 » if (!PyArg_ParseTuple(args, "|OO", &v, &context)) { 2646 » if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO", kwlist,
2647 » &v, &context)) {
2795 return NULL; 2648 return NULL;
2796 } 2649 }
2797 CONTEXT_CHECK_VA(context); 2650 CONTEXT_CHECK_VA(context);
2798 2651
2799 return PyDecType_FromObjectExact(type, v, context); 2652 return PyDecType_FromObjectExact(type, v, context);
2800 } 2653 }
2801 2654
2802 static PyObject * 2655 static PyObject *
2803 ctx_create_decimal(PyObject *context, PyObject *args) 2656 ctx_create_decimal(PyObject *context, PyObject *args)
2804 { 2657 {
2805 PyObject *v = NULL; 2658 PyObject *v = NULL;
2806 2659
2807 if (!PyArg_ParseTuple(args, "|O", &v)) { 2660 if (!PyArg_ParseTuple(args, "|O", &v)) {
2808 return NULL; 2661 return NULL;
2809 } 2662 }
2810 2663
2811 return PyDec_FromObject(v, context); 2664 return PyDec_FromObject(v, context);
2812 } 2665 }
2813 2666
2814 2667
2815 /******************************************************************************/ 2668 /******************************************************************************/
2816 /* Implicit conversions to Decimal */ 2669 /* Implicit conversions to Decimal */
2817 /******************************************************************************/ 2670 /******************************************************************************/
2818 2671
2819 /* Try to convert PyObject v to a new PyDecObject conv. If the conversion 2672 /* Try to convert PyObject v to a new PyDecObject conv. If the conversion
2820 fails, set conv to NULL (exception is set). If the conversion is not 2673 fails, set conv to NULL (exception is set). If the conversion is not
2821 implemented, set conv to Py_NotImplemented. */ 2674 implemented, set conv to Py_NotImplemented. */
2822 #define NOT_IMPL 0 2675 #define NOT_IMPL 0
2823 #define TYPE_ERR 1 2676 #define TYPE_ERR 1
2824 static inline int 2677 Py_LOCAL_INLINE(int)
2825 convert_op(int type_err, PyObject **conv, PyObject *v, PyObject *context) 2678 convert_op(int type_err, PyObject **conv, PyObject *v, PyObject *context)
2826 { 2679 {
2827 2680
2828 if (PyDec_Check(v)) { 2681 if (PyDec_Check(v)) {
2829 *conv = v; 2682 *conv = v;
2830 Py_INCREF(v); 2683 Py_INCREF(v);
2831 return 1; 2684 return 1;
2832 } 2685 }
2833 if (PyLong_Check(v)) { 2686 if (PyLong_Check(v)) {
2834 *conv = PyDec_FromLongExact(v, context); 2687 *conv = PyDec_FromLongExact(v, context);
2835 if (*conv == NULL) { 2688 if (*conv == NULL) {
2836 return 0; 2689 return 0;
2837 } 2690 }
2838 return 1; 2691 return 1;
2839 } 2692 }
2840 2693
2841 if (type_err) { 2694 if (type_err) {
2842 PyErr_Format(PyExc_TypeError, 2695 PyErr_Format(PyExc_TypeError,
2843 » » "conversion from %s to Decimal is not supported.", 2696 » » "conversion from %s to Decimal is not supported",
2844 v->ob_type->tp_name); 2697 v->ob_type->tp_name);
2845 } 2698 }
2846 else { 2699 else {
2847 Py_INCREF(Py_NotImplemented); 2700 Py_INCREF(Py_NotImplemented);
2848 *conv = Py_NotImplemented; 2701 *conv = Py_NotImplemented;
2849 } 2702 }
2850 return 0; 2703 return 0;
2851 } 2704 }
2852 2705
2853 /* Return NotImplemented for unsupported types. */ 2706 /* Return NotImplemented for unsupported types. */
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2907 Py_DECREF(*(b)); \ 2760 Py_DECREF(*(b)); \
2908 return NULL; \ 2761 return NULL; \
2909 } 2762 }
2910 2763
2911 2764
2912 /******************************************************************************/ 2765 /******************************************************************************/
2913 /* Implicit conversions to Decimal for comparison */ 2766 /* Implicit conversions to Decimal for comparison */
2914 /******************************************************************************/ 2767 /******************************************************************************/
2915 2768
2916 /* Convert rationals for comparison */ 2769 /* Convert rationals for comparison */
2917 static PyObject *_Rational = NULL; 2770 static PyObject *Rational = NULL;
2918 static PyObject * 2771 static PyObject *
2919 multiply_by_denominator(PyObject *v, PyObject *r, PyObject *context) 2772 multiply_by_denominator(PyObject *v, PyObject *r, PyObject *context)
2920 { 2773 {
2921 PyObject *result; 2774 PyObject *result;
2922 PyObject *tmp = NULL; 2775 PyObject *tmp = NULL;
2923 PyObject *denom = NULL; 2776 PyObject *denom = NULL;
2924 uint32_t status = 0; 2777 uint32_t status = 0;
2925 mpd_context_t maxctx; 2778 mpd_context_t maxctx;
2926 mpd_ssize_t exp; 2779 mpd_ssize_t exp;
2927 mpd_t *vv; 2780 mpd_t *vv;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2959 vv->exp = 0; 2812 vv->exp = 0;
2960 mpd_qmul(MPD(result), vv, MPD(denom), &maxctx, &status); 2813 mpd_qmul(MPD(result), vv, MPD(denom), &maxctx, &status);
2961 MPD(result)->exp = exp; 2814 MPD(result)->exp = exp;
2962 2815
2963 Py_DECREF(denom); 2816 Py_DECREF(denom);
2964 mpd_del(vv); 2817 mpd_del(vv);
2965 /* If any status has been accumulated during the multiplication, 2818 /* If any status has been accumulated during the multiplication,
2966 the result is invalid. This is very unlikely, since even the 2819 the result is invalid. This is very unlikely, since even the
2967 32-bit version supports 425000000 digits. */ 2820 32-bit version supports 425000000 digits. */
2968 if (status) { 2821 if (status) {
2969 » » PyErr_SetString(PyExc_ValueError, /* GCOV_NOT_REACHED */ 2822 » » PyErr_SetString(PyExc_ValueError,
2970 » » "exact conversion for comparison failed."); /* GCOV_NOT_REACHE D */ 2823 » » "exact conversion for comparison failed");
2971 » » Py_DECREF(result); /* GCOV_NOT_REACHED */ 2824 » » Py_DECREF(result);
2972 » » return NULL; /* GCOV_NOT_REACHED */ 2825 » » return NULL;
2973 } 2826 }
2974 2827
2975 return result; 2828 return result;
2976 } 2829 }
2977 2830
2978 static PyObject * 2831 static PyObject *
2979 numerator_as_decimal(PyObject *r, PyObject *context) 2832 numerator_as_decimal(PyObject *r, PyObject *context)
2980 { 2833 {
2981 PyObject *tmp, *num; 2834 PyObject *tmp, *num;
2982 2835
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
3015 dec_addstatus(context, MPD_Float_operation)) { 2868 dec_addstatus(context, MPD_Float_operation)) {
3016 *wcmp = NULL; 2869 *wcmp = NULL;
3017 } 2870 }
3018 else { 2871 else {
3019 ctx->status |= MPD_Float_operation; 2872 ctx->status |= MPD_Float_operation;
3020 *wcmp = PyDec_FromFloatExact(w, context); 2873 *wcmp = PyDec_FromFloatExact(w, context);
3021 } 2874 }
3022 } 2875 }
3023 else if (PyComplex_Check(w) && (op == Py_EQ || op == Py_NE)) { 2876 else if (PyComplex_Check(w) && (op == Py_EQ || op == Py_NE)) {
3024 Py_complex c = PyComplex_AsCComplex(w); 2877 Py_complex c = PyComplex_AsCComplex(w);
3025 » » if (PyErr_Occurred()) { 2878 » » if (c.real == -1.0 && PyErr_Occurred()) {
3026 *wcmp = NULL; 2879 *wcmp = NULL;
3027 } 2880 }
3028 else if (c.imag == 0.0) { 2881 else if (c.imag == 0.0) {
3029 PyObject *tmp = PyFloat_FromDouble(c.real); 2882 PyObject *tmp = PyFloat_FromDouble(c.real);
3030 if (tmp == NULL) { 2883 if (tmp == NULL) {
3031 *wcmp = NULL; 2884 *wcmp = NULL;
3032 } 2885 }
3033 else { 2886 else {
3034 ctx->status |= MPD_Float_operation; 2887 ctx->status |= MPD_Float_operation;
3035 *wcmp = PyDec_FromFloatExact(tmp, context); 2888 *wcmp = PyDec_FromFloatExact(tmp, context);
3036 Py_DECREF(tmp); 2889 Py_DECREF(tmp);
3037 } 2890 }
3038 } 2891 }
3039 else { 2892 else {
3040 Py_INCREF(Py_NotImplemented); 2893 Py_INCREF(Py_NotImplemented);
3041 *wcmp = Py_NotImplemented; 2894 *wcmp = Py_NotImplemented;
3042 } 2895 }
3043 } 2896 }
3044 » else if (PyObject_IsInstance(w, _Rational)) { 2897 » else if (PyObject_IsInstance(w, Rational)) {
3045 *wcmp = numerator_as_decimal(w, context); 2898 *wcmp = numerator_as_decimal(w, context);
3046 if (*wcmp && !mpd_isspecial(MPD(v))) { 2899 if (*wcmp && !mpd_isspecial(MPD(v))) {
3047 *vcmp = multiply_by_denominator(v, w, context); 2900 *vcmp = multiply_by_denominator(v, w, context);
3048 if (*vcmp == NULL) { 2901 if (*vcmp == NULL) {
3049 Py_CLEAR(*wcmp); 2902 Py_CLEAR(*wcmp);
3050 } 2903 }
3051 } 2904 }
3052 } 2905 }
3053 else { 2906 else {
3054 Py_INCREF(Py_NotImplemented); 2907 Py_INCREF(Py_NotImplemented);
(...skipping 12 matching lines...) Expand all
3067 #define CONVERT_BINOP_CMP(vcmp, wcmp, v, w, op, ctx) \ 2920 #define CONVERT_BINOP_CMP(vcmp, wcmp, v, w, op, ctx) \
3068 if (!convert_op_cmp(vcmp, wcmp, v, w, op, ctx)) { \ 2921 if (!convert_op_cmp(vcmp, wcmp, v, w, op, ctx)) { \
3069 return *(wcmp); \ 2922 return *(wcmp); \
3070 } \ 2923 } \
3071 2924
3072 2925
3073 /******************************************************************************/ 2926 /******************************************************************************/
3074 /* Conversions from decimal */ 2927 /* Conversions from decimal */
3075 /******************************************************************************/ 2928 /******************************************************************************/
3076 2929
2930 static PyObject *
2931 unicode_fromascii(const char *s, Py_ssize_t size)
2932 {
2933 PyObject *res;
2934
2935 res = PyUnicode_New(size, 127);
2936 if (res == NULL) {
2937 return NULL;
2938 }
2939
2940 memcpy(PyUnicode_1BYTE_DATA(res), s, size);
2941 return res;
2942 }
2943
3077 /* PyDecObject as a string. The default module context is only used for 2944 /* PyDecObject as a string. The default module context is only used for
3078 the value of 'capitals'. */ 2945 the value of 'capitals'. */
3079 static PyObject * 2946 static PyObject *
3080 dec_str(PyObject *dec) 2947 dec_str(PyObject *dec)
3081 { 2948 {
3082 » PyObject *s, *c; 2949 » PyObject *res, *context;
3083 » char *res; 2950 » mpd_ssize_t size;
3084 2951 » char *cp;
3085 » CURRENT_CONTEXT(c); 2952
3086 » res = mpd_to_sci(MPD(dec), CtxCaps(c)); 2953 » CURRENT_CONTEXT(context);
3087 » if (res == NULL) { 2954 » size = mpd_to_sci_size(&cp, MPD(dec), CtxCaps(context));
2955 » if (size < 0) {
3088 PyErr_NoMemory(); 2956 PyErr_NoMemory();
3089 return NULL; 2957 return NULL;
3090 } 2958 }
3091 2959
3092 » s = PyUnicode_FromString(res); 2960 » res = unicode_fromascii(cp, size);
3093 » mpd_free(res); 2961 » mpd_free(cp);
3094 2962 » return res;
3095 » return s; 2963 }
3096 }
3097
3098 static const char *dtag = "Decimal('";
3099 static const size_t dtaglen = 9; /* without NUL terminator */
3100 2964
3101 /* Representation of a PyDecObject. */ 2965 /* Representation of a PyDecObject. */
3102 static PyObject * 2966 static PyObject *
3103 dec_repr(PyObject *dec) 2967 dec_repr(PyObject *dec)
3104 { 2968 {
3105 » PyObject *s, *c; 2969 » PyObject *res, *context;
3106 » uint8_t err;
3107 char *cp; 2970 char *cp;
3108 » size_t declen; 2971
3109 2972 » CURRENT_CONTEXT(context);
3110 » CURRENT_CONTEXT(c); 2973 » cp = mpd_to_sci(MPD(dec), CtxCaps(context));
3111 » cp = mpd_to_sci(MPD(dec), CtxCaps(c));
3112 if (cp == NULL) { 2974 if (cp == NULL) {
3113 PyErr_NoMemory(); 2975 PyErr_NoMemory();
3114 return NULL; 2976 return NULL;
3115 } 2977 }
3116 » declen = strlen(cp); 2978
3117 2979 » res = PyUnicode_FromFormat("Decimal('%s')", cp);
3118 » err = 0;
3119 » cp = mpd_realloc(cp, (mpd_size_t)(declen+dtaglen+3), sizeof *cp, &err);
3120 » if (err) {
3121 » » mpd_free(cp);
3122 » » PyErr_NoMemory();
3123 » » return NULL;
3124 » }
3125
3126 » memmove(cp+dtaglen, cp, declen);
3127 » memcpy(cp, dtag, dtaglen);
3128 » cp[declen+dtaglen] = '\'';
3129 » cp[declen+dtaglen+1] = ')';
3130 » cp[declen+dtaglen+2] = '\0';
3131
3132 » s = PyUnicode_FromString(cp);
3133
3134 mpd_free(cp); 2980 mpd_free(cp);
3135 » return s; 2981 » return res;
2982 }
2983
2984 /* Convert decimal_point or thousands_sep, which may be multibyte or in
2985 the range [128, 255], to a UTF8 string. */
2986 static PyObject *
2987 dotsep_as_utf8(const char *s)
2988 {
2989 » PyObject *utf8;
2990 » PyObject *tmp;
2991 » wchar_t buf[2];
2992 » size_t n;
2993
2994 » n = mbstowcs(buf, s, 2);
2995 » if (n != 1) { /* Issue #7442 */
2996 » » PyErr_SetString(PyExc_ValueError,
2997 » » "invalid decimal point or unsupported "
2998 » » "combination of LC_CTYPE and LC_NUMERIC");
2999 » » return NULL;
3000 » }
3001 » tmp = PyUnicode_FromWideChar(buf, n);
3002 » if (tmp == NULL) {
3003 » » return NULL;
3004 » }
3005 » utf8 = PyUnicode_AsUTF8String(tmp);
3006 » Py_DECREF(tmp);
3007 » return utf8;
3136 } 3008 }
3137 3009
3138 /* Formatted representation of a PyDecObject. */ 3010 /* Formatted representation of a PyDecObject. */
3139 static PyObject * 3011 static PyObject *
3140 dec_format(PyObject *dec, PyObject *args) 3012 dec_format(PyObject *dec, PyObject *args)
3141 { 3013 {
3142 PyObject *result = NULL; 3014 PyObject *result = NULL;
3143 PyObject *override = NULL; 3015 PyObject *override = NULL;
3144 PyObject *dot = NULL; 3016 PyObject *dot = NULL;
3145 PyObject *sep = NULL; 3017 PyObject *sep = NULL;
3146 PyObject *grouping = NULL; 3018 PyObject *grouping = NULL;
3147 PyObject *fmt = NULL; 3019 PyObject *fmt = NULL;
3148 PyObject *fmtarg; 3020 PyObject *fmtarg;
3149 PyObject *tmp;
3150 PyObject *context; 3021 PyObject *context;
3151 mpd_spec_t spec; 3022 mpd_spec_t spec;
3152 wchar_t buf[2];
3153 char *decstring= NULL; 3023 char *decstring= NULL;
3154 uint32_t status = 0; 3024 uint32_t status = 0;
3155 size_t n; 3025 size_t n;
3156 3026
3157 3027
3158 CURRENT_CONTEXT(context); 3028 CURRENT_CONTEXT(context);
3159 if (!PyArg_ParseTuple(args, "O|O", &fmtarg, &override)) { 3029 if (!PyArg_ParseTuple(args, "O|O", &fmtarg, &override)) {
3160 return NULL; 3030 return NULL;
3161 } 3031 }
3162 3032
3163 if (PyUnicode_Check(fmtarg)) { 3033 if (PyUnicode_Check(fmtarg)) {
3164 » » if ((fmt = PyUnicode_AsUTF8String(fmtarg)) == NULL) { 3034 » » fmt = PyUnicode_AsUTF8String(fmtarg);
3035 » » if (fmt == NULL) {
3165 return NULL; 3036 return NULL;
3166 } 3037 }
3167 } 3038 }
3168 else { 3039 else {
3169 PyErr_SetString(PyExc_TypeError, 3040 PyErr_SetString(PyExc_TypeError,
3170 » » "format arg must be str."); 3041 » » "format arg must be str");
3171 return NULL; 3042 return NULL;
3172 } 3043 }
3173 3044
3174 if (!mpd_parse_fmt_str(&spec, PyBytes_AS_STRING(fmt), 3045 if (!mpd_parse_fmt_str(&spec, PyBytes_AS_STRING(fmt),
3175 CtxCaps(context))) { 3046 CtxCaps(context))) {
3176 PyErr_SetString(PyExc_ValueError, 3047 PyErr_SetString(PyExc_ValueError,
3177 » » "invalid format string."); 3048 » » "invalid format string");
3178 goto finish; 3049 goto finish;
3179 } 3050 }
3180 if (override) { 3051 if (override) {
3052 /* Values for decimal_point, thousands_sep and grouping can
3053 be explicitly specified in the override dict. These values
3054 take precedence over the values obtained from localeconv()
3055 in mpd_parse_fmt_str(). The feature is not documented and
3056 is only used in test_decimal. */
3181 if (!PyDict_Check(override)) { 3057 if (!PyDict_Check(override)) {
3182 PyErr_SetString(PyExc_TypeError, 3058 PyErr_SetString(PyExc_TypeError,
3183 » » » "optional argument must be a dict."); 3059 » » » "optional argument must be a dict");
3184 goto finish; 3060 goto finish;
3185 } 3061 }
3186 if ((dot = PyDict_GetItemString(override, "decimal_point"))) { 3062 if ((dot = PyDict_GetItemString(override, "decimal_point"))) {
3187 if ((dot = PyUnicode_AsUTF8String(dot)) == NULL) { 3063 if ((dot = PyUnicode_AsUTF8String(dot)) == NULL) {
3188 goto finish; 3064 goto finish;
3189 } 3065 }
3190 spec.dot = PyBytes_AS_STRING(dot); 3066 spec.dot = PyBytes_AS_STRING(dot);
3191 } 3067 }
3192 if ((sep = PyDict_GetItemString(override, "thousands_sep"))) { 3068 if ((sep = PyDict_GetItemString(override, "thousands_sep"))) {
3193 if ((sep = PyUnicode_AsUTF8String(sep)) == NULL) { 3069 if ((sep = PyUnicode_AsUTF8String(sep)) == NULL) {
3194 goto finish; 3070 goto finish;
3195 } 3071 }
3196 spec.sep = PyBytes_AS_STRING(sep); 3072 spec.sep = PyBytes_AS_STRING(sep);
3197 } 3073 }
3198 if ((grouping = PyDict_GetItemString(override, "grouping"))) { 3074 if ((grouping = PyDict_GetItemString(override, "grouping"))) {
3199 if ((grouping = PyUnicode_AsUTF8String(grouping)) == NUL L) { 3075 if ((grouping = PyUnicode_AsUTF8String(grouping)) == NUL L) {
3200 goto finish; 3076 goto finish;
3201 } 3077 }
3202 spec.grouping = PyBytes_AS_STRING(grouping); 3078 spec.grouping = PyBytes_AS_STRING(grouping);
3203 } 3079 }
3080 if (mpd_validate_lconv(&spec) < 0) {
3081 PyErr_SetString(PyExc_ValueError,
3082 "invalid override dict");
3083 goto finish;
3084 }
3204 } 3085 }
3205 else { 3086 else {
3206 n = strlen(spec.dot); 3087 n = strlen(spec.dot);
3207 if (n > 1 || (n == 1 && !isascii((uchar)spec.dot[0]))) { 3088 if (n > 1 || (n == 1 && !isascii((uchar)spec.dot[0]))) {
3208 » » » n = mbstowcs(buf, spec.dot, 2); 3089 » » » /* fix locale dependent non-ascii characters */
3209 » » » if (n != 1) { 3090 » » » dot = dotsep_as_utf8(spec.dot);
3210 » » » » PyErr_SetString(PyExc_ValueError, 3091 » » » if (dot == NULL) {
3211 » » » » "invalid decimal point or unsupported "
3212 » » » » "combination of LC_CTYPE and LC_NUMERIC.");
3213 » » » » goto finish;
3214 » » » }
3215 » » » if ((tmp = PyUnicode_FromWideChar(buf, n)) == NULL) {
3216 » » » » goto finish;
3217 » » » }
3218 » » » if ((dot = PyUnicode_AsUTF8String(tmp)) == NULL) {
3219 » » » » Py_DECREF(tmp);
3220 goto finish; 3092 goto finish;
3221 } 3093 }
3222 spec.dot = PyBytes_AS_STRING(dot); 3094 spec.dot = PyBytes_AS_STRING(dot);
3223 Py_DECREF(tmp);
3224 } 3095 }
3225 n = strlen(spec.sep); 3096 n = strlen(spec.sep);
3226 if (n > 1 || (n == 1 && !isascii((uchar)spec.sep[0]))) { 3097 if (n > 1 || (n == 1 && !isascii((uchar)spec.sep[0]))) {
3227 » » » n = mbstowcs(buf, spec.sep, 2); 3098 » » » /* fix locale dependent non-ascii characters */
3228 » » » if (n != 1) { 3099 » » » sep = dotsep_as_utf8(spec.sep);
3229 » » » » PyErr_SetString(PyExc_ValueError, 3100 » » » if (sep == NULL) {
3230 » » » » "invalid thousands separator or unsupported "
3231 » » » » "combination of LC_CTYPE and LC_NUMERIC.");
3232 » » » » goto finish;
3233 » » » }
3234 » » » if ((tmp = PyUnicode_FromWideChar(buf, n)) == NULL) {
3235 » » » » goto finish;
3236 » » » }
3237 » » » if ((sep = PyUnicode_AsUTF8String(tmp)) == NULL) {
3238 » » » » Py_DECREF(tmp);
3239 goto finish; 3101 goto finish;
3240 } 3102 }
3241 spec.sep = PyBytes_AS_STRING(sep); 3103 spec.sep = PyBytes_AS_STRING(sep);
3242 Py_DECREF(tmp);
3243 } 3104 }
3244 } 3105 }
3245 3106
3246 3107
3247 decstring = mpd_qformat_spec(MPD(dec), &spec, CTX(context), &status); 3108 decstring = mpd_qformat_spec(MPD(dec), &spec, CTX(context), &status);
3248 if (decstring == NULL) { 3109 if (decstring == NULL) {
3249 dec_addstatus(context, status); 3110 dec_addstatus(context, status);
3250 goto finish; 3111 goto finish;
3251 } 3112 }
3252 result = PyUnicode_DecodeUTF8(decstring, strlen(decstring), NULL); 3113 result = PyUnicode_DecodeUTF8(decstring, strlen(decstring), NULL);
(...skipping 16 matching lines...) Expand all
3269 PyLongObject *pylong; 3130 PyLongObject *pylong;
3270 size_t maxsize, n; 3131 size_t maxsize, n;
3271 Py_ssize_t i; 3132 Py_ssize_t i;
3272 mpd_t *x; 3133 mpd_t *x;
3273 mpd_context_t workctx; 3134 mpd_context_t workctx;
3274 uint32_t status = 0; 3135 uint32_t status = 0;
3275 3136
3276 if (mpd_isspecial(MPD(dec))) { 3137 if (mpd_isspecial(MPD(dec))) {
3277 if (mpd_isnan(MPD(dec))) { 3138 if (mpd_isnan(MPD(dec))) {
3278 PyErr_SetString(PyExc_ValueError, 3139 PyErr_SetString(PyExc_ValueError,
3279 » » » "cannot convert NaN to integer."); 3140 » » » "cannot convert NaN to integer");
3280 } 3141 }
3281 else { 3142 else {
3282 PyErr_SetString(PyExc_OverflowError, 3143 PyErr_SetString(PyExc_OverflowError,
3283 » » » "cannot convert Infinity to integer."); 3144 » » » "cannot convert Infinity to integer");
3284 » » } 3145 » » }
3285 » » return NULL; 3146 » » return NULL;
3286 » } 3147 » }
3287 3148
3288 » if ((x = mpd_qnew()) == NULL) { 3149 » x = mpd_qnew();
3150 » if (x == NULL) {
3289 PyErr_NoMemory(); 3151 PyErr_NoMemory();
3290 return NULL; 3152 return NULL;
3291 } 3153 }
3292 workctx = *CTX(context); 3154 workctx = *CTX(context);
3293 workctx.round = round; 3155 workctx.round = round;
3294 mpd_qround_to_int(x, MPD(dec), &workctx, &status); 3156 mpd_qround_to_int(x, MPD(dec), &workctx, &status);
3295 if (dec_addstatus(context, status)) { 3157 if (dec_addstatus(context, status)) {
3296 mpd_del(x); 3158 mpd_del(x);
3297 return NULL; 3159 return NULL;
3298 } 3160 }
3299 3161
3300 maxsize = mpd_sizeinbase(x, PyLong_BASE); 3162 maxsize = mpd_sizeinbase(x, PyLong_BASE);
3301 if (maxsize > PY_SSIZE_T_MAX) { 3163 if (maxsize > PY_SSIZE_T_MAX) {
3302 mpd_del(x); 3164 mpd_del(x);
3303 PyErr_NoMemory(); 3165 PyErr_NoMemory();
3304 return NULL; 3166 return NULL;
3305 } 3167 }
3306 » if ((pylong = _PyLong_New(maxsize)) == NULL) { 3168 » pylong = _PyLong_New(maxsize);
3169 » if (pylong == NULL) {
3307 mpd_del(x); 3170 mpd_del(x);
3308 return NULL; 3171 return NULL;
3309 } 3172 }
3310 3173
3311 status = 0; 3174 status = 0;
3312 #if PYLONG_BITS_IN_DIGIT == 30 3175 #if PYLONG_BITS_IN_DIGIT == 30
3313 n = mpd_qexport_u32(pylong->ob_digit, maxsize, PyLong_BASE, x, &status); 3176 n = mpd_qexport_u32(pylong->ob_digit, maxsize, PyLong_BASE, x, &status);
3314 #elif PYLONG_BITS_IN_DIGIT == 15 3177 #elif PYLONG_BITS_IN_DIGIT == 15
3315 n = mpd_qexport_u16(pylong->ob_digit, maxsize, PyLong_BASE, x, &status); 3178 n = mpd_qexport_u16(pylong->ob_digit, maxsize, PyLong_BASE, x, &status);
3316 #else 3179 #else
3317 #error "PYLONG_BITS_IN_DIGIT should be 15 or 30." 3180 #error "PYLONG_BITS_IN_DIGIT should be 15 or 30"
3318 #endif 3181 #endif
3319 if (dec_addstatus(context, status)) { 3182 if (dec_addstatus(context, status)) {
3320 Py_DECREF((PyObject *) pylong); 3183 Py_DECREF((PyObject *) pylong);
3321 mpd_del(x); 3184 mpd_del(x);
3322 return NULL; 3185 return NULL;
3323 } 3186 }
3324 3187
3325 i = n; 3188 i = n;
3326 while ((i > 0) && (pylong->ob_digit[i-1] == 0)) { 3189 while ((i > 0) && (pylong->ob_digit[i-1] == 0)) {
3327 i--; 3190 i--;
(...skipping 25 matching lines...) Expand all
3353 } 3216 }
3354 CONTEXT_CHECK_VA(context); 3217 CONTEXT_CHECK_VA(context);
3355 3218
3356 workctx = *CTX(context); 3219 workctx = *CTX(context);
3357 if (round >= 0) { 3220 if (round >= 0) {
3358 if (!mpd_qsetround(&workctx, round)) { 3221 if (!mpd_qsetround(&workctx, round)) {
3359 return type_error_ptr(invalid_rounding_err); 3222 return type_error_ptr(invalid_rounding_err);
3360 } 3223 }
3361 } 3224 }
3362 3225
3363 » if ((result = dec_alloc()) == NULL) { 3226 » result = dec_alloc();
3227 » if (result == NULL) {
3364 return NULL; 3228 return NULL;
3365 } 3229 }
3366 3230
3367 mpd_qround_to_int(MPD(result), MPD(dec), &workctx, &status); 3231 mpd_qround_to_int(MPD(result), MPD(dec), &workctx, &status);
3368 if (dec_addstatus(context, status)) { 3232 if (dec_addstatus(context, status)) {
3369 Py_DECREF(result); 3233 Py_DECREF(result);
3370 return NULL; 3234 return NULL;
3371 } 3235 }
3372 3236
3373 return result; 3237 return result;
(...skipping 16 matching lines...) Expand all
3390 } 3254 }
3391 CONTEXT_CHECK_VA(context); 3255 CONTEXT_CHECK_VA(context);
3392 3256
3393 workctx = *CTX(context); 3257 workctx = *CTX(context);
3394 if (round >= 0) { 3258 if (round >= 0) {
3395 if (!mpd_qsetround(&workctx, round)) { 3259 if (!mpd_qsetround(&workctx, round)) {
3396 return type_error_ptr(invalid_rounding_err); 3260 return type_error_ptr(invalid_rounding_err);
3397 } 3261 }
3398 } 3262 }
3399 3263
3400 » if ((result = dec_alloc()) == NULL) { 3264 » result = dec_alloc();
3265 » if (result == NULL) {
3401 return NULL; 3266 return NULL;
3402 } 3267 }
3403 3268
3404 mpd_qround_to_intx(MPD(result), MPD(dec), &workctx, &status); 3269 mpd_qround_to_intx(MPD(result), MPD(dec), &workctx, &status);
3405 if (dec_addstatus(context, status)) { 3270 if (dec_addstatus(context, status)) {
3406 Py_DECREF(result); 3271 Py_DECREF(result);
3407 return NULL; 3272 return NULL;
3408 } 3273 }
3409 3274
3410 return result; 3275 return result;
3411 } 3276 }
3412 3277
3413 static PyObject * 3278 static PyObject *
3414 PyDec_AsFloat(PyObject *dec) 3279 PyDec_AsFloat(PyObject *dec)
3415 { 3280 {
3416 PyObject *f, *s; 3281 PyObject *f, *s;
3417 3282
3418 » if ((s = dec_str(dec)) == NULL) { 3283 » s = dec_str(dec);
3284 » if (s == NULL) {
3419 return NULL; 3285 return NULL;
3420 } 3286 }
3421 3287
3422 f = PyFloat_FromString(s); 3288 f = PyFloat_FromString(s);
3423 Py_DECREF(s); 3289 Py_DECREF(s);
3424 3290
3425 return f; 3291 return f;
3426 } 3292 }
3427 3293
3428 static PyObject * 3294 static PyObject *
(...skipping 10 matching lines...) Expand all
3439 return NULL; 3305 return NULL;
3440 } 3306 }
3441 3307
3442 if (x) { 3308 if (x) {
3443 mpd_uint_t dq[1] = {1}; 3309 mpd_uint_t dq[1] = {1};
3444 mpd_t q = {MPD_STATIC|MPD_CONST_DATA,0,1,1,1,dq}; 3310 mpd_t q = {MPD_STATIC|MPD_CONST_DATA,0,1,1,1,dq};
3445 mpd_ssize_t y; 3311 mpd_ssize_t y;
3446 3312
3447 if (!PyLong_Check(x)) { 3313 if (!PyLong_Check(x)) {
3448 PyErr_SetString(PyExc_TypeError, 3314 PyErr_SetString(PyExc_TypeError,
3449 » » » "optional arg must be an integer."); 3315 » » » "optional arg must be an integer");
3450 return NULL; 3316 return NULL;
3451 } 3317 }
3452 3318
3453 » » y = long_as_mpd_ssize(x); 3319 » » y = PyLong_AsSsize_t(x);
3454 » » if (PyErr_Occurred()) { 3320 » » if (y == -1 && PyErr_Occurred()) {
3455 return NULL; 3321 return NULL;
3456 } 3322 }
3457 » » if ((result = dec_alloc()) == NULL) { 3323 » » result = dec_alloc();
3324 » » if (result == NULL) {
3458 return NULL; 3325 return NULL;
3459 } 3326 }
3460 3327
3461 q.exp = (y == MPD_SSIZE_MIN) ? MPD_SSIZE_MAX : -y; 3328 q.exp = (y == MPD_SSIZE_MIN) ? MPD_SSIZE_MAX : -y;
3462 mpd_qquantize(MPD(result), MPD(dec), &q, CTX(context), &status); 3329 mpd_qquantize(MPD(result), MPD(dec), &q, CTX(context), &status);
3463 if (dec_addstatus(context, status)) { 3330 if (dec_addstatus(context, status)) {
3464 Py_DECREF(result); 3331 Py_DECREF(result);
3465 return NULL; 3332 return NULL;
3466 } 3333 }
3467 3334
(...skipping 12 matching lines...) Expand all
3480 PyObject *result = NULL; 3347 PyObject *result = NULL;
3481 PyObject *sign = NULL; 3348 PyObject *sign = NULL;
3482 PyObject *coeff = NULL; 3349 PyObject *coeff = NULL;
3483 PyObject *expt = NULL; 3350 PyObject *expt = NULL;
3484 PyObject *tmp = NULL; 3351 PyObject *tmp = NULL;
3485 mpd_t *x = NULL; 3352 mpd_t *x = NULL;
3486 char *intstring = NULL; 3353 char *intstring = NULL;
3487 Py_ssize_t intlen, i; 3354 Py_ssize_t intlen, i;
3488 3355
3489 3356
3490 » if ((x = mpd_qncopy(MPD(dec))) == NULL) { 3357 » x = mpd_qncopy(MPD(dec));
3358 » if (x == NULL) {
3491 PyErr_NoMemory(); 3359 PyErr_NoMemory();
3492 goto out; 3360 goto out;
3493 } 3361 }
3494 3362
3495 » sign = Py_BuildValue("i", mpd_sign(MPD(dec))); 3363 » sign = PyLong_FromUnsignedLong(mpd_sign(MPD(dec)));
3496 » if (sign == NULL) goto out; 3364 » if (sign == NULL) {
3365 » » goto out;
3366 » }
3497 3367
3498 if (mpd_isinfinite(x)) { 3368 if (mpd_isinfinite(x)) {
3499 » » if ((expt = Py_BuildValue("s", "F")) == NULL) { 3369 » » expt = PyUnicode_FromString("F");
3370 » » if (expt == NULL) {
3500 goto out; 3371 goto out;
3501 } 3372 }
3502 /* decimal.py has non-compliant infinity payloads. */ 3373 /* decimal.py has non-compliant infinity payloads. */
3503 » » if ((coeff = Py_BuildValue("(i)", 0)) == NULL) { 3374 » » coeff = Py_BuildValue("(i)", 0);
3375 » » if (coeff == NULL) {
3504 goto out; 3376 goto out;
3505 } 3377 }
3506 } 3378 }
3507 else { 3379 else {
3508 if (mpd_isnan(x)) { 3380 if (mpd_isnan(x)) {
3509 » » » expt = Py_BuildValue("s", mpd_isqnan(x)?"n":"N"); 3381 » » » expt = PyUnicode_FromString(mpd_isqnan(x)?"n":"N");
3510 } 3382 }
3511 else { 3383 else {
3512 » » » expt = Py_BuildValue(CONV_mpd_ssize_t, MPD(dec)->exp); 3384 » » » expt = PyLong_FromSsize_t(MPD(dec)->exp);
3513 » » } 3385 » » }
3514 » » if (expt == NULL) goto out; 3386 » » if (expt == NULL) {
3387 » » » goto out;
3388 » » }
3515 3389
3516 /* coefficient is defined */ 3390 /* coefficient is defined */
3517 if (x->len > 0) { 3391 if (x->len > 0) {
3518 3392
3519 /* make an integer */ 3393 /* make an integer */
3520 x->exp = 0; 3394 x->exp = 0;
3521 /* clear NaN and sign */ 3395 /* clear NaN and sign */
3522 mpd_clear_flags(x); 3396 mpd_clear_flags(x);
3523 intstring = mpd_to_sci(x, 1); 3397 intstring = mpd_to_sci(x, 1);
3524 if (intstring == NULL) { 3398 if (intstring == NULL) {
3525 PyErr_NoMemory(); 3399 PyErr_NoMemory();
3526 goto out; 3400 goto out;
3527 } 3401 }
3528 3402
3529 intlen = strlen(intstring); 3403 intlen = strlen(intstring);
3530 » » » if ((coeff = PyTuple_New(intlen)) == NULL) { 3404 » » » coeff = PyTuple_New(intlen);
3405 » » » if (coeff == NULL) {
3531 goto out; 3406 goto out;
3532 } 3407 }
3533 3408
3534 for (i = 0; i < intlen; i++) { 3409 for (i = 0; i < intlen; i++) {
3535 » » » » tmp = Py_BuildValue("i", intstring[i]-'0'); 3410 » » » » tmp = PyLong_FromLong(intstring[i]-'0');
3536 » » » » if (tmp == NULL) goto out; 3411 » » » » if (tmp == NULL) {
3412 » » » » » goto out;
3413 » » » » }
3537 PyTuple_SET_ITEM(coeff, i, tmp); 3414 PyTuple_SET_ITEM(coeff, i, tmp);
3538 } 3415 }
3539 } 3416 }
3540 else { 3417 else {
3541 » » » if ((coeff = PyTuple_New(0)) == NULL) { 3418 » » » coeff = PyTuple_New(0);
3419 » » » if (coeff == NULL) {
3542 goto out; 3420 goto out;
3543 } 3421 }
3544 } 3422 }
3545 } 3423 }
3546 3424
3547 result = PyObject_CallFunctionObjArgs(DecimalTuple, 3425 result = PyObject_CallFunctionObjArgs(DecimalTuple,
3548 sign, coeff, expt, NULL); 3426 sign, coeff, expt, NULL);
3549 3427
3550 out: 3428 out:
3551 if (x) mpd_del(x); 3429 if (x) mpd_del(x);
(...skipping 28 matching lines...) Expand all
3580 Py_DECREF(result); \ 3458 Py_DECREF(result); \
3581 return NULL; \ 3459 return NULL; \
3582 } \ 3460 } \
3583 \ 3461 \
3584 return result; \ 3462 return result; \
3585 } 3463 }
3586 3464
3587 /* Binary number method that uses default module context. */ 3465 /* Binary number method that uses default module context. */
3588 #define Dec_BinaryNumberMethod(MPDFUNC) \ 3466 #define Dec_BinaryNumberMethod(MPDFUNC) \
3589 static PyObject * \ 3467 static PyObject * \
3590 nm_##MPDFUNC(PyObject *v, PyObject *w) \ 3468 nm_##MPDFUNC(PyObject *self, PyObject *other) \
3591 { \ 3469 { \
3592 PyObject *a, *b; \ 3470 PyObject *a, *b; \
3593 PyObject *result; \ 3471 PyObject *result; \
3594 PyObject *context; \ 3472 PyObject *context; \
3595 uint32_t status = 0; \ 3473 uint32_t status = 0; \
3596 \ 3474 \
3597 CURRENT_CONTEXT(context) ; \ 3475 CURRENT_CONTEXT(context) ; \
3598 CONVERT_BINOP(&a, &b, v, w, context); \ 3476 CONVERT_BINOP(&a, &b, self, other, context); \
3599 \ 3477 \
3600 if ((result = dec_alloc()) == NULL) { \ 3478 if ((result = dec_alloc()) == NULL) { \
3601 Py_DECREF(a); \ 3479 Py_DECREF(a); \
3602 Py_DECREF(b); \ 3480 Py_DECREF(b); \
3603 return NULL; \ 3481 return NULL; \
3604 } \ 3482 } \
3605 \ 3483 \
3606 MPDFUNC(MPD(result), MPD(a), MPD(b), CTX(context), &status); \ 3484 MPDFUNC(MPD(result), MPD(a), MPD(b), CTX(context), &status); \
3607 Py_DECREF(a); \ 3485 Py_DECREF(a); \
3608 Py_DECREF(b); \ 3486 Py_DECREF(b); \
3609 if (dec_addstatus(context, status)) { \ 3487 if (dec_addstatus(context, status)) { \
3610 Py_DECREF(result); \ 3488 Py_DECREF(result); \
3611 return NULL; \ 3489 return NULL; \
3612 } \ 3490 } \
3613 \ 3491 \
3614 return result; \ 3492 return result; \
3615 } 3493 }
3616 3494
3617 /* Boolean function without a context arg. */ 3495 /* Boolean function without a context arg. */
3618 #define Dec_BoolFunc(MPDFUNC) \ 3496 #define Dec_BoolFunc(MPDFUNC) \
3619 static PyObject * \ 3497 static PyObject * \
3620 dec_##MPDFUNC(PyObject *self, PyObject *dummy UNUSED) \ 3498 dec_##MPDFUNC(PyObject *self, PyObject *dummy UNUSED) \
3621 { \ 3499 { \
3622 return MPDFUNC(MPD(self)) ? Dec_INCREF_TRUE : Dec_INCREF_FALSE; \ 3500 return MPDFUNC(MPD(self)) ? incr_true() : incr_false(); \
3623 } 3501 }
3624 3502
3625 /* Boolean function with an optional context arg. */ 3503 /* Boolean function with an optional context arg. */
3626 #define Dec_BoolFuncVA(MPDFUNC) \ 3504 #define Dec_BoolFuncVA(MPDFUNC) \
3627 static PyObject * \ 3505 static PyObject * \
3628 dec_##MPDFUNC(PyObject *self, PyObject *args) \ 3506 dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \
3629 { \ 3507 { \
3630 PyObject *context; \ 3508 static char *kwlist[] = {"context", NULL}; \
3631 \ 3509 PyObject *context; \
3632 CURRENT_CONTEXT(context); \ 3510 \
3633 if (!PyArg_ParseTuple(args, "|O", &context)) { \ 3511 CURRENT_CONTEXT(context); \
3634 return NULL; \ 3512 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, \
3635 } \ 3513 &context)) { \
3636 CONTEXT_CHECK_VA(context); \ 3514 return NULL; \
3637 \ 3515 } \
3638 return MPDFUNC(MPD(self), CTX(context)) \ 3516 CONTEXT_CHECK_VA(context); \
3639 ? Dec_INCREF_TRUE : Dec_INCREF_FALSE; \ 3517 \
3518 return MPDFUNC(MPD(self), CTX(context)) ? incr_true() : incr_false(); \
3640 } 3519 }
3641 3520
3642 /* Unary function with an optional context arg. */ 3521 /* Unary function with an optional context arg. */
3643 #define Dec_UnaryFuncVA(MPDFUNC) \ 3522 #define Dec_UnaryFuncVA(MPDFUNC) \
3644 static PyObject * \ 3523 static PyObject * \
3645 dec_##MPDFUNC(PyObject *self, PyObject *args) \ 3524 dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \
3646 { \ 3525 { \
3647 PyObject *result; \ 3526 static char *kwlist[] = {"context", NULL}; \
3648 PyObject *context; \ 3527 PyObject *result; \
3649 uint32_t status = 0; \ 3528 PyObject *context; \
3650 \ 3529 uint32_t status = 0; \
3651 CURRENT_CONTEXT(context); \ 3530 \
3652 if (!PyArg_ParseTuple(args, "|O", &context)) { \ 3531 CURRENT_CONTEXT(context); \
3653 return NULL; \ 3532 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, \
3654 } \ 3533 &context)) { \
3655 CONTEXT_CHECK_VA(context); \ 3534 return NULL; \
3656 \ 3535 } \
3657 if ((result = dec_alloc()) == NULL) { \ 3536 CONTEXT_CHECK_VA(context); \
3658 return NULL; \ 3537 \
3659 } \ 3538 if ((result = dec_alloc()) == NULL) { \
3660 \ 3539 return NULL; \
3661 MPDFUNC(MPD(result), MPD(self), CTX(context), &status); \ 3540 } \
3662 if (dec_addstatus(context, status)) { \ 3541 \
3663 Py_DECREF(result); \ 3542 MPDFUNC(MPD(result), MPD(self), CTX(context), &status); \
3664 return NULL; \ 3543 if (dec_addstatus(context, status)) { \
3665 } \ 3544 Py_DECREF(result); \
3666 \ 3545 return NULL; \
3667 return result; \ 3546 } \
3547 \
3548 return result; \
3549 }
3550
3551 /* Unary function with an optional context arg. The actual MPDFUNC
3552 only takes a status parameter. */
3553 #define Dec_UnaryFuncVA_NO_CTX(MPDFUNC) \
3554 static PyObject * \
3555 dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \
3556 { \
3557 static char *kwlist[] = {"context", NULL}; \
3558 PyObject *result; \
3559 PyObject *context; \
3560 uint32_t status = 0; \
3561 \
3562 CURRENT_CONTEXT(context); \
3563 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, \
3564 &context)) { \
3565 return NULL; \
3566 } \
3567 CONTEXT_CHECK_VA(context); \
3568 \
3569 if ((result = dec_alloc()) == NULL) { \
3570 return NULL; \
3571 } \
3572 \
3573 MPDFUNC(MPD(result), MPD(self), &status); \
3574 if (dec_addstatus(context, status)) { \
3575 Py_DECREF(result); \
3576 return NULL; \
3577 } \
3578 \
3579 return result; \
3668 } 3580 }
3669 3581
3670 /* Binary function with an optional context arg. */ 3582 /* Binary function with an optional context arg. */
3671 #define Dec_BinaryFuncVA(MPDFUNC) \ 3583 #define Dec_BinaryFuncVA(MPDFUNC) \
3672 static PyObject * \ 3584 static PyObject * \
3673 dec_##MPDFUNC(PyObject *v, PyObject *args) \ 3585 dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \
3674 { \ 3586 { \
3675 PyObject *w, *context; \ 3587 static char *kwlist[] = {"other", "context", NULL}; \
3588 PyObject *other, *context; \
3676 PyObject *a, *b; \ 3589 PyObject *a, *b; \
3677 PyObject *result; \ 3590 PyObject *result; \
3678 uint32_t status = 0; \ 3591 uint32_t status = 0; \
3679 \ 3592 \
3680 CURRENT_CONTEXT(context); \ 3593 CURRENT_CONTEXT(context); \
3681 if (!PyArg_ParseTuple(args, "O|O", &w, &context)) { \ 3594 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist, \
3595 &other, &context)) { \
3682 return NULL; \ 3596 return NULL; \
3683 } \ 3597 } \
3684 CONTEXT_CHECK_VA(context); \ 3598 CONTEXT_CHECK_VA(context); \
3685 CONVERT_BINOP_RAISE(&a, &b, v, w, context); \ 3599 CONVERT_BINOP_RAISE(&a, &b, self, other, context); \
3686 \ 3600 \
3687 if ((result = dec_alloc()) == NULL) { \ 3601 if ((result = dec_alloc()) == NULL) { \
3688 Py_DECREF(a); \ 3602 Py_DECREF(a); \
3689 Py_DECREF(b); \ 3603 Py_DECREF(b); \
3690 return NULL; \ 3604 return NULL; \
3691 } \ 3605 } \
3692 \ 3606 \
3693 MPDFUNC(MPD(result), MPD(a), MPD(b), CTX(context), &status); \ 3607 MPDFUNC(MPD(result), MPD(a), MPD(b), CTX(context), &status); \
3694 Py_DECREF(a); \ 3608 Py_DECREF(a); \
3695 Py_DECREF(b); \ 3609 Py_DECREF(b); \
3696 if (dec_addstatus(context, status)) { \ 3610 if (dec_addstatus(context, status)) { \
3697 Py_DECREF(result); \ 3611 Py_DECREF(result); \
3698 return NULL; \ 3612 return NULL; \
3699 } \ 3613 } \
3700 \ 3614 \
3701 return result; \ 3615 return result; \
3702 } 3616 }
3703 3617
3704 /* Binary function with an optional context arg. Actual MPDFUNC does 3618 /* Binary function with an optional context arg. Actual MPDFUNC does
3705 NOT take a context. Uses optional context for conversion only. */ 3619 NOT take a context. The context is used to record InvalidOperation
3620 if the second operand cannot be converted exactly. */
3706 #define Dec_BinaryFuncVA_NO_CTX(MPDFUNC) \ 3621 #define Dec_BinaryFuncVA_NO_CTX(MPDFUNC) \
3707 static PyObject * \ 3622 static PyObject * \
3708 dec_##MPDFUNC(PyObject *v, PyObject *args) \ 3623 dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \
3709 { \ 3624 { \
3710 PyObject *w, *context; \ 3625 static char *kwlist[] = {"other", "context", NULL}; \
3711 PyObject *a, *b; \ 3626 PyObject *other, *context; \
3712 PyObject *result; \ 3627 PyObject *a, *b; \
3713 \ 3628 PyObject *result; \
3714 CURRENT_CONTEXT(context); \ 3629 \
3715 if (!PyArg_ParseTuple(args, "O|O", &w, &context)) { \ 3630 CURRENT_CONTEXT(context); \
3716 return NULL; \ 3631 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist, \
3717 } \ 3632 &other, &context)) { \
3718 CONTEXT_CHECK_VA(context); \ 3633 return NULL; \
3719 CONVERT_BINOP_RAISE(&a, &b, v, w, context); \ 3634 } \
3720 \ 3635 CONTEXT_CHECK_VA(context); \
3721 if ((result = dec_alloc()) == NULL) { \ 3636 CONVERT_BINOP_RAISE(&a, &b, self, other, context); \
3722 Py_DECREF(a); \ 3637 \
3723 Py_DECREF(b); \ 3638 if ((result = dec_alloc()) == NULL) { \
3724 return NULL; \ 3639 Py_DECREF(a); \
3725 } \ 3640 Py_DECREF(b); \
3726 \ 3641 return NULL; \
3727 MPDFUNC(MPD(result), MPD(a), MPD(b)); \ 3642 } \
3728 Py_DECREF(a); \ 3643 \
3729 Py_DECREF(b); \ 3644 MPDFUNC(MPD(result), MPD(a), MPD(b)); \
3730 \ 3645 Py_DECREF(a); \
3731 return result; \ 3646 Py_DECREF(b); \
3647 \
3648 return result; \
3732 } 3649 }
3733 3650
3734 /* Ternary function with an optional context arg. */ 3651 /* Ternary function with an optional context arg. */
3735 #define Dec_TernaryFuncVA(MPDFUNC) \ 3652 #define Dec_TernaryFuncVA(MPDFUNC) \
3736 static PyObject * \ 3653 static PyObject * \
3737 dec_##MPDFUNC(PyObject *v, PyObject *args) \ 3654 dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \
3738 { \ 3655 { \
3739 PyObject *w, *x, *context; \ 3656 static char *kwlist[] = {"other", "third", "context", NULL}; \