Main Page | Modules | Data Structures | File List | Data Fields | Globals | Related Pages

python/rpmds-py.c

Go to the documentation of this file.
00001 
00005 #include "system.h"
00006 
00007 #include <rpmlib.h>
00008 
00009 #include "header-py.h"
00010 #include "rpmds-py.h"
00011 
00012 #include "debug.h"
00013 
00014 /*@access rpmds @*/
00015 
00023 static
00024 void rpmds_ParseEVR(char * evr,
00025                 /*@exposed@*/ /*@out@*/ const char ** ep,
00026                 /*@exposed@*/ /*@out@*/ const char ** vp,
00027                 /*@exposed@*/ /*@out@*/ const char ** rp)
00028         /*@modifies *ep, *vp, *rp @*/
00029         /*@requires maxSet(ep) >= 0 /\ maxSet(vp) >= 0 /\ maxSet(rp) >= 0 @*/
00030 {
00031     const char *epoch;
00032     const char *version;                /* assume only version is present */
00033     const char *release;
00034     char *s, *se;
00035 
00036     s = evr;
00037     while (*s && xisdigit(*s)) s++;     /* s points to epoch terminator */
00038     se = strrchr(s, '-');               /* se points to version terminator */
00039 
00040     if (*s == ':') {
00041         epoch = evr;
00042         *s++ = '\0';
00043         version = s;
00044         /*@-branchstate@*/
00045         if (*epoch == '\0') epoch = "0";
00046         /*@=branchstate@*/
00047     } else {
00048         epoch = NULL;   /* XXX disable epoch compare if missing */
00049         version = evr;
00050     }
00051     if (se) {
00052 /*@-boundswrite@*/
00053         *se++ = '\0';
00054 /*@=boundswrite@*/
00055         release = se;
00056     } else {
00057         release = NULL;
00058     }
00059 
00060     if (ep) *ep = epoch;
00061     if (vp) *vp = version;
00062     if (rp) *rp = release;
00063 }
00064 
00065 /*@null@*/
00066 static PyObject *
00067 rpmds_Debug(/*@unused@*/ rpmdsObject * s, PyObject * args)
00068         /*@globals _Py_NoneStruct @*/
00069         /*@modifies _Py_NoneStruct @*/
00070 {
00071     if (!PyArg_ParseTuple(args, "i", &_rpmds_debug)) return NULL;
00072     Py_INCREF(Py_None);
00073     return Py_None;
00074 }
00075 
00076 /*@null@*/
00077 static PyObject *
00078 rpmds_Count(rpmdsObject * s, PyObject * args)
00079         /*@*/
00080 {
00081     if (!PyArg_ParseTuple(args, ":Count")) return NULL;
00082     return Py_BuildValue("i", rpmdsCount(s->ds));
00083 }
00084 
00085 /*@null@*/
00086 static PyObject *
00087 rpmds_Ix(rpmdsObject * s, PyObject * args)
00088         /*@*/
00089 {
00090     if (!PyArg_ParseTuple(args, ":Ix")) return NULL;
00091     return Py_BuildValue("i", rpmdsIx(s->ds));
00092 }
00093 
00094 /*@null@*/
00095 static PyObject *
00096 rpmds_DNEVR(rpmdsObject * s, PyObject * args)
00097         /*@*/
00098 {
00099     if (!PyArg_ParseTuple(args, ":DNEVR")) return NULL;
00100     return Py_BuildValue("s", rpmdsDNEVR(s->ds));
00101 }
00102 
00103 /*@null@*/
00104 static PyObject *
00105 rpmds_N(rpmdsObject * s, PyObject * args)
00106         /*@*/
00107 {
00108     if (!PyArg_ParseTuple(args, ":N")) return NULL;
00109     return Py_BuildValue("s", rpmdsN(s->ds));
00110 }
00111 
00112 /*@null@*/
00113 static PyObject *
00114 rpmds_EVR(rpmdsObject * s, PyObject * args)
00115         /*@*/
00116 {
00117     if (!PyArg_ParseTuple(args, ":EVR")) return NULL;
00118     return Py_BuildValue("s", rpmdsEVR(s->ds));
00119 }
00120 
00121 /*@null@*/
00122 static PyObject *
00123 rpmds_Flags(rpmdsObject * s, PyObject * args)
00124         /*@*/
00125 {
00126     if (!PyArg_ParseTuple(args, ":Flags")) return NULL;
00127     return Py_BuildValue("i", rpmdsFlags(s->ds));
00128 }
00129 
00130 /*@null@*/
00131 static PyObject *
00132 rpmds_BT(rpmdsObject * s, PyObject * args)
00133         /*@*/
00134 {
00135     if (!PyArg_ParseTuple(args, ":BT")) return NULL;
00136     return Py_BuildValue("i", (int) rpmdsBT(s->ds));
00137 }
00138 
00139 /*@null@*/
00140 static PyObject *
00141 rpmds_TagN(rpmdsObject * s, PyObject * args)
00142         /*@*/
00143 {
00144     if (!PyArg_ParseTuple(args, ":TagN")) return NULL;
00145     return Py_BuildValue("i", rpmdsTagN(s->ds));
00146 }
00147 
00148 /*@null@*/
00149 static PyObject *
00150 rpmds_Color(rpmdsObject * s, PyObject * args)
00151         /*@*/
00152 {
00153     if (!PyArg_ParseTuple(args, ":Color")) return NULL;
00154     return Py_BuildValue("i", rpmdsColor(s->ds));
00155 }
00156 
00157 /*@null@*/
00158 static PyObject *
00159 rpmds_Refs(rpmdsObject * s, PyObject * args)
00160         /*@*/
00161 {
00162     if (!PyArg_ParseTuple(args, ":Refs")) return NULL;
00163     return Py_BuildValue("i", rpmdsRefs(s->ds));
00164 }
00165 
00168 static int compare_values(const char *str1, const char *str2)
00169 {
00170     if (!str1 && !str2)
00171         return 0;
00172     else if (str1 && !str2)
00173         return 1;
00174     else if (!str1 && str2)
00175         return -1;
00176     return rpmvercmp(str1, str2);
00177 }
00178 
00179 static int
00180 rpmds_compare(rpmdsObject * a, rpmdsObject * b)
00181         /*@*/
00182 {
00183     char *aEVR = xstrdup(rpmdsEVR(a->ds));
00184     const char *aE, *aV, *aR;
00185     char *bEVR = xstrdup(rpmdsEVR(b->ds));
00186     const char *bE, *bV, *bR;
00187     int rc;
00188 
00189     /* XXX W2DO? should N be compared? */
00190     rpmds_ParseEVR(aEVR, &aE, &aV, &aR);
00191     rpmds_ParseEVR(bEVR, &bE, &bV, &bR);
00192 
00193     rc = compare_values(aE, bE);
00194     if (!rc) {
00195         rc = compare_values(aV, bV);
00196         if (!rc)
00197             rc = compare_values(aR, bR);
00198     }
00199 
00200     aEVR = _free(aEVR);
00201     bEVR = _free(bEVR);
00202 
00203     return rc;
00204 }
00205 
00206 static PyObject *
00207 rpmds_richcompare(rpmdsObject * a, rpmdsObject * b, int op)
00208         /*@*/
00209 {
00210     int rc;
00211 
00212     switch (op) {
00213     case Py_NE:
00214         /* XXX map ranges overlap boolean onto '!=' python syntax. */
00215         rc = rpmdsCompare(a->ds, b->ds);
00216         rc = (rc < 0 ? -1 : (rc == 0 ? 1 : 0));
00217         break;
00218     case Py_LT:
00219     case Py_LE:
00220     case Py_GT:
00221     case Py_GE:
00222     case Py_EQ:
00223         /*@fallthrough@*/
00224     default:
00225         rc = -1;
00226         break;
00227     }
00228     return Py_BuildValue("i", rc);
00229 }
00230 
00231 static PyObject *
00232 rpmds_iter(rpmdsObject * s)
00233         /*@*/
00234 {
00235     Py_INCREF(s);
00236     return (PyObject *)s;
00237 }
00238 
00239 /*@null@*/
00240 static PyObject *
00241 rpmds_iternext(rpmdsObject * s)
00242         /*@globals _Py_NoneStruct @*/
00243         /*@modifies s, _Py_NoneStruct @*/
00244 {
00245     PyObject * result = NULL;
00246 
00247     /* Reset loop indices on 1st entry. */
00248     if (!s->active) {
00249         s->ds = rpmdsInit(s->ds);
00250         s->active = 1;
00251     }
00252 
00253     /* If more to do, return a (N, EVR, Flags) tuple. */
00254     if (rpmdsNext(s->ds) >= 0) {
00255         const char * N = rpmdsN(s->ds);
00256         const char * EVR = rpmdsEVR(s->ds);
00257         int Flags = rpmdsFlags(s->ds);
00258 
00259         result = PyTuple_New(3);
00260         PyTuple_SET_ITEM(result, 0, Py_BuildValue("s", N));
00261         if (EVR == NULL) {
00262             Py_INCREF(Py_None);
00263             PyTuple_SET_ITEM(result, 1, Py_None);
00264             Py_INCREF(Py_None);
00265             PyTuple_SET_ITEM(result, 2, Py_None);
00266         } else {
00267             PyTuple_SET_ITEM(result, 1, Py_BuildValue("s", EVR));
00268             PyTuple_SET_ITEM(result, 2, PyInt_FromLong(Flags));
00269         }
00270 
00271     } else
00272         s->active = 0;
00273 
00274     return result;
00275 }
00276 
00277 /*@null@*/
00278 static PyObject *
00279 rpmds_Next(rpmdsObject * s, PyObject *args)
00280         /*@globals _Py_NoneStruct @*/
00281         /*@modifies s, _Py_NoneStruct @*/
00282 {
00283     PyObject * result;
00284 
00285     if (!PyArg_ParseTuple(args, ":Next"))
00286         return NULL;
00287 
00288     result = rpmds_iternext(s);
00289 
00290     if (result == NULL) {
00291         Py_INCREF(Py_None);
00292         return Py_None;
00293     }
00294     return result;
00295 }
00296 
00297 /*@null@*/
00298 static PyObject *
00299 rpmds_SetNoPromote(rpmdsObject * s, PyObject * args)
00300         /*@modifies s @*/
00301 {
00302     int nopromote;
00303 
00304     if (!PyArg_ParseTuple(args, "i:SetNoPromote", &nopromote))
00305         return NULL;
00306     return Py_BuildValue("i", rpmdsSetNoPromote(s->ds, nopromote));
00307 }
00308 
00309 /*@null@*/
00310 static PyObject *
00311 rpmds_Notify(rpmdsObject * s, PyObject * args)
00312         /*@globals _Py_NoneStruct @*/
00313         /*@modifies _Py_NoneStruct @*/
00314 {
00315     const char * where;
00316     int rc;
00317 
00318     if (!PyArg_ParseTuple(args, "si:Notify", &where, &rc))
00319         return NULL;
00320     rpmdsNotify(s->ds, where, rc);
00321     Py_INCREF(Py_None);
00322     return Py_None;
00323 }
00324 
00325 #ifdef  NOTYET
00326 /*@null@*/
00327 static PyObject *
00328 rpmds_Problem(rpmdsObject * s, PyObject * args)
00329         /*@*/
00330 {
00331     if (!PyArg_ParseTuple(args, ":Problem"))
00332         return NULL;
00333     Py_INCREF(Py_None);
00334     return Py_None;
00335 }
00336 #endif
00337 
00338 /*@-fullinitblock@*/
00339 /*@unchecked@*/ /*@observer@*/
00340 static struct PyMethodDef rpmds_methods[] = {
00341  {"Debug",      (PyCFunction)rpmds_Debug,       METH_VARARGS,
00342         NULL},
00343  {"Count",      (PyCFunction)rpmds_Count,       METH_VARARGS,
00344         "ds.Count -> Count      - Return no. of elements.\n" },
00345  {"Ix",         (PyCFunction)rpmds_Ix,          METH_VARARGS,
00346         "ds.Ix -> Ix            - Return current element index.\n" },
00347  {"DNEVR",      (PyCFunction)rpmds_DNEVR,       METH_VARARGS,
00348         "ds.DNEVR -> DNEVR      - Return current DNEVR.\n" },
00349  {"N",          (PyCFunction)rpmds_N,           METH_VARARGS,
00350         "ds.N -> N              - Return current N.\n" },
00351  {"EVR",        (PyCFunction)rpmds_EVR,         METH_VARARGS,
00352         "ds.EVR -> EVR          - Return current EVR.\n" },
00353  {"Flags",      (PyCFunction)rpmds_Flags,       METH_VARARGS,
00354         "ds.Flags -> Flags      - Return current Flags.\n" },
00355  {"BT",         (PyCFunction)rpmds_BT,          METH_VARARGS,
00356         "ds.BT -> BT    - Return build time.\n" },
00357  {"TagN",       (PyCFunction)rpmds_TagN,        METH_VARARGS,
00358         "ds.TagN -> TagN        - Return current TagN.\n" },
00359  {"Color",      (PyCFunction)rpmds_Color,       METH_VARARGS,
00360         "ds.Color -> Color      - Return current Color.\n" },
00361  {"Refs",       (PyCFunction)rpmds_Refs,        METH_VARARGS,
00362         "ds.Refs -> Refs        - Return current Refs.\n" },
00363  {"next",       (PyCFunction)rpmds_Next,        METH_VARARGS,
00364 "ds.next() -> (N, EVR, Flags)\n\
00365 - Retrieve next dependency triple.\n" },
00366  {"SetNoPromote",(PyCFunction)rpmds_SetNoPromote, METH_VARARGS,
00367         NULL},
00368  {"Notify",     (PyCFunction)rpmds_Notify,      METH_VARARGS,
00369         NULL},
00370 #ifdef  NOTYET
00371  {"Problem",    (PyCFunction)rpmds_Problem,     METH_VARARGS,
00372         NULL},
00373 #endif
00374  {NULL,         NULL}           /* sentinel */
00375 };
00376 /*@=fullinitblock@*/
00377 
00378 /* ---------- */
00379 
00380 static void
00381 rpmds_dealloc(rpmdsObject * s)
00382         /*@modifies s @*/
00383 {
00384     if (s) {
00385         s->ds = rpmdsFree(s->ds);
00386         PyObject_Del(s);
00387     }
00388 }
00389 
00390 static int
00391 rpmds_print(rpmdsObject * s, FILE * fp, /*@unused@*/ int flags)
00392         /*@globals fileSystem @*/
00393         /*@modifies s, fp, fileSystem @*/
00394 {
00395     if (!(s && s->ds))
00396         return -1;
00397 
00398     s->ds = rpmdsInit(s->ds);
00399     while (rpmdsNext(s->ds) >= 0)
00400         fprintf(fp, "%s\n", rpmdsDNEVR(s->ds));
00401     return 0;
00402 }
00403 
00404 static PyObject * rpmds_getattro(PyObject * o, PyObject * n)
00405         /*@*/
00406 {
00407     return PyObject_GenericGetAttr(o, n);
00408 }
00409 
00410 static int rpmds_setattro(PyObject * o, PyObject * n, PyObject * v)
00411         /*@*/
00412 {
00413     return PyObject_GenericSetAttr(o, n, v);
00414 }
00415 
00416 static int
00417 rpmds_length(rpmdsObject * s)
00418         /*@*/
00419 {
00420     return rpmdsCount(s->ds);
00421 }
00422 
00423 /*@null@*/
00424 static PyObject *
00425 rpmds_subscript(rpmdsObject * s, PyObject * key)
00426         /*@modifies s @*/
00427 {
00428     int ix;
00429 
00430     if (!PyInt_Check(key)) {
00431         PyErr_SetString(PyExc_TypeError, "integer expected");
00432         return NULL;
00433     }
00434 
00435     ix = (int) PyInt_AsLong(key);
00436     /* XXX make sure that DNEVR exists. */
00437     rpmdsSetIx(s->ds, ix-1);
00438     (void) rpmdsNext(s->ds);
00439     return Py_BuildValue("s", rpmdsDNEVR(s->ds));
00440 }
00441 
00442 static PyMappingMethods rpmds_as_mapping = {
00443         (inquiry) rpmds_length,         /* mp_length */
00444         (binaryfunc) rpmds_subscript,   /* mp_subscript */
00445         (objobjargproc)0,               /* mp_ass_subscript */
00446 };
00447 
00450 /*@unchecked@*/ /*@observer@*/
00451 static char rpmds_doc[] =
00452 "";
00453 
00454 /*@-fullinitblock@*/
00455 PyTypeObject rpmds_Type = {
00456         PyObject_HEAD_INIT(&PyType_Type)
00457         0,                              /* ob_size */
00458         "rpm.ds",                       /* tp_name */
00459         sizeof(rpmdsObject),            /* tp_basicsize */
00460         0,                              /* tp_itemsize */
00461         /* methods */
00462         (destructor) rpmds_dealloc,     /* tp_dealloc */
00463         (printfunc) rpmds_print,        /* tp_print */
00464         (getattrfunc)0,                 /* tp_getattr */
00465         (setattrfunc)0,                 /* tp_setattr */
00466         (cmpfunc) rpmds_compare,        /* tp_compare */
00467         (reprfunc)0,                    /* tp_repr */
00468         0,                              /* tp_as_number */
00469         0,                              /* tp_as_sequence */
00470         &rpmds_as_mapping,              /* tp_as_mapping */
00471         (hashfunc)0,                    /* tp_hash */
00472         (ternaryfunc)0,                 /* tp_call */
00473         (reprfunc)0,                    /* tp_str */
00474         (getattrofunc) rpmds_getattro,  /* tp_getattro */
00475         (setattrofunc) rpmds_setattro,  /* tp_setattro */
00476         0,                              /* tp_as_buffer */
00477         Py_TPFLAGS_DEFAULT |            /* tp_flags */
00478             Py_TPFLAGS_HAVE_RICHCOMPARE,
00479         rpmds_doc,                      /* tp_doc */
00480 #if Py_TPFLAGS_HAVE_ITER
00481         0,                              /* tp_traverse */
00482         0,                              /* tp_clear */
00483         (richcmpfunc) rpmds_richcompare,/* tp_richcompare */
00484         0,                              /* tp_weaklistoffset */
00485         (getiterfunc) rpmds_iter,       /* tp_iter */
00486         (iternextfunc) rpmds_iternext,  /* tp_iternext */
00487         rpmds_methods,                  /* tp_methods */
00488         0,                              /* tp_members */
00489         0,                              /* tp_getset */
00490         0,                              /* tp_base */
00491         0,                              /* tp_dict */
00492         0,                              /* tp_descr_get */
00493         0,                              /* tp_descr_set */
00494         0,                              /* tp_dictoffset */
00495         0,                              /* tp_init */
00496         0,                              /* tp_alloc */
00497         0,                              /* tp_new */
00498         0,                              /* tp_free */
00499         0,                              /* tp_is_gc */
00500 #endif
00501 };
00502 /*@=fullinitblock@*/
00503 
00504 /* ---------- */
00505 
00506 rpmds dsFromDs(rpmdsObject * s)
00507 {
00508     return s->ds;
00509 }
00510 
00511 rpmdsObject *
00512 rpmds_Wrap(rpmds ds)
00513 {
00514     rpmdsObject * s = PyObject_New(rpmdsObject, &rpmds_Type);
00515 
00516     if (s == NULL)
00517         return NULL;
00518     s->ds = ds;
00519     s->active = 0;
00520     return s;
00521 }
00522 
00523 rpmdsObject *
00524 rpmds_Single(/*@unused@*/ PyObject * s, PyObject * args)
00525 {
00526     PyObject * to = NULL;
00527     int tagN = RPMTAG_PROVIDENAME;
00528     const char * N;
00529     const char * EVR = NULL;
00530     int Flags = 0;
00531 
00532     if (!PyArg_ParseTuple(args, "Os|si:Single", &to, &N, &EVR, &Flags))
00533         return NULL;
00534     if (to != NULL) {
00535         tagN = tagNumFromPyObject(to);
00536         if (tagN == -1) {
00537             PyErr_SetString(PyExc_KeyError, "unknown header tag");
00538             return NULL;
00539         }
00540     }
00541     if (N != NULL) N = xstrdup(N);
00542     if (EVR != NULL) EVR = xstrdup(EVR);
00543     return rpmds_Wrap( rpmdsSingle(tagN, N, EVR, Flags) );
00544 }
00545 
00546 rpmdsObject *
00547 hdr_dsFromHeader(PyObject * s, PyObject * args)
00548 {
00549     hdrObject * ho = (hdrObject *)s;
00550     PyObject * to = NULL;
00551     rpmTag tagN = RPMTAG_REQUIRENAME;
00552     int scareMem = 0;
00553 
00554     if (!PyArg_ParseTuple(args, "|O:dsFromHeader", &to))
00555         return NULL;
00556     if (to != NULL) {
00557         tagN = tagNumFromPyObject(to);
00558         if (tagN == -1) {
00559             PyErr_SetString(PyExc_KeyError, "unknown header tag");
00560             return NULL;
00561         }
00562     }
00563     return rpmds_Wrap( rpmdsNew(hdrGetHeader(ho), tagN, scareMem) );
00564 }
00565 
00566 rpmdsObject *
00567 hdr_dsOfHeader(PyObject * s, PyObject * args)
00568 {
00569     hdrObject * ho = (hdrObject *)s;
00570     int tagN = RPMTAG_PROVIDENAME;
00571     int Flags = RPMSENSE_EQUAL;
00572 
00573     if (!PyArg_ParseTuple(args, ":dsOfHeader"))
00574         return NULL;
00575     return rpmds_Wrap( rpmdsThis(hdrGetHeader(ho), tagN, Flags) );
00576 }

Generated on Tue Dec 28 15:13:24 2004 for rpm by doxygen 1.3.6