346 lines
7.7 KiB
C
346 lines
7.7 KiB
C
/** \ingroup py_c
|
|
* \file python/rpmps-py.c
|
|
*/
|
|
|
|
#include "system.h"
|
|
|
|
#include <rpmlib.h>
|
|
|
|
#include "rpmdebug-py.c"
|
|
|
|
#include "rpmps-py.h"
|
|
|
|
#include "debug.h"
|
|
|
|
|
|
static PyObject *
|
|
rpmps_Debug(rpmpsObject * s, PyObject * args, PyObject * kwds)
|
|
{
|
|
char * kwlist[] = {"debugLevel", NULL};
|
|
|
|
if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &_rpmps_debug))
|
|
return NULL;
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
static PyObject *
|
|
rpmps_iter(rpmpsObject * s)
|
|
{
|
|
if (_rpmps_debug < 0)
|
|
fprintf(stderr, "*** rpmps_iter(%p)\n", s);
|
|
s->ix = -1;
|
|
Py_INCREF(s);
|
|
return (PyObject *)s;
|
|
}
|
|
|
|
static PyObject *
|
|
rpmps_iternext(rpmpsObject * s)
|
|
{
|
|
PyObject * result = NULL;
|
|
rpmps ps = s->ps;
|
|
|
|
if (_rpmps_debug < 0)
|
|
fprintf(stderr, "*** rpmps_iternext(%p) ps %p ix %d active %d\n", s, s->ps, s->ix, s->active);
|
|
|
|
/* Reset loop indices on 1st entry. */
|
|
if (!s->active) {
|
|
s->ix = -1;
|
|
s->active = 1;
|
|
}
|
|
|
|
/* If more to do, return a problem set string. */
|
|
s->ix++;
|
|
if (s->ix < ps->numProblems) {
|
|
result = Py_BuildValue("s", rpmProblemString(ps->probs+s->ix));
|
|
} else {
|
|
s->active = 0;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
static struct PyMethodDef rpmps_methods[] = {
|
|
{"Debug", (PyCFunction)rpmps_Debug, METH_VARARGS|METH_KEYWORDS,
|
|
NULL},
|
|
{NULL, NULL} /* sentinel */
|
|
};
|
|
|
|
/* ---------- */
|
|
|
|
static void
|
|
rpmps_dealloc(rpmpsObject * s)
|
|
{
|
|
if (_rpmps_debug < 0)
|
|
fprintf(stderr, "*** rpmps_dealloc(%p)\n", s);
|
|
if (s) {
|
|
s->ps = rpmpsFree(s->ps);
|
|
PyObject_Del(s);
|
|
}
|
|
}
|
|
|
|
static int
|
|
rpmps_print(rpmpsObject * s, FILE * fp, int flags)
|
|
{
|
|
if (_rpmps_debug < 0)
|
|
fprintf(stderr, "*** rpmps_print(%p,%p,%x)\n", s, (void *)fp, flags);
|
|
if (s && s->ps)
|
|
rpmpsPrint(fp, s->ps);
|
|
return 0;
|
|
}
|
|
|
|
static PyObject * rpmps_getattro(PyObject * o, PyObject * n)
|
|
{
|
|
if (_rpmps_debug < 0)
|
|
fprintf(stderr, "*** rpmps_getattro(%p,%p)\n", o, n);
|
|
return PyObject_GenericGetAttr(o, n);
|
|
}
|
|
|
|
static int rpmps_setattro(PyObject * o, PyObject * n, PyObject * v)
|
|
{
|
|
if (_rpmps_debug < 0)
|
|
fprintf(stderr, "*** rpmps_setattro(%p,%p,%p)\n", o, n, v);
|
|
return PyObject_GenericSetAttr(o, n, v);
|
|
}
|
|
|
|
static int
|
|
rpmps_length(rpmpsObject * s)
|
|
{
|
|
int rc;
|
|
rc = rpmpsNumProblems(s->ps);
|
|
if (_rpmps_debug < 0)
|
|
fprintf(stderr, "*** rpmps_length(%p) rc %d\n", s, rc);
|
|
return rc;
|
|
}
|
|
|
|
static PyObject *
|
|
rpmps_subscript(rpmpsObject * s, PyObject * key)
|
|
{
|
|
PyObject * result = NULL;
|
|
rpmps ps;
|
|
int ix;
|
|
|
|
if (!PyInt_Check(key)) {
|
|
if (_rpmps_debug < 0)
|
|
fprintf(stderr, "*** rpmps_subscript(%p[%s],%p[%s])\n", s, lbl(s), key, lbl(key));
|
|
PyErr_SetString(PyExc_TypeError, "integer expected");
|
|
return NULL;
|
|
}
|
|
|
|
ix = (int) PyInt_AsLong(key);
|
|
/* XXX range check */
|
|
ps = s->ps;
|
|
if (ix < ps->numProblems) {
|
|
result = Py_BuildValue("s", rpmProblemString(ps->probs + ix));
|
|
if (_rpmps_debug < 0)
|
|
fprintf(stderr, "*** rpmps_subscript(%p,%p) %s\n", s, key, PyString_AsString(result));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
static int
|
|
rpmps_ass_sub(rpmpsObject * s, PyObject * key, PyObject * value)
|
|
{
|
|
rpmps ps;
|
|
int ix;
|
|
|
|
if (!PyArg_Parse(key, "i:ass_sub", &ix)) {
|
|
PyErr_SetString(PyExc_TypeError, "rpmps key type must be integer");
|
|
return -1;
|
|
}
|
|
|
|
/* XXX get rid of negative indices */
|
|
if (ix < 0) ix = -ix;
|
|
|
|
ps = s->ps;
|
|
|
|
if (_rpmps_debug < 0)
|
|
fprintf(stderr, "*** rpmps_ass_sub(%p[%s],%p[%s],%p[%s]) ps %p[%d:%d:%d]\n", s, lbl(s), key, lbl(key), value, lbl(value), ps, ix, ps->numProblems, ps->numProblemsAlloced);
|
|
|
|
if (value == NULL) {
|
|
if (ix < ps->numProblems) {
|
|
rpmProblem op = ps->probs + ix;
|
|
|
|
op->pkgNEVR = _free(op->pkgNEVR);
|
|
op->altNEVR = _free(op->altNEVR);
|
|
op->str1 = _free(op->str1);
|
|
|
|
if ((ix+1) == ps->numProblems)
|
|
memset(op, 0, sizeof(*op));
|
|
else
|
|
memmove(op, op+1, (ps->numProblems - ix) * sizeof(*op));
|
|
if (ps->numProblems > 0)
|
|
ps->numProblems--;
|
|
}
|
|
} else {
|
|
rpmProblem p = memset(alloca(sizeof(*p)), 0, sizeof(*p));
|
|
|
|
if (!PyArg_ParseTuple(value, "ssOiisN:rpmps value tuple",
|
|
&p->pkgNEVR, &p->altNEVR, &p->key,
|
|
&p->type, &p->ignoreProblem, &p->str1,
|
|
&p->ulong1))
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
if (ix >= ps->numProblems) {
|
|
/* XXX force append for indices out of range. */
|
|
rpmpsAppend(s->ps, p->type, p->pkgNEVR, p->key,
|
|
p->str1, NULL, p->altNEVR, p->ulong1);
|
|
} else {
|
|
rpmProblem op = ps->probs + ix;
|
|
|
|
op->pkgNEVR = _free(op->pkgNEVR);
|
|
op->altNEVR = _free(op->altNEVR);
|
|
op->str1 = _free(op->str1);
|
|
|
|
p->pkgNEVR = (p->pkgNEVR && *p->pkgNEVR ? xstrdup(p->pkgNEVR) : NULL);
|
|
p->altNEVR = (p->altNEVR && *p->altNEVR ? xstrdup(p->altNEVR) : NULL);
|
|
p->str1 = (p->str1 && *p->str1 ? xstrdup(p->str1) : NULL);
|
|
|
|
*op = *p; /* structure assignment */
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static PyMappingMethods rpmps_as_mapping = {
|
|
(lenfunc) rpmps_length, /* mp_length */
|
|
(binaryfunc) rpmps_subscript, /* mp_subscript */
|
|
(objobjargproc) rpmps_ass_sub, /* mp_ass_subscript */
|
|
};
|
|
|
|
/** \ingroup py_c
|
|
*/
|
|
static int rpmps_init(rpmpsObject * s, PyObject *args, PyObject *kwds)
|
|
{
|
|
char * kwlist[] = {NULL};
|
|
|
|
if (_rpmps_debug < 0)
|
|
fprintf(stderr, "*** rpmps_init(%p,%p,%p)\n", s, args, kwds);
|
|
|
|
if (!PyArg_ParseTupleAndKeywords(args, kwds, ":rpmps_init", kwlist))
|
|
return -1;
|
|
|
|
s->ps = rpmpsCreate();
|
|
s->active = 0;
|
|
s->ix = -1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/** \ingroup py_c
|
|
*/
|
|
static void rpmps_free(rpmpsObject * s)
|
|
{
|
|
if (_rpmps_debug)
|
|
fprintf(stderr, "%p -- ps %p\n", s, s->ps);
|
|
s->ps = rpmpsFree(s->ps);
|
|
|
|
PyObject_Del((PyObject *)s);
|
|
}
|
|
|
|
/** \ingroup py_c
|
|
*/
|
|
static PyObject * rpmps_alloc(PyTypeObject * subtype, int nitems)
|
|
{
|
|
PyObject * s = PyType_GenericAlloc(subtype, nitems);
|
|
|
|
if (_rpmps_debug < 0)
|
|
fprintf(stderr, "*** rpmps_alloc(%p,%d) ret %p\n", subtype, nitems, s);
|
|
return s;
|
|
}
|
|
|
|
/** \ingroup py_c
|
|
*/
|
|
static PyObject * rpmps_new(PyTypeObject * subtype, PyObject *args, PyObject *kwds)
|
|
{
|
|
rpmpsObject * s = (void *) PyObject_New(rpmpsObject, subtype);
|
|
|
|
/* Perform additional initialization. */
|
|
if (rpmps_init(s, args, kwds) < 0) {
|
|
rpmps_free(s);
|
|
return NULL;
|
|
}
|
|
|
|
if (_rpmps_debug)
|
|
fprintf(stderr, "%p ++ ps %p\n", s, s->ps);
|
|
|
|
return (PyObject *)s;
|
|
}
|
|
|
|
/**
|
|
*/
|
|
static char rpmps_doc[] =
|
|
"";
|
|
|
|
PyTypeObject rpmps_Type = {
|
|
PyObject_HEAD_INIT(&PyType_Type)
|
|
0, /* ob_size */
|
|
"rpm.ps", /* tp_name */
|
|
sizeof(rpmpsObject), /* tp_basicsize */
|
|
0, /* tp_itemsize */
|
|
/* methods */
|
|
(destructor) rpmps_dealloc, /* tp_dealloc */
|
|
(printfunc) rpmps_print, /* tp_print */
|
|
(getattrfunc)0, /* tp_getattr */
|
|
(setattrfunc)0, /* tp_setattr */
|
|
(cmpfunc)0, /* tp_compare */
|
|
(reprfunc)0, /* tp_repr */
|
|
0, /* tp_as_number */
|
|
0, /* tp_as_sequence */
|
|
&rpmps_as_mapping, /* tp_as_mapping */
|
|
(hashfunc)0, /* tp_hash */
|
|
(ternaryfunc)0, /* tp_call */
|
|
(reprfunc)0, /* tp_str */
|
|
(getattrofunc) rpmps_getattro, /* tp_getattro */
|
|
(setattrofunc) rpmps_setattro, /* tp_setattro */
|
|
0, /* tp_as_buffer */
|
|
Py_TPFLAGS_DEFAULT, /* tp_flags */
|
|
rpmps_doc, /* tp_doc */
|
|
#if Py_TPFLAGS_HAVE_ITER
|
|
0, /* tp_traverse */
|
|
0, /* tp_clear */
|
|
(richcmpfunc)0, /* tp_richcompare */
|
|
0, /* tp_weaklistoffset */
|
|
(getiterfunc) rpmps_iter, /* tp_iter */
|
|
(iternextfunc) rpmps_iternext, /* tp_iternext */
|
|
rpmps_methods, /* tp_methods */
|
|
0, /* tp_members */
|
|
0, /* tp_getset */
|
|
0, /* tp_base */
|
|
0, /* tp_dict */
|
|
0, /* tp_descr_get */
|
|
0, /* tp_descr_set */
|
|
0, /* tp_dictoffset */
|
|
(initproc) rpmps_init, /* tp_init */
|
|
(allocfunc) rpmps_alloc, /* tp_alloc */
|
|
(newfunc) rpmps_new, /* tp_new */
|
|
(freefunc) rpmps_free, /* tp_free */
|
|
0, /* tp_is_gc */
|
|
#endif
|
|
};
|
|
|
|
/* ---------- */
|
|
|
|
rpmps psFromPs(rpmpsObject * s)
|
|
{
|
|
return s->ps;
|
|
}
|
|
|
|
rpmpsObject *
|
|
rpmps_Wrap(rpmps ps)
|
|
{
|
|
rpmpsObject * s = PyObject_New(rpmpsObject, &rpmps_Type);
|
|
|
|
if (s == NULL)
|
|
return NULL;
|
|
s->ps = ps;
|
|
s->active = 0;
|
|
s->ix = -1;
|
|
return s;
|
|
}
|