#define is_rpmbc(o) ((o)->ob_type == &rpmbc_Type)
+#ifdef NOTYET
+static const char initialiser_name[] = "rpmbc";
+
+static PyObject *
+rpmbc_format(rpmbcObject * s, int base, unsigned char withname)
+{
+ PyStringObject * so;
+ size_t i;
+ int cmpres;
+ int taglong;
+ char *cp;
+ char prefix[5];
+
+ char * tcp = &prefix[0];
+
+ if (s == NULL || !is_rpmbc(s)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+
+ assert(base >= 2 && base <= 36);
+
+ if (withname)
+ i = strlen(initialiser_name) + 2; /* e.g. 'rpmbc(' + ')' */
+ else
+ i = 0;
+
+ if (mp32z(s->n.size, s->n.data))
+ base = 10; /* '0' in every base, right */
+ else if (mp32msbset(s->n.size, s->n.data)) {
+ *tcp++ = '-';
+ i += 1; /* space to hold '-' */
+ }
+
+ i += (int)mpz_sizeinbase(&s->mpz, base);
+
+ if (base == 16) {
+ *tcp++ = '0';
+ *tcp++ = 'x';
+ i += 2; /* space to hold '0x' */
+ } else if (base == 8) {
+ *tcp++ = '0';
+ i += 1; /* space to hold the extra '0' */
+ } else if (base > 10) {
+ *tcp++ = '0' + base / 10;
+ *tcp++ = '0' + base % 10;
+ *tcp++ = '#';
+ i += 3; /* space to hold e.g. '12#' */
+ } else if (base < 10) {
+ *tcp++ = '0' + base;
+ *tcp++ = '#';
+ i += 2; /* space to hold e.g. '6#' */
+ }
+
+ /*
+ ** the following code looks if we need a 'L' attached to the number
+ ** it will also attach an 'L' to the value -0x80000000
+ */
+ taglong = 0;
+ if (mpz_size(&s->mpz) > 1
+ || (long)mpz_get_ui(&s->mpz) < 0L) {
+ taglong = 1;
+ i += 1; /* space to hold 'L' */
+ }
+
+ so = (PyStringObject *)PyString_FromStringAndSize((char *)0, i);
+ if (so == NULL)
+ return NULL;
+
+ /* get the beginning of the string memory and start copying things */
+ cp = PyString_AS_STRING(so);
+ if (withname) {
+ strcpy(cp, initialiser_name);
+ cp += strlen(initialiser_name);
+ *cp++ = '('; /*')'*/
+ }
+
+ /* copy the already prepared prefix; e.g. sign and base indicator */
+ *tcp = '\0';
+ strcpy(cp, prefix);
+ cp += tcp - prefix;
+
+ /* since' we have the sign already, let the lib think it's a positive
+ number */
+ if (cmpres < 0)
+ mpz_neg(&s->mpz,&s->mpz); /* hack Hack HAck HACk HACK */
+ (void)mpz_get_str(cp, base, &s->mpz);
+ if (cmpres < 0)
+ mpz_neg(&s->mpz,&s->mpz); /* hack Hack HAck HACk HACK */
+ cp += strlen(cp);
+
+ if (taglong)
+ *cp++ = 'L';
+ if (withname)
+ *cp++ = /*'('*/ ')';
+
+ *cp = '\0';
+
+ assert(cp - PyString_AS_STRING(so) <= i);
+
+ if (cp - PyString_AS_STRING(so) != i)
+ so->ob_size -= i - (cp - PyString_AS_STRING(so));
+
+ return (PyObject *)so;
+}
+#endif
+
/* ---------- */
static void
/** \ingroup python
*/
-static int rpmbc_init(rpmbcObject * s, PyObject *args, PyObject *kwds)
- /*@modifies s @*/
+static int rpmbc_init(rpmbcObject * z, PyObject *args, PyObject *kwds)
+ /*@modifies z @*/
{
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);
+ if (z->n.data == NULL)
+ mp32nsetw(&z->n, 0);
} else if (PyInt_Check(o)) {
l = PyInt_AsLong(o);
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);
+ mp32nsethex(&z->n, hex);
} else {
PyErr_SetString(PyExc_TypeError, "non-numeric coercion failed (rpmbc_init)");
return -1;
}
if (words > 0) {
- mp32nsize(&s->n, words);
+ mp32nsize(&z->n, words);
switch (words) {
case 2:
/*@-shiftimplementation @*/
- s->n.data[0] = (l >> 32) & 0xffffffff;
+ z->n.data[0] = (l >> 32) & 0xffffffff;
/*@=shiftimplementation @*/
- s->n.data[1] = (l ) & 0xffffffff;
+ z->n.data[1] = (l ) & 0xffffffff;
break;
case 1:
- s->n.data[0] = (l ) & 0xffffffff;
+ z->n.data[0] = (l ) & 0xffffffff;
break;
}
}
+if (_bc_debug)
+fprintf(stderr, "*** rpmbc_init(%p[%s],%p[%s],%p[%s]):\t", z, lbl(z), args, lbl(args), kwds, lbl(kwds)), mp32println(stderr, z->n.size, z->n.data);
+
return 0;
}
if (ns != NULL)
mp32nzero(&((rpmbcObject *)ns)->n);
-if (_bc_debug)
+if (_bc_debug < 0)
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;
}
rpmbcObject * z;
uint32 carry;
-if (_bc_debug)
-fprintf(stderr, "*** rpmbc_add(%p,%p)\n", a, b);
-
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);
}
+
+if (_bc_debug)
+fprintf(stderr, "*** rpmbc_add(%p,%p):\t", a, b), mp32println(stderr, z->n.size, z->n.data);
+
return (PyObject *)z;
}
rpmbcObject * z;
uint32 carry;
-if (_bc_debug)
-fprintf(stderr, "*** rpmbc_subtract(%p,%p)\n", a, b);
-
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);
}
+
+if (_bc_debug)
+fprintf(stderr, "*** rpmbc_subtract(%p,%p):\t", a, b), mp32println(stderr, z->n.size, z->n.data);
+
return (PyObject *)z;
}
{
rpmbcObject * z;
-if (_bc_debug)
-fprintf(stderr, "*** rpmbc_multiply(%p,%p)\n", a, b);
-
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);
}
+
+if (_bc_debug)
+fprintf(stderr, "*** rpmbc_multiply(%p,%p):\t", a, b), mp32println(stderr, z->n.size, z->n.data);
+
return (PyObject *)z;
}
rpmbcObject * z = NULL;
uint32 * wksp;
-if (_bc_debug)
-fprintf(stderr, "*** rpmbc_divide(%p,%p)\n", a, b);
-
if (mp32z(b->n.size, b->n.data)) {
PyErr_SetString(PyExc_ZeroDivisionError, "rpmbc_divide by zero");
return NULL;
mp32nsize(&z->n, a->n.size);
mp32ndivmod(z->n.data, a->n.size, a->n.data, b->n.size, b->n.data, wksp);
+ free(wksp);
+
+if (_bc_debug)
+fprintf(stderr, "*** rpmbc_divide(%p,%p):\t", a, b), mp32println(stderr, z->n.size, z->n.data);
+
return (PyObject *)z;
}
{
rpmbcObject * z;
-if (_bc_debug)
-fprintf(stderr, "*** rpmbc_remainder(%p,%p)\n", a, b);
-
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);
free(wksp);
}
+
+if (_bc_debug)
+fprintf(stderr, "*** rpmbc_remainder(%p,%p):\t", a, b), mp32println(stderr, z->n.size, z->n.data);
+
return (PyObject *)z;
}
{
rpmbcObject * z;
-if (_bc_debug)
-fprintf(stderr, "*** rpmbc_negative(%p)\n", a);
-
if ((z = rpmbc_New()) != NULL) {
mp32ninit(&z->n, a->n.size, a->n.data);
mp32neg(z->n.size, z->n.data);
}
+
+if (_bc_debug)
+fprintf(stderr, "*** rpmbc_negative(%p):\t", a), mp32println(stderr, z->n.size, z->n.data);
+
return (PyObject *)z;
}
rpmbc_positive(rpmbcObject * a)
/*@*/
{
+ Py_INCREF(a);
+
if (_bc_debug)
-fprintf(stderr, "*** rpmbc_positive(%p)\n", a);
+fprintf(stderr, "*** rpmbc_positive(%p):\t", a), mp32println(stderr, a->n.size, a->n.data);
- Py_INCREF(a);
return (PyObject *)a;
}
{
rpmbcObject * z;
-if (_bc_debug)
-fprintf(stderr, "*** rpmbc_absolute(%p)\n", a);
-
if (mp32msbset(a->n.size, a->n.data) == 0) {
Py_INCREF(a);
return (PyObject *)a;
mp32ninit(&z->n, a->n.size, a->n.data);
mp32neg(z->n.size, z->n.data);
}
+
+if (_bc_debug)
+fprintf(stderr, "*** rpmbc_absolute(%p):\t", a), mp32println(stderr, z->n.size, z->n.data);
+
return (PyObject *)z;
}
rpmbc_invert(rpmbcObject * a)
/*@*/
{
+ rpmbcObject * z;
+
+ if ((z = rpmbc_New()) != NULL) {
+ mp32ninit(&z->n, a->n.size, a->n.data);
+ mp32not(z->n.size, z->n.data);
+ }
+
if (_bc_debug)
-fprintf(stderr, "*** rpmbc_invert(%p)\n", a);
- return NULL;
+fprintf(stderr, "*** rpmbc_invert(%p):\t", a), mp32println(stderr, z->n.size, z->n.data);
+
+ return (PyObject *)z;
}
static PyObject *
rpmbcObject * z;
uint32 count = 0;
-if (_bc_debug)
-fprintf(stderr, "*** rpmbc_lshift(%p[%s],%p[%s])\n", a, lbl(a), b, lbl(b));
-
+ /* XXX check shift count in range. */
if ((z = rpmbc_New()) != NULL) {
+ if (b->n.size == 1)
+ count = b->n.data[0];
mp32ninit(&z->n, a->n.size, a->n.data);
mp32lshift(z->n.size, z->n.data, count);
}
+
+if (_bc_debug)
+fprintf(stderr, "*** rpmbc_lshift(%p[%s],%p[%s]):\t", a, lbl(a), b, lbl(b)), mp32println(stderr, z->n.size, z->n.data);
+
return (PyObject *)z;
}
rpmbcObject * z;
uint32 count = 0;
-if (_bc_debug)
-fprintf(stderr, "*** rpmbc_rshift(%p[%s],%p[%s])\n", a, lbl(a), b, lbl(b));
-
+ /* XXX check shift count in range. */
if ((z = rpmbc_New()) != NULL) {
+ if (b->n.size == 1)
+ count = b->n.data[0];
mp32ninit(&z->n, a->n.size, a->n.data);
mp32rshift(z->n.size, z->n.data, count);
}
+
+if (_bc_debug)
+fprintf(stderr, "*** rpmbc_rshift(%p[%s],%p[%s]):\t", a, lbl(a), b, lbl(b)), mp32println(stderr, z->n.size, z->n.data);
+
return (PyObject *)z;
}
rpmbc_and(rpmbcObject * a, rpmbcObject * b)
/*@*/
{
+ rpmbcObject * z;
+
+ if ((z = rpmbc_New()) != NULL) {
+ rpmbcObject * c, * d;
+
+ if (a->n.size <= b->n.size) {
+ c = a;
+ d = b;
+ } else {
+ c = b;
+ d = a;
+ }
+ mp32ninit(&z->n, c->n.size, c->n.data);
+ mp32and(z->n.size, z->n.data, d->n.data + (d->n.size - c->n.size));
+ }
+
if (_bc_debug)
-fprintf(stderr, "*** rpmbc_and(%p,%p)\n", a, b);
- return NULL;
+fprintf(stderr, "*** rpmbc_and(%p,%p):\t", a, b), mp32println(stderr, z->n.size, z->n.data);
+
+ return (PyObject *)z;
}
static PyObject *
rpmbc_xor(rpmbcObject * a, rpmbcObject * b)
/*@*/
{
+ rpmbcObject * z;
+
+ if ((z = rpmbc_New()) != NULL) {
+ rpmbcObject * c, * d;
+
+ if (a->n.size <= b->n.size) {
+ c = a;
+ d = b;
+ } else {
+ c = b;
+ d = a;
+ }
+ mp32ninit(&z->n, c->n.size, c->n.data);
+ mp32xor(z->n.size, z->n.data, d->n.data + (d->n.size - c->n.size));
+ }
+
if (_bc_debug)
-fprintf(stderr, "*** rpmbc_xor(%p,%p)\n", a, b);
- return NULL;
+fprintf(stderr, "*** rpmbc_xor(%p,%p):\t", a, b), mp32println(stderr, z->n.size, z->n.data);
+
+ return (PyObject *)z;
}
static PyObject *
rpmbc_or(rpmbcObject * a, rpmbcObject * b)
/*@*/
{
+ rpmbcObject * z;
+
+ if ((z = rpmbc_New()) != NULL) {
+ rpmbcObject * c, * d;
+
+ if (a->n.size <= b->n.size) {
+ c = a;
+ d = b;
+ } else {
+ c = b;
+ d = a;
+ }
+ mp32ninit(&z->n, c->n.size, c->n.data);
+ mp32or(z->n.size, z->n.data, d->n.data + (d->n.size - c->n.size));
+ }
+
if (_bc_debug)
-fprintf(stderr, "*** rpmbc_or(%p,%p)\n", a, b);
- return NULL;
+fprintf(stderr, "*** rpmbc_or(%p,%p):\t", a, b), mp32println(stderr, z->n.size, z->n.data);
+
+ return (PyObject *)z;
}
static int
rpmbc_int(rpmbcObject * a)
/*@*/
{
-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");
return NULL;
}
+
+if (_bc_debug)
+fprintf(stderr, "*** rpmbc_int(%p):\t%08x\n", a, (int)(a->n.data ? a->n.data[0] : 0));
+
return Py_BuildValue("i", (a->n.data ? a->n.data[0] : 0));
}
rpmbc_long(rpmbcObject * a)
/*@*/
{
-if (_bc_debug)
-fprintf(stderr, "*** rpmbc_long(%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_long() arg too long to convert");
return NULL;
}
+
+if (_bc_debug)
+fprintf(stderr, "*** rpmbc_long(%p):\t%08lx\n", a, (long)(a->n.data ? a->n.data[0] : 0));
+
return Py_BuildValue("l", (a->n.data ? a->n.data[0] : 0));
}
{
uint32 carry;
-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);
- return NULL;
+if (_bc_debug)
+fprintf(stderr, "*** rpmbc_inplace_add(%p,%p):\t", a, b), mp32println(stderr, a->n.size, a->n.data);
+
+ Py_INCREF(a);
+ return (PyObject *)a;
}
static PyObject *
{
uint32 carry;
-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);
- return NULL;
+if (_bc_debug)
+fprintf(stderr, "*** rpmbc_inplace_subtract(%p,%p):\t", a, b), mp32println(stderr, a->n.size, a->n.data);
+
+ Py_INCREF(a);
+ return (PyObject *)a;
}
static PyObject *
rpmbc_inplace_multiply(rpmbcObject * a, rpmbcObject * b)
/*@*/
{
- uint32 * result = NULL;
-
-if (_bc_debug)
-fprintf(stderr, "*** rpmbc_inplace_multiply(%p,%p)\n", a, b);
+ uint32 * result = xmalloc((a->n.size + b->n.size) * sizeof(*result));
mp32mul(result, a->n.size, a->n.data, b->n.size, b->n.data);
- return NULL;
+ free(a->n.data);
+ a->n.size += b->n.size;
+ a->n.data = result;
+
+if (_bc_debug)
+fprintf(stderr, "*** rpmbc_inplace_multiply(%p,%p):\t", a, b), mp32println(stderr, a->n.size, a->n.data);
+
+ Py_INCREF(a);
+ return (PyObject *)a;
}
static PyObject *
rpmbc_inplace_divide(rpmbcObject * a, rpmbcObject * b)
/*@*/
{
+ uint32 * result = xmalloc(a->n.size * sizeof(*result));
+ uint32 * wksp = xmalloc(b->n.size+1);
+
+ mp32ndivmod(result, a->n.size, a->n.data, b->n.size, b->n.data, wksp);
+
+ free(wksp);
+ free(a->n.data);
+ a->n.data = result;
+
if (_bc_debug)
-fprintf(stderr, "*** rpmbc_inplace_divide(%p,%p)\n", a, b);
- return NULL;
+fprintf(stderr, "*** rpmbc_inplace_divide(%p,%p):\t", a, b), mp32println(stderr, a->n.size, a->n.data);
+
+ Py_INCREF(a);
+ return (PyObject *)a;
}
static PyObject *
rpmbc_inplace_remainder(rpmbcObject * a, rpmbcObject * b)
/*@*/
{
+ uint32 * result = xmalloc(a->n.size * sizeof(*result));
+ uint32 * wksp = xmalloc(a->n.size+1);
+
+ mp32nmod(result, a->n.size, a->n.data, b->n.size, b->n.data, wksp);
+
+ free(wksp);
+ free(a->n.data);
+ a->n.data = result;
+
if (_bc_debug)
-fprintf(stderr, "*** rpmbc_inplace_remainder(%p,%p)\n", a, b);
- return NULL;
+fprintf(stderr, "*** rpmbc_inplace_remainder(%p,%p):\t", a, b), mp32println(stderr, a->n.size, a->n.data);
+
+ Py_INCREF(a);
+ return (PyObject *)a;
}
static PyObject *
/*@*/
{
if (_bc_debug)
-fprintf(stderr, "*** rpmbc_inplace_power(%p,%p,%p)\n", a, b, c);
- return NULL;
+fprintf(stderr, "*** rpmbc_inplace_power(%p,%p,%p):\t", a, b, c), mp32println(stderr, a->n.size, a->n.data);
+
+ Py_INCREF(a);
+ return (PyObject *)a;
}
static PyObject *
{
uint32 count = 0;
-if (_bc_debug)
-fprintf(stderr, "*** rpmbc_inplace_lshift(%p,%p)\n", a, b);
-
+ /* XXX check shift count in range. */
+ if (b->n.size == 1)
+ count = b->n.data[0];
mp32lshift(a->n.size, a->n.data, count);
- return NULL;
+if (_bc_debug)
+fprintf(stderr, "*** rpmbc_inplace_lshift(%p,%p):\t", a, b), mp32println(stderr, a->n.size, a->n.data);
+
+ Py_INCREF(a);
+ return (PyObject *)a;
}
static PyObject *
{
uint32 count = 0;
-if (_bc_debug)
-fprintf(stderr, "*** rpmbc_inplace_rshift(%p,%p)\n", a, b);
-
+ /* XXX check shift count in range. */
+ if (b->n.size == 1)
+ count = b->n.data[0];
mp32rshift(a->n.size, a->n.data, count);
- return NULL;
+if (_bc_debug)
+fprintf(stderr, "*** rpmbc_inplace_rshift(%p,%p):\t", a, b), mp32println(stderr, a->n.size, a->n.data);
+
+ Py_INCREF(a);
+ return (PyObject *)a;
}
static PyObject *
rpmbc_inplace_and(rpmbcObject * a, rpmbcObject * b)
/*@*/
{
+ if (a->n.size <= b->n.size)
+ mp32and(a->n.size, a->n.data, b->n.data + (b->n.size - a->n.size));
+ else {
+ memset(a->n.data, 0, (a->n.size - b->n.size) * sizeof(*a->n.data));
+ mp32and(a->n.size, a->n.data + (a->n.size - b->n.size), b->n.data);
+ }
+
if (_bc_debug)
-fprintf(stderr, "*** rpmbc_inplace_and(%p,%p)\n", a, b);
- return NULL;
+fprintf(stderr, "*** rpmbc_inplace_and(%p,%p):\t", a, b), mp32println(stderr, a->n.size, a->n.data);
+
+ Py_INCREF(a);
+ return (PyObject *)a;
}
static PyObject *
rpmbc_inplace_xor(rpmbcObject * a, rpmbcObject * b)
{
+ if (a->n.size <= b->n.size)
+ mp32xor(a->n.size, a->n.data, b->n.data + (b->n.size - a->n.size));
+ else {
+ memset(a->n.data, 0, (a->n.size - b->n.size) * sizeof(*a->n.data));
+ mp32xor(a->n.size, a->n.data + (a->n.size - b->n.size), b->n.data);
+ }
+
if (_bc_debug)
-fprintf(stderr, "*** rpmbc_inplace_xor(%p,%p)\n", a, b);
- return NULL;
+fprintf(stderr, "*** rpmbc_inplace_xor(%p,%p):\t", a, b), mp32println(stderr, a->n.size, a->n.data);
+
+ Py_INCREF(a);
+ return (PyObject *)a;
}
static PyObject *
rpmbc_inplace_or(rpmbcObject * a, rpmbcObject * b)
/*@*/
{
+ if (a->n.size <= b->n.size)
+ mp32or(a->n.size, a->n.data, b->n.data + (b->n.size - a->n.size));
+ else {
+ memset(a->n.data, 0, (a->n.size - b->n.size) * sizeof(*a->n.data));
+ mp32or(a->n.size, a->n.data + (a->n.size - b->n.size), b->n.data);
+ }
+
if (_bc_debug)
-fprintf(stderr, "*** rpmbc_inplace_or(%p,%p)\n", a, b);
- return NULL;
+fprintf(stderr, "*** rpmbc_inplace_or(%p,%p):\t", a, b), mp32println(stderr, a->n.size, a->n.data);
+
+ Py_INCREF(a);
+ return (PyObject *)a;
}
static PyObject *
(binaryfunc) rpmbc_xor, /* nb_xor */
(binaryfunc) rpmbc_or, /* nb_or */
(coercion) rpmbc_coerce, /* nb_coerce */
+
(unaryfunc) rpmbc_int, /* nb_int */
(unaryfunc) rpmbc_long, /* nb_long */
(unaryfunc) rpmbc_float, /* nb_float */