diff mbox series

[3/5] parser: function to get a new path of a node

Message ID 20181101170635.13493-3-sbabic@denx.de
State Changes Requested
Headers show
Series [1/5] Factorize function to count elements in array of strings | expand

Commit Message

Stefano Babic Nov. 1, 2018, 5:06 p.m. UTC
Using links, the path to a node must be computed again. The function
set_find_path() get the string pointed to the link and modify the array
of strings containing the whole path to a node.

A convention is used to traverse the tree upwards. If the string begins
with "..", this means to go up in the tree. Multiple leading ".." are
allowed to go up into the tree.

Signed-off-by: Stefano Babic <sbabic@denx.de>
---
 corelib/parsing_library.c | 56 +++++++++++++++++++++++++++++++++++++++
 include/parselib.h        | 10 +++++++
 2 files changed, 66 insertions(+)
diff mbox series

Patch

diff --git a/corelib/parsing_library.c b/corelib/parsing_library.c
index e9739fe..00463a7 100644
--- a/corelib/parsing_library.c
+++ b/corelib/parsing_library.c
@@ -12,6 +12,7 @@ 
 #include <fcntl.h>
 #include <errno.h>
 #include <sys/stat.h>
+#include <stdbool.h>
 #include <assert.h>
 #include "generated/autoconf.h"
 #include "bsdqueue.h"
@@ -19,6 +20,8 @@ 
 #include "swupdate.h"
 #include "parselib.h"
 
+#define MAX_LINKS_DEPTH	10
+
 void check_field_string(const char *src, char *dst, const size_t max_len)
 {
 	assert(max_len>0);
@@ -159,3 +162,56 @@  void get_hash_value(parsertype p, void *elem, unsigned char *hash)
 
 	ascii_to_hash(hash, hash_ascii);
 }
+
+bool set_find_path(const char **nodes, const char *newpath, char **tmp)
+{
+	unsigned int nleading;
+	char **iter, **paths;
+	unsigned int count = count_string_array(nodes);
+	unsigned int countpaths;
+
+	if (!newpath)
+		return false;
+
+	/*
+	 * Check if we have to traverse back
+	 */
+	for (nleading = 0; newpath[nleading] == '.'; nleading++);
+
+	/*
+	 * delimiter at the beginning indicates a relative path
+	 * exactly as in Unix, that mean .. for the upper directory
+	 * .. = parent 
+	 * .... = parent of parent
+	 * The number of leading "." must be even, else
+	 * it is a malformed path
+	 */
+	if (nleading % 2)
+		return false;
+
+	nleading /= 2;
+	if ((count - nleading) <= 0)
+		return false;
+
+	count -= nleading;
+	if (count > 0) count--;
+
+	paths = string_split(newpath, '.');
+
+	/*
+	 * check if there is enough space in nodes
+	 */
+	countpaths = count_string_array((const char **)paths);
+	if (count + countpaths >= MAX_PARSED_NODES)
+		return false;
+	if (!countpaths)
+		nodes[count++] = newpath;
+	else
+		for (iter = paths; *iter != NULL; iter++, count++)
+			nodes[count] = *iter;
+	nodes[count] = NULL;
+
+	tmp = paths;
+
+	return true;
+}
diff --git a/include/parselib.h b/include/parselib.h
index f53dd00..2fca3b5 100644
--- a/include/parselib.h
+++ b/include/parselib.h
@@ -9,6 +9,7 @@ 
 #define _PARSE_LIBRARY_H
 
 #include <assert.h>
+#include <stdbool.h>
 
 typedef enum {
 	LIBCFG_PARSER,
@@ -18,6 +19,12 @@  typedef enum {
 typedef void (*iterate_callback)(const char *name, const char *value,
 				 void *data);
 
+/*
+ * This is to limit the structure (array) used to save the whole
+ * path to the entry to be read.
+ */
+#define MAX_PARSED_NODES	20
+
 #ifdef CONFIG_LIBCONFIG
 #include <libconfig.h>
 #define LIBCONFIG_VERSION ((LIBCONFIG_VER_MAJOR << 16) | \
@@ -83,6 +90,9 @@  void get_field(parsertype p, void *e, const char *path, void *dest);
 int exist_field_string(parsertype p, void *e, const char *path);
 void get_hash_value(parsertype p, void *elem, unsigned char *hash);
 void check_field_string(const char *src, char *dst, const size_t max_len);
+bool find_root(parsertype p, void *root, const char **nodes);
+void *get_node(parsertype p, void *root, const char **nodes);
+bool set_find_path(const char **nodes, const char *newpath, char **tmp);
 
 #define GET_FIELD_STRING(p, e, name, d) \
 	get_field_string_with_size(p, e, name, d, sizeof(d))