From c02661b7a8151a49a77c39241b040aa9bdb30223 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sun, 17 Nov 2019 19:39:09 +0100 Subject: Fixed the search of Yaml nodes. --- plugins/yaml/node.c | 61 ++++++++++++++++++++++++---------------------- tests/plugins/yamlrdr.py | 63 +++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 91 insertions(+), 33 deletions(-) diff --git a/plugins/yaml/node.c b/plugins/yaml/node.c index 57eb3d2..3dc6ec0 100644 --- a/plugins/yaml/node.c +++ b/plugins/yaml/node.c @@ -284,65 +284,64 @@ void _g_yaml_node_find_by_path(GYamlNode *node, const char *path, GYamlNode ***n { GYamlLine *line; /* Ligne Yaml liée au noeud */ const char *key; /* Clef associée au noeud */ - bool matched; /* Correspondance établie ? */ char *next; /* Prochaine partie du chemin */ size_t cmplen; /* Etendue de la comparaison */ int ret; /* Bilan d'une comparaison */ GYamlCollection *collec; /* Collection de noeuds */ + if (path[0] == '\0') + goto exit; + + line = g_yaml_node_get_yaml_line(node); + if (path[0] == '/') + { path++; - /* Correspondance au niveau du noeud ? */ + if (path[0] == '\0') + goto matched; - line = g_yaml_node_get_yaml_line(node); + } + + /* Correspondance au niveau du noeud ? */ if (line != NULL) { key = g_yaml_line_get_key(line); - if (path[0] == '\0') - matched = true; + next = strchr(path, '/'); + + if (next == NULL) + ret = strcmp(path, key); else { - next = strchr(path, '/'); - - cmplen = (next == NULL ? strlen(path) : next - path); + cmplen = next - path; if (cmplen == 0) goto cont; ret = strncmp(path, key, cmplen); - if (ret != 0) - goto done; - - else - { - if (next == NULL) - matched = true; - - else - { - path += cmplen; - goto cont; - } + } - } + if (ret != 0) + goto done; + else if (next != NULL) + { + path += cmplen; + goto cont; } - if (matched) - { - *nodes = realloc(*nodes, ++(*count) * sizeof(GYamlNode **)); + matched: - g_object_ref(G_OBJECT(node)); - (*nodes)[*count - 1] = node; + *nodes = realloc(*nodes, ++(*count) * sizeof(GYamlNode **)); - goto done; + g_object_ref(G_OBJECT(node)); + (*nodes)[*count - 1] = node; - } + goto done; } @@ -363,6 +362,10 @@ void _g_yaml_node_find_by_path(GYamlNode *node, const char *path, GYamlNode ***n if (line != NULL) g_object_unref(G_OBJECT(line)); + exit: + + ; + } diff --git a/tests/plugins/yamlrdr.py b/tests/plugins/yamlrdr.py index 103d6e8..eeae032 100644 --- a/tests/plugins/yamlrdr.py +++ b/tests/plugins/yamlrdr.py @@ -52,10 +52,24 @@ root: ''' + cls._mixed = tempfile.NamedTemporaryFile() + + cls._mixed_data = b''' +root: + - a: av + aa: aav + ab: abv + - b: bv + ba: bav + bb: bbv + +''' + tmp = [ [ cls._simple_map, cls._simple_map_data ], [ cls._simple_seq, cls._simple_seq_data ], - [ cls._nested, cls._nested_data ] + [ cls._nested, cls._nested_data ], + [ cls._mixed, cls._mixed_data ], ] for f, d in tmp: @@ -75,6 +89,7 @@ root: cls._simple_map, cls._simple_seq, cls._nested, + cls._mixed, ] for f in tmp: @@ -87,12 +102,12 @@ root: def testSimpleYamlContent(self): """Validate Yaml content readers.""" - def _build_node_desc(node, left): + def _build_node_desc(node, left, extra = ''): line = node.yaml_line if line: - prefix = '- ' if line.is_list_item else '' + prefix = '- ' if line.is_list_item else extra desc = left + prefix + line.key + ':' + (' ' + line.value if line.value else '') + '\n' indent = ' ' else: @@ -100,8 +115,12 @@ root: indent = '' if node.collection: + + if node.collection.is_sequence: + extra = ' ' + for child in node.collection.nodes: - desc += _build_node_desc(child, left + indent) + desc += _build_node_desc(child, left + indent, extra) return desc @@ -130,6 +149,14 @@ root: self.assertEqual('\n' + fulldesc + '\n', self._nested_data.decode('ascii')) + reader = YamlReader.new_from_path(self._mixed.name) + self.assertIsNotNone(reader) + self.assertIsNotNone(reader.tree) + + fulldesc = _build_node_desc(reader.tree.root, '') + + self.assertEqual('\n' + fulldesc + '\n', self._mixed_data.decode('ascii')) + def testSimpleYamlContentFinder(self): """Validate Yaml nested content search.""" @@ -194,3 +221,31 @@ root: self.assertEqual(found[0].yaml_line.key, 'i') self.assertEqual(found[0].yaml_line.is_list_item, True) + + + def testMixedYamlContentFinder(self): + """Validate Yaml mixed content search.""" + + reader = YamlReader.new_from_path(self._mixed.name) + self.assertIsNotNone(reader) + + found = reader.tree.find_by_path('/root') + + self.assertEqual(len(found), 1) + + if len(found) == 1: + self.assertEqual(found[0].yaml_line.key, 'root') + + found = reader.tree.find_by_path('/root/') + + self.assertEqual(len(found), 2) + + if len(found) == 2: + + sub = found[0].find_by_path('/a') + self.assertEqual(len(sub), 1) + self.assertEqual(sub[0].yaml_line.key, 'a') + + sub = found[0].find_by_path('/aa') + self.assertEqual(len(sub), 1) + self.assertEqual(sub[0].yaml_line.key, 'aa') -- cgit v0.11.2-87-g4458