summaryrefslogtreecommitdiff
path: root/python/tag.cc
diff options
context:
space:
mode:
Diffstat (limited to 'python/tag.cc')
-rw-r--r--python/tag.cc244
1 files changed, 185 insertions, 59 deletions
diff --git a/python/tag.cc b/python/tag.cc
index 6fe97ed5..b1a3e520 100644
--- a/python/tag.cc
+++ b/python/tag.cc
@@ -34,19 +34,32 @@
using namespace std;
/*}}}*/
/* We need to keep a private copy of the data.. */
-struct TagSecData : public CppPyObject<pkgTagSection>
+struct TagSecData : public CppOwnedPyObject<pkgTagSection>
{
char *Data;
};
-struct TagFileData : public PyObject
+// The owner of the TagFile is a Python file object.
+struct TagFileData : public CppOwnedPyObject<pkgTagFile>
{
- pkgTagFile Object;
- PyObject *File;
TagSecData *Section;
FileFd Fd;
};
+// Traversal and Clean for owned objects
+int TagFileTraverse(PyObject *self, visitproc visit, void* arg) {
+ Py_VISIT(((TagFileData *)self)->Section);
+ Py_VISIT(((TagFileData *)self)->Owner);
+ return 0;
+}
+
+int TagFileClear(PyObject *self) {
+ Py_CLEAR(((TagFileData *)self)->Section);
+ Py_CLEAR(((TagFileData *)self)->Owner);
+ return 0;
+}
+
+
/*}}}*/
// TagSecFree - Free a Tag Section /*{{{*/
// ---------------------------------------------------------------------
@@ -55,7 +68,7 @@ void TagSecFree(PyObject *Obj)
{
TagSecData *Self = (TagSecData *)Obj;
delete [] Self->Data;
- CppDealloc<pkgTagSection>(Obj);
+ CppOwnedDealloc<pkgTagSection>(Obj);
}
/*}}}*/
// TagFileFree - Free a Tag File /*{{{*/
@@ -63,12 +76,15 @@ void TagSecFree(PyObject *Obj)
/* */
void TagFileFree(PyObject *Obj)
{
+ #ifdef ALLOC_DEBUG
+ std::cerr << "=== DEALLOCATING " << Obj->ob_type->tp_name << "^ ===\n";
+ #endif
TagFileData *Self = (TagFileData *)Obj;
- Py_DECREF((PyObject *)Self->Section);
+ Py_CLEAR(Self->Section);
Self->Object.~pkgTagFile();
Self->Fd.~FileFd();
- Py_DECREF(Self->File);
- PyObject_DEL(Obj);
+ Py_CLEAR(Self->Owner);
+ Obj->ob_type->tp_free(Obj);
}
/*}}}*/
@@ -183,6 +199,7 @@ static PyObject *TagSecKeys(PyObject *Self,PyObject *Args)
return List;
}
+#if PY_MAJOR_VERSION < 3
static char *doc_Exists = "Exists(Name) -> integer";
static PyObject *TagSecExists(PyObject *Self,PyObject *Args)
{
@@ -196,6 +213,19 @@ static PyObject *TagSecExists(PyObject *Self,PyObject *Args)
return Py_BuildValue("i",0);
return Py_BuildValue("i",1);
}
+#endif
+
+static int TagSecContains(PyObject *Self,PyObject *Arg)
+{
+ if (PyString_Check(Arg) == 0)
+ return 0;
+ const char *Name = PyString_AsString(Arg);
+ const char *Start;
+ const char *Stop;
+ if (GetCpp<pkgTagSection>(Self).Find(Name,Start,Stop) == false)
+ return 0;
+ return 1;
+}
static char *doc_Bytes = "Bytes() -> integer";
static PyObject *TagSecBytes(PyObject *Self,PyObject *Args)
@@ -252,15 +282,14 @@ static PyObject *TagFileJump(PyObject *Self,PyObject *Args)
/*}}}*/
// ParseSection - Parse a single section from a tag file /*{{{*/
// ---------------------------------------------------------------------
-char *doc_ParseSection ="ParseSection(Text) -> SectionObject";
-PyObject *ParseSection(PyObject *self,PyObject *Args)
-{
+static PyObject *TagSecNew(PyTypeObject *type,PyObject *Args,PyObject *kwds) {
char *Data;
- if (PyArg_ParseTuple(Args,"s",&Data) == 0)
+ char *kwlist[] = {"text", 0};
+ if (PyArg_ParseTupleAndKeywords(Args,kwds,"s",kwlist,&Data) == 0)
return 0;
// Create the object..
- TagSecData *New = PyObject_NEW(TagSecData,&TagSecType);
+ TagSecData *New = (TagSecData*)type->tp_alloc(type, 0);
new (&New->Object) pkgTagSection();
New->Data = new char[strlen(Data)+2];
snprintf(New->Data,strlen(Data)+2,"%s\n",Data);
@@ -277,30 +306,56 @@ PyObject *ParseSection(PyObject *self,PyObject *Args)
return New;
}
+
+#ifdef COMPAT_0_7
+char *doc_ParseSection ="ParseSection(Text) -> TagSection() object. Deprecated.";
+PyObject *ParseSection(PyObject *self,PyObject *Args)
+{
+ PyErr_WarnEx(PyExc_DeprecationWarning, "apt_pkg.ParseSection() is "
+ "deprecated. Please see apt_pkg.TagSection() for the "
+ "replacement.", 1);
+ return TagSecNew(&PyTagSection_Type,Args,0);
+}
+#endif
/*}}}*/
// ParseTagFile - Parse a tagd file /*{{{*/
// ---------------------------------------------------------------------
/* This constructs the parser state. */
-char *doc_ParseTagFile = "ParseTagFile(File) -> TagFile";
-PyObject *ParseTagFile(PyObject *self,PyObject *Args)
+
+static PyObject *TagFileNew(PyTypeObject *type,PyObject *Args,PyObject *kwds)
{
PyObject *File;
- if (PyArg_ParseTuple(Args,"O!",&PyFile_Type,&File) == 0)
+ char *kwlist[] = {"file", 0};
+ if (PyArg_ParseTupleAndKeywords(Args,kwds,"O",kwlist,&File) == 0)
+ return 0;
+ int fileno = PyObject_AsFileDescriptor(File);
+ if (fileno == -1)
return 0;
- TagFileData *New = PyObject_NEW(TagFileData,&TagFileType);
- new (&New->Fd) FileFd(fileno(PyFile_AsFile(File)),false);
- New->File = File;
- Py_INCREF(New->File);
+ TagFileData *New = (TagFileData*)type->tp_alloc(type, 0);
+ new (&New->Fd) FileFd(fileno,false);
+ New->Owner = File;
+ Py_INCREF(New->Owner);
new (&New->Object) pkgTagFile(&New->Fd);
// Create the section
- New->Section = PyObject_NEW(TagSecData,&TagSecType);
+ New->Section = (TagSecData*)(&PyTagSection_Type)->tp_alloc(&PyTagSection_Type, 0);
new (&New->Section->Object) pkgTagSection();
+ New->Section->Owner = New;
+ Py_INCREF(New->Section->Owner);
New->Section->Data = 0;
return HandleErrors(New);
}
+#ifdef COMPAT_0_7
+char *doc_ParseTagFile = "ParseTagFile(File) -> TagFile() object. Deprecated.";
+PyObject *ParseTagFile(PyObject *self,PyObject *Args) {
+ PyErr_WarnEx(PyExc_DeprecationWarning, "apt_pkg.ParseTagFile() is "
+ "deprecated. Please see apt_pkg.TagFile() for the "
+ "replacement.", 1);
+ return TagFileNew(&PyTagFile_Type,Args,0);
+}
+#endif
/*}}}*/
// RewriteSection - Rewrite a section.. /*{{{*/
// ---------------------------------------------------------------------
@@ -326,7 +381,7 @@ PyObject *RewriteSection(PyObject *self,PyObject *Args)
PyObject *Section;
PyObject *Order;
PyObject *Rewrite;
- if (PyArg_ParseTuple(Args,"O!O!O!",&TagSecType,&Section,
+ if (PyArg_ParseTuple(Args,"O!O!O!",&PyTagSection_Type,&Section,
&PyList_Type,&Order,&PyList_Type,&Rewrite) == 0)
return 0;
@@ -377,93 +432,164 @@ PyObject *RewriteSection(PyObject *self,PyObject *Args)
static PyMethodDef TagSecMethods[] =
{
// Query
+ {"find",TagSecFind,METH_VARARGS,doc_Find},
+ {"find_raw",TagSecFindRaw,METH_VARARGS,doc_FindRaw},
+ {"find_flag",TagSecFindFlag,METH_VARARGS,doc_FindFlag},
+ {"bytes",TagSecBytes,METH_VARARGS,doc_Bytes},
+#ifdef COMPAT_0_7
{"Find",TagSecFind,METH_VARARGS,doc_Find},
{"FindRaw",TagSecFindRaw,METH_VARARGS,doc_FindRaw},
{"FindFlag",TagSecFindFlag,METH_VARARGS,doc_FindFlag},
{"Bytes",TagSecBytes,METH_VARARGS,doc_Bytes},
+#endif
// Python Special
{"keys",TagSecKeys,METH_VARARGS,doc_Keys},
+#if PY_MAJOR_VERSION < 3
{"has_key",TagSecExists,METH_VARARGS,doc_Exists},
+#endif
{"get",TagSecFind,METH_VARARGS,doc_Find},
{}
};
-// TagSecGetAttr - Get an attribute - variable/method /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-static PyObject *TagSecGetAttr(PyObject *Self,char *Name)
-{
- return Py_FindMethod(TagSecMethods,Self,Name);
-}
- /*}}}*/
-// Type for a Tag Section
+
+PySequenceMethods TagSecSeqMeth = {0,0,0,0,0,0,0,TagSecContains,0,0};
PyMappingMethods TagSecMapMeth = {TagSecLength,TagSecMap,0};
-PyTypeObject TagSecType =
+
+
+static char *doc_TagSec = "TagSection(text) -> Create a new object.\n\n"
+ "TagSection() objects provide methods to access rfc822-style formatted\n"
+ "header sections, like those in debian/control or Packages files.\n\n"
+ "TagSection() behave like read-only dictionaries and also provide access\n"
+ "to the functions provided by the C++ class (e.g. Find)";
+PyTypeObject PyTagSection_Type =
{
- PyObject_HEAD_INIT(&PyType_Type)
- 0, // ob_size
- "TagSection", // tp_name
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.TagSection", // tp_name
sizeof(TagSecData), // tp_basicsize
0, // tp_itemsize
// Methods
TagSecFree, // tp_dealloc
- 0, // tp_print
- TagSecGetAttr, // tp_getattr
+ 0, // tp_print
+ 0, // tp_getattr
0, // tp_setattr
0, // tp_compare
0, // tp_repr
0, // tp_as_number
- 0, // tp_as_sequence
+ &TagSecSeqMeth, // tp_as_sequence
&TagSecMapMeth, // tp_as_mapping
0, // tp_hash
- 0, // tp_call
- TagSecStr, // tp_str
+ 0, // tp_call
+ TagSecStr, // tp_str
+ 0, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ (Py_TPFLAGS_DEFAULT | // tp_flags
+ Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_HAVE_GC),
+ doc_TagSec, // tp_doc
+ CppOwnedTraverse<pkgTagSection>, // tp_traverse
+ CppOwnedClear<pkgTagSection>, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ TagSecMethods, // tp_methods
+ 0, // tp_members
+ 0, // 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
+ TagSecNew, // tp_new
};
// Method table for the Tag File object
static PyMethodDef TagFileMethods[] =
{
// Query
+ {"step",TagFileStep,METH_VARARGS,doc_Step},
+ {"offset",TagFileOffset,METH_VARARGS,doc_Offset},
+ {"jump",TagFileJump,METH_VARARGS,doc_Jump},
+#ifdef COMPAT_0_7
{"Step",TagFileStep,METH_VARARGS,doc_Step},
{"Offset",TagFileOffset,METH_VARARGS,doc_Offset},
{"Jump",TagFileJump,METH_VARARGS,doc_Jump},
+#endif
{}
};
-// TagFileGetAttr - Get an attribute - variable/method /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-static PyObject *TagFileGetAttr(PyObject *Self,char *Name)
-{
- if (strcmp("Section",Name) == 0)
- {
- PyObject *Obj = ((TagFileData *)Self)->Section;
- Py_INCREF(Obj);
- return Obj;
- }
-
- return Py_FindMethod(TagFileMethods,Self,Name);
+// Return the current section.
+static PyObject *TagFileGetSection(PyObject *Self,void*) {
+ PyObject *Obj = ((TagFileData *)Self)->Section;
+ Py_INCREF(Obj);
+ return Obj;
}
+static PyGetSetDef TagFileGetSet[] = {
+ {"section",TagFileGetSection,0,"Return a TagSection.",0},
+#ifdef COMPAT_0_7
+ {"Section",TagFileGetSection,0,"Return a TagSection.",0},
+#endif
+ {}
+};
+
+static char *doc_TagFile = "TagFile(file) -> TagFile() object. \n\n"
+ "TagFile() objects provide access to debian control files, which consists\n"
+ "of multiple RFC822-like formatted sections.\n\n"
+ "A file may consists of multiple sections, and you can use Step() to move\n"
+ "forward. The current TagSection() is available via the attribute section"
+ ".\n\n"
+ "The parameter *file* refers to an object providing a fileno() method or\n"
+ "a file descriptor (an integer)";
+
// Type for a Tag File
-PyTypeObject TagFileType =
+PyTypeObject PyTagFile_Type =
{
- PyObject_HEAD_INIT(&PyType_Type)
- 0, // ob_size
- "TagFile", // tp_name
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.TagFile", // tp_name
sizeof(TagFileData), // tp_basicsize
0, // tp_itemsize
// Methods
TagFileFree, // tp_dealloc
0, // tp_print
- TagFileGetAttr, // tp_getattr
+ 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_as_mapping
0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ 0, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ (Py_TPFLAGS_DEFAULT | // tp_flags
+ Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_HAVE_GC),
+ doc_TagFile, // tp_doc
+ TagFileTraverse, // tp_traverse
+ TagFileClear, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ TagFileMethods, // tp_methods
+ 0, // tp_members
+ TagFileGetSet, // 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
+ TagFileNew, // tp_new
+
};