drgn/libdrgn/python/language.c
Omar Sandoval 1fe01bb4b8 libdrgn: python: add call_tp_alloc()
There are a bunch of places where we call .tp_alloc() directly, which is
very verbose. Add a macro that removes the boilerplate.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2022-10-05 16:24:29 -07:00

83 lines
2.0 KiB
C

// Copyright (c) Meta Platforms, Inc. and affiliates.
// SPDX-License-Identifier: GPL-3.0-or-later
#include "drgnpy.h"
#include "../array.h"
#include "../language.h"
static PyObject *Language_repr(Language *self)
{
return PyUnicode_FromFormat("Language.%s", self->attr_name);
}
static PyObject *Language_get_name(Language *self, void *arg)
{
return PyUnicode_FromString(self->language->name);
}
static PyGetSetDef Language_getset[] = {
{"name", (getter)Language_get_name, NULL, drgn_Language_name_DOC, NULL},
{},
};
PyTypeObject Language_type = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "_drgn.Language",
.tp_basicsize = sizeof(Language),
.tp_repr = (reprfunc)Language_repr,
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_doc = drgn_Language_DOC,
.tp_getset = Language_getset,
};
static PyObject *languages_py[DRGN_NUM_LANGUAGES];
PyObject *Language_wrap(const struct drgn_language *language)
{
PyObject *obj = languages_py[language->number];
Py_INCREF(obj);
return obj;
}
int language_converter(PyObject *o, void *p)
{
const struct drgn_language **ret = p;
if (o == Py_None) {
*ret = NULL;
return 1;
} else if (PyObject_TypeCheck(o, &Language_type)) {
*ret = ((Language *)o)->language;
return 1;
} else {
PyErr_Format(PyExc_TypeError,
"expected Language, not %s",
Py_TYPE(o)->tp_name);
return 0;
}
}
int add_languages(void)
{
static const char * const attr_names[] = {
[DRGN_LANGUAGE_C] = "C",
[DRGN_LANGUAGE_CPP] = "CPP",
};
static_assert(array_size(attr_names) == DRGN_NUM_LANGUAGES,
"missing language in attr_names");
for (size_t i = 0; i < DRGN_NUM_LANGUAGES; i++) {
Language *language_obj = call_tp_alloc(Language);
if (!language_obj)
return -1;
language_obj->attr_name = attr_names[i];
language_obj->language = drgn_languages[i];
languages_py[i] = (PyObject *)language_obj;
int ret = PyDict_SetItemString(Language_type.tp_dict,
attr_names[i],
(PyObject *)language_obj);
if (ret)
return ret;
}
return 0;
}