summaryrefslogtreecommitdiffstats
path: root/python/pkgsrcrecords.cc
diff options
context:
space:
mode:
Diffstat (limited to 'python/pkgsrcrecords.cc')
-rw-r--r--python/pkgsrcrecords.cc438
1 files changed, 438 insertions, 0 deletions
diff --git a/python/pkgsrcrecords.cc b/python/pkgsrcrecords.cc
new file mode 100644
index 0000000..e813c6e
--- /dev/null
+++ b/python/pkgsrcrecords.cc
@@ -0,0 +1,438 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+// $Id: pkgsrcrecords.cc,v 1.2 2003/12/26 17:04:22 mdz Exp $
+/* ######################################################################
+
+ Package Records - Wrapper for the package records functions
+
+ ##################################################################### */
+ /*}}}*/
+// Include Files /*{{{*/
+#include "generic.h"
+#include "apt_pkgmodule.h"
+
+#include <apt-pkg/sourcelist.h>
+
+#include <Python.h>
+ /*}}}*/
+
+// PkgSrcRecordFiles Class /*{{{*/
+// ---------------------------------------------------------------------
+typedef pkgSrcRecords::File PkgSrcRecordFilesStruct;
+
+// compat with the old API that provided a tuple (md5,size,path,type)
+static Py_ssize_t pkgSrcRecordFiles_length(PyObject *Self) {
+ return 4;
+}
+
+// compat with the old API that provided a tuple (md5,size,path,type)
+static PyObject* pkgSrcRecordFiles_item(PyObject *Self, Py_ssize_t i) {
+ APT_IGNORE_DEPRECATED_PUSH
+ PkgSrcRecordFilesStruct f = GetCpp<PkgSrcRecordFilesStruct>(Self);
+ switch (i) {
+ case 0:
+ Py_INCREF(Py_None);
+ return Py_None;
+ case 1:
+ return Py_BuildValue("N", MkPyNumber(f.FileSize));
+ case 2:
+ return Py_BuildValue("s", f.Path.c_str());
+ case 3:
+ return Py_BuildValue("s", f.Type.c_str());
+ }
+
+ PyErr_Format(PyExc_IndexError, "index %d out of range, consider using the properties instead", i);
+ return NULL;
+ APT_IGNORE_DEPRECATED_POP
+}
+
+static PySequenceMethods pkgsrcrecordfiles_as_sequence = {
+ pkgSrcRecordFiles_length,0,0,pkgSrcRecordFiles_item,0,0,0,0,0,0
+};
+
+static PyObject *PkgSrcRecordFilesNew(PyTypeObject *type,PyObject *args,PyObject *kwds) {
+ char *kwlist[] = {0};
+ if (PyArg_ParseTupleAndKeywords(args,kwds,"",kwlist) == 0)
+ return 0;
+
+ return HandleErrors(CppPyObject_NEW<PkgSrcRecordFilesStruct>(NULL, type));
+}
+
+static const char *sourcerecordfile_doc =
+ "SourceRecordFile()\n\n"
+ "Provide an easy way to look up the src records of a source package.\n";
+
+static PyObject *PkgSrcRecordFilesGetPath(PyObject *Self,void*) {
+ PkgSrcRecordFilesStruct f = GetCpp<PkgSrcRecordFilesStruct>(Self);
+ return CppPyString(f.Path.c_str());
+}
+
+static PyObject *PkgSrcRecordFilesGetType(PyObject *Self,void*) {
+ PkgSrcRecordFilesStruct f = GetCpp<PkgSrcRecordFilesStruct>(Self);
+ return CppPyString(f.Type.c_str());
+}
+
+static PyObject *PkgSrcRecordFilesGetSize(PyObject *Self,void*) {
+ PkgSrcRecordFilesStruct f = GetCpp<PkgSrcRecordFilesStruct>(Self);
+ return Py_BuildValue("N", MkPyNumber(f.FileSize));
+}
+
+static PyObject *PkgSrcRecordFilesGetHashes(PyObject *Self,void*) {
+ PkgSrcRecordFilesStruct f = GetCpp<PkgSrcRecordFilesStruct>(Self);
+ auto py = CppPyObject_NEW<HashStringList> (nullptr, &PyHashStringList_Type);
+ py->Object = f.Hashes;
+ return py;
+}
+
+static PyGetSetDef PkgSrcRecordFilesGetSet[] = {
+ {"path",PkgSrcRecordFilesGetPath,0,
+ "The remote path of the source package file."},
+ {"type",PkgSrcRecordFilesGetType,0,
+ "The type of the source package file."},
+ {"size",PkgSrcRecordFilesGetSize,0,
+ "The size of the source package file."},
+ {"hashes",PkgSrcRecordFilesGetHashes,0,
+ "The hashes of the source package file."},
+ {}
+};
+
+PyTypeObject PySourceRecordFiles_Type =
+{
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.SourceRecordFiles", // tp_name
+ sizeof(CppPyObject<PkgSrcRecordFilesStruct>), // tp_basicsize
+ 0, // tp_itemsize
+ // Methods
+ CppDealloc<PkgSrcRecordFilesStruct>, // tp_dealloc
+ 0, // tp_print
+ 0, // tp_getattr
+ 0, // tp_setattr
+ 0, // tp_compare
+ 0, // tp_repr
+ 0, // tp_as_number
+ &pkgsrcrecordfiles_as_sequence, // tp_as_sequence
+ 0, // tp_as_mapping
+ 0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ _PyAptObject_getattro, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ (Py_TPFLAGS_DEFAULT | // tp_flags
+ Py_TPFLAGS_BASETYPE),
+ sourcerecordfile_doc, // tp_doc
+ 0, // tp_traverse
+ 0, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ 0, // tp_methods
+ 0, // tp_members
+ PkgSrcRecordFilesGetSet, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ 0, // tp_init
+ 0, // tp_alloc
+ PkgSrcRecordFilesNew, // tp_new
+};
+// ---------------------------------------------------------------------
+
+struct PkgSrcRecordsStruct
+{
+ pkgSourceList List;
+ pkgSrcRecords *Records;
+ pkgSrcRecords::Parser *Last;
+
+ PkgSrcRecordsStruct() : Last(0) {
+ List.ReadMainList();
+ Records = new pkgSrcRecords(List);
+ };
+ ~PkgSrcRecordsStruct() {
+ delete Records;
+ };
+};
+
+
+// PkgSrcRecords Class /*{{{*/
+// ---------------------------------------------------------------------
+
+static char *doc_PkgSrcRecordsLookup =
+ "lookup(name: str) -> bool\n\n"
+ "Look up the source package with the given name. Each call moves\n"
+ "the position of the records parser forward. If there are no\n"
+ "more records, return None. If the lookup failed this way,\n"
+ "access to any of the attributes will result in an AttributeError.";
+static PyObject *PkgSrcRecordsLookup(PyObject *Self,PyObject *Args)
+{
+ PkgSrcRecordsStruct &Struct = GetCpp<PkgSrcRecordsStruct>(Self);
+
+ char *Name = 0;
+ if (PyArg_ParseTuple(Args,"s",&Name) == 0)
+ return 0;
+
+ Struct.Last = Struct.Records->Find(Name, false);
+ if (Struct.Last == 0) {
+ Struct.Records->Restart();
+ Py_INCREF(Py_None);
+ return HandleErrors(Py_None);
+ }
+
+ return PyBool_FromLong(1);
+}
+
+static char *doc_PkgSrcRecordsRestart =
+ "restart()\n\n"
+ "Restart the lookup process. This moves the parser to the first\n"
+ "package and lookups can now be made just like on a new object.";
+static PyObject *PkgSrcRecordsRestart(PyObject *Self,PyObject *Args)
+{
+ PkgSrcRecordsStruct &Struct = GetCpp<PkgSrcRecordsStruct>(Self);
+
+ if (PyArg_ParseTuple(Args,"") == 0)
+ return 0;
+
+ Struct.Records->Restart();
+
+ Py_INCREF(Py_None);
+ return HandleErrors(Py_None);
+}
+
+static char *doc_PkgSrcRecordsStep =
+ "step() -> bool\n\n"
+ "Go to the source package. Each call moves\n"
+ "the position of the records parser forward. If there are no\n"
+ "more records, return None. If the lookup failed this way,\n"
+ "access to any of the attributes will result in an AttributeError.";
+static PyObject *PkgSrcRecordsStep(PyObject *Self,PyObject *Args)
+{
+ PkgSrcRecordsStruct &Struct = GetCpp<PkgSrcRecordsStruct>(Self);
+
+ if (PyArg_ParseTuple(Args,"") == 0)
+ return 0;
+
+ Struct.Last = (pkgSrcRecords::Parser*)Struct.Records->Step();
+ if (Struct.Last == 0) {
+ Struct.Records->Restart();
+ Py_INCREF(Py_None);
+ return HandleErrors(Py_None);
+ }
+
+ return PyBool_FromLong(1);
+}
+
+static PyMethodDef PkgSrcRecordsMethods[] =
+{
+ {"lookup",PkgSrcRecordsLookup,METH_VARARGS,doc_PkgSrcRecordsLookup},
+ {"restart",PkgSrcRecordsRestart,METH_VARARGS,doc_PkgSrcRecordsRestart},
+ {"step",PkgSrcRecordsStep,METH_VARARGS,doc_PkgSrcRecordsStep},
+ {}
+};
+
+/**
+ * Get the PkgSrcRecordsStruct from a PyObject. If no package has been looked
+ * up, set an AttributeError using the given name.
+ */
+static inline PkgSrcRecordsStruct &GetStruct(PyObject *Self,char *name) {
+ PkgSrcRecordsStruct &Struct = GetCpp<PkgSrcRecordsStruct>(Self);
+ if (Struct.Last == 0)
+ PyErr_SetString(PyExc_AttributeError,name);
+ return Struct;
+}
+
+static PyObject *PkgSrcRecordsGetPackage(PyObject *Self,void*) {
+ PkgSrcRecordsStruct &Struct = GetStruct(Self,"Package");
+ return (Struct.Last != 0) ? CppPyString(Struct.Last->Package()) : 0;
+}
+static PyObject *PkgSrcRecordsGetVersion(PyObject *Self,void*) {
+ PkgSrcRecordsStruct &Struct = GetStruct(Self,"Version");
+ return (Struct.Last != 0) ? CppPyString(Struct.Last->Version()) : 0;
+}
+static PyObject *PkgSrcRecordsGetMaintainer(PyObject *Self,void*) {
+ PkgSrcRecordsStruct &Struct = GetStruct(Self,"Maintainer");
+ return (Struct.Last != 0) ? CppPyString(Struct.Last->Maintainer()) : 0;
+}
+static PyObject *PkgSrcRecordsGetSection(PyObject *Self,void*) {
+ PkgSrcRecordsStruct &Struct = GetStruct(Self,"Section");
+ return (Struct.Last != 0) ? CppPyString(Struct.Last->Section()) : 0;
+}
+static PyObject *PkgSrcRecordsGetRecord(PyObject *Self,void*) {
+ PkgSrcRecordsStruct &Struct = GetStruct(Self,"Record");
+ return (Struct.Last != 0) ? CppPyString(Struct.Last->AsStr()) : 0;
+}
+static PyObject *PkgSrcRecordsGetBinaries(PyObject *Self,void*) {
+ PkgSrcRecordsStruct &Struct = GetStruct(Self,"Binaries");
+ if (Struct.Last == 0)
+ return 0;
+ PyObject *List = PyList_New(0);
+ for(const char **b = Struct.Last->Binaries(); *b != 0; ++b)
+ PyList_Append(List, CppPyString(*b));
+ return List; // todo
+}
+static PyObject *PkgSrcRecordsGetIndex(PyObject *Self,void*) {
+ PkgSrcRecordsStruct &Struct = GetStruct(Self,"Index");
+ if (Struct.Last == 0)
+ return 0;
+ const pkgIndexFile &tmp = Struct.Last->Index();
+ CppPyObject<pkgIndexFile*> *PyObj;
+ PyObj = CppPyObject_NEW<pkgIndexFile*>(Self,&PyIndexFile_Type,
+ (pkgIndexFile*)&tmp);
+ // Do not delete the pkgIndexFile*, it is managed by PkgSrcRecords::Parser.
+ PyObj->NoDelete=true;
+ return PyObj;
+}
+
+static PyObject *PkgSrcRecordsGetFiles(PyObject *Self,void*) {
+ PkgSrcRecordsStruct &Struct = GetStruct(Self,"Files");
+ if (Struct.Last == 0)
+ return 0;
+ PyObject *List = PyList_New(0);
+
+ std::vector<pkgSrcRecords::File> f;
+ if(!Struct.Last->Files(f))
+ return NULL; // error
+
+ PyObject *v;
+ for(unsigned int i=0;i<f.size();i++) {
+ v = CppPyObject_NEW<PkgSrcRecordFilesStruct>(Self, &PySourceRecordFiles_Type, f[i]);
+ PyList_Append(List, v);
+ Py_DECREF(v);
+ }
+ return List;
+}
+
+static PyObject *PkgSrcRecordsGetBuildDepends(PyObject *Self,void*) {
+ PkgSrcRecordsStruct &Struct = GetStruct(Self,"BuildDepends");
+ if (Struct.Last == 0)
+ return 0;
+
+ PyObject *Dict = PyDict_New();
+ PyObject *Dep = 0;
+ PyObject *LastDep = 0;
+ PyObject *OrGroup = 0;
+
+ std::vector<pkgSrcRecords::Parser::BuildDepRec> bd;
+ if(!Struct.Last->BuildDepends(bd, false /* arch-only*/))
+ return NULL; // error
+
+ PyObject *v;
+ for(unsigned int i=0;i<bd.size();i++) {
+
+ Dep = CppPyString(pkgSrcRecords::Parser::BuildDepType(bd[i].Type));
+
+ LastDep = PyDict_GetItem(Dict,Dep);
+ if (LastDep == 0)
+ {
+ LastDep = PyList_New(0);
+ PyDict_SetItem(Dict,Dep,LastDep);
+ Py_DECREF(LastDep);
+ }
+ Py_DECREF(Dep);
+ OrGroup = PyList_New(0);
+ PyList_Append(LastDep, OrGroup);
+ Py_DECREF(OrGroup);
+
+ // Add at least one package to the group, add more if Or is set.
+ while (i < bd.size())
+ {
+ v = Py_BuildValue("(sss)", bd[i].Package.c_str(),
+ bd[i].Version.c_str(), pkgCache::CompType(bd[i].Op));
+ PyList_Append(OrGroup, v);
+ Py_DECREF(v);
+ if (pkgCache::Dep::Or != (bd[i].Op & pkgCache::Dep::Or))
+ break;
+ i++;
+ }
+
+ }
+ return Dict;
+}
+
+
+static PyGetSetDef PkgSrcRecordsGetSet[] = {
+ {"binaries",PkgSrcRecordsGetBinaries,0,
+ "A list of the names of the binaries produced by this source package."},
+ {"build_depends",PkgSrcRecordsGetBuildDepends,0,
+ "A dictionary describing the build-time dependencies of the package;\n"
+ "the format is the same as used for apt_pkg.Version.depends_list_str."},
+ {"files",PkgSrcRecordsGetFiles,0,
+ "A list of :class:`SourceRecordFiles` objects."},
+ {"index",PkgSrcRecordsGetIndex,0,
+ "The index file associated with this record as a list of\n"
+ "apt_pkg.IndexFile objects."},
+ {"maintainer",PkgSrcRecordsGetMaintainer,0,
+ "The maintainer of the package."},
+ {"package",PkgSrcRecordsGetPackage,0,
+ "The name of the source package."},
+ {"record",PkgSrcRecordsGetRecord,0,
+ "The raw record, suitable for parsing using apt_pkg.TagSection."},
+ {"section",PkgSrcRecordsGetSection,0,
+ "The section of the source package."},
+ {"version",PkgSrcRecordsGetVersion,0,
+ "The version of the source package."},
+ {}
+};
+
+static PyObject *PkgSrcRecordsNew(PyTypeObject *type,PyObject *args,PyObject *kwds) {
+ char *kwlist[] = {0};
+ if (PyArg_ParseTupleAndKeywords(args,kwds,"",kwlist) == 0)
+ return 0;
+
+ return HandleErrors(CppPyObject_NEW<PkgSrcRecordsStruct>(NULL, type));
+}
+
+static const char *sourcerecords_doc =
+ "SourceRecords()\n\n"
+ "Provide an easy way to look up the records of source packages and\n"
+ "provide easy attributes for some widely used fields of the record.";
+
+PyTypeObject PySourceRecords_Type =
+{
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.SourceRecords", // tp_name
+ sizeof(CppPyObject<PkgSrcRecordsStruct>), // tp_basicsize
+ 0, // tp_itemsize
+ // Methods
+ CppDealloc<PkgSrcRecordsStruct>, // tp_dealloc
+ 0, // tp_print
+ 0, // tp_getattr
+ 0, // tp_setattr
+ 0, // tp_compare
+ 0, // tp_repr
+ 0, // tp_as_number
+ 0, // tp_as_sequence
+ 0, // tp_as_mapping
+ 0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ _PyAptObject_getattro, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ (Py_TPFLAGS_DEFAULT | // tp_flags
+ Py_TPFLAGS_BASETYPE),
+ sourcerecords_doc, // tp_doc
+ 0, // tp_traverse
+ 0, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ PkgSrcRecordsMethods, // tp_methods
+ 0, // tp_members
+ PkgSrcRecordsGetSet, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ 0, // tp_init
+ 0, // tp_alloc
+ PkgSrcRecordsNew, // tp_new
+};
+
+
+ /*}}}*/
+