From dc3be188b42a90404d0655c250e6697f5a55b862 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sun, 21 Feb 2021 14:26:27 +0100 Subject: Delete intermediate Python modules for some API features. --- plugins/pychrysalide/common/fnv1a.c | 91 ++++++-------------------- plugins/pychrysalide/common/fnv1a.h | 7 +- plugins/pychrysalide/common/leb128.c | 4 +- plugins/pychrysalide/common/module.c | 4 +- plugins/pychrysalide/common/pathname.c | 114 ++++++++++----------------------- plugins/pychrysalide/common/pathname.h | 7 +- tests/common/fnv1a.py | 13 +--- tests/common/pathname.py | 30 +++------ 8 files changed, 73 insertions(+), 197 deletions(-) diff --git a/plugins/pychrysalide/common/fnv1a.c b/plugins/pychrysalide/common/fnv1a.c index 510b531..4103c86 100644 --- a/plugins/pychrysalide/common/fnv1a.c +++ b/plugins/pychrysalide/common/fnv1a.c @@ -36,16 +36,8 @@ -#define FNV1A_DOC \ - "Python version for Chrysalide of the Fowler-Noll-Vo" \ - " hash function.\n" \ - "\n" \ - "There is no constructor for this class: its methods" \ - " are static methods only." - - /* Détermine l'empreinte FNV1a d'une chaîne de caractères. */ -static PyObject *py_fnv1a_hash(PyObject *, PyObject *); +static PyObject *py_fnv1a(PyObject *, PyObject *); @@ -62,18 +54,21 @@ static PyObject *py_fnv1a_hash(PyObject *, PyObject *); * * ******************************************************************************/ -static PyObject *py_fnv1a_hash(PyObject *self, PyObject *args) +static PyObject *py_fnv1a(PyObject *self, PyObject *args) { PyObject *result; /* Instance à retourner */ const char *str; /* Chaîne à traiter. */ int ret; /* Bilan de lecture des args. */ fnv64_t value; /* Empreinte calculée */ -#define FNV1A_HASH_METHOD PYTHON_METHOD_DEF \ -( \ - hash, "str, /", \ - METH_VARARGS | METH_STATIC, py_fnv1a, \ - "Compute the FNV-1a hash from a given string." \ +#define FNV1A_METHOD PYTHON_METHOD_DEF \ +( \ + fnv1a, "str, /", \ + METH_VARARGS, py, \ + "Compute the Fowler-Noll-Vo hash (version 1a) of a" \ + " given string." \ + "\n" \ + "The result is 64-bit integer value." \ ) ret = PyArg_ParseTuple(args, "s", &str); @@ -92,48 +87,7 @@ static PyObject *py_fnv1a_hash(PyObject *self, PyObject *args) * * * Paramètres : - * * * -* Description : Fournit un accès à une définition de type à diffuser. * -* * -* Retour : Définition d'objet pour Python. * -* * -* Remarques : - * -* * -******************************************************************************/ - -PyTypeObject *get_python_fnv1a_type(void) -{ - static PyMethodDef py_fnv1a_methods[] = { - FNV1A_HASH_METHOD, - { NULL } - }; - - static PyTypeObject py_fnv1a_type = { - - PyVarObject_HEAD_INIT(NULL, 0) - - .tp_name = "pychrysalide.common.fnv1a", - .tp_basicsize = sizeof(PyObject), - - .tp_flags = Py_TPFLAGS_DEFAULT, - - .tp_doc = FNV1A_DOC, - - .tp_methods = py_fnv1a_methods, - - .tp_new = no_python_constructor_allowed, - - }; - - return &py_fnv1a_type; - -} - - -/****************************************************************************** -* * -* Paramètres : module = module dont la définition est à compléter. * -* * -* Description : Prend en charge l'objet 'pychrysalide.core.fnv1a'. * +* Description : Définit une extension du module 'common' à compléter. * * * * Retour : Bilan de l'opération. * * * @@ -141,25 +95,20 @@ PyTypeObject *get_python_fnv1a_type(void) * * ******************************************************************************/ -bool ensure_python_fnv1a_is_registered(void) +bool populate_common_module_with_fnv1a(void) { - PyTypeObject *type; /* Type Python pour 'fnv1a' */ + bool result; /* Bilan à retourner */ PyObject *module; /* Module à recompléter */ - type = get_python_fnv1a_type(); - - if (!PyType_HasFeature(type, Py_TPFLAGS_READY)) - { - if (PyType_Ready(type) != 0) - return false; - - module = get_access_to_python_module("pychrysalide.common"); + static PyMethodDef py_fnv1a_methods[] = { + FNV1A_METHOD, + { NULL } + }; - if (!register_python_module_object(module, type)) - return false; + module = get_access_to_python_module("pychrysalide.common"); - } + result = register_python_module_methods(module, py_fnv1a_methods); - return true; + return result; } diff --git a/plugins/pychrysalide/common/fnv1a.h b/plugins/pychrysalide/common/fnv1a.h index 0bdd2c8..52b5cf5 100644 --- a/plugins/pychrysalide/common/fnv1a.h +++ b/plugins/pychrysalide/common/fnv1a.h @@ -31,11 +31,8 @@ -/* Fournit un accès à une définition de type à diffuser. */ -PyTypeObject *get_python_fnv1a_type(void); - -/* Prend en charge l'objet 'pychrysalide.common.fnv1a'. */ -bool ensure_python_fnv1a_is_registered(void); +/* Définit une extension du module 'common' à compléter. */ +bool populate_common_module_with_fnv1a(void); diff --git a/plugins/pychrysalide/common/leb128.c b/plugins/pychrysalide/common/leb128.c index 49ef533..8e1bf28 100644 --- a/plugins/pychrysalide/common/leb128.c +++ b/plugins/pychrysalide/common/leb128.c @@ -273,7 +273,7 @@ bool populate_common_module_with_leb128(void) bool result; /* Bilan à retourner */ PyObject *module; /* Module à recompléter */ - static PyMethodDef py_queue_methods[] = { + static PyMethodDef py_leb128_methods[] = { LEB128_PACK_ULEB128_METHOD, LEB128_PACK_LEB128_METHOD, LEB128_UNPACK_ULEB128_METHOD, @@ -283,7 +283,7 @@ bool populate_common_module_with_leb128(void) module = get_access_to_python_module("pychrysalide.common"); - result = register_python_module_methods(module, py_queue_methods); + result = register_python_module_methods(module, py_leb128_methods); return result; diff --git a/plugins/pychrysalide/common/module.c b/plugins/pychrysalide/common/module.c index a5cf957..865b7e2 100644 --- a/plugins/pychrysalide/common/module.c +++ b/plugins/pychrysalide/common/module.c @@ -95,12 +95,12 @@ bool populate_common_module(void) result = true; + if (result) result = populate_common_module_with_fnv1a(); if (result) result = populate_common_module_with_leb128(); + if (result) result = populate_common_module_with_pathname(); if (result) result = ensure_python_bitfield_is_registered(); - if (result) result = ensure_python_fnv1a_is_registered(); if (result) result = ensure_python_packed_buffer_is_registered(); - if (result) result = ensure_python_pathname_is_registered(); assert(result); diff --git a/plugins/pychrysalide/common/pathname.c b/plugins/pychrysalide/common/pathname.c index c83c27d..9ea9a2b 100644 --- a/plugins/pychrysalide/common/pathname.c +++ b/plugins/pychrysalide/common/pathname.c @@ -40,18 +40,11 @@ -#define PYTHON_PATHNAME_DOC \ - "Path manipulations in Python for Chrysalide.\n" \ - "\n" \ - "There is no constructor for this class: its methods" \ - " are static methods only." - - /* Calcule le chemin relatif entre deux fichiers donnés. */ -static PyObject *py_build_relative_filename(PyObject *, PyObject *); +static PyObject *py_pathname_build_relative_filename(PyObject *, PyObject *); /* Calcule le chemin absolu d'un fichier par rapport à un autre. */ -static PyObject *py_build_absolute_filename(PyObject *, PyObject *); +static PyObject *py_pathname_build_absolute_filename(PyObject *, PyObject *); @@ -68,7 +61,7 @@ static PyObject *py_build_absolute_filename(PyObject *, PyObject *); * * ******************************************************************************/ -static PyObject *py_build_relative_filename(PyObject *self, PyObject *args) +static PyObject *py_pathname_build_relative_filename(PyObject *self, PyObject *args) { PyObject *result; /* Instance à retourner */ const char *ref; /* Fichier de référence */ @@ -76,13 +69,16 @@ static PyObject *py_build_relative_filename(PyObject *self, PyObject *args) int ret; /* Bilan de lecture des args. */ char *relative; /* Chemin d'accès construit */ -#define BUILD_RELATIVE_FILENAME_METHOD PYTHON_METHOD_DEF \ -( \ - build_relative_filename, "ref, target", \ - METH_VARARGS | METH_STATIC, py, \ - "Compute the relative path between two files.\n" \ - "\n" \ - "Both arguments must be strings." \ +#define BUILD_RELATIVE_FILENAME_METHOD PYTHON_METHOD_DEF \ +( \ + build_relative_filename, "reference, target", \ + METH_VARARGS, py_pathname, \ + "Compute the relative path between two files: a *reference*" \ + " location as point of view and a *target* file.\n" \ + "\n" \ + "Both arguments must be strings.\n" \ + "\n" \ + "The result is also a string." \ ) ret = PyArg_ParseTuple(args, "ss", &ref, &target); @@ -112,7 +108,7 @@ static PyObject *py_build_relative_filename(PyObject *self, PyObject *args) * * ******************************************************************************/ -static PyObject *py_build_absolute_filename(PyObject *self, PyObject *args) +static PyObject *py_pathname_build_absolute_filename(PyObject *self, PyObject *args) { PyObject *result; /* Instance à retourner */ const char *ref; /* Fichier de référence */ @@ -120,13 +116,17 @@ static PyObject *py_build_absolute_filename(PyObject *self, PyObject *args) int ret; /* Bilan de lecture des args. */ char *relative; /* Chemin d'accès construit */ -#define BUILD_ABSOLUTE_FILENAME_METHOD PYTHON_METHOD_DEF \ -( \ - build_absolute_filename, "ref, target", \ - METH_VARARGS | METH_STATIC, py, \ - "Compute the absolute path for a file.\n" \ - "\n" \ - "Both arguments must be strings." \ +#define BUILD_ABSOLUTE_FILENAME_METHOD PYTHON_METHOD_DEF \ +( \ + build_absolute_filename, "reference, target", \ + METH_VARARGS, py_pathname, \ + "Compute the absolute path for a *target* file from a" \ + " *reference* location.\n" \ + "\n" \ + "Both arguments must be strings.\n" \ + "\n" \ + "The result is a string on success. A *ValueError* exception" \ + " is raised on failure." \ ) ret = PyArg_ParseTuple(args, "ss", &ref, &target); @@ -154,75 +154,29 @@ static PyObject *py_build_absolute_filename(PyObject *self, PyObject *args) * * * Paramètres : - * * * -* Description : Fournit un accès à une définition de type à diffuser. * +* Description : Définit une extension du module 'common' à compléter. * * * -* Retour : Définition d'objet pour Python. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -PyTypeObject *get_python_pathname_type(void) +bool populate_common_module_with_pathname(void) { + bool result; /* Bilan à retourner */ + PyObject *module; /* Module à recompléter */ + static PyMethodDef py_pathname_methods[] = { BUILD_RELATIVE_FILENAME_METHOD, BUILD_ABSOLUTE_FILENAME_METHOD, { NULL } }; - static PyTypeObject py_pathname_type = { - - PyVarObject_HEAD_INIT(NULL, 0) - - .tp_name = "pychrysalide.common.pathname", - .tp_basicsize = sizeof(PyObject), - - .tp_flags = Py_TPFLAGS_DEFAULT, - - .tp_doc = PYTHON_PATHNAME_DOC, - - .tp_methods = py_pathname_methods, + module = get_access_to_python_module("pychrysalide.common"); - .tp_new = no_python_constructor_allowed, + result = register_python_module_methods(module, py_pathname_methods); - }; - - return &py_pathname_type; - -} - - -/****************************************************************************** -* * -* Paramètres : module = module dont la définition est à compléter. * -* * -* Description : Prend en charge l'objet 'pychrysalide.core.pathname'. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool ensure_python_pathname_is_registered(void) -{ - PyTypeObject *type; /* Type Python pour 'pathname' */ - PyObject *module; /* Module à recompléter */ - - type = get_python_pathname_type(); - - if (!PyType_HasFeature(type, Py_TPFLAGS_READY)) - { - if (PyType_Ready(type) != 0) - return false; - - module = get_access_to_python_module("pychrysalide.common"); - - if (!register_python_module_object(module, type)) - return false; - - } - - return true; + return result; } diff --git a/plugins/pychrysalide/common/pathname.h b/plugins/pychrysalide/common/pathname.h index 619053c..3e22aa0 100644 --- a/plugins/pychrysalide/common/pathname.h +++ b/plugins/pychrysalide/common/pathname.h @@ -31,11 +31,8 @@ -/* Fournit un accès à une définition de type à diffuser. */ -PyTypeObject *get_python_pathname_type(void); - -/* Prend en charge l'objet 'pychrysalide.common.pathname'. */ -bool ensure_python_pathname_is_registered(void); +/* Définit une extension du module 'common' à compléter. */ +bool populate_common_module_with_pathname(void); diff --git a/tests/common/fnv1a.py b/tests/common/fnv1a.py index 2013afa..3bb7c32 100644 --- a/tests/common/fnv1a.py +++ b/tests/common/fnv1a.py @@ -4,22 +4,15 @@ from pychrysalide.common import fnv1a class TestFnv1a(ChrysalideTestCase): - """TestCase for common.fnv1a*""" - - def testFnv1aConstructor(self): - """Check that no constructor is available for the fnv1a class.""" - - with self.assertRaisesRegex(NotImplementedError, 'Chrysalide does not allow building this kind of object from Python'): - instance = fnv1a() - + """TestCase for common FNV-1a hashing features.""" def testFnv1aSamples(self): """Compute some Fnv1a hashs.""" # Test cases from http://isthe.com/chongo/src/fnv/test_fnv.c - val = fnv1a.hash('') + val = fnv1a('') self.assertEqual(val, 0xcbf29ce484222325) - val = fnv1a.hash('chongo was here!\n') + val = fnv1a('chongo was here!\n') self.assertEqual(val, 0x46810940eff5f915) diff --git a/tests/common/pathname.py b/tests/common/pathname.py index 00a084b..23ca2b0 100644 --- a/tests/common/pathname.py +++ b/tests/common/pathname.py @@ -1,10 +1,10 @@ from chrysacase import ChrysalideTestCase -from pychrysalide.common import pathname +from pychrysalide.common import build_relative_filename, build_absolute_filename class TestPathnames(ChrysalideTestCase): - """TestCase for common.pathname*""" + """TestCase for common pathname features.""" @classmethod def setUpClass(cls): @@ -58,11 +58,9 @@ class TestPathnames(ChrysalideTestCase): def testBuildingRelative(self): """Build valid relative paths.""" - build_relative = pathname.build_relative_filename - for tst in self._tests: - got = build_relative(tst['ref'], tst['target']) + got = build_relative_filename(tst['ref'], tst['target']) self.assertEqual(got, tst['relative']) @@ -70,11 +68,9 @@ class TestPathnames(ChrysalideTestCase): def testBuildingAbsolute(self): """Build valid absolute paths.""" - build_absolute = pathname.build_absolute_filename - for tst in self._tests: - got = build_absolute(tst['ref'], tst['relative']) + got = build_absolute_filename(tst['ref'], tst['relative']) self.assertEqual(got, tst['target']) @@ -82,29 +78,19 @@ class TestPathnames(ChrysalideTestCase): def testBuildingWrongAbsolute(self): """Build invalid absolute paths.""" - build_absolute = pathname.build_absolute_filename - with self.assertRaisesRegex(Exception, 'Relative path is too deep.'): - got = build_absolute('/a/b', '../../c') - - - def testPathnameConstructor(self): - """Check that no constructor is available for the pathname class.""" - - with self.assertRaisesRegex(NotImplementedError, 'Chrysalide does not allow building this kind of object from Python'): - - instance = pathname() + got = build_absolute_filename('/a/b', '../../c') def testPathnameSamples(self): """Play with some path samples.""" - filename = pathname.build_absolute_filename('/tmp/deep', '../myfile') + filename = build_absolute_filename('/tmp/deep', '../myfile') self.assertEqual(filename, '/myfile') - filename = pathname.build_absolute_filename('/tmp/deep/', '../myfile') + filename = build_absolute_filename('/tmp/deep/', '../myfile') self.assertEqual(filename, '/tmp/myfile') - filename = pathname.build_relative_filename('/tmp/deep', '/myfile') + filename = build_relative_filename('/tmp/deep', '/myfile') self.assertEqual(filename, '../myfile') -- cgit v0.11.2-87-g4458