[v2,3/5] parser: Replace properties array with a group of properties

Message ID 1515769128-29657-3-git-send-email-stefan@herbrechtsmeier.net
State Changes Requested
Headers show
Series
  • [v2,1/5] dict: Rename dictionary struct and its key to distinguish it from simple lists
Related show

Commit Message

Stefan Herbrechtsmeier Jan. 12, 2018, 2:58 p.m.
From: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>

Signed-off-by: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>

---

Changes in v2:
- Check name and value inside add_properties_cb function to skip NULL values
- Add support for properties with value arrays

 corelib/installer.c                 |  1 +
 corelib/parsing_library.c           | 15 +++++++++++++++
 corelib/parsing_library_libconfig.c | 24 ++++++++++++++++++++++++
 corelib/parsing_library_libjson.c   | 31 +++++++++++++++++++++++++++++++
 doc/source/handlers.rst             |  8 +++-----
 include/parselib.h                  |  9 +++++++++
 parser/parser.c                     | 35 +++++++++++++++--------------------
 7 files changed, 98 insertions(+), 25 deletions(-)

Comments

Stefan Herbrechtsmeier Jan. 12, 2018, 3:14 p.m. | #1
Hi,

> -----Ursprüngliche Nachricht-----
> Von: stefan@herbrechtsmeier.net [mailto:stefan@herbrechtsmeier.net]
> Gesendet: Freitag, 12. Januar 2018 15:59
> An: swupdate@googlegroups.com
> Cc: Herbrechtsmeier Dr.-Ing. , Stefan
> <Stefan.Herbrechtsmeier@weidmueller.com>
> Betreff: [PATCH v2 3/5] parser: Replace properties array with a group of
> properties

[snip]

> diff --git a/include/parselib.h b/include/parselib.h index 7c44a5e..b63349c
> 100644
> --- a/include/parselib.h
> +++ b/include/parselib.h
> @@ -27,6 +27,9 @@ typedef enum {
>       JSON_PARSER
>  } parsertype;
>
> +typedef void (*iterate_callback)(const char *name, const char *value,
> +                              void *data);
> +
>  #ifdef CONFIG_LIBCONFIG
>  #include <libconfig.h>
>  #define LIBCONFIG_VERSION ((LIBCONFIG_VER_MAJOR << 16) | \ @@ -
> 38,6 +41,8 @@ typedef enum {  void get_value_libconfig(const
> config_setting_t *e, void *dest);  void get_field_cfg(config_setting_t *e,
> const char *path, void *dest);  void *get_child_libconfig(void *e, const char
> *name);
> +void iterate_field_libconfig(config_setting_t *e, iterate_callback cb,
> +                          void *data);
>  const char *get_field_string_libconfig(config_setting_t *e, const char
> *path);
>
>  #else
> @@ -47,6 +52,7 @@ const char *get_field_string_libconfig(config_setting_t
> *e, const char *path);  #define find_node_libconfig(cfg, field, swcfg) (NULL)
>  #define get_field_string_libconfig(e, path)  (NULL)
>  #define get_child_libconfig(e, name)         (NULL)
> +#define iterate_field_libconfig(e, cb, data) (0)

The (0) must be replaced by { } to suppress build warning if libconfig is disabled.

>  #define get_field_cfg(e, path, dest)
>  #endif
>
> @@ -57,6 +63,7 @@ const char *get_field_string_json(json_object *e, const
> char *path);  void get_value_json(json_object *e, void *dest);  void
> get_field_json(json_object *e, const char *path, void *dest);  void
> *get_child_json(json_object *e, const char *name);
> +void iterate_field_json(json_object *e, iterate_callback cb, void
> +*data);
>  json_object *find_json_recursive_node(json_object *root, const char
> **names);  json_object *json_get_key(json_object *json_root, const char
> *key);  const char *json_get_value(struct json_object *json_root, @@ -68,6
> +75,7 @@ char *json_get_data_url(json_object *json_root, const char
> *key);
>  #define find_node_json(a, b, c)              (NULL)
>  #define get_field_string_json(e, path)  (NULL)
>  #define get_child_json(e, name)              (NULL)
> +#define iterate_field_json(e, cb, data)      (0)

The (0) must be replaced by { } to suppress build warning if libjson is disabled.

>  #define get_field_json(e, path, dest)
>  #define json_object_object_get_ex(a,b,c) (0)
>  #define json_object_array_get_idx(a, b)      (0)
> @@ -82,6 +90,7 @@ void get_field_string_with_size(parsertype p, void *e,
> const char *path,  int get_array_length(parsertype p, void *root);  void
> *get_elem_from_idx(parsertype p, void *node, int idx);  void
> *get_child(parsertype p, void *node, const char *name);
> +void iterate_field(parsertype p, void *e, iterate_callback cb, void
> +*data);
>  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); diff --git
> a/parser/parser.c b/parser/parser.c index 3ecc2da..9a60181 100644

[snip]

Best regards

Stefan Herbrechtsmeier
Software Developer Embedded Systems

Weidmüller - Your partner in Industrial Connectivity
We look forward to sharing ideas with you - Let's connect.

Weidmueller Interface GmbH & Co. KG
Klingenbergstraße 16, 32758 Detmold, Germany
Email: Stefan.Herbrechtsmeier@weidmueller.com - Web: www.weidmueller.com

Patch

diff --git a/corelib/installer.c b/corelib/installer.c
index 7da49b2..5ccfb21 100644
--- a/corelib/installer.c
+++ b/corelib/installer.c
@@ -220,6 +220,7 @@  static int prepare_boot_script(struct swupdate_cfg *cfg, const char *script)
 	LIST_FOREACH(bootvar, &cfg->bootloader, next) {
 		char *key = dict_entry_get_key(bootvar);
 		char *value = dict_entry_get_value(bootvar);
+
 		if (!key || !value)
 			continue;
 		snprintf(buf, sizeof(buf), "%s %s\n", key, value);
diff --git a/corelib/parsing_library.c b/corelib/parsing_library.c
index 79f3886..8f4637d 100644
--- a/corelib/parsing_library.c
+++ b/corelib/parsing_library.c
@@ -74,6 +74,21 @@  void *get_child(parsertype p, void *e, const char *name)
 	return NULL;
 }
 
+void iterate_field(parsertype p, void *e, iterate_callback cb, void *data)
+{
+	switch (p) {
+	case LIBCFG_PARSER:
+		iterate_field_libconfig(e, cb, data);
+		break;
+	case JSON_PARSER:
+		iterate_field_json(e, cb, data);
+		break;
+	default:
+		(void)e;
+		(void)data;
+	}
+}
+
 void *get_elem_from_idx(parsertype p, void *node, int idx)
 {
 	switch (p) {
diff --git a/corelib/parsing_library_libconfig.c b/corelib/parsing_library_libconfig.c
index f0cfb38..ccd596b 100644
--- a/corelib/parsing_library_libconfig.c
+++ b/corelib/parsing_library_libconfig.c
@@ -59,6 +59,30 @@  void *get_child_libconfig(void *e, const char *name)
 	return config_setting_get_member(e, name);
 }
 
+void iterate_field_libconfig(config_setting_t *e, iterate_callback cb, void *data)
+{
+	config_setting_t *entry, *elem;
+	const char *str;
+	int i, j;
+
+	if (!cb)
+		return;
+
+	for (i = 0; i < config_setting_length(e); i++) {
+		entry = config_setting_get_elem(e, i);
+		if (!config_setting_length(entry)) {
+			str = config_setting_get_string(entry);
+			cb(entry->name, str, data);
+		} else {
+			for (j = 0; j < config_setting_length(entry); j++) {
+				elem = config_setting_get_elem(entry, j);
+				str = config_setting_get_string(elem);
+				cb(entry->name, str, data);
+			}
+		}
+	}
+}
+
 void get_field_cfg(config_setting_t *e, const char *path, void *dest)
 {
 	config_setting_t *elem;
diff --git a/corelib/parsing_library_libjson.c b/corelib/parsing_library_libjson.c
index 67cbc2c..e995b8f 100644
--- a/corelib/parsing_library_libjson.c
+++ b/corelib/parsing_library_libjson.c
@@ -63,6 +63,37 @@  void *get_child_json(json_object *e, const char *path)
 	return node;
 }
 
+void iterate_field_json(json_object *e, iterate_callback cb, void *data)
+{
+	json_object *subnode;
+	const char *str;
+	int i;
+
+	if (!cb || json_object_get_type(e) != json_type_object)
+		return;
+
+	json_object_object_foreach(e, key, node) {
+		switch (json_object_get_type(node)) {
+		case json_type_string:
+			str = json_object_get_string(node);
+			cb(key, str, data);
+			break;
+		case json_type_array:
+			for (i = 0; i < json_object_array_length(node); i++) {
+				subnode = json_object_array_get_idx(node, i);
+				if (json_object_get_type(subnode) != json_type_string)
+					continue;
+
+				str = json_object_get_string(subnode);
+				cb(key, str, data);
+			}
+			break;
+		default:
+			break;
+		}
+	}
+}
+
 const char *get_field_string_json(json_object *e, const char *path)
 {
 	const char *str;
diff --git a/doc/source/handlers.rst b/doc/source/handlers.rst
index 74bf94a..c07b215 100644
--- a/doc/source/handlers.rst
+++ b/doc/source/handlers.rst
@@ -340,9 +340,7 @@  the SWU forwarder:
 			filename = "image.swu";
 			type = "swuforward";
 
-			properties: (
-			{
-				name = "url";
-				value = "http://192.168.178.41:8080";
-			});
+			properties: {
+				url = "http://192.168.178.41:8080";
+			};
 		});
diff --git a/include/parselib.h b/include/parselib.h
index 7c44a5e..b63349c 100644
--- a/include/parselib.h
+++ b/include/parselib.h
@@ -27,6 +27,9 @@  typedef enum {
 	JSON_PARSER
 } parsertype;
 
+typedef void (*iterate_callback)(const char *name, const char *value,
+				 void *data);
+
 #ifdef CONFIG_LIBCONFIG
 #include <libconfig.h>
 #define LIBCONFIG_VERSION ((LIBCONFIG_VER_MAJOR << 16) | \
@@ -38,6 +41,8 @@  typedef enum {
 void get_value_libconfig(const config_setting_t *e, void *dest);
 void get_field_cfg(config_setting_t *e, const char *path, void *dest);
 void *get_child_libconfig(void *e, const char *name);
+void iterate_field_libconfig(config_setting_t *e, iterate_callback cb,
+			     void *data);
 const char *get_field_string_libconfig(config_setting_t *e, const char *path);
 
 #else
@@ -47,6 +52,7 @@  const char *get_field_string_libconfig(config_setting_t *e, const char *path);
 #define find_node_libconfig(cfg, field, swcfg) (NULL)
 #define get_field_string_libconfig(e, path)	(NULL)
 #define get_child_libconfig(e, name)		(NULL)
+#define iterate_field_libconfig(e, cb, data)	(0)
 #define get_field_cfg(e, path, dest)
 #endif
 
@@ -57,6 +63,7 @@  const char *get_field_string_json(json_object *e, const char *path);
 void get_value_json(json_object *e, void *dest);
 void get_field_json(json_object *e, const char *path, void *dest);
 void *get_child_json(json_object *e, const char *name);
+void iterate_field_json(json_object *e, iterate_callback cb, void *data);
 json_object *find_json_recursive_node(json_object *root, const char **names);
 json_object *json_get_key(json_object *json_root, const char *key);
 const char *json_get_value(struct json_object *json_root,
@@ -68,6 +75,7 @@  char *json_get_data_url(json_object *json_root, const char *key);
 #define find_node_json(a, b, c)		(NULL)
 #define get_field_string_json(e, path)  (NULL)
 #define get_child_json(e, name)		(NULL)
+#define iterate_field_json(e, cb, data)	(0)
 #define get_field_json(e, path, dest)
 #define json_object_object_get_ex(a,b,c) (0)
 #define json_object_array_get_idx(a, b)	(0)
@@ -82,6 +90,7 @@  void get_field_string_with_size(parsertype p, void *e, const char *path,
 int get_array_length(parsertype p, void *root);
 void *get_elem_from_idx(parsertype p, void *node, int idx);
 void *get_child(parsertype p, void *node, const char *name);
+void iterate_field(parsertype p, void *e, iterate_callback cb, void *data);
 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);
diff --git a/parser/parser.c b/parser/parser.c
index 3ecc2da..9a60181 100644
--- a/parser/parser.c
+++ b/parser/parser.c
@@ -152,32 +152,27 @@  static void *find_node(parsertype p, void *root, const char *node,
 	return NULL;
 }
 
-static void add_properties(parsertype p, void *node, struct img_type *image)
+static void add_properties_cb(const char *name, const char *value, void *data)
 {
+	struct img_type *image = (struct img_type *)data;
 
-	void *properties, *prop;
-	int count, i;
+	if (!name || !value)
+		return;
+
+	TRACE("\t\tProperty %s: %s", name, value);
+	if (dict_insert_value(&image->properties, (char *)name, (char *)value))
+		ERROR("Property not stored, skipping...");
+}
+
+static void add_properties(parsertype p, void *node, struct img_type *image)
+{
+	void *properties;
 
 	properties = get_child(p, node, "properties");
 	if (properties) {
-		count = get_array_length(p, properties);
-
-		TRACE("Found %d properties for %s:", count, image->fname);
-
-		for (i = 0; i < count; i++) {
-			char key[255];
-			char value[255];
-			prop = get_elem_from_idx(p, properties, i);
-			GET_FIELD_STRING(p, prop, "name", key);
-			GET_FIELD_STRING(p, prop, "value", value);
-			TRACE("\t\tProperty %d: name=%s val=%s ", i,
-				key,
-				value
-			);
-			if (dict_insert_value(&image->properties, key, value))
-				ERROR("Property not stored, skipping...");
+		TRACE("Found properties for %s:", image->fname);
 
-		}
+		iterate_field(p, properties, add_properties_cb, image);
 	}
 }