- Main Page
- Related Pages
- Modules
- Data Structures
- Files

# python/rpmds-py.c

Go to the documentation of this file.

    00001
    00005 #include "system.h"
    00006
    00007 #include <rpmio.h>
    00008 #include <rpmcb.h>              /* XXX fnpyKey */
    00009 #include <rpmlib.h>
    00010
    00011 #include "header-py.h"
    00012 #include "rpmds-py.h"
    00013
    00014 #include "debug.h"
    00015
    00016 /*@access rpmds @*/
    00017
    00025 static
    00026 void rpmds_ParseEVR(char * evr,
    00027                 /*@exposed@*/ /*@out@*/ const char ** ep,
    00028                 /*@exposed@*/ /*@out@*/ const char ** vp,
    00029                 /*@exposed@*/ /*@out@*/ const char ** rp)
    00030         /*@modifies *ep, *vp, *rp @*/
    00031         /*@requires maxSet(ep) >= 0 /\ maxSet(vp) >= 0 /\ maxSet(rp) >= 0 @*/
    00032 {
    00033     const char *epoch;
    00034     const char *version;                /* assume only version is present */
    00035     const char *release;
    00036     char *s, *se;
    00037
    00038     s = evr;
    00039     while (*s && xisdigit(*s)) s++;     /* s points to epoch terminator */
    00040     se = strrchr(s, '-');               /* se points to version terminator */
    00041
    00042     if (*s == ':') {
    00043         epoch = evr;
    00044         *s++ = '\0';
    00045         version = s;
    00046         /*@-branchstate@*/
    00047         if (*epoch == '\0') epoch = "0";
    00048         /*@=branchstate@*/
    00049     } else {
    00050         epoch = NULL;   /* XXX disable epoch compare if missing */
    00051         version = evr;
    00052     }
    00053     if (se) {
    00054 /*@-boundswrite@*/
    00055         *se++ = '\0';
    00056 /*@=boundswrite@*/
    00057         release = se;
    00058     } else {
    00059         release = NULL;
    00060     }
    00061
    00062     if (ep) *ep = epoch;
    00063     if (vp) *vp = version;
    00064     if (rp) *rp = release;
    00065 }
    00066
    00069 static int compare_values(const char *str1, const char *str2)
    00070 {
    00071     if (!str1 && !str2)
    00072         return 0;
    00073     else if (str1 && !str2)
    00074         return 1;
    00075     else if (!str1 && str2)
    00076         return -1;
    00077     return rpmvercmp(str1, str2);
    00078 }
    00079
    00080 static int
    00081 rpmds_compare(rpmdsObject * a, rpmdsObject * b)
    00082         /*@*/
    00083 {
    00084     char *aEVR = xstrdup(rpmdsEVR(a->ds));
    00085     const char *aE, *aV, *aR;
    00086     char *bEVR = xstrdup(rpmdsEVR(b->ds));
    00087     const char *bE, *bV, *bR;
    00088     int rc;
    00089
    00090     /* XXX W2DO? should N be compared? */
    00091     rpmds_ParseEVR(aEVR, &aE, &aV, &aR);
    00092     rpmds_ParseEVR(bEVR, &bE, &bV, &bR);
    00093
    00094     rc = compare_values(aE, bE);
    00095     if (!rc) {
    00096         rc = compare_values(aV, bV);
    00097         if (!rc)
    00098             rc = compare_values(aR, bR);
    00099     }
    00100
    00101     aEVR = _free(aEVR);
    00102     bEVR = _free(bEVR);
    00103
    00104     return rc;
    00105 }
    00106
    00107 static PyObject *
    00108 rpmds_richcompare(rpmdsObject * a, rpmdsObject * b, int op)
    00109         /*@*/
    00110 {
    00111     int rc;
    00112
    00113     switch (op) {
    00114     case Py_NE:
    00115         /* XXX map ranges overlap boolean onto '!=' python syntax. */
    00116         rc = rpmdsCompare(a->ds, b->ds);
    00117         rc = (rc < 0 ? -1 : (rc == 0 ? 1 : 0));
    00118         break;
    00119     case Py_LT:
    00120     case Py_LE:
    00121     case Py_GT:
    00122     case Py_GE:
    00123     case Py_EQ:
    00124         /*@fallthrough@*/
    00125     default:
    00126         rc = -1;
    00127         break;
    00128     }
    00129     return Py_BuildValue("i", rc);
    00130 }
    00131
    00132 static PyObject *
    00133 rpmds_iter(rpmdsObject * s)
    00134         /*@*/
    00135 {
    00136     Py_INCREF(s);
    00137     return (PyObject *)s;
    00138 }
    00139
    00140 /*@null@*/
    00141 static PyObject *
    00142 rpmds_iternext(rpmdsObject * s)
    00143         /*@modifies s @*/
    00144 {
    00145     PyObject * result = NULL;
    00146
    00147     /* Reset loop indices on 1st entry. */
    00148     if (!s->active) {
    00149         s->ds = rpmdsInit(s->ds);
    00150         s->active = 1;
    00151     }
    00152
    00153     /* If more to do, return a (N, EVR, Flags) tuple. */
    00154     if (rpmdsNext(s->ds) >= 0) {
    00155         const char * N = rpmdsN(s->ds);
    00156         const char * EVR = rpmdsEVR(s->ds);
    00157         int tagN = rpmdsTagN(s->ds);
    00158         int Flags = rpmdsFlags(s->ds);
    00159
    00160 /*@-branchstate@*/
    00161         if (N != NULL) N = xstrdup(N);
    00162         if (EVR != NULL) EVR = xstrdup(EVR);
    00163 /*@=branchstate@*/
    00164         result = (PyObject *)rpmds_Wrap( rpmdsSingle(tagN, N, EVR, Flags) );
    00165     } else
    00166         s->active = 0;
    00167
    00168     return result;
    00169 }
    00170
    00175
    00176 /*@null@*/
    00177 static PyObject *
    00178 rpmds_Next(rpmdsObject * s)
    00179         /*@globals _Py_NoneStruct @*/
    00180         /*@modifies s, _Py_NoneStruct @*/
    00181 {
    00182     PyObject * result;
    00183
    00184     result = rpmds_iternext(s);
    00185
    00186     if (result == NULL) {
    00187         Py_INCREF(Py_None);
    00188         return Py_None;
    00189     }
    00190     return result;
    00191 }
    00192
    00193 /*@null@*/
    00194 static PyObject *
    00195 rpmds_Debug(/*@unused@*/ rpmdsObject * s, PyObject * args, PyObject * kwds)
    00196         /*@globals _Py_NoneStruct @*/
    00197         /*@modifies _Py_NoneStruct @*/
    00198 {
    00199     char * kwlist[] = {"debugLevel", NULL};
    00200
    00201     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &_rpmds_debug))
    00202         return NULL;
    00203
    00204     Py_INCREF(Py_None);
    00205     return Py_None;
    00206 }
    00207
    00208 /*@null@*/
    00209 static PyObject *
    00210 rpmds_Count(rpmdsObject * s)
    00211         /*@*/
    00212 {
    00213     return Py_BuildValue("i", rpmdsCount(s->ds));
    00214 }
    00215
    00216 /*@null@*/
    00217 static PyObject *
    00218 rpmds_Ix(rpmdsObject * s)
    00219         /*@*/
    00220 {
    00221     return Py_BuildValue("i", rpmdsIx(s->ds));
    00222 }
    00223
    00224 /*@null@*/
    00225 static PyObject *
    00226 rpmds_DNEVR(rpmdsObject * s)
    00227         /*@*/
    00228 {
    00229     return Py_BuildValue("s", rpmdsDNEVR(s->ds));
    00230 }
    00231
    00232 /*@null@*/
    00233 static PyObject *
    00234 rpmds_N(rpmdsObject * s)
    00235         /*@*/
    00236 {
    00237     return Py_BuildValue("s", rpmdsN(s->ds));
    00238 }
    00239
    00240 /*@null@*/
    00241 static PyObject *
    00242 rpmds_EVR(rpmdsObject * s)
    00243         /*@*/
    00244 {
    00245     return Py_BuildValue("s", rpmdsEVR(s->ds));
    00246 }
    00247
    00248 /*@null@*/
    00249 static PyObject *
    00250 rpmds_Flags(rpmdsObject * s)
    00251         /*@*/
    00252 {
    00253     return Py_BuildValue("i", rpmdsFlags(s->ds));
    00254 }
    00255
    00256 /*@null@*/
    00257 static PyObject *
    00258 rpmds_BT(rpmdsObject * s)
    00259         /*@*/
    00260 {
    00261     return Py_BuildValue("i", (int) rpmdsBT(s->ds));
    00262 }
    00263
    00264 /*@null@*/
    00265 static PyObject *
    00266 rpmds_TagN(rpmdsObject * s)
    00267         /*@*/
    00268 {
    00269     return Py_BuildValue("i", rpmdsTagN(s->ds));
    00270 }
    00271
    00272 /*@null@*/
    00273 static PyObject *
    00274 rpmds_Color(rpmdsObject * s)
    00275         /*@*/
    00276 {
    00277     return Py_BuildValue("i", rpmdsColor(s->ds));
    00278 }
    00279
    00280 /*@null@*/
    00281 static PyObject *
    00282 rpmds_Refs(rpmdsObject * s)
    00283         /*@*/
    00284 {
    00285     return Py_BuildValue("i", rpmdsRefs(s->ds));
    00286 }
    00287
    00288 /*@null@*/
    00289 static PyObject *
    00290 rpmds_Result(rpmdsObject * s)
    00291         /*@*/
    00292 {
    00293     return Py_BuildValue("i", rpmdsResult(s->ds));
    00294 }
    00295 /*@null@*/
    00296 static PyObject *
    00297 rpmds_SetNoPromote(rpmdsObject * s, PyObject * args, PyObject * kwds)
    00298         /*@modifies s @*/
    00299 {
    00300     int nopromote;
    00301     char * kwlist[] = {"noPromote", NULL};
    00302
    00303     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:SetNoPromote", kwlist,
    00304             &nopromote))
    00305         return NULL;
    00306
    00307     return Py_BuildValue("i", rpmdsSetNoPromote(s->ds, nopromote));
    00308 }
    00309
    00310 /*@null@*/
    00311 static PyObject *
    00312 rpmds_Notify(rpmdsObject * s, PyObject * args, PyObject * kwds)
    00313         /*@globals _Py_NoneStruct @*/
    00314         /*@modifies _Py_NoneStruct @*/
    00315 {
    00316     const char * where;
    00317     int rc;
    00318     char * kwlist[] = {"location", "returnCode", NULL};
    00319
    00320     if (!PyArg_ParseTupleAndKeywords(args, kwds, "si:Notify", kwlist,
    00321             &where, &rc))
    00322         return NULL;
    00323
    00324     rpmdsNotify(s->ds, where, rc);
    00325     Py_INCREF(Py_None);
    00326     return Py_None;
    00327 }
    00328
    00329 /* XXX rpmdsFind uses bsearch on s->ds, so a sort is needed. */
    00330 /*@null@*/
    00331 static PyObject *
    00332 rpmds_Sort(rpmdsObject * s)
    00333         /*@globals _Py_NoneStruct @*/
    00334         /*@modifies _Py_NoneStruct @*/
    00335 {
    00336     rpmds nds = NULL;
    00337
    00338     if (rpmdsMerge(&nds, s->ds) >= 0) {
    00339         s->ds = rpmdsFree(s->ds);
    00340         s->ds = nds;
    00341     }
    00342     Py_INCREF(Py_None);
    00343     return Py_None;
    00344 }
    00345
    00346 /*@null@*/
    00347 static PyObject *
    00348 rpmds_Find(rpmdsObject * s, PyObject * args, PyObject * kwds)
    00349         /*@modifies s @*/
    00350 {
    00351     PyObject * to = NULL;
    00352     rpmdsObject * o;
    00353     char * kwlist[] = {"element", NULL};
    00354
    00355     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:Find", kwlist, &to))
    00356         return NULL;
    00357
    00358     /* XXX ds type check needed. */
    00359     o = (rpmdsObject *)to;
    00360
    00361     /* XXX make sure ods index is valid, real fix in lib/rpmds.c. */
    00362     if (rpmdsIx(o->ds) == -1)   rpmdsSetIx(o->ds, 0);
    00363
    00364     return Py_BuildValue("i", rpmdsFind(s->ds, o->ds));
    00365 }
    00366
    00367 /*@null@*/
    00368 static PyObject *
    00369 rpmds_Merge(rpmdsObject * s, PyObject * args, PyObject * kwds)
    00370         /*@modifies s @*/
    00371 {
    00372     PyObject * to = NULL;
    00373     rpmdsObject * o;
    00374     char * kwlist[] = {"element", NULL};
    00375
    00376     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:Merge", kwlist, &to))
    00377         return NULL;
    00378
    00379     /* XXX ds type check needed. */
    00380     o = (rpmdsObject *)to;
    00381     return Py_BuildValue("i", rpmdsMerge(&s->ds, o->ds));
    00382 }
    00383
    00384 /*@null@*/
    00385 static PyObject *
    00386 rpmds_Search(rpmdsObject * s, PyObject * args, PyObject * kwds)
    00387         /*@modifies s @*/
    00388 {
    00389     PyObject * to = NULL;
    00390     rpmdsObject * o;
    00391     char * kwlist[] = {"element", NULL};
    00392
    00393     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:Merge", kwlist, &to))
    00394         return NULL;
    00395
    00396     /* XXX ds type check needed. */
    00397     o = (rpmdsObject *)to;
    00398     return Py_BuildValue("i", rpmdsSearch(s->ds, o->ds));
    00399 }
    00400
    00401 static PyObject *
    00402 rpmds_Cpuinfo(rpmdsObject * s)
    00403         /*@*/
    00404 {
    00405     rpmds ds = NULL;
    00406     int xx;
    00407
    00408     /* XXX check return code, permit arg (NULL uses system default). */
    00409     xx = rpmdsCpuinfo(&ds, NULL);
    00410
    00411     return (PyObject *) rpmds_Wrap( ds );
    00412 }
    00413
    00414 static PyObject *
    00415 rpmds_Rpmlib(rpmdsObject * s)
    00416         /*@*/
    00417 {
    00418     rpmds ds = NULL;
    00419     int xx;
    00420
    00421     /* XXX check return code, permit arg (NULL uses system default). */
    00422     xx = rpmdsRpmlib(&ds, NULL);
    00423
    00424     return (PyObject *) rpmds_Wrap( ds );
    00425 }
    00426
    00427 static PyObject *
    00428 rpmds_Sysinfo(rpmdsObject * s)
    00429         /*@*/
    00430 {
    00431     rpmPRCO PRCO = rpmdsNewPRCO(NULL);
    00432     rpmds P = NULL;
    00433     int xx;
    00434
    00435     /* XXX check return code, permit arg (NULL uses system default). */
    00436     xx = rpmdsSysinfo(PRCO, NULL);
    00437     P = rpmdsLink(rpmdsFromPRCO(PRCO, RPMTAG_PROVIDENAME), "rpmds_Sysinfo");
    00438     PRCO = rpmdsFreePRCO(PRCO);
    00439
    00440     return (PyObject *) rpmds_Wrap( P );
    00441 }
    00442
    00443 static PyObject *
    00444 rpmds_Getconf(rpmdsObject * s)
    00445         /*@*/
    00446 {
    00447     rpmds ds = NULL;
    00448     int xx;
    00449
    00450     /* XXX check return code, permit arg (NULL uses system default). */
    00451     xx = rpmdsGetconf(&ds, NULL);
    00452
    00453     return (PyObject *) rpmds_Wrap( ds );
    00454 }
    00455
    00456 static PyObject *
    00457 rpmds_Ldconfig(rpmdsObject * s)
    00458         /*@*/
    00459 {
    00460     rpmPRCO PRCO = rpmdsNewPRCO(NULL);
    00461     rpmds P = NULL;
    00462     int xx;
    00463
    00464     /* XXX check return code, permit arg (NULL uses system default). */
    00465     xx = rpmdsLdconfig(PRCO, NULL);
    00466
    00467     P = rpmdsLink(rpmdsFromPRCO(PRCO, RPMTAG_PROVIDENAME), "rpmds_Ldconfig");
    00468     PRCO = rpmdsFreePRCO(PRCO);
    00469     return (PyObject *) rpmds_Wrap( P );
    00470 }
    00471
    00472 static PyObject *
    00473 rpmds_Uname(rpmdsObject * s)
    00474         /*@*/
    00475 {
    00476     rpmds ds = NULL;
    00477     int xx;
    00478
    00479     /* XXX check return code, permit arg (NULL uses system default). */
    00480     xx = rpmdsUname(&ds, NULL);
    00481
    00482     return (PyObject *) rpmds_Wrap( ds );
    00483 }
    00484
    00485 #ifdef  NOTYET
    00486 static PyObject *
    00487 rpmds_Compare(rpmdsObject * s, PyObject * args, PyObject * kwds)
    00488         /*@modifies s @*/
    00489 {
    00490     PyObject * to = NULL;
    00491     rpmdsObject * o;
    00492     char * kwlist[] = {"other", NULL};
    00493
    00494     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:Compare", kwlist, &to))
    00495         return NULL;
    00496
    00497     /* XXX ds type check needed. */
    00498     o = (rpmdsObject *)to;
    00499     return Py_BuildValue("i", rpmdsCompare(s->ds, o->ds));
    00500 }
    00501
    00502 /*@null@*/
    00503 static PyObject *
    00504 rpmds_Problem(rpmdsObject * s)
    00505         /*@*/
    00506 {
    00507     if (!PyArg_ParseTuple(args, ":Problem"))
    00508         return NULL;
    00509     Py_INCREF(Py_None);
    00510     return Py_None;
    00511 }
    00512 #endif
    00513
    00516 /*@-fullinitblock@*/
    00517 /*@unchecked@*/ /*@observer@*/
    00518 static struct PyMethodDef rpmds_methods[] = {
    00519  {"Debug",      (PyCFunction)rpmds_Debug,       METH_VARARGS|METH_KEYWORDS,
    00520         NULL},
    00521  {"Count",      (PyCFunction)rpmds_Count,       METH_NOARGS,
    00522         "ds.Count -> Count      - Return no. of elements.\n" },
    00523  {"Ix",         (PyCFunction)rpmds_Ix,          METH_NOARGS,
    00524         "ds.Ix -> Ix            - Return current element index.\n" },
    00525  {"DNEVR",      (PyCFunction)rpmds_DNEVR,       METH_NOARGS,
    00526         "ds.DNEVR -> DNEVR      - Return current DNEVR.\n" },
    00527  {"N",          (PyCFunction)rpmds_N,           METH_NOARGS,
    00528         "ds.N -> N              - Return current N.\n" },
    00529  {"EVR",        (PyCFunction)rpmds_EVR,         METH_NOARGS,
    00530         "ds.EVR -> EVR          - Return current EVR.\n" },
    00531  {"Flags",      (PyCFunction)rpmds_Flags,       METH_NOARGS,
    00532         "ds.Flags -> Flags      - Return current Flags.\n" },
    00533  {"BT",         (PyCFunction)rpmds_BT,          METH_NOARGS,
    00534         "ds.BT -> BT    - Return build time.\n" },
    00535  {"TagN",       (PyCFunction)rpmds_TagN,        METH_NOARGS,
    00536         "ds.TagN -> TagN        - Return current TagN.\n" },
    00537  {"Color",      (PyCFunction)rpmds_Color,       METH_NOARGS,
    00538         "ds.Color -> Color      - Return current Color.\n" },
    00539  {"Refs",       (PyCFunction)rpmds_Refs,        METH_NOARGS,
    00540         "ds.Refs -> Refs        - Return current Refs.\n" },
    00541  {"Result",     (PyCFunction)rpmds_Result,      METH_NOARGS,
    00542         "ds.Result -> Result    - Return current Result.\n" },
    00543  {"next",       (PyCFunction)rpmds_Next,        METH_NOARGS,
    00544 "ds.next() -> (N, EVR, Flags)\n\
    00545 - Retrieve next dependency triple.\n" },
    00546  {"SetNoPromote",(PyCFunction)rpmds_SetNoPromote, METH_VARARGS|METH_KEYWORDS,
    00547         NULL},
    00548  {"Notify",     (PyCFunction)rpmds_Notify,      METH_VARARGS|METH_KEYWORDS,
    00549         NULL},
    00550  {"Sort",       (PyCFunction)rpmds_Sort,        METH_NOARGS,
    00551 "ds.Sort() -> None\n\
    00552 - Sort the (N,EVR,Flags) elements in ds\n" },
    00553  {"Find",       (PyCFunction)rpmds_Find,        METH_VARARGS|METH_KEYWORDS,
    00554 "ds.Find(element) -> matching ds index (-1 on failure)\n\
    00555 - Check for an exactly matching element in ds.\n\
    00556 The current index in ds is positioned at matching member upon success.\n" },
    00557  {"Merge",      (PyCFunction)rpmds_Merge,       METH_VARARGS|METH_KEYWORDS,
    00558 "ds.Merge(elements) -> 0 on success\n\
    00559 - Merge elements into ds, maintaining (N,EVR,Flags) sort order.\n" },
    00560  {"Search",     (PyCFunction)rpmds_Search,      METH_VARARGS|METH_KEYWORDS,
    00561 "ds.Search(element) -> matching ds index (-1 on failure)\n\
    00562 - Check that element dependency range overlaps some member of ds.\n\
    00563 The current index in ds is positioned at overlapping member upon success.\n" },
    00564  {"Cpuinfo",    (PyCFunction)rpmds_Cpuinfo,     METH_NOARGS|METH_STATIC,
    00565         "ds.Cpuinfo -> nds      - Return /proc/cpuinfo dependency set.\n"},
    00566  {"Rpmlib",     (PyCFunction)rpmds_Rpmlib,      METH_NOARGS|METH_STATIC,
    00567         "ds.Rpmlib -> nds       - Return internal rpmlib dependency set.\n"},
    00568  {"Sysinfo",    (PyCFunction)rpmds_Sysinfo,     METH_NOARGS|METH_STATIC,
    00569         "ds.Sysinfo -> nds      - Return /etc/rpm/sysinfo dependency set.\n"},
    00570  {"Getconf",    (PyCFunction)rpmds_Getconf,     METH_NOARGS|METH_STATIC,
    00571         "ds.Getconf -> nds      - Return getconf(1) dependency set.\n"},
    00572  {"Ldconfig",   (PyCFunction)rpmds_Ldconfig,    METH_NOARGS|METH_STATIC,
    00573         "ds.Ldconfig -> nds     - Return /etc/ld.so.cache dependency set.\n"},
    00574  {"Uname",      (PyCFunction)rpmds_Uname,       METH_NOARGS|METH_STATIC,
    00575         "ds.Uname -> nds        - Return uname(2) dependency set.\n"},
    00576 #ifdef  NOTYET
    00577  {"Compare",    (PyCFunction)rpmds_Compare,     METH_VARARGS|METH_KEYWORDS,
    00578         NULL},
    00579  {"Problem",    (PyCFunction)rpmds_Problem,     METH_NOARGS,
    00580         NULL},
    00581 #endif
    00582  {NULL,         NULL}           /* sentinel */
    00583 };
    00584 /*@=fullinitblock@*/
    00585
    00586 /* ---------- */
    00587
    00588 static void
    00589 rpmds_dealloc(rpmdsObject * s)
    00590         /*@modifies s @*/
    00591 {
    00592     if (s) {
    00593         s->ds = rpmdsFree(s->ds);
    00594         PyObject_Del(s);
    00595     }
    00596 }
    00597
    00598 static int
    00599 rpmds_print(rpmdsObject * s, FILE * fp, /*@unused@*/ int flags)
    00600         /*@globals fileSystem @*/
    00601         /*@modifies s, fp, fileSystem @*/
    00602 {
    00603     if (!(s && s->ds))
    00604         return -1;
    00605
    00606     s->ds = rpmdsInit(s->ds);
    00607     while (rpmdsNext(s->ds) >= 0)
    00608         fprintf(fp, "%s\n", rpmdsDNEVR(s->ds));
    00609     return 0;
    00610 }
    00611
    00612 static PyObject * rpmds_getattro(PyObject * o, PyObject * n)
    00613         /*@*/
    00614 {
    00615     return PyObject_GenericGetAttr(o, n);
    00616 }
    00617
    00618 static int rpmds_setattro(PyObject * o, PyObject * n, PyObject * v)
    00619         /*@*/
    00620 {
    00621     return PyObject_GenericSetAttr(o, n, v);
    00622 }
    00623
    00624 static int
    00625 rpmds_length(rpmdsObject * s)
    00626         /*@*/
    00627 {
    00628     return rpmdsCount(s->ds);
    00629 }
    00630
    00631 /*@null@*/
    00632 static PyObject *
    00633 rpmds_subscript(rpmdsObject * s, PyObject * key)
    00634         /*@modifies s @*/
    00635 {
    00636     int ix;
    00637
    00638     if (!PyInt_Check(key)) {
    00639         PyErr_SetString(PyExc_TypeError, "integer expected");
    00640         return NULL;
    00641     }
    00642
    00643     ix = (int) PyInt_AsLong(key);
    00644     /* XXX make sure that DNEVR exists. */
    00645     rpmdsSetIx(s->ds, ix-1);
    00646     (void) rpmdsNext(s->ds);
    00647     return Py_BuildValue("s", rpmdsDNEVR(s->ds));
    00648 }
    00649
    00650 static PyMappingMethods rpmds_as_mapping = {
    00651         (inquiry) rpmds_length,         /* mp_length */
    00652         (binaryfunc) rpmds_subscript,   /* mp_subscript */
    00653         (objobjargproc)0,               /* mp_ass_subscript */
    00654 };
    00655
    00658 static int rpmds_init(rpmdsObject * s, PyObject *args, PyObject *kwds)
    00659         /*@globals rpmGlobalMacroContext @*/
    00660         /*@modifies s, rpmGlobalMacroContext @*/
    00661 {
    00662     hdrObject * ho = NULL;
    00663     PyObject * to = NULL;
    00664     int tagN = RPMTAG_REQUIRENAME;
    00665     int flags = 0;
    00666     char * kwlist[] = {"header", "tag", "flags", NULL};
    00667
    00668 if (_rpmds_debug < 0)
    00669 fprintf(stderr, "*** rpmds_init(%p,%p,%p)\n", s, args, kwds);
    00670
    00671     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|Oi:rpmds_init", kwlist,
    00672             &hdr_Type, &ho, &to, &flags))
    00673         return -1;
    00674
    00675     if (to != NULL) {
    00676         tagN = tagNumFromPyObject(to);
    00677         if (tagN == -1) {
    00678             PyErr_SetString(PyExc_KeyError, "unknown header tag");
    00679             return -1;
    00680         }
    00681     }
    00682     s->ds = rpmdsNew(hdrGetHeader(ho), tagN, flags);
    00683     s->active = 0;
    00684
    00685     return 0;
    00686 }
    00687
    00690 static void rpmds_free(/*@only@*/ rpmdsObject * s)
    00691         /*@modifies s @*/
    00692 {
    00693 if (_rpmds_debug)
    00694 fprintf(stderr, "%p -- ds %p\n", s, s->ds);
    00695     s->ds = rpmdsFree(s->ds);
    00696
    00697     PyObject_Del((PyObject *)s);
    00698 }
    00699
    00702 static PyObject * rpmds_alloc(PyTypeObject * subtype, int nitems)
    00703         /*@*/
    00704 {
    00705     PyObject * s = PyType_GenericAlloc(subtype, nitems);
    00706
    00707 if (_rpmds_debug < 0)
    00708 fprintf(stderr, "*** rpmds_alloc(%p,%d) ret %p\n", subtype, nitems, s);
    00709     return s;
    00710 }
    00711
    00714 /*@null@*/
    00715 static PyObject * rpmds_new(PyTypeObject * subtype, PyObject *args, PyObject *kwds)
    00716         /*@globals rpmGlobalMacroContext @*/
    00717         /*@modifies rpmGlobalMacroContext @*/
    00718 {
    00719     rpmdsObject * s = (void *) PyObject_New(rpmdsObject, subtype);
    00720
    00721     /* Perform additional initialization. */
    00722     if (rpmds_init(s, args, kwds) < 0) {
    00723         rpmds_free(s);
    00724         return NULL;
    00725     }
    00726
    00727 if (_rpmds_debug)
    00728 fprintf(stderr, "%p ++ ds %p\n", s, s->ds);
    00729
    00730     return (PyObject *)s;
    00731 }
    00732
    00735 /*@unchecked@*/ /*@observer@*/
    00736 static char rpmds_doc[] =
    00737 "";
    00738
    00739 /*@-fullinitblock@*/
    00740 PyTypeObject rpmds_Type = {
    00741         PyObject_HEAD_INIT(&PyType_Type)
    00742         0,                              /* ob_size */
    00743         "rpm.ds",                       /* tp_name */
    00744         sizeof(rpmdsObject),            /* tp_basicsize */
    00745         0,                              /* tp_itemsize */
    00746         /* methods */
    00747         (destructor) rpmds_dealloc,     /* tp_dealloc */
    00748         (printfunc) rpmds_print,        /* tp_print */
    00749         (getattrfunc)0,                 /* tp_getattr */
    00750         (setattrfunc)0,                 /* tp_setattr */
    00751         (cmpfunc) rpmds_compare,        /* tp_compare */
    00752         (reprfunc)0,                    /* tp_repr */
    00753         0,                              /* tp_as_number */
    00754         0,                              /* tp_as_sequence */
    00755         &rpmds_as_mapping,              /* tp_as_mapping */
    00756         (hashfunc)0,                    /* tp_hash */
    00757         (ternaryfunc)0,                 /* tp_call */
    00758         (reprfunc)0,                    /* tp_str */
    00759         (getattrofunc) rpmds_getattro,  /* tp_getattro */
    00760         (setattrofunc) rpmds_setattro,  /* tp_setattro */
    00761         0,                              /* tp_as_buffer */
    00762         Py_TPFLAGS_DEFAULT |            /* tp_flags */
    00763             Py_TPFLAGS_HAVE_RICHCOMPARE,
    00764         rpmds_doc,                      /* tp_doc */
    00765 #if Py_TPFLAGS_HAVE_ITER
    00766         0,                              /* tp_traverse */
    00767         0,                              /* tp_clear */
    00768         (richcmpfunc) rpmds_richcompare,/* tp_richcompare */
    00769         0,                              /* tp_weaklistoffset */
    00770         (getiterfunc) rpmds_iter,       /* tp_iter */
    00771         (iternextfunc) rpmds_iternext,  /* tp_iternext */
    00772         rpmds_methods,                  /* tp_methods */
    00773         0,                              /* tp_members */
    00774         0,                              /* tp_getset */
    00775         0,                              /* tp_base */
    00776         0,                              /* tp_dict */
    00777         0,                              /* tp_descr_get */
    00778         0,                              /* tp_descr_set */
    00779         0,                              /* tp_dictoffset */
    00780         (initproc) rpmds_init,          /* tp_init */
    00781         (allocfunc) rpmds_alloc,        /* tp_alloc */
    00782         (newfunc) rpmds_new,            /* tp_new */
    00783         (freefunc) rpmds_free,          /* tp_free */
    00784         0,                              /* tp_is_gc */
    00785 #endif
    00786 };
    00787 /*@=fullinitblock@*/
    00788
    00789 /* ---------- */
    00790
    00791 rpmds dsFromDs(rpmdsObject * s)
    00792 {
    00793     return s->ds;
    00794 }
    00795
    00796 rpmdsObject *
    00797 rpmds_Wrap(rpmds ds)
    00798 {
    00799     rpmdsObject * s = PyObject_New(rpmdsObject, &rpmds_Type);
    00800
    00801     if (s == NULL)
    00802         return NULL;
    00803     s->ds = ds;
    00804     s->active = 0;
    00805     return s;
    00806 }
    00807
    00808
    00809 rpmdsObject *
    00810 rpmds_Single(/*@unused@*/ PyObject * s, PyObject * args, PyObject * kwds)
    00811 {
    00812     PyObject * to = NULL;
    00813     int tagN = RPMTAG_PROVIDENAME;
    00814     const char * N;
    00815     const char * EVR = NULL;
    00816     int Flags = 0;
    00817     char * kwlist[] = {"to", "name", "evr", "flags", NULL};
    00818
    00819     if (!PyArg_ParseTupleAndKeywords(args, kwds, "Os|si:Single", kwlist,
    00820             &to, &N, &EVR, &Flags))
    00821         return NULL;
    00822
    00823     if (to != NULL) {
    00824         tagN = tagNumFromPyObject(to);
    00825         if (tagN == -1) {
    00826             PyErr_SetString(PyExc_KeyError, "unknown header tag");
    00827             return NULL;
    00828         }
    00829     }
    00830     if (N != NULL) N = xstrdup(N);
    00831     if (EVR != NULL) EVR = xstrdup(EVR);
    00832     return rpmds_Wrap( rpmdsSingle(tagN, N, EVR, Flags) );
    00833 }
    00834
    00835 rpmdsObject *
    00836 hdr_dsFromHeader(PyObject * s, PyObject * args, PyObject * kwds)
    00837 {
    00838     hdrObject * ho = (hdrObject *)s;
    00839     PyObject * to = NULL;
    00840     rpmTag tagN = RPMTAG_REQUIRENAME;
    00841     int flags = 0;
    00842     char * kwlist[] = {"to", "flags", NULL};
    00843
    00844     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:dsFromHeader", kwlist,
    00845             &to, &flags))
    00846         return NULL;
    00847
    00848     if (to != NULL) {
    00849         tagN = tagNumFromPyObject(to);
    00850         if (tagN == -1) {
    00851             PyErr_SetString(PyExc_KeyError, "unknown header tag");
    00852             return NULL;
    00853         }
    00854     }
    00855     return rpmds_Wrap( rpmdsNew(hdrGetHeader(ho), tagN, flags) );
    00856 }
    00857
    00858 rpmdsObject *
    00859 hdr_dsOfHeader(PyObject * s)
    00860 {
    00861     hdrObject * ho = (hdrObject *)s;
    00862     int tagN = RPMTAG_PROVIDENAME;
    00863     int Flags = RPMSENSE_EQUAL;
    00864
    00865     return rpmds_Wrap( rpmdsThis(hdrGetHeader(ho), tagN, Flags) );
    00866 }