diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2020-10-13 22:17:14 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2020-10-13 22:21:21 (GMT) |
commit | 601b8149bf81231a09e2977dbdbfe8e8e568c1f4 (patch) | |
tree | 9cf7c0e3b6398b4ad24880b3dcd26ef9b013a7fe /plugins/pychrysalide | |
parent | 362ff8ddd7fac8a10c7cccae303d2ce5ea6dd7f2 (diff) |
Defined proper Python bindings for class/enum types.
Diffstat (limited to 'plugins/pychrysalide')
-rw-r--r-- | plugins/pychrysalide/analysis/types/basic.c | 13 | ||||
-rw-r--r-- | plugins/pychrysalide/analysis/types/constants.c | 101 | ||||
-rw-r--r-- | plugins/pychrysalide/analysis/types/constants.h | 6 | ||||
-rw-r--r-- | plugins/pychrysalide/analysis/types/cse.c | 110 |
4 files changed, 167 insertions, 63 deletions
diff --git a/plugins/pychrysalide/analysis/types/basic.c b/plugins/pychrysalide/analysis/types/basic.c index 539bcad..9ae4f8f 100644 --- a/plugins/pychrysalide/analysis/types/basic.c +++ b/plugins/pychrysalide/analysis/types/basic.c @@ -116,12 +116,13 @@ static PyObject *py_basic_type_get_base(PyObject *self, void *closure) GBasicType *type; /* Version GLib du type */ BaseType base; /* Type de base à renvoyer */ -#define BASIC_TYPE_BASE_ATTRIB PYTHON_GET_DEF_FULL \ -( \ - base, py_basic_type, \ - "Provide the internal identifier of the basic type.\n" \ - "\n" \ - "This property provides a pychrysalide.analysis.BaseType value." \ +#define BASIC_TYPE_BASE_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + base, py_basic_type, \ + "Provide the internal identifier of the basic type.\n" \ + "\n" \ + "This property provides a" \ + " pychrysalide.analysis.types.BasicType.BaseType value." \ ) type = G_BASIC_TYPE(pygobject_get(self)); diff --git a/plugins/pychrysalide/analysis/types/constants.c b/plugins/pychrysalide/analysis/types/constants.c index 6562fa0..1112410 100644 --- a/plugins/pychrysalide/analysis/types/constants.c +++ b/plugins/pychrysalide/analysis/types/constants.c @@ -26,6 +26,7 @@ #include <analysis/types/basic.h> +#include <analysis/types/cse.h> #include "../../helpers.h" @@ -153,3 +154,103 @@ int convert_to_basic_type_base_type(PyObject *arg, void *dst) return result; } + + +/****************************************************************************** +* * +* Paramètres : type = type dont le dictionnaire est à compléter. * +* * +* Description : Définit les constantes relatives aux classes et énumérations.* +* * +* Retour : true en cas de succès de l'opération, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool define_class_enum_type_constants(PyTypeObject *type) +{ + bool result; /* Bilan à retourner */ + PyObject *values; /* Groupe de valeurs à établir */ + + values = PyDict_New(); + + result = add_const_to_group(values, "UNKNOWN", CEK_UNKNOWN); + if (result) result = add_const_to_group(values, "STRUCT", CEK_STRUCT); + if (result) result = add_const_to_group(values, "ENUM", CEK_ENUM); + if (result) result = add_const_to_group(values, "CLASS", CEK_CLASS); + if (result) result = add_const_to_group(values, "NAMESPACE", CEK_NAMESPACE); + if (result) result = add_const_to_group(values, "VIRTUAL_TABLE", CEK_VIRTUAL_TABLE); + if (result) result = add_const_to_group(values, "VIRTUAL_STRUCT", CEK_VIRTUAL_STRUCT); + if (result) result = add_const_to_group(values, "COUNT", CEK_COUNT); + + if (!result) + { + Py_DECREF(values); + goto exit; + } + + result = attach_constants_group_to_type(type, false, "ClassEnumKind", values, + "Kind of types such as classes, structures and enumerations."); + + exit: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : arg = argument quelconque à tenter de convertir. * +* dst = destination des valeurs récupérées en cas de succès. * +* * +* Description : Tente de convertir en constante ClassEnumKind. * +* * +* Retour : Bilan de l'opération, voire indications supplémentaires. * +* * +* Remarques : - * +* * +******************************************************************************/ + +int convert_to_class_enum_type_class_enum_kind(PyObject *arg, void *dst) +{ + int result; /* Bilan à retourner */ + unsigned long value; /* Valeur transcrite */ + + result = PyObject_IsInstance(arg, (PyObject *)&PyLong_Type); + + switch (result) + { + case -1: + /* L'exception est déjà fixée par Python */ + result = 0; + break; + + case 0: + PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to ClassEnumKind"); + break; + + case 1: + value = PyLong_AsUnsignedLong(arg); + + if (value > CEK_COUNT) + { + PyErr_SetString(PyExc_TypeError, "invalid value for ClassEnumKind"); + result = 0; + } + + else + *((ClassEnumKind *)dst) = value; + + break; + + default: + assert(false); + break; + + } + + return result; + +} diff --git a/plugins/pychrysalide/analysis/types/constants.h b/plugins/pychrysalide/analysis/types/constants.h index 9598f75..b695e8d 100644 --- a/plugins/pychrysalide/analysis/types/constants.h +++ b/plugins/pychrysalide/analysis/types/constants.h @@ -37,6 +37,12 @@ bool define_basic_type_constants(PyTypeObject *); /* Tente de convertir en constante BaseType. */ int convert_to_basic_type_base_type(PyObject *, void *); +/* Définit les constantes relatives aux classes et énumérations. */ +bool define_class_enum_type_constants(PyTypeObject *); + +/* Tente de convertir en constante ClassEnumKind. */ +int convert_to_class_enum_type_class_enum_kind(PyObject *, void *); + #endif /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_TYPES_CONSTANTS_H */ diff --git a/plugins/pychrysalide/analysis/types/cse.c b/plugins/pychrysalide/analysis/types/cse.c index 5f0bb0a..7701d48 100644 --- a/plugins/pychrysalide/analysis/types/cse.c +++ b/plugins/pychrysalide/analysis/types/cse.c @@ -32,6 +32,7 @@ #include <analysis/types/cse.h> +#include "constants.h" #include "../type.h" #include "../../access.h" #include "../../helpers.h" @@ -42,14 +43,11 @@ static PyObject *py_class_enum_type_new(PyTypeObject *, PyObject *, PyObject *); /* Fournit le type pris en compte géré par le type. */ -static PyObject *py_class_enum_type_get_base_type(PyObject *, void *); +static PyObject *py_class_enum_type_get_kind(PyObject *, void *); /* Donne la désignation de la classe / structure / énumération. */ static PyObject *py_class_enum_type_get_name(PyObject *, void *); -/* Définit les constantes pour les types de classe/énumération. */ -static bool py_class_enum_type_define_constants(PyTypeObject *); - /****************************************************************************** @@ -69,21 +67,35 @@ static bool py_class_enum_type_define_constants(PyTypeObject *); static PyObject *py_class_enum_type_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *result; /* Instance à retourner */ - unsigned long base; /* Type de base à créer */ + ClassEnumKind kind; /* Type de base à créer */ const char *name; /* Désignation humaine */ int ret; /* Bilan de lecture des args. */ GDataType *dtype; /* Version GLib du type */ - ret = PyArg_ParseTuple(args, "ks", &base, &name); +#define CLASS_ENUM_TYPE_DOC \ + "The ClassEnumType class handles types embedding other types, such as" \ + " classes, structures or enumerations.\n" \ + "\n" \ + "Instances can be created using the following constructor:\n" \ + "\n" \ + " ClassEnumType(kind, name=None)" \ + "\n" \ + "Where *kind* is one of the" \ + " pychrysalide.analysis.types.ClassEnumType.ClassEnumKind values," \ + " except *ClassEnumKind.COUNT*, and *name* is an optional string." + + name = NULL; + + ret = PyArg_ParseTuple(args, "O&|s", convert_to_class_enum_type_class_enum_kind, &kind, &name); if (!ret) return NULL; - if (base >= CET_COUNT) + if (kind >= CEK_COUNT) { - PyErr_SetString(PyExc_TypeError, _("Bad basic type.")); + PyErr_SetString(PyExc_TypeError, _("Bad class/enum kind.")); return NULL; } - dtype = g_class_enum_type_new(base, strdup(name)); + dtype = g_class_enum_type_new(kind, name != NULL ? strdup(name) : NULL); result = pygobject_new(G_OBJECT(dtype)); g_object_unref(dtype); @@ -105,17 +117,26 @@ static PyObject *py_class_enum_type_new(PyTypeObject *type, PyObject *args, PyOb * * ******************************************************************************/ -static PyObject *py_class_enum_type_get_base_type(PyObject *self, void *closure) +static PyObject *py_class_enum_type_get_kind(PyObject *self, void *closure) { PyObject *result; /* Résultat à retourner */ GClassEnumType *type; /* Version GLib du type */ - ClassEnumType base; /* Type de base à renvoyer */ + ClassEnumKind kind; /* Type de base à renvoyer */ + +#define CLASS_ENUM_TYPE_KIND_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + kind, py_class_enum_type, \ + "Provide the internal identifier for the kind of the type.\n" \ + "\n" \ + "This property provides a" \ + " pychrysalide.analysis.types.ClassEnumType.ClassEnumKind value." \ +) type = G_CLASS_ENUM_TYPE(pygobject_get(self)); - base = g_class_enum_type_get_base(type); + kind = g_class_enum_type_get_kind(type); - result = PyLong_FromUnsignedLong(base); + result = cast_with_constants_group_from_type(get_python_class_enum_type_type(), "ClassEnumKind", kind); return result; @@ -141,11 +162,25 @@ static PyObject *py_class_enum_type_get_name(PyObject *self, void *closure) GClassEnumType *type; /* Version GLib du type */ const char *name; /* Désignation humaine */ +#define CLASS_ENUM_TYPE_NAME_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + name, py_class_enum_type, \ + "Provide the name registered for the type.\n" \ + "\n" \ + "This property provides a string or None if no value is defined." \ +) + type = G_CLASS_ENUM_TYPE(pygobject_get(self)); name = g_class_enum_type_get_name(type); - result = PyUnicode_FromString(name); + if (name != NULL) + result = PyUnicode_FromString(name); + else + { + result = Py_None; + Py_INCREF(result); + } return result; @@ -171,14 +206,8 @@ PyTypeObject *get_python_class_enum_type_type(void) }; static PyGetSetDef py_class_enum_type_getseters[] = { - { - "base", py_class_enum_type_get_base_type, NULL, - "Provide the internal identifier of the type.", NULL - }, - { - "name", py_class_enum_type_get_name, NULL, - "Provide the name of the type.", NULL - }, + CLASS_ENUM_TYPE_KIND_ATTRIB, + CLASS_ENUM_TYPE_NAME_ATTRIB, { NULL } }; @@ -191,7 +220,7 @@ PyTypeObject *get_python_class_enum_type_type(void) .tp_flags = Py_TPFLAGS_DEFAULT, - .tp_doc = "PyChrysalide basic type", + .tp_doc = CLASS_ENUM_TYPE_DOC, .tp_methods = py_class_enum_type_methods, .tp_getset = py_class_enum_type_getseters, @@ -206,39 +235,6 @@ PyTypeObject *get_python_class_enum_type_type(void) /****************************************************************************** * * -* Paramètres : obj_type = type dont le dictionnaire est à compléter. * -* * -* Description : Définit les constantes pour les types de classe/énumération. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool py_class_enum_type_define_constants(PyTypeObject *obj_type) -{ - bool result; /* Bilan à retourner */ - - result = true; - - result &= PyDict_AddULongMacro(obj_type, CET_UNKNOWN); - result &= PyDict_AddULongMacro(obj_type, CET_STRUCT); - result &= PyDict_AddULongMacro(obj_type, CET_ENUM); - result &= PyDict_AddULongMacro(obj_type, CET_CLASS); - result &= PyDict_AddULongMacro(obj_type, CET_NAMESPACE); - result &= PyDict_AddULongMacro(obj_type, CET_VIRTUAL_TABLE); - result &= PyDict_AddULongMacro(obj_type, CET_VIRTUAL_STRUCT); - - result &= PyDict_AddULongMacro(obj_type, CET_COUNT); - - return result; - -} - - -/****************************************************************************** -* * * Paramètres : module = module dont la définition est à compléter. * * * * Description : Prend en charge l'objet 'pychrysalide.....ClassEnumType'. * @@ -269,7 +265,7 @@ bool ensure_python_class_enum_type_is_registered(void) if (!register_class_for_pygobject(dict, G_TYPE_CLASS_ENUM_TYPE, type, get_python_data_type_type())) return false; - if (!py_class_enum_type_define_constants(type)) + if (!define_class_enum_type_constants(type)) return false; } |