From 601b8149bf81231a09e2977dbdbfe8e8e568c1f4 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Wed, 14 Oct 2020 00:17:14 +0200 Subject: Defined proper Python bindings for class/enum types. --- plugins/dexbnf/shorty.c | 2 +- plugins/dexbnf/type.c | 4 +- plugins/itanium/abi.c | 12 +-- plugins/itanium/component.c | 16 ++-- plugins/javadesc/field.c | 4 +- plugins/pychrysalide/analysis/types/basic.c | 13 +-- plugins/pychrysalide/analysis/types/constants.c | 101 ++++++++++++++++++++++ plugins/pychrysalide/analysis/types/constants.h | 6 ++ plugins/pychrysalide/analysis/types/cse.c | 110 ++++++++++++------------ src/analysis/type.c | 3 + src/analysis/types/cse.c | 24 +++--- src/analysis/types/cse.h | 24 +++--- tests/analysis/types/basic.py | 4 +- tests/analysis/types/cse.py | 30 +++++++ 14 files changed, 245 insertions(+), 108 deletions(-) create mode 100644 tests/analysis/types/cse.py diff --git a/plugins/dexbnf/shorty.c b/plugins/dexbnf/shorty.c index 434aa3b..2dbd019 100644 --- a/plugins/dexbnf/shorty.c +++ b/plugins/dexbnf/shorty.c @@ -213,7 +213,7 @@ static GDataType *dsd_shorty_field_type(input_buffer *buffer, char ahead) break; case 'L': - result = g_class_enum_type_new(CET_CLASS, NULL); + result = g_class_enum_type_new(CEK_CLASS, NULL); break; default: diff --git a/plugins/dexbnf/type.c b/plugins/dexbnf/type.c index 5a0d82c..db838c1 100644 --- a/plugins/dexbnf/type.c +++ b/plugins/dexbnf/type.c @@ -88,7 +88,7 @@ static GDataType *dtd_full_class_name(input_buffer *buffer) } else - result = g_class_enum_type_new(CET_CLASS, name); + result = g_class_enum_type_new(CEK_CLASS, name); /* Eventuels autres étages précédents */ @@ -114,7 +114,7 @@ static GDataType *dtd_full_class_name(input_buffer *buffer) ns = result; - result = g_class_enum_type_new(CET_CLASS, name); + result = g_class_enum_type_new(CEK_CLASS, name); g_data_type_set_namespace(result, ns, strdup(".")); diff --git a/plugins/itanium/abi.c b/plugins/itanium/abi.c index 0304938..213d5f7 100644 --- a/plugins/itanium/abi.c +++ b/plugins/itanium/abi.c @@ -1926,7 +1926,7 @@ static itanium_component *itd_type(GItaniumDemangling *context) else { - builtin = g_class_enum_type_new(CET_UNKNOWN, itd_translate_component(vendor, NULL)); + builtin = g_class_enum_type_new(CEK_UNKNOWN, itd_translate_component(vendor, NULL)); result = itd_make_type(builtin); itd_set_type(result, ICT_VENDOR_TYPE); itd_unref_comp(vendor); @@ -2348,9 +2348,9 @@ static itanium_component *itd_builtin_type(GItaniumDemangling *context) case 'n': - std = g_class_enum_type_new(CET_NAMESPACE, strdup("std")); + std = g_class_enum_type_new(CEK_NAMESPACE, strdup("std")); - builtin = g_class_enum_type_new(CET_CLASS, strdup("nullptr_t")); + builtin = g_class_enum_type_new(CEK_CLASS, strdup("nullptr_t")); g_data_type_set_namespace(builtin, std, strdup("::")); result = itd_make_type(builtin); @@ -2377,7 +2377,7 @@ static itanium_component *itd_builtin_type(GItaniumDemangling *context) result = NULL; else { - builtin = g_class_enum_type_new(CET_UNKNOWN, itd_translate_component(vendor, NULL)); + builtin = g_class_enum_type_new(CEK_UNKNOWN, itd_translate_component(vendor, NULL)); result = itd_make_type(builtin); itd_unref_comp(vendor); } @@ -3480,14 +3480,14 @@ static itanium_component *itd_substitution(GItaniumDemangling *context) if (stdinfo->code == cur) { - std = g_class_enum_type_new(CET_NAMESPACE, strdup("std")); + std = g_class_enum_type_new(CEK_NAMESPACE, strdup("std")); if (stdinfo->class == NULL) type = std; else { - type = g_class_enum_type_new(CET_CLASS, strdup(stdinfo->class)); + type = g_class_enum_type_new(CEK_CLASS, strdup(stdinfo->class)); g_data_type_set_namespace(type, std, strdup("::")); } diff --git a/plugins/itanium/component.c b/plugins/itanium/component.c index f035e36..3791c4c 100644 --- a/plugins/itanium/component.c +++ b/plugins/itanium/component.c @@ -1415,14 +1415,14 @@ GDataType *itd_translate_component_to_type(const itanium_component *comp, Routin { case ICT_NAME: name = itd_translate_component(comp, NULL); - result = g_class_enum_type_new(CET_STRUCT, name); + result = g_class_enum_type_new(CEK_STRUCT, name); break; case ICT_STD_UNSCOPED_NAME: result = itd_translate_component_to_type(comp->unary, rtype); if (result != NULL) { - ns = g_class_enum_type_new(CET_NAMESPACE, strdup("std")); + ns = g_class_enum_type_new(CEK_NAMESPACE, strdup("std")); itd_prepend_namespace_to_type(result, ns); } break; @@ -1434,7 +1434,7 @@ GDataType *itd_translate_component_to_type(const itanium_component *comp, Routin name = itd_translate_component(comp->binary.left, NULL); name = itd_translate_component(comp->binary.right, name); - result = g_class_enum_type_new(CET_CLASS, name); + result = g_class_enum_type_new(CEK_CLASS, name); } @@ -1515,7 +1515,7 @@ GDataType *itd_translate_component_to_type(const itanium_component *comp, Routin name = itd_translate_component(comp->binary.left, NULL); name = itd_translate_component(comp->binary.right, name); - result = g_class_enum_type_new(CET_CLASS, name); + result = g_class_enum_type_new(CEK_CLASS, name); } @@ -1544,7 +1544,7 @@ GDataType *itd_translate_component_to_type(const itanium_component *comp, Routin name = itd_translate_component(comp->binary.left, NULL); name = itd_translate_component(comp->binary.right, name); - result = g_class_enum_type_new(CET_CLASS, name); + result = g_class_enum_type_new(CEK_CLASS, name); } @@ -1582,7 +1582,7 @@ GDataType *itd_translate_component_to_type(const itanium_component *comp, Routin case ICT_OPERATOR_NAME: name = itd_translate_component(comp, NULL); - result = g_class_enum_type_new(CET_STRUCT, name); + result = g_class_enum_type_new(CEK_STRUCT, name); break; case ICT_SPECIAL_NAME_VTABLE: @@ -1594,7 +1594,7 @@ GDataType *itd_translate_component_to_type(const itanium_component *comp, Routin else { - result = g_class_enum_type_new(CET_VIRTUAL_TABLE, NULL); + result = g_class_enum_type_new(CEK_VIRTUAL_TABLE, NULL); itd_prepend_namespace_to_type(result, ns); } @@ -1609,7 +1609,7 @@ GDataType *itd_translate_component_to_type(const itanium_component *comp, Routin else { - result = g_class_enum_type_new(CET_VIRTUAL_STRUCT, NULL); + result = g_class_enum_type_new(CEK_VIRTUAL_STRUCT, NULL); itd_prepend_namespace_to_type(result, ns); } diff --git a/plugins/javadesc/field.c b/plugins/javadesc/field.c index 95b0b8f..799d39d 100644 --- a/plugins/javadesc/field.c +++ b/plugins/javadesc/field.c @@ -91,7 +91,7 @@ static GDataType *jtd_object_type_descriptor(input_buffer *buffer) name[len - 1] = '\0'; - root = g_class_enum_type_new(CET_CLASS, name); + root = g_class_enum_type_new(CEK_CLASS, name); /** * Pour éviter les fuites si aucun paquet n'est présent... @@ -154,7 +154,7 @@ static GDataType *jtd_object_type_descriptor(input_buffer *buffer) while (1); if (name != NULL) - result = g_class_enum_type_new(CET_CLASS, name); + result = g_class_enum_type_new(CEK_CLASS, name); return result; 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 +#include #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 +#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; } diff --git a/src/analysis/type.c b/src/analysis/type.c index f19d846..9a8e85b 100644 --- a/src/analysis/type.c +++ b/src/analysis/type.c @@ -198,6 +198,9 @@ char *g_data_type_to_string(const GDataType *type, bool include) result = class->to_string(type, include); + if (result == NULL) + result = strdup(""); + if (include && type->namespace != NULL && g_data_type_handle_namespaces(type)) { namespace = g_data_type_to_string(type->namespace, true); diff --git a/src/analysis/types/cse.c b/src/analysis/types/cse.c index 54884af..9f9adcd 100644 --- a/src/analysis/types/cse.c +++ b/src/analysis/types/cse.c @@ -37,7 +37,7 @@ struct _GClassEnumType { GDataType parent; /* A laisser en premier */ - ClassEnumType type; /* Type représenté si connu */ + ClassEnumKind kind; /* Type représenté si connu */ char *name; /* Description humaine */ }; @@ -118,7 +118,7 @@ static void g_class_enum_type_class_init(GClassEnumTypeClass *klass) static void g_class_enum_type_init(GClassEnumType *type) { - type->type = CET_COUNT; + type->kind = CEK_COUNT; type->name = NULL; } @@ -167,7 +167,7 @@ static void g_class_enum_type_finalize(GClassEnumType *type) /****************************************************************************** * * -* Paramètres : type = type de structure à représenter. * +* Paramètres : kind = type de structure à représenter. * * name = désignation humaine du type. * * * * Description : Crée une représentation de classe, structure ou énumération. * @@ -178,13 +178,13 @@ static void g_class_enum_type_finalize(GClassEnumType *type) * * ******************************************************************************/ -GDataType *g_class_enum_type_new(ClassEnumType type, char *name) +GDataType *g_class_enum_type_new(ClassEnumKind kind, char *name) { GClassEnumType *result; /* Structure à retourner */ result = g_object_new(G_TYPE_CLASS_ENUM_TYPE, NULL); - result->type = type; + result->kind = kind; result->name = name; return G_DATA_TYPE(result); @@ -211,7 +211,7 @@ static GDataType *g_class_enum_type_dup(const GClassEnumType *type) name = (type->name != NULL ? strdup(type->name) : NULL); - result = g_class_enum_type_new(type->type, name); + result = g_class_enum_type_new(type->kind, name); return result; @@ -235,13 +235,13 @@ static char *g_class_enum_type_to_string(const GClassEnumType *type, bool includ { char *result; /* Valeur à renvoyer */ - switch (type->type) + switch (type->kind) { - case CET_VIRTUAL_TABLE: + case CEK_VIRTUAL_TABLE: result = strdup("vtable"); break; - case CET_VIRTUAL_STRUCT: + case CEK_VIRTUAL_STRUCT: result = strdup("vstruct"); break; @@ -268,11 +268,11 @@ static char *g_class_enum_type_to_string(const GClassEnumType *type, bool includ * * ******************************************************************************/ -ClassEnumType g_class_enum_type_get_base(const GClassEnumType *type) +ClassEnumKind g_class_enum_type_get_kind(const GClassEnumType *type) { - ClassEnumType result; /* Type de base à renvoyer */ + ClassEnumKind result; /* Type de base à renvoyer */ - result = type->type; + result = type->kind; return result; diff --git a/src/analysis/types/cse.h b/src/analysis/types/cse.h index ad0bc58..5831928 100644 --- a/src/analysis/types/cse.h +++ b/src/analysis/types/cse.h @@ -48,29 +48,29 @@ typedef struct _GClassEnumTypeClass GClassEnumTypeClass; /* Type pris en compte */ -typedef enum _ClassEnumType +typedef enum _ClassEnumKind { - CET_UNKNOWN, /* Statut inconnu */ - CET_STRUCT, /* Structure */ - CET_ENUM, /* Enumération */ - CET_CLASS, /* Classe */ - CET_NAMESPACE, /* Espace de nom */ - CET_VIRTUAL_TABLE, /* Table virtuelle */ - CET_VIRTUAL_STRUCT, /* Indice de construction VT */ + CEK_UNKNOWN, /* Statut inconnu */ + CEK_STRUCT, /* Structure */ + CEK_ENUM, /* Enumération */ + CEK_CLASS, /* Classe */ + CEK_NAMESPACE, /* Espace de nom */ + CEK_VIRTUAL_TABLE, /* Table virtuelle */ + CEK_VIRTUAL_STRUCT, /* Indice de construction VT */ - CET_COUNT + CEK_COUNT -} ClassEnumType; +} ClassEnumKind; /* Indique le type défini pour un type classe ou assimilé. */ GType g_class_enum_type_get_type(void); /* Crée une représentation de classe, structure ou énumération. */ -GDataType *g_class_enum_type_new(ClassEnumType, char *); +GDataType *g_class_enum_type_new(ClassEnumKind, char *); /* Fournit le type pris en compte géré par le type. */ -ClassEnumType g_class_enum_type_get_base(const GClassEnumType *); +ClassEnumKind g_class_enum_type_get_kind(const GClassEnumType *); /* Donne la désignation de la classe / structure / énumération. */ const char *g_class_enum_type_get_name(const GClassEnumType *); diff --git a/tests/analysis/types/basic.py b/tests/analysis/types/basic.py index 7b7403b..65700bd 100644 --- a/tests/analysis/types/basic.py +++ b/tests/analysis/types/basic.py @@ -6,8 +6,8 @@ from chrysacase import ChrysalideTestCase from pychrysalide.analysis.types import BasicType -class TestDataType(ChrysalideTestCase): - """TestCase for analysis.DataType.""" +class TestBasicType(ChrysalideTestCase): + """TestCase for analysis.BasicType.""" def testBasicTypeConstructor(self): diff --git a/tests/analysis/types/cse.py b/tests/analysis/types/cse.py new file mode 100644 index 0000000..9b6b016 --- /dev/null +++ b/tests/analysis/types/cse.py @@ -0,0 +1,30 @@ +#!/usr/bin/python3-dbg +# -*- coding: utf-8 -*- + + +from chrysacase import ChrysalideTestCase +from pychrysalide.analysis.types import ClassEnumType + + +class TestClassEnumType(ChrysalideTestCase): + """TestCase for analysis.ClassEnumType.""" + + + def testClassEnumTypeConstructor(self): + """Build some class/enum types.""" + + tp = ClassEnumType(ClassEnumType.ClassEnumKind.STRUCT) + + self.assertEqual(str(tp), '') + + tp = ClassEnumType(ClassEnumType.ClassEnumKind.STRUCT, 'XXX') + + self.assertEqual(str(tp), 'XXX') + + with self.assertRaisesRegex(TypeError, 'Bad class/enum kind.'): + + tp = ClassEnumType(ClassEnumType.ClassEnumKind.COUNT) + + with self.assertRaisesRegex(TypeError, 'invalid value for ClassEnumKind'): + + tp = ClassEnumType(0x1234) -- cgit v0.11.2-87-g4458