rpm  4.5
rpmds-py.c
Go to the documentation of this file.
1 
5 #include "system.h"
6 
7 #include <rpmlib.h>
8 
9 #include "header-py.h"
10 #include "rpmds-py.h"
11 
12 #include "debug.h"
13 
14 /*@access rpmds @*/
15 
23 static
24 void rpmds_ParseEVR(char * evr,
25  /*@exposed@*/ /*@out@*/ const char ** ep,
26  /*@exposed@*/ /*@out@*/ const char ** vp,
27  /*@exposed@*/ /*@out@*/ const char ** rp)
28  /*@modifies *ep, *vp, *rp @*/
29  /*@requires maxSet(ep) >= 0 /\ maxSet(vp) >= 0 /\ maxSet(rp) >= 0 @*/
30 {
31  const char *epoch;
32  const char *version; /* assume only version is present */
33  const char *release;
34  char *s, *se;
35 
36  s = evr;
37  while (*s && xisdigit(*s)) s++; /* s points to epoch terminator */
38  se = strrchr(s, '-'); /* se points to version terminator */
39 
40  if (*s == ':') {
41  epoch = evr;
42  *s++ = '\0';
43  version = s;
44  /*@-branchstate@*/
45  if (*epoch == '\0') epoch = "0";
46  /*@=branchstate@*/
47  } else {
48  epoch = NULL; /* XXX disable epoch compare if missing */
49  version = evr;
50  }
51  if (se) {
52 /*@-boundswrite@*/
53  *se++ = '\0';
54 /*@=boundswrite@*/
55  release = se;
56  } else {
57  release = NULL;
58  }
59 
60  if (ep) *ep = epoch;
61  if (vp) *vp = version;
62  if (rp) *rp = release;
63 }
64 
67 static int compare_values(const char *str1, const char *str2)
68 {
69  if (!str1 && !str2)
70  return 0;
71  else if (str1 && !str2)
72  return 1;
73  else if (!str1 && str2)
74  return -1;
75  return rpmvercmp(str1, str2);
76 }
77 
78 static int
80  /*@*/
81 {
82  char *aEVR = xstrdup(rpmdsEVR(a->ds));
83  const char *aE, *aV, *aR;
84  char *bEVR = xstrdup(rpmdsEVR(b->ds));
85  const char *bE, *bV, *bR;
86  int rc;
87 
88  /* XXX W2DO? should N be compared? */
89  rpmds_ParseEVR(aEVR, &aE, &aV, &aR);
90  rpmds_ParseEVR(bEVR, &bE, &bV, &bR);
91 
92  rc = compare_values(aE, bE);
93  if (!rc) {
94  rc = compare_values(aV, bV);
95  if (!rc)
96  rc = compare_values(aR, bR);
97  }
98 
99  aEVR = _free(aEVR);
100  bEVR = _free(bEVR);
101 
102  return rc;
103 }
104 
105 static PyObject *
107  /*@*/
108 {
109  int rc;
110 
111  switch (op) {
112  case Py_NE:
113  /* XXX map ranges overlap boolean onto '!=' python syntax. */
114  rc = rpmdsCompare(a->ds, b->ds);
115  rc = (rc < 0 ? -1 : (rc == 0 ? 1 : 0));
116  break;
117  case Py_LT:
118  case Py_LE:
119  case Py_GT:
120  case Py_GE:
121  case Py_EQ:
122  /*@fallthrough@*/
123  default:
124  rc = -1;
125  break;
126  }
127  return Py_BuildValue("i", rc);
128 }
129 
130 static PyObject *
132  /*@*/
133 {
134  Py_INCREF(s);
135  return (PyObject *)s;
136 }
137 
138 /*@null@*/
139 static PyObject *
141  /*@modifies s @*/
142 {
143  PyObject * result = NULL;
144 
145  /* Reset loop indices on 1st entry. */
146  if (!s->active) {
147  s->ds = rpmdsInit(s->ds);
148  s->active = 1;
149  }
150 
151  /* If more to do, return a (N, EVR, Flags) tuple. */
152  if (rpmdsNext(s->ds) >= 0) {
153  const char * N = rpmdsN(s->ds);
154  const char * EVR = rpmdsEVR(s->ds);
155  int tagN = rpmdsTagN(s->ds);
156  int Flags = rpmdsFlags(s->ds);
157 
158 /*@-branchstate@*/
159  if (N != NULL) N = xstrdup(N);
160  if (EVR != NULL) EVR = xstrdup(EVR);
161 /*@=branchstate@*/
162  result = (PyObject *)rpmds_Wrap( rpmdsSingle(tagN, N, EVR, Flags) );
163  } else
164  s->active = 0;
165 
166  return result;
167 }
168 
173 
174 /*@null@*/
175 static PyObject *
177  /*@globals _Py_NoneStruct @*/
178  /*@modifies s, _Py_NoneStruct @*/
179 {
180  PyObject * result;
181 
182  result = rpmds_iternext(s);
183 
184  if (result == NULL) {
185  Py_INCREF(Py_None);
186  return Py_None;
187  }
188  return result;
189 }
190 
191 /*@null@*/
192 static PyObject *
193 rpmds_Debug(/*@unused@*/ rpmdsObject * s, PyObject * args, PyObject * kwds)
194  /*@globals _Py_NoneStruct @*/
195  /*@modifies _Py_NoneStruct @*/
196 {
197  char * kwlist[] = {"debugLevel", NULL};
198 
199  if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &_rpmds_debug))
200  return NULL;
201 
202  Py_INCREF(Py_None);
203  return Py_None;
204 }
205 
206 /*@null@*/
207 static PyObject *
209  /*@*/
210 {
211  return Py_BuildValue("i", rpmdsCount(s->ds));
212 }
213 
214 /*@null@*/
215 static PyObject *
217  /*@*/
218 {
219  return Py_BuildValue("i", rpmdsIx(s->ds));
220 }
221 
222 /*@null@*/
223 static PyObject *
225  /*@*/
226 {
227  return Py_BuildValue("s", rpmdsDNEVR(s->ds));
228 }
229 
230 /*@null@*/
231 static PyObject *
233  /*@*/
234 {
235  return Py_BuildValue("s", rpmdsN(s->ds));
236 }
237 
238 /*@null@*/
239 static PyObject *
241  /*@*/
242 {
243  return Py_BuildValue("s", rpmdsEVR(s->ds));
244 }
245 
246 /*@null@*/
247 static PyObject *
249  /*@*/
250 {
251  return Py_BuildValue("i", rpmdsFlags(s->ds));
252 }
253 
254 /*@null@*/
255 static PyObject *
257  /*@*/
258 {
259  return Py_BuildValue("i", (int) rpmdsBT(s->ds));
260 }
261 
262 /*@null@*/
263 static PyObject *
265  /*@*/
266 {
267  return Py_BuildValue("i", rpmdsTagN(s->ds));
268 }
269 
270 /*@null@*/
271 static PyObject *
273  /*@*/
274 {
275  return Py_BuildValue("i", rpmdsColor(s->ds));
276 }
277 
278 /*@null@*/
279 static PyObject *
281  /*@*/
282 {
283  return Py_BuildValue("i", rpmdsRefs(s->ds));
284 }
285 
286 /*@null@*/
287 static PyObject *
289  /*@*/
290 {
291  return Py_BuildValue("i", rpmdsResult(s->ds));
292 }
293 /*@null@*/
294 static PyObject *
295 rpmds_SetNoPromote(rpmdsObject * s, PyObject * args, PyObject * kwds)
296  /*@modifies s @*/
297 {
298  int nopromote;
299  char * kwlist[] = {"noPromote", NULL};
300 
301  if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:SetNoPromote", kwlist,
302  &nopromote))
303  return NULL;
304 
305  return Py_BuildValue("i", rpmdsSetNoPromote(s->ds, nopromote));
306 }
307 
308 /*@null@*/
309 static PyObject *
310 rpmds_Notify(rpmdsObject * s, PyObject * args, PyObject * kwds)
311  /*@globals _Py_NoneStruct @*/
312  /*@modifies _Py_NoneStruct @*/
313 {
314  const char * where;
315  int rc;
316  char * kwlist[] = {"location", "returnCode", NULL};
317 
318  if (!PyArg_ParseTupleAndKeywords(args, kwds, "si:Notify", kwlist,
319  &where, &rc))
320  return NULL;
321 
322  rpmdsNotify(s->ds, where, rc);
323  Py_INCREF(Py_None);
324  return Py_None;
325 }
326 
327 /* XXX rpmdsFind uses bsearch on s->ds, so a sort is needed. */
328 /*@null@*/
329 static PyObject *
331  /*@globals _Py_NoneStruct @*/
332  /*@modifies _Py_NoneStruct @*/
333 {
334  rpmds nds = NULL;
335 
336  if (rpmdsMerge(&nds, s->ds) >= 0) {
337  s->ds = rpmdsFree(s->ds);
338  s->ds = nds;
339  }
340  Py_INCREF(Py_None);
341  return Py_None;
342 }
343 
344 /*@null@*/
345 static PyObject *
346 rpmds_Find(rpmdsObject * s, PyObject * args, PyObject * kwds)
347  /*@modifies s @*/
348 {
349  PyObject * to = NULL;
350  rpmdsObject * o;
351  char * kwlist[] = {"element", NULL};
352 
353  if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:Find", kwlist, &to))
354  return NULL;
355 
356  /* XXX ds type check needed. */
357  o = (rpmdsObject *)to;
358 
359  /* XXX make sure ods index is valid, real fix in lib/rpmds.c. */
360  if (rpmdsIx(o->ds) == -1) rpmdsSetIx(o->ds, 0);
361 
362  return Py_BuildValue("i", rpmdsFind(s->ds, o->ds));
363 }
364 
365 /*@null@*/
366 static PyObject *
367 rpmds_Merge(rpmdsObject * s, PyObject * args, PyObject * kwds)
368  /*@modifies s @*/
369 {
370  PyObject * to = NULL;
371  rpmdsObject * o;
372  char * kwlist[] = {"element", NULL};
373 
374  if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:Merge", kwlist, &to))
375  return NULL;
376 
377  /* XXX ds type check needed. */
378  o = (rpmdsObject *)to;
379  return Py_BuildValue("i", rpmdsMerge(&s->ds, o->ds));
380 }
381 
382 /*@null@*/
383 static PyObject *
384 rpmds_Search(rpmdsObject * s, PyObject * args, PyObject * kwds)
385  /*@modifies s @*/
386 {
387  PyObject * to = NULL;
388  rpmdsObject * o;
389  char * kwlist[] = {"element", NULL};
390 
391  if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:Merge", kwlist, &to))
392  return NULL;
393 
394  /* XXX ds type check needed. */
395  o = (rpmdsObject *)to;
396  return Py_BuildValue("i", rpmdsSearch(s->ds, o->ds));
397 }
398 
399 static PyObject *
401  /*@*/
402 {
403  rpmds ds = NULL;
404  int xx;
405 
406  /* XXX check return code, permit arg (NULL uses system default). */
407  xx = rpmdsCpuinfo(&ds, NULL);
408 
409  return (PyObject *) rpmds_Wrap( ds );
410 }
411 
412 static PyObject *
414  /*@*/
415 {
416  rpmds ds = NULL;
417  int xx;
418 
419  /* XXX check return code, permit arg (NULL uses system default). */
420  xx = rpmdsRpmlib(&ds, NULL);
421 
422  return (PyObject *) rpmds_Wrap( ds );
423 }
424 
425 static PyObject *
427  /*@*/
428 {
429  rpmPRCO PRCO = rpmdsNewPRCO(NULL);
430  rpmds P = NULL;
431  int xx;
432 
433  /* XXX check return code, permit arg (NULL uses system default). */
434  xx = rpmdsSysinfo(PRCO, NULL);
435  P = rpmdsLink(rpmdsFromPRCO(PRCO, RPMTAG_PROVIDENAME), __FUNCTION__);
436  PRCO = rpmdsFreePRCO(PRCO);
437 
438  return (PyObject *) rpmds_Wrap( P );
439 }
440 
441 static PyObject *
443  /*@*/
444 {
445  rpmds ds = NULL;
446  int xx;
447 
448  /* XXX check return code, permit arg (NULL uses system default). */
449  xx = rpmdsGetconf(&ds, NULL);
450 
451  return (PyObject *) rpmds_Wrap( ds );
452 }
453 
454 static PyObject *
456  /*@*/
457 {
458  rpmPRCO PRCO = rpmdsNewPRCO(NULL);
459  rpmds P = NULL;
460  int xx;
461 
462  /* XXX check return code, permit arg (NULL uses system default). */
463  xx = rpmdsLdconfig(PRCO, NULL);
464 
465  P = rpmdsLink(rpmdsFromPRCO(PRCO, RPMTAG_PROVIDENAME), __FUNCTION__);
466  PRCO = rpmdsFreePRCO(PRCO);
467  return (PyObject *) rpmds_Wrap( P );
468 }
469 
470 #ifdef NOTYET
471 static PyObject *
472 rpmds_Compare(rpmdsObject * s, PyObject * args, PyObject * kwds)
473  /*@modifies s @*/
474 {
475  PyObject * to = NULL;
476  rpmdsObject * o;
477  char * kwlist[] = {"other", NULL};
478 
479  if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:Compare", kwlist, &to))
480  return NULL;
481 
482  /* XXX ds type check needed. */
483  o = (rpmdsObject *)to;
484  return Py_BuildValue("i", rpmdsCompare(s->ds, o->ds));
485 }
486 
487 /*@null@*/
488 static PyObject *
489 rpmds_Problem(rpmdsObject * s)
490  /*@*/
491 {
492  if (!PyArg_ParseTuple(args, ":Problem"))
493  return NULL;
494  Py_INCREF(Py_None);
495  return Py_None;
496 }
497 #endif
498 
501 /*@-fullinitblock@*/
502 /*@unchecked@*/ /*@observer@*/
503 static struct PyMethodDef rpmds_methods[] = {
504  {"Debug", (PyCFunction)rpmds_Debug, METH_VARARGS|METH_KEYWORDS,
505  NULL},
506  {"Count", (PyCFunction)rpmds_Count, METH_NOARGS,
507  "ds.Count -> Count - Return no. of elements.\n" },
508  {"Ix", (PyCFunction)rpmds_Ix, METH_NOARGS,
509  "ds.Ix -> Ix - Return current element index.\n" },
510  {"DNEVR", (PyCFunction)rpmds_DNEVR, METH_NOARGS,
511  "ds.DNEVR -> DNEVR - Return current DNEVR.\n" },
512  {"N", (PyCFunction)rpmds_N, METH_NOARGS,
513  "ds.N -> N - Return current N.\n" },
514  {"EVR", (PyCFunction)rpmds_EVR, METH_NOARGS,
515  "ds.EVR -> EVR - Return current EVR.\n" },
516  {"Flags", (PyCFunction)rpmds_Flags, METH_NOARGS,
517  "ds.Flags -> Flags - Return current Flags.\n" },
518  {"BT", (PyCFunction)rpmds_BT, METH_NOARGS,
519  "ds.BT -> BT - Return build time.\n" },
520  {"TagN", (PyCFunction)rpmds_TagN, METH_NOARGS,
521  "ds.TagN -> TagN - Return current TagN.\n" },
522  {"Color", (PyCFunction)rpmds_Color, METH_NOARGS,
523  "ds.Color -> Color - Return current Color.\n" },
524  {"Refs", (PyCFunction)rpmds_Refs, METH_NOARGS,
525  "ds.Refs -> Refs - Return current Refs.\n" },
526  {"Result", (PyCFunction)rpmds_Result, METH_NOARGS,
527  "ds.Result -> Result - Return current Result.\n" },
528  {"next", (PyCFunction)rpmds_Next, METH_NOARGS,
529 "ds.next() -> (N, EVR, Flags)\n\
530 - Retrieve next dependency triple.\n" },
531  {"SetNoPromote",(PyCFunction)rpmds_SetNoPromote, METH_VARARGS|METH_KEYWORDS,
532  NULL},
533  {"Notify", (PyCFunction)rpmds_Notify, METH_VARARGS|METH_KEYWORDS,
534  NULL},
535  {"Sort", (PyCFunction)rpmds_Sort, METH_NOARGS,
536 "ds.Sort() -> None\n\
537 - Sort the (N,EVR,Flags) elements in ds\n" },
538  {"Find", (PyCFunction)rpmds_Find, METH_VARARGS|METH_KEYWORDS,
539 "ds.Find(element) -> matching ds index (-1 on failure)\n\
540 - Check for an exactly matching element in ds.\n\
541 The current index in ds is positioned at matching member upon success.\n" },
542  {"Merge", (PyCFunction)rpmds_Merge, METH_VARARGS|METH_KEYWORDS,
543 "ds.Merge(elements) -> 0 on success\n\
544 - Merge elements into ds, maintaining (N,EVR,Flags) sort order.\n" },
545  {"Search", (PyCFunction)rpmds_Search, METH_VARARGS|METH_KEYWORDS,
546 "ds.Search(element) -> matching ds index (-1 on failure)\n\
547 - Check that element dependency range overlaps some member of ds.\n\
548 The current index in ds is positioned at overlapping member upon success.\n" },
549  {"Cpuinfo", (PyCFunction)rpmds_Cpuinfo, METH_NOARGS|METH_STATIC,
550  "ds.Cpuinfo -> nds - Return /proc/cpuinfo dependency set.\n"},
551  {"Rpmlib", (PyCFunction)rpmds_Rpmlib, METH_NOARGS|METH_STATIC,
552  "ds.Rpmlib -> nds - Return internal rpmlib dependency set.\n"},
553  {"Sysinfo", (PyCFunction)rpmds_Sysinfo, METH_NOARGS|METH_STATIC,
554  "ds.Sysinfo -> nds - Return /etc/rpm/sysinfo dependency set.\n"},
555  {"Getconf", (PyCFunction)rpmds_Getconf, METH_NOARGS|METH_STATIC,
556  "ds.Getconf -> nds - Return getconf(1) dependency set.\n"},
557  {"Ldconfig", (PyCFunction)rpmds_Ldconfig, METH_NOARGS|METH_STATIC,
558  "ds.Ldconfig -> nds - Return /etc/ld.so.cache dependency set.\n"},
559 #ifdef NOTYET
560  {"Compare", (PyCFunction)rpmds_Compare, METH_VARARGS|METH_KEYWORDS,
561  NULL},
562  {"Problem", (PyCFunction)rpmds_Problem, METH_NOARGS,
563  NULL},
564 #endif
565  {NULL, NULL} /* sentinel */
566 };
567 /*@=fullinitblock@*/
568 
569 /* ---------- */
570 
571 static void
573  /*@modifies s @*/
574 {
575  if (s) {
576  s->ds = rpmdsFree(s->ds);
577  PyObject_Del(s);
578  }
579 }
580 
581 static int
582 rpmds_print(rpmdsObject * s, FILE * fp, /*@unused@*/ int flags)
583  /*@globals fileSystem @*/
584  /*@modifies s, fp, fileSystem @*/
585 {
586  if (!(s && s->ds))
587  return -1;
588 
589  s->ds = rpmdsInit(s->ds);
590  while (rpmdsNext(s->ds) >= 0)
591  fprintf(fp, "%s\n", rpmdsDNEVR(s->ds));
592  return 0;
593 }
594 
595 static PyObject * rpmds_getattro(PyObject * o, PyObject * n)
596  /*@*/
597 {
598  return PyObject_GenericGetAttr(o, n);
599 }
600 
601 static int rpmds_setattro(PyObject * o, PyObject * n, PyObject * v)
602  /*@*/
603 {
604  return PyObject_GenericSetAttr(o, n, v);
605 }
606 
607 static int
609  /*@*/
610 {
611  return rpmdsCount(s->ds);
612 }
613 
614 /*@null@*/
615 static PyObject *
616 rpmds_subscript(rpmdsObject * s, PyObject * key)
617  /*@modifies s @*/
618 {
619  int ix;
620 
621  if (!PyInt_Check(key)) {
622  PyErr_SetString(PyExc_TypeError, "integer expected");
623  return NULL;
624  }
625 
626  ix = (int) PyInt_AsLong(key);
627  /* XXX make sure that DNEVR exists. */
628  rpmdsSetIx(s->ds, ix-1);
629  (void) rpmdsNext(s->ds);
630  return Py_BuildValue("s", rpmdsDNEVR(s->ds));
631 }
632 
633 static PyMappingMethods rpmds_as_mapping = {
634  (inquiry) rpmds_length, /* mp_length */
635  (binaryfunc) rpmds_subscript, /* mp_subscript */
636  (objobjargproc)0, /* mp_ass_subscript */
637 };
638 
641 static int rpmds_init(rpmdsObject * s, PyObject *args, PyObject *kwds)
642  /*@globals rpmGlobalMacroContext @*/
643  /*@modifies s, rpmGlobalMacroContext @*/
644 {
645  hdrObject * ho = NULL;
646  PyObject * to = NULL;
647  int tagN = RPMTAG_REQUIRENAME;
648  int flags = 0;
649  char * kwlist[] = {"header", "tag", "flags", NULL};
650 
651 if (_rpmds_debug < 0)
652 fprintf(stderr, "*** rpmds_init(%p,%p,%p)\n", s, args, kwds);
653 
654  if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|Oi:rpmds_init", kwlist,
655  &hdr_Type, &ho, &to, &flags))
656  return -1;
657 
658  if (to != NULL) {
659  tagN = tagNumFromPyObject(to);
660  if (tagN == -1) {
661  PyErr_SetString(PyExc_KeyError, "unknown header tag");
662  return -1;
663  }
664  }
665  s->ds = rpmdsNew(hdrGetHeader(ho), tagN, flags);
666  s->active = 0;
667 
668  return 0;
669 }
670 
673 static void rpmds_free(/*@only@*/ rpmdsObject * s)
674  /*@modifies s @*/
675 {
676 if (_rpmds_debug)
677 fprintf(stderr, "%p -- ds %p\n", s, s->ds);
678  s->ds = rpmdsFree(s->ds);
679 
680  PyObject_Del((PyObject *)s);
681 }
682 
685 static PyObject * rpmds_alloc(PyTypeObject * subtype, int nitems)
686  /*@*/
687 {
688  PyObject * s = PyType_GenericAlloc(subtype, nitems);
689 
690 if (_rpmds_debug < 0)
691 fprintf(stderr, "*** rpmds_alloc(%p,%d) ret %p\n", subtype, nitems, s);
692  return s;
693 }
694 
697 /*@null@*/
698 static PyObject * rpmds_new(PyTypeObject * subtype, PyObject *args, PyObject *kwds)
699  /*@globals rpmGlobalMacroContext @*/
700  /*@modifies rpmGlobalMacroContext @*/
701 {
702  rpmdsObject * s = (void *) PyObject_New(rpmdsObject, subtype);
703 
704  /* Perform additional initialization. */
705  if (rpmds_init(s, args, kwds) < 0) {
706  rpmds_free(s);
707  return NULL;
708  }
709 
710 if (_rpmds_debug)
711 fprintf(stderr, "%p ++ ds %p\n", s, s->ds);
712 
713  return (PyObject *)s;
714 }
715 
718 /*@unchecked@*/ /*@observer@*/
719 static char rpmds_doc[] =
720 "";
721 
722 /*@-fullinitblock@*/
723 PyTypeObject rpmds_Type = {
724  PyObject_HEAD_INIT(&PyType_Type)
725  0, /* ob_size */
726  "rpm.ds", /* tp_name */
727  sizeof(rpmdsObject), /* tp_basicsize */
728  0, /* tp_itemsize */
729  /* methods */
730  (destructor) rpmds_dealloc, /* tp_dealloc */
731  (printfunc) rpmds_print, /* tp_print */
732  (getattrfunc)0, /* tp_getattr */
733  (setattrfunc)0, /* tp_setattr */
734  (cmpfunc) rpmds_compare, /* tp_compare */
735  (reprfunc)0, /* tp_repr */
736  0, /* tp_as_number */
737  0, /* tp_as_sequence */
738  &rpmds_as_mapping, /* tp_as_mapping */
739  (hashfunc)0, /* tp_hash */
740  (ternaryfunc)0, /* tp_call */
741  (reprfunc)0, /* tp_str */
742  (getattrofunc) rpmds_getattro, /* tp_getattro */
743  (setattrofunc) rpmds_setattro, /* tp_setattro */
744  0, /* tp_as_buffer */
745  Py_TPFLAGS_DEFAULT | /* tp_flags */
746  Py_TPFLAGS_HAVE_RICHCOMPARE,
747  rpmds_doc, /* tp_doc */
748 #if Py_TPFLAGS_HAVE_ITER
749  0, /* tp_traverse */
750  0, /* tp_clear */
751  (richcmpfunc) rpmds_richcompare,/* tp_richcompare */
752  0, /* tp_weaklistoffset */
753  (getiterfunc) rpmds_iter, /* tp_iter */
754  (iternextfunc) rpmds_iternext, /* tp_iternext */
755  rpmds_methods, /* tp_methods */
756  0, /* tp_members */
757  0, /* tp_getset */
758  0, /* tp_base */
759  0, /* tp_dict */
760  0, /* tp_descr_get */
761  0, /* tp_descr_set */
762  0, /* tp_dictoffset */
763  (initproc) rpmds_init, /* tp_init */
764  (allocfunc) rpmds_alloc, /* tp_alloc */
765  (newfunc) rpmds_new, /* tp_new */
766  rpmds_free, /* tp_free */
767  0, /* tp_is_gc */
768 #endif
769 };
770 /*@=fullinitblock@*/
771 
772 /* ---------- */
773 
775 {
776  return s->ds;
777 }
778 
779 rpmdsObject *
781 {
782  rpmdsObject * s = PyObject_New(rpmdsObject, &rpmds_Type);
783 
784  if (s == NULL)
785  return NULL;
786  s->ds = ds;
787  s->active = 0;
788  return s;
789 }
790 
791 
792 rpmdsObject *
793 rpmds_Single(/*@unused@*/ PyObject * s, PyObject * args, PyObject * kwds)
794 {
795  PyObject * to = NULL;
796  int tagN = RPMTAG_PROVIDENAME;
797  const char * N;
798  const char * EVR = NULL;
799  int Flags = 0;
800  char * kwlist[] = {"to", "name", "evr", "flags", NULL};
801 
802  if (!PyArg_ParseTupleAndKeywords(args, kwds, "Os|si:Single", kwlist,
803  &to, &N, &EVR, &Flags))
804  return NULL;
805 
806  if (to != NULL) {
807  tagN = tagNumFromPyObject(to);
808  if (tagN == -1) {
809  PyErr_SetString(PyExc_KeyError, "unknown header tag");
810  return NULL;
811  }
812  }
813  if (N != NULL) N = xstrdup(N);
814  if (EVR != NULL) EVR = xstrdup(EVR);
815  return rpmds_Wrap( rpmdsSingle(tagN, N, EVR, Flags) );
816 }
817 
818 rpmdsObject *
819 hdr_dsFromHeader(PyObject * s, PyObject * args, PyObject * kwds)
820 {
821  hdrObject * ho = (hdrObject *)s;
822  PyObject * to = NULL;
823  rpmTag tagN = RPMTAG_REQUIRENAME;
824  int flags = 0;
825  char * kwlist[] = {"to", "flags", NULL};
826 
827  if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:dsFromHeader", kwlist,
828  &to, &flags))
829  return NULL;
830 
831  if (to != NULL) {
832  tagN = tagNumFromPyObject(to);
833  if (tagN == -1) {
834  PyErr_SetString(PyExc_KeyError, "unknown header tag");
835  return NULL;
836  }
837  }
838  return rpmds_Wrap( rpmdsNew(hdrGetHeader(ho), tagN, flags) );
839 }
840 
841 rpmdsObject *
842 hdr_dsOfHeader(PyObject * s)
843 {
844  hdrObject * ho = (hdrObject *)s;
845  int tagN = RPMTAG_PROVIDENAME;
846  int Flags = RPMSENSE_EQUAL;
847 
848  return rpmds_Wrap( rpmdsThis(hdrGetHeader(ho), tagN, Flags) );
849 }