As reported by: https://github.com/mchehab/zbar/issues/92 python bindings don't build with Python 3.9, because it is using tp_print, which has been silently ignored since Python 3.0, according with[1]: "The tp_print slot of PyTypeObject has been removed. It was used for printing objects to files in Python 2.7 and before. Since Python 3.0, it has been ignored and unused." [1] https://docs.python.org/3.9/whatsnew/3.9.html#id3 Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
273 lines
7.3 KiB
C
273 lines
7.3 KiB
C
/*------------------------------------------------------------------------
|
|
* Copyright 2009-2010 (c) Jeff Brown <spadix@users.sourceforge.net>
|
|
*
|
|
* This file is part of the ZBar Bar Code Reader.
|
|
*
|
|
* The ZBar Bar Code Reader is free software; you can redistribute it
|
|
* and/or modify it under the terms of the GNU Lesser Public License as
|
|
* published by the Free Software Foundation; either version 2.1 of
|
|
* the License, or (at your option) any later version.
|
|
*
|
|
* The ZBar Bar Code Reader is distributed in the hope that it will be
|
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
|
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser Public License
|
|
* along with the ZBar Bar Code Reader; if not, write to the Free
|
|
* Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
|
* Boston, MA 02110-1301 USA
|
|
*
|
|
* http://sourceforge.net/projects/zbar
|
|
*------------------------------------------------------------------------*/
|
|
|
|
#include "zbarmodule.h"
|
|
|
|
static char enumitem_doc[] = PyDoc_STR(
|
|
"simple enumeration item.\n"
|
|
"\n"
|
|
"associates an int value with a name for printing.");
|
|
|
|
static zbarEnumItem*
|
|
enumitem_new (PyTypeObject *type,
|
|
PyObject *args,
|
|
PyObject *kwds)
|
|
{
|
|
int val = 0;
|
|
PyObject *name = NULL;
|
|
static char *kwlist[] = { "value", "name", NULL };
|
|
if(!PyArg_ParseTupleAndKeywords(args, kwds, "iS", kwlist, &val, &name))
|
|
return(NULL);
|
|
|
|
zbarEnumItem *self = (zbarEnumItem*)type->tp_alloc(type, 0);
|
|
if(!self)
|
|
return(NULL);
|
|
|
|
#if PY_MAJOR_VERSION >= 3
|
|
PyLongObject *longval = (PyLongObject*)PyLong_FromLong(val);
|
|
if (!longval) {
|
|
Py_DECREF(self);
|
|
return(NULL);
|
|
}
|
|
|
|
/* we assume the "fast path" for a single-digit ints (see longobject.c) */
|
|
/* this also holds if we get a small_int preallocated long */
|
|
Py_SIZE(&self->val) = Py_SIZE(longval);
|
|
self->val.ob_digit[0] = longval->ob_digit[0];
|
|
Py_DECREF(longval);
|
|
#else
|
|
self->val.ob_ival = val;
|
|
#endif
|
|
self->name = name;
|
|
return(self);
|
|
}
|
|
|
|
static void
|
|
enumitem_dealloc (zbarEnumItem *self)
|
|
{
|
|
Py_CLEAR(self->name);
|
|
((PyObject*)self)->ob_type->tp_free((PyObject*)self);
|
|
}
|
|
|
|
static PyObject*
|
|
enumitem_str (zbarEnumItem *self)
|
|
{
|
|
Py_INCREF(self->name);
|
|
return(self->name);
|
|
}
|
|
|
|
#if PY_MAJOR_VERSION < 3
|
|
/* tp_print was dropped on Python 3.9 */
|
|
static int
|
|
enumitem_print (zbarEnumItem *self,
|
|
FILE *fp,
|
|
int flags)
|
|
{
|
|
return(self->name->ob_type->tp_print(self->name, fp, flags));
|
|
}
|
|
#endif
|
|
|
|
static PyObject*
|
|
enumitem_repr (zbarEnumItem *self)
|
|
{
|
|
PyObject *name = PyObject_Repr(self->name);
|
|
if(!name)
|
|
return(NULL);
|
|
#if PY_MAJOR_VERSION >= 3
|
|
PyObject *repr =
|
|
PyUnicode_FromFormat("%s(%ld, %U)",
|
|
((PyObject*)self)->ob_type->tp_name,
|
|
PyLong_AsLong((PyObject *)self), name);
|
|
#else
|
|
char *namestr = PyString_AsString(name);
|
|
PyObject *repr =
|
|
PyString_FromFormat("%s(%ld, %s)",
|
|
((PyObject*)self)->ob_type->tp_name,
|
|
self->val.ob_ival, namestr);
|
|
#endif
|
|
Py_DECREF(name);
|
|
return((PyObject*)repr);
|
|
}
|
|
|
|
PyTypeObject zbarEnumItem_Type = {
|
|
PyVarObject_HEAD_INIT(NULL, 0)
|
|
.tp_name = "zbar.EnumItem",
|
|
.tp_doc = enumitem_doc,
|
|
.tp_basicsize = sizeof(zbarEnumItem),
|
|
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
|
.tp_new = (newfunc)enumitem_new,
|
|
.tp_dealloc = (destructor)enumitem_dealloc,
|
|
.tp_str = (reprfunc)enumitem_str,
|
|
#if PY_MAJOR_VERSION < 3
|
|
.tp_print = (printfunc)enumitem_print,
|
|
#endif
|
|
.tp_repr = (reprfunc)enumitem_repr,
|
|
};
|
|
|
|
|
|
zbarEnumItem*
|
|
zbarEnumItem_New (PyObject *byname,
|
|
PyObject *byvalue,
|
|
int val,
|
|
const char *name)
|
|
{
|
|
zbarEnumItem *self = PyObject_New(zbarEnumItem, &zbarEnumItem_Type);
|
|
if(!self)
|
|
return(NULL);
|
|
#if PY_MAJOR_VERSION >= 3
|
|
PyLongObject *longval = (PyLongObject*)PyLong_FromLong(val);
|
|
if (!longval) {
|
|
Py_DECREF(self);
|
|
return(NULL);
|
|
}
|
|
|
|
/* we assume the "fast path" for a single-digit ints (see longobject.c) */
|
|
/* this also holds if we get a small_int preallocated long */
|
|
Py_SIZE(&self->val) = Py_SIZE(longval);
|
|
self->val.ob_digit[0] = longval->ob_digit[0];
|
|
Py_DECREF(longval);
|
|
|
|
self->name = PyUnicode_FromString(name);
|
|
#else
|
|
self->val.ob_ival = val;
|
|
self->name = PyString_FromString(name);
|
|
#endif
|
|
if(!self->name ||
|
|
(byname && PyDict_SetItem(byname, self->name, (PyObject*)self)) ||
|
|
(byvalue && PyDict_SetItem(byvalue, (PyObject*)self, (PyObject*)self))) {
|
|
Py_DECREF((PyObject*)self);
|
|
return(NULL);
|
|
}
|
|
return(self);
|
|
}
|
|
|
|
|
|
static char enum_doc[] = PyDoc_STR(
|
|
"enumeration container for EnumItems.\n"
|
|
"\n"
|
|
"exposes items as read-only attributes");
|
|
|
|
/* FIXME add iteration */
|
|
|
|
static int
|
|
enum_traverse (zbarEnum *self,
|
|
visitproc visit,
|
|
void *arg)
|
|
{
|
|
Py_VISIT(self->byname);
|
|
Py_VISIT(self->byvalue);
|
|
return(0);
|
|
}
|
|
|
|
static int
|
|
enum_clear (zbarEnum *self)
|
|
{
|
|
Py_CLEAR(self->byname);
|
|
Py_CLEAR(self->byvalue);
|
|
return(0);
|
|
}
|
|
|
|
static void
|
|
enum_dealloc (zbarEnum *self)
|
|
{
|
|
enum_clear(self);
|
|
((PyObject*)self)->ob_type->tp_free((PyObject*)self);
|
|
}
|
|
|
|
PyTypeObject zbarEnum_Type = {
|
|
PyVarObject_HEAD_INIT(NULL, 0)
|
|
.tp_name = "zbar.Enum",
|
|
.tp_doc = enum_doc,
|
|
.tp_basicsize = sizeof(zbarEnum),
|
|
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
|
|
Py_TPFLAGS_HAVE_GC,
|
|
.tp_dictoffset = offsetof(zbarEnum, byname),
|
|
.tp_traverse = (traverseproc)enum_traverse,
|
|
.tp_clear = (inquiry)enum_clear,
|
|
.tp_dealloc = (destructor)enum_dealloc,
|
|
};
|
|
|
|
|
|
zbarEnum*
|
|
zbarEnum_New ()
|
|
{
|
|
zbarEnum *self = PyObject_GC_New(zbarEnum, &zbarEnum_Type);
|
|
if(!self)
|
|
return(NULL);
|
|
self->byname = PyDict_New();
|
|
self->byvalue = PyDict_New();
|
|
if(!self->byname || !self->byvalue) {
|
|
Py_DECREF(self);
|
|
return(NULL);
|
|
}
|
|
return(self);
|
|
}
|
|
|
|
int
|
|
zbarEnum_Add (zbarEnum *self,
|
|
int val,
|
|
const char *name)
|
|
{
|
|
zbarEnumItem *item;
|
|
item = zbarEnumItem_New(self->byname, self->byvalue, val, name);
|
|
if(!item)
|
|
return(-1);
|
|
return(0);
|
|
}
|
|
|
|
zbarEnumItem*
|
|
zbarEnum_LookupValue (zbarEnum *self,
|
|
int val)
|
|
{
|
|
#if PY_MAJOR_VERSION >= 3
|
|
PyObject *key = PyLong_FromLong(val);
|
|
#else
|
|
PyObject *key = PyInt_FromLong(val);
|
|
#endif
|
|
zbarEnumItem *e = (zbarEnumItem*)PyDict_GetItem(self->byvalue, key);
|
|
if(!e)
|
|
return((zbarEnumItem*)key);
|
|
Py_INCREF((PyObject*)e);
|
|
Py_DECREF(key);
|
|
return(e);
|
|
}
|
|
|
|
PyObject*
|
|
zbarEnum_SetFromMask (zbarEnum *self,
|
|
unsigned int mask)
|
|
{
|
|
PyObject *result = PySet_New(NULL);
|
|
PyObject *key, *item;
|
|
Py_ssize_t i = 0;
|
|
while(PyDict_Next(self->byvalue, &i, &key, &item)) {
|
|
#if PY_MAJOR_VERSION >= 3
|
|
unsigned long val = (unsigned long)PyLong_AsLong(item);
|
|
#else
|
|
int val = PyInt_AsLong(item);
|
|
#endif
|
|
if(val < sizeof(mask) * 8 && ((mask >> val) & 1))
|
|
PySet_Add(result, item);
|
|
}
|
|
return(result);
|
|
}
|