[Python-checkins] r46179 - sandbox/trunk/decimal-c/_decimal.c
georg.brandl
python-checkins at python.org
Wed May 24 17:06:18 CEST 2006
Author: georg.brandl
Date: Wed May 24 17:06:16 2006
New Revision: 46179
Modified:
sandbox/trunk/decimal-c/_decimal.c
Log:
Resolve conflict.
Modified: sandbox/trunk/decimal-c/_decimal.c
==============================================================================
--- sandbox/trunk/decimal-c/_decimal.c (original)
+++ sandbox/trunk/decimal-c/_decimal.c Wed May 24 17:06:16 2006
@@ -925,71 +925,83 @@
return Py_NotImplemented;
}
-#define STUB_HEAD static PyObject *
-#define STUB_TAIL (PyObject *self, PyObject *args) { return NULL; }
-#define STUB_TAIL1 (PyObject *self) { return NULL; }
-#define STUB(name) STUB_HEAD decimal_##name STUB_TAIL
-#define STUB1(name) STUB_HEAD decimal_##name STUB_TAIL1
-
static char *ctxkwlist[] = {"context", 0};
+static char *decctxkwlist[] = {"other", "context", 0};
-#define ENSURE_DECIMAL(methname, dec) \
- dec = _convert_to_decimal((PyObject *)dec, ctx); \
- if (!dec) { \
- PyErr_SetString(PyExc_TypeError, methname ": " #dec " must be a Decimal object"); \
- return NULL; \
- }
-
-#define ENSURE_CONTEXT(methname, ctx) \
- if (ctx == NULL) { \
- if (!(ctx = getcontext())) return NULL; \
- } else if (!PyDecimalContext_Check(ctx)) { \
- PyErr_SetString(PyExc_TypeError, methname ": context must be a Context object"); \
- return NULL; \
- }
-
-#define PARSE_CONTEXT(methname, ctx) \
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:" methname, ctxkwlist, &ctx)) \
- { return NULL; } \
- ENSURE_CONTEXT(methname, ctx)
+#define ENSURE_DECIMAL(methname, dec, type) \
+ dec = _convert_to_decimal(type, (PyObject *)dec, ctx, 1); \
+ if (!dec) { \
+ PyErr_SetString(PyExc_TypeError, methname ": " #dec " must be a Decimal object"); \
+ return NULL; \
+ }
-STUB(compare)
+#define ENSURE_CONTEXT(methname, ctx) \
+ if (ctx == NULL) { \
+ if (!(ctx = getcontext())) return NULL; \
+ } else if (!PyDecimalContext_Check(ctx)) { \
+ PyErr_SetString(PyExc_TypeError, methname ": context must be a Context object"); \
+ return NULL; \
+ }
-static decimalobject *
-decimal_max(decimalobject *self, PyObject *args, PyObject *kwds)
-{
- static char *kwlist[] = {"other", "context", 0};
- decimalobject *other = NULL;
- contextobject *ctx = NULL;
+#define DECIMAL_UNARY_FUNC(methname) \
+ static PyObject * \
+ decimal_##methname(decimalobject *self, PyObject *args, PyObject *kwds) \
+ { \
+ contextobject *ctx = NULL; \
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:" #methname, ctxkwlist, &ctx)) \
+ return NULL; \
+ ENSURE_CONTEXT(#methname, ctx); \
+ return _do_decimal_##methname(self, ctx); \
+ }
+
+#define DECIMAL_BINARY_FUNC(methname) \
+ static PyObject * \
+ decimal_##methname(decimalobject *self, PyObject *args, PyObject *kwds) \
+ { \
+ decimalobject *res; \
+ decimalobject *dec = NULL; \
+ contextobject *ctx = NULL; \
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:" #methname, \
+ decctxkwlist, &dec, &ctx)) \
+ return NULL; \
+ ENSURE_CONTEXT(#methname, ctx); \
+ ENSURE_DECIMAL(#methname, dec, self->ob_type); \
+ res = _do_decimal_##methname(self, dec, ctx); \
+ Py_DECREF(dec); \
+ return res; \
+ }
+
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:max", kwlist,
- &other, &ctx))
- return NULL;
- ENSURE_CONTEXT("max", ctx);
+static decimalobject *
+_do_decimal_compare(decimalobject *self, decimalobject *other,
+ contextobject *ctx)
+{
+ /* XXX */
}
+DECIMAL_BINARY_FUNC(compare)
static decimalobject *
-decimal_min(decimalobject *self, PyObject *args, PyObject *kwds)
+_do_decimal_max(decimalobject *self, decimalobject *other,
+ contextobject *ctx)
{
- static char *kwlist[] = {"other", "context", 0};
- decimalobject *other = NULL;
- contextobject *ctx = NULL;
+ /* XXX */
+}
+DECIMAL_BINARY_FUNC(max)
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:min", kwlist,
- &other, &ctx))
- return NULL;
- ENSURE_CONTEXT("max", ctx);
+static decimalobject *
+_do_decimal_min(decimalobject *self, decimalobject *other,
+ contextobject *ctx)
+{
+ /* XXX */
}
+DECIMAL_BINARY_FUNC(min)
/* strip trailing 0s, change anything equal to 0 to 0e0 */
static decimalobject *
-decimal_normalize(decimalobject *self, PyObject *args, PyObject *kwds)
+_do_decimal_normalize(decimalobject *self, contextobject *ctx)
{
decimalobject *dup, *new;
- contextobject *ctx = NULL;
- PARSE_CONTEXT("normalize", ctx);
-
if (ISSPECIAL(self)) {
decimalobject *nan = NULL;
int res;
@@ -1016,8 +1028,32 @@
}
return dup;
}
+DECIMAL_UNARY_FUNC(normalize)
/* Quantize self so that its exponent is the same as the exponent of another. */
+
+static decimalobject *
+_do_decimal_quantize(decimalobject *self, decimalobject *other,
+ contextobject *ctx, int rounding, int watchexp)
+{
+ if (ISSPECIAL(self) || ISSPECIAL(other)) {
+ decimalobject *nan = NULL;
+ int res;
+ res = _check_nans(self, other, ctx, &nan);
+ if (res != 0) return nan; /* can be NULL on error */
+
+ if (ISINF(self) || ISINF(other)) {
+ if (ISINF(self) && ISINF(other)) {
+ Py_INCREF(self);
+ return self;
+ }
+ return handle_InvalidOperation(self->ob_type, ctx,
+ "quantize with one INF", NULL);
+ }
+ }
+ return _decimal_rescale(self, other->exp, ctx, rounding, watchexp);
+}
+
static decimalobject *
decimal_quantize(decimalobject *self, PyObject *args, PyObject *kwds)
{
@@ -1041,42 +1077,22 @@
PyErr_SetString(PyExc_TypeError, "exp must be a Decimal object");
return NULL;
}
- if (ISSPECIAL(self) || ISSPECIAL(other)) {
- decimalobject *nan = NULL;
- int res;
- res = _check_nans(self, other, ctx, &nan);
- if (res != 0) return nan; /* can be NULL on error */
- if (ISINF(self) || ISINF(other)) {
- if (ISINF(self) && ISINF(other)) {
- Py_INCREF(self);
- return self;
- }
- return handle_InvalidOperation(self->ob_type, ctx,
- "quantize with one INF", NULL);
- }
- }
- return _decimal_rescale(self, other->exp, ctx, rounding, watchexp);
+ return _do_decimal_quantize(self, other, ctx, rounding, watchexp);
}
-STUB(remainder_near)
-
-static PyObject *
-decimal_same_quantum(decimalobject *self, PyObject *args, PyObject *kwds)
+static decimalobject *
+_do_decimal_remainder_near(decimalobject *self, decimalobject *other,
+ contextobject *ctx)
{
- static char *kwlist[] = {"other", 0};
- decimalobject *other = NULL;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:same_quantum", kwlist,
- &other))
- return NULL;
+}
+DECIMAL_BINARY_FUNC(remainder_near)
- if (!PyDecimal_Check(other)) {
- PyErr_SetString(PyExc_TypeError, "other must be a Decimal object");
- return NULL;
- }
+static PyObject *
+_do_decimal_same_quantum(decimalobject *self, decimalobject *other)
+{
if (ISSPECIAL(self) && ISSPECIAL(other)) {
if (GETNAN(self) || GETNAN(other)) {
if (GETNAN(self) && GETNAN(other))
@@ -1098,9 +1114,65 @@
Py_RETURN_FALSE;
}
+static PyObject *
+decimal_same_quantum(decimalobject *self, PyObject *args, PyObject *kwds)
+{
+ static char *kwlist[] = {"other", 0};
+ decimalobject *other = NULL;
+
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:same_quantum", kwlist,
+ &other))
+ return NULL;
+
+
+ if (!PyDecimal_Check(other)) {
+ PyErr_SetString(PyExc_TypeError, "other must be a Decimal object");
+ return NULL;
+ }
+
+ return _do_decimal_same_quantum(self, other);
+}
+
+
+static decimalobject *
+_do_decimal_sqrt(decimalobject *self, contextobject *ctx)
+{
+}
+DECIMAL_UNARY_FUNC(sqrt)
+
+
+static decimalobject *
+_do_decimal_to_eng_string(decimalobject *self, contextobject *ctx)
+{
+ return _do_decimal_str(self, ctx, 1);
+}
+DECIMAL_UNARY_FUNC(to_eng_string)
+
-STUB(sqrt)
-STUB(to_integral)
+static decimalobject *
+_do_decimal_to_integral(decimalobject *self, contextobject *ctx, int rounding)
+{
+ /* XXX */
+}
+
+static PyObject *
+decimal_to_integral(decimalobject *self, PyObject *args, PyObject *kwds)
+{
+ static char *kwlist[] = {"rounding", "context", 0};
+ contextobject *ctx = NULL;
+ int rounding = -1;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iO:to_integral", kwlist,
+ &rounding, &ctx))
+ return NULL;
+ ENSURE_CONTEXT("to_integral", ctx);
+ if (rounding < -1 || rounding > 6) {
+ PyErr_SetString(PyExc_ValueError, "invalid rounding value");
+ return NULL;
+ }
+ return _do_decimal_to_integral(self, ctx, rounding);
+}
static PyObject *
@@ -1268,16 +1340,6 @@
}
PyObject *
-decimal_to_eng_string(PyObject *self, PyObject *args, PyObject *kwds)
-{
- static char *kwlist[] = {"context", 0};
- PyObject *context = NULL;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O!", kwlist, &context, &PyDecimal_DecimalContextType))
- return NULL;
- return _do_decimal_str((decimalobject *)self, (contextobject *)context, 1);
-}
-PyObject *
PyDecimal_Str(PyObject *self, PyObject *args, PyObject *kwds)
{
return _do_decimal_str((decimalobject *)self, NULL, 0);
@@ -2338,6 +2400,8 @@
tmp2 = PyTuple_New(0);
if (!tmp2)
return -1;
+ /* This is not calling _do_decimal_normalize because we're having
+ no Context ready. */
tmp = (PyObject *)decimal_normalize(d, tmp2, NULL);
Py_DECREF(tmp2);
if (!tmp)
@@ -2583,10 +2647,59 @@
return new;
}
-/* Context methods ***********************************************************/
+/* Context properties *********************************************************/
-#define CSTUB(name) STUB_HEAD context_##name STUB_TAIL
+static PyObject *
+_dict_from_bitmask(int bitmask)
+{
+ PyObject *dict = NULL, *val, *dp;
+ int i, res;
+
+ dict = PyDict_New();
+ if (!dict) return NULL;
+ for (i = 0; i < NUMSIGNALS; i++) {
+ val = PyInt_FromLong(ISFLAGSET(bitmask, i));
+ if (!val) goto err;
+ res = PyDict_SetItem(dict, errors[i], val);
+ Py_DECREF(val);
+ if (val < 0) goto err;
+ }
+ dp = PyDictProxy_New(dict);
+ Py_DECREF(dict);
+ return dp;
+
+ err:
+ Py_XDECREF(dict);
+ return NULL;
+}
+
+static PyObject *
+context_get_flags(contextobject *self)
+{
+ return _dict_from_bitmask(self->flags);
+}
+
+static PyObject *
+context_get_traps(contextobject *self)
+{
+ return _dict_from_bitmask(self->traps);
+}
+
+static PyObject *
+context_get_ignored(contextobject *self)
+{
+ return _dict_from_bitmask(self->ignored);
+}
+
+static PyGetSetDef context_getset[] = {
+ {"flags", (getter)context_get_flags, (setter)0},
+ {"traps", (getter)context_get_traps, (setter)0},
+ {"_ignored", (getter)context_get_ignored, (setter)0},
+ {NULL}
+};
+
+/* Context methods ************************************************************/
static PyObject *
context_clear_flags(contextobject *self)
@@ -2674,7 +2787,7 @@
context_##name(contextobject *self, PyObject *args) { \
PyObject *a, *b; \
decimalobject *dec_a = NULL, *dec_b = NULL, *res; \
- if (!PyArg_ParseTuple(args, "OO:" #name)) return NULL; \
+ if (!PyArg_ParseTuple(args, "OO:" #name, &a, &b)) return NULL; \
dec_a = (decimalobject *)_convert_to_decimal( \
&PyDecimal_DecimalType, a, self, 1); \
if (dec_a == NULL) return NULL; \
@@ -2687,7 +2800,7 @@
return res; \
}
-/* helper so that I can use the CONTEXT_UNARY_FUNC macro above */
+/* helper so that we can use the CONTEXT_UNARY_FUNC macro above */
#define _do_decimal_abs_with_round(a, b) \
_do_decimal_absolute(a, b, 1)
@@ -2696,25 +2809,177 @@
CONTEXT_BINARY_FUNC(divide, divide)
CONTEXT_BINARY_FUNC(divide_int, floor_div)
CONTEXT_BINARY_FUNC(divmod, divmod)
+CONTEXT_BINARY_FUNC(remainder, remainder)
CONTEXT_UNARY_FUNC(minus, negative)
CONTEXT_BINARY_FUNC(multiply, multiply)
CONTEXT_UNARY_FUNC(plus, positive)
CONTEXT_BINARY_FUNC(subtract, subtract)
-CSTUB(compare)
-CSTUB(min)
-CSTUB(max)
-CSTUB(normalize)
-CSTUB(power)
-CSTUB(quantize)
-CSTUB(reduce)
-CSTUB(remainder)
-CSTUB(remainder_near)
-CSTUB(same_quantum)
-CSTUB(sqrt)
-CSTUB(to_eng_string)
-CSTUB(to_integral)
-CSTUB(to_sci_string)
+CONTEXT_BINARY_FUNC(compare, compare)
+CONTEXT_BINARY_FUNC(min, min)
+CONTEXT_BINARY_FUNC(max, max)
+CONTEXT_UNARY_FUNC(normalize, normalize)
+CONTEXT_BINARY_FUNC(remainder_near, remainder_near)
+CONTEXT_UNARY_FUNC(sqrt, sqrt)
+CONTEXT_UNARY_FUNC(to_eng_string, to_eng_string)
+
+
+/* Unfortunately, the following methods are non-standard and can't
+ be created by macros. */
+
+static PyObject *
+context_power(contextobject *self, PyObject *args)
+{
+ PyObject *a, *b, *c;
+ decimalobject *dec_a = NULL, *dec_b = NULL, *dec_c = NULL, *res;
+ if (!PyArg_ParseTuple(args, "OO|O:power", &a, &b, &c))
+ return NULL;
+ dec_a = (decimalobject *)_convert_to_decimal(
+ &PyDecimal_DecimalType, a, self, 1);
+ if (dec_a == NULL)
+ return NULL;
+
+ dec_b = (decimalobject *)_convert_to_decimal(
+ &PyDecimal_DecimalType, b, self, 1);
+ if (dec_b == NULL) {
+ Py_DECREF(dec_a);
+ return NULL;
+ }
+
+ dec_c = (decimalobject *)_convert_to_decimal(
+ &PyDecimal_DecimalType, c, self, 1);
+ if (dec_c == NULL) {
+ Py_DECREF(dec_a);
+ Py_DECREF(dec_b);
+ return NULL;
+ }
+ res = _do_decimal_power(dec_a, dec_b, dec_c, self);
+ Py_DECREF(dec_a);
+ Py_DECREF(dec_b);
+ Py_DECREF(dec_c);
+ return res;
+}
+
+
+static PyObject *
+context_quantize(contextobject *self, PyObject *args)
+{
+ PyObject *a, *b;
+ decimalobject *dec_a = NULL, *dec_b = NULL, *res;
+ if (!PyArg_ParseTuple(args, "OO:quantize", &a, &b))
+ return NULL;
+
+ dec_a = (decimalobject *)_convert_to_decimal(
+ &PyDecimal_DecimalType, a, self, 1);
+ if (dec_a == NULL)
+ return NULL;
+
+ dec_b = (decimalobject *)_convert_to_decimal(
+ &PyDecimal_DecimalType, b, self, 1);
+ if (dec_b == NULL) {
+ Py_DECREF(dec_a);
+ return NULL;
+ }
+
+ res = _do_decimal_quantize(dec_a, dec_b, self, -1, 1);
+ Py_DECREF(dec_a);
+ Py_DECREF(dec_b);
+ return res;
+}
+
+
+static PyObject *
+context_same_quantum(contextobject *self, PyObject *args)
+{
+ PyObject *a, *b, *res;
+ decimalobject *dec_a = NULL, *dec_b = NULL;
+ if (!PyArg_ParseTuple(args, "OO:same_quantum", &a, &b))
+ return NULL;
+
+ dec_a = (decimalobject *)_convert_to_decimal(
+ &PyDecimal_DecimalType, a, self, 1);
+ if (dec_a == NULL)
+ return NULL;
+
+ dec_b = (decimalobject *)_convert_to_decimal(
+ &PyDecimal_DecimalType, b, self, 1);
+ if (dec_b == NULL) {
+ Py_DECREF(dec_a);
+ return NULL;
+ }
+
+ res = _do_decimal_same_quantum(dec_a, dec_b);
+ Py_DECREF(dec_a);
+ Py_DECREF(dec_b);
+ return res;
+}
+
+
+static PyObject *
+context_to_integral(contextobject *self, PyObject *args)
+{
+ PyObject *a, *res;
+ decimalobject *dec_a = NULL;
+
+ if (!PyArg_ParseTuple(args, "O:to_integral", &a))
+ return NULL;
+
+ dec_a = (decimalobject *)_convert_to_decimal(
+ &PyDecimal_DecimalType, a, self, 1);
+ if (dec_a == NULL)
+ return NULL;
+
+ res = _do_decimal_to_integral(dec_a, self, -1);
+ Py_DECREF(dec_a);
+ return res;
+}
+
+
+static PyObject *
+context_to_sci_string(contextobject *self, PyObject *args)
+{
+ PyObject *a, *res;
+ decimalobject *dec_a = NULL;
+
+ if (!PyArg_ParseTuple(args, "O:to_sci_string", &a))
+ return NULL;
+
+ dec_a = (decimalobject *)_convert_to_decimal(
+ &PyDecimal_DecimalType, a, self, 1);
+ if (dec_a == NULL)
+ return NULL;
+
+ /* XXX: default third argument? */
+ res = _do_decimal_str(dec_a, self, -1);
+ Py_DECREF(dec_a);
+ return res;
+}
+
+
+static PyObject *
+context_reduce(contextobject *self)
+{
+ PyObject *flags = NULL, *traps = NULL, *ignored = NULL;
+ PyObject *res = NULL;
+
+ flags = context_get_flags(self);
+ if (!flags) goto err;
+ traps = context_get_traps(self);
+ if (!traps) goto err;
+ ignored = context_get_ignored(self);
+ if (!ignored) goto err;
+
+ res = Py_BuildValue("liiOOlliiO", self->prec, self->rounding,
+ self->rounding_dec, traps, flags, self->Emin,
+ self->Emax, self->capitals, self->clamp,
+ ignored);
+
+ err:
+ Py_XDECREF(flags);
+ Py_XDECREF(traps);
+ Py_XDECREF(ignored);
+ return res;
+}
static PyMethodDef context_methods[] = {
@@ -2791,8 +3056,6 @@
c->ob_type->tp_free(c);
}
-CSTUB(richcompare)
-
static PyObject *
context_repr(contextobject *self)
{
@@ -2973,59 +3236,6 @@
ignored);
}
-static PyObject *
-context_get_flags(contextobject *self)
-{
- PyObject *dict = NULL, *val, *dp;
- int i, res;
-
- dict = PyDict_New();
- if (!dict) return NULL;
- for (i = 0; i < NUMSIGNALS; i++) {
- val = PyInt_FromLong(ISFLAGSET(self->flags, i));
- if (!val) goto err;
- res = PyDict_SetItem(dict, errors[i], val);
- Py_DECREF(val);
- if (val < 0) goto err;
- }
- dp = PyDictProxy_New(dict);
- Py_DECREF(dict);
- return dp;
-
- err:
- Py_XDECREF(dict);
- return NULL;
-}
-
-static PyObject *
-context_get_traps(contextobject *self)
-{
- PyObject *dict = NULL, *val, *dp;
- int i, res;
-
- dict = PyDict_New();
- if (!dict) return NULL;
- for (i = 0; i < NUMSIGNALS; i++) {
- val = PyInt_FromLong(ISFLAGSET(self->traps, i));
- if (!val) goto err;
- res = PyDict_SetItem(dict, errors[i], val);
- Py_DECREF(val);
- if (val < 0) goto err;
- }
- dp = PyDictProxy_New(dict);
- Py_DECREF(dict);
- return dp;
-
- err:
- Py_XDECREF(dict);
- return NULL;
-}
-
-static PyGetSetDef context_getset[] = {
- {"flags", (getter)context_get_flags, (setter)0},
- {"traps", (getter)context_get_traps, (setter)0},
- {NULL}
-};
#define OFF(x) offsetof(contextobject, x)
@@ -3066,7 +3276,7 @@
context_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
- (richcmpfunc)context_richcompare, /* tp_richcompare */
+ 0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
@@ -3162,8 +3372,10 @@
return 0;
}
-#define ADD_CONST(m, name) \
- if (PyModule_AddIntConstant(m, #name, name) < 0) { return; }
+#define ADD_CONST(m, name) \
+ if (PyModule_AddIntConstant(m, #name, name) < 0) { \
+ return; \
+ }
#define INIT_EXC(m, name, base) \
name = PyErr_NewException(MODULE_NAME "." #name, base, NULL); \
More information about the Python-checkins
mailing list