diff options
Diffstat (limited to 'python/tag.cc')
| -rw-r--r-- | python/tag.cc | 244 |
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 + }; |
