summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2022-02-20 23:22:59 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2022-02-20 23:22:59 (GMT)
commit2a0b25fca5f6d4bef7edd4d618e420559209e8ec (patch)
tree36d1b6dfc9a49af0f04af0abbc169c0ffd4bd070
parent945e0c9ecce02155555387aad672e272f5646362 (diff)
Translate enumerations before PyGObject using internal definitions when needed.
-rw-r--r--plugins/pychrysalide/helpers.c104
-rw-r--r--plugins/pychrysalide/helpers.h54
2 files changed, 139 insertions, 19 deletions
diff --git a/plugins/pychrysalide/helpers.c b/plugins/pychrysalide/helpers.c
index 92a5db9..320e40a 100644
--- a/plugins/pychrysalide/helpers.c
+++ b/plugins/pychrysalide/helpers.c
@@ -1440,15 +1440,15 @@ int convert_to_gdk_rgba(PyObject *arg, void *dst)
* *
* Description : Officialise un groupe de constantes avec sémentique. *
* *
-* Retour : true en cas de succès de l'opération, false sinon. *
+* Retour : Groupe de constantes mis en place ou NULL en cas d'échec. *
* *
* Remarques : - *
* *
******************************************************************************/
-bool _attach_constants_group(const char *owner, PyObject *dict, bool flags, const char *name, PyObject *values, const char *doc)
+PyObject *_attach_constants_group(const char *owner, PyObject *dict, bool flags, const char *name, PyObject *values, const char *doc)
{
- bool result; /* Bilan à retourner */
+ PyObject *result; /* Instance à retourner */
PyObject *enum_mod; /* Module Python enum */
PyObject *class; /* Classe "Enum*" */
PyObject *str_obj; /* Conversion en Python */
@@ -1462,7 +1462,7 @@ bool _attach_constants_group(const char *owner, PyObject *dict, bool flags, cons
PyObject *features; /* Module à recompléter */
PyObject *features_dict; /* Dictionnaire à compléter */
- result = false;
+ result = NULL;
/* Recherche de la classe Python */
@@ -1539,7 +1539,8 @@ bool _attach_constants_group(const char *owner, PyObject *dict, bool flags, cons
ret = PyDict_SetItemString(features_dict, name, new);
if (ret != 0) goto register_1_error;
- result = true;
+ result = new;
+ Py_INCREF(result);
/* Sortie propre */
@@ -1570,6 +1571,99 @@ bool _attach_constants_group(const char *owner, PyObject *dict, bool flags, cons
}
+/******************************************************************************
+* *
+* Paramètres : owner = désignation du propriétaire du dictionnaire visé. *
+* dict = dictionnaire dont le contenu est à compléter. *
+* flags = indique le type d'énumération ciblée. *
+* name = désignation humaine du groupe à constituer. *
+* values = noms et valeurs associées. *
+* doc = documentation à associer au groupe. *
+* gtype = énumération GLib à lier. *
+* *
+* Description : Officialise un groupe de constantes avec lien GLib. *
+* *
+* Retour : Groupe de constantes mis en place ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+PyObject *_attach_constants_group_with_pyg_enum(const char *owner, PyObject *dict, bool flags, const char *name, PyObject *values, const char *doc, GType gtype)
+{
+ PyObject *result; /* Instance à retourner */
+ PyObject *values_set; /* Zone pour nouvelles valeurs */
+ int ret; /* Bilan d'une insertion */
+ PyObject *new; /* Nouvelle instance en place */
+ PyObject *values_src; /* Source de nouvelles valeurs */
+ PyObject *values_dest; /* Destination des valeurs */
+
+ static GQuark pygenum_class_key = 0; /* Clef d'accès au marquage */
+
+ result = NULL;
+
+ /**
+ * Le seul intérêt d'un tel enregistrement en bonne et due forme est de
+ * permettre une impression, via str() ou repr(), de l'énumération
+ * transcrite en GLib via g_enum_register_static() et potentiellement
+ * convertie de façon brusque par _pygi_argument_to_object(), lors d'une
+ * émission de signal par exemple.
+ *
+ * La satisfaction de la fonction pyg_enum_from_gtype() est ainsi recherchée.
+ * Tous les éléments sont normalement mis en place à partir de la fonction
+ * pyg_enum_add().
+ */
+
+ /* Préparation du réceptacle */
+
+ values_set = PyDict_New();
+
+ ret = PyDict_SetItemString(values, "__enum_values__", values_set);
+
+ Py_DECREF(values_set);
+
+ if (ret != 0) goto exit;
+
+ /* Création */
+
+ new = _attach_constants_group(owner, dict, flags, name, values, doc);
+ if (new == NULL) goto exit;
+
+ /* Actualisation des valeurs */
+
+ values_src = PyDict_GetItemString(((PyTypeObject *)new)->tp_dict, "_value2member_map_");
+ if (values_src == NULL) goto exit_without_src;
+
+ values_dest = PyDict_GetItemString(((PyTypeObject *)new)->tp_dict, "__enum_values__");
+ if (values_dest == NULL) goto exit_without_dest;
+
+ assert(values_dest == values_set);
+
+ ret = PyDict_Merge(values_dest, values_src, true);
+
+ if (ret == 0)
+ {
+ result = new;
+ Py_INCREF(result);
+
+ if (pygenum_class_key == 0)
+ pygenum_class_key = g_quark_from_static_string("PyGEnum::class");
+
+ g_type_set_qdata(gtype, pygenum_class_key, result);
+
+ }
+
+ exit_without_dest:
+ exit_without_src:
+
+ Py_DECREF(new);
+
+ exit:
+
+ return result;
+
+}
+
/******************************************************************************
* *
diff --git a/plugins/pychrysalide/helpers.h b/plugins/pychrysalide/helpers.h
index 931be95..0ef8adc 100644
--- a/plugins/pychrysalide/helpers.h
+++ b/plugins/pychrysalide/helpers.h
@@ -308,20 +308,46 @@ int convert_to_gdk_rgba(PyObject *, void *);
})
/* Officialise un groupe de constantes avec sémentique. */
-bool _attach_constants_group(const char *, PyObject *, bool, const char *, PyObject *, const char *);
-
-#define attach_constants_group_to_type(type, flags, name, values, doc) \
- _attach_constants_group(type->tp_name, type->tp_dict, flags, name, values, doc)
-
-#define attach_constants_group_to_module(mod, flags, name, values, doc) \
- ({ \
- bool __result; \
- const char *__owner; \
- PyObject *__dict; \
- __owner = PyModule_GetName(mod); \
- __dict = PyModule_GetDict(mod); \
- __result = _attach_constants_group(__owner, __dict, flags, name, values, doc); \
- __result; \
+PyObject *_attach_constants_group(const char *, PyObject *, bool, const char *, PyObject *, const char *);
+
+#define attach_constants_group_to_type(type, flags, name, values, doc) \
+ ({ \
+ bool __result; \
+ PyObject *__new; \
+ __new = _attach_constants_group(type->tp_name, type->tp_dict, flags, name, values, \
+ doc); \
+ __result = (__new != NULL); \
+ Py_XDECREF(__new); \
+ __result; \
+ })
+
+#define attach_constants_group_to_module(mod, flags, name, values, doc) \
+ ({ \
+ bool __result; \
+ const char *__owner; \
+ PyObject *__dict; \
+ PyObject *__new; \
+ __owner = PyModule_GetName(mod); \
+ __dict = PyModule_GetDict(mod); \
+ __new = _attach_constants_group(__owner, __dict, flags, name, values, doc); \
+ __result = (__new != NULL); \
+ Py_XDECREF(__new); \
+ __result; \
+ })
+
+/* Officialise un groupe de constantes avec lien GLib. */
+PyObject *_attach_constants_group_with_pyg_enum(const char *, PyObject *, bool, const char *, PyObject *, const char *, GType);
+
+
+#define attach_constants_group_to_type_with_pyg_enum(type, flags, name, values, doc, gtype) \
+ ({ \
+ bool __result; \
+ PyObject *__new; \
+ __new = _attach_constants_group_with_pyg_enum(type->tp_name, type->tp_dict, flags, \
+ name, values, doc, gtype); \
+ __result = (__new != NULL); \
+ Py_XDECREF(__new); \
+ __result; \
})
/* Traduit une valeur constante C en équivalent Python. */