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
00015
00023 static
00024 void rpmds_ParseEVR(char * evr,
00025 const char ** ep,
00026 const char ** vp,
00027 const char ** rp)
00028
00029
00030 {
00031 const char *epoch;
00032 const char *version;
00033 const char *release;
00034 char *s, *se;
00035
00036 s = evr;
00037 while (*s && xisdigit(*s)) s++;
00038 se = strrchr(s, '-');
00039
00040 if (*s == ':') {
00041 epoch = evr;
00042 *s++ = '\0';
00043 version = s;
00044
00045 if (*epoch == '\0') epoch = "0";
00046
00047 } else {
00048 epoch = NULL;
00049 version = evr;
00050 }
00051 if (se) {
00052
00053 *se++ = '\0';
00054
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
00066 static PyObject *
00067 rpmds_Debug( rpmdsObject * s, PyObject * args, PyObject * kwds)
00068
00069
00070 {
00071 char * kwlist[] = {"debugLevel", NULL};
00072
00073 if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &_rpmds_debug))
00074 return NULL;
00075
00076 Py_INCREF(Py_None);
00077 return Py_None;
00078 }
00079
00080
00081 static PyObject *
00082 rpmds_Count(rpmdsObject * s)
00083
00084 {
00085 return Py_BuildValue("i", rpmdsCount(s->ds));
00086 }
00087
00088
00089 static PyObject *
00090 rpmds_Ix(rpmdsObject * s)
00091
00092 {
00093 return Py_BuildValue("i", rpmdsIx(s->ds));
00094 }
00095
00096
00097 static PyObject *
00098 rpmds_DNEVR(rpmdsObject * s)
00099
00100 {
00101 return Py_BuildValue("s", rpmdsDNEVR(s->ds));
00102 }
00103
00104
00105 static PyObject *
00106 rpmds_N(rpmdsObject * s)
00107
00108 {
00109 return Py_BuildValue("s", rpmdsN(s->ds));
00110 }
00111
00112
00113 static PyObject *
00114 rpmds_EVR(rpmdsObject * s)
00115
00116 {
00117 return Py_BuildValue("s", rpmdsEVR(s->ds));
00118 }
00119
00120
00121 static PyObject *
00122 rpmds_Flags(rpmdsObject * s)
00123
00124 {
00125 return Py_BuildValue("i", rpmdsFlags(s->ds));
00126 }
00127
00128
00129 static PyObject *
00130 rpmds_BT(rpmdsObject * s)
00131
00132 {
00133 return Py_BuildValue("i", (int) rpmdsBT(s->ds));
00134 }
00135
00136
00137 static PyObject *
00138 rpmds_TagN(rpmdsObject * s)
00139
00140 {
00141 return Py_BuildValue("i", rpmdsTagN(s->ds));
00142 }
00143
00144
00145 static PyObject *
00146 rpmds_Color(rpmdsObject * s)
00147
00148 {
00149 return Py_BuildValue("i", rpmdsColor(s->ds));
00150 }
00151
00152
00153 static PyObject *
00154 rpmds_Refs(rpmdsObject * s)
00155
00156 {
00157 return Py_BuildValue("i", rpmdsRefs(s->ds));
00158 }
00159
00162 static int compare_values(const char *str1, const char *str2)
00163 {
00164 if (!str1 && !str2)
00165 return 0;
00166 else if (str1 && !str2)
00167 return 1;
00168 else if (!str1 && str2)
00169 return -1;
00170 return rpmvercmp(str1, str2);
00171 }
00172
00173 static int
00174 rpmds_compare(rpmdsObject * a, rpmdsObject * b)
00175
00176 {
00177 char *aEVR = xstrdup(rpmdsEVR(a->ds));
00178 const char *aE, *aV, *aR;
00179 char *bEVR = xstrdup(rpmdsEVR(b->ds));
00180 const char *bE, *bV, *bR;
00181 int rc;
00182
00183
00184 rpmds_ParseEVR(aEVR, &aE, &aV, &aR);
00185 rpmds_ParseEVR(bEVR, &bE, &bV, &bR);
00186
00187 rc = compare_values(aE, bE);
00188 if (!rc) {
00189 rc = compare_values(aV, bV);
00190 if (!rc)
00191 rc = compare_values(aR, bR);
00192 }
00193
00194 aEVR = _free(aEVR);
00195 bEVR = _free(bEVR);
00196
00197 return rc;
00198 }
00199
00200 static PyObject *
00201 rpmds_richcompare(rpmdsObject * a, rpmdsObject * b, int op)
00202
00203 {
00204 int rc;
00205
00206 switch (op) {
00207 case Py_NE:
00208
00209 rc = rpmdsCompare(a->ds, b->ds);
00210 rc = (rc < 0 ? -1 : (rc == 0 ? 1 : 0));
00211 break;
00212 case Py_LT:
00213 case Py_LE:
00214 case Py_GT:
00215 case Py_GE:
00216 case Py_EQ:
00217
00218 default:
00219 rc = -1;
00220 break;
00221 }
00222 return Py_BuildValue("i", rc);
00223 }
00224
00225 static PyObject *
00226 rpmds_iter(rpmdsObject * s)
00227
00228 {
00229 Py_INCREF(s);
00230 return (PyObject *)s;
00231 }
00232
00233
00234 static PyObject *
00235 rpmds_iternext(rpmdsObject * s)
00236
00237 {
00238 PyObject * result = NULL;
00239
00240
00241 if (!s->active) {
00242 s->ds = rpmdsInit(s->ds);
00243 s->active = 1;
00244 }
00245
00246
00247 if (rpmdsNext(s->ds) >= 0) {
00248 const char * N = rpmdsN(s->ds);
00249 const char * EVR = rpmdsEVR(s->ds);
00250 int tagN = rpmdsTagN(s->ds);
00251 int Flags = rpmdsFlags(s->ds);
00252
00253
00254 if (N != NULL) N = xstrdup(N);
00255 if (EVR != NULL) EVR = xstrdup(EVR);
00256
00257 result = rpmds_Wrap( rpmdsSingle(tagN, N, EVR, Flags) );
00258 } else
00259 s->active = 0;
00260
00261 return result;
00262 }
00263
00264
00265 static PyObject *
00266 rpmds_Next(rpmdsObject * s)
00267
00268
00269 {
00270 PyObject * result;
00271
00272 result = rpmds_iternext(s);
00273
00274 if (result == NULL) {
00275 Py_INCREF(Py_None);
00276 return Py_None;
00277 }
00278 return result;
00279 }
00280
00281
00282 static PyObject *
00283 rpmds_SetNoPromote(rpmdsObject * s, PyObject * args, PyObject * kwds)
00284
00285 {
00286 int nopromote;
00287 char * kwlist[] = {"noPromote", NULL};
00288
00289 if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:SetNoPromote", kwlist,
00290 &nopromote))
00291 return NULL;
00292
00293 return Py_BuildValue("i", rpmdsSetNoPromote(s->ds, nopromote));
00294 }
00295
00296
00297 static PyObject *
00298 rpmds_Notify(rpmdsObject * s, PyObject * args, PyObject * kwds)
00299
00300
00301 {
00302 const char * where;
00303 int rc;
00304 char * kwlist[] = {"location", "returnCode", NULL};
00305
00306 if (!PyArg_ParseTupleAndKeywords(args, kwds, "si:Notify", kwlist,
00307 &where, &rc))
00308 return NULL;
00309
00310 rpmdsNotify(s->ds, where, rc);
00311 Py_INCREF(Py_None);
00312 return Py_None;
00313 }
00314
00315
00316
00317 static PyObject *
00318 rpmds_Sort(rpmdsObject * s)
00319
00320
00321 {
00322
00323 Py_INCREF(Py_None);
00324 return Py_None;
00325 }
00326
00327
00328 static PyObject *
00329 rpmds_Find(rpmdsObject * s, PyObject * args, PyObject * kwds)
00330
00331 {
00332 PyObject * to = NULL;
00333 rpmdsObject * o;
00334 int rc;
00335 char * kwlist[] = {"element", NULL};
00336
00337 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:Find", kwlist, &to))
00338 return NULL;
00339
00340
00341 o = (rpmdsObject *)to;
00342
00343
00344 if (rpmdsIx(o->ds) == -1) rpmdsSetIx(o->ds, 0);
00345
00346 rc = rpmdsFind(s->ds, o->ds);
00347 return Py_BuildValue("i", rc);
00348 }
00349
00350
00351 static PyObject *
00352 rpmds_Merge(rpmdsObject * s, PyObject * args, PyObject * kwds)
00353
00354 {
00355 PyObject * to = NULL;
00356 rpmdsObject * o;
00357 char * kwlist[] = {"element", NULL};
00358
00359 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:Merge", kwlist, &to))
00360 return NULL;
00361
00362
00363 o = (rpmdsObject *)to;
00364 return Py_BuildValue("i", rpmdsMerge(&s->ds, o->ds));
00365 }
00366
00367 #ifdef NOTYET
00368 static PyObject *
00369 rpmds_Compare(rpmdsObject * s, PyObject * args, PyObject * kwds)
00370
00371 {
00372 PyObject * to = NULL;
00373 rpmdsObject * o;
00374 char * kwlist[] = {"other", NULL};
00375
00376 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:Compare", kwlist, &to))
00377 return NULL;
00378
00379
00380 o = (rpmdsObject *)to;
00381 return Py_BuildValue("i", rpmdsCompare(s->ds, o->ds));
00382 }
00383
00384
00385 static PyObject *
00386 rpmds_Problem(rpmdsObject * s)
00387
00388 {
00389 if (!PyArg_ParseTuple(args, ":Problem"))
00390 return NULL;
00391 Py_INCREF(Py_None);
00392 return Py_None;
00393 }
00394 #endif
00395
00396
00397
00398 static struct PyMethodDef rpmds_methods[] = {
00399 {"Debug", (PyCFunction)rpmds_Debug, METH_VARARGS|METH_KEYWORDS,
00400 NULL},
00401 {"Count", (PyCFunction)rpmds_Count, METH_NOARGS,
00402 "ds.Count -> Count - Return no. of elements.\n" },
00403 {"Ix", (PyCFunction)rpmds_Ix, METH_NOARGS,
00404 "ds.Ix -> Ix - Return current element index.\n" },
00405 {"DNEVR", (PyCFunction)rpmds_DNEVR, METH_NOARGS,
00406 "ds.DNEVR -> DNEVR - Return current DNEVR.\n" },
00407 {"N", (PyCFunction)rpmds_N, METH_NOARGS,
00408 "ds.N -> N - Return current N.\n" },
00409 {"EVR", (PyCFunction)rpmds_EVR, METH_NOARGS,
00410 "ds.EVR -> EVR - Return current EVR.\n" },
00411 {"Flags", (PyCFunction)rpmds_Flags, METH_NOARGS,
00412 "ds.Flags -> Flags - Return current Flags.\n" },
00413 {"BT", (PyCFunction)rpmds_BT, METH_NOARGS,
00414 "ds.BT -> BT - Return build time.\n" },
00415 {"TagN", (PyCFunction)rpmds_TagN, METH_NOARGS,
00416 "ds.TagN -> TagN - Return current TagN.\n" },
00417 {"Color", (PyCFunction)rpmds_Color, METH_NOARGS,
00418 "ds.Color -> Color - Return current Color.\n" },
00419 {"Refs", (PyCFunction)rpmds_Refs, METH_NOARGS,
00420 "ds.Refs -> Refs - Return current Refs.\n" },
00421 {"next", (PyCFunction)rpmds_Next, METH_NOARGS,
00422 "ds.next() -> (N, EVR, Flags)\n\
00423 - Retrieve next dependency triple.\n" },
00424 {"SetNoPromote",(PyCFunction)rpmds_SetNoPromote, METH_VARARGS|METH_KEYWORDS,
00425 NULL},
00426 {"Notify", (PyCFunction)rpmds_Notify, METH_VARARGS|METH_KEYWORDS,
00427 NULL},
00428 {"Sort", (PyCFunction)rpmds_Sort, METH_NOARGS,
00429 NULL},
00430 {"Find", (PyCFunction)rpmds_Find, METH_VARARGS|METH_KEYWORDS,
00431 NULL},
00432 {"Merge", (PyCFunction)rpmds_Merge, METH_VARARGS|METH_KEYWORDS,
00433 NULL},
00434 #ifdef NOTYET
00435 {"Compare", (PyCFunction)rpmds_Compare, METH_VARARGS|METH_KEYWORDS,
00436 NULL},
00437 {"Problem", (PyCFunction)rpmds_Problem, METH_NOARGS,
00438 NULL},
00439 #endif
00440 {NULL, NULL}
00441 };
00442
00443
00444
00445
00446 static void
00447 rpmds_dealloc(rpmdsObject * s)
00448
00449 {
00450 if (s) {
00451 s->ds = rpmdsFree(s->ds);
00452 PyObject_Del(s);
00453 }
00454 }
00455
00456 static int
00457 rpmds_print(rpmdsObject * s, FILE * fp, int flags)
00458
00459
00460 {
00461 if (!(s && s->ds))
00462 return -1;
00463
00464 s->ds = rpmdsInit(s->ds);
00465 while (rpmdsNext(s->ds) >= 0)
00466 fprintf(fp, "%s\n", rpmdsDNEVR(s->ds));
00467 return 0;
00468 }
00469
00470 static PyObject * rpmds_getattro(PyObject * o, PyObject * n)
00471
00472 {
00473 return PyObject_GenericGetAttr(o, n);
00474 }
00475
00476 static int rpmds_setattro(PyObject * o, PyObject * n, PyObject * v)
00477
00478 {
00479 return PyObject_GenericSetAttr(o, n, v);
00480 }
00481
00482 static int
00483 rpmds_length(rpmdsObject * s)
00484
00485 {
00486 return rpmdsCount(s->ds);
00487 }
00488
00489
00490 static PyObject *
00491 rpmds_subscript(rpmdsObject * s, PyObject * key)
00492
00493 {
00494 int ix;
00495
00496 if (!PyInt_Check(key)) {
00497 PyErr_SetString(PyExc_TypeError, "integer expected");
00498 return NULL;
00499 }
00500
00501 ix = (int) PyInt_AsLong(key);
00502
00503 rpmdsSetIx(s->ds, ix-1);
00504 (void) rpmdsNext(s->ds);
00505 return Py_BuildValue("s", rpmdsDNEVR(s->ds));
00506 }
00507
00508 static PyMappingMethods rpmds_as_mapping = {
00509 (inquiry) rpmds_length,
00510 (binaryfunc) rpmds_subscript,
00511 (objobjargproc)0,
00512 };
00513
00516 static int rpmds_init(rpmdsObject * s, PyObject *args, PyObject *kwds)
00517
00518
00519 {
00520 hdrObject * ho = NULL;
00521 PyObject * to = NULL;
00522 int tagN = RPMTAG_REQUIRENAME;
00523 int flags = 0;
00524 char * kwlist[] = {"header", "tag", "flags", NULL};
00525
00526 if (_rpmds_debug < 0)
00527 fprintf(stderr, "*** rpmds_init(%p,%p,%p)\n", s, args, kwds);
00528
00529 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|Oi:rpmds_init", kwlist,
00530 &hdr_Type, &ho, &to, &flags))
00531 return -1;
00532
00533 if (to != NULL) {
00534 tagN = tagNumFromPyObject(to);
00535 if (tagN == -1) {
00536 PyErr_SetString(PyExc_KeyError, "unknown header tag");
00537 return -1;
00538 }
00539 }
00540 s->ds = rpmdsNew(hdrGetHeader(ho), tagN, flags);
00541 s->active = 0;
00542
00543 return 0;
00544 }
00545
00548 static void rpmds_free( rpmdsObject * s)
00549
00550 {
00551 if (_rpmds_debug)
00552 fprintf(stderr, "%p -- ds %p\n", s, s->ds);
00553 s->ds = rpmdsFree(s->ds);
00554
00555 PyObject_Del((PyObject *)s);
00556 }
00557
00560 static PyObject * rpmds_alloc(PyTypeObject * subtype, int nitems)
00561
00562 {
00563 PyObject * s = PyType_GenericAlloc(subtype, nitems);
00564
00565 if (_rpmds_debug < 0)
00566 fprintf(stderr, "*** rpmds_alloc(%p,%d) ret %p\n", subtype, nitems, s);
00567 return s;
00568 }
00569
00572
00573 static PyObject * rpmds_new(PyTypeObject * subtype, PyObject *args, PyObject *kwds)
00574
00575
00576 {
00577 rpmdsObject * s = (void *) PyObject_New(rpmdsObject, subtype);
00578
00579
00580 if (rpmds_init(s, args, kwds) < 0) {
00581 rpmds_free(s);
00582 return NULL;
00583 }
00584
00585 if (_rpmds_debug)
00586 fprintf(stderr, "%p ++ ds %p\n", s, s->ds);
00587
00588 return (PyObject *)s;
00589 }
00590
00593
00594 static char rpmds_doc[] =
00595 "";
00596
00597
00598 PyTypeObject rpmds_Type = {
00599 PyObject_HEAD_INIT(&PyType_Type)
00600 0,
00601 "rpm.ds",
00602 sizeof(rpmdsObject),
00603 0,
00604
00605 (destructor) rpmds_dealloc,
00606 (printfunc) rpmds_print,
00607 (getattrfunc)0,
00608 (setattrfunc)0,
00609 (cmpfunc) rpmds_compare,
00610 (reprfunc)0,
00611 0,
00612 0,
00613 &rpmds_as_mapping,
00614 (hashfunc)0,
00615 (ternaryfunc)0,
00616 (reprfunc)0,
00617 (getattrofunc) rpmds_getattro,
00618 (setattrofunc) rpmds_setattro,
00619 0,
00620 Py_TPFLAGS_DEFAULT |
00621 Py_TPFLAGS_HAVE_RICHCOMPARE,
00622 rpmds_doc,
00623 #if Py_TPFLAGS_HAVE_ITER
00624 0,
00625 0,
00626 (richcmpfunc) rpmds_richcompare,
00627 0,
00628 (getiterfunc) rpmds_iter,
00629 (iternextfunc) rpmds_iternext,
00630 rpmds_methods,
00631 0,
00632 0,
00633 0,
00634 0,
00635 0,
00636 0,
00637 0,
00638 (initproc) rpmds_init,
00639 (allocfunc) rpmds_alloc,
00640 (newfunc) rpmds_new,
00641 rpmds_free,
00642 0,
00643 #endif
00644 };
00645
00646
00647
00648
00649 rpmds dsFromDs(rpmdsObject * s)
00650 {
00651 return s->ds;
00652 }
00653
00654 rpmdsObject *
00655 rpmds_Wrap(rpmds ds)
00656 {
00657 rpmdsObject * s = PyObject_New(rpmdsObject, &rpmds_Type);
00658
00659 if (s == NULL)
00660 return NULL;
00661 s->ds = ds;
00662 s->active = 0;
00663 return s;
00664 }
00665
00666 rpmdsObject *
00667 rpmds_Single( PyObject * s, PyObject * args, PyObject * kwds)
00668 {
00669 PyObject * to = NULL;
00670 int tagN = RPMTAG_PROVIDENAME;
00671 const char * N;
00672 const char * EVR = NULL;
00673 int Flags = 0;
00674 char * kwlist[] = {"to", "name", "evr", "flags", NULL};
00675
00676 if (!PyArg_ParseTupleAndKeywords(args, kwds, "Os|si:Single", kwlist,
00677 &to, &N, &EVR, &Flags))
00678 return NULL;
00679
00680 if (to != NULL) {
00681 tagN = tagNumFromPyObject(to);
00682 if (tagN == -1) {
00683 PyErr_SetString(PyExc_KeyError, "unknown header tag");
00684 return NULL;
00685 }
00686 }
00687 if (N != NULL) N = xstrdup(N);
00688 if (EVR != NULL) EVR = xstrdup(EVR);
00689 return rpmds_Wrap( rpmdsSingle(tagN, N, EVR, Flags) );
00690 }
00691
00692 rpmdsObject *
00693 hdr_dsFromHeader(PyObject * s, PyObject * args, PyObject * kwds)
00694 {
00695 hdrObject * ho = (hdrObject *)s;
00696 PyObject * to = NULL;
00697 rpmTag tagN = RPMTAG_REQUIRENAME;
00698 int flags = 0;
00699 char * kwlist[] = {"to", "flags", NULL};
00700
00701 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:dsFromHeader", kwlist,
00702 &to, &flags))
00703 return NULL;
00704
00705 if (to != NULL) {
00706 tagN = tagNumFromPyObject(to);
00707 if (tagN == -1) {
00708 PyErr_SetString(PyExc_KeyError, "unknown header tag");
00709 return NULL;
00710 }
00711 }
00712 return rpmds_Wrap( rpmdsNew(hdrGetHeader(ho), tagN, flags) );
00713 }
00714
00715 rpmdsObject *
00716 hdr_dsOfHeader(PyObject * s)
00717 {
00718 hdrObject * ho = (hdrObject *)s;
00719 int tagN = RPMTAG_PROVIDENAME;
00720 int Flags = RPMSENSE_EQUAL;
00721
00722 return rpmds_Wrap( rpmdsThis(hdrGetHeader(ho), tagN, Flags) );
00723 }