From 0aea964ab880a972e8a4d54b36f7eee340f49d5b Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Fri, 8 Oct 2021 08:52:02 +0200 Subject: Extract filenames when creating content attributes. --- plugins/pychrysalide/analysis/cattribs.c | 79 +++++++++++--------------------- src/analysis/cattribs.c | 45 ++++++------------ src/analysis/cattribs.h | 5 +- src/analysis/contents/memory.c | 2 +- src/main.c | 14 ++++-- tests/analysis/cattribs.py | 42 ++++++++--------- 6 files changed, 72 insertions(+), 115 deletions(-) diff --git a/plugins/pychrysalide/analysis/cattribs.c b/plugins/pychrysalide/analysis/cattribs.c index be5c5b1..895fed8 100644 --- a/plugins/pychrysalide/analysis/cattribs.c +++ b/plugins/pychrysalide/analysis/cattribs.c @@ -45,9 +45,6 @@ static PyObject *py_content_attributes_new(PyTypeObject *, PyObject *, PyObject /* Fournit l'ensemble des clefs d'un ensemble d'attributs. */ static PyObject *py_content_attributes_subscript(PyObject *, PyObject *); -/* Fournit le fichier de base compris dans le chemin initial. */ -static PyObject *py_content_attributes_get_filename(PyObject *, void *); - /* Fournit l'ensemble des clefs d'un ensemble d'attributs. */ static PyObject *py_content_attributes_get_keys(PyObject *, void *); @@ -72,7 +69,10 @@ static PyObject *py_content_attributes_new(PyTypeObject *type, PyObject *args, P PyObject *result; /* Instance à retourner */ const char *path; /* Chemin d'accès à traiter */ int ret; /* Bilan de lecture des args. */ + char *filename; /* Nom de fichier embarqué */ GContentAttributes *attribs; /* Création GLib à transmettre */ + PyObject *obj; /* Objet Python à retourner */ + PyObject *str; /* Chaîne à retourner */ #define CONTENT_ATTRIBUTES_DOC \ "ContentAttributes is a set of values used at binary content loading.\n" \ @@ -87,25 +87,43 @@ static PyObject *py_content_attributes_new(PyTypeObject *type, PyObject *args, P "\n" \ " ContentAttributes(path)\n" \ "\n" \ - "Where path is a list of parameters: '[...]&key0=value0&key1=value1...'" + "Where path is a list of parameters: '[...]&key0=value0&key1=value1...'" \ + "\n" \ + "The constructor returns a tuple containing a ContentAttributes instance" \ + " and the original targot filename." ret = PyArg_ParseTuple(args, "s", &path); if (!ret) return NULL; - attribs = g_content_attributes_new(path); + attribs = g_content_attributes_new(path, &filename); if (attribs != NULL) { g_object_ref_sink(G_OBJECT(attribs)); - result = pygobject_new(G_OBJECT(attribs)); + obj = pygobject_new(G_OBJECT(attribs)); g_object_unref(attribs); } else { - result = Py_None; - Py_INCREF(result); + obj = Py_None; + Py_INCREF(obj); } + if (filename != NULL) + { + str = PyUnicode_FromString(filename); + free(filename); + } + else + { + str = Py_None; + Py_INCREF(str); + } + + result = PyTuple_New(2); + PyTuple_SetItem(result, 0, obj); + PyTuple_SetItem(result, 1, str); + return result; } @@ -200,50 +218,6 @@ static PyObject *py_content_attributes_get_keys(PyObject *self, void *closure) /****************************************************************************** * * -* Paramètres : self = objet Python concerné par l'appel. * -* closure = non utilisé ici. * -* * -* Description : Fournit le fichier de base compris dans le chemin initial. * -* * -* Retour : Nom de fichier renvoyant vers un contenu à charger ou None. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_content_attributes_get_filename(PyObject *self, void *closure) -{ - PyObject *result; /* Valeur à retourner */ - GContentAttributes *cattribs; /* Version native */ - const char *filename; /* Nom de fichier natif */ - -#define CONTENT_ATTRIBUTES_FILENAME_ATTRIB PYTHON_GET_DEF_FULL \ -( \ - filename, py_content_attributes, \ - "Filename extracted from the path provided to the attribute set," \ - " constructor, or None if no filename was defined." \ -) - - cattribs = G_CONTENT_ATTRIBUTES(pygobject_get(self)); - - filename = g_content_attributes_get_filename(cattribs); - - if (filename != NULL) - result = PyUnicode_FromString(filename); - - else - { - result = Py_None; - Py_INCREF(result); - } - - return result; - -} - - -/****************************************************************************** -* * * Paramètres : - * * * * Description : Fournit un accès à une définition de type à diffuser. * @@ -267,7 +241,6 @@ PyTypeObject *get_python_content_attributes_type(void) }; static PyGetSetDef py_content_attributes_getseters[] = { - CONTENT_ATTRIBUTES_FILENAME_ATTRIB, CONTENT_ATTRIBUTES_KEYS_ATTRIB, { NULL } }; diff --git a/src/analysis/cattribs.c b/src/analysis/cattribs.c index 704e665..1299991 100644 --- a/src/analysis/cattribs.c +++ b/src/analysis/cattribs.c @@ -37,8 +37,6 @@ struct _GContentAttributes { GObject parent; /* A laisser en premier */ - char *filename; /* Fichier de base du chemin */ - GGenConfig **configs; /* Paramètres par niveaux */ size_t count; /* Quantité de ces niveaux */ @@ -108,8 +106,6 @@ static void g_content_attributes_class_init(GContentAttributesClass *klass) static void g_content_attributes_init(GContentAttributes *attribs) { - attribs->filename = NULL; - attribs->configs = malloc(sizeof(GGenConfig *)); attribs->count = 1; @@ -165,7 +161,8 @@ static void g_content_attributes_finalize(GContentAttributes *attribs) /****************************************************************************** * * -* Paramètres : path = chemin d'accès à un contenu à charger. * +* Paramètres : path = chemin d'accès à un contenu à charger. * +* filename = nom de fichier embarqué. * * * * Description : Construit un ensemble d'attribut pour contenu binaire. * * * @@ -175,7 +172,7 @@ static void g_content_attributes_finalize(GContentAttributes *attribs) * * ******************************************************************************/ -GContentAttributes *g_content_attributes_new(const char *path) +GContentAttributes *g_content_attributes_new(const char *path, char **filename) { GContentAttributes *result; /* Adresse à retourner */ GGenConfig *config; /* Niveau de config. courant */ @@ -184,17 +181,26 @@ GContentAttributes *g_content_attributes_new(const char *path) char *part; /* Clef et sa valeur */ char *eq; /* Signe '=' rencontré */ + if (filename != NULL) + *filename = NULL; + result = g_object_new(G_TYPE_CONTENT_ATTRIBUTES, NULL); iter = strchr(path, '&'); if (iter == NULL) - result->filename = strdup(path); + { + if (strlen(path) && filename != NULL) + *filename = strdup(path); + } else { if (iter != path) - result->filename = strndup(path, iter - path); + { + if (filename != NULL) + *filename = strndup(path, iter - path); + } config = result->configs[0]; @@ -253,29 +259,6 @@ GContentAttributes *g_content_attributes_new(const char *path) /****************************************************************************** * * * Paramètres : attribs = ensemble d'attributs de contenu à consulter. * -* * -* Description : Fournit le fichier de base compris dans le chemin initial. * -* * -* Retour : Nom de fichier renvoyant vers un contenu à charger ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -const char *g_content_attributes_get_filename(const GContentAttributes *attribs) -{ - char *result; /* Nom de fichier à retourner */ - - result = attribs->filename; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : attribs = ensemble d'attributs de contenu à consulter. * * count = taille de la liste de clefs renvoyées. [OUT] * * * * Description : Fournit l'ensemble des clefs d'un ensemble d'attributs. * diff --git a/src/analysis/cattribs.h b/src/analysis/cattribs.h index c2e8a2e..2745fde 100644 --- a/src/analysis/cattribs.h +++ b/src/analysis/cattribs.h @@ -47,10 +47,7 @@ typedef struct _GContentAttributesClass GContentAttributesClass; GType g_content_attributes_get_type(void); /* Construit un ensemble d'attribut pour contenu binaire. */ -GContentAttributes *g_content_attributes_new(const char *); - -/* Fournit le fichier de base compris dans le chemin initial. */ -const char *g_content_attributes_get_filename(const GContentAttributes *); +GContentAttributes *g_content_attributes_new(const char *, char **); /* Fournit l'ensemble des clefs d'un ensemble d'attributs. */ const char **g_content_attributes_get_keys(const GContentAttributes *, size_t *); diff --git a/src/analysis/contents/memory.c b/src/analysis/contents/memory.c index 6a020e8..50647f6 100644 --- a/src/analysis/contents/memory.c +++ b/src/analysis/contents/memory.c @@ -170,7 +170,7 @@ static void g_memory_content_init(GMemoryContent *content) content->attribs = NULL; - empty = g_content_attributes_new(""); + empty = g_content_attributes_new("", NULL); g_binary_content_set_attributes(G_BIN_CONTENT(content), empty); diff --git a/src/main.c b/src/main.c index 7d49ba6..434c861 100644 --- a/src/main.c +++ b/src/main.c @@ -511,7 +511,7 @@ static int open_binaries(char **files, int count) GStudyProject *project; /* Projet courant à compléter */ int i; /* Boucle de parcours */ GContentAttributes *attribs; /* Attributs à lier au contenu */ - const char *filename; /* Chemin d'accès au contenu */ + char *filename; /* Chemin d'accès au contenu */ GBinContent *content; /* Contenu binaire à charger */ result = EXIT_SUCCESS; @@ -520,11 +520,15 @@ static int open_binaries(char **files, int count) for (i = 0; i < count && result == EXIT_SUCCESS; i++) { - attribs = g_content_attributes_new(files[i]); + attribs = g_content_attributes_new(files[i], &filename); - filename = g_content_attributes_get_filename(attribs); - - content = g_file_content_new(filename); + if (filename == NULL) + content = NULL; + else + { + content = g_file_content_new(filename); + free(filename); + } if (content != NULL) { diff --git a/tests/analysis/cattribs.py b/tests/analysis/cattribs.py index 1a7f7da..e388afc 100644 --- a/tests/analysis/cattribs.py +++ b/tests/analysis/cattribs.py @@ -15,10 +15,10 @@ class TestProjectFeatures(ChrysalideTestCase): def testEmptyContentAttributeSet(self): """Check properties of empty content attribute set.""" - attribs = ContentAttributes('') - self.assertIsNotNone(attribs) + attribs, filename = ContentAttributes('') - self.assertIsNone(attribs.filename) + self.assertIsNotNone(attribs) + self.assertIsNone(filename) self.assertEqual(len(attribs.keys), 0) @@ -33,16 +33,16 @@ class TestProjectFeatures(ChrysalideTestCase): 'dddd': '3', } - filename = 'filename' - path = filename + orig_filename = 'filename' + path = orig_filename for k in model.keys(): path += '&%s=%s' % (k, model[k]) - attribs = ContentAttributes(path) - self.assertIsNotNone(attribs) + attribs, filename = ContentAttributes(path) - self.assertEqual(attribs.filename, filename) + self.assertIsNotNone(attribs) + self.assertEqual(orig_filename, filename) kcount = 0 @@ -73,10 +73,10 @@ class TestProjectFeatures(ChrysalideTestCase): for k in model.keys(): path += '&e%s=%s' % (k, model[k]) - attribs = ContentAttributes(path) - self.assertIsNotNone(attribs) + attribs, filename = ContentAttributes(path) - self.assertIsNone(attribs.filename) + self.assertIsNotNone(attribs) + self.assertIsNone(filename) kcount = 0 @@ -92,31 +92,31 @@ class TestProjectFeatures(ChrysalideTestCase): path = '&&' - attribs = ContentAttributes(path) - self.assertIsNotNone(attribs) + attribs, filename = ContentAttributes(path) - self.assertIsNone(attribs.filename) + self.assertIsNotNone(attribs) + self.assertIsNone(filename) self.assertEqual(len(attribs.keys), 0) path = '&&&' - attribs = ContentAttributes(path) - self.assertIsNotNone(attribs) + attribs, filename = ContentAttributes(path) - self.assertIsNone(attribs.filename) + self.assertIsNotNone(attribs) + self.assertIsNone(filename) self.assertEqual(len(attribs.keys), 0) path = 'filename' - attribs = ContentAttributes(path) + attribs, filename = ContentAttributes(path) + self.assertIsNotNone(attribs) + self.assertEqual(filename, path) self.assertEqual(len(attribs.keys), 0) - self.assertEqual(attribs.filename, path) - def testContentAttributesKeyAccess(self): """Test some access keys for content attributes.""" @@ -130,7 +130,7 @@ class TestProjectFeatures(ChrysalideTestCase): for k in model.keys(): path += '&%s=%s' % (k, model[k]) - attribs = ContentAttributes(path) + attribs, _ = ContentAttributes(path) self.assertIsNotNone(attribs) with self.assertRaisesRegex(Exception, 'key must be a string value'): -- cgit v0.11.2-87-g4458