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)
00068
00069
00070 {
00071 if (!PyArg_ParseTuple(args, "i", &_rpmds_debug)) return NULL;
00072 Py_INCREF(Py_None);
00073 return Py_None;
00074 }
00075
00076
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
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
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
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
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
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
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
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
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
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
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
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
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
00240 static PyObject *
00241 rpmds_iternext(rpmdsObject * s)
00242
00243
00244 {
00245 PyObject * result = NULL;
00246
00247
00248 if (!s->active) {
00249 s->ds = rpmdsInit(s->ds);
00250 s->active = 1;
00251 }
00252
00253
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
00278 static PyObject *
00279 rpmds_Next(rpmdsObject * s, PyObject *args)
00280
00281
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
00298 static PyObject *
00299 rpmds_SetNoPromote(rpmdsObject * s, PyObject * args)
00300
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
00310 static PyObject *
00311 rpmds_Notify(rpmdsObject * s, PyObject * args)
00312
00313
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
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
00339
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}
00375 };
00376
00377
00378
00379
00380 static void
00381 rpmds_dealloc(rpmdsObject * s)
00382
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, int flags)
00392
00393
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
00424 static PyObject *
00425 rpmds_subscript(rpmdsObject * s, PyObject * key)
00426
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
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,
00444 (binaryfunc) rpmds_subscript,
00445 (objobjargproc)0,
00446 };
00447
00450
00451 static char rpmds_doc[] =
00452 "";
00453
00454
00455 PyTypeObject rpmds_Type = {
00456 PyObject_HEAD_INIT(&PyType_Type)
00457 0,
00458 "rpm.ds",
00459 sizeof(rpmdsObject),
00460 0,
00461
00462 (destructor) rpmds_dealloc,
00463 (printfunc) rpmds_print,
00464 (getattrfunc)0,
00465 (setattrfunc)0,
00466 (cmpfunc) rpmds_compare,
00467 (reprfunc)0,
00468 0,
00469 0,
00470 &rpmds_as_mapping,
00471 (hashfunc)0,
00472 (ternaryfunc)0,
00473 (reprfunc)0,
00474 (getattrofunc) rpmds_getattro,
00475 (setattrofunc) rpmds_setattro,
00476 0,
00477 Py_TPFLAGS_DEFAULT |
00478 Py_TPFLAGS_HAVE_RICHCOMPARE,
00479 rpmds_doc,
00480 #if Py_TPFLAGS_HAVE_ITER
00481 0,
00482 0,
00483 (richcmpfunc) rpmds_richcompare,
00484 0,
00485 (getiterfunc) rpmds_iter,
00486 (iternextfunc) rpmds_iternext,
00487 rpmds_methods,
00488 0,
00489 0,
00490 0,
00491 0,
00492 0,
00493 0,
00494 0,
00495 0,
00496 0,
00497 0,
00498 0,
00499 0,
00500 #endif
00501 };
00502
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( 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 }