summaryrefslogtreecommitdiff
path: root/plugins/pychrysalide
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2020-10-10 12:01:40 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2020-10-10 12:01:40 (GMT)
commit0b0f69bd1278b8f5d95c6ea8fb56915148992a77 (patch)
tree0d9ab819a636c6d7bf61e09856283efd1562353a /plugins/pychrysalide
parent1af362266f616aed07e2661c9676c67dc3365740 (diff)
Updated the basic types definition and its Python bindings.
Diffstat (limited to 'plugins/pychrysalide')
-rw-r--r--plugins/pychrysalide/analysis/constants.c98
-rw-r--r--plugins/pychrysalide/analysis/constants.h6
-rw-r--r--plugins/pychrysalide/analysis/type.c707
-rw-r--r--plugins/pychrysalide/analysis/type.h3
-rw-r--r--plugins/pychrysalide/helpers.c50
-rw-r--r--plugins/pychrysalide/helpers.h22
6 files changed, 816 insertions, 70 deletions
diff --git a/plugins/pychrysalide/analysis/constants.c b/plugins/pychrysalide/analysis/constants.c
index dc507dc..8d68edc 100644
--- a/plugins/pychrysalide/analysis/constants.c
+++ b/plugins/pychrysalide/analysis/constants.c
@@ -25,6 +25,7 @@
#include "constants.h"
+#include <analysis/type.h>
#include <common/endianness.h>
@@ -212,3 +213,100 @@ int convert_to_memory_data_size(PyObject *arg, void *dst)
return result;
}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type dont le dictionnaire est à compléter. *
+* *
+* Description : Définit les constantes pour les types de données. *
+* *
+* Retour : true en cas de succès de l'opération, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool define_analysis_data_type_constants(PyTypeObject *type)
+{
+ bool result; /* Bilan à retourner */
+ PyObject *values; /* Groupe de valeurs à établir */
+
+ values = PyDict_New();
+
+ result = add_const_to_group(values, "NONE", TQF_NONE);
+ if (result) result = add_const_to_group(values, "RESTRICT", TQF_RESTRICT);
+ if (result) result = add_const_to_group(values, "VOLATILE", TQF_VOLATILE);
+ if (result) result = add_const_to_group(values, "CONST", TQF_CONST);
+ if (result) result = add_const_to_group(values, "ALL", TQF_ALL);
+
+ if (!result)
+ {
+ Py_DECREF(values);
+ goto exit;
+ }
+
+ result = attach_constants_group_to_type(type, false, "TypeQualifier", values,
+ "Qualifier for a data type.");
+
+ 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 TypeQualifier. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_to_data_type_qualifier(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 TypeQualifier");
+ break;
+
+ case 1:
+ value = PyLong_AsUnsignedLong(arg);
+
+ if ((value & ~TQF_ALL) != 0)
+ {
+ PyErr_SetString(PyExc_TypeError, "invalid value for TypeQualifier");
+ result = 0;
+ }
+
+ else
+ *((TypeQualifier *)dst) = value;
+
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ return result;
+
+}
diff --git a/plugins/pychrysalide/analysis/constants.h b/plugins/pychrysalide/analysis/constants.h
index 45982bb..fb96e99 100644
--- a/plugins/pychrysalide/analysis/constants.h
+++ b/plugins/pychrysalide/analysis/constants.h
@@ -39,6 +39,12 @@ int convert_to_source_endian(PyObject *, void *);
/* Tente de convertir en constante MemoryDataSize. */
int convert_to_memory_data_size(PyObject *, void *);
+/* Définit les constantes pour les types de données. */
+bool define_analysis_data_type_constants(PyTypeObject *);
+
+/* Tente de convertir en constante TypeQualifier. */
+int convert_to_data_type_qualifier(PyObject *, void *);
+
#endif /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_CONSTANTS_H */
diff --git a/plugins/pychrysalide/analysis/type.c b/plugins/pychrysalide/analysis/type.c
index 6043042..cd849e4 100644
--- a/plugins/pychrysalide/analysis/type.c
+++ b/plugins/pychrysalide/analysis/type.c
@@ -33,17 +33,54 @@
#include <i18n.h>
-#include <analysis/type.h>
+#include <analysis/type-int.h>
+#include <plugins/dt.h>
+#include "constants.h"
#include "../access.h"
#include "../helpers.h"
+/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
+
+
+/* Accompagne la création d'une instance dérivée en Python. */
+static PyObject *py_data_type_new(PyTypeObject *, PyObject *, PyObject *);
+
+/* Initialise la classe des types quelconques. */
+static void py_data_type_init_gclass(GDataTypeClass *, gpointer);
+
+/* Crée un copie d'un type existant. */
+static GDataType *py_data_type_dup_wrapper(const GDataType *);
+
+/* Décrit le type fourni sous forme de caractères. */
+static char *py_data_type_to_string_wrapper(const GDataType *, bool);
+
+/* Indique si le type assure une gestion des espaces de noms. */
+static bool py_data_type_handle_namespaces_wrapper(const GDataType *);
+
+/* Indique si le type est un pointeur. */
+static bool py_data_type_is_pointer_wrapper(const GDataType *);
+
+/* Indique si le type est une référence. */
+static bool py_data_type_is_reference_wrapper(const GDataType *);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_data_type_init(PyObject *, PyObject *, PyObject *);
+
+
+
+/* ----------------- FONCTIONNALITES BASIQUES POUR TYPES DE DONNEES ----------------- */
+
+
/* Décrit le type fourni sous forme de caractères. */
static PyObject *py_data_type_to_str(PyObject *);
+/* Crée un copie d'un type existant. */
+static PyObject *py_data_type_dup(PyObject *, PyObject *);
+
/* Fournit le groupe d'appartenance d'un type donné. */
static PyObject *py_data_type_get_namespace(PyObject *, void *);
@@ -56,16 +93,432 @@ static PyObject *py_data_type_get_qualifiers(PyObject *, void *);
/* Définit l'ensemble des qualificatifs d'une instance de type. */
static int py_data_type_set_qualifiers(PyObject *, PyObject *, void *);
+/* Indique si le type assure une gestion des espaces de noms. */
+static PyObject *py_data_type_handle_namespaces(PyObject *, void *);
+
/* Indique si le type est un pointeur. */
static PyObject *py_data_type_is_pointer(PyObject *, void *);
/* Indique si le type est une référence. */
static PyObject *py_data_type_is_reference(PyObject *, void *);
-/* Définit les constantes pour les types de données. */
-static bool py_data_type_define_constants(PyTypeObject *);
+/* ---------------------------------------------------------------------------------- */
+/* GLUE POUR CREATION DEPUIS PYTHON */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type du nouvel objet à mettre en place. *
+* args = éventuelle liste d'arguments. *
+* kwds = éventuel dictionnaire de valeurs mises à disposition. *
+* *
+* Description : Accompagne la création d'une instance dérivée en Python. *
+* *
+* Retour : Nouvel objet Python mis en place ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_data_type_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *result; /* Objet à retourner */
+ PyTypeObject *base; /* Type de base à dériver */
+ bool first_time; /* Evite les multiples passages*/
+ GType gtype; /* Nouveau type de processeur */
+ bool status; /* Bilan d'un enregistrement */
+
+ /* Validations diverses */
+
+ base = get_python_data_type_type();
+
+ if (type == base)
+ {
+ result = NULL;
+ PyErr_Format(PyExc_RuntimeError, _("%s is an abstract class"), type->tp_name);
+ goto exit;
+ }
+
+ /* Mise en place d'un type dédié */
+
+ first_time = (g_type_from_name(type->tp_name) == 0);
+
+ gtype = build_dynamic_type(G_TYPE_DATA_TYPE, type->tp_name,
+ (GClassInitFunc)py_data_type_init_gclass, NULL, NULL);
+
+ if (first_time)
+ {
+ status = register_class_for_dynamic_pygobject(gtype, type, base);
+
+ if (!status)
+ {
+ result = NULL;
+ goto exit;
+ }
+
+ }
+
+ /* On crée, et on laisse ensuite la main à PyGObject_Type.tp_init() */
+
+ result = PyType_GenericNew(type, args, kwds);
+
+ exit:
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : class = classe à initialiser. *
+* unused = données non utilisées ici. *
+* *
+* Description : Initialise la classe des types quelconques. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void py_data_type_init_gclass(GDataTypeClass *class, gpointer unused)
+{
+ class->dup = py_data_type_dup_wrapper;
+ class->to_string = py_data_type_to_string_wrapper;
+
+ class->handle_ns = py_data_type_handle_namespaces_wrapper;
+ class->is_pointer = py_data_type_is_pointer_wrapper;
+ class->is_reference = py_data_type_is_reference_wrapper;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type à dupliquer. *
+* *
+* Description : Crée un copie d'un type existant. *
+* *
+* Retour : Nouvelle instance de type identique à celle fournie. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GDataType *py_data_type_dup_wrapper(const GDataType *type)
+{
+ GDataType *result; /* Copie à retourner */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pyret; /* Bilan de consultation */
+
+#define DATA_TYPE_DUP_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _dup, "$self, /", \
+ METH_NOARGS, \
+ "Abstract method used to create a copy of a data type.\n" \
+ "\n" \
+ "The returned value has to be a new instance of the" \
+ " pychrysalide.analysis.DataType class." \
+)
+
+ result = NULL;
+
+ pyobj = pygobject_new(G_OBJECT(type));
+
+ if (has_python_method(pyobj, "_dup"))
+ {
+ pyret = run_python_method(pyobj, "_dup", NULL);
+
+ if (pyret != NULL)
+ {
+ if (PyObject_TypeCheck(pyret, get_python_data_type_type()))
+ {
+ result = G_DATA_TYPE(pygobject_get(pyret));
+ g_object_ref(G_OBJECT(result));
+ }
+ }
+
+ Py_XDECREF(pyret);
+
+ }
+
+ Py_DECREF(pyobj);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type à convertir. *
+* include = doit-on inclure les espaces de noms ? *
+* *
+* Description : Décrit le type fourni sous forme de caractères. *
+* *
+* Retour : Chaîne à libérer de la mémoire après usage. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static char *py_data_type_to_string_wrapper(const GDataType *type, bool include)
+{
+ char *result; /* Etiquette à retourner */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *arg; /* Version Python de l'argument*/
+ PyObject *args; /* Arguments pour l'appel */
+ PyObject *pyret; /* Bilan de consultation */
+
+#define DATA_TYPE_TO_STRING_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _to_string, "$self, include, /", \
+ METH_VARARGS, \
+ "Abstract method used to provide the string represention of" \
+ " a data type.\n" \
+ "\n" \
+ "The *include* argument defines if the type namespace has to" \
+ " get prepended, if it exists.\n" \
+ "\n" \
+ "The returned value has to be a string." \
+)
+
+ result = NULL;
+
+ pyobj = pygobject_new(G_OBJECT(type));
+
+ if (has_python_method(pyobj, "_to_string"))
+ {
+ arg = include ? Py_True : Py_False;
+ Py_INCREF(arg);
+
+ args = PyTuple_New(1);
+ PyTuple_SetItem(args, 0, arg);
+
+ pyret = run_python_method(pyobj, "_to_string", args);
+
+ if (pyret != NULL)
+ {
+ if (PyUnicode_Check(pyret))
+ result = strdup(PyUnicode_DATA(pyret));
+ }
+
+ Py_XDECREF(pyret);
+
+ Py_DECREF(args);
+
+ }
+
+ Py_DECREF(pyobj);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type à consulter. *
+* *
+* Description : Indique si le type assure une gestion des espaces de noms. *
+* *
+* Retour : Bilan de la consultation. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool py_data_type_handle_namespaces_wrapper(const GDataType *type)
+{
+ bool result; /* Bilan à retourner */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pyret; /* Bilan de consultation */
+
+#define DATA_TYPE_HANDLE_NAMESPACES_WRAPPER PYTHON_TRUE_WRAPPER_DEF \
+( \
+ _handle_namespaces, "$self, /", \
+ METH_NOARGS, \
+ "Abstract method used to state if the type handles namespaces" \
+ " or not.\n" \
+ "\n" \
+ "The return is a boolean value. If this method does not" \
+ " exist, the True value is assumed." \
+)
+
+ result = true;
+
+ pyobj = pygobject_new(G_OBJECT(type));
+
+ if (has_python_method(pyobj, "_handle_namespaces"))
+ {
+ pyret = run_python_method(pyobj, "_handle_namespaces", NULL);
+
+ result = (pyret == Py_True);
+
+ Py_XDECREF(pyret);
+
+ }
+
+ Py_DECREF(pyobj);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type à consulter. *
+* *
+* Description : Indique si le type est un pointeur. *
+* *
+* Retour : Bilan de la consultation. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool py_data_type_is_pointer_wrapper(const GDataType *type)
+{
+ bool result; /* Bilan à retourner */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pyret; /* Bilan de consultation */
+
+#define DATA_TYPE_IS_POINTER_WRAPPER PYTHON_FALSE_WRAPPER_DEF \
+( \
+ _is_pointer, "$self, /", \
+ METH_NOARGS, \
+ "Abstract method used to state if the type points to" \
+ " another type or not.\n" \
+ "\n" \
+ "The return is a boolean value. If this method does not" \
+ " exist, the False value is assumed." \
+)
+
+ result = false;
+
+ pyobj = pygobject_new(G_OBJECT(type));
+
+ if (has_python_method(pyobj, "_is_pointer"))
+ {
+ pyret = run_python_method(pyobj, "_is_pointer", NULL);
+
+ result = (pyret == Py_True);
+
+ Py_XDECREF(pyret);
+
+ }
+
+ Py_DECREF(pyobj);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type à consulter. *
+* *
+* Description : Indique si le type est une référence. *
+* *
+* Retour : Bilan de la consultation. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool py_data_type_is_reference_wrapper(const GDataType *type)
+{
+ bool result; /* Bilan à retourner */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pyret; /* Bilan de consultation */
+
+#define DATA_TYPE_IS_REFERENCE_WRAPPER PYTHON_FALSE_WRAPPER_DEF \
+( \
+ _is_reference, "$self, /", \
+ METH_NOARGS, \
+ "Abstract method used to state if the type refers to" \
+ " another type or not.\n" \
+ "\n" \
+ "The return is a boolean value. If this method does not" \
+ " exist, the False value is assumed." \
+)
+
+ result = false;
+
+ pyobj = pygobject_new(G_OBJECT(type));
+
+ if (has_python_method(pyobj, "_is_reference"))
+ {
+ pyret = run_python_method(pyobj, "_is_reference", NULL);
+
+ result = (pyret == Py_True);
+
+ Py_XDECREF(pyret);
+
+ }
+
+ Py_DECREF(pyobj);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet à initialiser (théoriquement). *
+* args = arguments fournis à l'appel. *
+* kwds = arguments de type key=val fournis. *
+* *
+* Description : Initialise une instance sur la base du dérivé de GObject. *
+* *
+* Retour : 0. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static int py_data_type_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ int ret; /* Bilan de lecture des args. */
+
+#define DATA_TYPE_DOC \
+ "The DataType object is the base class for all data types.\n" \
+ "\n" \
+ "Instances can be created using the following constructor:\n" \
+ "\n" \
+ " DataType()" \
+ "\n" \
+ "The following methods have to be defined for new classes:\n" \
+ "* pychrysalide.analysis.DataType._dup();\n" \
+ "* pychrysalide.analysis.DataType._to_string()." \
+ "\n" \
+ "Some extra method definitions are optional for new classes:\n" \
+ "* pychrysalide.analysis.DataType._handle_namespaces();\n" \
+ "* pychrysalide.analysis.DataType._is_pointer();\n" \
+ "* pychrysalide.analysis.DataType._is_reference();" \
+
+ /* Initialisation d'un objet GLib */
+
+ ret = forward_pygobjet_init(self);
+ if (ret == -1) return -1;
+
+ return 0;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* FONCTIONNALITES BASIQUES POUR TYPES DE DONNEES */
+/* ---------------------------------------------------------------------------------- */
+
/******************************************************************************
* *
@@ -100,6 +553,56 @@ static PyObject *py_data_type_to_str(PyObject *self)
/******************************************************************************
* *
+* Paramètres : self = serveur à manipuler. *
+* args = arguments d'appel non utilisés ici. *
+* *
+* Description : Crée un copie d'un type existant. *
+* *
+* Retour : Nouvelle instance de type identique à celle fournie. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_data_type_dup(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Bilan à retourner */
+ GDataType *type; /* Version native de l'objet */
+ GDataType *copy; /* Copie du type obtenue */
+
+#define DATA_TYPE_DUP_METHOD PYTHON_METHOD_DEF \
+( \
+ dup, "$self, /", \
+ METH_NOARGS, py_data_type, \
+ "Create a copy of a data type.\n" \
+ "\n" \
+ "The returned value has to be a new instance of the" \
+ " pychrysalide.analysis.DataType class." \
+)
+
+ type = G_DATA_TYPE(pygobject_get(self));
+
+ copy = g_data_type_dup(type);
+
+ if (copy != NULL)
+ {
+ result = pygobject_new(G_OBJECT(copy));
+ g_object_unref(G_OBJECT(copy));
+ }
+
+ else
+ {
+ result = Py_None;
+ Py_INCREF(result);
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : self = objet Python concerné par l'appel. *
* closure = non utilisé ici. *
* *
@@ -116,14 +619,33 @@ static PyObject *py_data_type_get_namespace(PyObject *self, void *closure)
PyObject *result; /* Valeur à retourner */
GDataType *type; /* Elément à consulter */
GDataType *ns; /* Espace de noms */
+ const char *sep; /* Séparateur d'espace */
+
+#define DATA_TYPE_NAMESPACE_ATTRIB PYTHON_GETSET_DEF_FULL \
+( \
+ namespace, py_data_type, \
+ "Namespace for the type, None if any.\n" \
+ "\n" \
+ "This property carries a tuple of two values:\n" \
+ "* a namespace, as a pychrysalide.analysis.DataType.TypeQualifier" \
+ " instance;\n" \
+ "* a namespace separator, as a string." \
+)
type = G_DATA_TYPE(pygobject_get(self));
+
ns = g_data_type_get_namespace(type);
+ sep = g_data_type_get_namespace_separator(type);
- if (ns != NULL)
+ if (ns != NULL && sep != NULL)
{
- result = pygobject_new(G_OBJECT(ns));
+ result = PyTuple_New(2);
+
+ PyTuple_SetItem(result, 0, pygobject_new(G_OBJECT(ns)));
g_object_unref(G_OBJECT(ns));
+
+ PyTuple_SetItem(result, 1, PyUnicode_FromString(sep));
+
}
else
@@ -184,7 +706,7 @@ static int py_data_type_set_namespace(PyObject *self, PyObject *value, void *clo
}
ns = G_DATA_TYPE(pygobject_get(PyTuple_GetItem(value, 0)));
- sep = strdup(PyUnicode_DATA(pygobject_get(PyTuple_GetItem(value, 1))));
+ sep = strdup(PyUnicode_DATA(PyTuple_GetItem(value, 1)));
g_object_ref(G_OBJECT(ns));
g_data_type_set_namespace(type, ns, sep);
@@ -215,10 +737,18 @@ static PyObject *py_data_type_get_qualifiers(PyObject *self, void *closure)
GDataType *type; /* Elément à consulter */
TypeQualifier qualifiers; /* Qualificatifs en place */
+#define DATA_TYPE_QUALIFIERS_ATTRIB PYTHON_GETSET_DEF_FULL \
+( \
+ qualifiers, py_data_type, \
+ "Qualifier for the data type, *TypeQualifier.NONE* if any.\n" \
+ "\n" \
+ "This property carries a pychrysalide.analysis.DataType.TypeQualifier value." \
+)
+
type = G_DATA_TYPE(pygobject_get(self));
qualifiers = g_data_type_get_qualifiers(type);
- result = PyLong_FromUnsignedLong(qualifiers);
+ result = cast_with_constants_group_from_type(get_python_data_type_type(), "TypeQualifier", qualifiers);
return result;
@@ -242,21 +772,11 @@ static PyObject *py_data_type_get_qualifiers(PyObject *self, void *closure)
static int py_data_type_set_qualifiers(PyObject *self, PyObject *value, void *closure)
{
GDataType *type; /* Elément à traiter */
- unsigned long qualifiers; /* Qualificatifs à intégrer */
-
- if (!PyLong_Check(value))
- {
- PyErr_SetString(PyExc_TypeError, _("The attribute value must be a integer mask."));
- return -1;
- }
-
- qualifiers = PyLong_AsUnsignedLong(value);
+ TypeQualifier qualifiers; /* Qualificatifs à intégrer */
+ int ret; /* Bilan d'une conversion */
- if (qualifiers > TQF_ALL)
- {
- PyErr_SetString(PyExc_TypeError, _("Invalid value for type qualifiers."));
- return -1;
- }
+ ret = convert_to_data_type_qualifier(value, &qualifiers);
+ if (ret != 1) return -1;
type = G_DATA_TYPE(pygobject_get(self));
@@ -272,6 +792,43 @@ static int py_data_type_set_qualifiers(PyObject *self, PyObject *value, void *cl
* Paramètres : self = objet Python concerné par l'appel. *
* closure = non utilisé ici. *
* *
+* Description : Indique si le type assure une gestion des espaces de noms. *
+* *
+* Retour : Bilan de la consultation. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_data_type_handle_namespaces(PyObject *self, void *closure)
+{
+ PyObject *result; /* Valeur à retourner */
+ GDataType *type; /* Elément à consulter */
+ bool status; /* Etat à faire suivre */
+
+#define DATA_TYPE_NAMESPACES_ATTRIB PYTHON_RAWGET_DEF_FULL \
+( \
+ handle_namespaces, py_data_type, \
+ "True if the type handles namespaces, False otherwise." \
+)
+
+ type = G_DATA_TYPE(pygobject_get(self));
+
+ status = g_data_type_handle_namespaces(type);
+
+ result = status ? Py_True : Py_False;
+ Py_INCREF(result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
* Description : Indique si le type est un pointeur. *
* *
* Retour : Bilan de la consultation. *
@@ -286,6 +843,12 @@ static PyObject *py_data_type_is_pointer(PyObject *self, void *closure)
GDataType *type; /* Elément à consulter */
bool status; /* Etat à faire suivre */
+#define DATA_TYPE_POINTER_ATTRIB PYTHON_IS_DEF_FULL \
+( \
+ pointer, py_data_type, \
+ "True if the type is a pointer, False otherwise." \
+)
+
type = G_DATA_TYPE(pygobject_get(self));
status = g_data_type_is_pointer(type);
@@ -317,6 +880,12 @@ static PyObject *py_data_type_is_reference(PyObject *self, void *closure)
GDataType *type; /* Elément à consulter */
bool status; /* Etat à faire suivre */
+#define DATA_TYPE_REFERENCE_ATTRIB PYTHON_IS_DEF_FULL \
+( \
+ reference, py_data_type, \
+ "True if the type is a reference, False otherwise." \
+)
+
type = G_DATA_TYPE(pygobject_get(self));
status = g_data_type_is_reference(type);
@@ -344,26 +913,20 @@ static PyObject *py_data_type_is_reference(PyObject *self, void *closure)
PyTypeObject *get_python_data_type_type(void)
{
static PyMethodDef py_data_type_methods[] = {
+ DATA_TYPE_DUP_WRAPPER,
+ DATA_TYPE_TO_STRING_WRAPPER,
+ DATA_TYPE_HANDLE_NAMESPACES_WRAPPER,
+ DATA_TYPE_IS_POINTER_WRAPPER,
+ DATA_TYPE_DUP_METHOD,
{ NULL }
};
static PyGetSetDef py_data_type_getseters[] = {
- {
- "namespace", py_data_type_get_namespace, py_data_type_set_namespace,
- "Namespace for the type, None if any.", NULL
- },
- {
- "qualifiers", py_data_type_get_qualifiers, py_data_type_set_qualifiers,
- "Qualifiers linked to the type, TQF_NONE if any.", NULL
- },
- {
- "is_pointer", py_data_type_is_pointer, NULL,
- "True if the type is a pointer.", NULL
- },
- {
- "is_reference", py_data_type_is_reference, NULL,
- "True if the type is a reference.", NULL
- },
+ DATA_TYPE_NAMESPACE_ATTRIB,
+ DATA_TYPE_QUALIFIERS_ATTRIB,
+ DATA_TYPE_NAMESPACES_ATTRIB,
+ DATA_TYPE_POINTER_ATTRIB,
+ DATA_TYPE_REFERENCE_ATTRIB,
{ NULL }
};
@@ -377,10 +940,13 @@ PyTypeObject *get_python_data_type_type(void)
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
- .tp_doc = "PyChrysalide data type",
+ .tp_doc = DATA_TYPE_DOC,
.tp_methods = py_data_type_methods,
- .tp_getset = py_data_type_getseters
+ .tp_getset = py_data_type_getseters,
+
+ .tp_init = py_data_type_init,
+ .tp_new = py_data_type_new
};
@@ -391,36 +957,6 @@ PyTypeObject *get_python_data_type_type(void)
/******************************************************************************
* *
-* Paramètres : obj_type = type dont le dictionnaire est à compléter. *
-* *
-* Description : Définit les constantes pour les types de données. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static bool py_data_type_define_constants(PyTypeObject *obj_type)
-{
- bool result; /* Bilan à retourner */
-
- result = true;
-
- result &= PyDict_AddULongMacro(obj_type, TQF_NONE);
- result &= PyDict_AddULongMacro(obj_type, TQF_RESTRICT);
- result &= PyDict_AddULongMacro(obj_type, TQF_VOLATILE);
- result &= PyDict_AddULongMacro(obj_type, TQF_CONST);
-
- result &= PyDict_AddULongMacro(obj_type, TQF_ALL);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
* Paramètres : - *
* *
* Description : Prend en charge l'objet 'pychrysalide.analysis.DataType'. *
@@ -448,7 +984,7 @@ bool ensure_python_data_type_is_registered(void)
if (!register_class_for_pygobject(dict, G_TYPE_DATA_TYPE, type, &PyGObject_Type))
return false;
- if (!py_data_type_define_constants(type))
+ if (!define_analysis_data_type_constants(type))
return false;
}
@@ -501,3 +1037,34 @@ int convert_to_data_type(PyObject *arg, void *dst)
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 type de donnée ou NULL. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_to_data_type_or_none(PyObject *arg, void *dst)
+{
+ int result; /* Bilan à retourner */
+
+ if (arg == Py_None)
+ {
+ *((GDataType **)dst) = NULL;
+ result = 1;
+ }
+
+ else
+ result = convert_to_data_type(arg, dst);
+
+ return result;
+
+}
diff --git a/plugins/pychrysalide/analysis/type.h b/plugins/pychrysalide/analysis/type.h
index 8ea1096..9997a83 100644
--- a/plugins/pychrysalide/analysis/type.h
+++ b/plugins/pychrysalide/analysis/type.h
@@ -40,6 +40,9 @@ bool ensure_python_data_type_is_registered(void);
/* Tente de convertir en type de donnée. */
int convert_to_data_type(PyObject *, void *);
+/* Tente de convertir en type de donnée ou NULL. */
+int convert_to_data_type_or_none(PyObject *, void *);
+
#endif /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_TYPE_H */
diff --git a/plugins/pychrysalide/helpers.c b/plugins/pychrysalide/helpers.c
index 25ce772..870035d 100644
--- a/plugins/pychrysalide/helpers.c
+++ b/plugins/pychrysalide/helpers.c
@@ -648,6 +648,56 @@ PyObject *py_return_none(PyObject *self, PyObject *args)
/******************************************************************************
* *
+* Paramètres : self = objet quelconque. *
+* args = arguments fournis à l'appel. *
+* *
+* Description : Retourne toujours faux. *
+* *
+* Retour : False. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+PyObject *py_return_false(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Bilan à retourner */
+
+ result = Py_False;
+ Py_INCREF(result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet quelconque. *
+* args = arguments fournis à l'appel. *
+* *
+* Description : Retourne toujours vrai. *
+* *
+* Retour : False. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+PyObject *py_return_true(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Bilan à retourner */
+
+ result = Py_True;
+ Py_INCREF(result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : self = objet quelconque dont le code Python hérite. *
* closure = non utilisé ici. *
* *
diff --git a/plugins/pychrysalide/helpers.h b/plugins/pychrysalide/helpers.h
index f5b5781..45b3083 100644
--- a/plugins/pychrysalide/helpers.h
+++ b/plugins/pychrysalide/helpers.h
@@ -104,6 +104,19 @@ bool register_python_module_object(PyObject *, PyTypeObject *);
#name "(" args ")\n--\n\n" doc \
}
+#define PYTHON_FALSE_WRAPPER_DEF(name, args, flags, doc)\
+ { \
+ #name, (PyCFunction)py_return_false, \
+ flags, \
+ #name "(" args ")\n--\n\n" doc \
+ }
+
+#define PYTHON_TRUE_WRAPPER_DEF(name, args, flags, doc)\
+ { \
+ #name, (PyCFunction)py_return_true, \
+ flags, \
+ #name "(" args ")\n--\n\n" doc \
+ }
#define PYTHON_GETSET_DEF(name, get, set, doc, closure) \
{ \
@@ -118,6 +131,9 @@ bool register_python_module_object(PyObject *, PyTypeObject *);
#define PYTHON_HAS_DEF_FULL(name, base, doc) \
PYTHON_GETSET_DEF(#name, base ## _has_ ## name, NULL, doc, NULL)
+#define PYTHON_RAWGET_DEF_FULL(name, base, doc) \
+ PYTHON_GETSET_DEF(#name, base ## _ ## name, NULL, doc, NULL)
+
#define PYTHON_GET_DEF_FULL(name, base, doc) \
PYTHON_GETSET_DEF(#name, base ## _get_ ## name, NULL, doc, NULL)
@@ -151,6 +167,12 @@ PyObject *not_yet_implemented_method(PyObject *, PyObject *);
/* Retourne toujours rien. */
PyObject *py_return_none(PyObject *, PyObject *);
+/* Retourne toujours faux. */
+PyObject *py_return_false(PyObject *, PyObject *);
+
+/* Retourne toujours vrai. */
+PyObject *py_return_true(PyObject *, PyObject *);
+
/* Marque l'absence d'implémentation pour un attribut donné. */
PyObject *not_yet_implemented_getter(PyObject *, void *);