Add coercions.
authorjbj <devnull@localhost>
Tue, 10 Dec 2002 16:31:39 +0000 (16:31 +0000)
committerjbj <devnull@localhost>
Tue, 10 Dec 2002 16:31:39 +0000 (16:31 +0000)
CVS patchset: 5928
CVS date: 2002/12/10 16:31:39

python/rpmbc-py.c
python/rpmmodule.c
python/rpmrc-py.c

index 2a3a5d7..4b4c613 100644 (file)
 
 #include "rpmbc-py.h"
 
+#if Py_TPFLAGS_HAVE_ITER        /* XXX backport to python-1.5.2 */
+/*@unchecked@*/
+extern PyTypeObject PyCode_Type;
+/*@unchecked@*/
+extern PyTypeObject PyDictIter_Type;
+/*@unchecked@*/
+extern PyTypeObject PyFrame_Type;
+
+#include <rpmcli.h>    /* XXX debug only */
+
+#include "header-py.h"  /* XXX debug only */
+#include "rpmal-py.h"   /* XXX debug only */
+#include "rpmds-py.h"   /* XXX debug only */
+#include "rpmfd-py.h"   /* XXX debug only */
+#include "rpmfi-py.h"   /* XXX debug only */
+#include "rpmmi-py.h"   /* XXX debug only */
+#include "rpmrc-py.h"   /* XXX debug only */
+#include "rpmte-py.h"   /* XXX debug only */
+#include "rpmts-py.h"   /* XXX debug only */
+#endif
+
 #include "debug.h"
 
-static int _rpmbc_debug = 1;
+/*@unchecked@*/
+static int _bc_debug = 1;
 
-/** \ingroup python
- */    
-static PyObject * 
-rpmbc_Debug(/*@unused@*/ rpmbcObject * s, PyObject * args)
-        /*@globals _Py_NoneStruct @*/
-        /*@modifies _Py_NoneStruct @*/ 
-{
-    if (!PyArg_ParseTuple(args, "i:Debug", &_rpmbc_debug)) return NULL;
-if (_rpmbc_debug < 0) 
-fprintf(stderr, "*** rpmbc_Debug(%p)\n", s);
-    Py_INCREF(Py_None);
-    return Py_None;
-}
+#define is_rpmbc(o)    ((o)->ob_type == &rpmbc_Type)
 
-/*@-fullinitblock@*/
-/*@unchecked@*/ /*@observer@*/
-static struct PyMethodDef rpmbc_methods[] = {
- {"Debug",     (PyCFunction)rpmbc_Debug,       METH_VARARGS,
-       NULL},
- {NULL,                NULL}           /* sentinel */
-};
-/*@=fullinitblock@*/
+/**
+ */
+static const char * lbl(void * s)
+       /*@*/
+{
+    PyObject * o = s;
+
+    if (o == NULL)     return "null";
+
+    if (o->ob_type == &PyType_Type)    return o->ob_type->tp_name;
+
+    if (o->ob_type == &PyBuffer_Type)  return "Buffer";
+    if (o->ob_type == &PyCFunction_Type)       return "CFunction";
+    if (o->ob_type == &PyCObject_Type) return "CObject";
+    if (o->ob_type == &PyCell_Type)    return "Cell";
+    if (o->ob_type == &PyClass_Type)   return "Class";
+    if (o->ob_type == &PyCode_Type)    return "Code";
+    if (o->ob_type == &PyComplex_Type) return "Complex";
+    if (o->ob_type == &PyDict_Type)    return "Dict";
+    if (o->ob_type == &PyDictIter_Type)        return "DictIter";
+    if (o->ob_type == &PyFile_Type)    return "File";
+    if (o->ob_type == &PyFloat_Type)   return "Float";
+    if (o->ob_type == &PyFrame_Type)   return "Frame";
+    if (o->ob_type == &PyFunction_Type)        return "Function";
+    if (o->ob_type == &PyInstance_Type)        return "Instance";
+    if (o->ob_type == &PyInt_Type)     return "Int";
+    if (o->ob_type == &PyList_Type)    return "List";
+    if (o->ob_type == &PyLong_Type)    return "Long";
+    if (o->ob_type == &PyMethod_Type)  return "Method";
+    if (o->ob_type == &PyModule_Type)  return "Module";
+    if (o->ob_type == &PyRange_Type)   return "Range";
+    if (o->ob_type == &PySeqIter_Type) return "SeqIter";
+    if (o->ob_type == &PySlice_Type)   return "Slice";
+    if (o->ob_type == &PyString_Type)  return "String";
+    if (o->ob_type == &PyTuple_Type)   return "Tuple";
+    if (o->ob_type == &PyType_Type)    return "Type";
+    if (o->ob_type == &PyUnicode_Type) return "Unicode";
+
+    if (o->ob_type == &hdr_Type)       return "hdr";
+    if (o->ob_type == &rpmal_Type)     return "rpmal";
+    if (o->ob_type == &rpmbc_Type)     return "rpmbc";
+    if (o->ob_type == &rpmds_Type)     return "rpmds";
+    if (o->ob_type == &rpmfd_Type)     return "rpmfd";
+    if (o->ob_type == &rpmfi_Type)     return "rpmfi";
+    if (o->ob_type == &rpmmi_Type)     return "rpmmi";
+    if (o->ob_type == &rpmrc_Type)     return "rpmrc";
+    if (o->ob_type == &rpmte_Type)     return "rpmte";
+    if (o->ob_type == &rpmts_Type)     return "rpmts";
+
+    return "Unknown";
+}
 
 /* ---------- */
 
-static rpmbcObject *
-rpmbc_new(void)
-{
-    rpmbcObject * s = PyObject_New(rpmbcObject, &rpmbc_Type);
-    if (s)
-       mp32nzero(&s->n);
-    return s;
-}
-
 static void
 rpmbc_dealloc(rpmbcObject * s)
        /*@modifies s @*/
 {
-if (_rpmbc_debug)
+if (_bc_debug < 0)
 fprintf(stderr, "*** rpmbc_dealloc(%p)\n", s);
 
     mp32nfree(&s->n);
@@ -68,24 +110,17 @@ rpmbc_print(rpmbcObject * s, FILE * fp, /*@unused@*/ int flags)
        /*@globals fileSystem @*/
        /*@modifies s, fp, fileSystem @*/
 {
-if (_rpmbc_debug)
+if (_bc_debug < 0)
 fprintf(stderr, "*** rpmbc_print(%p)\n", s);
     mp32print(fp, s->n.size, s->n.data);
     return 0;
 }
 
-static PyObject *
-rpmbc_getattr(rpmbcObject * s, char * name)
-       /*@*/
-{
-    return Py_FindMethod(rpmbc_methods, (PyObject *)s, name);
-}
-
 static int
 rpmbc_compare(rpmbcObject * a, rpmbcObject * b)
        /*@*/
 {
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_compare(%p,%p)\n", a, b);
     return 0;
 }
@@ -94,11 +129,230 @@ static PyObject *
 rpmbc_repr(rpmbcObject * a)
        /*@*/
 {
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_repr(%p)\n", a);
     return NULL;
 }
 
+/** \ingroup python
+ */
+static int rpmbc_init(rpmbcObject * s, PyObject *args, PyObject *kwds)
+       /*@*/
+{
+    PyObject * o = NULL;
+    uint32 words = 0;
+    long l = 0;
+
+if (_bc_debug)
+fprintf(stderr, "*** rpmbc_init(%p[%s],%p[%s],%p[%s])\n", s, lbl(s), args, lbl(args), kwds, lbl(kwds));
+
+    if (!PyArg_ParseTuple(args, "|O:Cvt", &o)) return -1;
+
+    if (o == NULL) {
+       if (s->n.data == NULL)
+           mp32nsetw(&s->n, 0);
+    } else if (PyInt_Check(o)) {
+       l = PyInt_AsLong(o);
+       words = sizeof(l)/sizeof(words);
+    } else if (PyLong_Check(o)) {
+       l = PyLong_AsLong(o);
+       words = sizeof(l)/sizeof(words);
+    } else if (PyFloat_Check(o)) {
+       double d = PyFloat_AsDouble(o);
+       /* XXX TODO: check for overflow/underflow. */
+       l = (long) (d + 0.5);
+       words = sizeof(l)/sizeof(words);
+    } else if (PyString_Check(o)) {
+       const unsigned char * hex = PyString_AsString(o);
+       /* XXX TODO: check for hex. */
+       mp32nsethex(&s->n, hex);
+    } else {
+       PyErr_SetString(PyExc_TypeError, "non-numeric coercion failed (rpmbc_init)");
+       return -1;
+    }
+
+    if (words > 0) {
+       mp32nsize(&s->n, words);
+       switch (words) {
+       case 2:
+           s->n.data[0] = (l >> 32) & 0xffffffff;
+           s->n.data[1] = (l      ) & 0xffffffff;
+           break;
+       case 1:
+           s->n.data[0] = (l      ) & 0xffffffff;
+           break;
+       }
+    }
+
+    return 0;
+}
+
+/** \ingroup python
+ */
+static void rpmbc_free(rpmbcObject * s)
+       /*@*/
+{
+if (_bc_debug)
+fprintf(stderr, "*** rpmbc_free(%p[%s])\n", s, lbl(s));
+    mp32nfree(&s->n);
+   _PyObject_GC_Del((PyObject *)s);
+}
+
+/** \ingroup python
+ */
+static PyObject * rpmbc_alloc(PyTypeObject * subtype, int nitems)
+       /*@*/
+{
+    PyObject * ns = PyType_GenericAlloc(subtype, nitems);
+
+if (_bc_debug)
+fprintf(stderr, "*** rpmbc_alloc(%p[%s},%d) ret %p[%s]\n", subtype, lbl(subtype), nitems, ns, lbl(ns));
+    return (PyObject *) ns;
+}
+
+static PyObject *
+rpmbc_new(PyTypeObject * subtype, PyObject *args, PyObject *kwds)
+       /*@*/
+{
+    PyObject * ns = (PyObject *) PyObject_New(rpmbcObject, &rpmbc_Type);
+
+    mp32nzero(&((rpmbcObject *)ns)->n);
+
+if (_bc_debug)
+fprintf(stderr, "*** rpmbc_new(%p[%s],%p[%s],%p[%s]) ret %p[%s]\n", subtype, lbl(subtype), args, lbl(args), kwds, lbl(kwds), ns, lbl(ns));
+    return ns;
+}
+
+static rpmbcObject *
+rpmbc_New(void)
+{
+    rpmbcObject * ns = PyObject_New(rpmbcObject, &rpmbc_Type);
+
+    mp32nzero(&ns->n);
+    return ns;
+}
+
+static rpmbcObject *
+rpmbc_i2bc(PyObject * o)
+{
+    if (is_rpmbc(o)) {
+       Py_INCREF(o);
+       return (rpmbcObject *)o;
+    }
+    if (PyInt_Check(o) || PyLong_Check(o)) {
+       rpmbcObject * ns = PyObject_New(rpmbcObject, &rpmbc_Type);
+       PyObject * args = PyTuple_New(1);
+
+       mp32nzero(&((rpmbcObject *)ns)->n);
+       (void) PyTuple_SetItem(args, 0, o);
+       rpmbc_init(ns, args, NULL);
+       Py_DECREF(args);
+       return ns;
+    }
+
+    PyErr_SetString(PyExc_TypeError, "number coercion (to rpmbcObject) failed");
+    return NULL;
+}
+
+/* ---------- */
+
+/** \ingroup python
+ */    
+static PyObject * 
+rpmbc_Debug(/*@unused@*/ rpmbcObject * s, PyObject * args)
+        /*@globals _Py_NoneStruct @*/
+        /*@modifies _Py_NoneStruct @*/ 
+{
+    if (!PyArg_ParseTuple(args, "i:Debug", &_bc_debug)) return NULL;
+if (_bc_debug < 0) 
+fprintf(stderr, "*** rpmbc_Debug(%p)\n", s);
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+/** \ingroup python
+ */    
+static PyObject * 
+rpmbc_Gcd(/*@unused@*/ rpmbcObject * s, PyObject * args)
+        /*@globals _Py_NoneStruct @*/
+        /*@modifies _Py_NoneStruct @*/ 
+{
+    PyObject * op1;
+    PyObject * op2;
+    rpmbcObject * a = NULL;
+    rpmbcObject * b = NULL;
+    rpmbcObject * z = NULL;
+    uint32 * wksp = NULL;
+
+if (_bc_debug < 0) 
+fprintf(stderr, "*** rpmbc_Gcd(%p)\n", s);
+    if (!PyArg_ParseTuple(args, "OO:Gcd", &op1, &op2)) return NULL;
+
+    if ((a = rpmbc_i2bc(op1)) != NULL
+     && (b = rpmbc_i2bc(op2)) != NULL
+     && (wksp = malloc(a->n.size)) != NULL
+     && (z = rpmbc_New()) != NULL) {
+       mp32nsize(&z->n, a->n.size);
+       mp32gcd_w(a->n.size, a->n.data, b->n.data, z->n.data, wksp);
+    }
+
+    if (wksp != NULL) free(wksp);
+    Py_DECREF(a);
+    Py_DECREF(b);
+
+    return (PyObject *)z;
+}
+
+/** \ingroup python
+ */    
+static PyObject * 
+rpmbc_Sqrt(/*@unused@*/ rpmbcObject * s, PyObject * args)
+        /*@globals _Py_NoneStruct @*/
+        /*@modifies _Py_NoneStruct @*/ 
+{
+    PyObject * op1;
+    rpmbcObject * a = NULL;
+    rpmbcObject * z = NULL;
+
+if (_bc_debug < 0) 
+fprintf(stderr, "*** rpmbc_Sqrt(%p)\n", s);
+    if (!PyArg_ParseTuple(args, "O:Sqrt", &op1)) return NULL;
+
+    if ((a = rpmbc_i2bc(op1)) != NULL
+     && (z = rpmbc_New()) != NULL) {
+       mp32nsize(&z->n, a->n.size);
+       mp32sqr(z->n.data, a->n.size, a->n.data);
+    }
+
+    Py_DECREF(a);
+
+    return (PyObject *)z;
+}
+
+/*@-fullinitblock@*/
+/*@unchecked@*/ /*@observer@*/
+static struct PyMethodDef rpmbc_methods[] = {
+ {"Debug",     (PyCFunction)rpmbc_Debug,       METH_VARARGS,
+       NULL},
+ {"gcd",       (PyCFunction)rpmbc_Gcd,         METH_VARARGS,
+       NULL},
+ {"sqrt",      (PyCFunction)rpmbc_Sqrt,        METH_VARARGS,
+       NULL},
+ {NULL,                NULL}           /* sentinel */
+};
+/*@=fullinitblock@*/
+
+static PyObject *
+rpmbc_getattr(PyObject * s, char * name)
+       /*@*/
+{
+    return Py_FindMethod(rpmbc_methods, s, name);
+}
+
 /* ---------- */
 
 static PyObject *
@@ -108,10 +362,10 @@ rpmbc_add(rpmbcObject * a, rpmbcObject * b)
     rpmbcObject * z;
     uint32 carry;
 
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_add(%p,%p)\n", a, b);
 
-    if ((z = rpmbc_new()) != NULL) {
+    if ((z = rpmbc_New()) != NULL) {
        mp32ninit(&z->n, a->n.size, a->n.data);
        carry = mp32addx(z->n.size, z->n.data, b->n.size, b->n.data);
     }
@@ -125,10 +379,10 @@ rpmbc_subtract(rpmbcObject * a, rpmbcObject * b)
     rpmbcObject * z;
     uint32 carry;
 
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_subtract(%p,%p)\n", a, b);
 
-    if ((z = rpmbc_new()) != NULL) {
+    if ((z = rpmbc_New()) != NULL) {
        mp32ninit(&z->n, a->n.size, a->n.data);
        carry = mp32subx(z->n.size, z->n.data, b->n.size, b->n.data);
     }
@@ -141,10 +395,11 @@ rpmbc_multiply(rpmbcObject * a, rpmbcObject * b)
 {
     rpmbcObject * z;
 
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_multiply(%p,%p)\n", a, b);
 
-    if ((z = rpmbc_new()) != NULL) {
+    if ((z = rpmbc_New()) != NULL) {
+       /* XXX TODO: calculate zsize of result. */
        mp32nsize(&z->n, (a->n.size + b->n.size));
        mp32mul(z->n.data, a->n.size, a->n.data, b->n.size, b->n.data);
     }
@@ -158,7 +413,7 @@ rpmbc_divide(rpmbcObject * a, rpmbcObject * b)
     rpmbcObject * z = NULL;
     uint32 * wksp;
 
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_divide(%p,%p)\n", a, b);
 
     if (mp32z(b->n.size, b->n.data)) {
@@ -166,13 +421,13 @@ fprintf(stderr, "*** rpmbc_divide(%p,%p)\n", a, b);
        return NULL;
     }
 
-    if ((z = rpmbc_new()) == NULL
+    if ((z = rpmbc_New()) == NULL
      || (wksp = malloc(b->n.size+1)) == NULL) {
        Py_XDECREF(z);
        return NULL;
     }
 
-    mp32nsize(&z->n, a->n.size+1);
+    mp32nsize(&z->n, a->n.size);
     mp32ndivmod(z->n.data, a->n.size, a->n.data, b->n.size, b->n.data, wksp);
 
     return (PyObject *)z;
@@ -184,10 +439,10 @@ rpmbc_remainder(rpmbcObject * a, rpmbcObject * b)
 {
     rpmbcObject * z;
 
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_remainder(%p,%p)\n", a, b);
 
-    if ((z = rpmbc_new()) != NULL) {
+    if ((z = rpmbc_New()) != NULL) {
        uint32 * wksp = malloc(a->n.size+1);
        mp32nsize(&z->n, a->n.size);
        mp32nmod(z->n.data, a->n.size, a->n.data, b->n.size, b->n.data, wksp);
@@ -201,10 +456,10 @@ rpmbc_divmod(rpmbcObject * a, rpmbcObject * b)
        /*@*/
 {
     PyObject * z = NULL;
-    rpmbcObject * d = NULL;
+    rpmbcObject * q = NULL;
     rpmbcObject * r = NULL;
 
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_divmod(%p,%p)\n", a, b);
 
     if (mp32z(b->n.size, b->n.data)) {
@@ -213,20 +468,20 @@ fprintf(stderr, "*** rpmbc_divmod(%p,%p)\n", a, b);
     }
 
     if ((z = PyTuple_New(2)) == NULL
-     || (d = rpmbc_new()) == NULL
-     || (r = rpmbc_new()) == NULL) {
+     || (q = rpmbc_New()) == NULL
+     || (r = rpmbc_New()) == NULL) {
        Py_XDECREF(z);
-       Py_XDECREF(d);
+       Py_XDECREF(q);
        Py_XDECREF(r);
        return NULL;
     }
 
-    mp32nsize(&d->n, a->n.size+1);
+    mp32nsize(&q->n, a->n.size+1);
     mp32nsize(&r->n, b->n.size+1);
 
-    mp32ndivmod(d->n.data, a->n.size, a->n.data, b->n.size, b->n.data, r->n.data);
+    mp32ndivmod(q->n.data, a->n.size, a->n.data, b->n.size, b->n.data, r->n.data);
 
-    (void) PyTuple_SetItem(z, 0, (PyObject *)d);
+    (void) PyTuple_SetItem(z, 0, (PyObject *)q);
     (void) PyTuple_SetItem(z, 1, (PyObject *)r);
     return (PyObject *)z;
 }
@@ -235,7 +490,7 @@ static PyObject *
 rpmbc_power(rpmbcObject * a, rpmbcObject * b, rpmbcObject * c)
        /*@*/
 {
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_power(%p,%p,%p)\n", a, b, c);
     return NULL;
 }
@@ -246,10 +501,10 @@ rpmbc_negative(rpmbcObject * a)
 {
     rpmbcObject * z;
 
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_negative(%p)\n", a);
 
-    if ((z = rpmbc_new()) != NULL) {
+    if ((z = rpmbc_New()) != NULL) {
        mp32ninit(&z->n, a->n.size, a->n.data);
        mp32neg(z->n.size, z->n.data);
     }
@@ -260,7 +515,7 @@ static PyObject *
 rpmbc_positive(rpmbcObject * a)
        /*@*/
 {
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_positive(%p)\n", a);
 
     Py_INCREF(a);
@@ -273,7 +528,7 @@ rpmbc_absolute(rpmbcObject * a)
 {
     rpmbcObject * z;
 
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_absolute(%p)\n", a);
 
     if (mp32msbset(a->n.size, a->n.data) == 0) {
@@ -281,7 +536,7 @@ fprintf(stderr, "*** rpmbc_absolute(%p)\n", a);
        return (PyObject *)a;
     }
 
-    if ((z = rpmbc_new()) != NULL) {
+    if ((z = rpmbc_New()) != NULL) {
        mp32ninit(&z->n, a->n.size, a->n.data);
        mp32neg(z->n.size, z->n.data);
     }
@@ -292,7 +547,7 @@ static int
 rpmbc_nonzero(rpmbcObject * a)
        /*@*/
 {
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_nonzero(%p)\n", a);
     return mp32nz(a->n.size, a->n.data);
 }
@@ -301,7 +556,7 @@ static PyObject *
 rpmbc_invert(rpmbcObject * a)
        /*@*/
 {
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_invert(%p)\n", a);
     return NULL;
 }
@@ -312,7 +567,7 @@ rpmbc_lshift(rpmbcObject * a, rpmbcObject * b)
 {
     uint32 count = 0;
 
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_lshift(%p,%p)\n", a, b);
 
     mp32lshift(a->n.size, a->n.data, count);
@@ -326,7 +581,7 @@ rpmbc_rshift(rpmbcObject * a, rpmbcObject * b)
 {
     uint32 count = 0;
 
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_rshift(%p,%p)\n", a, b);
 
     mp32rshift(a->n.size, a->n.data, count);
@@ -338,7 +593,7 @@ static PyObject *
 rpmbc_and(rpmbcObject * a, rpmbcObject * b)
        /*@*/
 {
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_and(%p,%p)\n", a, b);
     return NULL;
 }
@@ -347,7 +602,7 @@ static PyObject *
 rpmbc_xor(rpmbcObject * a, rpmbcObject * b)
        /*@*/
 {
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_xor(%p,%p)\n", a, b);
     return NULL;
 }
@@ -356,48 +611,90 @@ static PyObject *
 rpmbc_or(rpmbcObject * a, rpmbcObject * b)
        /*@*/
 {
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_or(%p,%p)\n", a, b);
     return NULL;
 }
 
 static int
-rpmbc_coerce(PyObject ** ap, PyObject ** bp)
-       /*@*/
-{
-if (_rpmbc_debug)
-fprintf(stderr, "*** rpmbc_coerce(%p,%p)\n", ap, bp);
-    return -1;
+rpmbc_coerce(PyObject ** pv, PyObject ** pw)
+       /*@*/
+{
+    uint32 words = 0;
+    long l = 0;
+
+if (_bc_debug)
+fprintf(stderr, "*** rpmbc_coerce(%p[%s],%p[%s])\n", pv, lbl(*pv), pw, lbl(*pw));
+
+    if (is_rpmbc(*pw)) {
+       Py_INCREF(*pw);
+    } else if (PyInt_Check(*pw)) {
+       l = PyInt_AsLong(*pw);
+       words = sizeof(l)/sizeof(words);
+    } else if (PyLong_Check(*pw)) {
+       l = PyLong_AsLong(*pw);
+       words = sizeof(l)/sizeof(words);
+    } else if (PyFloat_Check(*pw)) {
+       double d = PyFloat_AsDouble(*pw);
+       /* XXX TODO: check for overflow/underflow. */
+       l = (long) (d + 0.5);
+       words = sizeof(l)/sizeof(words);
+    } else {
+       PyErr_SetString(PyExc_TypeError, "non-numeric coercion failed (rpmbc_coerce)");
+       return 1;
+    }
+
+    if (words > 0) {
+       rpmbcObject * z = rpmbc_New();
+       mp32nsize(&z->n, words);
+       switch (words) {
+       case 2:
+           z->n.data[0] = (l >> 32) & 0xffffffff;
+           z->n.data[1] = (l      ) & 0xffffffff;
+           break;
+       case 1:
+           z->n.data[0] = (l      ) & 0xffffffff;
+           break;
+       }
+       (*pw) = (PyObject *) z;
+    }
+
+    Py_INCREF(*pv);
+    return 0;
 }
 
 static PyObject *
 rpmbc_int(rpmbcObject * a)
        /*@*/
 {
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_int(%p)\n", a);
 
     if (mp32size(a->n.size, a->n.data) > 1) {
-       PyErr_SetString(PyExc_ValueError, "rpmbc_int() arg too long to convert");
+       PyErr_SetString(PyExc_ValueError, "rpmbc_int: arg too long to convert");
        return NULL;
     }
-    return NULL;
+    return Py_BuildValue("i", (a->n.data ? a->n.data[0] : 0));
 }
 
 static PyObject *
 rpmbc_long(rpmbcObject * a)
        /*@*/
 {
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_long(%p)\n", a);
-    return NULL;
+    if (mp32size(a->n.size, a->n.data) > 1) {
+       PyErr_SetString(PyExc_ValueError, "rpmbc_int() arg too long to convert");
+       return NULL;
+    }
+    return Py_BuildValue("l", (a->n.data ? a->n.data[0] : 0));
 }
 
 static PyObject *
 rpmbc_float(rpmbcObject * a)
        /*@*/
 {
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_float(%p)\n", a);
     return NULL;
 }
@@ -406,7 +703,7 @@ static PyObject *
 rpmbc_oct(rpmbcObject * a)
        /*@*/
 {
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_oct(%p)\n", a);
     return NULL;
 }
@@ -415,7 +712,7 @@ static PyObject *
 rpmbc_hex(rpmbcObject * a)
        /*@*/
 {
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_hex(%p)\n", a);
     return NULL;
 }
@@ -426,7 +723,7 @@ rpmbc_inplace_add(rpmbcObject * a, rpmbcObject * b)
 {
     uint32 carry;
 
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_inplace_add(%p,%p)\n", a, b);
 
     carry = mp32addx(a->n.size, a->n.data, b->n.size, b->n.data);
@@ -440,7 +737,7 @@ rpmbc_inplace_subtract(rpmbcObject * a, rpmbcObject * b)
 {
     uint32 carry;
 
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_inplace_subtract(%p,%p)\n", a, b);
 
     carry = mp32subx(a->n.size, a->n.data, b->n.size, b->n.data);
@@ -454,7 +751,7 @@ rpmbc_inplace_multiply(rpmbcObject * a, rpmbcObject * b)
 {
     uint32 * result = NULL;
 
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_inplace_multiply(%p,%p)\n", a, b);
 
     mp32mul(result, a->n.size, a->n.data, b->n.size, b->n.data);
@@ -466,7 +763,7 @@ static PyObject *
 rpmbc_inplace_divide(rpmbcObject * a, rpmbcObject * b)
        /*@*/
 {
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_inplace_divide(%p,%p)\n", a, b);
     return NULL;
 }
@@ -475,7 +772,7 @@ static PyObject *
 rpmbc_inplace_remainder(rpmbcObject * a, rpmbcObject * b)
        /*@*/
 {
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_inplace_remainder(%p,%p)\n", a, b);
     return NULL;
 }
@@ -484,7 +781,7 @@ static PyObject *
 rpmbc_inplace_power(rpmbcObject * a, rpmbcObject * b, rpmbcObject * c)
        /*@*/
 {
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_inplace_power(%p,%p,%p)\n", a, b, c);
     return NULL;
 }
@@ -495,7 +792,7 @@ rpmbc_inplace_lshift(rpmbcObject * a, rpmbcObject * b)
 {
     uint32 count = 0;
 
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_inplace_lshift(%p,%p)\n", a, b);
 
     mp32lshift(a->n.size, a->n.data, count);
@@ -509,7 +806,7 @@ rpmbc_inplace_rshift(rpmbcObject * a, rpmbcObject * b)
 {
     uint32 count = 0;
 
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_inplace_rshift(%p,%p)\n", a, b);
 
     mp32rshift(a->n.size, a->n.data, count);
@@ -521,7 +818,7 @@ static PyObject *
 rpmbc_inplace_and(rpmbcObject * a, rpmbcObject * b)
        /*@*/
 {
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_inplace_and(%p,%p)\n", a, b);
     return NULL;
 }
@@ -529,7 +826,7 @@ fprintf(stderr, "*** rpmbc_inplace_and(%p,%p)\n", a, b);
 static PyObject *
 rpmbc_inplace_xor(rpmbcObject * a, rpmbcObject * b)
 {
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_inplace_xor(%p,%p)\n", a, b);
     return NULL;
 }
@@ -538,7 +835,7 @@ static PyObject *
 rpmbc_inplace_or(rpmbcObject * a, rpmbcObject * b)
        /*@*/
 {
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_inplace_or(%p,%p)\n", a, b);
     return NULL;
 }
@@ -547,7 +844,7 @@ static PyObject *
 rpmbc_floor_divide(rpmbcObject * a, rpmbcObject * b)
        /*@*/
 {
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_floor_divide(%p,%p)\n", a, b);
     return NULL;
 }
@@ -556,7 +853,7 @@ static PyObject *
 rpmbc_true_divide(rpmbcObject * a, rpmbcObject * b)
        /*@*/
 {
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_true_divide(%p,%p)\n", a, b);
     return NULL;
 }
@@ -565,7 +862,7 @@ static PyObject *
 rpmbc_inplace_floor_divide(rpmbcObject * a, rpmbcObject * b)
        /*@*/
 {
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_inplace_floor_divide(%p,%p)\n", a, b);
     return NULL;
 }
@@ -574,7 +871,7 @@ static PyObject *
 rpmbc_inplace_true_divide(rpmbcObject * a, rpmbcObject * b)
        /*@*/
 {
-if (_rpmbc_debug)
+if (_bc_debug)
 fprintf(stderr, "*** rpmbc_inplace_true_divide(%p,%p)\n", a, b);
     return NULL;
 }
@@ -628,39 +925,6 @@ static PyNumberMethods rpmbc_as_number = {
 
 /* ---------- */
 
-#ifdef NOTYET
-static int
-rpmbc_length(rpmbcObject * s)
-       /*@*/
-{
-    return rpmbcCount(s->ds);
-}
-
-static PyObject *
-rpmbc_subscript(rpmbcObject * s, PyObject * key)
-       /*@modifies s @*/
-{
-    int ix;
-
-    if (!PyInt_Check(key)) {
-       PyErr_SetString(PyExc_TypeError, "integer expected");
-       return NULL;
-    }
-
-    ix = (int) PyInt_AsLong(key);
-    rpmbcSetIx(s->ds, ix);
-    return Py_BuildValue("s", rpmbcDNEVR(s->ds));
-}
-
-static PyMappingMethods rpmbc_as_mapping = {
-        (inquiry) rpmbc_length,                /* mp_length */
-        (binaryfunc) rpmbc_subscript,  /* mp_subscript */
-        (objobjargproc)0,              /* mp_ass_subscript */
-};
-#endif
-
-/* ---------- */
-
 /**
  */
 /*@unchecked@*/ /*@observer@*/
@@ -707,10 +971,10 @@ PyTypeObject rpmbc_Type = {
        0,                              /* tp_descr_get */
        0,                              /* tp_descr_set */
        0,                              /* tp_dictoffset */
-       0,                              /* tp_init */
-       0,                              /* tp_alloc */
-       0,                              /* tp_new */
-       0,                              /* tp_free */
+       (initproc) rpmbc_init,          /* tp_init */
+       (allocfunc) rpmbc_alloc,        /* tp_alloc */
+       (newfunc) rpmbc_new,            /* tp_new */
+       (destructor) rpmbc_free,        /* tp_free */
        0,                              /* tp_is_gc */
 #endif
 };
index cdadbbf..6de56b2 100644 (file)
@@ -344,6 +344,7 @@ void initrpm(void)
 #if Py_TPFLAGS_HAVE_ITER        /* XXX backport to python-1.5.2 */
     if (PyType_Ready(&hdr_Type) < 0) return;
     if (PyType_Ready(&rpmal_Type) < 0) return;
+    if (PyType_Ready(&rpmbc_Type) < 0) return;
     if (PyType_Ready(&rpmds_Type) < 0) return;
     if (PyType_Ready(&rpmfd_Type) < 0) return;
     if (PyType_Ready(&rpmfi_Type) < 0) return;
index 285acad..4899260 100644 (file)
@@ -80,7 +80,6 @@ PyObject * rpmrc_DelMacro(/*@unused@*/ PyObject * self, PyObject * args)
 #if Py_TPFLAGS_HAVE_ITER       /* XXX backport to python-1.5.2 */
 /**
  */
-
 static const char * lbl(void * s)
        /*@*/
 {