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

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

Issue 7652: Merge C version of decimal into py3k.
Left Patch Set: Created 8 years, 4 months ago
Right Patch Set: Created 7 years, 7 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 *newob; 1374 » PyObject *copy;
1375
1376 » copy = PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL);
1377 » if (copy == NULL) {
1378 » » return NULL;
1379 » }
1380
1381 » *CTX(copy) = *CTX(self);
1382 » CTX(copy)->newtrap = 0;
1383 » CtxCaps(copy) = CtxCaps(self);
1384
1385 » return copy;
1386 }
1387
1388 static PyObject *
1389 context_reduce(PyObject *self, PyObject *args UNUSED)
1390 {
1391 » PyObject *flags;
1392 » PyObject *traps;
1393 » PyObject *ret;
1521 mpd_context_t *ctx; 1394 mpd_context_t *ctx;
1522 1395
1523 newob = PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL);
1524 if (newob == NULL) {
1525 return NULL;
1526 }
1527
1528 ctx = CTX(newob);
1529
1530 *ctx = *CTX(self);
1531 ctx->newtrap = 0;
1532 CtxCaps(newob) = CtxCaps(self);
1533
1534 return newob;
1535 }
1536
1537 static PyObject *
1538 context_reduce(PyObject *self, PyObject *args UNUSED)
1539 {
1540 PyObject *flags;
1541 PyObject *traps;
1542 PyObject *ret;
1543 mpd_context_t *ctx;
1544
1545 ctx = CTX(self); 1396 ctx = CTX(self);
1546 1397
1547 » if ((flags = signals_as_list(ctx->status)) == NULL) { 1398 » flags = signals_as_list(ctx->status);
1548 » » return NULL; 1399 » if (flags == NULL) {
1549 » } 1400 » » return NULL;
1550 » if ((traps = signals_as_list(ctx->traps)) == NULL) { 1401 » }
1402 » traps = signals_as_list(ctx->traps);
1403 » if (traps == NULL) {
1551 Py_DECREF(flags); 1404 Py_DECREF(flags);
1552 return NULL; 1405 return NULL;
1553 } 1406 }
1554 1407
1555 ret = Py_BuildValue( 1408 ret = Py_BuildValue(
1556 » "O(" CONV_mpd_ssize_t "s" CONV_mpd_ssize_t CONV_mpd_ssize_t 1409 » "O(nsnniiOO)",
1557 » "iiOO)",
1558 Py_TYPE(self), 1410 Py_TYPE(self),
1559 ctx->prec, mpd_round_string[ctx->round], ctx->emin, ctx->emax, 1411 ctx->prec, mpd_round_string[ctx->round], ctx->emin, ctx->emax,
1560 CtxCaps(self), ctx->clamp, flags, traps 1412 CtxCaps(self), ctx->clamp, flags, traps
1561 ); 1413 );
1562 1414
1563 Py_DECREF(flags); 1415 Py_DECREF(flags);
1564 Py_DECREF(traps); 1416 Py_DECREF(traps);
1565 return ret; 1417 return ret;
1566 }
1567
1568 static PyObject *
1569 PyDec_SetStatusFromList(PyObject *self, PyObject *value)
1570 {
1571 if (context_setstatus_list(self, value) < 0) {
1572 return NULL;
1573 }
1574 Py_RETURN_NONE;
1575 }
1576
1577 static PyObject *
1578 PyDec_SetTrapsFromList(PyObject *self, PyObject *value)
1579 {
1580 if (context_settraps_list(self, value) < 0) {
1581 return NULL;
1582 }
1583 Py_RETURN_NONE;
1584 } 1418 }
1585 1419
1586 1420
1587 static PyGetSetDef context_getsets [] = 1421 static PyGetSetDef context_getsets [] =
1588 { 1422 {
1589 { "prec", (getter)context_getprec, (setter)context_setprec, NULL, NULL}, 1423 { "prec", (getter)context_getprec, (setter)context_setprec, NULL, NULL},
1590 { "Emax", (getter)context_getemax, (setter)context_setemax, NULL, NULL}, 1424 { "Emax", (getter)context_getemax, (setter)context_setemax, NULL, NULL},
1591 { "Emin", (getter)context_getemin, (setter)context_setemin, NULL, NULL}, 1425 { "Emin", (getter)context_getemin, (setter)context_setemin, NULL, NULL},
1592 { "rounding", (getter)context_getround, (setter)context_setround, NULL, NULL}, 1426 { "rounding", (getter)context_getround, (setter)context_setround, NULL, NULL},
1593 { "capitals", (getter)context_getcapitals, (setter)context_setcapitals, NULL, NULL}, 1427 { "capitals", (getter)context_getcapitals, (setter)context_setcapitals, NULL, NULL},
1594 { "clamp", (getter)context_getclamp, (setter)context_setclamp, NULL, NULL}, 1428 { "clamp", (getter)context_getclamp, (setter)context_setclamp, NULL, NULL},
1595 { "_clamp", (getter)context_getclamp, (setter)context_setclamp, NULL, NULL}, 1429 #ifdef EXTRA_FUNCTIONALITY
1596 { "_allcr", (getter)context_getallcr, (setter)context_setallcr, NULL, NULL}, 1430 { "_allcr", (getter)context_getallcr, (setter)context_setallcr, NULL, NULL},
1597 { "_traps", (getter)context_gettraps, (setter)context_settraps, NULL, NULL}, 1431 { "_traps", (getter)context_gettraps, (setter)context_settraps, NULL, NULL},
1598 { "_flags", (getter)context_getstatus, (setter)context_setstatus, NULL, NULL}, 1432 { "_flags", (getter)context_getstatus, (setter)context_setstatus, NULL, NULL},
1433 #endif
1599 {NULL} 1434 {NULL}
1600 }; 1435 };
1601 1436
1602 1437
1603 #define CONTEXT_CHECK(obj) \ 1438 #define CONTEXT_CHECK(obj) \
1604 if (!PyDecContext_Check(obj)) { \ 1439 if (!PyDecContext_Check(obj)) { \
1605 PyErr_SetString(PyExc_TypeError, \ 1440 PyErr_SetString(PyExc_TypeError, \
1606 "argument must be a context."); \ 1441 "argument must be a context"); \
1607 return NULL; \ 1442 return NULL; \
1608 } 1443 }
1609 1444
1610 #define CONTEXT_CHECK_VA(obj) \ 1445 #define CONTEXT_CHECK_VA(obj) \
1611 if (!PyDecContext_Check(obj)) { \ 1446 if (!PyDecContext_Check(obj)) { \
1612 PyErr_SetString(PyExc_TypeError, \ 1447 PyErr_SetString(PyExc_TypeError, \
1613 "optional argument must be a context."); \ 1448 "optional argument must be a context"); \
1614 return NULL; \ 1449 return NULL; \
1615 } 1450 }
1616 1451
1617 1452
1618 /******************************************************************************/ 1453 /******************************************************************************/
1619 /* Global, thread local and temporary contexts */ 1454 /* Global, thread local and temporary contexts */
1620 /******************************************************************************/ 1455 /******************************************************************************/
1621 1456
1622 #ifdef WITHOUT_THREADS 1457 #ifdef WITHOUT_THREADS
1623 /* Return borrowed reference to the current context. When compiled 1458 /* Return borrowed reference to the current context. When compiled
1624 * 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
1662 static PyObject * 1497 static PyObject *
1663 PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v) 1498 PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v)
1664 { 1499 {
1665 CONTEXT_CHECK(v); 1500 CONTEXT_CHECK(v);
1666 1501
1667 /* 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.
1668 * This is the current behavior of decimal.py. */ 1503 * This is the current behavior of decimal.py. */
1669 if (v == default_context_template || 1504 if (v == default_context_template ||
1670 v == basic_context_template || 1505 v == basic_context_template ||
1671 v == extended_context_template) { 1506 v == extended_context_template) {
1672 » » if ((v = context_copy(v)) == NULL) { 1507 » » v = context_copy(v);
1508 » » if (v == NULL) {
1673 return NULL; 1509 return NULL;
1674 } 1510 }
1675 } 1511 }
1676 else { 1512 else {
1677 Py_INCREF(v); 1513 Py_INCREF(v);
1678 } 1514 }
1679 1515
1680 Py_XDECREF(module_context); 1516 Py_XDECREF(module_context);
1681 module_context = v; 1517 module_context = v;
1682 module_context_set = 1; 1518 module_context_set = 1;
(...skipping 10 matching lines...) Expand all
1693 /* Return borrowed reference to thread local context. */ 1529 /* Return borrowed reference to thread local context. */
1694 static PyObject * 1530 static PyObject *
1695 current_context(void) 1531 current_context(void)
1696 { 1532 {
1697 PyObject *dict = NULL; 1533 PyObject *dict = NULL;
1698 PyObject *tl_context = NULL; 1534 PyObject *tl_context = NULL;
1699 1535
1700 dict = PyThreadState_GetDict(); 1536 dict = PyThreadState_GetDict();
1701 if (dict == NULL) { 1537 if (dict == NULL) {
1702 PyErr_SetString(PyExc_RuntimeError, 1538 PyErr_SetString(PyExc_RuntimeError,
1703 » » "cannot get thread state."); 1539 » » "cannot get thread state");
1704 » » return NULL; 1540 » » return NULL;
1705 » } 1541 » }
1706 1542
1707 » tl_context = PyDict_GetItem(dict, tls_context_key); 1543 » tl_context = PyDict_GetItemWithError(dict, tls_context_key);
1708 if (tl_context != NULL) { 1544 if (tl_context != NULL) {
1709 /* We already have a thread local context and 1545 /* We already have a thread local context and
1710 * return a borrowed reference. */ 1546 * return a borrowed reference. */
1711 CONTEXT_CHECK(tl_context); 1547 CONTEXT_CHECK(tl_context);
1712 return tl_context; 1548 return tl_context;
1713 } 1549 }
1550 if (PyErr_Occurred()) {
1551 return NULL;
1552 }
1714 1553
1715 /* Otherwise, set up a new thread local context. */ 1554 /* Otherwise, set up a new thread local context. */
1716 tl_context = context_copy(default_context_template); 1555 tl_context = context_copy(default_context_template);
1717 if (tl_context == NULL) { 1556 if (tl_context == NULL) {
1718 return NULL; 1557 return NULL;
1719 } 1558 }
1720 if (PyDict_SetItem(dict, tls_context_key, tl_context) < 0) { 1559 if (PyDict_SetItem(dict, tls_context_key, tl_context) < 0) {
1721 Py_DECREF(tl_context); 1560 Py_DECREF(tl_context);
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 /* Return a new PyDecObject or a subtype from a PyUnicodeObject. */ 1918 /* Return a new PyDecObject or a subtype from a PyUnicodeObject. */
2030 static PyObject * 1919 static PyObject *
2031 PyDecType_FromUnicode(PyTypeObject *type, const PyObject *u, 1920 PyDecType_FromUnicode(PyTypeObject *type, const PyObject *u,
2032 PyObject *context) 1921 PyObject *context)
2033 { 1922 {
2034 PyObject *dec; 1923 PyObject *dec;
2035 char *s; 1924 char *s;
2036 1925
2037 » s = dec_unicode_as_str(u); 1926 » s = numeric_as_ascii(u, 0);
2038 if (s == NULL) { 1927 if (s == NULL) {
2039 return NULL; 1928 return NULL;
2040 } 1929 }
2041 1930
2042 dec = PyDecType_FromCString(type, s, context); 1931 dec = PyDecType_FromCString(type, s, context);
2043 PyMem_Free(s); 1932 PyMem_Free(s);
2044 return dec; 1933 return dec;
2045 } 1934 }
2046 1935
2047 /* Strip leading and trailing whitespace. Return x unchanged if no
2048 whitespace is found, otherwise return a newly allocated string
2049 with whitespace stripped. */
2050 static char *
2051 strip_ws(const char *x)
2052 {
2053 char *s, *t;
2054 char *y;
2055 size_t n;
2056
2057 s = (char *)x;
2058 while (isspace((unsigned char)*s))
2059 s++;
2060
2061 t = y = s+strlen(s);
2062 while (t > s && isspace((unsigned char)*(t-1)))
2063 t--;
2064
2065 if (s != x || t != y) {
2066 n = t-s;
2067 if ((y = PyMem_Malloc(n+1)) == NULL) {
2068 PyErr_NoMemory();
2069 return NULL;
2070 }
2071 strncpy(y, s, n);
2072 y[n] = '\0';
2073 return y;
2074 }
2075
2076 return (char *)x;
2077 }
2078
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 ooperand. */ 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;
2121 MPD(dec)->data[1] = q; 1968 MPD(dec)->data[1] = q;
2122 MPD(dec)->data[0] = r; 1969 MPD(dec)->data[0] = r;
2123 MPD(dec)->len = q ? 2 : 1; 1970 MPD(dec)->len = q ? 2 : 1;
2124 #endif 1971 #endif
2125 mpd_set_flags(MPD(dec), sign); 1972 mpd_set_flags(MPD(dec), sign);
2126 MPD(dec)->exp = exp; 1973 MPD(dec)->exp = exp;
2127 mpd_setdigits(MPD(dec)); 1974 mpd_setdigits(MPD(dec));
2128 } 1975 }
2129 1976
2130 /* Return a new PyDecObject from a uint32_t. */ 1977 /* Return a new PyDecObject from an mpd_ssize_t. */
2131 static PyObject * 1978 static PyObject *
2132 PyDec_FromUint32(uint32_t v, PyObject *context) 1979 PyDecType_FromSsize(PyTypeObject *type, mpd_ssize_t v, PyObject *context)
2133 { 1980 {
2134 PyObject *dec; 1981 PyObject *dec;
2135 uint32_t status = 0; 1982 uint32_t status = 0;
2136 1983
2137 » dec = dec_alloc(); 1984 » dec = PyDecType_New(type);
2138 if (dec == NULL) { 1985 if (dec == NULL) {
2139 return NULL; 1986 return NULL;
2140 } 1987 }
2141 1988
2142 » mpd_qset_u32(MPD(dec), v, CTX(context), &status); 1989 » mpd_qset_ssize(MPD(dec), v, CTX(context), &status);
2143 if (dec_addstatus(context, status)) { 1990 if (dec_addstatus(context, status)) {
2144 Py_DECREF(dec); 1991 Py_DECREF(dec);
2145 return NULL; 1992 return NULL;
2146 } 1993 }
2147 return dec; 1994 return dec;
2148 } 1995 }
2149 1996
2150 /* Return a new PyDecObject from a uint32_t. Conversion is exact. */ 1997 /* Return a new PyDecObject from an mpd_ssize_t. Conversion is exact. */
2151 static PyObject * 1998 static PyObject *
2152 PyDec_FromUint32Exact(uint32_t v, PyObject *context) 1999 PyDecType_FromSsizeExact(PyTypeObject *type, mpd_ssize_t v, PyObject *context)
2153 { 2000 {
2154 PyObject *dec; 2001 PyObject *dec;
2155 uint32_t status = 0; 2002 uint32_t status = 0;
2156 mpd_context_t maxctx; 2003 mpd_context_t maxctx;
2157 2004
2158 » dec = dec_alloc(); 2005 » dec = PyDecType_New(type);
2159 if (dec == NULL) { 2006 if (dec == NULL) {
2160 return NULL; 2007 return NULL;
2161 } 2008 }
2162 2009
2163 mpd_maxcontext(&maxctx); 2010 mpd_maxcontext(&maxctx);
2164 2011
2165 » mpd_qset_u32(MPD(dec), v, &maxctx, &status); 2012 » mpd_qset_ssize(MPD(dec), v, &maxctx, &status);
2166 if (dec_addstatus(context, status)) { 2013 if (dec_addstatus(context, status)) {
2167 Py_DECREF(dec); 2014 Py_DECREF(dec);
2168 return NULL; 2015 return NULL;
2169 } 2016 }
2170 return dec; 2017 return dec;
2171 } 2018 }
2172 2019
2173 /* Convert from a PyLongObject. The context is not modified; flags set 2020 /* Convert from a PyLongObject. The context is not modified; flags set
2174 during conversion are accumulated in the status parameter. */ 2021 during conversion are accumulated in the status parameter. */
2175 static PyObject * 2022 static PyObject *
(...skipping 32 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
2419 /* Return a new C string representation of a DecimalTuple (may be a 2266 static PyObject *
2420 list as well). */ 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
2281 /* Return a new C string representation of a DecimalTuple. */
2421 static char * 2282 static char *
2422 dec_sequence_as_str(PyObject *v) 2283 dectuple_as_str(PyObject *dectuple)
2423 { 2284 {
2424 » PyObject *dectuple; 2285 » PyObject *digits = NULL, *tmp;
2425 » PyObject *digits, *tmp;
2426 char *decstring = NULL; 2286 char *decstring = NULL;
2427 char sign_special[6]; 2287 char sign_special[6];
2428 char *cp; 2288 char *cp;
2429 long sign, l; 2289 long sign, l;
2430 mpd_ssize_t exp = 0; 2290 mpd_ssize_t exp = 0;
2431 Py_ssize_t i, mem, tsize; 2291 Py_ssize_t i, mem, tsize;
2432 int n; 2292 int n;
2433 2293
2434 » dectuple = PySequence_Tuple(v); 2294 » assert(PyTuple_Check(dectuple));
2435 » if (dectuple == NULL) {
2436 » » return NULL;
2437 » }
2438 2295
2439 if (PyTuple_Size(dectuple) != 3) { 2296 if (PyTuple_Size(dectuple) != 3) {
2440 PyErr_SetString(PyExc_ValueError, 2297 PyErr_SetString(PyExc_ValueError,
2441 » » "argument must be a sequence of length 3."); 2298 » » "argument must be a sequence of length 3");
2442 goto error; 2299 goto error;
2443 } 2300 }
2444 2301
2445 /* sign */ 2302 /* sign */
2446 tmp = PyTuple_GET_ITEM(dectuple, 0); 2303 tmp = PyTuple_GET_ITEM(dectuple, 0);
2447 if (!PyLong_Check(tmp)) { 2304 if (!PyLong_Check(tmp)) {
2448 PyErr_SetString(PyExc_ValueError, 2305 PyErr_SetString(PyExc_ValueError,
2449 » » "sign must be an integer with the value 0 or 1."); 2306 » » "sign must be an integer with the value 0 or 1");
2450 goto error; 2307 goto error;
2451 } 2308 }
2452 sign = PyLong_AsLong(tmp); 2309 sign = PyLong_AsLong(tmp);
2453 » if (PyErr_Occurred()) { 2310 » if (sign == -1 && PyErr_Occurred()) {
2454 goto error; 2311 goto error;
2455 } 2312 }
2456 if (sign != 0 && sign != 1) { 2313 if (sign != 0 && sign != 1) {
2457 PyErr_SetString(PyExc_ValueError, 2314 PyErr_SetString(PyExc_ValueError,
2458 » » "sign must be an integer with the value 0 or 1."); 2315 » » "sign must be an integer with the value 0 or 1");
2459 goto error; 2316 goto error;
2460 } 2317 }
2461 sign_special[0] = sign ? '-' : '+'; 2318 sign_special[0] = sign ? '-' : '+';
2462 sign_special[1] = '\0'; 2319 sign_special[1] = '\0';
2463 2320
2464 /* exponent or encoding for a special number */ 2321 /* exponent or encoding for a special number */
2465 tmp = PyTuple_GET_ITEM(dectuple, 2); 2322 tmp = PyTuple_GET_ITEM(dectuple, 2);
2466 if (PyUnicode_Check(tmp)) { 2323 if (PyUnicode_Check(tmp)) {
2467 /* special */ 2324 /* special */
2468 if (PyUnicode_CompareWithASCIIString(tmp, "F") == 0) { 2325 if (PyUnicode_CompareWithASCIIString(tmp, "F") == 0) {
2469 strcat(sign_special, "Inf"); 2326 strcat(sign_special, "Inf");
2470 } 2327 }
2471 else if (PyUnicode_CompareWithASCIIString(tmp, "n") == 0) { 2328 else if (PyUnicode_CompareWithASCIIString(tmp, "n") == 0) {
2472 strcat(sign_special, "NaN"); 2329 strcat(sign_special, "NaN");
2473 } 2330 }
2474 else if (PyUnicode_CompareWithASCIIString(tmp, "N") == 0) { 2331 else if (PyUnicode_CompareWithASCIIString(tmp, "N") == 0) {
2475 strcat(sign_special, "sNaN"); 2332 strcat(sign_special, "sNaN");
2476 } 2333 }
2477 else { 2334 else {
2478 PyErr_SetString(PyExc_ValueError, 2335 PyErr_SetString(PyExc_ValueError,
2479 "string argument in the third position " 2336 "string argument in the third position "
2480 » » » "must be 'F', 'n' or 'N'."); 2337 » » » "must be 'F', 'n' or 'N'");
2481 goto error; 2338 goto error;
2482 } 2339 }
2483 } 2340 }
2484 else { 2341 else {
2485 /* exponent */ 2342 /* exponent */
2486 if (!PyLong_Check(tmp)) { 2343 if (!PyLong_Check(tmp)) {
2487 PyErr_SetString(PyExc_ValueError, 2344 PyErr_SetString(PyExc_ValueError,
2488 » » » "exponent must be an integer."); 2345 » » » "exponent must be an integer");
2489 goto error; 2346 goto error;
2490 } 2347 }
2491 » » exp = long_as_mpd_ssize(tmp); 2348 » » exp = PyLong_AsSsize_t(tmp);
2492 » » if (PyErr_Occurred()) { 2349 » » if (exp == -1 && PyErr_Occurred()) {
2493 goto error; 2350 goto error;
2494 } 2351 }
2495 } 2352 }
2496 2353
2497 /* coefficient */ 2354 /* coefficient */
2498 » digits = PyTuple_GET_ITEM(dectuple, 1); 2355 » digits = sequence_as_tuple(PyTuple_GET_ITEM(dectuple, 1),
2499 » if (!PyTuple_Check(digits)) { 2356 PyExc_ValueError, "coefficient must be a tuple of digits");
2500 » » PyErr_SetString(PyExc_ValueError, 2357 » if (digits == NULL) {
2501 » » "coefficient must be a tuple of digits.");
2502 goto error; 2358 goto error;
2503 } 2359 }
2504 2360
2505 tsize = PyTuple_Size(digits); 2361 tsize = PyTuple_Size(digits);
2506 /* [sign][coeffdigits+1][E][-][expdigits+1]['\0'] */ 2362 /* [sign][coeffdigits+1][E][-][expdigits+1]['\0'] */
2507 mem = 1 + tsize + 3 + MPD_EXPDIGITS + 2; 2363 mem = 1 + tsize + 3 + MPD_EXPDIGITS + 2;
2508 cp = decstring = PyMem_Malloc(mem); 2364 cp = decstring = PyMem_Malloc(mem);
2509 if (decstring == NULL) { 2365 if (decstring == NULL) {
2510 PyErr_NoMemory(); 2366 PyErr_NoMemory();
2511 goto error; 2367 goto error;
2512 } 2368 }
2513 2369
2514 n = snprintf(cp, mem, "%s", sign_special); 2370 n = snprintf(cp, mem, "%s", sign_special);
2515 if (n < 0 || n >= mem) { 2371 if (n < 0 || n >= mem) {
2516 PyErr_SetString(PyExc_RuntimeError, 2372 PyErr_SetString(PyExc_RuntimeError,
2517 » » "internal error in dec_sequence_as_str."); 2373 » » "internal error in dec_sequence_as_str");
2518 goto error; 2374 goto error;
2519 } 2375 }
2520 cp += n; 2376 cp += n;
2521 2377
2522 if (tsize == 0 && sign_special[1] == '\0') { 2378 if (tsize == 0 && sign_special[1] == '\0') {
2523 /* empty tuple: zero coefficient, except for special numbers */ 2379 /* empty tuple: zero coefficient, except for special numbers */
2524 *cp++ = '0'; 2380 *cp++ = '0';
2525 } 2381 }
2526 for (i = 0; i < tsize; i++) { 2382 for (i = 0; i < tsize; i++) {
2527 tmp = PyTuple_GET_ITEM(digits, i); 2383 tmp = PyTuple_GET_ITEM(digits, i);
2528 if (!PyLong_Check(tmp)) { 2384 if (!PyLong_Check(tmp)) {
2529 PyErr_SetString(PyExc_ValueError, 2385 PyErr_SetString(PyExc_ValueError,
2530 » » » "coefficient must be a tuple of digits."); 2386 » » » "coefficient must be a tuple of digits");
2531 goto error; 2387 goto error;
2532 } 2388 }
2533 l = PyLong_AsLong(tmp); 2389 l = PyLong_AsLong(tmp);
2534 » » if (PyErr_Occurred()) { 2390 » » if (l == -1 && PyErr_Occurred()) {
2535 goto error; 2391 goto error;
2536 } 2392 }
2537 if (l < 0 || l > 9) { 2393 if (l < 0 || l > 9) {
2538 PyErr_SetString(PyExc_ValueError, 2394 PyErr_SetString(PyExc_ValueError,
2539 » » » "coefficient must be a tuple of digits."); 2395 » » » "coefficient must be a tuple of digits");
2540 goto error; 2396 goto error;
2541 } 2397 }
2542 *cp++ = (char)l + '0'; 2398 *cp++ = (char)l + '0';
2543 } 2399 }
2544 *cp = '\0'; 2400 *cp = '\0';
2545 2401
2546 if (sign_special[1] == '\0') { 2402 if (sign_special[1] == '\0') {
2547 /* not a special number */ 2403 /* not a special number */
2548 *cp++ = 'E'; 2404 *cp++ = 'E';
2549 n = snprintf(cp, MPD_EXPDIGITS+1, "%" PRI_mpd_ssize_t, exp); 2405 n = snprintf(cp, MPD_EXPDIGITS+1, "%" PRI_mpd_ssize_t, exp);
2550 if (n < 0 || n >= MPD_EXPDIGITS+1) { 2406 if (n < 0 || n >= MPD_EXPDIGITS+1) {
2551 PyErr_SetString(PyExc_RuntimeError, 2407 PyErr_SetString(PyExc_RuntimeError,
2552 » » » "internal error in dec_sequence_as_str."); 2408 » » » "internal error in dec_sequence_as_str");
2553 goto error; 2409 goto error;
2554 } 2410 }
2555 } 2411 }
2556 2412
2557 » Py_DECREF(dectuple); 2413 » Py_XDECREF(digits);
2558 return decstring; 2414 return decstring;
2559 2415
2560 2416
2561 error: 2417 error:
2418 Py_XDECREF(digits);
2562 if (decstring) PyMem_Free(decstring); 2419 if (decstring) PyMem_Free(decstring);
2563 Py_DECREF(dectuple);
2564 return NULL; 2420 return NULL;
2565 } 2421 }
2566 2422
2423 /* Currently accepts tuples and lists. */
2567 static PyObject * 2424 static PyObject *
2568 PyDecType_FromSequence(PyTypeObject *type, PyObject *v, 2425 PyDecType_FromSequence(PyTypeObject *type, PyObject *v,
2569 PyObject *context) 2426 PyObject *context)
2570 { 2427 {
2428 PyObject *dectuple;
2571 PyObject *dec; 2429 PyObject *dec;
2572 char *s; 2430 char *s;
2573 2431
2574 » s = dec_sequence_as_str(v); 2432 » dectuple = sequence_as_tuple(v, PyExc_TypeError,
2433 » "argument must be a tuple or list");
2434 » if (dectuple == NULL) {
2435 » » return NULL;
2436 » }
2437
2438 » s = dectuple_as_str(dectuple);
2439 » Py_DECREF(dectuple);
2575 if (s == NULL) { 2440 if (s == NULL) {
2576 return NULL; 2441 return NULL;
2577 } 2442 }
2578 2443
2579 dec = PyDecType_FromCString(type, s, context); 2444 dec = PyDecType_FromCString(type, s, context);
2445
2580 PyMem_Free(s); 2446 PyMem_Free(s);
2581 return dec; 2447 return dec;
2582 } 2448 }
2583 2449
2450 /* Currently accepts tuples and lists. */
2584 static PyObject * 2451 static PyObject *
2585 PyDecType_FromSequenceExact(PyTypeObject *type, PyObject *v, 2452 PyDecType_FromSequenceExact(PyTypeObject *type, PyObject *v,
2586 PyObject *context) 2453 PyObject *context)
2587 { 2454 {
2455 PyObject *dectuple;
2588 PyObject *dec; 2456 PyObject *dec;
2589 char *s; 2457 char *s;
2590 2458
2591 » s = dec_sequence_as_str(v); 2459 » dectuple = sequence_as_tuple(v, PyExc_TypeError,
2460 » "argument must be a tuple or list");
2461 » if (dectuple == NULL) {
2462 » » return NULL;
2463 » }
2464
2465 » s = dectuple_as_str(dectuple);
2466 » Py_DECREF(dectuple);
2592 if (s == NULL) { 2467 if (s == NULL) {
2593 return NULL; 2468 return NULL;
2594 } 2469 }
2595 2470
2596 dec = PyDecType_FromCStringExact(type, s, context); 2471 dec = PyDecType_FromCStringExact(type, s, context);
2472
2597 PyMem_Free(s); 2473 PyMem_Free(s);
2598 return dec; 2474 return dec;
2599 } 2475 }
2600 2476
2601 #define PyDec_FromCString(str, context) \ 2477 #define PyDec_FromCString(str, context) \
2602 PyDecType_FromCString(&PyDec_Type, str, context) 2478 PyDecType_FromCString(&PyDec_Type, str, context)
2603 #define PyDec_FromCStringExact(str, context) \ 2479 #define PyDec_FromCStringExact(str, context) \
2604 PyDecType_FromCStringExact(&PyDec_Type, str, context) 2480 PyDecType_FromCStringExact(&PyDec_Type, str, context)
2605 2481
2606 #define PyDec_FromUnicode(unicode, context) \ 2482 #define PyDec_FromUnicode(unicode, context) \
2607 PyDecType_FromUnicode(&PyDec_Type, unicode, context) 2483 PyDecType_FromUnicode(&PyDec_Type, unicode, context)
2608 #define PyDec_FromUnicodeExact(unicode, context) \ 2484 #define PyDec_FromUnicodeExact(unicode, context) \
2609 PyDecType_FromUnicodeExact(&PyDec_Type, unicode, context) 2485 PyDecType_FromUnicodeExact(&PyDec_Type, unicode, context)
2610 #define PyDec_FromUnicodeExactWS(unicode, context) \ 2486 #define PyDec_FromUnicodeExactWS(unicode, context) \
2611 PyDecType_FromUnicodeExactWS(&PyDec_Type, unicode, context) 2487 PyDecType_FromUnicodeExactWS(&PyDec_Type, unicode, context)
2612 2488
2489 #define PyDec_FromSsize(v, context) \
2490 PyDecType_FromSsize(&PyDec_Type, v, context)
2491 #define PyDec_FromSsizeExact(v, context) \
2492 PyDecType_FromSsizeExact(&PyDec_Type, v, context)
2493
2613 #define PyDec_FromLong(pylong, context) \ 2494 #define PyDec_FromLong(pylong, context) \
2614 PyDecType_FromLong(&PyDec_Type, pylong, context) 2495 PyDecType_FromLong(&PyDec_Type, pylong, context)
2615 #define PyDec_FromLongExact(pylong, context) \ 2496 #define PyDec_FromLongExact(pylong, context) \
2616 PyDecType_FromLongExact(&PyDec_Type, pylong, context) 2497 PyDecType_FromLongExact(&PyDec_Type, pylong, context)
2617 2498
2618 #define PyDec_FromFloat(pyfloat, context) \ 2499 #define PyDec_FromFloat(pyfloat, context) \
2619 PyDecType_FromFloat(&PyDec_Type, pyfloat, context) 2500 PyDecType_FromFloat(&PyDec_Type, pyfloat, context)
2620 #define PyDec_FromFloatExact(pyfloat, context) \ 2501 #define PyDec_FromFloatExact(pyfloat, context) \
2621 PyDecType_FromFloatExact(&PyDec_Type, pyfloat, context) 2502 PyDecType_FromFloatExact(&PyDec_Type, pyfloat, context)
2622 2503
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2669 return result; 2550 return result;
2670 } 2551 }
2671 2552
2672 /* 'v' can have any type accepted by the Decimal constructor. Attempt 2553 /* 'v' can have any type accepted by the Decimal constructor. Attempt
2673 an exact conversion. If the result does not meet the restrictions 2554 an exact conversion. If the result does not meet the restrictions
2674 for an mpd_t, fail with InvalidOperation. */ 2555 for an mpd_t, fail with InvalidOperation. */
2675 static PyObject * 2556 static PyObject *
2676 PyDecType_FromObjectExact(PyTypeObject *type, PyObject *v, PyObject *context) 2557 PyDecType_FromObjectExact(PyTypeObject *type, PyObject *v, PyObject *context)
2677 { 2558 {
2678 if (v == NULL) { 2559 if (v == NULL) {
2679 » » return PyDec_FromUint32Exact(0, context); 2560 » » return PyDecType_FromSsizeExact(type, 0, context);
2680 } 2561 }
2681 else if (PyDec_Check(v)) { 2562 else if (PyDec_Check(v)) {
2682 Py_INCREF(v); 2563 Py_INCREF(v);
2683 return v; 2564 return v;
2684 } 2565 }
2685 else if (PyUnicode_Check(v)) { 2566 else if (PyUnicode_Check(v)) {
2686 return PyDecType_FromUnicodeExactWS(type, v, context); 2567 return PyDecType_FromUnicodeExactWS(type, v, context);
2687 } 2568 }
2688 else if (PyLong_Check(v)) { 2569 else if (PyLong_Check(v)) {
2689 return PyDecType_FromLongExact(type, v, context); 2570 return PyDecType_FromLongExact(type, v, context);
2690 } 2571 }
2691 » else if (PySequence_Check(v)) { 2572 » else if (PyTuple_Check(v) || PyList_Check(v)) {
2692 return PyDecType_FromSequenceExact(type, v, context); 2573 return PyDecType_FromSequenceExact(type, v, context);
2693 } 2574 }
2694 else if (PyFloat_Check(v)) { 2575 else if (PyFloat_Check(v)) {
2695 if (dec_addstatus(context, MPD_Float_operation)) { 2576 if (dec_addstatus(context, MPD_Float_operation)) {
2696 return NULL; 2577 return NULL;
2697 } 2578 }
2698 return PyDecType_FromFloatExact(type, v, context); 2579 return PyDecType_FromFloatExact(type, v, context);
2699 } 2580 }
2700 else { 2581 else {
2701 PyErr_Format(PyExc_TypeError, 2582 PyErr_Format(PyExc_TypeError,
2702 » » "conversion from %s to Decimal is not supported.", 2583 » » "conversion from %s to Decimal is not supported",
2703 v->ob_type->tp_name); 2584 v->ob_type->tp_name);
2704 return NULL; 2585 return NULL;
2705 } 2586 }
2706 } 2587 }
2707 2588
2708 /* 'v' can have any type accepted by the Decimal constructor. The 2589 /* The context is used during conversion. This function is the
2709 context is used during conversion. This function is the equivalent 2590 equivalent of context.create_decimal(). */
2710 of context.create_decimal(). */
2711 static PyObject * 2591 static PyObject *
2712 PyDec_FromObject(PyObject *v, PyObject *context) 2592 PyDec_FromObject(PyObject *v, PyObject *context)
2713 { 2593 {
2714 if (v == NULL) { 2594 if (v == NULL) {
2715 » » return PyDec_FromUint32(0, context); 2595 » » return PyDec_FromSsize(0, context);
2716 } 2596 }
2717 else if (PyDec_Check(v)) { 2597 else if (PyDec_Check(v)) {
2718 mpd_context_t *ctx = CTX(context); 2598 mpd_context_t *ctx = CTX(context);
2719 if (mpd_isnan(MPD(v)) && 2599 if (mpd_isnan(MPD(v)) &&
2720 MPD(v)->digits > ctx->prec - ctx->clamp) { 2600 MPD(v)->digits > ctx->prec - ctx->clamp) {
2721 /* Special case: too many NaN payload digits */ 2601 /* Special case: too many NaN payload digits */
2722 PyObject *result; 2602 PyObject *result;
2723 if (dec_addstatus(context, MPD_Conversion_syntax)) { 2603 if (dec_addstatus(context, MPD_Conversion_syntax)) {
2724 return NULL; 2604 return NULL;
2725 } 2605 }
2726 result = dec_alloc(); 2606 result = dec_alloc();
2727 if (result == NULL) { 2607 if (result == NULL) {
2728 return NULL; 2608 return NULL;
2729 } 2609 }
2730 mpd_setspecial(MPD(result), MPD_POS, MPD_NAN); 2610 mpd_setspecial(MPD(result), MPD_POS, MPD_NAN);
2731 return result; 2611 return result;
2732 } 2612 }
2733 return dec_apply(v, context); 2613 return dec_apply(v, context);
2734 } 2614 }
2735 else if (PyUnicode_Check(v)) { 2615 else if (PyUnicode_Check(v)) {
2736 return PyDec_FromUnicode(v, context); 2616 return PyDec_FromUnicode(v, context);
2737 } 2617 }
2738 else if (PyLong_Check(v)) { 2618 else if (PyLong_Check(v)) {
2739 return PyDec_FromLong(v, context); 2619 return PyDec_FromLong(v, context);
2740 } 2620 }
2741 » else if (PySequence_Check(v)) { 2621 » else if (PyTuple_Check(v) || PyList_Check(v)) {
2742 return PyDec_FromSequence(v, context); 2622 return PyDec_FromSequence(v, context);
2743 } 2623 }
2744 else if (PyFloat_Check(v)) { 2624 else if (PyFloat_Check(v)) {
2745 if (dec_addstatus(context, MPD_Float_operation)) { 2625 if (dec_addstatus(context, MPD_Float_operation)) {
2746 return NULL; 2626 return NULL;
2747 } 2627 }
2748 return PyDec_FromFloat(v, context); 2628 return PyDec_FromFloat(v, context);
2749 } 2629 }
2750 else { 2630 else {
2751 PyErr_Format(PyExc_TypeError, 2631 PyErr_Format(PyExc_TypeError,
2752 » » "conversion from %s to Decimal is not supported.", 2632 » » "conversion from %s to Decimal is not supported",
2753 v->ob_type->tp_name); 2633 v->ob_type->tp_name);
2754 return NULL; 2634 return NULL;
2755 } 2635 }
2756 } 2636 }
2757 2637
2758 static PyObject * 2638 static PyObject *
2759 dec_new(PyTypeObject *type, PyObject *args, PyObject *kwds UNUSED) 2639 dec_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2760 { 2640 {
2641 » static char *kwlist[] = {"value", "context", NULL};
2761 PyObject *v = NULL; 2642 PyObject *v = NULL;
2762 PyObject *context; 2643 PyObject *context;
2763 2644
2764 CURRENT_CONTEXT(context); 2645 CURRENT_CONTEXT(context);
2765 » if (!PyArg_ParseTuple(args, "|OO", &v, &context)) { 2646 » if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO", kwlist,
2647 » &v, &context)) {
2766 return NULL; 2648 return NULL;
2767 } 2649 }
2768 CONTEXT_CHECK_VA(context); 2650 CONTEXT_CHECK_VA(context);
2769 2651
2770 return PyDecType_FromObjectExact(type, v, context); 2652 return PyDecType_FromObjectExact(type, v, context);
2771 } 2653 }
2772 2654
2773 static PyObject * 2655 static PyObject *
2774 ctx_create_decimal(PyObject *context, PyObject *args) 2656 ctx_create_decimal(PyObject *context, PyObject *args)
2775 { 2657 {
2776 PyObject *v = NULL; 2658 PyObject *v = NULL;
2777 2659
2778 if (!PyArg_ParseTuple(args, "|O", &v)) { 2660 if (!PyArg_ParseTuple(args, "|O", &v)) {
2779 return NULL; 2661 return NULL;
2780 } 2662 }
2781 2663
2782 return PyDec_FromObject(v, context); 2664 return PyDec_FromObject(v, context);
2783 } 2665 }
2784 2666
2785 2667
2786 /******************************************************************************/ 2668 /******************************************************************************/
2787 /* Implicit conversions to Decimal */ 2669 /* Implicit conversions to Decimal */
2788 /******************************************************************************/ 2670 /******************************************************************************/
2789 2671
2790 /* 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
2791 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
2792 implemented, set conv to Py_NotImplemented. */ 2674 implemented, set conv to Py_NotImplemented. */
2793 #define NOT_IMPL 0 2675 #define NOT_IMPL 0
2794 #define TYPE_ERR 1 2676 #define TYPE_ERR 1
2795 static inline int 2677 Py_LOCAL_INLINE(int)
2796 convert_op(int type_err, PyObject **conv, PyObject *v, PyObject *context) 2678 convert_op(int type_err, PyObject **conv, PyObject *v, PyObject *context)
2797 { 2679 {
2798 2680
2799 if (PyDec_Check(v)) { 2681 if (PyDec_Check(v)) {
2800 *conv = v; 2682 *conv = v;
2801 Py_INCREF(v); 2683 Py_INCREF(v);
2802 return 1; 2684 return 1;
2803 } 2685 }
2804 if (PyLong_Check(v)) { 2686 if (PyLong_Check(v)) {
2805 *conv = PyDec_FromLongExact(v, context); 2687 *conv = PyDec_FromLongExact(v, context);
2806 if (*conv == NULL) { 2688 if (*conv == NULL) {
2807 return 0; 2689 return 0;
2808 } 2690 }
2809 return 1; 2691 return 1;
2810 } 2692 }
2811 2693
2812 if (type_err) { 2694 if (type_err) {
2813 PyErr_Format(PyExc_TypeError, 2695 PyErr_Format(PyExc_TypeError,
2814 » » "conversion from %s to Decimal is not supported.", 2696 » » "conversion from %s to Decimal is not supported",
2815 v->ob_type->tp_name); 2697 v->ob_type->tp_name);
2816 } 2698 }
2817 else { 2699 else {
2818 Py_INCREF(Py_NotImplemented); 2700 Py_INCREF(Py_NotImplemented);
2819 *conv = Py_NotImplemented; 2701 *conv = Py_NotImplemented;
2820 } 2702 }
2821 return 0; 2703 return 0;
2822 } 2704 }
2823 2705
2824 /* Return NotImplemented for unsupported types. */ 2706 /* Return NotImplemented for unsupported types. */
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2878 Py_DECREF(*(b)); \ 2760 Py_DECREF(*(b)); \
2879 return NULL; \ 2761 return NULL; \
2880 } 2762 }
2881 2763
2882 2764
2883 /******************************************************************************/ 2765 /******************************************************************************/
2884 /* Implicit conversions to Decimal for comparison */ 2766 /* Implicit conversions to Decimal for comparison */
2885 /******************************************************************************/ 2767 /******************************************************************************/
2886 2768
2887 /* Convert rationals for comparison */ 2769 /* Convert rationals for comparison */
2888 static PyObject *_Rational = NULL; 2770 static PyObject *Rational = NULL;
2889 static PyObject * 2771 static PyObject *
2890 multiply_by_denominator(PyObject *v, PyObject *r, PyObject *context) 2772 multiply_by_denominator(PyObject *v, PyObject *r, PyObject *context)
2891 { 2773 {
2892 PyObject *result; 2774 PyObject *result;
2893 PyObject *tmp = NULL; 2775 PyObject *tmp = NULL;
2894 PyObject *denom = NULL; 2776 PyObject *denom = NULL;
2895 uint32_t status = 0; 2777 uint32_t status = 0;
2896 mpd_context_t maxctx; 2778 mpd_context_t maxctx;
2897 mpd_ssize_t exp; 2779 mpd_ssize_t exp;
2898 mpd_t *vv; 2780 mpd_t *vv;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2930 vv->exp = 0; 2812 vv->exp = 0;
2931 mpd_qmul(MPD(result), vv, MPD(denom), &maxctx, &status); 2813 mpd_qmul(MPD(result), vv, MPD(denom), &maxctx, &status);
2932 MPD(result)->exp = exp; 2814 MPD(result)->exp = exp;
2933 2815
2934 Py_DECREF(denom); 2816 Py_DECREF(denom);
2935 mpd_del(vv); 2817 mpd_del(vv);
2936 /* If any status has been accumulated during the multiplication, 2818 /* If any status has been accumulated during the multiplication,
2937 the result is invalid. This is very unlikely, since even the 2819 the result is invalid. This is very unlikely, since even the
2938 32-bit version supports 425000000 digits. */ 2820 32-bit version supports 425000000 digits. */
2939 if (status) { 2821 if (status) {
2940 » » PyErr_SetString(PyExc_ValueError, /* GCOV_NOT_REACHED */ 2822 » » PyErr_SetString(PyExc_ValueError,
2941 » » "exact conversion for comparison failed."); /* GCOV_NOT_REACHE D */ 2823 » » "exact conversion for comparison failed");
2942 » » Py_DECREF(result); /* GCOV_NOT_REACHED */ 2824 » » Py_DECREF(result);
2943 » » return NULL; /* GCOV_NOT_REACHED */ 2825 » » return NULL;
2944 } 2826 }
2945 2827
2946 return result; 2828 return result;
2947 } 2829 }
2948 2830
2949 static PyObject * 2831 static PyObject *
2950 numerator_as_decimal(PyObject *r, PyObject *context) 2832 numerator_as_decimal(PyObject *r, PyObject *context)
2951 { 2833 {
2952 PyObject *tmp, *num; 2834 PyObject *tmp, *num;
2953 2835
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2986 dec_addstatus(context, MPD_Float_operation)) { 2868 dec_addstatus(context, MPD_Float_operation)) {
2987 *wcmp = NULL; 2869 *wcmp = NULL;
2988 } 2870 }
2989 else { 2871 else {
2990 ctx->status |= MPD_Float_operation; 2872 ctx->status |= MPD_Float_operation;
2991 *wcmp = PyDec_FromFloatExact(w, context); 2873 *wcmp = PyDec_FromFloatExact(w, context);
2992 } 2874 }
2993 } 2875 }
2994 else if (PyComplex_Check(w) && (op == Py_EQ || op == Py_NE)) { 2876 else if (PyComplex_Check(w) && (op == Py_EQ || op == Py_NE)) {
2995 Py_complex c = PyComplex_AsCComplex(w); 2877 Py_complex c = PyComplex_AsCComplex(w);
2996 » » if (PyErr_Occurred()) { 2878 » » if (c.real == -1.0 && PyErr_Occurred()) {
2997 *wcmp = NULL; 2879 *wcmp = NULL;
2998 } 2880 }
2999 else if (c.imag == 0.0) { 2881 else if (c.imag == 0.0) {
3000 PyObject *tmp = PyFloat_FromDouble(c.real); 2882 PyObject *tmp = PyFloat_FromDouble(c.real);
3001 if (tmp == NULL) { 2883 if (tmp == NULL) {
3002 *wcmp = NULL; 2884 *wcmp = NULL;
3003 } 2885 }
3004 else { 2886 else {
3005 ctx->status |= MPD_Float_operation; 2887 ctx->status |= MPD_Float_operation;
3006 *wcmp = PyDec_FromFloatExact(tmp, context); 2888 *wcmp = PyDec_FromFloatExact(tmp, context);
3007 Py_DECREF(tmp); 2889 Py_DECREF(tmp);
3008 } 2890 }
3009 } 2891 }
3010 else { 2892 else {
3011 Py_INCREF(Py_NotImplemented); 2893 Py_INCREF(Py_NotImplemented);
3012 *wcmp = Py_NotImplemented; 2894 *wcmp = Py_NotImplemented;
3013 } 2895 }
3014 } 2896 }
3015 » else if (PyObject_IsInstance(w, _Rational)) { 2897 » else if (PyObject_IsInstance(w, Rational)) {
3016 *wcmp = numerator_as_decimal(w, context); 2898 *wcmp = numerator_as_decimal(w, context);
3017 if (*wcmp && !mpd_isspecial(MPD(v))) { 2899 if (*wcmp && !mpd_isspecial(MPD(v))) {
3018 *vcmp = multiply_by_denominator(v, w, context); 2900 *vcmp = multiply_by_denominator(v, w, context);
3019 if (*vcmp == NULL) { 2901 if (*vcmp == NULL) {
3020 Py_CLEAR(*wcmp); 2902 Py_CLEAR(*wcmp);
3021 } 2903 }
3022 } 2904 }
3023 } 2905 }
3024 else { 2906 else {
3025 Py_INCREF(Py_NotImplemented); 2907 Py_INCREF(Py_NotImplemented);
(...skipping 12 matching lines...) Expand all
3038 #define CONVERT_BINOP_CMP(vcmp, wcmp, v, w, op, ctx) \ 2920 #define CONVERT_BINOP_CMP(vcmp, wcmp, v, w, op, ctx) \
3039 if (!convert_op_cmp(vcmp, wcmp, v, w, op, ctx)) { \ 2921 if (!convert_op_cmp(vcmp, wcmp, v, w, op, ctx)) { \
3040 return *(wcmp); \ 2922 return *(wcmp); \
3041 } \ 2923 } \
3042 2924
3043 2925
3044 /******************************************************************************/ 2926 /******************************************************************************/
3045 /* Conversions from decimal */ 2927 /* Conversions from decimal */
3046 /******************************************************************************/ 2928 /******************************************************************************/
3047 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
3048 /* 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
3049 the value of 'capitals'. */ 2945 the value of 'capitals'. */
3050 static PyObject * 2946 static PyObject *
3051 dec_str(PyObject *dec) 2947 dec_str(PyObject *dec)
3052 { 2948 {
3053 » PyObject *s, *c; 2949 » PyObject *res, *context;
3054 » char *res; 2950 » mpd_ssize_t size;
3055 2951 » char *cp;
3056 » CURRENT_CONTEXT(c); 2952
3057 » res = mpd_to_sci(MPD(dec), CtxCaps(c)); 2953 » CURRENT_CONTEXT(context);
3058 » if (res == NULL) { 2954 » size = mpd_to_sci_size(&cp, MPD(dec), CtxCaps(context));
2955 » if (size < 0) {
3059 PyErr_NoMemory(); 2956 PyErr_NoMemory();
3060 return NULL; 2957 return NULL;
3061 } 2958 }
3062 2959
3063 » s = PyUnicode_FromString(res); 2960 » res = unicode_fromascii(cp, size);
3064 » mpd_free(res); 2961 » mpd_free(cp);
3065 2962 » return res;
3066 » return s; 2963 }
3067 }
3068
3069 static const char *dtag = "Decimal('";
3070 static const size_t dtaglen = 9; /* without NUL terminator */
3071 2964
3072 /* Representation of a PyDecObject. */ 2965 /* Representation of a PyDecObject. */
3073 static PyObject * 2966 static PyObject *
3074 dec_repr(PyObject *dec) 2967 dec_repr(PyObject *dec)
3075 { 2968 {
3076 » PyObject *s, *c; 2969 » PyObject *res, *context;
3077 » uint8_t err;
3078 char *cp; 2970 char *cp;
3079 » size_t declen; 2971
3080 2972 » CURRENT_CONTEXT(context);
3081 » CURRENT_CONTEXT(c); 2973 » cp = mpd_to_sci(MPD(dec), CtxCaps(context));
3082 » cp = mpd_to_sci(MPD(dec), CtxCaps(c));
3083 if (cp == NULL) { 2974 if (cp == NULL) {
3084 PyErr_NoMemory(); 2975 PyErr_NoMemory();
3085 return NULL; 2976 return NULL;
3086 } 2977 }
3087 » declen = strlen(cp); 2978
3088 2979 » res = PyUnicode_FromFormat("Decimal('%s')", cp);
3089 » err = 0;
3090 » cp = mpd_realloc(cp, (mpd_size_t)(declen+dtaglen+3), sizeof *cp, &err);
3091 » if (err) {
3092 » » mpd_free(cp);
3093 » » PyErr_NoMemory();
3094 » » return NULL;
3095 » }
3096
3097 » memmove(cp+dtaglen, cp, declen);
3098 » memcpy(cp, dtag, dtaglen);
3099 » cp[declen+dtaglen] = '\'';
3100 » cp[declen+dtaglen+1] = ')';
3101 » cp[declen+dtaglen+2] = '\0';
3102
3103 » s = PyUnicode_FromString(cp);
3104
3105 mpd_free(cp); 2980 mpd_free(cp);
3106 » 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;
3107 } 3008 }
3108 3009
3109 /* Formatted representation of a PyDecObject. */ 3010 /* Formatted representation of a PyDecObject. */
3110 static PyObject * 3011 static PyObject *
3111 dec_format(PyObject *dec, PyObject *args) 3012 dec_format(PyObject *dec, PyObject *args)
3112 { 3013 {
3113 PyObject *result = NULL; 3014 PyObject *result = NULL;
3114 PyObject *override = NULL; 3015 PyObject *override = NULL;
3115 PyObject *dot = NULL; 3016 PyObject *dot = NULL;
3116 PyObject *sep = NULL; 3017 PyObject *sep = NULL;
3117 PyObject *grouping = NULL; 3018 PyObject *grouping = NULL;
3118 PyObject *fmt = NULL; 3019 PyObject *fmt = NULL;
3119 PyObject *fmtarg; 3020 PyObject *fmtarg;
3120 PyObject *tmp;
3121 PyObject *context; 3021 PyObject *context;
3122 mpd_spec_t spec; 3022 mpd_spec_t spec;
3123 wchar_t buf[2];
3124 char *decstring= NULL; 3023 char *decstring= NULL;
3125 uint32_t status = 0; 3024 uint32_t status = 0;
3126 size_t n; 3025 size_t n;
3127 3026
3128 3027
3129 CURRENT_CONTEXT(context); 3028 CURRENT_CONTEXT(context);
3130 if (!PyArg_ParseTuple(args, "O|O", &fmtarg, &override)) { 3029 if (!PyArg_ParseTuple(args, "O|O", &fmtarg, &override)) {
3131 return NULL; 3030 return NULL;
3132 } 3031 }
3133 3032
3134 if (PyUnicode_Check(fmtarg)) { 3033 if (PyUnicode_Check(fmtarg)) {
3135 » » if ((fmt = PyUnicode_AsUTF8String(fmtarg)) == NULL) { 3034 » » fmt = PyUnicode_AsUTF8String(fmtarg);
3035 » » if (fmt == NULL) {
3136 return NULL; 3036 return NULL;
3137 } 3037 }
3138 } 3038 }
3139 else { 3039 else {
3140 PyErr_SetString(PyExc_TypeError, 3040 PyErr_SetString(PyExc_TypeError,
3141 » » "format arg must be str."); 3041 » » "format arg must be str");
3142 return NULL; 3042 return NULL;
3143 } 3043 }
3144 3044
3145 if (!mpd_parse_fmt_str(&spec, PyBytes_AS_STRING(fmt), 3045 if (!mpd_parse_fmt_str(&spec, PyBytes_AS_STRING(fmt),
3146 CtxCaps(context))) { 3046 CtxCaps(context))) {
3147 PyErr_SetString(PyExc_ValueError, 3047 PyErr_SetString(PyExc_ValueError,
3148 » » "invalid format string."); 3048 » » "invalid format string");
3149 goto finish; 3049 goto finish;
3150 } 3050 }
3151 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. */
3152 if (!PyDict_Check(override)) { 3057 if (!PyDict_Check(override)) {
3153 PyErr_SetString(PyExc_TypeError, 3058 PyErr_SetString(PyExc_TypeError,
3154 » » » "optional argument must be a dict."); 3059 » » » "optional argument must be a dict");
3155 goto finish; 3060 goto finish;
3156 } 3061 }
3157 if ((dot = PyDict_GetItemString(override, "decimal_point"))) { 3062 if ((dot = PyDict_GetItemString(override, "decimal_point"))) {
3158 if ((dot = PyUnicode_AsUTF8String(dot)) == NULL) { 3063 if ((dot = PyUnicode_AsUTF8String(dot)) == NULL) {
3159 goto finish; 3064 goto finish;
3160 } 3065 }
3161 spec.dot = PyBytes_AS_STRING(dot); 3066 spec.dot = PyBytes_AS_STRING(dot);
3162 } 3067 }
3163 if ((sep = PyDict_GetItemString(override, "thousands_sep"))) { 3068 if ((sep = PyDict_GetItemString(override, "thousands_sep"))) {
3164 if ((sep = PyUnicode_AsUTF8String(sep)) == NULL) { 3069 if ((sep = PyUnicode_AsUTF8String(sep)) == NULL) {
3165 goto finish; 3070 goto finish;
3166 } 3071 }
3167 spec.sep = PyBytes_AS_STRING(sep); 3072 spec.sep = PyBytes_AS_STRING(sep);
3168 } 3073 }
3169 if ((grouping = PyDict_GetItemString(override, "grouping"))) { 3074 if ((grouping = PyDict_GetItemString(override, "grouping"))) {
3170 if ((grouping = PyUnicode_AsUTF8String(grouping)) == NUL L) { 3075 if ((grouping = PyUnicode_AsUTF8String(grouping)) == NUL L) {
3171 goto finish; 3076 goto finish;
3172 } 3077 }
3173 spec.grouping = PyBytes_AS_STRING(grouping); 3078 spec.grouping = PyBytes_AS_STRING(grouping);
3174 } 3079 }
3080 if (mpd_validate_lconv(&spec) < 0) {
3081 PyErr_SetString(PyExc_ValueError,
3082 "invalid override dict");
3083 goto finish;
3084 }
3175 } 3085 }
3176 else { 3086 else {
3177 n = strlen(spec.dot); 3087 n = strlen(spec.dot);
3178 if (n > 1 || (n == 1 && !isascii((uchar)spec.dot[0]))) { 3088 if (n > 1 || (n == 1 && !isascii((uchar)spec.dot[0]))) {
3179 » » » n = mbstowcs(buf, spec.dot, 2); 3089 » » » /* fix locale dependent non-ascii characters */
3180 » » » if (n != 1) { 3090 » » » dot = dotsep_as_utf8(spec.dot);
3181 » » » » PyErr_SetString(PyExc_ValueError, 3091 » » » if (dot == NULL) {
3182 » » » » "invalid decimal point or unsupported "
3183 » » » » "combination of LC_CTYPE and LC_NUMERIC.");
3184 » » » » goto finish;
3185 » » » }
3186 » » » if ((tmp = PyUnicode_FromWideChar(buf, n)) == NULL) {
3187 » » » » goto finish;
3188 » » » }
3189 » » » if ((dot = PyUnicode_AsUTF8String(tmp)) == NULL) {
3190 » » » » Py_DECREF(tmp);
3191 goto finish; 3092 goto finish;
3192 } 3093 }
3193 spec.dot = PyBytes_AS_STRING(dot); 3094 spec.dot = PyBytes_AS_STRING(dot);
3194 Py_DECREF(tmp);
3195 } 3095 }
3196 n = strlen(spec.sep); 3096 n = strlen(spec.sep);
3197 if (n > 1 || (n == 1 && !isascii((uchar)spec.sep[0]))) { 3097 if (n > 1 || (n == 1 && !isascii((uchar)spec.sep[0]))) {
3198 » » » n = mbstowcs(buf, spec.sep, 2); 3098 » » » /* fix locale dependent non-ascii characters */
3199 » » » if (n != 1) { 3099 » » » sep = dotsep_as_utf8(spec.sep);
3200 » » » » PyErr_SetString(PyExc_ValueError, 3100 » » » if (sep == NULL) {
3201 » » » » "invalid thousands separator or unsupported "
3202 » » » » "combination of LC_CTYPE and LC_NUMERIC.");
3203 » » » » goto finish;
3204 » » » }
3205 » » » if ((tmp = PyUnicode_FromWideChar(buf, n)) == NULL) {
3206 » » » » goto finish;
3207 » » » }
3208 » » » if ((sep = PyUnicode_AsUTF8String(tmp)) == NULL) {
3209 » » » » Py_DECREF(tmp);
3210 goto finish; 3101 goto finish;
3211 } 3102 }
3212 spec.sep = PyBytes_AS_STRING(sep); 3103 spec.sep = PyBytes_AS_STRING(sep);
3213 Py_DECREF(tmp);
3214 } 3104 }
3215 } 3105 }
3216 3106
3217 3107
3218 decstring = mpd_qformat_spec(MPD(dec), &spec, CTX(context), &status); 3108 decstring = mpd_qformat_spec(MPD(dec), &spec, CTX(context), &status);
3219 if (decstring == NULL) { 3109 if (decstring == NULL) {
3220 dec_addstatus(context, status); 3110 dec_addstatus(context, status);
3221 goto finish; 3111 goto finish;
3222 } 3112 }
3223 result = PyUnicode_DecodeUTF8(decstring, strlen(decstring), NULL); 3113 result = PyUnicode_DecodeUTF8(decstring, strlen(decstring), NULL);
(...skipping 16 matching lines...) Expand all
3240 PyLongObject *pylong; 3130 PyLongObject *pylong;
3241 size_t maxsize, n; 3131 size_t maxsize, n;
3242 Py_ssize_t i; 3132 Py_ssize_t i;
3243 mpd_t *x; 3133 mpd_t *x;
3244 mpd_context_t workctx; 3134 mpd_context_t workctx;
3245 uint32_t status = 0; 3135 uint32_t status = 0;
3246 3136
3247 if (mpd_isspecial(MPD(dec))) { 3137 if (mpd_isspecial(MPD(dec))) {
3248 if (mpd_isnan(MPD(dec))) { 3138 if (mpd_isnan(MPD(dec))) {
3249 PyErr_SetString(PyExc_ValueError, 3139 PyErr_SetString(PyExc_ValueError,
3250 » » » "cannot convert NaN to integer."); 3140 » » » "cannot convert NaN to integer");
3251 } 3141 }
3252 else { 3142 else {
3253 PyErr_SetString(PyExc_OverflowError, 3143 PyErr_SetString(PyExc_OverflowError,
3254 » » » "cannot convert Infinity to integer."); 3144 » » » "cannot convert Infinity to integer");
3255 » » } 3145 » » }
3256 » » return NULL; 3146 » » return NULL;
3257 » } 3147 » }
3258 3148
3259 » if ((x = mpd_qnew()) == NULL) { 3149 » x = mpd_qnew();
3150 » if (x == NULL) {
3260 PyErr_NoMemory(); 3151 PyErr_NoMemory();
3261 return NULL; 3152 return NULL;
3262 } 3153 }
3263 workctx = *CTX(context); 3154 workctx = *CTX(context);
3264 workctx.round = round; 3155 workctx.round = round;
3265 mpd_qround_to_int(x, MPD(dec), &workctx, &status); 3156 mpd_qround_to_int(x, MPD(dec), &workctx, &status);
3266 if (dec_addstatus(context, status)) { 3157 if (dec_addstatus(context, status)) {
3267 mpd_del(x); 3158 mpd_del(x);
3268 return NULL; 3159 return NULL;
3269 } 3160 }
3270 3161
3271 maxsize = mpd_sizeinbase(x, PyLong_BASE); 3162 maxsize = mpd_sizeinbase(x, PyLong_BASE);
3272 if (maxsize > PY_SSIZE_T_MAX) { 3163 if (maxsize > PY_SSIZE_T_MAX) {
3273 mpd_del(x); 3164 mpd_del(x);
3274 PyErr_NoMemory(); 3165 PyErr_NoMemory();
3275 return NULL; 3166 return NULL;
3276 } 3167 }
3277 » if ((pylong = _PyLong_New(maxsize)) == NULL) { 3168 » pylong = _PyLong_New(maxsize);
3169 » if (pylong == NULL) {
3278 mpd_del(x); 3170 mpd_del(x);
3279 return NULL; 3171 return NULL;
3280 } 3172 }
3281 3173
3282 status = 0; 3174 status = 0;
3283 #if PYLONG_BITS_IN_DIGIT == 30 3175 #if PYLONG_BITS_IN_DIGIT == 30
3284 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);
3285 #elif PYLONG_BITS_IN_DIGIT == 15 3177 #elif PYLONG_BITS_IN_DIGIT == 15
3286 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);
3287 #else 3179 #else
3288 #error "PYLONG_BITS_IN_DIGIT should be 15 or 30." 3180 #error "PYLONG_BITS_IN_DIGIT should be 15 or 30"
3289 #endif 3181 #endif
3290 if (dec_addstatus(context, status)) { 3182 if (dec_addstatus(context, status)) {
3291 Py_DECREF((PyObject *) pylong); 3183 Py_DECREF((PyObject *) pylong);
3292 mpd_del(x); 3184 mpd_del(x);
3293 return NULL; 3185 return NULL;
3294 } 3186 }
3295 3187
3296 i = n; 3188 i = n;
3297 while ((i > 0) && (pylong->ob_digit[i-1] == 0)) { 3189 while ((i > 0) && (pylong->ob_digit[i-1] == 0)) {
3298 i--; 3190 i--;
(...skipping 25 matching lines...) Expand all
3324 } 3216 }
3325 CONTEXT_CHECK_VA(context); 3217 CONTEXT_CHECK_VA(context);
3326 3218
3327 workctx = *CTX(context); 3219 workctx = *CTX(context);
3328 if (round >= 0) { 3220 if (round >= 0) {
3329 if (!mpd_qsetround(&workctx, round)) { 3221 if (!mpd_qsetround(&workctx, round)) {
3330 return type_error_ptr(invalid_rounding_err); 3222 return type_error_ptr(invalid_rounding_err);
3331 } 3223 }
3332 } 3224 }
3333 3225
3334 » if ((result = dec_alloc()) == NULL) { 3226 » result = dec_alloc();
3227 » if (result == NULL) {
3335 return NULL; 3228 return NULL;
3336 } 3229 }
3337 3230
3338 mpd_qround_to_int(MPD(result), MPD(dec), &workctx, &status); 3231 mpd_qround_to_int(MPD(result), MPD(dec), &workctx, &status);
3339 if (dec_addstatus(context, status)) { 3232 if (dec_addstatus(context, status)) {
3340 Py_DECREF(result); 3233 Py_DECREF(result);
3341 return NULL; 3234 return NULL;
3342 } 3235 }
3343 3236
3344 return result; 3237 return result;
(...skipping 16 matching lines...) Expand all
3361 } 3254 }
3362 CONTEXT_CHECK_VA(context); 3255 CONTEXT_CHECK_VA(context);
3363 3256
3364 workctx = *CTX(context); 3257 workctx = *CTX(context);
3365 if (round >= 0) { 3258 if (round >= 0) {
3366 if (!mpd_qsetround(&workctx, round)) { 3259 if (!mpd_qsetround(&workctx, round)) {
3367 return type_error_ptr(invalid_rounding_err); 3260 return type_error_ptr(invalid_rounding_err);
3368 } 3261 }
3369 } 3262 }
3370 3263
3371 » if ((result = dec_alloc()) == NULL) { 3264 » result = dec_alloc();
3265 » if (result == NULL) {
3372 return NULL; 3266 return NULL;
3373 } 3267 }
3374 3268
3375 mpd_qround_to_intx(MPD(result), MPD(dec), &workctx, &status); 3269 mpd_qround_to_intx(MPD(result), MPD(dec), &workctx, &status);
3376 if (dec_addstatus(context, status)) { 3270 if (dec_addstatus(context, status)) {
3377 Py_DECREF(result); 3271 Py_DECREF(result);
3378 return NULL; 3272 return NULL;
3379 } 3273 }
3380 3274
3381 return result; 3275 return result;
3382 } 3276 }
3383 3277
3384 static PyObject * 3278 static PyObject *
3385 PyDec_AsFloat(PyObject *dec) 3279 PyDec_AsFloat(PyObject *dec)
3386 { 3280 {
3387 PyObject *f, *s; 3281 PyObject *f, *s;
3388 3282
3389 » if ((s = dec_str(dec)) == NULL) { 3283 » s = dec_str(dec);
3284 » if (s == NULL) {
3390 return NULL; 3285 return NULL;
3391 } 3286 }
3392 3287
3393 f = PyFloat_FromString(s); 3288 f = PyFloat_FromString(s);
3394 Py_DECREF(s); 3289 Py_DECREF(s);
3395 3290
3396 return f; 3291 return f;
3397 } 3292 }
3398 3293
3399 static PyObject * 3294 static PyObject *
(...skipping 10 matching lines...) Expand all
3410 return NULL; 3305 return NULL;
3411 } 3306 }
3412 3307
3413 if (x) { 3308 if (x) {
3414 mpd_uint_t dq[1] = {1}; 3309 mpd_uint_t dq[1] = {1};
3415 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};
3416 mpd_ssize_t y; 3311 mpd_ssize_t y;
3417 3312
3418 if (!PyLong_Check(x)) { 3313 if (!PyLong_Check(x)) {
3419 PyErr_SetString(PyExc_TypeError, 3314 PyErr_SetString(PyExc_TypeError,
3420 » » » "optional arg must be an integer."); 3315 » » » "optional arg must be an integer");
3421 return NULL; 3316 return NULL;
3422 } 3317 }
3423 3318
3424 » » y = long_as_mpd_ssize(x); 3319 » » y = PyLong_AsSsize_t(x);
3425 » » if (PyErr_Occurred()) { 3320 » » if (y == -1 && PyErr_Occurred()) {
3426 return NULL; 3321 return NULL;
3427 } 3322 }
3428 » » if ((result = dec_alloc()) == NULL) { 3323 » » result = dec_alloc();
3324 » » if (result == NULL) {
3429 return NULL; 3325 return NULL;
3430 } 3326 }
3431 3327
3432 q.exp = (y == MPD_SSIZE_MIN) ? MPD_SSIZE_MAX : -y; 3328 q.exp = (y == MPD_SSIZE_MIN) ? MPD_SSIZE_MAX : -y;
3433 mpd_qquantize(MPD(result), MPD(dec), &q, CTX(context), &status); 3329 mpd_qquantize(MPD(result), MPD(dec), &q, CTX(context), &status);
3434 if (dec_addstatus(context, status)) { 3330 if (dec_addstatus(context, status)) {
3435 Py_DECREF(result); 3331 Py_DECREF(result);
3436 return NULL; 3332 return NULL;
3437 } 3333 }
3438 3334
(...skipping 12 matching lines...) Expand all
3451 PyObject *result = NULL; 3347 PyObject *result = NULL;
3452 PyObject *sign = NULL; 3348 PyObject *sign = NULL;
3453 PyObject *coeff = NULL; 3349 PyObject *coeff = NULL;
3454 PyObject *expt = NULL; 3350 PyObject *expt = NULL;
3455 PyObject *tmp = NULL; 3351 PyObject *tmp = NULL;
3456 mpd_t *x = NULL; 3352 mpd_t *x = NULL;
3457 char *intstring = NULL; 3353 char *intstring = NULL;
3458 Py_ssize_t intlen, i; 3354 Py_ssize_t intlen, i;
3459 3355
3460 3356
3461 » if ((x = mpd_qncopy(MPD(dec))) == NULL) { 3357 » x = mpd_qncopy(MPD(dec));
3358 » if (x == NULL) {
3462 PyErr_NoMemory(); 3359 PyErr_NoMemory();
3463 goto out; 3360 goto out;
3464 } 3361 }
3465 3362
3466 » sign = Py_BuildValue("i", mpd_sign(MPD(dec))); 3363 » sign = PyLong_FromUnsignedLong(mpd_sign(MPD(dec)));
3467 » if (sign == NULL) goto out; 3364 » if (sign == NULL) {
3365 » » goto out;
3366 » }
3468 3367
3469 if (mpd_isinfinite(x)) { 3368 if (mpd_isinfinite(x)) {
3470 » » if ((expt = Py_BuildValue("s", "F")) == NULL) { 3369 » » expt = PyUnicode_FromString("F");
3370 » » if (expt == NULL) {
3471 goto out; 3371 goto out;
3472 } 3372 }
3473 /* decimal.py has non-compliant infinity payloads. */ 3373 /* decimal.py has non-compliant infinity payloads. */
3474 » » if ((coeff = Py_BuildValue("(i)", 0)) == NULL) { 3374 » » coeff = Py_BuildValue("(i)", 0);
3375 » » if (coeff == NULL) {
3475 goto out; 3376 goto out;
3476 } 3377 }
3477 } 3378 }
3478 else { 3379 else {
3479 if (mpd_isnan(x)) { 3380 if (mpd_isnan(x)) {
3480 » » » expt = Py_BuildValue("s", mpd_isqnan(x)?"n":"N"); 3381 » » » expt = PyUnicode_FromString(mpd_isqnan(x)?"n":"N");
3481 } 3382 }
3482 else { 3383 else {
3483 » » » expt = Py_BuildValue(CONV_mpd_ssize_t, MPD(dec)->exp); 3384 » » » expt = PyLong_FromSsize_t(MPD(dec)->exp);
3484 » » } 3385 » » }
3485 » » if (expt == NULL) goto out; 3386 » » if (expt == NULL) {
3387 » » » goto out;
3388 » » }
3486 3389
3487 /* coefficient is defined */ 3390 /* coefficient is defined */
3488 if (x->len > 0) { 3391 if (x->len > 0) {
3489 3392
3490 /* make an integer */ 3393 /* make an integer */
3491 x->exp = 0; 3394 x->exp = 0;
3492 /* clear NaN and sign */ 3395 /* clear NaN and sign */
3493 mpd_clear_flags(x); 3396 mpd_clear_flags(x);
3494 intstring = mpd_to_sci(x, 1); 3397 intstring = mpd_to_sci(x, 1);
3495 if (intstring == NULL) { 3398 if (intstring == NULL) {
3496 PyErr_NoMemory(); 3399 PyErr_NoMemory();
3497 goto out; 3400 goto out;
3498 } 3401 }
3499 3402
3500 intlen = strlen(intstring); 3403 intlen = strlen(intstring);
3501 » » » if ((coeff = PyTuple_New(intlen)) == NULL) { 3404 » » » coeff = PyTuple_New(intlen);
3405 » » » if (coeff == NULL) {
3502 goto out; 3406 goto out;
3503 } 3407 }
3504 3408
3505 for (i = 0; i < intlen; i++) { 3409 for (i = 0; i < intlen; i++) {
3506 » » » » tmp = Py_BuildValue("i", intstring[i]-'0'); 3410 » » » » tmp = PyLong_FromLong(intstring[i]-'0');
3507 » » » » if (tmp == NULL) goto out; 3411 » » » » if (tmp == NULL) {
3412 » » » » » goto out;
3413 » » » » }
3508 PyTuple_SET_ITEM(coeff, i, tmp); 3414 PyTuple_SET_ITEM(coeff, i, tmp);
3509 } 3415 }
3510 } 3416 }
3511 else { 3417 else {
3512 » » » if ((coeff = PyTuple_New(0)) == NULL) { 3418 » » » coeff = PyTuple_New(0);
3419 » » » if (coeff == NULL) {
3513 goto out; 3420 goto out;
3514 } 3421 }
3515 } 3422 }
3516 } 3423 }
3517 3424
3518 result = PyObject_CallFunctionObjArgs(DecimalTuple, 3425 result = PyObject_CallFunctionObjArgs(DecimalTuple,
3519 sign, coeff, expt, NULL); 3426 sign, coeff, expt, NULL);
3520 3427
3521 out: 3428 out:
3522 if (x) mpd_del(x); 3429 if (x) mpd_del(x);
(...skipping 28 matching lines...) Expand all
3551 Py_DECREF(result); \ 3458 Py_DECREF(result); \
3552 return NULL; \ 3459 return NULL; \
3553 } \ 3460 } \
3554 \ 3461 \
3555 return result; \ 3462 return result; \
3556 } 3463 }
3557 3464
3558 /* Binary number method that uses default module context. */ 3465 /* Binary number method that uses default module context. */
3559 #define Dec_BinaryNumberMethod(MPDFUNC) \ 3466 #define Dec_BinaryNumberMethod(MPDFUNC) \
3560 static PyObject * \ 3467 static PyObject * \
3561 nm_##MPDFUNC(PyObject *v, PyObject *w) \ 3468 nm_##MPDFUNC(PyObject *self, PyObject *other) \
3562 { \ 3469 { \
3563 PyObject *a, *b; \ 3470 PyObject *a, *b; \
3564 PyObject *result; \ 3471 PyObject *result; \
3565 PyObject *context; \ 3472 PyObject *context; \
3566 uint32_t status = 0; \ 3473 uint32_t status = 0; \
3567 \ 3474 \
3568 CURRENT_CONTEXT(context) ; \ 3475 CURRENT_CONTEXT(context) ; \
3569 CONVERT_BINOP(&a, &b, v, w, context); \ 3476 CONVERT_BINOP(&a, &b, self, other, context); \
3570 \ 3477 \
3571 if ((result = dec_alloc()) == NULL) { \ 3478 if ((result = dec_alloc()) == NULL) { \
3572 Py_DECREF(a); \ 3479 Py_DECREF(a); \
3573 Py_DECREF(b); \ 3480 Py_DECREF(b); \
3574 return NULL; \ 3481 return NULL; \
3575 } \ 3482 } \
3576 \ 3483 \
3577 MPDFUNC(MPD(result), MPD(a), MPD(b), CTX(context), &status); \ 3484 MPDFUNC(MPD(result), MPD(a), MPD(b), CTX(context), &status); \
3578 Py_DECREF(a); \ 3485 Py_DECREF(a); \
3579 Py_DECREF(b); \ 3486 Py_DECREF(b); \
3580 if (dec_addstatus(context, status)) { \ 3487 if (dec_addstatus(context, status)) { \
3581 Py_DECREF(result); \ 3488 Py_DECREF(result); \
3582 return NULL; \ 3489 return NULL; \
3583 } \ 3490 } \
3584 \ 3491 \
3585 return result; \ 3492 return result; \
3586 } 3493 }
3587 3494
3588 /* Boolean function without a context arg. */ 3495 /* Boolean function without a context arg. */
3589 #define Dec_BoolFunc(MPDFUNC) \ 3496 #define Dec_BoolFunc(MPDFUNC) \
3590 static PyObject * \ 3497 static PyObject * \
3591 dec_##MPDFUNC(PyObject *self, PyObject *dummy UNUSED) \ 3498 dec_##MPDFUNC(PyObject *self, PyObject *dummy UNUSED) \
3592 { \ 3499 { \
3593 return MPDFUNC(MPD(self)) ? Dec_INCREF_TRUE : Dec_INCREF_FALSE; \ 3500 return MPDFUNC(MPD(self)) ? incr_true() : incr_false(); \
3594 } 3501 }
3595 3502
3596 /* Boolean function with an optional context arg. */ 3503 /* Boolean function with an optional context arg. */
3597 #define Dec_BoolFuncVA(MPDFUNC) \ 3504 #define Dec_BoolFuncVA(MPDFUNC) \
3598 static PyObject * \ 3505 static PyObject * \
3599 dec_##MPDFUNC(PyObject *self, PyObject *args) \ 3506 dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \
3600 { \ 3507 { \
3601 PyObject *context; \ 3508 static char *kwlist[] = {"context", NULL}; \
3602 \ 3509 PyObject *context; \
3603 CURRENT_CONTEXT(context); \ 3510 \
3604 if (!PyArg_ParseTuple(args, "|O", &context)) { \ 3511 CURRENT_CONTEXT(context); \
3605 return NULL; \ 3512 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, \
3606 } \ 3513 &context)) { \
3607 CONTEXT_CHECK_VA(context); \ 3514 return NULL; \
3608 \ 3515 } \
3609 return MPDFUNC(MPD(self), CTX(context)) \ 3516 CONTEXT_CHECK_VA(context); \
3610 ? Dec_INCREF_TRUE : Dec_INCREF_FALSE; \ 3517 \
3518 return MPDFUNC(MPD(self), CTX(context)) ? incr_true() : incr_false(); \
3611 } 3519 }
3612 3520
3613 /* Unary function with an optional context arg. */ 3521 /* Unary function with an optional context arg. */
3614 #define Dec_UnaryFuncVA(MPDFUNC) \ 3522 #define Dec_UnaryFuncVA(MPDFUNC) \
3615 static PyObject * \ 3523 static PyObject * \
3616 dec_##MPDFUNC(PyObject *self, PyObject *args) \ 3524 dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \
3617 { \ 3525 { \
3618 PyObject *result; \ 3526 <