fix msm-plugin.c svace issue: make sure dupPath is not NULL before strchr()
[platform/upstream/rpm.git] / python / rpmii-py.c
1 #include "rpmsystem-py.h"
2
3 #include <rpm/rpmdb.h>
4 #include <rpm/rpmtd.h>
5
6 #include "rpmtd-py.h"
7 #include "rpmii-py.h"
8 #include "header-py.h"
9
10 /** \ingroup python
11  * \class Rpmii
12  * \brief A python rpm.ii key iterator object represents the keys of a
13  *      database index.
14  *
15  * The rpm.ii class conains the following methods:
16  * - next() -> key              Return the next key.
17  *
18  * To obtain a rpm.ii object to query the database used by a transaction,
19  * the ts.dbIndex(tag) method is used.
20  *
21  * Here's an example that prints the name of all installed packages:
22  * \code
23  *      import rpm
24  *      ts = rpm.TransactionSet()
25  *      for name in ts.dbIndex("conflictname"):
26  *          print name
27  * \endcode
28  *
29  * ts.dbIndex() can be used to get the packages containing the keys of interest
30  */
31
32 /** \ingroup python
33  * \name Class: Rpmii
34  */
35
36 struct rpmiiObject_s {
37     PyObject_HEAD
38     PyObject *md_dict;          /*!< to look like PyModuleObject */
39     PyObject *ref;              /* for db/ts refcounting */
40     rpmdbIndexIterator ii;
41     rpmtd keytd;
42 };
43
44 static PyObject *
45 rpmii_iternext(rpmiiObject * s)
46 {
47     PyObject *keyo = NULL;
48
49     if (s->ii != NULL) {
50         if (rpmdbIndexIteratorNextTd(s->ii, s->keytd) == 0) {
51             /* The keys must never be arrays so rpmtd_AsPyObj() wont work */
52             keyo = rpmtd_ItemAsPyobj(s->keytd, rpmtdClass(s->keytd));
53             rpmtdFreeData(s->keytd);
54         } else {
55             s->ii = rpmdbIndexIteratorFree(s->ii);
56         }
57     }
58
59     return keyo;
60 };
61
62 static PyObject *
63 rpmii_instances(rpmiiObject * s)
64 {
65     int entries = rpmdbIndexIteratorNumPkgs(s->ii);
66     PyObject * list = PyList_New(entries);
67     PyObject * tuple;
68     for (int i = 0; i < entries; i++) {
69         tuple = PyTuple_New(2);
70         PyTuple_SET_ITEM(tuple, 0,
71                          PyInt_FromLong(rpmdbIndexIteratorPkgOffset(s->ii, i)));
72         PyTuple_SET_ITEM(tuple, 1,
73                          PyInt_FromLong(rpmdbIndexIteratorTagNum(s->ii, i)));
74         PyList_SET_ITEM(list, i, tuple);
75     }
76     return list;
77 }
78
79 static struct PyMethodDef rpmii_methods[] = {
80     {"instances", (PyCFunction) rpmii_instances, METH_NOARGS, NULL},
81     {NULL,              NULL}           /* sentinel */
82 };
83
84 static void rpmii_dealloc(rpmiiObject * s)
85 {
86     s->ii = rpmdbIndexIteratorFree(s->ii);
87     rpmtdFree(s->keytd);
88     Py_DECREF(s->ref);
89     Py_TYPE(s)->tp_free((PyObject *)s);
90 }
91
92 static int rpmii_bool(rpmiiObject *s)
93 {
94     return (s->ii != NULL);
95 }
96
97 static PyNumberMethods rpmii_as_number = {
98         0, /* nb_add */
99         0, /* nb_subtract */
100         0, /* nb_multiply */
101 #if PY_MAJOR_VERSION < 3
102         0, /* nb_divide */
103 #endif
104         0, /* nb_remainder */
105         0, /* nb_divmod */
106         0, /* nb_power */
107         0, /* nb_negative */
108         0, /* nb_positive */
109         0, /* nb_absolute */
110         (inquiry)rpmii_bool, /* nb_bool/nonzero */
111 };
112
113 static char rpmii_doc[] =
114 "";
115
116 PyTypeObject rpmii_Type = {
117         PyVarObject_HEAD_INIT(&PyType_Type, 0)
118         "rpm.ii",                       /* tp_name */
119         sizeof(rpmiiObject),            /* tp_size */
120         0,                              /* tp_itemsize */
121         (destructor) rpmii_dealloc,     /* tp_dealloc */
122         0,                              /* tp_print */
123         (getattrfunc)0,                 /* tp_getattr */
124         0,                              /* tp_setattr */
125         0,                              /* tp_compare */
126         0,                              /* tp_repr */
127         &rpmii_as_number,               /* tp_as_number */
128         0,                              /* tp_as_sequence */
129         0,                              /* tp_as_mapping */
130         0,                              /* tp_hash */
131         0,                              /* tp_call */
132         0,                              /* tp_str */
133         PyObject_GenericGetAttr,        /* tp_getattro */
134         PyObject_GenericSetAttr,        /* tp_setattro */
135         0,                              /* tp_as_buffer */
136         Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
137         rpmii_doc,                      /* tp_doc */
138         0,                              /* tp_traverse */
139         0,                              /* tp_clear */
140         0,                              /* tp_richcompare */
141         0,                              /* tp_weaklistoffset */
142         PyObject_SelfIter,              /* tp_iter */
143         (iternextfunc) rpmii_iternext,  /* tp_iternext */
144         rpmii_methods,                  /* tp_methods */
145         0,                              /* tp_members */
146         0,                              /* tp_getset */
147         0,                              /* tp_base */
148         0,                              /* tp_dict */
149         0,                              /* tp_descr_get */
150         0,                              /* tp_descr_set */
151         0,                              /* tp_dictoffset */
152         0,                              /* tp_init */
153         0,                              /* tp_alloc */
154         0,                              /* tp_new */
155         0,                              /* tp_free */
156         0,                              /* tp_is_gc */
157 };
158
159 PyObject * rpmii_Wrap(PyTypeObject *subtype, rpmdbIndexIterator ii, PyObject *s)
160 {
161     rpmiiObject * iio = (rpmiiObject *)subtype->tp_alloc(subtype, 0);
162     if (iio == NULL) return NULL;
163
164     iio->ii = ii;
165     iio->ref = s;
166     iio->keytd = rpmtdNew();
167     Py_INCREF(iio->ref);
168     return (PyObject *) iio;
169 }