diff mbox series

[v3,5/7] docparse: Add type normalization

Message ID 20211103120233.20728-6-chrubis@suse.cz
State Accepted
Headers show
Series docparse improvements | expand

Commit Message

Cyril Hrubis Nov. 3, 2021, 12:02 p.m. UTC
For now just for .test_variants.

There are two reasons for this:

- This code makes sure that we get right value parsed and aborts the
  compilation if the parser got confused. This part is important since
  if the testrunners are going to use the metadata the data in there
  must be correct.

- And much less important it makes the resulting json nicer to read

Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
Reviewed-by: Richard Palethorpe <rpalethorpe@suse.com>
---
 docparse/data_storage.h               | 16 ++++++++
 docparse/docparse.c                   | 59 +++++++++++++++++++++++++++
 docparse/tests/include.c.json         |  2 +-
 docparse/tests/macro.c.json           |  2 +-
 docparse/tests/multiline_macro.c.json |  2 +-
 5 files changed, 78 insertions(+), 3 deletions(-)

Comments

Petr Vorel Nov. 4, 2021, 8:46 p.m. UTC | #1
Hi Cyril,

> For now just for .test_variants.

> There are two reasons for this:

> - This code makes sure that we get right value parsed and aborts the
>   compilation if the parser got confused. This part is important since
>   if the testrunners are going to use the metadata the data in there
>   must be correct.
Very good idea.

> - And much less important it makes the resulting json nicer to read

...
> +static void convert_str2int(struct data_node *res, const char *id, const char *str_val)
> +{
> +	long val;
> +	char *endptr;
> +
> +	errno = 0;
> +	val = strtol(str_val, &endptr, 10);
> +
> +	if (errno || *endptr) {
> +		fprintf(stderr,	"Cannot convert %s value %s to int!", id, str_val);
=> missing \n.
> +		exit(1);
> +	}
> +
> +	if (verbose)
> +		fprintf(stderr, "NORMALIZING %s TO INT %li", id, val);
And here.
> +
> +	data_node_hash_del(res, id);
> +	data_node_hash_add(res, id, data_node_int(val));
> +}
> +
> +static void check_normalize_types(struct data_node *res)
> +{
> +	unsigned int i;
> +
> +	for (i = 0; tst_test_typemap[i].id; i++) {
> +		struct data_node *n;
> +		struct typemap *typemap = &tst_test_typemap[i];
> +
> +		n = data_node_hash_get(res, typemap->id);
> +		if (!n)
> +			continue;
> +
> +		if (n->type == typemap->type)
> +			continue;
> +
> +		if (n->type == DATA_STRING && typemap->type == DATA_INT) {
> +			convert_str2int(res, typemap->id, n->string.val);
> +			continue;
> +		}
> +
> +		fprintf(stderr, "Cannot convert %s from %s to %s!",
And here.
> +			typemap->id, data_type_name(n->type),
> +			data_type_name(typemap->type));
> +		exit(1);
> +	}
> +}

Reviewed-by: Petr Vorel <pvorel@suse.cz>

Kind regards,
Petr
diff mbox series

Patch

diff --git a/docparse/data_storage.h b/docparse/data_storage.h
index 117c1d127..91ea70a02 100644
--- a/docparse/data_storage.h
+++ b/docparse/data_storage.h
@@ -57,6 +57,22 @@  struct data_node {
 	};
 };
 
+static inline const char* data_type_name(enum data_type type)
+{
+	switch (type) {
+	case DATA_ARRAY:
+		return "array";
+	case DATA_HASH:
+		return "hash";
+	case DATA_STRING:
+		return "string";
+	case DATA_INT:
+		return "int";
+	default:
+		return "???";
+	}
+}
+
 static inline struct data_node *data_node_string(const char *string)
 {
 	size_t size = sizeof(struct data_node_string) + strlen(string) + 1;
diff --git a/docparse/docparse.c b/docparse/docparse.c
index bef56d004..733558c47 100644
--- a/docparse/docparse.c
+++ b/docparse/docparse.c
@@ -12,6 +12,7 @@ 
 #include <libgen.h>
 #include <ctype.h>
 #include <unistd.h>
+#include <errno.h>
 
 #include "data_storage.h"
 
@@ -721,6 +722,61 @@  static struct data_node *parse_file(const char *fname)
 	return res;
 }
 
+static struct typemap {
+	const char *id;
+	enum data_type type;
+} tst_test_typemap[] = {
+	{.id = "test_variants", .type = DATA_INT},
+	{}
+};
+
+static void convert_str2int(struct data_node *res, const char *id, const char *str_val)
+{
+	long val;
+	char *endptr;
+
+	errno = 0;
+	val = strtol(str_val, &endptr, 10);
+
+	if (errno || *endptr) {
+		fprintf(stderr,	"Cannot convert %s value %s to int!", id, str_val);
+		exit(1);
+	}
+
+	if (verbose)
+		fprintf(stderr, "NORMALIZING %s TO INT %li", id, val);
+
+	data_node_hash_del(res, id);
+	data_node_hash_add(res, id, data_node_int(val));
+}
+
+static void check_normalize_types(struct data_node *res)
+{
+	unsigned int i;
+
+	for (i = 0; tst_test_typemap[i].id; i++) {
+		struct data_node *n;
+		struct typemap *typemap = &tst_test_typemap[i];
+
+		n = data_node_hash_get(res, typemap->id);
+		if (!n)
+			continue;
+
+		if (n->type == typemap->type)
+			continue;
+
+		if (n->type == DATA_STRING && typemap->type == DATA_INT) {
+			convert_str2int(res, typemap->id, n->string.val);
+			continue;
+		}
+
+		fprintf(stderr, "Cannot convert %s from %s to %s!",
+			typemap->id, data_type_name(n->type),
+			data_type_name(typemap->type));
+		exit(1);
+	}
+}
+
 static const char *filter_out[] = {
 	"bufs",
 	"cleanup",
@@ -822,6 +878,9 @@  int main(int argc, char *argv[])
 		}
 	}
 
+	/* Normalize types */
+	check_normalize_types(res);
+
 	for (i = 0; implies[i].flag; i++) {
 		if (data_node_hash_get(res, implies[i].flag)) {
 			for (j = 0; implies[i].implies[j]; j++) {
diff --git a/docparse/tests/include.c.json b/docparse/tests/include.c.json
index b4ef1ccda..b7c636e82 100644
--- a/docparse/tests/include.c.json
+++ b/docparse/tests/include.c.json
@@ -1,4 +1,4 @@ 
   "include": {
-   "test_variants": "10",
+   "test_variants": 10,
    "fname": "include.c"
   }
\ No newline at end of file
diff --git a/docparse/tests/macro.c.json b/docparse/tests/macro.c.json
index 0dc73d8ec..c3f53ae43 100644
--- a/docparse/tests/macro.c.json
+++ b/docparse/tests/macro.c.json
@@ -1,4 +1,4 @@ 
   "macro": {
-   "test_variants": "10",
+   "test_variants": 10,
    "fname": "macro.c"
   }
\ No newline at end of file
diff --git a/docparse/tests/multiline_macro.c.json b/docparse/tests/multiline_macro.c.json
index bafd037da..634516242 100644
--- a/docparse/tests/multiline_macro.c.json
+++ b/docparse/tests/multiline_macro.c.json
@@ -1,4 +1,4 @@ 
   "multiline_macro": {
-   "test_variants": "10",
+   "test_variants": 10,
    "fname": "multiline_macro.c"
   }
\ No newline at end of file