rpm 5.2.1

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

- File List
- Globals

python/rpmds-py.c
Go to the documentation of this file.

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