astra / python /tag.cc
Lorenzob's picture
Upload folder using huggingface_hub
859a779 verified
raw
history blame
37 kB
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// $Id: tag.cc,v 1.3 2002/02/26 01:36:15 mdz Exp $
/* ######################################################################
Tag - Binding for the RFC 822 tag file parser
Upon reflection I have make the TagSection wrapper look like a map..
The other option was to use a sequence (which nicely matches the internal
storage) but really makes no sense to a Python Programmer.. One
specialized lookup is provided, the FindFlag lookup - as well as the
usual set of duplicate things to match the C++ interface.
The TagFile interface is also slightly different, it has a built in
internal TagSection object that is used. Do not hold onto a reference
to a TagSection and let TagFile go out of scope! The underlying storage
for the section will go away and it will seg.
##################################################################### */
/*}}}*/
// Include Files /*{{{*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include "generic.h"
#include "apt_pkgmodule.h"
#include <apt-pkg/tagfile.h>
#include <apt-pkg/fileutl.h>
#include <stdio.h>
#include <iostream>
#include <Python.h>
using namespace std;
/*}}}*/
/* We need to keep a private copy of the data.. */
struct TagSecData : public CppPyObject<pkgTagSection>
{
char *Data;
bool Bytes;
#if PY_MAJOR_VERSION >= 3
PyObject *Encoding;
#endif
};
// The owner of the TagFile is a Python file object.
struct TagFileData : public CppPyObject<pkgTagFile>
{
TagSecData *Section;
FileFd Fd;
bool Bytes;
#if PY_MAJOR_VERSION >= 3
PyObject *Encoding;
#endif
};
// 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;
}
// Helpers to return Unicode or bytes as appropriate.
#if PY_MAJOR_VERSION < 3
#define TagSecString_FromStringAndSize(self, v, len) \
PyString_FromStringAndSize((v), (len))
#define TagSecString_FromString(self, v) CppPyString(v)
#else
static PyObject *TagSecString_FromStringAndSize(PyObject *self, const char *v,
Py_ssize_t len) {
TagSecData *Self = (TagSecData *)self;
if (Self->Bytes)
return PyBytes_FromStringAndSize(v, len);
else if (Self->Encoding)
return PyUnicode_Decode(v, len, PyUnicode_AsString(Self->Encoding), 0);
else
return PyUnicode_FromStringAndSize(v, len);
}
static PyObject *TagSecString_FromString(PyObject *self, const char *v) {
TagSecData *Self = (TagSecData *)self;
if (Self->Bytes)
return PyBytes_FromString(v);
else if (Self->Encoding)
return PyUnicode_Decode(v, strlen(v),
PyUnicode_AsString(Self->Encoding), 0);
else
return PyUnicode_FromString(v);
}
#endif
/*}}}*/
// TagSecFree - Free a Tag Section /*{{{*/
// ---------------------------------------------------------------------
/* */
void TagSecFree(PyObject *Obj)
{
TagSecData *Self = (TagSecData *)Obj;
delete [] Self->Data;
CppDealloc<pkgTagSection>(Obj);
}
/*}}}*/
// TagFileFree - Free a Tag File /*{{{*/
// ---------------------------------------------------------------------
/* */
void TagFileFree(PyObject *Obj)
{
#ifdef ALLOC_DEBUG
std::cerr << "=== DEALLOCATING " << Obj->ob_type->tp_name << "^ ===\n";
#endif
TagFileData *Self = (TagFileData *)Obj;
Py_CLEAR(Self->Section);
Self->Object.~pkgTagFile();
Self->Fd.~FileFd();
Py_CLEAR(Self->Owner);
Obj->ob_type->tp_free(Obj);
}
/*}}}*/
// Tag Section Wrappers /*{{{*/
static char *doc_Find =
"find(name: str[, default = None]) -> str\n\n"
"Find the key given by 'name' and return the value. If the key can\n"
"not be found, return 'default'.";
static PyObject *TagSecFind(PyObject *Self,PyObject *Args)
{
char *Name = 0;
char *Default = 0;
if (PyArg_ParseTuple(Args,"s|z",&Name,&Default) == 0)
return 0;
const char *Start;
const char *Stop;
if (GetCpp<pkgTagSection>(Self).Find(Name,Start,Stop) == false)
{
if (Default == 0)
Py_RETURN_NONE;
return TagSecString_FromString(Self,Default);
}
return TagSecString_FromStringAndSize(Self,Start,Stop-Start);
}
static char *doc_FindRaw =
"find_raw(name: str[, default = None] -> str\n\n"
"Same as find(), but returns the complete 'key: value' field; instead of\n"
"just the value.";
static PyObject *TagSecFindRaw(PyObject *Self,PyObject *Args)
{
char *Name = 0;
char *Default = 0;
if (PyArg_ParseTuple(Args,"s|z",&Name,&Default) == 0)
return 0;
unsigned Pos;
if (GetCpp<pkgTagSection>(Self).Find(Name,Pos) == false)
{
if (Default == 0)
Py_RETURN_NONE;
return TagSecString_FromString(Self,Default);
}
const char *Start;
const char *Stop;
GetCpp<pkgTagSection>(Self).Get(Start,Stop,Pos);
return TagSecString_FromStringAndSize(Self,Start,Stop-Start);
}
static char *doc_FindFlag =
"find_flag(name: str) -> int\n\n"
"Return 1 if the key's value is 'yes' or a similar value describing\n"
"a boolean true. If the field does not exist, or does not have such a\n"
"value, return 0.";
static PyObject *TagSecFindFlag(PyObject *Self,PyObject *Args)
{
char *Name = 0;
if (PyArg_ParseTuple(Args,"s",&Name) == 0)
return 0;
unsigned long Flag = 0;
if (GetCpp<pkgTagSection>(Self).FindFlag(Name,Flag,1) == false)
{
Py_INCREF(Py_None);
return Py_None;
}
return PyBool_FromLong(Flag);
}
static char *doc_Write =
"write(file: int, order: List[str], rewrite: List[Tag]) -> None\n\n"
"Rewrites the section into the given file descriptor, which should be\n"
"a file descriptor or an object providing a fileno() method.\n"
"\n"
".. versionadded:: 1.9.0";
static PyObject *TagSecWrite(PyObject *Self, PyObject *Args, PyObject *kwds)
{
char *kwlist[] = {"file", "order", "rewrite", nullptr};
PyObject *pFile;
PyObject *pOrder;
PyObject *pRewrite;
if (PyArg_ParseTupleAndKeywords(Args,kwds, "OO!O!",kwlist, &pFile,&PyList_Type,&pOrder, &PyList_Type, &pRewrite) == 0)
return nullptr;
int fileno = PyObject_AsFileDescriptor(pFile);
// handle invalid arguments
if (fileno == -1)
{
PyErr_SetString(PyExc_TypeError,
"Argument must be string, fd or have a fileno() method");
return 0;
}
FileFd file(fileno);
const char **order = ListToCharChar(pOrder,true);
if (order == nullptr)
return nullptr;
std::vector<pkgTagSection::Tag> rewrite;
for (int I = 0; I != PySequence_Length(pRewrite); I++) {
PyObject *item = PySequence_GetItem(pRewrite, I);
if (!PyObject_TypeCheck(item, &PyTag_Type))
return PyErr_SetString(PyExc_TypeError, "Wrong type for tag in list"), nullptr;
rewrite.push_back(GetCpp<pkgTagSection::Tag>(item));
}
return HandleErrors(PyBool_FromLong(GetCpp<pkgTagSection>(Self).Write(file, order, rewrite)));
}
// Map access, operator []
static PyObject *TagSecMap(PyObject *Self,PyObject *Arg)
{
const char *Name = PyObject_AsString(Arg);
if (Name == 0)
return 0;
const char *Start;
const char *Stop;
if (GetCpp<pkgTagSection>(Self).Find(Name,Start,Stop) == false)
{
PyErr_SetString(PyExc_KeyError,Name);
return 0;
}
return TagSecString_FromStringAndSize(Self,Start,Stop-Start);
}
// len() operation
static Py_ssize_t TagSecLength(PyObject *Self)
{
pkgTagSection &Sec = GetCpp<pkgTagSection>(Self);
return Sec.Count();
}
// Look like a mapping
static char *doc_Keys =
"keys() -> list\n\n"
"Return a list of all keys.";
static PyObject *TagSecKeys(PyObject *Self,PyObject *Args)
{
pkgTagSection &Tags = GetCpp<pkgTagSection>(Self);
if (PyArg_ParseTuple(Args,"") == 0)
return 0;
// Convert the whole configuration space into a list
PyObject *List = PyList_New(0);
for (unsigned int I = 0; I != Tags.Count(); I++)
{
const char *Start;
const char *Stop;
Tags.Get(Start,Stop,I);
const char *End = Start;
for (; End < Stop && *End != ':'; End++);
PyObject *Obj;
PyList_Append(List,Obj = PyString_FromStringAndSize(Start,End-Start));
Py_DECREF(Obj);
}
return List;
}
#if PY_MAJOR_VERSION < 3
static char *doc_Exists =
"has_key(name: str) -> bool\n\n"
"Return True if the key given by 'name' exists, False otherwise.";
static PyObject *TagSecExists(PyObject *Self,PyObject *Args)
{
char *Name = 0;
if (PyArg_ParseTuple(Args,"s",&Name) == 0)
return 0;
const char *Start;
const char *Stop;
return PyBool_FromLong(GetCpp<pkgTagSection>(Self).Find(Name,Start,Stop));
}
#endif
static int TagSecContains(PyObject *Self,PyObject *Arg)
{
const char *Name = PyObject_AsString(Arg);
if (Name == 0)
return 0;
const char *Start;
const char *Stop;
if (GetCpp<pkgTagSection>(Self).Find(Name,Start,Stop) == false)
return 0;
return 1;
}
static char *doc_Bytes =
"bytes() -> int\n\n"
"Return the number of bytes this section is large.";
static PyObject *TagSecBytes(PyObject *Self,PyObject *Args)
{
if (PyArg_ParseTuple(Args,"") == 0)
return 0;
return MkPyNumber(GetCpp<pkgTagSection>(Self).size());
}
static PyObject *TagSecStr(PyObject *Self)
{
const char *Start;
const char *Stop;
GetCpp<pkgTagSection>(Self).GetSection(Start,Stop);
return TagSecString_FromStringAndSize(Self,Start,Stop-Start);
}
/*}}}*/
// TagFile Wrappers /*{{{*/
static char *doc_Step =
"step() -> bool\n\n"
"Step forward in the file";
static PyObject *TagFileStep(PyObject *Self,PyObject *Args)
{
if (PyArg_ParseTuple(Args,"") == 0)
return 0;
TagFileData &Obj = *(TagFileData *)Self;
if (Obj.Object.Step(Obj.Section->Object) == false)
return HandleErrors(PyBool_FromLong(0));
return HandleErrors(PyBool_FromLong(1));
}
// TagFile Wrappers /*{{{*/
static PyObject *TagFileNext(PyObject *Self)
{
TagFileData &Obj = *(TagFileData *)Self;
// Replace the section.
Py_CLEAR(Obj.Section);
Obj.Section = (TagSecData*)(&PyTagSection_Type)->tp_alloc(&PyTagSection_Type, 0);
new (&Obj.Section->Object) pkgTagSection();
Obj.Section->Owner = Self;
Py_INCREF(Obj.Section->Owner);
Obj.Section->Data = 0;
Obj.Section->Bytes = Obj.Bytes;
#if PY_MAJOR_VERSION >= 3
// We don't need to incref Encoding as the previous Section object already
// held a reference to it.
Obj.Section->Encoding = Obj.Encoding;
#endif
if (Obj.Object.Step(Obj.Section->Object) == false)
return HandleErrors(NULL);
// Bug-Debian: http://bugs.debian.org/572596
// Duplicate the data here and scan the duplicated section data; in order
// to not use any shared storage.
// TODO: Provide an API in apt-pkg to do this; this is really ugly.
// Fetch old section data
const char *Start;
const char *Stop;
Obj.Section->Object.GetSection(Start,Stop);
// Duplicate the data and
// append a \n because GetSection() will only give us a single \n
// but Scan() needs \n\n to work
Obj.Section->Data = new char[Stop-Start+2];
memcpy(Obj.Section->Data, Start, Stop - Start);
Obj.Section->Data[Stop-Start] = '\n';
Obj.Section->Data[Stop-Start+1] = '\0';
// Rescan it
if(Obj.Section->Object.Scan(Obj.Section->Data, Stop-Start+2) == false)
return HandleErrors(NULL);
Py_INCREF(Obj.Section);
return HandleErrors(Obj.Section);
}
static PyObject *TagFileIter(PyObject *Self) {
Py_INCREF(Self);
return Self;
}
static char *doc_Offset =
"offset() -> int\n\n"
"Return the current offset.";
static PyObject *TagFileOffset(PyObject *Self,PyObject *Args)
{
if (PyArg_ParseTuple(Args,"") == 0)
return 0;
return MkPyNumber(((TagFileData *)Self)->Object.Offset());
}
static char *doc_Jump =
"jump(offset: int) -> bool\n\n"
"Jump to the given offset; return True on success. Note that jumping to\n"
"an offset is not very reliable, and the 'section' attribute may point\n"
"to an unexpected section.";
static PyObject *TagFileJump(PyObject *Self,PyObject *Args)
{
int Offset;
if (PyArg_ParseTuple(Args,"i",&Offset) == 0)
return 0;
TagFileData &Obj = *(TagFileData *)Self;
if (Obj.Object.Jump(Obj.Section->Object,Offset) == false)
return HandleErrors(PyBool_FromLong(0));
return HandleErrors(PyBool_FromLong(1));
}
static char *doc_Close =
"close()\n\n"
"Close the file.";
static PyObject *TagFileClose(PyObject *self, PyObject *args)
{
if (args != NULL && !PyArg_ParseTuple(args, ""))
return NULL;
TagFileData &Obj = *(TagFileData *) self;
Obj.Fd.Close();
Py_INCREF(Py_None);
return HandleErrors(Py_None);
}
static PyObject *TagFileExit(PyObject *self, PyObject *args)
{
PyObject *exc_type = 0;
PyObject *exc_value = 0;
PyObject *traceback = 0;
if (!PyArg_UnpackTuple(args, "__exit__", 3, 3, &exc_type, &exc_value,
&traceback)) {
return 0;
}
PyObject *res = TagFileClose(self, NULL);
if (res == NULL) {
// The close failed. If no exception happened within the suite, we
// will raise an error here. Otherwise, we just display the error, so
// Python can handle the original exception instead.
if (exc_type == Py_None)
return NULL;
PyErr_WriteUnraisable(self);
} else {
Py_DECREF(res);
}
// Return False, as required by the context manager protocol.
Py_RETURN_FALSE;
}
static PyObject *TagFileEnter(PyObject *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, ""))
return NULL;
Py_INCREF(self);
return self;
}
/*}}}*/
// ParseSection - Parse a single section from a tag file /*{{{*/
// ---------------------------------------------------------------------
static PyObject *TagSecNew(PyTypeObject *type,PyObject *Args,PyObject *kwds) {
char *Data;
Py_ssize_t Len;
char Bytes = 0;
char *kwlist[] = {"text", "bytes", 0};
// this allows reading "byte" types from python3 - but we don't
// make (much) use of it yet
if (PyArg_ParseTupleAndKeywords(Args,kwds,"s#|b",kwlist,&Data,&Len,&Bytes) == 0)
return 0;
if (memchr(Data, 0, Len) != nullptr) {
PyErr_SetString(PyExc_ValueError, "Input contains NUL byte");
return 0;
}
if (Data[Len] != 0) {
PyErr_SetString(PyExc_ValueError, "Input is not terminated by NUL byte");
return 0;
}
// Create the object..
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);
New->Bytes = Bytes;
#if PY_MAJOR_VERSION >= 3
New->Encoding = 0;
#endif
if (New->Object.Scan(New->Data,strlen(New->Data)) == false)
{
cerr << New->Data << endl;
Py_DECREF((PyObject *)New);
PyErr_SetString(PyExc_ValueError,"Unable to parse section data");
return 0;
}
New->Object.Trim();
return New;
}
/*}}}*/
// ParseTagFile - Parse a tagd file /*{{{*/
// ---------------------------------------------------------------------
/* This constructs the parser state. */
static PyObject *TagFileNew(PyTypeObject *type,PyObject *Args,PyObject *kwds)
{
PyObject *File = 0;
char Bytes = 0;
char *kwlist[] = {"file", "bytes", 0};
if (PyArg_ParseTupleAndKeywords(Args,kwds,"O|b",kwlist,&File,&Bytes) == 0)
return 0;
// check if we got a filename or a file object
int fileno = -1;
PyApt_Filename filename;
if (!filename.init(File)) {
PyErr_Clear();
fileno = PyObject_AsFileDescriptor(File);
}
// handle invalid arguments
if (fileno == -1 && filename == NULL)
{
PyErr_SetString(PyExc_TypeError,
"Argument must be string, fd or have a fileno() method");
return 0;
}
PyApt_UniqueObject<TagFileData> New((TagFileData*)type->tp_alloc(type, 0));
if (fileno != -1)
{
#ifdef APT_HAS_GZIP
new (&New->Fd) FileFd();
New->Fd.OpenDescriptor(fileno, FileFd::ReadOnlyGzip, false);
#else
new (&New->Fd) FileFd(fileno,false);
#endif
}
else
{
// FileFd::Extension got added in this revision
#if (APT_PKG_MAJOR > 4 || (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 12))
new (&New->Fd) FileFd(filename, FileFd::ReadOnly, FileFd::Extension, false);
#else
new (&New->Fd) FileFd(filename, FileFd::ReadOnly, false);
#endif
}
New->Bytes = Bytes;
New->Owner = File;
Py_INCREF(New->Owner);
#if PY_MAJOR_VERSION >= 3
if (fileno != -1) {
New->Encoding = PyObject_GetAttr(File, PyUnicode_FromString("encoding"));
if (!New->Encoding)
PyErr_Clear();
if (New->Encoding && !PyUnicode_Check(New->Encoding))
New->Encoding = 0;
} else
New->Encoding = 0;
Py_XINCREF(New->Encoding);
#endif
new (&New->Object) pkgTagFile(&New->Fd);
// Create the section
New->Section = (TagSecData*)(&PyTagSection_Type)->tp_alloc(&PyTagSection_Type, 0);
new (&New->Section->Object) pkgTagSection();
New->Section->Owner = New.get();
Py_INCREF(New->Section->Owner);
New->Section->Data = 0;
New->Section->Bytes = Bytes;
#if PY_MAJOR_VERSION >= 3
New->Section->Encoding = New->Encoding;
Py_XINCREF(New->Section->Encoding);
#endif
return HandleErrors(New.release());
}
/*}}}*/
// Method table for the Tag Section object
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},
{"write",(PyCFunction) TagSecWrite,METH_VARARGS|METH_KEYWORDS,doc_Write},
// 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},
{}
};
PySequenceMethods TagSecSeqMeth = {0,0,0,0,0,0,0,TagSecContains,0,0};
PyMappingMethods TagSecMapMeth = {TagSecLength,TagSecMap,0};
static char *doc_TagSec = "TagSection(text: str, [bytes: bool = False])\n\n"
"Provide methods to access RFC822-style header sections, like those\n"
"found 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).\n\n"
"By default, text read from files is treated as strings (binary data in\n"
"Python 2, Unicode strings in Python 3). Use bytes=True to cause all\n"
"header values read from this TagSection to be bytes even in Python 3.\n"
"Header names are always treated as Unicode.";
PyTypeObject PyTagSection_Type =
{
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
0, // tp_getattr
0, // tp_setattr
0, // tp_compare
0, // tp_repr
0, // tp_as_number
&TagSecSeqMeth, // tp_as_sequence
&TagSecMapMeth, // tp_as_mapping
0, // tp_hash
0, // tp_call
TagSecStr, // tp_str
_PyAptObject_getattro, // 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
CppTraverse<pkgTagSection>, // tp_traverse
CppClear<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},
{"close",TagFileClose,METH_VARARGS,doc_Close},
{"__enter__",TagFileEnter,METH_VARARGS,"Context manager entry, return self."},
{"__exit__",TagFileExit,METH_VARARGS,"Context manager exit, calls close."},
{}
};
// 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,
"The current section, as a TagSection object.",0},
{}
};
static char *doc_TagFile = "TagFile(file, [bytes: bool = False])\n\n"
"TagFile() objects provide access to debian control files, which consist\n"
"of multiple RFC822-style sections.\n\n"
"To provide access to those sections, TagFile objects provide an iterator\n"
"which yields TagSection objects for each section.\n\n"
"TagFile objects also provide another API which uses a shared TagSection\n"
"object in the 'section' member. The functions step() and jump() can be\n"
"used to navigate within the file; offset() returns the current\n"
"position.\n\n"
"It is important to not mix the use of both APIs, because this can have\n"
"unwanted effects.\n\n"
"The parameter 'file' refers to an object providing a fileno() method or\n"
"a file descriptor (an integer).\n\n"
"By default, text read from files is treated as strings (binary data in\n"
"Python 2, Unicode strings in Python 3). Use bytes=True to cause all\n"
"header values read from this TagFile to be bytes even in Python 3.\n"
"Header names are always treated as Unicode.";
// Type for a Tag File
PyTypeObject PyTagFile_Type =
{
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
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 |
Py_TPFLAGS_HAVE_GC),
doc_TagFile, // tp_doc
TagFileTraverse, // tp_traverse
TagFileClear, // tp_clear
0, // tp_richcompare
0, // tp_weaklistoffset
TagFileIter, // tp_iter
TagFileNext, // 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
};
// Return the current section.
static PyObject *TagGetAction(PyObject *Self,void*) {
return MkPyNumber(GetCpp<pkgTagSection::Tag>(Self).Action);
}
static PyObject *TagGetName(PyObject *Self,void*) {
return CppPyString(GetCpp<pkgTagSection::Tag>(Self).Name);
}
static PyObject *TagGetData(PyObject *Self,void*) {
return CppPyString(GetCpp<pkgTagSection::Tag>(Self).Data);
}
static PyObject *PyTagRename_New(PyTypeObject *type,PyObject *Args,PyObject *kwds) {
char *oldName;
char *newName;
char *kwlist[] = {"old_name", "new_name", 0};
if (PyArg_ParseTupleAndKeywords(Args,kwds,"ss",kwlist, &oldName, &newName) == 0)
return nullptr;
if (oldName[0] == '\0') {
PyErr_SetString(PyExc_ValueError, "Old tag name may not be empty.");
return nullptr;
}
if (newName[0] == '\0') {
PyErr_SetString(PyExc_ValueError, "New tag name may not be empty.");
return nullptr;
}
auto tag = pkgTagSection::Tag::Rename(oldName, newName);
return CppPyObject_NEW<pkgTagSection::Tag>(nullptr, type, tag);
}
static PyObject *PyTagRewrite_New(PyTypeObject *type,PyObject *Args,PyObject *kwds) {
char *name;
char *data;
char *kwlist[] = {"name", "data", 0};
if (PyArg_ParseTupleAndKeywords(Args,kwds,"ss",kwlist, &name, &data) == 0)
return nullptr;
if (name[0] == '\0') {
PyErr_SetString(PyExc_ValueError, "Tag name may not be empty.");
return nullptr;
}
if (data[0] == '\0') {
PyErr_SetString(PyExc_ValueError, "New value may not be empty.");
return nullptr;
}
auto tag = pkgTagSection::Tag::Rewrite(name, data);
return CppPyObject_NEW<pkgTagSection::Tag>(nullptr, type, tag);
}
static PyObject *PyTagRemove_New(PyTypeObject *type,PyObject *Args,PyObject *kwds) {
char *name;
char *kwlist[] = {"name", nullptr};
if (PyArg_ParseTupleAndKeywords(Args,kwds,"s",kwlist, &name) == 0)
return nullptr;
if (name[0] == '\0') {
PyErr_SetString(PyExc_ValueError, "Tag name may not be empty.");
return nullptr;
}
auto tag = pkgTagSection::Tag::Remove(name);
return CppPyObject_NEW<pkgTagSection::Tag>(nullptr, type, tag);
}
static PyGetSetDef TagGetSet[] = {
{"action",TagGetAction,0,
"The action to perform.",0},
{"name",TagGetName,0,
"The name of the tag to perform the action on.",0},
{"data",TagGetData,0,
"The data to write instead (for REWRITE), or the new tag name (RENAME)",0},
{}
};
static char doc_Tag[] = "Tag\n\n"
"Identify actions to be executed on a task\n"
"\n"
"This is used in conjunction with :meth:`TagSection.write` to rewrite\n"
"a tag section into a new one.\n"
"\n"
"This class is abstract, use one of the subclasses:\n"
":class:`TagRewrite`, :class:`TagRemove`, :class:`TagRename`\n"
"\n"
".. versionadded:: 1.1";
static char doc_TagRewrite[] = "TagRewrite(name: str, data: str)\n\n"
"Change the value of the tag to the string passed in *data*\n"
"\n"
".. versionadded:: 1.1";
static char doc_TagRename[] = "TagRename(old_name: str, new_name: str)\n\n"
"Rename the tag *old_name* to *new_name*\n"
"\n"
".. versionadded:: 1.1";
static char doc_TagRemove[] = "TagRemove(name: str)\n\n"
"Remove the tag *name* from the tag section\n"
"\n"
".. versionadded:: 1.1";
// Type for a Tag File
PyTypeObject PyTag_Type =
{
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"apt_pkg.Tag", // tp_name
sizeof(CppPyObject<pkgTagSection::Tag>), // tp_basicsize
0, // tp_itemsize
// Methods
CppDealloc<pkgTagSection::Tag>, // 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
0, // tp_getattro
0, // tp_setattro
0, // tp_as_buffer
(Py_TPFLAGS_DEFAULT // tp_flags
| Py_TPFLAGS_BASETYPE),
doc_Tag, // tp_doc
CppTraverse<pkgTagSection::Tag>, // tp_traverse
CppClear<pkgTagSection::Tag>, // tp_clear
0, // tp_richcompare
0, // tp_weaklistoffset
0, // tp_iter
0, // tp_iternext
0, // tp_methods
0, // tp_members
TagGetSet, // 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
0, // tp_new
};
// Type for a Tag File
PyTypeObject PyTagRewrite_Type =
{
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"apt_pkg.TagRewrite", // tp_name
sizeof(CppPyObject<pkgTagSection::Tag>), // tp_basicsize
0, // tp_itemsize
// Methods
CppDealloc<pkgTagSection::Tag>, // 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
0, // tp_getattro
0, // tp_setattro
0, // tp_as_buffer
Py_TPFLAGS_DEFAULT, // tp_flags
doc_TagRewrite, // tp_doc
CppTraverse<pkgTagSection::Tag>, // tp_traverse
CppClear<pkgTagSection::Tag>, // tp_clear
0, // tp_richcompare
0, // tp_weaklistoffset
0, // tp_iter
0, // tp_iternext
0, // tp_methods
0, // tp_members
0, // tp_getset
&PyTag_Type, // tp_base
0, // tp_dict
0, // tp_descr_get
0, // tp_descr_set
0, // tp_dictoffset
0, // tp_init
0, // tp_alloc
PyTagRewrite_New, // tp_new
};
// Type for a Tag File
PyTypeObject PyTagRemove_Type =
{
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"apt_pkg.TagRemove", // tp_name
sizeof(CppPyObject<pkgTagSection::Tag>), // tp_basicsize
0, // tp_itemsize
// Methods
CppDealloc<pkgTagSection::Tag>, // 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
0, // tp_getattro
0, // tp_setattro
0, // tp_as_buffer
Py_TPFLAGS_DEFAULT, // tp_flags
doc_TagRemove, // tp_doc
CppTraverse<pkgTagSection::Tag>, // tp_traverse
CppClear<pkgTagSection::Tag>, // tp_clear
0, // tp_richcompare
0, // tp_weaklistoffset
0, // tp_iter
0, // tp_iternext
0, // tp_methods
0, // tp_members
0, // tp_getset
&PyTag_Type, // tp_base
0, // tp_dict
0, // tp_descr_get
0, // tp_descr_set
0, // tp_dictoffset
0, // tp_init
0, // tp_alloc
PyTagRemove_New, // tp_new
};
// Type for a Tag File
PyTypeObject PyTagRename_Type =
{
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"apt_pkg.TagRename", // tp_name
sizeof(CppPyObject<pkgTagSection::Tag>), // tp_basicsize
0, // tp_itemsize
// Methods
CppDealloc<pkgTagSection::Tag>, // 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
0, // tp_getattro
0, // tp_setattro
0, // tp_as_buffer
Py_TPFLAGS_DEFAULT, // tp_flags
doc_TagRename, // tp_doc
CppTraverse<pkgTagSection::Tag>, // tp_traverse
CppClear<pkgTagSection::Tag>, // tp_clear
0, // tp_richcompare
0, // tp_weaklistoffset
0, // tp_iter
0, // tp_iternext
0, // tp_methods
0, // tp_members
0, // tp_getset
&PyTag_Type, // tp_base
0, // tp_dict
0, // tp_descr_get
0, // tp_descr_set
0, // tp_dictoffset
0, // tp_init
0, // tp_alloc
PyTagRename_New, // tp_new
};