ltp.lists.linux.it archive mirror
 help / color / mirror / Atom feed
* [LTP] [PATCH 0/7] docparse improvements
@ 2021-10-18 15:47 Cyril Hrubis
  2021-10-18 15:47 ` [LTP] [PATCH 1/7] docparse: Implement #define and #include Cyril Hrubis
                   ` (8 more replies)
  0 siblings, 9 replies; 30+ messages in thread
From: Cyril Hrubis @ 2021-10-18 15:47 UTC (permalink / raw)
  To: ltp

Implement support for various missing bits to the docparse tool and
enables it unconditionally so that the metadata.json file is present on
all builds.

This is first part of bigger effort to get the metadata useful for the
testrunners, expecially we need the .test_variants field to be properly
parsed in order to compute the overall test runtime correctly.

Cyril Hrubis (7):
  docparse: Implement #define and #include
  docparse: Add tests
  docparse: data_storage: Add integer type node
  docparse: Implement ARRAY_SIZE()
  docparse: Add type normalization
  docparse: Group data to 'testsuite' and 'defaults'
  docparse/Makefile: Do not abort on missing generators

 Makefile                             |   5 +-
 docparse/Makefile                    |   4 -
 docparse/data_storage.h              |  45 +++
 docparse/docparse.c                  | 466 ++++++++++++++++++++++++++-
 docparse/parse.sh                    |  18 +-
 docparse/testinfo.pl                 |  16 +-
 docparse/tests/array_size01.c        |   5 +
 docparse/tests/array_size01.c.out    |   4 +
 docparse/tests/array_size02.c        |   5 +
 docparse/tests/array_size02.c.out    |   4 +
 docparse/tests/array_size03.c        |  10 +
 docparse/tests/array_size03.c.out    |   4 +
 docparse/tests/array_size04.c        |   5 +
 docparse/tests/array_size04.c.out    |   4 +
 docparse/tests/empty_struct.c        |   2 +
 docparse/tests/empty_struct.c.out    |   3 +
 docparse/tests/expand_flags.c        |   3 +
 docparse/tests/expand_flags.c.out    |   6 +
 docparse/tests/include.c             |   5 +
 docparse/tests/include.c.out         |   4 +
 docparse/tests/include.h             |   7 +
 docparse/tests/macro.c               |   5 +
 docparse/tests/macro.c.out           |   4 +
 docparse/tests/multiline_macro.c     |   6 +
 docparse/tests/multiline_macro.c.out |   4 +
 docparse/tests/tags.c                |   7 +
 docparse/tests/tags.c.out            |  13 +
 docparse/tests/test.sh               |  18 ++
 m4/ltp-docparse.m4                   |   3 -
 29 files changed, 644 insertions(+), 41 deletions(-)
 create mode 100644 docparse/tests/array_size01.c
 create mode 100644 docparse/tests/array_size01.c.out
 create mode 100644 docparse/tests/array_size02.c
 create mode 100644 docparse/tests/array_size02.c.out
 create mode 100644 docparse/tests/array_size03.c
 create mode 100644 docparse/tests/array_size03.c.out
 create mode 100644 docparse/tests/array_size04.c
 create mode 100644 docparse/tests/array_size04.c.out
 create mode 100644 docparse/tests/empty_struct.c
 create mode 100644 docparse/tests/empty_struct.c.out
 create mode 100644 docparse/tests/expand_flags.c
 create mode 100644 docparse/tests/expand_flags.c.out
 create mode 100644 docparse/tests/include.c
 create mode 100644 docparse/tests/include.c.out
 create mode 100644 docparse/tests/include.h
 create mode 100644 docparse/tests/macro.c
 create mode 100644 docparse/tests/macro.c.out
 create mode 100644 docparse/tests/multiline_macro.c
 create mode 100644 docparse/tests/multiline_macro.c.out
 create mode 100644 docparse/tests/tags.c
 create mode 100644 docparse/tests/tags.c.out
 create mode 100755 docparse/tests/test.sh

-- 
2.32.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [LTP] [PATCH 1/7] docparse: Implement #define and #include
  2021-10-18 15:47 [LTP] [PATCH 0/7] docparse improvements Cyril Hrubis
@ 2021-10-18 15:47 ` Cyril Hrubis
  2021-10-29  8:26   ` Petr Vorel
  2021-10-29  8:27   ` Petr Vorel
  2021-10-18 15:47 ` [LTP] [PATCH 2/7] docparse: Add tests Cyril Hrubis
                   ` (7 subsequent siblings)
  8 siblings, 2 replies; 30+ messages in thread
From: Cyril Hrubis @ 2021-10-18 15:47 UTC (permalink / raw)
  To: ltp

We ignore most of the include statements and we attempt to parse only
header files that reside in the same directory as the test source code,
that is since we are not interested in any system or library headers as
we are only looking for constants used in the tst_test structure that
are always either directly in the test source or in header in the same
directory.

The macro support is very simple as well, it's a single pass as we are
not interested in intricate macros. We just need values for constants
that are used in the tst_test structure intializations.

+ Also add -v verbose mode that prints included files and defined macros

Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
 docparse/docparse.c | 219 ++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 209 insertions(+), 10 deletions(-)

diff --git a/docparse/docparse.c b/docparse/docparse.c
index 8cd0d0eef..cab01c384 100644
--- a/docparse/docparse.c
+++ b/docparse/docparse.c
@@ -1,9 +1,12 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 /*
- * Copyright (c) 2019 Cyril Hrubis <chrubis@suse.cz>
+ * Copyright (c) 2019-2021 Cyril Hrubis <chrubis@suse.cz>
  * Copyright (c) 2020 Petr Vorel <pvorel@suse.cz>
  */
 
+#define _GNU_SOURCE
+
+#include <search.h>
 #include <stdio.h>
 #include <string.h>
 #include <libgen.h>
@@ -12,6 +15,8 @@
 
 #include "data_storage.h"
 
+static int verbose;
+
 #define WARN(str) fprintf(stderr, "WARNING: " str "\n")
 
 static void oneline_comment(FILE *f)
@@ -126,7 +131,7 @@ static void maybe_comment(FILE *f, struct data_node *doc)
 	}
 }
 
-const char *next_token(FILE *f, struct data_node *doc)
+static char *next_token(FILE *f, struct data_node *doc)
 {
 	size_t i = 0;
 	static char buf[4096];
@@ -172,6 +177,7 @@ const char *next_token(FILE *f, struct data_node *doc)
 		case '.':
 		case '_':
 		case '-':
+		case '#':
 			buf[i++] = c;
 		break;
 		case '/':
@@ -197,6 +203,46 @@ exit:
 	return buf;
 }
 
+static FILE *open_include(const char *includepath, FILE *f)
+{
+	char buf[256];
+	char *path;
+	FILE *inc;
+
+	if (!fscanf(f, "%s\n", buf))
+		return NULL;
+
+	if (buf[0] != '"')
+		return NULL;
+
+	char *filename = buf + 1;
+
+	if (!buf[0])
+		return NULL;
+
+	filename[strlen(filename)-1] = 0;
+
+	if (asprintf(&path, "%s/%s", includepath, filename) < 0)
+		return NULL;
+
+	inc = fopen(path, "r");
+
+	if (inc && verbose)
+		fprintf(stderr, "INCLUDE %s\n", path);
+
+	free(path);
+
+	return inc;
+}
+
+static void close_include(FILE *inc)
+{
+	if (verbose)
+		fprintf(stderr, "INCLUDE END\n");
+
+	fclose(inc);
+}
+
 static int parse_array(FILE *f, struct data_node *node)
 {
 	const char *token;
@@ -234,9 +280,28 @@ static int parse_array(FILE *f, struct data_node *node)
 	return 0;
 }
 
+static void try_apply_macro(char **res)
+{
+	ENTRY macro = {
+		.key = *res,
+	};
+
+	ENTRY *ret;
+
+	ret = hsearch(macro, FIND);
+
+	if (!ret)
+		return;
+
+	if (verbose)
+		fprintf(stderr, "APPLYING MACRO %s=%s\n", ret->key, (char*)ret->data);
+
+	*res = ret->data;
+}
+
 static int parse_test_struct(FILE *f, struct data_node *doc, struct data_node *node)
 {
-	const char *token;
+	char *token;
 	char *id = NULL;
 	int state = 0;
 	struct data_node *ret;
@@ -280,6 +345,7 @@ static int parse_test_struct(FILE *f, struct data_node *doc, struct data_node *n
 			ret = data_node_array();
 			parse_array(f, ret);
 		} else {
+			try_apply_macro(&token);
 			ret = data_node_string(token);
 		}
 
@@ -302,6 +368,103 @@ static const char *tokens[] = {
 	"{",
 };
 
+static void macro_get_string(FILE *f, char *buf, char *buf_end)
+{
+	int c;
+
+	for (;;) {
+		c = fgetc(f);
+
+		switch (c) {
+		case '"':
+		case EOF:
+			*buf = 0;
+			return;
+		default:
+			if (buf < buf_end)
+				*(buf++) = c;
+		}
+	}
+}
+
+static void macro_get_val(FILE *f, char *buf, size_t buf_len)
+{
+	int c, prev = 0;
+	char *buf_end = buf + buf_len - 1;
+
+	c = fgetc(f);
+	if (c == '"') {
+		macro_get_string(f, buf, buf_end);
+		return;
+	}
+
+	for (;;) {
+		switch (c) {
+		case '\n':
+			if (prev == '\\') {
+				buf--;
+			} else {
+				*buf = 0;
+				return;
+			}
+		break;
+		case EOF:
+			*buf = 0;
+			return;
+		case ' ':
+		case '\t':
+		break;
+		default:
+			if (buf < buf_end)
+				*(buf++) = c;
+		}
+
+		prev = c;
+		c = fgetc(f);
+	}
+}
+
+static void parse_macro(FILE *f)
+{
+	char name[128];
+	char val[256];
+
+	if (!fscanf(f, "%s[^\n]", name))
+		return;
+
+	if (fgetc(f) == '\n')
+		return;
+
+	macro_get_val(f, val, sizeof(val));
+
+	ENTRY e = {
+		.key = strdup(name),
+		.data = strdup(val),
+	};
+
+	if (verbose)
+		fprintf(stderr, " MACRO %s=%s\n", e.key, (char*)e.data);
+
+	hsearch(e, ENTER);
+}
+
+static void parse_include_macros(const char *includepath, FILE *f)
+{
+	FILE *inc;
+	const char *token;
+
+	inc = open_include(includepath, f);
+	if (!inc)
+		return;
+
+	while ((token = next_token(inc, NULL))) {
+		if (!strcmp(token, "#define"))
+			parse_macro(inc);
+	}
+
+	close_include(inc);
+}
+
 static struct data_node *parse_file(const char *fname)
 {
 	int state = 0, found = 0;
@@ -314,14 +477,25 @@ static struct data_node *parse_file(const char *fname)
 
 	FILE *f = fopen(fname, "r");
 
+	const char *includepath = dirname(strdup(fname));
+
 	struct data_node *res = data_node_hash();
 	struct data_node *doc = data_node_array();
 
 	while ((token = next_token(f, doc))) {
-		if (state < 6 && !strcmp(tokens[state], token))
+		if (state < 6 && !strcmp(tokens[state], token)) {
 			state++;
-		else
+		} else {
+			if (token[0] == '#') {
+				if (!strcmp(token, "#define"))
+					parse_macro(f);
+
+				if (!strcmp(token, "#include"))
+					parse_include_macros(includepath, f);
+			}
+
 			state = 0;
+		}
 
 		if (state < 6)
 			continue;
@@ -386,17 +560,42 @@ const char *strip_name(char *path)
 	return name;
 }
 
+static void print_help(const char *prgname)
+{
+	printf("usage: %s [-vh] input.c\n\n", prgname);
+	printf("-v sets verbose mode\n");
+	printf("-h prints this help\n\n");
+	exit(0);
+}
+
 int main(int argc, char *argv[])
 {
 	unsigned int i, j;
 	struct data_node *res;
+	int opt;
+
+	while ((opt = getopt(argc, argv, "hv")) != -1) {
+		switch (opt) {
+		case 'h':
+			print_help(argv[0]);
+		break;
+		case 'v':
+			verbose = 1;
+		break;
+		}
+	}
+
+	if (optind >= argc) {
+		fprintf(stderr, "No input filename.c\n");
+		return 1;
+	}
 
-	if (argc != 2) {
-		fprintf(stderr, "Usage: docparse filename.c\n");
+	if (!hcreate(128)) {
+		fprintf(stderr, "Failed to initialize hash table\n");
 		return 1;
 	}
 
-	res = parse_file(argv[1]);
+	res = parse_file(argv[optind]);
 	if (!res)
 		return 0;
 
@@ -425,8 +624,8 @@ int main(int argc, char *argv[])
 		}
 	}
 
-	data_node_hash_add(res, "fname", data_node_string(argv[1]));
-	printf("  \"%s\": ", strip_name(argv[1]));
+	data_node_hash_add(res, "fname", data_node_string(argv[optind]));
+	printf("  \"%s\": ", strip_name(argv[optind]));
 	data_to_json(res, stdout, 2);
 	data_node_free(res);
 
-- 
2.32.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [LTP] [PATCH 2/7] docparse: Add tests
  2021-10-18 15:47 [LTP] [PATCH 0/7] docparse improvements Cyril Hrubis
  2021-10-18 15:47 ` [LTP] [PATCH 1/7] docparse: Implement #define and #include Cyril Hrubis
@ 2021-10-18 15:47 ` Cyril Hrubis
  2021-10-22 11:32   ` Petr Vorel
  2021-10-22 11:41   ` Petr Vorel
  2021-10-18 15:47 ` [LTP] [PATCH 3/7] docparse: data_storage: Add integer type node Cyril Hrubis
                   ` (6 subsequent siblings)
  8 siblings, 2 replies; 30+ messages in thread
From: Cyril Hrubis @ 2021-10-18 15:47 UTC (permalink / raw)
  To: ltp

This add a simple tests for the docparse parser.

Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
 docparse/tests/empty_struct.c        |  2 ++
 docparse/tests/empty_struct.c.out    |  3 +++
 docparse/tests/expand_flags.c        |  3 +++
 docparse/tests/expand_flags.c.out    |  6 ++++++
 docparse/tests/include.c             |  5 +++++
 docparse/tests/include.c.out         |  4 ++++
 docparse/tests/include.h             |  1 +
 docparse/tests/macro.c               |  5 +++++
 docparse/tests/macro.c.out           |  4 ++++
 docparse/tests/multiline_macro.c     |  6 ++++++
 docparse/tests/multiline_macro.c.out |  4 ++++
 docparse/tests/tags.c                |  7 +++++++
 docparse/tests/tags.c.out            | 13 +++++++++++++
 docparse/tests/test.sh               | 18 ++++++++++++++++++
 14 files changed, 81 insertions(+)
 create mode 100644 docparse/tests/empty_struct.c
 create mode 100644 docparse/tests/empty_struct.c.out
 create mode 100644 docparse/tests/expand_flags.c
 create mode 100644 docparse/tests/expand_flags.c.out
 create mode 100644 docparse/tests/include.c
 create mode 100644 docparse/tests/include.c.out
 create mode 100644 docparse/tests/include.h
 create mode 100644 docparse/tests/macro.c
 create mode 100644 docparse/tests/macro.c.out
 create mode 100644 docparse/tests/multiline_macro.c
 create mode 100644 docparse/tests/multiline_macro.c.out
 create mode 100644 docparse/tests/tags.c
 create mode 100644 docparse/tests/tags.c.out
 create mode 100755 docparse/tests/test.sh

diff --git a/docparse/tests/empty_struct.c b/docparse/tests/empty_struct.c
new file mode 100644
index 000000000..e5d986413
--- /dev/null
+++ b/docparse/tests/empty_struct.c
@@ -0,0 +1,2 @@
+static struct tst_test test = {
+};
diff --git a/docparse/tests/empty_struct.c.out b/docparse/tests/empty_struct.c.out
new file mode 100644
index 000000000..9f49f5332
--- /dev/null
+++ b/docparse/tests/empty_struct.c.out
@@ -0,0 +1,3 @@
+  "empty_struct": {
+   "fname": "empty_struct.c"
+  }
\ No newline at end of file
diff --git a/docparse/tests/expand_flags.c b/docparse/tests/expand_flags.c
new file mode 100644
index 000000000..64f6da64e
--- /dev/null
+++ b/docparse/tests/expand_flags.c
@@ -0,0 +1,3 @@
+static struct tst_test test = {
+	.all_filesystems = 1,
+};
diff --git a/docparse/tests/expand_flags.c.out b/docparse/tests/expand_flags.c.out
new file mode 100644
index 000000000..cd79dd296
--- /dev/null
+++ b/docparse/tests/expand_flags.c.out
@@ -0,0 +1,6 @@
+  "expand_flags": {
+   "all_filesystems": "1",
+   "needs_device": "1",
+   "needs_tmpdir": "1",
+   "fname": "expand_flags.c"
+  }
\ No newline at end of file
diff --git a/docparse/tests/include.c b/docparse/tests/include.c
new file mode 100644
index 000000000..7a35e3bb4
--- /dev/null
+++ b/docparse/tests/include.c
@@ -0,0 +1,5 @@
+#include "include.h"
+
+static struct tst_test test = {
+	.test_variants = TEST_VARIANTS,
+};
diff --git a/docparse/tests/include.c.out b/docparse/tests/include.c.out
new file mode 100644
index 000000000..b4ef1ccda
--- /dev/null
+++ b/docparse/tests/include.c.out
@@ -0,0 +1,4 @@
+  "include": {
+   "test_variants": "10",
+   "fname": "include.c"
+  }
\ No newline at end of file
diff --git a/docparse/tests/include.h b/docparse/tests/include.h
new file mode 100644
index 000000000..efa11d24f
--- /dev/null
+++ b/docparse/tests/include.h
@@ -0,0 +1 @@
+#define TEST_VARIANTS 10
diff --git a/docparse/tests/macro.c b/docparse/tests/macro.c
new file mode 100644
index 000000000..296da12f5
--- /dev/null
+++ b/docparse/tests/macro.c
@@ -0,0 +1,5 @@
+#define TEST_VARIANTS 10
+
+static struct tst_test test = {
+	.test_variants = TEST_VARIANTS,
+};
diff --git a/docparse/tests/macro.c.out b/docparse/tests/macro.c.out
new file mode 100644
index 000000000..0dc73d8ec
--- /dev/null
+++ b/docparse/tests/macro.c.out
@@ -0,0 +1,4 @@
+  "macro": {
+   "test_variants": "10",
+   "fname": "macro.c"
+  }
\ No newline at end of file
diff --git a/docparse/tests/multiline_macro.c b/docparse/tests/multiline_macro.c
new file mode 100644
index 000000000..2de58112b
--- /dev/null
+++ b/docparse/tests/multiline_macro.c
@@ -0,0 +1,6 @@
+#define TEST_VARIANTS \
+	10
+
+static struct tst_test test = {
+	.test_variants = TEST_VARIANTS,
+};
diff --git a/docparse/tests/multiline_macro.c.out b/docparse/tests/multiline_macro.c.out
new file mode 100644
index 000000000..bafd037da
--- /dev/null
+++ b/docparse/tests/multiline_macro.c.out
@@ -0,0 +1,4 @@
+  "multiline_macro": {
+   "test_variants": "10",
+   "fname": "multiline_macro.c"
+  }
\ No newline at end of file
diff --git a/docparse/tests/tags.c b/docparse/tests/tags.c
new file mode 100644
index 000000000..ade3974ff
--- /dev/null
+++ b/docparse/tests/tags.c
@@ -0,0 +1,7 @@
+static struct tst_test test = {
+	.tags = (const struct tst_tag[]) {
+		{"tag-name-1", "tag-value-1"},
+		{"tag-name-2", "tag-value-2"},
+		{}
+	}
+};
diff --git a/docparse/tests/tags.c.out b/docparse/tests/tags.c.out
new file mode 100644
index 000000000..14cc14f1c
--- /dev/null
+++ b/docparse/tests/tags.c.out
@@ -0,0 +1,13 @@
+  "tags": {
+   "tags": [
+     [
+      "tag-name-1",
+      "tag-value-1"
+     ],
+     [
+      "tag-name-2",
+      "tag-value-2"
+     ]
+    ],
+   "fname": "tags.c"
+  }
\ No newline at end of file
diff --git a/docparse/tests/test.sh b/docparse/tests/test.sh
new file mode 100755
index 000000000..cc78dcae6
--- /dev/null
+++ b/docparse/tests/test.sh
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+fail=0
+
+for i in *.c; do
+	../docparse $i > out.tmp
+	if ! diff out.tmp $i.out &> /dev/null; then
+		echo "***"
+		echo "$i output differs!"
+		diff -u out.tmp $i.out
+		echo "***"
+		fail=1
+	fi
+done
+
+rm -f out.tmp
+
+exit $fail
-- 
2.32.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [LTP] [PATCH 3/7] docparse: data_storage: Add integer type node
  2021-10-18 15:47 [LTP] [PATCH 0/7] docparse improvements Cyril Hrubis
  2021-10-18 15:47 ` [LTP] [PATCH 1/7] docparse: Implement #define and #include Cyril Hrubis
  2021-10-18 15:47 ` [LTP] [PATCH 2/7] docparse: Add tests Cyril Hrubis
@ 2021-10-18 15:47 ` Cyril Hrubis
  2021-10-18 15:47 ` [LTP] [PATCH 4/7] docparse: Implement ARRAY_SIZE() Cyril Hrubis
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 30+ messages in thread
From: Cyril Hrubis @ 2021-10-18 15:47 UTC (permalink / raw)
  To: ltp

Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
 docparse/data_storage.h | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/docparse/data_storage.h b/docparse/data_storage.h
index 339450c8b..117c1d127 100644
--- a/docparse/data_storage.h
+++ b/docparse/data_storage.h
@@ -15,6 +15,7 @@ enum data_type {
 	DATA_ARRAY,
 	DATA_HASH,
 	DATA_STRING,
+	DATA_INT,
 };
 
 struct data_node_array {
@@ -41,12 +42,18 @@ struct data_node_string {
 	char val[];
 };
 
+struct data_node_int {
+	enum data_type type;
+	long val;
+};
+
 struct data_node {
 	union {
 		enum data_type type;
 		struct data_node_hash hash;
 		struct data_node_array array;
 		struct data_node_string string;
+		struct data_node_int i;
 	};
 };
 
@@ -64,6 +71,19 @@ static inline struct data_node *data_node_string(const char *string)
 	return node;
 }
 
+static inline struct data_node *data_node_int(long i)
+{
+	struct data_node *node = malloc(sizeof(struct data_node_int));
+
+	if (!node)
+		return NULL;
+
+	node->type = DATA_INT;
+	node->i.val = i;
+
+	return node;
+}
+
 #define MAX_ELEMS 100
 
 static inline struct data_node *data_node_hash(void)
@@ -122,6 +142,7 @@ static inline void data_node_free(struct data_node *self)
 
 	switch (self->type) {
 	case DATA_STRING:
+	case DATA_INT:
 	break;
 	case DATA_HASH:
 		for (i = 0; i < self->hash.elems_used; i++) {
@@ -209,6 +230,10 @@ static inline void data_node_print_(struct data_node *self, unsigned int padd)
 	unsigned int i;
 
 	switch (self->type) {
+	case DATA_INT:
+		data_print_padd(padd);
+		printf("%li\n", self->i.val);
+	break;
 	case DATA_STRING:
 		data_print_padd(padd);
 		printf("'%s'\n", self->string.val);
@@ -295,6 +320,10 @@ static inline void data_to_json_(struct data_node *self, FILE *f, unsigned int p
 	unsigned int i;
 
 	switch (self->type) {
+	case DATA_INT:
+		padd = do_padd ? padd : 0;
+		data_fprintf(f, padd, "%li", self->i.val);
+	break;
 	case DATA_STRING:
 		padd = do_padd ? padd : 0;
 		data_fprintf_esc(f, padd, self->string.val);
-- 
2.32.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [LTP] [PATCH 4/7] docparse: Implement ARRAY_SIZE()
  2021-10-18 15:47 [LTP] [PATCH 0/7] docparse improvements Cyril Hrubis
                   ` (2 preceding siblings ...)
  2021-10-18 15:47 ` [LTP] [PATCH 3/7] docparse: data_storage: Add integer type node Cyril Hrubis
@ 2021-10-18 15:47 ` Cyril Hrubis
  2021-11-01 12:36   ` Richard Palethorpe
  2021-10-18 15:47 ` [LTP] [PATCH 5/7] docparse: Add type normalization Cyril Hrubis
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 30+ messages in thread
From: Cyril Hrubis @ 2021-10-18 15:47 UTC (permalink / raw)
  To: ltp

Adds a special handlingn for ARRAY_SIZE() macro.

If we stumble upon ARRAY_SIZE() in the tst_test structure we try to
lookup the array and count its members.

Proper parsing of .test_variants also requires that we add -I switch to
the docparse to be able to specify include paths on a command line since
some variants are stuck in top level include while others are in
testcases/kernel/syscalls/utils/.

+ tests

Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
 docparse/docparse.c               | 222 +++++++++++++++++++++++++++---
 docparse/parse.sh                 |   2 +-
 docparse/tests/array_size01.c     |   5 +
 docparse/tests/array_size01.c.out |   4 +
 docparse/tests/array_size02.c     |   5 +
 docparse/tests/array_size02.c.out |   4 +
 docparse/tests/array_size03.c     |  10 ++
 docparse/tests/array_size03.c.out |   4 +
 docparse/tests/array_size04.c     |   5 +
 docparse/tests/array_size04.c.out |   4 +
 docparse/tests/include.h          |   6 +
 11 files changed, 248 insertions(+), 23 deletions(-)
 create mode 100644 docparse/tests/array_size01.c
 create mode 100644 docparse/tests/array_size01.c.out
 create mode 100644 docparse/tests/array_size02.c
 create mode 100644 docparse/tests/array_size02.c.out
 create mode 100644 docparse/tests/array_size03.c
 create mode 100644 docparse/tests/array_size03.c.out
 create mode 100644 docparse/tests/array_size04.c
 create mode 100644 docparse/tests/array_size04.c.out

diff --git a/docparse/docparse.c b/docparse/docparse.c
index cab01c384..9a1ed830c 100644
--- a/docparse/docparse.c
+++ b/docparse/docparse.c
@@ -15,7 +15,12 @@
 
 #include "data_storage.h"
 
+#define INCLUDE_PATH_MAX 5
+
 static int verbose;
+static char *cmdline_includepath[INCLUDE_PATH_MAX];
+static unsigned int cmdline_includepaths;
+static char *includepath;
 
 #define WARN(str) fprintf(stderr, "WARNING: " str "\n")
 
@@ -131,13 +136,14 @@ static void maybe_comment(FILE *f, struct data_node *doc)
 	}
 }
 
-static char *next_token(FILE *f, struct data_node *doc)
+static char *next_token2(FILE *f, char *buf, size_t buf_len, struct data_node *doc)
 {
 	size_t i = 0;
-	static char buf[4096];
 	int c;
 	int in_str = 0;
 
+	buf_len--;
+
 	for (;;) {
 		c = fgetc(f);
 
@@ -150,7 +156,8 @@ static char *next_token(FILE *f, struct data_node *doc)
 					goto exit;
 			}
 
-			buf[i++] = c;
+			if (i < buf_len)
+				buf[i++] = c;
 			continue;
 		}
 
@@ -169,7 +176,8 @@ static char *next_token(FILE *f, struct data_node *doc)
 				goto exit;
 			}
 
-			buf[i++] = c;
+			if (i < buf_len)
+				buf[i++] = c;
 			goto exit;
 		case '0' ... '9':
 		case 'a' ... 'z':
@@ -178,7 +186,8 @@ static char *next_token(FILE *f, struct data_node *doc)
 		case '_':
 		case '-':
 		case '#':
-			buf[i++] = c;
+			if (i < buf_len)
+				buf[i++] = c;
 		break;
 		case '/':
 			maybe_comment(f, doc);
@@ -203,11 +212,33 @@ exit:
 	return buf;
 }
 
-static FILE *open_include(const char *includepath, FILE *f)
+static char *next_token(FILE *f, struct data_node *doc)
 {
-	char buf[256];
+	static char buf[4096];
+
+	return next_token2(f, buf, sizeof(buf), doc);
+}
+
+static FILE *open_file(const char *dir, const char *fname)
+{
+	FILE *f;
 	char *path;
+
+	if (asprintf(&path, "%s/%s", dir, fname) < 0)
+		return NULL;
+
+	f = fopen(path, "r");
+
+	free(path);
+
+	return f;
+}
+
+static FILE *open_include(FILE *f)
+{
+	char buf[256], *fname;
 	FILE *inc;
+	unsigned int i;
 
 	if (!fscanf(f, "%s\n", buf))
 		return NULL;
@@ -215,24 +246,36 @@ static FILE *open_include(const char *includepath, FILE *f)
 	if (buf[0] != '"')
 		return NULL;
 
-	char *filename = buf + 1;
+	fname = buf + 1;
 
 	if (!buf[0])
 		return NULL;
 
-	filename[strlen(filename)-1] = 0;
+	fname[strlen(fname)-1] = 0;
 
-	if (asprintf(&path, "%s/%s", includepath, filename) < 0)
-		return NULL;
+	inc = open_file(includepath, fname);
+	if (inc) {
+		if (verbose)
+			fprintf(stderr, "INCLUDE %s/%s\n", includepath, fname);
 
-	inc = fopen(path, "r");
+		return inc;
+	}
 
-	if (inc && verbose)
-		fprintf(stderr, "INCLUDE %s\n", path);
+	for (i = 0; i < cmdline_includepaths; i++) {
+		inc = open_file(cmdline_includepath[i], fname);
 
-	free(path);
+		if (!inc)
+			continue;
+
+		if (verbose) {
+			fprintf(stderr, "INCLUDE %s/%s\n",
+				cmdline_includepath[i], fname);
+		}
 
-	return inc;
+		return inc;
+	}
+
+	return NULL;
 }
 
 static void close_include(FILE *inc)
@@ -299,6 +342,127 @@ static void try_apply_macro(char **res)
 	*res = ret->data;
 }
 
+static int parse_get_array_len(FILE *f)
+{
+	const char *token;
+	int cnt = 0, depth = 0, prev_comma = 0;
+
+	if (!(token = next_token(f, NULL)))
+		return 0;
+
+	if (strcmp(token, "{"))
+		return 0;
+
+	for (;;) {
+		if (!(token = next_token(f, NULL)))
+			return 0;
+
+		if (!strcmp(token, "{"))
+			depth++;
+
+		if (!strcmp(token, "}"))
+			depth--;
+		else
+			prev_comma = 0;
+
+		if (!strcmp(token, ",") && !depth) {
+			prev_comma = 1;
+			cnt++;
+		}
+
+		if (depth < 0)
+			return cnt + !prev_comma;
+	}
+}
+
+static void look_for_array_size(FILE *f, const char *arr_id, struct data_node **res)
+{
+	const char *token;
+	char buf[2][2048] = {};
+	int cur_buf = 0;
+	int prev_buf = 1;
+
+	for (;;) {
+		if (!(token = next_token2(f, buf[cur_buf], 2048, NULL)))
+			break;
+
+		if (!strcmp(token, "=") && !strcmp(buf[prev_buf], arr_id)) {
+			int arr_len = parse_get_array_len(f);
+
+			if (verbose)
+				fprintf(stderr, "ARRAY %s LENGTH = %i\n", arr_id, arr_len);
+
+			*res = data_node_int(arr_len);
+
+			break;
+		}
+
+		if (strcmp(buf[cur_buf], "]") && strcmp(buf[cur_buf], "[")) {
+			cur_buf = !cur_buf;
+			prev_buf = !prev_buf;
+		}
+	}
+}
+
+static int parse_array_size(FILE *f, struct data_node **res)
+{
+	const char *token;
+	char *arr_id;
+	long pos;
+
+	*res = NULL;
+
+	if (!(token = next_token(f, NULL)))
+		return 1;
+
+	if (strcmp(token, "("))
+		return 1;
+
+	if (!(token = next_token(f, NULL)))
+		return 1;
+
+	arr_id = strdup(token);
+
+	if (verbose)
+		fprintf(stderr, "COMPUTING ARRAY '%s' LENGHT\n", arr_id);
+
+	pos = ftell(f);
+
+	rewind(f);
+
+	look_for_array_size(f, arr_id, res);
+
+	if (!*res) {
+		FILE *inc;
+
+		rewind(f);
+
+		for (;;) {
+			if (!(token = next_token(f, NULL)))
+				break;
+
+			if (!strcmp(token, "#include")) {
+				inc = open_include(f);
+
+				if (inc) {
+					look_for_array_size(inc, arr_id, res);
+					close_include(inc);
+				}
+			}
+
+			if (*res)
+				break;
+		}
+	}
+
+	free(arr_id);
+
+	if (fseek(f, pos, SEEK_SET))
+		return 1;
+
+	return 0;
+}
+
 static int parse_test_struct(FILE *f, struct data_node *doc, struct data_node *node)
 {
 	char *token;
@@ -344,11 +508,17 @@ static int parse_test_struct(FILE *f, struct data_node *doc, struct data_node *n
 		if (!strcmp(token, "{")) {
 			ret = data_node_array();
 			parse_array(f, ret);
+		} else if (!strcmp(token, "ARRAY_SIZE")) {
+			if (parse_array_size(f, &ret))
+				return 1;
 		} else {
 			try_apply_macro(&token);
 			ret = data_node_string(token);
 		}
 
+		if (!ret)
+			continue;
+
 		const char *key = id;
 		if (key[0] == '.')
 			key++;
@@ -448,12 +618,12 @@ static void parse_macro(FILE *f)
 	hsearch(e, ENTER);
 }
 
-static void parse_include_macros(const char *includepath, FILE *f)
+static void parse_include_macros(FILE *f)
 {
 	FILE *inc;
 	const char *token;
 
-	inc = open_include(includepath, f);
+	inc = open_include(f);
 	if (!inc)
 		return;
 
@@ -477,7 +647,7 @@ static struct data_node *parse_file(const char *fname)
 
 	FILE *f = fopen(fname, "r");
 
-	const char *includepath = dirname(strdup(fname));
+	includepath = dirname(strdup(fname));
 
 	struct data_node *res = data_node_hash();
 	struct data_node *doc = data_node_array();
@@ -491,7 +661,7 @@ static struct data_node *parse_file(const char *fname)
 					parse_macro(f);
 
 				if (!strcmp(token, "#include"))
-					parse_include_macros(includepath, f);
+					parse_include_macros(f);
 			}
 
 			state = 0;
@@ -504,7 +674,6 @@ static struct data_node *parse_file(const char *fname)
 		parse_test_struct(f, doc, res);
 	}
 
-
 	if (data_node_array_len(doc)) {
 		data_node_hash_add(res, "doc", doc);
 		found = 1;
@@ -564,6 +733,7 @@ static void print_help(const char *prgname)
 {
 	printf("usage: %s [-vh] input.c\n\n", prgname);
 	printf("-v sets verbose mode\n");
+	printf("-I add include path\n");
 	printf("-h prints this help\n\n");
 	exit(0);
 }
@@ -574,11 +744,19 @@ int main(int argc, char *argv[])
 	struct data_node *res;
 	int opt;
 
-	while ((opt = getopt(argc, argv, "hv")) != -1) {
+	while ((opt = getopt(argc, argv, "hI:v")) != -1) {
 		switch (opt) {
 		case 'h':
 			print_help(argv[0]);
 		break;
+		case 'I':
+			if (cmdline_includepaths >= INCLUDE_PATH_MAX) {
+				fprintf(stderr, "Too much include paths!");
+				exit(1);
+			}
+
+			cmdline_includepath[cmdline_includepaths++] = optarg;
+		break;
 		case 'v':
 			verbose = 1;
 		break;
diff --git a/docparse/parse.sh b/docparse/parse.sh
index 79011bc10..2ace34fa0 100755
--- a/docparse/parse.sh
+++ b/docparse/parse.sh
@@ -26,7 +26,7 @@ echo ' "tests": {'
 first=1
 
 for test in `find testcases/ -name '*.c'`; do
-	a=$($top_builddir/docparse/docparse "$test")
+	a=$($top_builddir/docparse/docparse -Iinclude -Itestcases/kernel/syscalls/utils/ "$test")
 	if [ -n "$a" ]; then
 		if [ -z "$first" ]; then
 			echo ','
diff --git a/docparse/tests/array_size01.c b/docparse/tests/array_size01.c
new file mode 100644
index 000000000..8a0b9252b
--- /dev/null
+++ b/docparse/tests/array_size01.c
@@ -0,0 +1,5 @@
+static int variants = {1};
+
+static struct tst_test test = {
+	.test_variants = ARRAY_SIZE(variants),
+};
diff --git a/docparse/tests/array_size01.c.out b/docparse/tests/array_size01.c.out
new file mode 100644
index 000000000..ec364be12
--- /dev/null
+++ b/docparse/tests/array_size01.c.out
@@ -0,0 +1,4 @@
+  "array_size01": {
+   "test_variants": 1,
+   "fname": "array_size01.c"
+  }
\ No newline at end of file
diff --git a/docparse/tests/array_size02.c b/docparse/tests/array_size02.c
new file mode 100644
index 000000000..5c7d4471e
--- /dev/null
+++ b/docparse/tests/array_size02.c
@@ -0,0 +1,5 @@
+static int variants = {{1}, {2}, {3}};
+
+static struct tst_test test = {
+	.test_variants = ARRAY_SIZE(variants),
+};
diff --git a/docparse/tests/array_size02.c.out b/docparse/tests/array_size02.c.out
new file mode 100644
index 000000000..122686952
--- /dev/null
+++ b/docparse/tests/array_size02.c.out
@@ -0,0 +1,4 @@
+  "array_size02": {
+   "test_variants": 3,
+   "fname": "array_size02.c"
+  }
\ No newline at end of file
diff --git a/docparse/tests/array_size03.c b/docparse/tests/array_size03.c
new file mode 100644
index 000000000..9058db813
--- /dev/null
+++ b/docparse/tests/array_size03.c
@@ -0,0 +1,10 @@
+static struct foo variants[] = {
+#ifdef FOO
+	{.bar = 11},
+#endif
+	{.bar = 10},
+};
+
+static struct tst_test test = {
+	.test_variants = ARRAY_SIZE(variants),
+};
diff --git a/docparse/tests/array_size03.c.out b/docparse/tests/array_size03.c.out
new file mode 100644
index 000000000..bb690c9f5
--- /dev/null
+++ b/docparse/tests/array_size03.c.out
@@ -0,0 +1,4 @@
+  "array_size03": {
+   "test_variants": 2,
+   "fname": "array_size03.c"
+  }
\ No newline at end of file
diff --git a/docparse/tests/array_size04.c b/docparse/tests/array_size04.c
new file mode 100644
index 000000000..5f1d9986e
--- /dev/null
+++ b/docparse/tests/array_size04.c
@@ -0,0 +1,5 @@
+#include "include.h"
+
+static struct tst_test test = {
+	.test_variants = ARRAY_SIZE(variants),
+};
diff --git a/docparse/tests/array_size04.c.out b/docparse/tests/array_size04.c.out
new file mode 100644
index 000000000..6b8d41792
--- /dev/null
+++ b/docparse/tests/array_size04.c.out
@@ -0,0 +1,4 @@
+  "array_size04": {
+   "test_variants": 3,
+   "fname": "array_size04.c"
+  }
\ No newline at end of file
diff --git a/docparse/tests/include.h b/docparse/tests/include.h
index efa11d24f..fbc69a561 100644
--- a/docparse/tests/include.h
+++ b/docparse/tests/include.h
@@ -1 +1,7 @@
 #define TEST_VARIANTS 10
+
+static struct variants[] = {
+	{.bar = 10},
+	{.bar = 11},
+	{.bar = 12}
+};
-- 
2.32.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [LTP] [PATCH 5/7] docparse: Add type normalization
  2021-10-18 15:47 [LTP] [PATCH 0/7] docparse improvements Cyril Hrubis
                   ` (3 preceding siblings ...)
  2021-10-18 15:47 ` [LTP] [PATCH 4/7] docparse: Implement ARRAY_SIZE() Cyril Hrubis
@ 2021-10-18 15:47 ` Cyril Hrubis
  2021-10-18 15:47 ` [LTP] [PATCH 6/7] docparse: Group data to 'testsuite' and 'defaults' Cyril Hrubis
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 30+ messages in thread
From: Cyril Hrubis @ 2021-10-18 15:47 UTC (permalink / raw)
  To: ltp

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>
---
 docparse/data_storage.h              | 16 ++++++++
 docparse/docparse.c                  | 59 ++++++++++++++++++++++++++++
 docparse/tests/include.c.out         |  2 +-
 docparse/tests/macro.c.out           |  2 +-
 docparse/tests/multiline_macro.c.out |  2 +-
 5 files changed, 78 insertions(+), 3 deletions(-)

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 9a1ed830c..63edd290e 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"
 
@@ -691,6 +692,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",
@@ -792,6 +848,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.out b/docparse/tests/include.c.out
index b4ef1ccda..b7c636e82 100644
--- a/docparse/tests/include.c.out
+++ b/docparse/tests/include.c.out
@@ -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.out b/docparse/tests/macro.c.out
index 0dc73d8ec..c3f53ae43 100644
--- a/docparse/tests/macro.c.out
+++ b/docparse/tests/macro.c.out
@@ -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.out b/docparse/tests/multiline_macro.c.out
index bafd037da..634516242 100644
--- a/docparse/tests/multiline_macro.c.out
+++ b/docparse/tests/multiline_macro.c.out
@@ -1,4 +1,4 @@
   "multiline_macro": {
-   "test_variants": "10",
+   "test_variants": 10,
    "fname": "multiline_macro.c"
   }
\ No newline at end of file
-- 
2.32.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [LTP] [PATCH 6/7] docparse: Group data to 'testsuite' and 'defaults'
  2021-10-18 15:47 [LTP] [PATCH 0/7] docparse improvements Cyril Hrubis
                   ` (4 preceding siblings ...)
  2021-10-18 15:47 ` [LTP] [PATCH 5/7] docparse: Add type normalization Cyril Hrubis
@ 2021-10-18 15:47 ` Cyril Hrubis
  2021-10-18 15:47 ` [LTP] [PATCH 7/7] docparse/Makefile: Do not abort on missing generators Cyril Hrubis
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 30+ messages in thread
From: Cyril Hrubis @ 2021-10-18 15:47 UTC (permalink / raw)
  To: ltp

Group all data belonging to testsuite info to 'testsuite' object and
move default timeout to 'defaults' object. This makes the JSON structure
a bit cleaner and easier to understand.

Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
 docparse/parse.sh    | 16 ++++++++++------
 docparse/testinfo.pl | 16 ++++++++--------
 2 files changed, 18 insertions(+), 14 deletions(-)

diff --git a/docparse/parse.sh b/docparse/parse.sh
index 2ace34fa0..52d9a5cbf 100755
--- a/docparse/parse.sh
+++ b/docparse/parse.sh
@@ -15,12 +15,16 @@ if [ -d .git ]; then
 fi
 
 echo '{'
-echo ' "testsuite": "Linux Test Project",'
-echo ' "testsuite_short": "LTP",'
-echo ' "url": "https://github.com/linux-test-project/ltp/",'
-echo ' "scm_url_base": "https://github.com/linux-test-project/ltp/tree/master/",'
-echo ' "timeout": 300,'
-echo " \"version\": \"$version\","
+echo ' "testsuite": {'
+echo '  "name": "Linux Test Project",'
+echo '  "short_name": "LTP",'
+echo '  "url": "https://github.com/linux-test-project/ltp/",'
+echo '  "scm_url_base": "https://github.com/linux-test-project/ltp/tree/master/",'
+echo "  \"version\": \"$version\""
+echo ' },'
+echo ' "defaults": {'
+echo '  "timeout": 300'
+echo ' },'
 echo ' "tests": {'
 
 first=1
diff --git a/docparse/testinfo.pl b/docparse/testinfo.pl
index c11064c05..891619532 100755
--- a/docparse/testinfo.pl
+++ b/docparse/testinfo.pl
@@ -164,9 +164,9 @@ sub content_about
 	my $json = shift;
 	my $content;
 
-	$content .= print_defined("URL", $json->{'url'});
-	$content .= print_defined("Version", $json->{'version'});
-	$content .= print_defined("Default timeout", $json->{'timeout'}, "seconds");
+	$content .= print_defined("URL", $json->{'testsuite'}->{'url'});
+	$content .= print_defined("Version", $json->{'testsuite'}->{'version'});
+	$content .= print_defined("Default timeout", $json->{'defaults'}->{'timeout'}, "seconds");
 
 	return $content;
 }
@@ -360,10 +360,10 @@ sub content_all_tests
 		$content .= h3($name);
 		$content .= $letters;
 
-		if (defined($json->{'scm_url_base'}) &&
+		if (defined($json->{'testsuite'}->{'scm_url_base'}) &&
 			defined($json->{'tests'}{$name}{fname})) {
 			$content .= paragraph(html_a(tag_url("fname", $json->{'tests'}{$name}{fname},
-					$json->{'scm_url_base'}), "source"));
+					$json->{'testsuite'}->{'scm_url_base'}), "source"));
 		}
 
 		if (defined $json->{'tests'}{$name}{doc}) {
@@ -386,7 +386,7 @@ sub content_all_tests
 				$content .= paragraph("Test timeout is $json->{'tests'}{$name}{timeout} seconds");
 			}
 		} else {
-			$content .= paragraph("Test timeout defaults to $json->{'timeout'} seconds");
+			$content .= paragraph("Test timeout defaults to $json->{'defaults'}->{'timeout'} seconds");
 		}
 
 		my $tmp2 = undef;
@@ -463,7 +463,7 @@ my $json = decode_json(load_json($ARGV[0]));
 my $config = [
     {
 		file => "about.txt",
-		title => h2("About $json->{'testsuite'}"),
+		title => h2("About $json->{'testsuite'}->{'name'}"),
 		content => \&content_about,
     },
     {
@@ -495,7 +495,7 @@ EOL
 	for my $c (@{$config}) {
 		$content .= "include::$c->{'file'}\[\]\n";
 	}
-	print_asciidoc_page($fh, $json, h1($json->{'testsuite_short'} . " test catalog"), $content);
+	print_asciidoc_page($fh, $json, h1($json->{'testsuite'}->{'short_name'} . " test catalog"), $content);
 }
 
 for my $c (@{$config}) {
-- 
2.32.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [LTP] [PATCH 7/7] docparse/Makefile: Do not abort on missing generators
  2021-10-18 15:47 [LTP] [PATCH 0/7] docparse improvements Cyril Hrubis
                   ` (5 preceding siblings ...)
  2021-10-18 15:47 ` [LTP] [PATCH 6/7] docparse: Group data to 'testsuite' and 'defaults' Cyril Hrubis
@ 2021-10-18 15:47 ` Cyril Hrubis
  2021-10-22 11:29   ` Petr Vorel
  2021-10-18 15:48 ` [LTP] [PATCH 0/7] docparse improvements Cyril Hrubis
  2021-10-27 13:22 ` Richard Palethorpe
  8 siblings, 1 reply; 30+ messages in thread
From: Cyril Hrubis @ 2021-10-18 15:47 UTC (permalink / raw)
  To: ltp

Since we want to use the metadata.json in the testrunner it must bte
build unconditionally.

Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
 Makefile           | 5 +----
 docparse/Makefile  | 4 ----
 m4/ltp-docparse.m4 | 3 ---
 3 files changed, 1 insertion(+), 11 deletions(-)

diff --git a/Makefile b/Makefile
index 4e37362f9..447525e75 100644
--- a/Makefile
+++ b/Makefile
@@ -62,10 +62,7 @@ $(1):: | $$(abs_top_builddir)/$$(basename $$(subst -,.,$(1)))
 endif
 endef
 
-COMMON_TARGETS		+= testcases tools
-ifeq ($(WITH_METADATA),yes)
-COMMON_TARGETS		+= docparse
-endif
+COMMON_TARGETS		+= testcases tools docparse
 
 # Don't want to nuke the original files if we're installing in-build-tree.
 ifneq ($(BUILD_TREE_STATE),$(BUILD_TREE_SRCDIR_INSTALL))
diff --git a/docparse/Makefile b/docparse/Makefile
index e2defad38..5f2f40544 100644
--- a/docparse/Makefile
+++ b/docparse/Makefile
@@ -18,10 +18,6 @@ METADATA_GENERATOR_PARAMS := --xsltproc-opts "--stringparam toc.section.depth 1"
 METADATA_GENERATOR_PARAMS_HTML := -f xhtml
 METADATA_GENERATOR_PARAMS_PDF := -f pdf
 METADATA_GENERATOR_PARAMS_HTML_CHUNKED := -f chunked
-else ifeq ($(METADATA_GENERATOR),)
-$(error 'METADATA_GENERATOR' not not configured, run ./configure in the root directory)
-else
-$(error '$(METADATA_GENERATOR)' not supported, only asciidoctor and asciidoc are supported)
 endif
 
 ifdef VERBOSE
diff --git a/m4/ltp-docparse.m4 b/m4/ltp-docparse.m4
index 88d2e08e4..4cdcfc071 100644
--- a/m4/ltp-docparse.m4
+++ b/m4/ltp-docparse.m4
@@ -31,7 +31,6 @@ AC_DEFUN([LTP_CHECK_METADATA_GENERATOR_ASCIIDOC], [
 ])
 
 AC_DEFUN([LTP_DOCPARSE], [
-with_metadata=no
 with_metadata_html=no
 with_metadata_pdf=no
 
@@ -96,7 +95,6 @@ elif test "x$ax_perl_modules_failed" = x1; then
 elif test "x$with_metadata_html" = xno -a "x$with_metadata_pdf" = xno; then
 	AC_MSG_WARN([$reason, $hint])
 else
-	with_metadata=yes
 	AC_SUBST(METADATA_GENERATOR, $with_metadata_generator)
 	if test "x$with_metadata_html" = xno -a "x$enable_metadata_html" = xyes; then
 		AC_MSG_WARN([HTML $reason, $hint])
@@ -106,7 +104,6 @@ else
 	fi
 fi
 
-AC_SUBST(WITH_METADATA, $with_metadata)
 AC_SUBST(WITH_METADATA_HTML, $with_metadata_html)
 AC_SUBST(WITH_METADATA_PDF, $with_metadata_pdf)
 ])
-- 
2.32.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [LTP] [PATCH 0/7] docparse improvements
  2021-10-18 15:47 [LTP] [PATCH 0/7] docparse improvements Cyril Hrubis
                   ` (6 preceding siblings ...)
  2021-10-18 15:47 ` [LTP] [PATCH 7/7] docparse/Makefile: Do not abort on missing generators Cyril Hrubis
@ 2021-10-18 15:48 ` Cyril Hrubis
  2021-10-27 13:22 ` Richard Palethorpe
  8 siblings, 0 replies; 30+ messages in thread
From: Cyril Hrubis @ 2021-10-18 15:48 UTC (permalink / raw)
  To: ltp

Implements support for various missing bits to the docparse tool and
enables it unconditionally so that the metadata.json file is present
on all builds.

This is first part of bigger effort to get the metadata useful for the
testrunners, expecially we need the .test_variants field to be properly
parsed in order to compute the overall test runtime.

Cyril Hrubis (7):
  docparse: Implement #define and #include
  docparse: Add tests
  docparse: data_storage: Add integer type node
  docparse: Implement ARRAY_SIZE()
  docparse: Add type normalization
  docparse: Group data to 'testsuite' and 'defaults'
  docparse/Makefile: Do not abort on missing generators

 Makefile                             |   5 +-
 docparse/Makefile                    |   4 -
 docparse/data_storage.h              |  45 +++
 docparse/docparse.c                  | 469 ++++++++++++++++++++++++++-
 docparse/parse.sh                    |  18 +-
 docparse/testinfo.pl                 |  16 +-
 docparse/tests/array_size01.c        |   5 +
 docparse/tests/array_size01.c.out    |   4 +
 docparse/tests/array_size02.c        |   5 +
 docparse/tests/array_size02.c.out    |   4 +
 docparse/tests/array_size03.c        |  10 +
 docparse/tests/array_size03.c.out    |   4 +
 docparse/tests/array_size04.c        |   5 +
 docparse/tests/array_size04.c.out    |   4 +
 docparse/tests/empty_struct.c        |   2 +
 docparse/tests/empty_struct.c.out    |   3 +
 docparse/tests/expand_flags.c        |   3 +
 docparse/tests/expand_flags.c.out    |   6 +
 docparse/tests/include.c             |   5 +
 docparse/tests/include.c.out         |   4 +
 docparse/tests/include.h             |   7 +
 docparse/tests/macro.c               |   5 +
 docparse/tests/macro.c.out           |   4 +
 docparse/tests/multiline_macro.c     |   6 +
 docparse/tests/multiline_macro.c.out |   4 +
 docparse/tests/tags.c                |   7 +
 docparse/tests/tags.c.out            |  13 +
 docparse/tests/test.sh               |  18 +
 m4/ltp-docparse.m4                   |   3 -
 29 files changed, 647 insertions(+), 41 deletions(-)
 create mode 100644 docparse/tests/array_size01.c
 create mode 100644 docparse/tests/array_size01.c.out
 create mode 100644 docparse/tests/array_size02.c
 create mode 100644 docparse/tests/array_size02.c.out
 create mode 100644 docparse/tests/array_size03.c
 create mode 100644 docparse/tests/array_size03.c.out
 create mode 100644 docparse/tests/array_size04.c
 create mode 100644 docparse/tests/array_size04.c.out
 create mode 100644 docparse/tests/empty_struct.c
 create mode 100644 docparse/tests/empty_struct.c.out
 create mode 100644 docparse/tests/expand_flags.c
 create mode 100644 docparse/tests/expand_flags.c.out
 create mode 100644 docparse/tests/include.c
 create mode 100644 docparse/tests/include.c.out
 create mode 100644 docparse/tests/include.h
 create mode 100644 docparse/tests/macro.c
 create mode 100644 docparse/tests/macro.c.out
 create mode 100644 docparse/tests/multiline_macro.c
 create mode 100644 docparse/tests/multiline_macro.c.out
 create mode 100644 docparse/tests/tags.c
 create mode 100644 docparse/tests/tags.c.out
 create mode 100755 docparse/tests/test.sh

-- 
2.32.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [LTP] [PATCH 7/7] docparse/Makefile: Do not abort on missing generators
  2021-10-18 15:47 ` [LTP] [PATCH 7/7] docparse/Makefile: Do not abort on missing generators Cyril Hrubis
@ 2021-10-22 11:29   ` Petr Vorel
  2021-10-25 12:48     ` Cyril Hrubis
  0 siblings, 1 reply; 30+ messages in thread
From: Petr Vorel @ 2021-10-22 11:29 UTC (permalink / raw)
  To: Cyril Hrubis; +Cc: ltp

Hi Cyril,

> Since we want to use the metadata.json in the testrunner it must bte
nit: typo s/bte/be

> build unconditionally.
According to docs:
  --with-metadata-generator=asciidoc|asciidoctor
  --disable-metadata      Disable metadata generation (both HTML and PDF,
                          default no)
  --disable-metadata-html Disable metadata HTML generation (default no)
  --enable-metadata-pdf   Enable metadata PDF generation (default no)

I'd like to have single option which does not create HTML and PDF (thus does not
require asciidoc|asciidoctor. I wonder if we could change build system to keep
--disable-metadata, build always docparse and json as we need, but with
./configured --disable-metadata just not run HTML and PDF generation?

Kind regards,
Petr

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [LTP] [PATCH 2/7] docparse: Add tests
  2021-10-18 15:47 ` [LTP] [PATCH 2/7] docparse: Add tests Cyril Hrubis
@ 2021-10-22 11:32   ` Petr Vorel
  2021-10-25 12:46     ` Cyril Hrubis
  2021-10-22 11:41   ` Petr Vorel
  1 sibling, 1 reply; 30+ messages in thread
From: Petr Vorel @ 2021-10-22 11:32 UTC (permalink / raw)
  To: Cyril Hrubis; +Cc: ltp

> This add a simple tests for the docparse parser.

Very nice, thanks! Maybe remame multiline_macro.c.out to multiline_macro.json
to get json syntax in editors? (multiline_macro.c.out.json would be ugly).

I also wanted to have perl parser which would take expected output from tests
sources put as comment, but I haven't finished Christian's effort. Thus atm it's
really better just to put files with output.

Kind regards,
Petr

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [LTP] [PATCH 2/7] docparse: Add tests
  2021-10-18 15:47 ` [LTP] [PATCH 2/7] docparse: Add tests Cyril Hrubis
  2021-10-22 11:32   ` Petr Vorel
@ 2021-10-22 11:41   ` Petr Vorel
  2021-10-25 12:51     ` Cyril Hrubis
  1 sibling, 1 reply; 30+ messages in thread
From: Petr Vorel @ 2021-10-22 11:41 UTC (permalink / raw)
  To: Cyril Hrubis; +Cc: ltp

HI Cyril,

It'd be nice, if this was run by make test.

Also I'm quite surprised by this behavior:

$ cd docparse/tests/ && make test
cat test.sh >test 
chmod a+x test

When this was added?

Kind regards,
Petr

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [LTP] [PATCH 2/7] docparse: Add tests
  2021-10-22 11:32   ` Petr Vorel
@ 2021-10-25 12:46     ` Cyril Hrubis
  2021-10-25 20:00       ` Petr Vorel
  0 siblings, 1 reply; 30+ messages in thread
From: Cyril Hrubis @ 2021-10-25 12:46 UTC (permalink / raw)
  To: Petr Vorel; +Cc: ltp

Hi!
> Very nice, thanks! Maybe remame multiline_macro.c.out to multiline_macro.json
> to get json syntax in editors? (multiline_macro.c.out.json would be ugly).

What about foo.c.json then?

-- 
Cyril Hrubis
chrubis@suse.cz

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [LTP] [PATCH 7/7] docparse/Makefile: Do not abort on missing generators
  2021-10-22 11:29   ` Petr Vorel
@ 2021-10-25 12:48     ` Cyril Hrubis
  2021-10-27  9:47       ` Petr Vorel
  0 siblings, 1 reply; 30+ messages in thread
From: Cyril Hrubis @ 2021-10-25 12:48 UTC (permalink / raw)
  To: Petr Vorel; +Cc: ltp

Hi!
> > Since we want to use the metadata.json in the testrunner it must bte
> nit: typo s/bte/be
> 
> > build unconditionally.
> According to docs:
>   --with-metadata-generator=asciidoc|asciidoctor
>   --disable-metadata      Disable metadata generation (both HTML and PDF,
>                           default no)
>   --disable-metadata-html Disable metadata HTML generation (default no)
>   --enable-metadata-pdf   Enable metadata PDF generation (default no)
> 
> I'd like to have single option which does not create HTML and PDF (thus does not
> require asciidoc|asciidoctor. I wonder if we could change build system to keep
> --disable-metadata, build always docparse and json as we need, but with
> ./configured --disable-metadata just not run HTML and PDF generation?

I'm starting to think that the docparse.c should be moved to a
metadata/paraser.c and that we should keep the documentation generators
separate from the parser, that would allow us to keep all the configure
switches while metadata.json would be build and installed
unconditionally.

-- 
Cyril Hrubis
chrubis@suse.cz

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [LTP] [PATCH 2/7] docparse: Add tests
  2021-10-22 11:41   ` Petr Vorel
@ 2021-10-25 12:51     ` Cyril Hrubis
  2021-10-25 20:01       ` Petr Vorel
  0 siblings, 1 reply; 30+ messages in thread
From: Cyril Hrubis @ 2021-10-25 12:51 UTC (permalink / raw)
  To: Petr Vorel; +Cc: ltp

Hi!
> It'd be nice, if this was run by make test.
> 
> Also I'm quite surprised by this behavior:
> 
> $ cd docparse/tests/ && make test
> cat test.sh >test 
> chmod a+x test
>
> When this was added?

There is no Makefile in that directory, this does not even make any
sense. I guess that this is GNU Make pulling default rules out of thin
air...

-- 
Cyril Hrubis
chrubis@suse.cz

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [LTP] [PATCH 2/7] docparse: Add tests
  2021-10-25 12:46     ` Cyril Hrubis
@ 2021-10-25 20:00       ` Petr Vorel
  0 siblings, 0 replies; 30+ messages in thread
From: Petr Vorel @ 2021-10-25 20:00 UTC (permalink / raw)
  To: Cyril Hrubis; +Cc: ltp

> Hi!
> > Very nice, thanks! Maybe remame multiline_macro.c.out to multiline_macro.json
> > to get json syntax in editors? (multiline_macro.c.out.json would be ugly).

> What about foo.c.json then?
Sure, LGTM.

Kind regards,
Petr

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [LTP] [PATCH 2/7] docparse: Add tests
  2021-10-25 12:51     ` Cyril Hrubis
@ 2021-10-25 20:01       ` Petr Vorel
  0 siblings, 0 replies; 30+ messages in thread
From: Petr Vorel @ 2021-10-25 20:01 UTC (permalink / raw)
  To: Cyril Hrubis; +Cc: ltp

> Hi!
> > It'd be nice, if this was run by make test.

> > Also I'm quite surprised by this behavior:

> > $ cd docparse/tests/ && make test
> > cat test.sh >test 
> > chmod a+x test

> > When this was added?

> There is no Makefile in that directory, this does not even make any
> sense. I guess that this is GNU Make pulling default rules out of thin
> air...
GNU make again surprised me :) OK, let's ignore this funny default target.
But it'd be nice to have these tests run in CI and in make test target by
default.

Kind regards,
Petr

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [LTP] [PATCH 7/7] docparse/Makefile: Do not abort on missing generators
  2021-10-25 12:48     ` Cyril Hrubis
@ 2021-10-27  9:47       ` Petr Vorel
  0 siblings, 0 replies; 30+ messages in thread
From: Petr Vorel @ 2021-10-27  9:47 UTC (permalink / raw)
  To: Cyril Hrubis; +Cc: ltp

> Hi!
> > > Since we want to use the metadata.json in the testrunner it must bte
> > nit: typo s/bte/be

> > > build unconditionally.
> > According to docs:
> >   --with-metadata-generator=asciidoc|asciidoctor
> >   --disable-metadata      Disable metadata generation (both HTML and PDF,
> >                           default no)
> >   --disable-metadata-html Disable metadata HTML generation (default no)
> >   --enable-metadata-pdf   Enable metadata PDF generation (default no)

> > I'd like to have single option which does not create HTML and PDF (thus does not
> > require asciidoc|asciidoctor. I wonder if we could change build system to keep
> > --disable-metadata, build always docparse and json as we need, but with
> > ./configured --disable-metadata just not run HTML and PDF generation?

> I'm starting to think that the docparse.c should be moved to a
> metadata/paraser.c and that we should keep the documentation generators
> separate from the parser, that would allow us to keep all the configure
> switches while metadata.json would be build and installed
> unconditionally.

Good idea, go ahead with a patch please.

Kind regards,
Petr

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [LTP] [PATCH 0/7] docparse improvements
  2021-10-18 15:47 [LTP] [PATCH 0/7] docparse improvements Cyril Hrubis
                   ` (7 preceding siblings ...)
  2021-10-18 15:48 ` [LTP] [PATCH 0/7] docparse improvements Cyril Hrubis
@ 2021-10-27 13:22 ` Richard Palethorpe
  2021-10-27 13:48   ` Cyril Hrubis
  8 siblings, 1 reply; 30+ messages in thread
From: Richard Palethorpe @ 2021-10-27 13:22 UTC (permalink / raw)
  To: Cyril Hrubis; +Cc: ltp

Hello,

Cyril Hrubis <chrubis@suse.cz> writes:

> Implement support for various missing bits to the docparse tool and
> enables it unconditionally so that the metadata.json file is present on
> all builds.
>
> This is first part of bigger effort to get the metadata useful for the
> testrunners, expecially we need the .test_variants field to be properly
> parsed in order to compute the overall test runtime correctly.

It's unfortunate that before starting this effort and the checker that
we didn't know about tree-sitter (although Sparse may still be the best
choice for the checker).

Tree-sitter can parse C into an AST and can easily be vendored into LTP:
https://tree-sitter.github.io/tree-sitter/using-parsers#building-the-library

Then we just need to work on the level of the AST. It also has a query
language. This should allow the initial matching to be done on a high
level.

If we continue down the path of hand parsing C, then it will most likely
result in constant tweaks and additions.

-- 
Thank you,
Richard.

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [LTP] [PATCH 0/7] docparse improvements
  2021-10-27 13:22 ` Richard Palethorpe
@ 2021-10-27 13:48   ` Cyril Hrubis
  2021-10-28  8:11     ` Richard Palethorpe
  0 siblings, 1 reply; 30+ messages in thread
From: Cyril Hrubis @ 2021-10-27 13:48 UTC (permalink / raw)
  To: Richard Palethorpe; +Cc: ltp

Hi!
> It's unfortunate that before starting this effort and the checker that
> we didn't know about tree-sitter (although Sparse may still be the best
> choice for the checker).
> 
> Tree-sitter can parse C into an AST and can easily be vendored into LTP:
> https://tree-sitter.github.io/tree-sitter/using-parsers#building-the-library
> 
> Then we just need to work on the level of the AST. It also has a query
> language. This should allow the initial matching to be done on a high
> level.

The only worry that I have about this would be speed, currently the code
I wrote takes a few second to process thousands of C files in LTP, that
is because we take a lot of shortcuts and ignore all the stuff we do not
need. Full parser that builds AST would be orders of magnitude slower,
so before we attempt to use it it should be benchmarked properly to see
if it's fast enough.

> If we continue down the path of hand parsing C, then it will most likely
> result in constant tweaks and additions.

Well I would say that this patchset is the last addition for the parser,
if we ever need anything more complex we should really switch to
something else. On the other hand I do not think that we will ever need
more complexity in the parser than this, as long as we keep things sane.

-- 
Cyril Hrubis
chrubis@suse.cz

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [LTP] [PATCH 0/7] docparse improvements
  2021-10-27 13:48   ` Cyril Hrubis
@ 2021-10-28  8:11     ` Richard Palethorpe
  2021-10-29  8:54       ` Cyril Hrubis
  0 siblings, 1 reply; 30+ messages in thread
From: Richard Palethorpe @ 2021-10-28  8:11 UTC (permalink / raw)
  To: Cyril Hrubis; +Cc: ltp

Hello,

Cyril Hrubis <chrubis@suse.cz> writes:

> Hi!
>> It's unfortunate that before starting this effort and the checker that
>> we didn't know about tree-sitter (although Sparse may still be the best
>> choice for the checker).
>> 
>> Tree-sitter can parse C into an AST and can easily be vendored into LTP:
>> https://tree-sitter.github.io/tree-sitter/using-parsers#building-the-library
>> 
>> Then we just need to work on the level of the AST. It also has a query
>> language. This should allow the initial matching to be done on a high
>> level.
>
> The only worry that I have about this would be speed, currently the code
> I wrote takes a few second to process thousands of C files in LTP, that
> is because we take a lot of shortcuts and ignore all the stuff we do not
> need. Full parser that builds AST would be orders of magnitude slower,
> so before we attempt to use it it should be benchmarked properly to see
> if it's fast enough.

It's incredibly fast, it has no trouble parsing the entire kernel.

Weggli uses tree-sitter

https://github.com/googleprojectzero/weggli

rich@g78 ~/q/ltp (master)> time weggli '_ verify_alarm(_) { exit(0); }' .
/home/rich/qa/ltp/./testcases/kernel/syscalls/alarm/alarm03.c:21
static void verify_alarm(void)
{
	pid_t pid;

	TEST(alarm(100));

..
		} else {
			tst_res(TPASS,
				"alarm(100), fork, alarm(0) child's "
				"alarm returned %ld", TST_RET);
		}
		exit(0);
	}

	TEST(alarm(0));
	if (TST_RET != 100) {
		tst_res(TFAIL,
..
}
/home/rich/qa/ltp/./testcases/kernel/syscalls/alarm/alarm07.c:20
static void verify_alarm(void)
{
	pid_t pid;
	alarm_cnt = 0;

	TEST(alarm(1));
..
			tst_res(TPASS, "alarm() request cleared in child");
		} else {
			tst_res(TFAIL, "alarm() request not cleared in "
				"child; alarms received:%d", alarm_cnt);
		}
		exit(0);
	}

	if (alarm_cnt != 1)
		tst_res(TFAIL, "Sigalarms in parent %i, expected 1", alarm_cnt);
	else
..
}

________________________________________________________
Executed in   49.35 millis    fish           external
   usr time  110.88 millis    0.00 millis  110.88 millis
   sys time   87.44 millis    1.20 millis   86.24 millis

>
>> If we continue down the path of hand parsing C, then it will most likely
>> result in constant tweaks and additions.
>
> Well I would say that this patchset is the last addition for the parser,
> if we ever need anything more complex we should really switch to
> something else. On the other hand I do not think that we will ever need
> more complexity in the parser than this, as long as we keep things
> sane.

This closes the door on a lot of options for no upside AFAICT. We have
two tools (Sparse and tree-sitter) that can be (or have been) vendored
and will parse a large subset of C. Sparse goes a step further allowing
control flow analysis. The usual reasons for reinventing the wheel are
not present.

-- 
Thank you,
Richard.

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [LTP] [PATCH 1/7] docparse: Implement #define and #include
  2021-10-18 15:47 ` [LTP] [PATCH 1/7] docparse: Implement #define and #include Cyril Hrubis
@ 2021-10-29  8:26   ` Petr Vorel
  2021-10-29  8:27   ` Petr Vorel
  1 sibling, 0 replies; 30+ messages in thread
From: Petr Vorel @ 2021-10-29  8:26 UTC (permalink / raw)
  To: Cyril Hrubis; +Cc: ltp

Hi Cyril,

very nice improvement, thanks!

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

Kind regards,
Petr

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [LTP] [PATCH 1/7] docparse: Implement #define and #include
  2021-10-18 15:47 ` [LTP] [PATCH 1/7] docparse: Implement #define and #include Cyril Hrubis
  2021-10-29  8:26   ` Petr Vorel
@ 2021-10-29  8:27   ` Petr Vorel
  1 sibling, 0 replies; 30+ messages in thread
From: Petr Vorel @ 2021-10-29  8:27 UTC (permalink / raw)
  To: Cyril Hrubis; +Cc: ltp

Hi Cyril,

> + Also add -v verbose mode that prints included files and defined macros
How about propagate VERBOSE=1 from Makefile to docparse as -v ?

Kind regards,
Petr

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [LTP] [PATCH 0/7] docparse improvements
  2021-10-28  8:11     ` Richard Palethorpe
@ 2021-10-29  8:54       ` Cyril Hrubis
  2021-11-01  9:04         ` Richard Palethorpe
  0 siblings, 1 reply; 30+ messages in thread
From: Cyril Hrubis @ 2021-10-29  8:54 UTC (permalink / raw)
  To: Richard Palethorpe; +Cc: ltp

Hi!
> It's incredibly fast, it has no trouble parsing the entire kernel.
> 
> Weggli uses tree-sitter
> 
> https://github.com/googleprojectzero/weggli
> ________________________________________________________
> Executed in   49.35 millis    fish           external
>    usr time  110.88 millis    0.00 millis  110.88 millis
>    sys time   87.44 millis    1.20 millis   86.24 millis

This looks like it's about the speed of grep, that sounds incredible.

> > Well I would say that this patchset is the last addition for the parser,
> > if we ever need anything more complex we should really switch to
> > something else. On the other hand I do not think that we will ever need
> > more complexity in the parser than this, as long as we keep things
> > sane.
> 
> This closes the door on a lot of options for no upside AFAICT. We have
> two tools (Sparse and tree-sitter) that can be (or have been) vendored
> and will parse a large subset of C. Sparse goes a step further allowing
> control flow analysis. The usual reasons for reinventing the wheel are
> not present.

Still working on a prototype based on tree-sitter would take a week or
two worth of time and I would like to get the metadata fixed now, so
that I can finally move on with runltp-ng. So I would slightly prefer
merging the patches for the current solution first, then we can have a
look on tree-sitter in the next LTP release cycle. What do you think?

-- 
Cyril Hrubis
chrubis@suse.cz

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [LTP] [PATCH 0/7] docparse improvements
  2021-10-29  8:54       ` Cyril Hrubis
@ 2021-11-01  9:04         ` Richard Palethorpe
  2021-11-01  9:59           ` Cyril Hrubis
  0 siblings, 1 reply; 30+ messages in thread
From: Richard Palethorpe @ 2021-11-01  9:04 UTC (permalink / raw)
  To: Cyril Hrubis; +Cc: ltp

Hello Cryil,

Cyril Hrubis <chrubis@suse.cz> writes:

> Hi!
>> It's incredibly fast, it has no trouble parsing the entire kernel.
>> 
>> Weggli uses tree-sitter
>> 
>> https://github.com/googleprojectzero/weggli
>> ________________________________________________________
>> Executed in   49.35 millis    fish           external
>>    usr time  110.88 millis    0.00 millis  110.88 millis
>>    sys time   87.44 millis    1.20 millis   86.24 millis
>
> This looks like it's about the speed of grep, that sounds incredible.
>
>> > Well I would say that this patchset is the last addition for the parser,
>> > if we ever need anything more complex we should really switch to
>> > something else. On the other hand I do not think that we will ever need
>> > more complexity in the parser than this, as long as we keep things
>> > sane.
>> 
>> This closes the door on a lot of options for no upside AFAICT. We have
>> two tools (Sparse and tree-sitter) that can be (or have been) vendored
>> and will parse a large subset of C. Sparse goes a step further allowing
>> control flow analysis. The usual reasons for reinventing the wheel are
>> not present.
>
> Still working on a prototype based on tree-sitter would take a week or
> two worth of time and I would like to get the metadata fixed now, so
> that I can finally move on with runltp-ng. So I would slightly prefer
> merging the patches for the current solution first, then we can have a
> look on tree-sitter in the next LTP release cycle. What do you think?

I think there is a small risk

1. It turns out that with tree-sitter it would make more sense to use a
   different meta-data format.
2. Someone starts building on the current solution without realising it
   might change

Of course this can be mitigated by saying that the implementation and
format are subject to change.

Note that in general I think it's best (on bigger projects) to have an
alternative branch for big changes where one needs to "rush" to an
end-to-end solution. Most likely we need an alternate branch for
integrating runltp-ng and the executor.

-- 
Thank you,
Richard.

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [LTP] [PATCH 0/7] docparse improvements
  2021-11-01  9:04         ` Richard Palethorpe
@ 2021-11-01  9:59           ` Cyril Hrubis
  2021-11-01 12:20             ` Richard Palethorpe
  0 siblings, 1 reply; 30+ messages in thread
From: Cyril Hrubis @ 2021-11-01  9:59 UTC (permalink / raw)
  To: Richard Palethorpe; +Cc: ltp

Hi!
> > Still working on a prototype based on tree-sitter would take a week or
> > two worth of time and I would like to get the metadata fixed now, so
> > that I can finally move on with runltp-ng. So I would slightly prefer
> > merging the patches for the current solution first, then we can have a
> > look on tree-sitter in the next LTP release cycle. What do you think?
> 
> I think there is a small risk
> 
> 1. It turns out that with tree-sitter it would make more sense to use a
>    different meta-data format.

What do you have in mind? I do not think that we should dramatically
chante the json structure we do have now.

> 2. Someone starts building on the current solution without realising it
>    might change
>
> Of course this can be mitigated by saying that the implementation and
> format are subject to change.

My approach here is to build the runltp-ng as a set of reusable
libraries, one of them would be a parser for the metadata that would
provide interfaces for the common queries. That makes the metadata an
intermediate format that could evolve over time. On the other hand I do
not expect big changes in the metadata format.

> Note that in general I think it's best (on bigger projects) to have an
> alternative branch for big changes where one needs to "rush" to an
> end-to-end solution. Most likely we need an alternate branch for
> integrating runltp-ng and the executor.

We can even do this in a separate github repository or whatever works,
but still we have to agree on general direction.

I still think that the best solution here is to apply this patchset and
put the tree-sitter on TODO. Unlike tree-sitter this is neither big nor
radical change and it would allow us to proceed with other stuff that
has been blocked for several releases at least.

-- 
Cyril Hrubis
chrubis@suse.cz

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [LTP] [PATCH 0/7] docparse improvements
  2021-11-01  9:59           ` Cyril Hrubis
@ 2021-11-01 12:20             ` Richard Palethorpe
  2021-11-01 15:10               ` Cyril Hrubis
  0 siblings, 1 reply; 30+ messages in thread
From: Richard Palethorpe @ 2021-11-01 12:20 UTC (permalink / raw)
  To: Cyril Hrubis; +Cc: ltp

Hello,

Cyril Hrubis <chrubis@suse.cz> writes:

> Hi!
>> > Still working on a prototype based on tree-sitter would take a week or
>> > two worth of time and I would like to get the metadata fixed now, so
>> > that I can finally move on with runltp-ng. So I would slightly prefer
>> > merging the patches for the current solution first, then we can have a
>> > look on tree-sitter in the next LTP release cycle. What do you think?
>> 
>> I think there is a small risk
>> 
>> 1. It turns out that with tree-sitter it would make more sense to use a
>>    different meta-data format.
>
> What do you have in mind? I do not think that we should dramatically
> chante the json structure we do have now.

Whatever tree-sitter produces most naturally and requires the least
amount of massaging.

>
>> 2. Someone starts building on the current solution without realising it
>>    might change
>>
>> Of course this can be mitigated by saying that the implementation and
>> format are subject to change.
>
> My approach here is to build the runltp-ng as a set of reusable
> libraries, one of them would be a parser for the metadata that would
> provide interfaces for the common queries. That makes the metadata an
> intermediate format that could evolve over time. On the other hand I do
> not expect big changes in the metadata format.
>
>> Note that in general I think it's best (on bigger projects) to have an
>> alternative branch for big changes where one needs to "rush" to an
>> end-to-end solution. Most likely we need an alternate branch for
>> integrating runltp-ng and the executor.
>
> We can even do this in a separate github repository or whatever works,
> but still we have to agree on general direction.
>
> I still think that the best solution here is to apply this patchset and
> put the tree-sitter on TODO. Unlike tree-sitter this is neither big nor
> radical change and it would allow us to proceed with other stuff that
> has been blocked for several releases at least.

As discussed in IRC, I prefer the route of trying either Sparse or
Tree-sitter first to produce the metadata. However please go ahead and
make the decision. After all once we have better automation it will
reduce the burden on reviewers.

-- 
Thank you,
Richard.

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [LTP] [PATCH 4/7] docparse: Implement ARRAY_SIZE()
  2021-10-18 15:47 ` [LTP] [PATCH 4/7] docparse: Implement ARRAY_SIZE() Cyril Hrubis
@ 2021-11-01 12:36   ` Richard Palethorpe
  2021-11-01 13:18     ` Cyril Hrubis
  0 siblings, 1 reply; 30+ messages in thread
From: Richard Palethorpe @ 2021-11-01 12:36 UTC (permalink / raw)
  To: Cyril Hrubis; +Cc: ltp

Hi,

Cyril Hrubis <chrubis@suse.cz> writes:

> Adds a special handlingn for ARRAY_SIZE() macro.
>
> If we stumble upon ARRAY_SIZE() in the tst_test structure we try to
> lookup the array and count its members.

Note that this is the type of thing Sparse should be able to handle
well. As it should evaluate this to a constant. Although there is the
risk it would be too clever and eliminate some expressions (for
example).

>
> Proper parsing of .test_variants also requires that we add -I switch to
> the docparse to be able to specify include paths on a command line since
> some variants are stuck in top level include while others are in
> testcases/kernel/syscalls/utils/.
>
> + tests
>
> Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
> ---
>  docparse/docparse.c               | 222 +++++++++++++++++++++++++++---
>  docparse/parse.sh                 |   2 +-
>  docparse/tests/array_size01.c     |   5 +
>  docparse/tests/array_size01.c.out |   4 +
>  docparse/tests/array_size02.c     |   5 +
>  docparse/tests/array_size02.c.out |   4 +
>  docparse/tests/array_size03.c     |  10 ++
>  docparse/tests/array_size03.c.out |   4 +
>  docparse/tests/array_size04.c     |   5 +
>  docparse/tests/array_size04.c.out |   4 +
>  docparse/tests/include.h          |   6 +
>  11 files changed, 248 insertions(+), 23 deletions(-)
>  create mode 100644 docparse/tests/array_size01.c
>  create mode 100644 docparse/tests/array_size01.c.out
>  create mode 100644 docparse/tests/array_size02.c
>  create mode 100644 docparse/tests/array_size02.c.out
>  create mode 100644 docparse/tests/array_size03.c
>  create mode 100644 docparse/tests/array_size03.c.out
>  create mode 100644 docparse/tests/array_size04.c
>  create mode 100644 docparse/tests/array_size04.c.out
>
> diff --git a/docparse/docparse.c b/docparse/docparse.c
> index cab01c384..9a1ed830c 100644
> --- a/docparse/docparse.c
> +++ b/docparse/docparse.c
> @@ -15,7 +15,12 @@
>  
>  #include "data_storage.h"
>  
> +#define INCLUDE_PATH_MAX 5
> +
>  static int verbose;
> +static char *cmdline_includepath[INCLUDE_PATH_MAX];
> +static unsigned int cmdline_includepaths;
> +static char *includepath;
>  
>  #define WARN(str) fprintf(stderr, "WARNING: " str "\n")
>  
> @@ -131,13 +136,14 @@ static void maybe_comment(FILE *f, struct data_node *doc)
>  	}
>  }
>  
> -static char *next_token(FILE *f, struct data_node *doc)
> +static char *next_token2(FILE *f, char *buf, size_t buf_len, struct data_node *doc)
>  {
>  	size_t i = 0;
> -	static char buf[4096];
>  	int c;
>  	int in_str = 0;
>  
> +	buf_len--;
> +
>  	for (;;) {
>  		c = fgetc(f);
>  
> @@ -150,7 +156,8 @@ static char *next_token(FILE *f, struct data_node *doc)
>  					goto exit;
>  			}
>  
> -			buf[i++] = c;
> +			if (i < buf_len)
> +				buf[i++] = c;
>  			continue;
>  		}
>  
> @@ -169,7 +176,8 @@ static char *next_token(FILE *f, struct data_node *doc)
>  				goto exit;
>  			}
>  
> -			buf[i++] = c;
> +			if (i < buf_len)
> +				buf[i++] = c;
>  			goto exit;
>  		case '0' ... '9':
>  		case 'a' ... 'z':
> @@ -178,7 +186,8 @@ static char *next_token(FILE *f, struct data_node *doc)
>  		case '_':
>  		case '-':
>  		case '#':
> -			buf[i++] = c;
> +			if (i < buf_len)
> +				buf[i++] = c;

I suspect you need to remove spaces after '#' (see below).

>  		break;
>  		case '/':
>  			maybe_comment(f, doc);
> @@ -203,11 +212,33 @@ exit:
>  	return buf;
>  }
>  
> -static FILE *open_include(const char *includepath, FILE *f)
> +static char *next_token(FILE *f, struct data_node *doc)
>  {
> -	char buf[256];
> +	static char buf[4096];
> +
> +	return next_token2(f, buf, sizeof(buf), doc);
> +}
> +
> +static FILE *open_file(const char *dir, const char *fname)
> +{
> +	FILE *f;
>  	char *path;
> +
> +	if (asprintf(&path, "%s/%s", dir, fname) < 0)
> +		return NULL;
> +
> +	f = fopen(path, "r");
> +
> +	free(path);
> +
> +	return f;
> +}
> +
> +static FILE *open_include(FILE *f)
> +{
> +	char buf[256], *fname;
>  	FILE *inc;
> +	unsigned int i;
>  
>  	if (!fscanf(f, "%s\n", buf))
>  		return NULL;
> @@ -215,24 +246,36 @@ static FILE *open_include(const char *includepath, FILE *f)
>  	if (buf[0] != '"')
>  		return NULL;
>  
> -	char *filename = buf + 1;
> +	fname = buf + 1;
>  
>  	if (!buf[0])
>  		return NULL;
>  
> -	filename[strlen(filename)-1] = 0;
> +	fname[strlen(fname)-1] = 0;
>  
> -	if (asprintf(&path, "%s/%s", includepath, filename) < 0)
> -		return NULL;
> +	inc = open_file(includepath, fname);
> +	if (inc) {
> +		if (verbose)
> +			fprintf(stderr, "INCLUDE %s/%s\n", includepath, fname);
>  
> -	inc = fopen(path, "r");
> +		return inc;
> +	}
>  
> -	if (inc && verbose)
> -		fprintf(stderr, "INCLUDE %s\n", path);
> +	for (i = 0; i < cmdline_includepaths; i++) {
> +		inc = open_file(cmdline_includepath[i], fname);
>  
> -	free(path);
> +		if (!inc)
> +			continue;
> +
> +		if (verbose) {
> +			fprintf(stderr, "INCLUDE %s/%s\n",
> +				cmdline_includepath[i], fname);
> +		}
>  
> -	return inc;
> +		return inc;
> +	}
> +
> +	return NULL;
>  }
>  
>  static void close_include(FILE *inc)
> @@ -299,6 +342,127 @@ static void try_apply_macro(char **res)
>  	*res = ret->data;
>  }
>  
> +static int parse_get_array_len(FILE *f)
> +{
> +	const char *token;
> +	int cnt = 0, depth = 0, prev_comma = 0;
> +
> +	if (!(token = next_token(f, NULL)))
> +		return 0;
> +
> +	if (strcmp(token, "{"))
> +		return 0;
> +
> +	for (;;) {
> +		if (!(token = next_token(f, NULL)))
> +			return 0;
> +
> +		if (!strcmp(token, "{"))
> +			depth++;
> +
> +		if (!strcmp(token, "}"))
> +			depth--;
> +		else
> +			prev_comma = 0;
> +
> +		if (!strcmp(token, ",") && !depth) {
> +			prev_comma = 1;
> +			cnt++;
> +		}
> +
> +		if (depth < 0)
> +			return cnt + !prev_comma;
> +	}
> +}
> +
> +static void look_for_array_size(FILE *f, const char *arr_id, struct data_node **res)
> +{
> +	const char *token;
> +	char buf[2][2048] = {};
> +	int cur_buf = 0;
> +	int prev_buf = 1;
> +
> +	for (;;) {
> +		if (!(token = next_token2(f, buf[cur_buf], 2048, NULL)))
> +			break;
> +
> +		if (!strcmp(token, "=") && !strcmp(buf[prev_buf], arr_id)) {
> +			int arr_len = parse_get_array_len(f);
> +
> +			if (verbose)
> +				fprintf(stderr, "ARRAY %s LENGTH = %i\n", arr_id, arr_len);
> +
> +			*res = data_node_int(arr_len);
> +
> +			break;
> +		}
> +
> +		if (strcmp(buf[cur_buf], "]") && strcmp(buf[cur_buf], "[")) {
> +			cur_buf = !cur_buf;
> +			prev_buf = !prev_buf;
> +		}
> +	}
> +}
> +
> +static int parse_array_size(FILE *f, struct data_node **res)
> +{
> +	const char *token;
> +	char *arr_id;
> +	long pos;
> +
> +	*res = NULL;
> +
> +	if (!(token = next_token(f, NULL)))
> +		return 1;
> +
> +	if (strcmp(token, "("))
> +		return 1;
> +
> +	if (!(token = next_token(f, NULL)))
> +		return 1;
> +
> +	arr_id = strdup(token);
> +
> +	if (verbose)
> +		fprintf(stderr, "COMPUTING ARRAY '%s' LENGHT\n", arr_id);
> +
> +	pos = ftell(f);
> +
> +	rewind(f);
> +
> +	look_for_array_size(f, arr_id, res);
> +
> +	if (!*res) {
> +		FILE *inc;
> +
> +		rewind(f);
> +
> +		for (;;) {
> +			if (!(token = next_token(f, NULL)))
> +				break;
> +
> +			if (!strcmp(token, "#include")) {

Are spaces removed after the '#'?

e.g.

#if X
#  include<Y>
#endif

> +				inc = open_include(f);
> +
> +				if (inc) {
> +					look_for_array_size(inc, arr_id, res);
> +					close_include(inc);
> +				}
> +			}
> +
> +			if (*res)
> +				break;
> +		}
> +	}
> +
> +	free(arr_id);
> +
> +	if (fseek(f, pos, SEEK_SET))
> +		return 1;
> +
> +	return 0;
> +}
> +
>  static int parse_test_struct(FILE *f, struct data_node *doc, struct data_node *node)
>  {
>  	char *token;
> @@ -344,11 +508,17 @@ static int parse_test_struct(FILE *f, struct data_node *doc, struct data_node *n
>  		if (!strcmp(token, "{")) {
>  			ret = data_node_array();
>  			parse_array(f, ret);
> +		} else if (!strcmp(token, "ARRAY_SIZE")) {
> +			if (parse_array_size(f, &ret))
> +				return 1;
>  		} else {
>  			try_apply_macro(&token);
>  			ret = data_node_string(token);
>  		}
>  
> +		if (!ret)
> +			continue;
> +
>  		const char *key = id;
>  		if (key[0] == '.')
>  			key++;
> @@ -448,12 +618,12 @@ static void parse_macro(FILE *f)
>  	hsearch(e, ENTER);
>  }
>  
> -static void parse_include_macros(const char *includepath, FILE *f)
> +static void parse_include_macros(FILE *f)
>  {
>  	FILE *inc;
>  	const char *token;
>  
> -	inc = open_include(includepath, f);
> +	inc = open_include(f);
>  	if (!inc)
>  		return;
>  
> @@ -477,7 +647,7 @@ static struct data_node *parse_file(const char *fname)
>  
>  	FILE *f = fopen(fname, "r");
>  
> -	const char *includepath = dirname(strdup(fname));
> +	includepath = dirname(strdup(fname));
>  
>  	struct data_node *res = data_node_hash();
>  	struct data_node *doc = data_node_array();
> @@ -491,7 +661,7 @@ static struct data_node *parse_file(const char *fname)
>  					parse_macro(f);
>  
>  				if (!strcmp(token, "#include"))
> -					parse_include_macros(includepath, f);
> +					parse_include_macros(f);
>  			}
>  
>  			state = 0;
> @@ -504,7 +674,6 @@ static struct data_node *parse_file(const char *fname)
>  		parse_test_struct(f, doc, res);
>  	}
>  
> -
>  	if (data_node_array_len(doc)) {
>  		data_node_hash_add(res, "doc", doc);
>  		found = 1;
> @@ -564,6 +733,7 @@ static void print_help(const char *prgname)
>  {
>  	printf("usage: %s [-vh] input.c\n\n", prgname);
>  	printf("-v sets verbose mode\n");
> +	printf("-I add include path\n");
>  	printf("-h prints this help\n\n");
>  	exit(0);
>  }
> @@ -574,11 +744,19 @@ int main(int argc, char *argv[])
>  	struct data_node *res;
>  	int opt;
>  
> -	while ((opt = getopt(argc, argv, "hv")) != -1) {
> +	while ((opt = getopt(argc, argv, "hI:v")) != -1) {
>  		switch (opt) {
>  		case 'h':
>  			print_help(argv[0]);
>  		break;
> +		case 'I':
> +			if (cmdline_includepaths >= INCLUDE_PATH_MAX) {
> +				fprintf(stderr, "Too much include paths!");
> +				exit(1);
> +			}
> +
> +			cmdline_includepath[cmdline_includepaths++] = optarg;
> +		break;
>  		case 'v':
>  			verbose = 1;
>  		break;
> diff --git a/docparse/parse.sh b/docparse/parse.sh
> index 79011bc10..2ace34fa0 100755
> --- a/docparse/parse.sh
> +++ b/docparse/parse.sh
> @@ -26,7 +26,7 @@ echo ' "tests": {'
>  first=1
>  
>  for test in `find testcases/ -name '*.c'`; do
> -	a=$($top_builddir/docparse/docparse "$test")
> +	a=$($top_builddir/docparse/docparse -Iinclude -Itestcases/kernel/syscalls/utils/ "$test")
>  	if [ -n "$a" ]; then
>  		if [ -z "$first" ]; then
>  			echo ','
> diff --git a/docparse/tests/array_size01.c b/docparse/tests/array_size01.c
> new file mode 100644
> index 000000000..8a0b9252b
> --- /dev/null
> +++ b/docparse/tests/array_size01.c
> @@ -0,0 +1,5 @@
> +static int variants = {1};

I can see how this might work, but looks odd.

> +
> +static struct tst_test test = {
> +	.test_variants = ARRAY_SIZE(variants),
> +};
> diff --git a/docparse/tests/array_size01.c.out b/docparse/tests/array_size01.c.out
> new file mode 100644
> index 000000000..ec364be12
> --- /dev/null
> +++ b/docparse/tests/array_size01.c.out
> @@ -0,0 +1,4 @@
> +  "array_size01": {
> +   "test_variants": 1,
> +   "fname": "array_size01.c"
> +  }
> \ No newline at end of file
> diff --git a/docparse/tests/array_size02.c b/docparse/tests/array_size02.c
> new file mode 100644
> index 000000000..5c7d4471e
> --- /dev/null
> +++ b/docparse/tests/array_size02.c
> @@ -0,0 +1,5 @@
> +static int variants = {{1}, {2}, {3}};

Should this be variants[]?

> +
> +static struct tst_test test = {
> +	.test_variants = ARRAY_SIZE(variants),
> +};
> diff --git a/docparse/tests/array_size02.c.out b/docparse/tests/array_size02.c.out
> new file mode 100644
> index 000000000..122686952
> --- /dev/null
> +++ b/docparse/tests/array_size02.c.out
> @@ -0,0 +1,4 @@
> +  "array_size02": {
> +   "test_variants": 3,
> +   "fname": "array_size02.c"
> +  }
> \ No newline at end of file
> diff --git a/docparse/tests/array_size03.c b/docparse/tests/array_size03.c
> new file mode 100644
> index 000000000..9058db813
> --- /dev/null
> +++ b/docparse/tests/array_size03.c
> @@ -0,0 +1,10 @@
> +static struct foo variants[] = {
> +#ifdef FOO
> +	{.bar = 11},
> +#endif
> +	{.bar = 10},
> +};
> +
> +static struct tst_test test = {
> +	.test_variants = ARRAY_SIZE(variants),
> +};
> diff --git a/docparse/tests/array_size03.c.out b/docparse/tests/array_size03.c.out
> new file mode 100644
> index 000000000..bb690c9f5
> --- /dev/null
> +++ b/docparse/tests/array_size03.c.out
> @@ -0,0 +1,4 @@
> +  "array_size03": {
> +   "test_variants": 2,
> +   "fname": "array_size03.c"
> +  }
> \ No newline at end of file
> diff --git a/docparse/tests/array_size04.c b/docparse/tests/array_size04.c
> new file mode 100644
> index 000000000..5f1d9986e
> --- /dev/null
> +++ b/docparse/tests/array_size04.c
> @@ -0,0 +1,5 @@
> +#include "include.h"
> +
> +static struct tst_test test = {
> +	.test_variants = ARRAY_SIZE(variants),
> +};
> diff --git a/docparse/tests/array_size04.c.out b/docparse/tests/array_size04.c.out
> new file mode 100644
> index 000000000..6b8d41792
> --- /dev/null
> +++ b/docparse/tests/array_size04.c.out
> @@ -0,0 +1,4 @@
> +  "array_size04": {
> +   "test_variants": 3,
> +   "fname": "array_size04.c"
> +  }
> \ No newline at end of file
> diff --git a/docparse/tests/include.h b/docparse/tests/include.h
> index efa11d24f..fbc69a561 100644
> --- a/docparse/tests/include.h
> +++ b/docparse/tests/include.h
> @@ -1 +1,7 @@
>  #define TEST_VARIANTS 10
> +
> +static struct variants[] = {
> +	{.bar = 10},
> +	{.bar = 11},
> +	{.bar = 12}
> +};
> -- 
> 2.32.0


-- 
Thank you,
Richard.

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [LTP] [PATCH 4/7] docparse: Implement ARRAY_SIZE()
  2021-11-01 12:36   ` Richard Palethorpe
@ 2021-11-01 13:18     ` Cyril Hrubis
  0 siblings, 0 replies; 30+ messages in thread
From: Cyril Hrubis @ 2021-11-01 13:18 UTC (permalink / raw)
  To: Richard Palethorpe; +Cc: ltp

Hi!
> > Adds a special handlingn for ARRAY_SIZE() macro.
> >
> > If we stumble upon ARRAY_SIZE() in the tst_test structure we try to
> > lookup the array and count its members.
> 
> Note that this is the type of thing Sparse should be able to handle
> well. As it should evaluate this to a constant. Although there is the
> risk it would be too clever and eliminate some expressions (for
> example).

That's another possible problem, the parser may end up too smart, but
that is something we will see once we try.

Hi!
> > +			if (!strcmp(token, "#include")) {
> 
> Are spaces removed after the '#'?
> 
> e.g.
> 
> #if X
> #  include<Y>
> #endif

Good catch, will fix that in v2 and add a test.

> > diff --git a/docparse/tests/array_size01.c b/docparse/tests/array_size01.c
> > new file mode 100644
> > index 000000000..8a0b9252b
> > --- /dev/null
> > +++ b/docparse/tests/array_size01.c
> > @@ -0,0 +1,5 @@
> > +static int variants = {1};
> 
> I can see how this might work, but looks odd.

This supposed to be static int variants[] = {1};

The thing is that we do not even have a parser here, it's an extractor
and we depend on the C code being correct. It does compile by a compiler
before we even attempt to extract the metadata. So it will happily
process input that is not correct C.

I will fix the test in v2 as well.

> > diff --git a/docparse/tests/array_size02.c b/docparse/tests/array_size02.c
> > new file mode 100644
> > index 000000000..5c7d4471e
> > --- /dev/null
> > +++ b/docparse/tests/array_size02.c
> > @@ -0,0 +1,5 @@
> > +static int variants = {{1}, {2}, {3}};
> 
> Should this be variants[]?

Indeed, it should be also struct foo { int val } type and not int. Will
fix a swell.

-- 
Cyril Hrubis
chrubis@suse.cz

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [LTP] [PATCH 0/7] docparse improvements
  2021-11-01 12:20             ` Richard Palethorpe
@ 2021-11-01 15:10               ` Cyril Hrubis
  0 siblings, 0 replies; 30+ messages in thread
From: Cyril Hrubis @ 2021-11-01 15:10 UTC (permalink / raw)
  To: Richard Palethorpe; +Cc: ltp

Hi!
> >> > Still working on a prototype based on tree-sitter would take a week or
> >> > two worth of time and I would like to get the metadata fixed now, so
> >> > that I can finally move on with runltp-ng. So I would slightly prefer
> >> > merging the patches for the current solution first, then we can have a
> >> > look on tree-sitter in the next LTP release cycle. What do you think?
> >> 
> >> I think there is a small risk
> >> 
> >> 1. It turns out that with tree-sitter it would make more sense to use a
> >>    different meta-data format.
> >
> > What do you have in mind? I do not think that we should dramatically
> > chante the json structure we do have now.
> 
> Whatever tree-sitter produces most naturally and requires the least
> amount of massaging.

I do not think that there will be a big differences though, the only
difference would be that we would get proper types, i.e. strings vs
integers. The rest of the processing we do filters out fields we are not
interested in, or checks if implied flags are not defined, etc. that is
going to stay regardless.

> >> Note that in general I think it's best (on bigger projects) to have an
> >> alternative branch for big changes where one needs to "rush" to an
> >> end-to-end solution. Most likely we need an alternate branch for
> >> integrating runltp-ng and the executor.
> >
> > We can even do this in a separate github repository or whatever works,
> > but still we have to agree on general direction.
> >
> > I still think that the best solution here is to apply this patchset and
> > put the tree-sitter on TODO. Unlike tree-sitter this is neither big nor
> > radical change and it would allow us to proceed with other stuff that
> > has been blocked for several releases at least.
> 
> As discussed in IRC, I prefer the route of trying either Sparse or
> Tree-sitter first to produce the metadata. However please go ahead and
> make the decision. After all once we have better automation it will
> reduce the burden on reviewers.

I've send a v2 for the patchset. I still think that we should merge
that in order to get usable metadata now so that we can finally
implement/fix several issues, namely:

https://github.com/linux-test-project/ltp/issues/868

Here we really need the metadata available and loaded in the testrunner
so that we know that reboot is comming. This one can be implemented only
with the last patch of the series that installs the json metadata
unconditionally.


https://github.com/linux-test-project/ltp/issues/824

This one is more complicated though, also the mmap1 is not the only test
that suffers from this condition, there is at least writev03 that
suffers from timeouts.

In order to compute the test runtime properly we need to know the upper
limit for the test iterations, which is currently multiplication of
.test_variants and supported filesystems if .all_filesystems is set,
which is the main motivation behing pushing this patchset forward along
with the runtime patchset. Once these two are merged, the test runtime
and safe enough timeout can be easily computed from the test metadata
and used by the testrunners.

-- 
Cyril Hrubis
chrubis@suse.cz

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2021-11-01 15:09 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-18 15:47 [LTP] [PATCH 0/7] docparse improvements Cyril Hrubis
2021-10-18 15:47 ` [LTP] [PATCH 1/7] docparse: Implement #define and #include Cyril Hrubis
2021-10-29  8:26   ` Petr Vorel
2021-10-29  8:27   ` Petr Vorel
2021-10-18 15:47 ` [LTP] [PATCH 2/7] docparse: Add tests Cyril Hrubis
2021-10-22 11:32   ` Petr Vorel
2021-10-25 12:46     ` Cyril Hrubis
2021-10-25 20:00       ` Petr Vorel
2021-10-22 11:41   ` Petr Vorel
2021-10-25 12:51     ` Cyril Hrubis
2021-10-25 20:01       ` Petr Vorel
2021-10-18 15:47 ` [LTP] [PATCH 3/7] docparse: data_storage: Add integer type node Cyril Hrubis
2021-10-18 15:47 ` [LTP] [PATCH 4/7] docparse: Implement ARRAY_SIZE() Cyril Hrubis
2021-11-01 12:36   ` Richard Palethorpe
2021-11-01 13:18     ` Cyril Hrubis
2021-10-18 15:47 ` [LTP] [PATCH 5/7] docparse: Add type normalization Cyril Hrubis
2021-10-18 15:47 ` [LTP] [PATCH 6/7] docparse: Group data to 'testsuite' and 'defaults' Cyril Hrubis
2021-10-18 15:47 ` [LTP] [PATCH 7/7] docparse/Makefile: Do not abort on missing generators Cyril Hrubis
2021-10-22 11:29   ` Petr Vorel
2021-10-25 12:48     ` Cyril Hrubis
2021-10-27  9:47       ` Petr Vorel
2021-10-18 15:48 ` [LTP] [PATCH 0/7] docparse improvements Cyril Hrubis
2021-10-27 13:22 ` Richard Palethorpe
2021-10-27 13:48   ` Cyril Hrubis
2021-10-28  8:11     ` Richard Palethorpe
2021-10-29  8:54       ` Cyril Hrubis
2021-11-01  9:04         ` Richard Palethorpe
2021-11-01  9:59           ` Cyril Hrubis
2021-11-01 12:20             ` Richard Palethorpe
2021-11-01 15:10               ` Cyril Hrubis

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).