- use rpmfiFDepends() underneath --fileprovide and --filerequire.
[platform/upstream/rpm.git] / python / rpmds-py.c
1 /** \ingroup python
2  * \file python/rpmds-py.c
3  */
4
5 #include "system.h"
6
7 #include "Python.h"
8 #ifdef __LCLINT__
9 #undef  PyObject_HEAD
10 #define PyObject_HEAD   int _PyObjectHead;
11 #endif
12
13 #include <rpmlib.h>
14
15 #include "header-py.h"
16 #include "rpmds-py.h"
17
18 #include "debug.h"
19
20 /*@access rpmds @*/
21
22 static PyObject *
23 rpmds_Debug(/*@unused@*/ rpmdsObject * s, PyObject * args)
24         /*@globals _Py_NoneStruct @*/
25         /*@modifies _Py_NoneStruct @*/
26 {
27     if (!PyArg_ParseTuple(args, "i", &_rpmds_debug)) return NULL;
28     Py_INCREF(Py_None);
29     return Py_None;
30 }
31
32 static PyObject *
33 rpmds_Count(rpmdsObject * s, PyObject * args)
34         /*@*/
35 {
36     if (!PyArg_ParseTuple(args, ":Count")) return NULL;
37     return Py_BuildValue("i", rpmdsCount(s->ds));
38 }
39
40 static PyObject *
41 rpmds_Ix(rpmdsObject * s, PyObject * args)
42         /*@*/
43 {
44     if (!PyArg_ParseTuple(args, ":Ix")) return NULL;
45     return Py_BuildValue("i", rpmdsIx(s->ds));
46 }
47
48 static PyObject *
49 rpmds_DNEVR(rpmdsObject * s, PyObject * args)
50         /*@*/
51 {
52     if (!PyArg_ParseTuple(args, ":DNEVR")) return NULL;
53     return Py_BuildValue("s", rpmdsDNEVR(s->ds));
54 }
55
56 static PyObject *
57 rpmds_N(rpmdsObject * s, PyObject * args)
58         /*@*/
59 {
60     if (!PyArg_ParseTuple(args, ":N")) return NULL;
61     return Py_BuildValue("s", rpmdsN(s->ds));
62 }
63
64 static PyObject *
65 rpmds_EVR(rpmdsObject * s, PyObject * args)
66         /*@*/
67 {
68     if (!PyArg_ParseTuple(args, ":EVR")) return NULL;
69     return Py_BuildValue("s", rpmdsEVR(s->ds));
70 }
71
72 static PyObject *
73 rpmds_Flags(rpmdsObject * s, PyObject * args)
74         /*@*/
75 {
76     if (!PyArg_ParseTuple(args, ":Flags")) return NULL;
77     return Py_BuildValue("i", rpmdsFlags(s->ds));
78 }
79
80 static PyObject *
81 rpmds_TagN(rpmdsObject * s, PyObject * args)
82         /*@*/
83 {
84     if (!PyArg_ParseTuple(args, ":TagN")) return NULL;
85     return Py_BuildValue("i", rpmdsTagN(s->ds));
86 }
87
88 static PyObject *
89 rpmds_Color(rpmdsObject * s, PyObject * args)
90         /*@*/
91 {
92     if (!PyArg_ParseTuple(args, ":Color")) return NULL;
93     return Py_BuildValue("i", rpmdsColor(s->ds));
94 }
95
96 static PyObject *
97 rpmds_Refs(rpmdsObject * s, PyObject * args)
98         /*@*/
99 {
100     if (!PyArg_ParseTuple(args, ":Refs")) return NULL;
101     return Py_BuildValue("i", rpmdsRefs(s->ds));
102 }
103
104 static int
105 rpmds_compare(rpmdsObject * a, rpmdsObject * b)
106         /*@*/
107 {
108     return rpmdsCompare(a->ds, b->ds);
109 }
110
111 static PyObject *
112 rpmds_iter(rpmdsObject * s)
113         /*@*/
114 {
115     Py_INCREF(s);
116     return (PyObject *)s;
117 }
118
119 static PyObject *
120 rpmds_iternext(rpmdsObject * s)
121         /*@globals _Py_NoneStruct @*/
122         /*@modifies s, _Py_NoneStruct @*/
123 {
124     PyObject * result = NULL;
125
126     /* Reset loop indices on 1st entry. */
127     if (!s->active) {
128         rpmdsInit(s->ds);
129         s->active = 1;
130     }
131
132     /* If more to do, return a (N, EVR, Flags) tuple. */
133     if (rpmdsNext(s->ds) >= 0) {
134         const char * N = rpmdsN(s->ds);
135         const char * EVR = rpmdsEVR(s->ds);
136         int Flags = rpmdsFlags(s->ds);
137
138         result = PyTuple_New(3);
139         PyTuple_SET_ITEM(result, 0, Py_BuildValue("s", N));
140         if (EVR == NULL) {
141             Py_INCREF(Py_None);
142             PyTuple_SET_ITEM(result, 1, Py_None);
143             Py_INCREF(Py_None);
144             PyTuple_SET_ITEM(result, 2, Py_None);
145         } else {
146             PyTuple_SET_ITEM(result, 1, Py_BuildValue("s", EVR));
147             PyTuple_SET_ITEM(result, 2, PyInt_FromLong(Flags));
148         }
149             
150     } else
151         s->active = 0;
152
153     return result;
154 }
155
156 static PyObject *
157 rpmds_Next(rpmdsObject * s, PyObject *args)
158         /*@globals _Py_NoneStruct @*/
159         /*@modifies s, _Py_NoneStruct @*/
160 {
161     PyObject * result;
162
163     if (!PyArg_ParseTuple(args, ":Next"))
164         return NULL;
165
166     result = rpmds_iternext(s);
167
168     if (result == NULL) {
169         Py_INCREF(Py_None);
170         return Py_None;
171     }
172     return result;
173 }
174
175 static PyObject *
176 rpmds_SetNoPromote(rpmdsObject * s, PyObject * args)
177         /*@modifies s @*/
178 {
179     int nopromote;
180
181     if (!PyArg_ParseTuple(args, "i:SetNoPromote", &nopromote))
182         return NULL;
183     return Py_BuildValue("i", rpmdsSetNoPromote(s->ds, nopromote));
184 }
185
186 static PyObject *
187 rpmds_Notify(rpmdsObject * s, PyObject * args)
188         /*@globals _Py_NoneStruct @*/
189         /*@modifies _Py_NoneStruct @*/
190 {
191     const char * where;
192     int rc;
193
194     if (!PyArg_ParseTuple(args, "si:Notify", &where, &rc))
195         return NULL;
196     rpmdsNotify(s->ds, where, rc);
197     Py_INCREF(Py_None);
198     return Py_None;
199 }
200
201 #ifdef  NOTYET
202 static PyObject *
203 rpmds_Problem(rpmdsObject * s, PyObject * args)
204         /*@*/
205 {
206     if (!PyArg_ParseTuple(args, ":Problem"))
207         return NULL;
208     Py_INCREF(Py_None);
209     return Py_None;
210 }
211 #endif
212
213 /*@-fullinitblock@*/
214 /*@unchecked@*/ /*@observer@*/
215 static struct PyMethodDef rpmds_methods[] = {
216  {"Debug",      (PyCFunction)rpmds_Debug,       METH_VARARGS,
217         NULL},
218  {"Count",      (PyCFunction)rpmds_Count,       METH_VARARGS,
219         "ds.Count -> Count      - Return no. of elements.\n" },
220  {"Ix",         (PyCFunction)rpmds_Ix,          METH_VARARGS,
221         "ds.Ix -> Ix            - Return current element index.\n" },
222  {"DNEVR",      (PyCFunction)rpmds_DNEVR,       METH_VARARGS,
223         "ds.DNEVR -> DNEVR      - Return current DNEVR.\n" },
224  {"N",          (PyCFunction)rpmds_N,           METH_VARARGS,
225         "ds.N -> N              - Return current N.\n" },
226  {"EVR",        (PyCFunction)rpmds_EVR,         METH_VARARGS,
227         "ds.EVR -> EVR          - Return current EVR.\n" },
228  {"Flags",      (PyCFunction)rpmds_Flags,       METH_VARARGS,
229         "ds.Flags -> Flags      - Return current Flags.\n" },
230  {"TagN",       (PyCFunction)rpmds_TagN,        METH_VARARGS,
231         "ds.TagN -> TagN        - Return current TagN.\n" },
232  {"Color",      (PyCFunction)rpmds_Color,       METH_VARARGS,
233         "ds.Color -> Color      - Return current Color.\n" },
234  {"Refs",       (PyCFunction)rpmds_Refs,        METH_VARARGS,
235         "ds.Refs -> Refs        - Return current Refs.\n" },
236  {"next",       (PyCFunction)rpmds_Next,        METH_VARARGS,
237 "ds.next() -> (N, EVR, Flags)\n\
238 - Retrieve next dependency triple.\n" }, 
239  {"SetNoPromote",(PyCFunction)rpmds_SetNoPromote, METH_VARARGS,
240         NULL},
241  {"Notify",     (PyCFunction)rpmds_Notify,      METH_VARARGS,
242         NULL},
243 #ifdef  NOTYET
244  {"Problem",    (PyCFunction)rpmds_Problem,     METH_VARARGS,
245         NULL},
246 #endif
247  {NULL,         NULL}           /* sentinel */
248 };
249 /*@=fullinitblock@*/
250
251 /* ---------- */
252
253 static void
254 rpmds_dealloc(rpmdsObject * s)
255         /*@modifies s @*/
256 {
257     if (s) {
258         s->ds = rpmdsFree(s->ds);
259         PyObject_Del(s);
260     }
261 }
262
263 static int
264 rpmds_print(rpmdsObject * s, FILE * fp, /*@unused@*/ int flags)
265         /*@globals fileSystem @*/
266         /*@modifies s, fp, fileSystem @*/
267 {
268     if (!(s && s->ds))
269         return -1;
270
271     rpmdsInit(s->ds);
272     while (rpmdsNext(s->ds) >= 0)
273         fprintf(fp, "%s\n", rpmdsDNEVR(s->ds));
274     return 0;
275 }
276
277 static PyObject *
278 rpmds_getattr(rpmdsObject * s, char * name)
279         /*@*/
280 {
281     return Py_FindMethod(rpmds_methods, (PyObject *)s, name);
282 }
283
284 static int
285 rpmds_length(rpmdsObject * s)
286         /*@*/
287 {
288     return rpmdsCount(s->ds);
289 }
290
291 static PyObject *
292 rpmds_subscript(rpmdsObject * s, PyObject * key)
293         /*@modifies s @*/
294 {
295     int ix;
296
297     if (!PyInt_Check(key)) {
298         PyErr_SetString(PyExc_TypeError, "integer expected");
299         return NULL;
300     }
301
302     ix = (int) PyInt_AsLong(key);
303     /* XXX make sure that DNEVR exists. */
304     rpmdsSetIx(s->ds, ix-1);
305     (void) rpmdsNext(s->ds);
306     return Py_BuildValue("s", rpmdsDNEVR(s->ds));
307 }
308
309 static PyMappingMethods rpmds_as_mapping = {
310         (inquiry) rpmds_length,         /* mp_length */
311         (binaryfunc) rpmds_subscript,   /* mp_subscript */
312         (objobjargproc)0,               /* mp_ass_subscript */
313 };
314
315 /**
316  */
317 /*@unchecked@*/ /*@observer@*/
318 static char rpmds_doc[] =
319 "";
320
321 /*@-fullinitblock@*/
322 PyTypeObject rpmds_Type = {
323         PyObject_HEAD_INIT(&PyType_Type)
324         0,                              /* ob_size */
325         "rpm.ds",                       /* tp_name */
326         sizeof(rpmdsObject),            /* tp_basicsize */
327         0,                              /* tp_itemsize */
328         /* methods */
329         (destructor) rpmds_dealloc,     /* tp_dealloc */
330         (printfunc) rpmds_print,        /* tp_print */
331         (getattrfunc) rpmds_getattr,    /* tp_getattr */
332         (setattrfunc) 0,                /* tp_setattr */
333         (cmpfunc) rpmds_compare,        /* tp_compare */
334         (reprfunc) 0,                   /* tp_repr */
335         0,                              /* tp_as_number */
336         0,                              /* tp_as_sequence */
337         &rpmds_as_mapping,              /* tp_as_mapping */
338         (hashfunc) 0,                   /* tp_hash */
339         (ternaryfunc) 0,                /* tp_call */
340         (reprfunc) 0,                   /* tp_str */
341         0,                              /* tp_getattro */
342         0,                              /* tp_setattro */
343         0,                              /* tp_as_buffer */
344         Py_TPFLAGS_DEFAULT,             /* tp_flags */
345         rpmds_doc,                      /* tp_doc */
346 #if Py_TPFLAGS_HAVE_ITER
347         0,                              /* tp_traverse */
348         0,                              /* tp_clear */
349         0,                              /* tp_richcompare */
350         0,                              /* tp_weaklistoffset */
351         (getiterfunc) rpmds_iter,       /* tp_iter */
352         (iternextfunc) rpmds_iternext,  /* tp_iternext */
353         rpmds_methods,                  /* tp_methods */
354         0,                              /* tp_members */
355         0,                              /* tp_getset */
356         0,                              /* tp_base */
357         0,                              /* tp_dict */
358         0,                              /* tp_descr_get */
359         0,                              /* tp_descr_set */
360         0,                              /* tp_dictoffset */
361         0,                              /* tp_init */
362         0,                              /* tp_alloc */
363         0,                              /* tp_new */
364         0,                              /* tp_free */
365         0,                              /* tp_is_gc */
366 #endif
367 };
368 /*@=fullinitblock@*/
369
370 /* ---------- */
371
372 rpmds dsFromDs(rpmdsObject * s)
373 {
374     return s->ds;
375 }
376
377 rpmdsObject *
378 rpmds_Wrap(rpmds ds)
379 {
380     rpmdsObject * s = PyObject_New(rpmdsObject, &rpmds_Type);
381
382     if (s == NULL)
383         return NULL;
384     s->ds = ds;
385     s->active = 0;
386     return s;
387 }
388
389 rpmdsObject *
390 rpmds_Single(/*@unused@*/ PyObject * s, PyObject * args)
391 {
392     PyObject * to = NULL;
393     int tagN = RPMTAG_PROVIDENAME;
394     const char * N;
395     const char * EVR = NULL;
396     int Flags = 0;
397
398     if (!PyArg_ParseTuple(args, "Os|si:Single", &to, &N, &EVR, &Flags))
399         return NULL;
400     if (to != NULL) {
401         tagN = tagNumFromPyObject(to);
402         if (tagN == -1) {
403             PyErr_SetString(PyExc_KeyError, "unknown header tag");
404             return NULL;
405         }
406     }
407     return rpmds_Wrap( rpmdsSingle(tagN, N, EVR, Flags) );
408 }
409
410 rpmdsObject *
411 hdr_dsFromHeader(PyObject * s, PyObject * args)
412 {
413     hdrObject * ho = (hdrObject *)s;
414     PyObject * to = NULL;
415     rpmTag tagN = RPMTAG_REQUIRENAME;
416     int scareMem = 0;
417
418     if (!PyArg_ParseTuple(args, "|O:dsFromHeader", &to))
419         return NULL;
420     if (to != NULL) {
421         tagN = tagNumFromPyObject(to);
422         if (tagN == -1) {
423             PyErr_SetString(PyExc_KeyError, "unknown header tag");
424             return NULL;
425         }
426     }
427     return rpmds_Wrap( rpmdsNew(hdrGetHeader(ho), tagN, scareMem) );
428 }
429
430 rpmdsObject *
431 hdr_dsOfHeader(PyObject * s, PyObject * args)
432 {
433     hdrObject * ho = (hdrObject *)s;
434     int tagN = RPMTAG_PROVIDENAME;
435     int Flags = RPMSENSE_EQUAL;
436
437     if (!PyArg_ParseTuple(args, ":dsOfHeader"))
438         return NULL;
439     return rpmds_Wrap( rpmdsThis(hdrGetHeader(ho), tagN, Flags) );
440 }