82422c0d1e7b12f79fefe9081dff88c9edda63f9
[platform/upstream/rpm.git] / python / rpmps-py.c
1 #include "rpmsystem-py.h"
2
3 #include "rpmps-py.h"
4
5 #include "debug.h"
6
7 struct rpmpsObject_s {
8     PyObject_HEAD
9     PyObject *md_dict;          /*!< to look like PyModuleObject */
10     rpmps       ps;
11     rpmpsi      psi;
12 };
13
14 static int
15 rpmps_append(rpmpsObject * s, PyObject * value)
16 {
17     char *pkgNEVR, *altNEVR, *str1;
18     unsigned long ulong1;
19     int ignoreProblem;
20     rpmProblemType type;
21     fnpyKey key;
22
23     if (!PyArg_ParseTuple(value, "ssOiisN:rpmps value tuple",
24                         &pkgNEVR, &altNEVR, &key,
25                         &type, &ignoreProblem, &str1,
26                         &ulong1))
27     {
28         return -1;
29     }
30     rpmpsAppend(s->ps, type, pkgNEVR, key, str1, NULL, altNEVR, ulong1);
31     return 0;
32 }
33
34 static PyObject *
35 rpmps_iternext(rpmpsObject * s)
36 {
37     PyObject * result = NULL;
38
39     /* Reset loop indices on 1st entry. */
40     if (s->psi == NULL) {
41         s->psi = rpmpsInitIterator(s->ps);
42     }
43
44     /* If more to do, return a problem set string. */
45     if (rpmpsNextIterator(s->psi) >= 0) {
46         char * ps = rpmProblemString(rpmpsGetProblem(s->psi));
47         result = Py_BuildValue("s", ps);
48         free(ps);
49     } else {
50         s->psi = rpmpsFreeIterator(s->psi);
51     }
52
53     return result;
54 }
55
56 static struct PyMethodDef rpmps_methods[] = {
57   {"append",    (PyCFunction)rpmps_append,      METH_VARARGS, NULL},
58  {NULL,         NULL}           /* sentinel */
59 };
60
61 static void
62 rpmps_dealloc(rpmpsObject * s)
63 {
64     if (s) {
65         s->ps = rpmpsFree(s->ps);
66         PyObject_Del(s);
67     }
68 }
69
70 static int
71 rpmps_length(rpmpsObject * s)
72 {
73     int rc;
74     rc = rpmpsNumProblems(s->ps);
75     return rc;
76 }
77
78 static PyObject *
79 rpmps_subscript(rpmpsObject * s, PyObject * key)
80 {
81     PyObject * result = NULL;
82     rpmpsi psi;
83     int ix, i;
84
85     if (!PyInt_Check(key)) {
86         PyErr_SetString(PyExc_TypeError, "integer expected");
87         return NULL;
88     }
89
90     ix = (int) PyInt_AsLong(key);
91     /* XXX range check */
92
93     psi = rpmpsInitIterator(s->ps);
94     while ((i = rpmpsNextIterator(psi)) >= 0) {
95         if (i == ix) {
96             char * ps = rpmProblemString(rpmpsGetProblem(psi));
97             result = Py_BuildValue("s", ps);
98             free(ps);
99             break;
100         }
101     }
102     psi = rpmpsFreeIterator(psi);
103
104     return result;
105 }
106
107 static PyMappingMethods rpmps_as_mapping = {
108         (lenfunc) rpmps_length,         /* mp_length */
109         (binaryfunc) rpmps_subscript,   /* mp_subscript */
110 };
111
112 static void rpmps_free(rpmpsObject * s)
113 {
114     s->ps = rpmpsFree(s->ps);
115
116     PyObject_Del((PyObject *)s);
117 }
118
119 static PyObject * rpmps_new(PyTypeObject * subtype, PyObject *args, PyObject *kwds)
120 {
121     rpmps ps = rpmpsCreate();
122     return rpmps_Wrap(subtype, ps);
123 }
124
125 static char rpmps_doc[] =
126 "";
127
128 PyTypeObject rpmps_Type = {
129         PyObject_HEAD_INIT(&PyType_Type)
130         0,                              /* ob_size */
131         "rpm.ps",                       /* tp_name */
132         sizeof(rpmpsObject),            /* tp_basicsize */
133         0,                              /* tp_itemsize */
134         /* methods */
135         (destructor) rpmps_dealloc,     /* tp_dealloc */
136         0,                              /* tp_print */
137         (getattrfunc)0,                 /* tp_getattr */
138         (setattrfunc)0,                 /* tp_setattr */
139         (cmpfunc)0,                     /* tp_compare */
140         (reprfunc)0,                    /* tp_repr */
141         0,                              /* tp_as_number */
142         0,                              /* tp_as_sequence */
143         &rpmps_as_mapping,              /* tp_as_mapping */
144         (hashfunc)0,                    /* tp_hash */
145         (ternaryfunc)0,                 /* tp_call */
146         (reprfunc)0,                    /* tp_str */
147         PyObject_GenericGetAttr,        /* tp_getattro */
148         PyObject_GenericSetAttr,        /* tp_setattro */
149         0,                              /* tp_as_buffer */
150         Py_TPFLAGS_DEFAULT,             /* tp_flags */
151         rpmps_doc,                      /* tp_doc */
152         0,                              /* tp_traverse */
153         0,                              /* tp_clear */
154         (richcmpfunc)0,                 /* tp_richcompare */
155         0,                              /* tp_weaklistoffset */
156         PyObject_SelfIter,              /* tp_iter */
157         (iternextfunc) rpmps_iternext,  /* tp_iternext */
158         rpmps_methods,                  /* tp_methods */
159         0,                              /* tp_members */
160         0,                              /* tp_getset */
161         0,                              /* tp_base */
162         0,                              /* tp_dict */
163         0,                              /* tp_descr_get */
164         0,                              /* tp_descr_set */
165         0,                              /* tp_dictoffset */
166         0,                              /* tp_init */
167         0,                              /* tp_alloc */
168         (newfunc) rpmps_new,            /* tp_new */
169         (freefunc) rpmps_free,          /* tp_free */
170         0,                              /* tp_is_gc */
171 };
172
173 rpmps psFromPs(rpmpsObject * s)
174 {
175     return s->ps;
176 }
177
178 PyObject * rpmps_Wrap(PyTypeObject *subtype, rpmps ps)
179 {
180     rpmpsObject * s = (rpmpsObject *)subtype->tp_alloc(subtype, 0);
181     if (s == NULL) return PyErr_NoMemory();
182
183     s->ps = ps; /* XXX refcounts? */
184     s->psi = NULL;
185     return (PyObject *) s;
186 }