Add bindings for __version_info__, __version__ and __author__

This commit is contained in:
angie 2023-09-22 19:23:34 -03:00
parent 5a9939afc5
commit df1a1233bd
8 changed files with 62 additions and 2 deletions

View File

@ -11,6 +11,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add `CHANGELOG.md`
- Add markdown linter to CI
- Add Python binding for `rabbitizer.__version_info__`
- Add Python binding for `rabbitizer.__version__`
- Add Python binding for `rabbitizer.__author__`
### Fixed

View File

@ -18,6 +18,9 @@ extern "C" {
#define RAB_VERSION_STR RAB_STRINGIFY(RAB_VERSION_MAJOR) "." RAB_STRINGIFY(RAB_VERSION_MINOR) "." RAB_STRINGIFY(RAB_VERSION_PATCH)
#define RAB_VERSION_AUTHOR "Decompollaborate"
// Compiled library version
extern const int RabVersion_Major;
extern const int RabVersion_Minor;
@ -25,6 +28,8 @@ extern const int RabVersion_Patch;
extern const char RabVersion_Str[];
extern const char RabVersion_Author[];
#ifdef __cplusplus
}

View File

@ -5,6 +5,10 @@
from __future__ import annotations
__version_info__: tuple[int, int, int]
__version__: str
__author__: str
from .Utils import *
from .Enum import *

View File

@ -10,6 +10,9 @@
#include "structmember.h"
#define RAB_STRCMP_LITERAL(var, literal) strncmp(var, literal, sizeof(literal) - 1)
#define DECL_RAB_TYPE(typeName, memberName) \
typedef struct PyRabbitizer##typeName { \
PyObject_HEAD \

View File

@ -7,6 +7,7 @@
#include "common/Utils.h"
#include "instructions/RabbitizerInstrId.h"
#include "common/RabbitizerVersion.h"
typedef enum ModuleAttributeCategory {
@ -123,12 +124,52 @@ error:
return -1;
}
#define rabbitizer_module_method___getattr___docs "Hacky way to get read-only global variables"
static PyModuleDef rabbitizer_module = {
PyObject *rabbitizer_module_method___getattr__(UNUSED void *self, PyObject *args, PyObject *kwds) {
static char *kwlist[] = { "name", NULL };
const char *attributeName = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &attributeName)) {
return NULL;
}
if (attributeName == NULL) {
PyErr_Format(PyExc_AssertionError, "%s: assert(attributeName != NULL)", __func__);
return NULL;
}
if (RAB_STRCMP_LITERAL(attributeName, "__version_info__") == 0) {
return Py_BuildValue("(iii)", RabVersion_Major, RabVersion_Minor, RabVersion_Patch);
}
if (RAB_STRCMP_LITERAL(attributeName, "__version__") == 0) {
return PyUnicode_FromString(RabVersion_Str);
}
if (RAB_STRCMP_LITERAL(attributeName, "__author__") == 0) {
return PyUnicode_FromString(RabVersion_Author);
}
PyErr_Format(PyExc_AttributeError, "module '%s' has no attribute '%s'",
rabbitizer_module.m_name, attributeName);
return NULL;
}
#define METHOD_NO_ARGS(name) { #name, (PyCFunction) (void *) rabbitizer_module_method_##name, METH_NOARGS, PyDoc_STR(rabbitizer_module_method_##name##_docs) }
#define METHOD_ARGS(name) { #name, (PyCFunction) (void *) rabbitizer_module_method_##name, METH_VARARGS | METH_KEYWORDS, PyDoc_STR(rabbitizer_module_method_##name##_docs) }
PyMethodDef rabbitizer_module_methods[] = {
METHOD_ARGS(__getattr__),
{ 0 },
};
PyModuleDef rabbitizer_module = {
PyModuleDef_HEAD_INIT,
.m_name = "rabbitizer",
.m_doc = "",
.m_size = -1,
.m_methods = rabbitizer_module_methods,
};
PyMODINIT_FUNC PyInit_rabbitizer(void) {

View File

@ -21,6 +21,8 @@
// TODO: clean up this...
extern PyModuleDef rabbitizer_module;
PyObject *rabbitizer_submodule_Utils_Init(void);
extern PyTypeObject rabbitizer_global_config_TypeObject;

View File

@ -610,7 +610,7 @@ static PyMethodDef rabbitizer_type_Instruction_methods[] = {
METHOD_ARGS(disassemble, "description"),
METHOD_ARGS(__reduce__, ""),
METHOD_NO_ARGS(__reduce__, ""),
{ 0 },
};

View File

@ -8,3 +8,5 @@ const int RabVersion_Minor = RAB_VERSION_MINOR;
const int RabVersion_Patch = RAB_VERSION_PATCH;
const char RabVersion_Str[] = RAB_VERSION_STR;
const char RabVersion_Author[] = RAB_VERSION_AUTHOR;