summaryrefslogtreecommitdiff
path: root/plugins/pychrysalide/analysis
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2020-10-13 22:17:14 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2020-10-13 22:21:21 (GMT)
commit601b8149bf81231a09e2977dbdbfe8e8e568c1f4 (patch)
tree9cf7c0e3b6398b4ad24880b3dcd26ef9b013a7fe /plugins/pychrysalide/analysis
parent362ff8ddd7fac8a10c7cccae303d2ce5ea6dd7f2 (diff)
Defined proper Python bindings for class/enum types.
Diffstat (limited to 'plugins/pychrysalide/analysis')
-rw-r--r--plugins/pychrysalide/analysis/types/basic.c13
-rw-r--r--plugins/pychrysalide/analysis/types/constants.c101
-rw-r--r--plugins/pychrysalide/analysis/types/constants.h6
-rw-r--r--plugins/pychrysalide/analysis/types/cse.c110
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;
}