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

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 tagN = rpmdsTagN(s->ds);
00258         int Flags = rpmdsFlags(s->ds);
00259 
00260         if (N != NULL) N = xstrdup(N);
00261         if (EVR != NULL) EVR = xstrdup(EVR);
00262         result = rpmds_Wrap( rpmdsSingle(tagN, N, EVR, Flags) );
00263     } else
00264         s->active = 0;
00265 
00266     return result;
00267 }
00268 
00269 /*@null@*/
00270 static PyObject *
00271 rpmds_Next(rpmdsObject * s, PyObject *args)
00272         /*@globals _Py_NoneStruct @*/
00273         /*@modifies s, _Py_NoneStruct @*/
00274 {
00275     PyObject * result;
00276 
00277     if (!PyArg_ParseTuple(args, ":Next"))
00278         return NULL;
00279 
00280     result = rpmds_iternext(s);
00281 
00282     if (result == NULL) {
00283         Py_INCREF(Py_None);
00284         return Py_None;
00285     }
00286     return result;
00287 }
00288 
00289 /*@null@*/
00290 static PyObject *
00291 rpmds_SetNoPromote(rpmdsObject * s, PyObject * args)
00292         /*@modifies s @*/
00293 {
00294     int nopromote;
00295 
00296     if (!PyArg_ParseTuple(args, "i:SetNoPromote", &nopromote))
00297         return NULL;
00298     return Py_BuildValue("i", rpmdsSetNoPromote(s->ds, nopromote));
00299 }
00300 
00301 /*@null@*/
00302 static PyObject *
00303 rpmds_Notify(rpmdsObject * s, PyObject * args)
00304         /*@globals _Py_NoneStruct @*/
00305         /*@modifies _Py_NoneStruct @*/
00306 {
00307     const char * where;
00308     int rc;
00309 
00310     if (!PyArg_ParseTuple(args, "si:Notify", &where, &rc))
00311         return NULL;
00312     rpmdsNotify(s->ds, where, rc);
00313     Py_INCREF(Py_None);
00314     return Py_None;
00315 }
00316 
00317 #ifdef  NOTYET
00318 /*@null@*/
00319 static PyObject *
00320 rpmds_Problem(rpmdsObject * s, PyObject * args)
00321         /*@*/
00322 {
00323     if (!PyArg_ParseTuple(args, ":Problem"))
00324         return NULL;
00325     Py_INCREF(Py_None);
00326     return Py_None;
00327 }
00328 #endif
00329 
00330 /*@-fullinitblock@*/
00331 /*@unchecked@*/ /*@observer@*/
00332 static struct PyMethodDef rpmds_methods[] = {
00333  {"Debug",      (PyCFunction)rpmds_Debug,       METH_VARARGS,
00334         NULL},
00335  {"Count",      (PyCFunction)rpmds_Count,       METH_VARARGS,
00336         "ds.Count -> Count      - Return no. of elements.\n" },
00337  {"Ix",         (PyCFunction)rpmds_Ix,          METH_VARARGS,
00338         "ds.Ix -> Ix            - Return current element index.\n" },
00339  {"DNEVR",      (PyCFunction)rpmds_DNEVR,       METH_VARARGS,
00340         "ds.DNEVR -> DNEVR      - Return current DNEVR.\n" },
00341  {"N",          (PyCFunction)rpmds_N,           METH_VARARGS,
00342         "ds.N -> N              - Return current N.\n" },
00343  {"EVR",        (PyCFunction)rpmds_EVR,         METH_VARARGS,
00344         "ds.EVR -> EVR          - Return current EVR.\n" },
00345  {"Flags",      (PyCFunction)rpmds_Flags,       METH_VARARGS,
00346         "ds.Flags -> Flags      - Return current Flags.\n" },
00347  {"BT",         (PyCFunction)rpmds_BT,          METH_VARARGS,
00348         "ds.BT -> BT    - Return build time.\n" },
00349  {"TagN",       (PyCFunction)rpmds_TagN,        METH_VARARGS,
00350         "ds.TagN -> TagN        - Return current TagN.\n" },
00351  {"Color",      (PyCFunction)rpmds_Color,       METH_VARARGS,
00352         "ds.Color -> Color      - Return current Color.\n" },
00353  {"Refs",       (PyCFunction)rpmds_Refs,        METH_VARARGS,
00354         "ds.Refs -> Refs        - Return current Refs.\n" },
00355  {"next",       (PyCFunction)rpmds_Next,        METH_VARARGS,
00356 "ds.next() -> (N, EVR, Flags)\n\
00357 - Retrieve next dependency triple.\n" },
00358  {"SetNoPromote",(PyCFunction)rpmds_SetNoPromote, METH_VARARGS,
00359         NULL},
00360  {"Notify",     (PyCFunction)rpmds_Notify,      METH_VARARGS,
00361         NULL},
00362 #ifdef  NOTYET
00363  {"Problem",    (PyCFunction)rpmds_Problem,     METH_VARARGS,
00364         NULL},
00365 #endif
00366  {NULL,         NULL}           /* sentinel */
00367 };
00368 /*@=fullinitblock@*/
00369 
00370 /* ---------- */
00371 
00372 static void
00373 rpmds_dealloc(rpmdsObject * s)
00374         /*@modifies s @*/
00375 {
00376     if (s) {
00377         s->ds = rpmdsFree(s->ds);
00378         PyObject_Del(s);
00379     }
00380 }
00381 
00382 static int
00383 rpmds_print(rpmdsObject * s, FILE * fp, /*@unused@*/ int flags)
00384         /*@globals fileSystem @*/
00385         /*@modifies s, fp, fileSystem @*/
00386 {
00387     if (!(s && s->ds))
00388         return -1;
00389 
00390     s->ds = rpmdsInit(s->ds);
00391     while (rpmdsNext(s->ds) >= 0)
00392         fprintf(fp, "%s\n", rpmdsDNEVR(s->ds));
00393     return 0;
00394 }
00395 
00396 static PyObject * rpmds_getattro(PyObject * o, PyObject * n)
00397         /*@*/
00398 {
00399     return PyObject_GenericGetAttr(o, n);
00400 }
00401 
00402 static int rpmds_setattro(PyObject * o, PyObject * n, PyObject * v)
00403         /*@*/
00404 {
00405     return PyObject_GenericSetAttr(o, n, v);
00406 }
00407 
00408 static int
00409 rpmds_length(rpmdsObject * s)
00410         /*@*/
00411 {
00412     return rpmdsCount(s->ds);
00413 }
00414 
00415 /*@null@*/
00416 static PyObject *
00417 rpmds_subscript(rpmdsObject * s, PyObject * key)
00418         /*@modifies s @*/
00419 {
00420     int ix;
00421 
00422     if (!PyInt_Check(key)) {
00423         PyErr_SetString(PyExc_TypeError, "integer expected");
00424         return NULL;
00425     }
00426 
00427     ix = (int) PyInt_AsLong(key);
00428     /* XXX make sure that DNEVR exists. */
00429     rpmdsSetIx(s->ds, ix-1);
00430     (void) rpmdsNext(s->ds);
00431     return Py_BuildValue("s", rpmdsDNEVR(s->ds));
00432 }
00433 
00434 static PyMappingMethods rpmds_as_mapping = {
00435         (inquiry) rpmds_length,         /* mp_length */
00436         (binaryfunc) rpmds_subscript,   /* mp_subscript */
00437         (objobjargproc)0,               /* mp_ass_subscript */
00438 };
00439 
00442 /*@unchecked@*/ /*@observer@*/
00443 static char rpmds_doc[] =
00444 "";
00445 
00446 /*@-fullinitblock@*/
00447 PyTypeObject rpmds_Type = {
00448         PyObject_HEAD_INIT(&PyType_Type)
00449         0,                              /* ob_size */
00450         "rpm.ds",                       /* tp_name */
00451         sizeof(rpmdsObject),            /* tp_basicsize */
00452         0,                              /* tp_itemsize */
00453         /* methods */
00454         (destructor) rpmds_dealloc,     /* tp_dealloc */
00455         (printfunc) rpmds_print,        /* tp_print */
00456         (getattrfunc)0,                 /* tp_getattr */
00457         (setattrfunc)0,                 /* tp_setattr */
00458         (cmpfunc) rpmds_compare,        /* tp_compare */
00459         (reprfunc)0,                    /* tp_repr */
00460         0,                              /* tp_as_number */
00461         0,                              /* tp_as_sequence */
00462         &rpmds_as_mapping,              /* tp_as_mapping */
00463         (hashfunc)0,                    /* tp_hash */
00464         (ternaryfunc)0,                 /* tp_call */
00465         (reprfunc)0,                    /* tp_str */
00466         (getattrofunc) rpmds_getattro,  /* tp_getattro */
00467         (setattrofunc) rpmds_setattro,  /* tp_setattro */
00468         0,                              /* tp_as_buffer */
00469         Py_TPFLAGS_DEFAULT |            /* tp_flags */
00470             Py_TPFLAGS_HAVE_RICHCOMPARE,
00471         rpmds_doc,                      /* tp_doc */
00472 #if Py_TPFLAGS_HAVE_ITER
00473         0,                              /* tp_traverse */
00474         0,                              /* tp_clear */
00475         (richcmpfunc) rpmds_richcompare,/* tp_richcompare */
00476         0,                              /* tp_weaklistoffset */
00477         (getiterfunc) rpmds_iter,       /* tp_iter */
00478         (iternextfunc) rpmds_iternext,  /* tp_iternext */
00479         rpmds_methods,                  /* tp_methods */
00480         0,                              /* tp_members */
00481         0,                              /* tp_getset */
00482         0,                              /* tp_base */
00483         0,                              /* tp_dict */
00484         0,                              /* tp_descr_get */
00485         0,                              /* tp_descr_set */
00486         0,                              /* tp_dictoffset */
00487         0,                              /* tp_init */
00488         0,                              /* tp_alloc */
00489         0,                              /* tp_new */
00490         0,                              /* tp_free */
00491         0,                              /* tp_is_gc */
00492 #endif
00493 };
00494 /*@=fullinitblock@*/
00495 
00496 /* ---------- */
00497 
00498 rpmds dsFromDs(rpmdsObject * s)
00499 {
00500     return s->ds;
00501 }
00502 
00503 rpmdsObject *
00504 rpmds_Wrap(rpmds ds)
00505 {
00506     rpmdsObject * s = PyObject_New(rpmdsObject, &rpmds_Type);
00507 
00508     if (s == NULL)
00509         return NULL;
00510     s->ds = ds;
00511     s->active = 0;
00512     return s;
00513 }
00514 
00515 rpmdsObject *
00516 rpmds_Single(/*@unused@*/ PyObject * s, PyObject * args)
00517 {
00518     PyObject * to = NULL;
00519     int tagN = RPMTAG_PROVIDENAME;
00520     const char * N;
00521     const char * EVR = NULL;
00522     int Flags = 0;
00523 
00524     if (!PyArg_ParseTuple(args, "Os|si:Single", &to, &N, &EVR, &Flags))
00525         return NULL;
00526     if (to != NULL) {
00527         tagN = tagNumFromPyObject(to);
00528         if (tagN == -1) {
00529             PyErr_SetString(PyExc_KeyError, "unknown header tag");
00530             return NULL;
00531         }
00532     }
00533     if (N != NULL) N = xstrdup(N);
00534     if (EVR != NULL) EVR = xstrdup(EVR);
00535     return rpmds_Wrap( rpmdsSingle(tagN, N, EVR, Flags) );
00536 }
00537 
00538 rpmdsObject *
00539 hdr_dsFromHeader(PyObject * s, PyObject * args)
00540 {
00541     hdrObject * ho = (hdrObject *)s;
00542     PyObject * to = NULL;
00543     rpmTag tagN = RPMTAG_REQUIRENAME;
00544     int scareMem = 0;
00545 
00546     if (!PyArg_ParseTuple(args, "|O:dsFromHeader", &to))
00547         return NULL;
00548     if (to != NULL) {
00549         tagN = tagNumFromPyObject(to);
00550         if (tagN == -1) {
00551             PyErr_SetString(PyExc_KeyError, "unknown header tag");
00552             return NULL;
00553         }
00554     }
00555     return rpmds_Wrap( rpmdsNew(hdrGetHeader(ho), tagN, scareMem) );
00556 }
00557 
00558 rpmdsObject *
00559 hdr_dsOfHeader(PyObject * s, PyObject * args)
00560 {
00561     hdrObject * ho = (hdrObject *)s;
00562     int tagN = RPMTAG_PROVIDENAME;
00563     int Flags = RPMSENSE_EQUAL;
00564 
00565     if (!PyArg_ParseTuple(args, ":dsOfHeader"))
00566         return NULL;
00567     return rpmds_Wrap( rpmdsThis(hdrGetHeader(ho), tagN, Flags) );
00568 }

Generated on Mon Mar 14 16:17:46 2005 for rpm by  doxygen 1.3.9.1