public inbox for linux-kbuild@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/27] kconfig: refactor lexer and parser code
@ 2024-02-02 15:57 Masahiro Yamada
  2024-02-02 15:57 ` [PATCH 01/27] kconfig: fix infinite loop when expanding a macro at the end of file Masahiro Yamada
                   ` (27 more replies)
  0 siblings, 28 replies; 29+ messages in thread
From: Masahiro Yamada @ 2024-02-02 15:57 UTC (permalink / raw)
  To: linux-kbuild; +Cc: linux-kernel, Masahiro Yamada

Random fixes, cleanups, etc.

Masahiro Yamada (27):
  kconfig: fix infinite loop when expanding a macro at the end of file
  kconfig: fix off-by-one in zconf_error()
  kconfig: remove orphan lookup_file() declaration
  kconfig: remove compat_getline()
  kconfig: remove unneeded sym_find() call in conf_parse()
  kconfig: write Kconfig files to autoconf.cmd in order
  kconfig: call env_write_dep() right after yyparse()
  kconfig: split preprocessor prototypes into preprocess.h
  kconfig: replace current_pos with separate cur_{filename,lineno}
  kconfig: remove zconf_curname() and zconf_lineno()
  kconfig: associate struct menu with file name directly
  kconfig: associate struct property with file name directly
  kconfig: replace file->name with name in zconf_nextfile()
  kconfig: do not delay the cur_filename update
  kconfig: replace remaining current_file->name with cur_filename
  kconfig: move the file and lineno in struct file to struct buffer
  kconfig: make file::name a flexible array member
  kconfig: change file_lookup() to return the file name
  kconfig: split list_head into a separate header
  kconfig: resync list.h
  kconfig: import more list macros and inline functions
  kconfig: add macros useful for hashtable
  kconfig: move ARRAY_SIZE to a header
  kconfig: move strhash() to a header
  kconfig: convert linked list of files to hash table
  kconfig: use generic macros to implement symbol hashtable
  kconfig: do not imply the type of choice value

 scripts/kconfig/array_size.h |  11 ++
 scripts/kconfig/conf.c       |  12 +-
 scripts/kconfig/confdata.c   |  91 +++----------
 scripts/kconfig/expr.h       |  24 +---
 scripts/kconfig/hashtable.h  |  48 +++++++
 scripts/kconfig/internal.h   |  12 ++
 scripts/kconfig/lexer.l      | 100 +++++++-------
 scripts/kconfig/list.h       | 254 ++++++++++++++++++++++++++---------
 scripts/kconfig/list_types.h |  17 +++
 scripts/kconfig/lkc.h        |   5 +-
 scripts/kconfig/lkc_proto.h  |  15 ---
 scripts/kconfig/mconf.c      |   1 +
 scripts/kconfig/menu.c       |  24 ++--
 scripts/kconfig/nconf.c      |   1 +
 scripts/kconfig/parser.y     |  92 +++++++------
 scripts/kconfig/preprocess.c |  23 ++--
 scripts/kconfig/preprocess.h |  19 +++
 scripts/kconfig/qconf.cc     |   2 +-
 scripts/kconfig/symbol.c     |  46 +++----
 scripts/kconfig/util.c       |  38 ++++--
 scripts/kconfig/util.h       |  15 +++
 21 files changed, 511 insertions(+), 339 deletions(-)
 create mode 100644 scripts/kconfig/array_size.h
 create mode 100644 scripts/kconfig/hashtable.h
 create mode 100644 scripts/kconfig/list_types.h
 create mode 100644 scripts/kconfig/preprocess.h
 create mode 100644 scripts/kconfig/util.h

-- 
2.40.1


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

* [PATCH 01/27] kconfig: fix infinite loop when expanding a macro at the end of file
  2024-02-02 15:57 [PATCH 00/27] kconfig: refactor lexer and parser code Masahiro Yamada
@ 2024-02-02 15:57 ` Masahiro Yamada
  2024-02-02 15:58 ` [PATCH 02/27] kconfig: fix off-by-one in zconf_error() Masahiro Yamada
                   ` (26 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: Masahiro Yamada @ 2024-02-02 15:57 UTC (permalink / raw)
  To: linux-kbuild; +Cc: linux-kernel, Masahiro Yamada

A macro placed at the end of a file with no newline causes an infinite
loop.

[Test Kconfig]
  $(info,hello)
  \ No newline at end of file

I realized that flex-provided input() returns 0 instead of EOF when it
reaches the end of a file.

Fixes: 104daea149c4 ("kconfig: reference environment variables directly and remove 'option env='")
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
---

 scripts/kconfig/lexer.l | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/scripts/kconfig/lexer.l b/scripts/kconfig/lexer.l
index f93b535a080c..5f1bc3320307 100644
--- a/scripts/kconfig/lexer.l
+++ b/scripts/kconfig/lexer.l
@@ -303,8 +303,11 @@ static char *expand_token(const char *in, size_t n)
 	new_string();
 	append_string(in, n);
 
-	/* get the whole line because we do not know the end of token. */
-	while ((c = input()) != EOF) {
+	/*
+	 * get the whole line because we do not know the end of token.
+	 * input() returns 0 (not EOF!) when it reachs the end of file.
+	 */
+	while ((c = input()) != 0) {
 		if (c == '\n') {
 			unput(c);
 			break;
-- 
2.40.1


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

* [PATCH 02/27] kconfig: fix off-by-one in zconf_error()
  2024-02-02 15:57 [PATCH 00/27] kconfig: refactor lexer and parser code Masahiro Yamada
  2024-02-02 15:57 ` [PATCH 01/27] kconfig: fix infinite loop when expanding a macro at the end of file Masahiro Yamada
@ 2024-02-02 15:58 ` Masahiro Yamada
  2024-02-02 15:58 ` [PATCH 03/27] kconfig: remove orphan lookup_file() declaration Masahiro Yamada
                   ` (25 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: Masahiro Yamada @ 2024-02-02 15:58 UTC (permalink / raw)
  To: linux-kbuild; +Cc: linux-kernel, Masahiro Yamada

yyerror() reports the line number of the next line.

This +1 adjustment was introduced more than 20 years ago [1]. At that
time, the line number was decremented then incremented back and forth.

The line number management was refactored in a more maintainable way.
Such compensation is no longer needed.

[1]: https://git.kernel.org/pub/scm/linux/kernel/git/history/history.git/commit/?id=d4f8a4530eb07a1385fd17b0e62a7dce97486f49

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
---

 scripts/kconfig/parser.y | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/kconfig/parser.y b/scripts/kconfig/parser.y
index 2af7ce4e1531..5ab2e3f7ca33 100644
--- a/scripts/kconfig/parser.y
+++ b/scripts/kconfig/parser.y
@@ -557,7 +557,7 @@ static void zconf_error(const char *err, ...)
 
 static void yyerror(const char *err)
 {
-	fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
+	fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno(), err);
 }
 
 static void print_quoted_string(FILE *out, const char *str)
-- 
2.40.1


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

* [PATCH 03/27] kconfig: remove orphan lookup_file() declaration
  2024-02-02 15:57 [PATCH 00/27] kconfig: refactor lexer and parser code Masahiro Yamada
  2024-02-02 15:57 ` [PATCH 01/27] kconfig: fix infinite loop when expanding a macro at the end of file Masahiro Yamada
  2024-02-02 15:58 ` [PATCH 02/27] kconfig: fix off-by-one in zconf_error() Masahiro Yamada
@ 2024-02-02 15:58 ` Masahiro Yamada
  2024-02-02 15:58 ` [PATCH 04/27] kconfig: remove compat_getline() Masahiro Yamada
                   ` (24 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: Masahiro Yamada @ 2024-02-02 15:58 UTC (permalink / raw)
  To: linux-kbuild; +Cc: linux-kernel, Masahiro Yamada

There is no definition, no caller for lookup_file().

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
---

 scripts/kconfig/expr.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index 4a9a23b1b7e1..e0d866569155 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -279,7 +279,6 @@ struct jump_key {
 
 extern struct file *file_list;
 extern struct file *current_file;
-struct file *lookup_file(const char *name);
 
 extern struct symbol symbol_yes, symbol_no, symbol_mod;
 extern struct symbol *modules_sym;
-- 
2.40.1


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

* [PATCH 04/27] kconfig: remove compat_getline()
  2024-02-02 15:57 [PATCH 00/27] kconfig: refactor lexer and parser code Masahiro Yamada
                   ` (2 preceding siblings ...)
  2024-02-02 15:58 ` [PATCH 03/27] kconfig: remove orphan lookup_file() declaration Masahiro Yamada
@ 2024-02-02 15:58 ` Masahiro Yamada
  2024-02-02 15:58 ` [PATCH 05/27] kconfig: remove unneeded sym_find() call in conf_parse() Masahiro Yamada
                   ` (23 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: Masahiro Yamada @ 2024-02-02 15:58 UTC (permalink / raw)
  To: linux-kbuild; +Cc: linux-kernel, Masahiro Yamada

Commit 1a7a8c6fd8ca ("kconfig: allow long lines in config file") added
a self-implemented getline() for better portability.

However, getline() is standardized [1] and already used in other programs
such as scripts/kallsyms.c.

Use getline() provided by libc.

[1]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getdelim.html

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
---

 scripts/kconfig/confdata.c | 53 +-------------------------------------
 1 file changed, 1 insertion(+), 52 deletions(-)

diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index f53dcdd44597..7f0aa39b68c1 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -293,63 +293,12 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
 	return 0;
 }
 
-#define LINE_GROWTH 16
-static int add_byte(int c, char **lineptr, size_t slen, size_t *n)
-{
-	size_t new_size = slen + 1;
-
-	if (new_size > *n) {
-		new_size += LINE_GROWTH - 1;
-		new_size *= 2;
-		*lineptr = xrealloc(*lineptr, new_size);
-		*n = new_size;
-	}
-
-	(*lineptr)[slen] = c;
-
-	return 0;
-}
-
-static ssize_t compat_getline(char **lineptr, size_t *n, FILE *stream)
-{
-	char *line = *lineptr;
-	size_t slen = 0;
-
-	for (;;) {
-		int c = getc(stream);
-
-		switch (c) {
-		case '\n':
-			if (add_byte(c, &line, slen, n) < 0)
-				goto e_out;
-			slen++;
-			/* fall through */
-		case EOF:
-			if (add_byte('\0', &line, slen, n) < 0)
-				goto e_out;
-			*lineptr = line;
-			if (slen == 0)
-				return -1;
-			return slen;
-		default:
-			if (add_byte(c, &line, slen, n) < 0)
-				goto e_out;
-			slen++;
-		}
-	}
-
-e_out:
-	line[slen-1] = '\0';
-	*lineptr = line;
-	return -1;
-}
-
 /* like getline(), but the newline character is stripped away */
 static ssize_t getline_stripped(char **lineptr, size_t *n, FILE *stream)
 {
 	ssize_t len;
 
-	len = compat_getline(lineptr, n, stream);
+	len = getline(lineptr, n, stream);
 
 	if (len > 0 && (*lineptr)[len - 1] == '\n') {
 		len--;
-- 
2.40.1


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

* [PATCH 05/27] kconfig: remove unneeded sym_find() call in conf_parse()
  2024-02-02 15:57 [PATCH 00/27] kconfig: refactor lexer and parser code Masahiro Yamada
                   ` (3 preceding siblings ...)
  2024-02-02 15:58 ` [PATCH 04/27] kconfig: remove compat_getline() Masahiro Yamada
@ 2024-02-02 15:58 ` Masahiro Yamada
  2024-02-02 15:58 ` [PATCH 06/27] kconfig: write Kconfig files to autoconf.cmd in order Masahiro Yamada
                   ` (22 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: Masahiro Yamada @ 2024-02-02 15:58 UTC (permalink / raw)
  To: linux-kbuild; +Cc: linux-kernel, Masahiro Yamada

sym_find("n") is equivalent to &symbol_no.

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
---

 scripts/kconfig/parser.y | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/kconfig/parser.y b/scripts/kconfig/parser.y
index 5ab2e3f7ca33..625224973c51 100644
--- a/scripts/kconfig/parser.y
+++ b/scripts/kconfig/parser.y
@@ -494,7 +494,7 @@ void conf_parse(const char *name)
 	if (yynerrs)
 		exit(1);
 	if (!modules_sym)
-		modules_sym = sym_find( "n" );
+		modules_sym = &symbol_no;
 
 	if (!menu_has_prompt(&rootmenu)) {
 		current_entry = &rootmenu;
-- 
2.40.1


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

* [PATCH 06/27] kconfig: write Kconfig files to autoconf.cmd in order
  2024-02-02 15:57 [PATCH 00/27] kconfig: refactor lexer and parser code Masahiro Yamada
                   ` (4 preceding siblings ...)
  2024-02-02 15:58 ` [PATCH 05/27] kconfig: remove unneeded sym_find() call in conf_parse() Masahiro Yamada
@ 2024-02-02 15:58 ` Masahiro Yamada
  2024-02-02 15:58 ` [PATCH 07/27] kconfig: call env_write_dep() right after yyparse() Masahiro Yamada
                   ` (21 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: Masahiro Yamada @ 2024-02-02 15:58 UTC (permalink / raw)
  To: linux-kbuild; +Cc: linux-kernel, Masahiro Yamada

Currently, include/config/autoconf.cmd saves included Kconfig files in
reverse order. While this is not a big deal, it is inconsistent with
other *.cmd files generated by fixdep.

Output the included Kconfig files in the included order.

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
---

 scripts/kconfig/confdata.c | 7 +++----
 scripts/kconfig/lkc.h      | 1 +
 scripts/kconfig/parser.y   | 4 ++++
 scripts/kconfig/util.c     | 3 +++
 4 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index 7f0aa39b68c1..f6a96fdddb7e 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -20,6 +20,8 @@
 
 #include "lkc.h"
 
+struct gstr autoconf_cmd;
+
 /* return true if 'path' exists, false otherwise */
 static bool is_present(const char *path)
 {
@@ -972,7 +974,6 @@ int conf_write(const char *name)
 static int conf_write_autoconf_cmd(const char *autoconf_name)
 {
 	char name[PATH_MAX], tmp[PATH_MAX];
-	struct file *file;
 	FILE *out;
 	int ret;
 
@@ -993,9 +994,7 @@ static int conf_write_autoconf_cmd(const char *autoconf_name)
 		return -1;
 	}
 
-	fprintf(out, "deps_config := \\\n");
-	for (file = file_list; file; file = file->next)
-		fprintf(out, "\t%s \\\n", file->name);
+	fputs(str_get(&autoconf_cmd), out);
 
 	fprintf(out, "\n%s: $(deps_config)\n\n", autoconf_name);
 
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index 5cdc8f5e6446..8616ad83be6d 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -40,6 +40,7 @@ int zconf_lineno(void);
 const char *zconf_curname(void);
 
 /* confdata.c */
+extern struct gstr autoconf_cmd;
 const char *conf_get_configname(void);
 void set_all_choice_values(struct symbol *csym);
 
diff --git a/scripts/kconfig/parser.y b/scripts/kconfig/parser.y
index 625224973c51..611038c502fc 100644
--- a/scripts/kconfig/parser.y
+++ b/scripts/kconfig/parser.y
@@ -480,6 +480,10 @@ void conf_parse(const char *name)
 	struct symbol *sym;
 	int i;
 
+	autoconf_cmd = str_new();
+
+	str_printf(&autoconf_cmd, "deps_config := \\\n");
+
 	zconf_initscan(name);
 
 	_menu_init();
diff --git a/scripts/kconfig/util.c b/scripts/kconfig/util.c
index 92e5b2b9761d..958543bb0a37 100644
--- a/scripts/kconfig/util.c
+++ b/scripts/kconfig/util.c
@@ -25,6 +25,9 @@ struct file *file_lookup(const char *name)
 	file->name = xstrdup(name);
 	file->next = file_list;
 	file_list = file;
+
+	str_printf(&autoconf_cmd, "\t%s \\\n", name);
+
 	return file;
 }
 
-- 
2.40.1


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

* [PATCH 07/27] kconfig: call env_write_dep() right after yyparse()
  2024-02-02 15:57 [PATCH 00/27] kconfig: refactor lexer and parser code Masahiro Yamada
                   ` (5 preceding siblings ...)
  2024-02-02 15:58 ` [PATCH 06/27] kconfig: write Kconfig files to autoconf.cmd in order Masahiro Yamada
@ 2024-02-02 15:58 ` Masahiro Yamada
  2024-02-02 15:58 ` [PATCH 08/27] kconfig: split preprocessor prototypes into preprocess.h Masahiro Yamada
                   ` (20 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: Masahiro Yamada @ 2024-02-02 15:58 UTC (permalink / raw)
  To: linux-kbuild; +Cc: linux-kernel, Masahiro Yamada

This allows preprocess.c to free up all of its resources when the parse
stage is finished. It also ensures conf_write_autoconf_cmd() produces
consistent results even if called multiple times for any reason.

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
---

 scripts/kconfig/confdata.c   |  8 ++------
 scripts/kconfig/lkc_proto.h  |  2 +-
 scripts/kconfig/parser.y     |  9 ++++++++-
 scripts/kconfig/preprocess.c | 11 +++++++----
 4 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index f6a96fdddb7e..dafc572e7b7e 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -994,14 +994,10 @@ static int conf_write_autoconf_cmd(const char *autoconf_name)
 		return -1;
 	}
 
+	fprintf(out, "autoconfig := %s\n", autoconf_name);
+
 	fputs(str_get(&autoconf_cmd), out);
 
-	fprintf(out, "\n%s: $(deps_config)\n\n", autoconf_name);
-
-	env_write_dep(out, autoconf_name);
-
-	fprintf(out, "\n$(deps_config): ;\n");
-
 	fflush(out);
 	ret = ferror(out); /* error check for all fprintf() calls */
 	fclose(out);
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h
index a4ae5e9eadad..85491d74a094 100644
--- a/scripts/kconfig/lkc_proto.h
+++ b/scripts/kconfig/lkc_proto.h
@@ -46,7 +46,7 @@ enum variable_flavor {
 	VAR_RECURSIVE,
 	VAR_APPEND,
 };
-void env_write_dep(FILE *f, const char *auto_conf_name);
+void env_write_dep(struct gstr *gs);
 void variable_add(const char *name, const char *value,
 		  enum variable_flavor flavor);
 void variable_all_del(void);
diff --git a/scripts/kconfig/parser.y b/scripts/kconfig/parser.y
index 611038c502fc..cfb82ba09037 100644
--- a/scripts/kconfig/parser.y
+++ b/scripts/kconfig/parser.y
@@ -482,7 +482,7 @@ void conf_parse(const char *name)
 
 	autoconf_cmd = str_new();
 
-	str_printf(&autoconf_cmd, "deps_config := \\\n");
+	str_printf(&autoconf_cmd, "\ndeps_config := \\\n");
 
 	zconf_initscan(name);
 
@@ -492,6 +492,13 @@ void conf_parse(const char *name)
 		yydebug = 1;
 	yyparse();
 
+	str_printf(&autoconf_cmd,
+		   "\n"
+		   "$(autoconfig): $(deps_config)\n"
+		   "$(deps_config): ;\n");
+
+	env_write_dep(&autoconf_cmd);
+
 	/* Variables are expanded in the parse phase. We can free them here. */
 	variable_all_del();
 
diff --git a/scripts/kconfig/preprocess.c b/scripts/kconfig/preprocess.c
index d1f5bcff4b62..b9853d4a891c 100644
--- a/scripts/kconfig/preprocess.c
+++ b/scripts/kconfig/preprocess.c
@@ -87,14 +87,17 @@ static char *env_expand(const char *name)
 	return xstrdup(value);
 }
 
-void env_write_dep(FILE *f, const char *autoconfig_name)
+void env_write_dep(struct gstr *s)
 {
 	struct env *e, *tmp;
 
 	list_for_each_entry_safe(e, tmp, &env_list, node) {
-		fprintf(f, "ifneq \"$(%s)\" \"%s\"\n", e->name, e->value);
-		fprintf(f, "%s: FORCE\n", autoconfig_name);
-		fprintf(f, "endif\n");
+		str_printf(s,
+			   "\n"
+			   "ifneq \"$(%s)\" \"%s\"\n"
+			   "$(autoconfig): FORCE\n"
+			   "endif\n",
+			   e->name, e->value);
 		env_del(e);
 	}
 }
-- 
2.40.1


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

* [PATCH 08/27] kconfig: split preprocessor prototypes into preprocess.h
  2024-02-02 15:57 [PATCH 00/27] kconfig: refactor lexer and parser code Masahiro Yamada
                   ` (6 preceding siblings ...)
  2024-02-02 15:58 ` [PATCH 07/27] kconfig: call env_write_dep() right after yyparse() Masahiro Yamada
@ 2024-02-02 15:58 ` Masahiro Yamada
  2024-02-02 15:58 ` [PATCH 09/27] kconfig: replace current_pos with separate cur_{filename,lineno} Masahiro Yamada
                   ` (19 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: Masahiro Yamada @ 2024-02-02 15:58 UTC (permalink / raw)
  To: linux-kbuild; +Cc: linux-kernel, Masahiro Yamada

These are needed only for the parse stage. Move the prototypes into
a separate header to make sure they are not used after that.

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
---

 scripts/kconfig/lexer.l      |  2 ++
 scripts/kconfig/lkc_proto.h  | 13 -------------
 scripts/kconfig/parser.y     |  1 +
 scripts/kconfig/preprocess.c |  1 +
 scripts/kconfig/preprocess.h | 19 +++++++++++++++++++
 5 files changed, 23 insertions(+), 13 deletions(-)
 create mode 100644 scripts/kconfig/preprocess.h

diff --git a/scripts/kconfig/lexer.l b/scripts/kconfig/lexer.l
index 5f1bc3320307..1bb372868ecf 100644
--- a/scripts/kconfig/lexer.l
+++ b/scripts/kconfig/lexer.l
@@ -14,6 +14,8 @@
 #include <string.h>
 
 #include "lkc.h"
+#include "preprocess.h"
+
 #include "parser.tab.h"
 
 #define YY_DECL		static int yylex1(void)
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h
index 85491d74a094..94299e42402f 100644
--- a/scripts/kconfig/lkc_proto.h
+++ b/scripts/kconfig/lkc_proto.h
@@ -40,19 +40,6 @@ const char * sym_get_string_value(struct symbol *sym);
 
 const char * prop_get_type_name(enum prop_type type);
 
-/* preprocess.c */
-enum variable_flavor {
-	VAR_SIMPLE,
-	VAR_RECURSIVE,
-	VAR_APPEND,
-};
-void env_write_dep(struct gstr *gs);
-void variable_add(const char *name, const char *value,
-		  enum variable_flavor flavor);
-void variable_all_del(void);
-char *expand_dollar(const char **str);
-char *expand_one_token(const char **str);
-
 /* expr.c */
 void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken);
 
diff --git a/scripts/kconfig/parser.y b/scripts/kconfig/parser.y
index cfb82ba09037..ff68def09a2b 100644
--- a/scripts/kconfig/parser.y
+++ b/scripts/kconfig/parser.y
@@ -13,6 +13,7 @@
 
 #include "lkc.h"
 #include "internal.h"
+#include "preprocess.h"
 
 #define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
 
diff --git a/scripts/kconfig/preprocess.c b/scripts/kconfig/preprocess.c
index b9853d4a891c..12665b981c3e 100644
--- a/scripts/kconfig/preprocess.c
+++ b/scripts/kconfig/preprocess.c
@@ -11,6 +11,7 @@
 
 #include "list.h"
 #include "lkc.h"
+#include "preprocess.h"
 
 #define ARRAY_SIZE(arr)		(sizeof(arr) / sizeof((arr)[0]))
 
diff --git a/scripts/kconfig/preprocess.h b/scripts/kconfig/preprocess.h
new file mode 100644
index 000000000000..a7e4a550638c
--- /dev/null
+++ b/scripts/kconfig/preprocess.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef PREPROCESS_H
+#define PREPROCESS_H
+
+enum variable_flavor {
+	VAR_SIMPLE,
+	VAR_RECURSIVE,
+	VAR_APPEND,
+};
+
+struct gstr;
+void env_write_dep(struct gstr *gs);
+void variable_add(const char *name, const char *value,
+		  enum variable_flavor flavor);
+void variable_all_del(void);
+char *expand_dollar(const char **str);
+char *expand_one_token(const char **str);
+
+#endif /* PREPROCESS_H */
-- 
2.40.1


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

* [PATCH 09/27] kconfig: replace current_pos with separate cur_{filename,lineno}
  2024-02-02 15:57 [PATCH 00/27] kconfig: refactor lexer and parser code Masahiro Yamada
                   ` (7 preceding siblings ...)
  2024-02-02 15:58 ` [PATCH 08/27] kconfig: split preprocessor prototypes into preprocess.h Masahiro Yamada
@ 2024-02-02 15:58 ` Masahiro Yamada
  2024-02-02 15:58 ` [PATCH 10/27] kconfig: remove zconf_curname() and zconf_lineno() Masahiro Yamada
                   ` (18 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: Masahiro Yamada @ 2024-02-02 15:58 UTC (permalink / raw)
  To: linux-kbuild; +Cc: linux-kernel, Masahiro Yamada

Replace current_pos with separate variables representing the file name
and the line number, respectively.

No functional change is intended.

By the way, you might wonder why the "<none>" fallback exists in
zconf_curname(). menu_add_symbol() saves the current file and the line
number. It is intended to be called only during the yyparse() time.
However, menu_finalize() calls it, where there is no file being parsed.
This is a long-standing hack that should be fixed later. I left a FIXME
comment.

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
---

 scripts/kconfig/lexer.l | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/scripts/kconfig/lexer.l b/scripts/kconfig/lexer.l
index 1bb372868ecf..540098435a3b 100644
--- a/scripts/kconfig/lexer.l
+++ b/scripts/kconfig/lexer.l
@@ -22,10 +22,14 @@
 
 #define START_STRSIZE	16
 
-static struct {
-	struct file *file;
-	int lineno;
-} current_pos;
+/* The Kconfig file currently being parsed.  */
+static const char *cur_filename;
+
+/*
+ * The line number of the current statement. This does not match yylineno.
+ * yylineno is used by the lexer, while cur_lineno is used by the parser.
+ */
+static int cur_lineno;
 
 static int prev_prev_token = T_EOL;
 static int prev_token = T_EOL;
@@ -279,9 +283,14 @@ repeat:
 			 * of each statement. Generally, \n is a statement
 			 * terminator in Kconfig, but it is not always true
 			 * because \n could be escaped by a backslash.
+			 *
+			 * FIXME:
+			 * cur_filename and cur_lineno are used even after
+			 * yyparse(); menu_finalize() calls menu_add_symbol().
+			 * This should be fixed.
 			 */
-			current_pos.file = current_file;
-			current_pos.lineno = yylineno;
+			cur_filename = current_file ? current_file->name : "<none>";
+			cur_lineno = yylineno;
 		}
 	}
 
@@ -462,10 +471,10 @@ static void zconf_endfile(void)
 
 int zconf_lineno(void)
 {
-	return current_pos.lineno;
+	return cur_lineno;
 }
 
 const char *zconf_curname(void)
 {
-	return current_pos.file ? current_pos.file->name : "<none>";
+	return cur_filename;
 }
-- 
2.40.1


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

* [PATCH 10/27] kconfig: remove zconf_curname() and zconf_lineno()
  2024-02-02 15:57 [PATCH 00/27] kconfig: refactor lexer and parser code Masahiro Yamada
                   ` (8 preceding siblings ...)
  2024-02-02 15:58 ` [PATCH 09/27] kconfig: replace current_pos with separate cur_{filename,lineno} Masahiro Yamada
@ 2024-02-02 15:58 ` Masahiro Yamada
  2024-02-02 15:58 ` [PATCH 11/27] kconfig: associate struct menu with file name directly Masahiro Yamada
                   ` (17 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: Masahiro Yamada @ 2024-02-02 15:58 UTC (permalink / raw)
  To: linux-kbuild; +Cc: linux-kernel, Masahiro Yamada

Now zconf_curname() and zconf_lineno() are so simple that they just
return cur_filename, cur_lineno, respectively.

Remove these functions, and then use cur_filename and cur_lineno
directly.

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
---

 scripts/kconfig/internal.h |  3 ++
 scripts/kconfig/lexer.l    | 20 ++++---------
 scripts/kconfig/lkc.h      |  2 --
 scripts/kconfig/menu.c     |  4 +--
 scripts/kconfig/parser.y   | 59 +++++++++++++++++---------------------
 5 files changed, 37 insertions(+), 51 deletions(-)

diff --git a/scripts/kconfig/internal.h b/scripts/kconfig/internal.h
index 2f7298c21b64..788401cd5d6f 100644
--- a/scripts/kconfig/internal.h
+++ b/scripts/kconfig/internal.h
@@ -6,4 +6,7 @@ struct menu;
 
 extern struct menu *current_menu, *current_entry;
 
+extern const char *cur_filename;
+extern int cur_lineno;
+
 #endif /* INTERNAL_H */
diff --git a/scripts/kconfig/lexer.l b/scripts/kconfig/lexer.l
index 540098435a3b..3b3893f673dc 100644
--- a/scripts/kconfig/lexer.l
+++ b/scripts/kconfig/lexer.l
@@ -23,13 +23,13 @@
 #define START_STRSIZE	16
 
 /* The Kconfig file currently being parsed.  */
-static const char *cur_filename;
+const char *cur_filename;
 
 /*
  * The line number of the current statement. This does not match yylineno.
  * yylineno is used by the lexer, while cur_lineno is used by the parser.
  */
-static int cur_lineno;
+int cur_lineno;
 
 static int prev_prev_token = T_EOL;
 static int prev_token = T_EOL;
@@ -187,7 +187,7 @@ n	[A-Za-z0-9_-]
 	\n	{
 		fprintf(stderr,
 			"%s:%d:warning: multi-line strings not supported\n",
-			zconf_curname(), zconf_lineno());
+			cur_filename, cur_lineno);
 		unput('\n');
 		BEGIN(INITIAL);
 		yylval.string = text;
@@ -423,12 +423,12 @@ void zconf_nextfile(const char *name)
 	yyin = zconf_fopen(file->name);
 	if (!yyin) {
 		fprintf(stderr, "%s:%d: can't open file \"%s\"\n",
-			zconf_curname(), zconf_lineno(), file->name);
+			cur_filename, cur_lineno, file->name);
 		exit(1);
 	}
 	yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
 
-	current_file->lineno = zconf_lineno();
+	current_file->lineno = cur_lineno;
 	file->parent = current_file;
 
 	for (iter = current_file; iter; iter = iter->parent) {
@@ -468,13 +468,3 @@ static void zconf_endfile(void)
 	current_buf = current_buf->parent;
 	free(tmp);
 }
-
-int zconf_lineno(void)
-{
-	return cur_lineno;
-}
-
-const char *zconf_curname(void)
-{
-	return cur_filename;
-}
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index 8616ad83be6d..d8249052f2e3 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -36,8 +36,6 @@ void zconf_starthelp(void);
 FILE *zconf_fopen(const char *name);
 void zconf_initscan(const char *name);
 void zconf_nextfile(const char *name);
-int zconf_lineno(void);
-const char *zconf_curname(void);
 
 /* confdata.c */
 extern struct gstr autoconf_cmd;
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 2cce8b651f61..ddca95879631 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -54,7 +54,7 @@ void menu_add_entry(struct symbol *sym)
 	menu->sym = sym;
 	menu->parent = current_menu;
 	menu->file = current_file;
-	menu->lineno = zconf_lineno();
+	menu->lineno = cur_lineno;
 
 	*last_entry_ptr = menu;
 	last_entry_ptr = &menu->next;
@@ -135,7 +135,7 @@ static struct property *menu_add_prop(enum prop_type type, struct expr *expr,
 	memset(prop, 0, sizeof(*prop));
 	prop->type = type;
 	prop->file = current_file;
-	prop->lineno = zconf_lineno();
+	prop->lineno = cur_lineno;
 	prop->menu = current_entry;
 	prop->expr = expr;
 	prop->visible.expr = dep;
diff --git a/scripts/kconfig/parser.y b/scripts/kconfig/parser.y
index ff68def09a2b..b9d7e26fc160 100644
--- a/scripts/kconfig/parser.y
+++ b/scripts/kconfig/parser.y
@@ -144,19 +144,19 @@ config_entry_start: T_CONFIG nonconst_symbol T_EOL
 {
 	$2->flags |= SYMBOL_OPTIONAL;
 	menu_add_entry($2);
-	printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2->name);
+	printd(DEBUG_PARSE, "%s:%d:config %s\n", cur_filename, cur_lineno, $2->name);
 };
 
 config_stmt: config_entry_start config_option_list
 {
-	printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
+	printd(DEBUG_PARSE, "%s:%d:endconfig\n", cur_filename, cur_lineno);
 };
 
 menuconfig_entry_start: T_MENUCONFIG nonconst_symbol T_EOL
 {
 	$2->flags |= SYMBOL_OPTIONAL;
 	menu_add_entry($2);
-	printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2->name);
+	printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", cur_filename, cur_lineno, $2->name);
 };
 
 menuconfig_stmt: menuconfig_entry_start config_option_list
@@ -165,7 +165,7 @@ menuconfig_stmt: menuconfig_entry_start config_option_list
 		current_entry->prompt->type = P_MENU;
 	else
 		zconfprint("warning: menuconfig statement without prompt");
-	printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
+	printd(DEBUG_PARSE, "%s:%d:endconfig\n", cur_filename, cur_lineno);
 };
 
 config_option_list:
@@ -178,15 +178,13 @@ config_option_list:
 config_option: type prompt_stmt_opt T_EOL
 {
 	menu_set_type($1);
-	printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
-		zconf_curname(), zconf_lineno(),
-		$1);
+	printd(DEBUG_PARSE, "%s:%d:type(%u)\n", cur_filename, cur_lineno, $1);
 };
 
 config_option: T_PROMPT T_WORD_QUOTE if_expr T_EOL
 {
 	menu_add_prompt(P_PROMPT, $2, $3);
-	printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
+	printd(DEBUG_PARSE, "%s:%d:prompt\n", cur_filename, cur_lineno);
 };
 
 config_option: default expr if_expr T_EOL
@@ -194,27 +192,26 @@ config_option: default expr if_expr T_EOL
 	menu_add_expr(P_DEFAULT, $2, $3);
 	if ($1 != S_UNKNOWN)
 		menu_set_type($1);
-	printd(DEBUG_PARSE, "%s:%d:default(%u)\n",
-		zconf_curname(), zconf_lineno(),
+	printd(DEBUG_PARSE, "%s:%d:default(%u)\n", cur_filename, cur_lineno,
 		$1);
 };
 
 config_option: T_SELECT nonconst_symbol if_expr T_EOL
 {
 	menu_add_symbol(P_SELECT, $2, $3);
-	printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
+	printd(DEBUG_PARSE, "%s:%d:select\n", cur_filename, cur_lineno);
 };
 
 config_option: T_IMPLY nonconst_symbol if_expr T_EOL
 {
 	menu_add_symbol(P_IMPLY, $2, $3);
-	printd(DEBUG_PARSE, "%s:%d:imply\n", zconf_curname(), zconf_lineno());
+	printd(DEBUG_PARSE, "%s:%d:imply\n", cur_filename, cur_lineno);
 };
 
 config_option: T_RANGE symbol symbol if_expr T_EOL
 {
 	menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4);
-	printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno());
+	printd(DEBUG_PARSE, "%s:%d:range\n", cur_filename, cur_lineno);
 };
 
 config_option: T_MODULES T_EOL
@@ -234,7 +231,7 @@ choice: T_CHOICE word_opt T_EOL
 	menu_add_entry(sym);
 	menu_add_expr(P_CHOICE, NULL, NULL);
 	free($2);
-	printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno());
+	printd(DEBUG_PARSE, "%s:%d:choice\n", cur_filename, cur_lineno);
 };
 
 choice_entry: choice choice_option_list
@@ -246,7 +243,7 @@ choice_end: end
 {
 	if (zconf_endtoken($1, "choice")) {
 		menu_end_menu();
-		printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno());
+		printd(DEBUG_PARSE, "%s:%d:endchoice\n", cur_filename, cur_lineno);
 	}
 };
 
@@ -263,27 +260,25 @@ choice_option_list:
 choice_option: T_PROMPT T_WORD_QUOTE if_expr T_EOL
 {
 	menu_add_prompt(P_PROMPT, $2, $3);
-	printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
+	printd(DEBUG_PARSE, "%s:%d:prompt\n", cur_filename, cur_lineno);
 };
 
 choice_option: logic_type prompt_stmt_opt T_EOL
 {
 	menu_set_type($1);
-	printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
-	       zconf_curname(), zconf_lineno(), $1);
+	printd(DEBUG_PARSE, "%s:%d:type(%u)\n", cur_filename, cur_lineno, $1);
 };
 
 choice_option: T_OPTIONAL T_EOL
 {
 	current_entry->sym->flags |= SYMBOL_OPTIONAL;
-	printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno());
+	printd(DEBUG_PARSE, "%s:%d:optional\n", cur_filename, cur_lineno);
 };
 
 choice_option: T_DEFAULT nonconst_symbol if_expr T_EOL
 {
 	menu_add_symbol(P_DEFAULT, $2, $3);
-	printd(DEBUG_PARSE, "%s:%d:default\n",
-	       zconf_curname(), zconf_lineno());
+	printd(DEBUG_PARSE, "%s:%d:default\n", cur_filename, cur_lineno);
 };
 
 type:
@@ -305,7 +300,7 @@ default:
 
 if_entry: T_IF expr T_EOL
 {
-	printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
+	printd(DEBUG_PARSE, "%s:%d:if\n", cur_filename, cur_lineno);
 	menu_add_entry(NULL);
 	menu_add_dep($2);
 	$$ = menu_add_menu();
@@ -315,7 +310,7 @@ if_end: end
 {
 	if (zconf_endtoken($1, "if")) {
 		menu_end_menu();
-		printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno());
+		printd(DEBUG_PARSE, "%s:%d:endif\n", cur_filename, cur_lineno);
 	}
 };
 
@@ -331,7 +326,7 @@ menu: T_MENU T_WORD_QUOTE T_EOL
 {
 	menu_add_entry(NULL);
 	menu_add_prompt(P_MENU, $2, NULL);
-	printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
+	printd(DEBUG_PARSE, "%s:%d:menu\n", cur_filename, cur_lineno);
 };
 
 menu_entry: menu menu_option_list
@@ -343,7 +338,7 @@ menu_end: end
 {
 	if (zconf_endtoken($1, "menu")) {
 		menu_end_menu();
-		printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno());
+		printd(DEBUG_PARSE, "%s:%d:endmenu\n", cur_filename, cur_lineno);
 	}
 };
 
@@ -358,7 +353,7 @@ menu_option_list:
 
 source_stmt: T_SOURCE T_WORD_QUOTE T_EOL
 {
-	printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2);
+	printd(DEBUG_PARSE, "%s:%d:source %s\n", cur_filename, cur_lineno, $2);
 	zconf_nextfile($2);
 	free($2);
 };
@@ -369,7 +364,7 @@ comment: T_COMMENT T_WORD_QUOTE T_EOL
 {
 	menu_add_entry(NULL);
 	menu_add_prompt(P_COMMENT, $2, NULL);
-	printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno());
+	printd(DEBUG_PARSE, "%s:%d:comment\n", cur_filename, cur_lineno);
 };
 
 comment_stmt: comment comment_option_list
@@ -384,7 +379,7 @@ comment_option_list:
 
 help_start: T_HELP T_EOL
 {
-	printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno());
+	printd(DEBUG_PARSE, "%s:%d:help\n", cur_filename, cur_lineno);
 	zconf_starthelp();
 };
 
@@ -409,7 +404,7 @@ help: help_start T_HELPTEXT
 depends: T_DEPENDS T_ON expr T_EOL
 {
 	menu_add_dep($3);
-	printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
+	printd(DEBUG_PARSE, "%s:%d:depends on\n", cur_filename, cur_lineno);
 };
 
 /* visibility option */
@@ -548,7 +543,7 @@ static void zconfprint(const char *err, ...)
 {
 	va_list ap;
 
-	fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
+	fprintf(stderr, "%s:%d: ", cur_filename, cur_lineno);
 	va_start(ap, err);
 	vfprintf(stderr, err, ap);
 	va_end(ap);
@@ -560,7 +555,7 @@ static void zconf_error(const char *err, ...)
 	va_list ap;
 
 	yynerrs++;
-	fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
+	fprintf(stderr, "%s:%d: ", cur_filename, cur_lineno);
 	va_start(ap, err);
 	vfprintf(stderr, err, ap);
 	va_end(ap);
@@ -569,7 +564,7 @@ static void zconf_error(const char *err, ...)
 
 static void yyerror(const char *err)
 {
-	fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno(), err);
+	fprintf(stderr, "%s:%d: %s\n", cur_filename, cur_lineno, err);
 }
 
 static void print_quoted_string(FILE *out, const char *str)
-- 
2.40.1


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

* [PATCH 11/27] kconfig: associate struct menu with file name directly
  2024-02-02 15:57 [PATCH 00/27] kconfig: refactor lexer and parser code Masahiro Yamada
                   ` (9 preceding siblings ...)
  2024-02-02 15:58 ` [PATCH 10/27] kconfig: remove zconf_curname() and zconf_lineno() Masahiro Yamada
@ 2024-02-02 15:58 ` Masahiro Yamada
  2024-02-02 15:58 ` [PATCH 12/27] kconfig: associate struct property " Masahiro Yamada
                   ` (16 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: Masahiro Yamada @ 2024-02-02 15:58 UTC (permalink / raw)
  To: linux-kbuild; +Cc: linux-kernel, Masahiro Yamada

struct menu is linked to struct file for diagnostic purposes.
It is always used to retrieve the file name through menu->file->name.

Associate struct menu with the file name directly.

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
---

 scripts/kconfig/expr.h   | 2 +-
 scripts/kconfig/menu.c   | 6 +++---
 scripts/kconfig/parser.y | 6 +++---
 scripts/kconfig/qconf.cc | 2 +-
 scripts/kconfig/symbol.c | 4 ++--
 5 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index e0d866569155..e8fc85d98cdd 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -256,7 +256,7 @@ struct menu {
 	char *help;
 
 	/* The location where the menu node appears in the Kconfig files */
-	struct file *file;
+	const char *filename;
 	int lineno;
 
 	/* For use by front ends that need to store auxiliary data */
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index ddca95879631..5ad4d2b9fb82 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -23,7 +23,7 @@ void menu_warn(struct menu *menu, const char *fmt, ...)
 {
 	va_list ap;
 	va_start(ap, fmt);
-	fprintf(stderr, "%s:%d:warning: ", menu->file->name, menu->lineno);
+	fprintf(stderr, "%s:%d:warning: ", menu->filename, menu->lineno);
 	vfprintf(stderr, fmt, ap);
 	fprintf(stderr, "\n");
 	va_end(ap);
@@ -53,7 +53,7 @@ void menu_add_entry(struct symbol *sym)
 	memset(menu, 0, sizeof(*menu));
 	menu->sym = sym;
 	menu->parent = current_menu;
-	menu->file = current_file;
+	menu->filename = cur_filename;
 	menu->lineno = cur_lineno;
 
 	*last_entry_ptr = menu;
@@ -676,7 +676,7 @@ struct menu *menu_get_parent_menu(struct menu *menu)
 static void get_def_str(struct gstr *r, struct menu *menu)
 {
 	str_printf(r, "Defined at %s:%d\n",
-		   menu->file->name, menu->lineno);
+		   menu->filename, menu->lineno);
 }
 
 static void get_dep_str(struct gstr *r, struct expr *expr, const char *prefix)
diff --git a/scripts/kconfig/parser.y b/scripts/kconfig/parser.y
index b9d7e26fc160..d1d05c8cd89d 100644
--- a/scripts/kconfig/parser.y
+++ b/scripts/kconfig/parser.y
@@ -101,7 +101,7 @@ struct menu *current_menu, *current_entry;
 
 %destructor {
 	fprintf(stderr, "%s:%d: missing end statement for this entry\n",
-		$$->file->name, $$->lineno);
+		$$->filename, $$->lineno);
 	if (current_menu == $$)
 		menu_end_menu();
 } if_entry menu_entry choice_entry
@@ -527,11 +527,11 @@ static bool zconf_endtoken(const char *tokenname,
 		yynerrs++;
 		return false;
 	}
-	if (current_menu->file != current_file) {
+	if (strcmp(current_menu->filename, cur_filename)) {
 		zconf_error("'%s' in different file than '%s'",
 			    tokenname, expected_tokenname);
 		fprintf(stderr, "%s:%d: location of the '%s'\n",
-			current_menu->file->name, current_menu->lineno,
+			current_menu->filename, current_menu->lineno,
 			expected_tokenname);
 		yynerrs++;
 		return false;
diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc
index 620a3527c767..c6c42c0f4e5d 100644
--- a/scripts/kconfig/qconf.cc
+++ b/scripts/kconfig/qconf.cc
@@ -1058,7 +1058,7 @@ void ConfigInfoView::menuInfo(void)
 				stream << "<br><br>";
 			}
 
-			stream << "defined at " << _menu->file->name << ":"
+			stream << "defined at " << _menu->filename << ":"
 			       << _menu->lineno << "<br><br>";
 		}
 	}
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index e9e9fb8d8674..7647e3e87cd5 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -1045,12 +1045,12 @@ static void sym_check_print_recursive(struct symbol *last_sym)
 
 		if (sym_is_choice(sym)) {
 			fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n",
-				menu->file->name, menu->lineno,
+				menu->filename, menu->lineno,
 				sym->name ? sym->name : "<choice>",
 				next_sym->name ? next_sym->name : "<choice>");
 		} else if (sym_is_choice_value(sym)) {
 			fprintf(stderr, "%s:%d:\tsymbol %s is part of choice %s\n",
-				menu->file->name, menu->lineno,
+				menu->filename, menu->lineno,
 				sym->name ? sym->name : "<choice>",
 				next_sym->name ? next_sym->name : "<choice>");
 		} else if (stack->expr == &sym->dir_dep.expr) {
-- 
2.40.1


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

* [PATCH 12/27] kconfig: associate struct property with file name directly
  2024-02-02 15:57 [PATCH 00/27] kconfig: refactor lexer and parser code Masahiro Yamada
                   ` (10 preceding siblings ...)
  2024-02-02 15:58 ` [PATCH 11/27] kconfig: associate struct menu with file name directly Masahiro Yamada
@ 2024-02-02 15:58 ` Masahiro Yamada
  2024-02-02 15:58 ` [PATCH 13/27] kconfig: replace file->name with name in zconf_nextfile() Masahiro Yamada
                   ` (15 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: Masahiro Yamada @ 2024-02-02 15:58 UTC (permalink / raw)
  To: linux-kbuild; +Cc: linux-kernel, Masahiro Yamada

struct property is linked to struct file for diagnostic purposes.
It is always used to retrieve the file name through prop->file->name.

Associate struct property with the file name directly.

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
---

 scripts/kconfig/expr.h   |  2 +-
 scripts/kconfig/menu.c   |  4 ++--
 scripts/kconfig/symbol.c | 12 ++++++------
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index e8fc85d98cdd..037db39c5bf0 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -195,7 +195,7 @@ struct property {
 	struct menu *menu;         /* the menu the property are associated with
 	                            * valid for: P_SELECT, P_RANGE, P_CHOICE,
 	                            * P_PROMPT, P_DEFAULT, P_MENU, P_COMMENT */
-	struct file *file;         /* what file was this property defined */
+	const char *filename;      /* what file was this property defined */
 	int lineno;                /* what lineno was this property defined */
 };
 
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 5ad4d2b9fb82..0ded0b1830d0 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -33,7 +33,7 @@ static void prop_warn(struct property *prop, const char *fmt, ...)
 {
 	va_list ap;
 	va_start(ap, fmt);
-	fprintf(stderr, "%s:%d:warning: ", prop->file->name, prop->lineno);
+	fprintf(stderr, "%s:%d:warning: ", prop->filename, prop->lineno);
 	vfprintf(stderr, fmt, ap);
 	fprintf(stderr, "\n");
 	va_end(ap);
@@ -134,7 +134,7 @@ static struct property *menu_add_prop(enum prop_type type, struct expr *expr,
 	prop = xmalloc(sizeof(*prop));
 	memset(prop, 0, sizeof(*prop));
 	prop->type = type;
-	prop->file = current_file;
+	prop->filename = cur_filename;
 	prop->lineno = cur_lineno;
 	prop->menu = current_entry;
 	prop->expr = expr;
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index 7647e3e87cd5..dae630a74e50 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -1041,7 +1041,7 @@ static void sym_check_print_recursive(struct symbol *last_sym)
 		}
 		if (stack->sym == last_sym)
 			fprintf(stderr, "%s:%d:error: recursive dependency detected!\n",
-				prop->file->name, prop->lineno);
+				prop->filename, prop->lineno);
 
 		if (sym_is_choice(sym)) {
 			fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n",
@@ -1055,28 +1055,28 @@ static void sym_check_print_recursive(struct symbol *last_sym)
 				next_sym->name ? next_sym->name : "<choice>");
 		} else if (stack->expr == &sym->dir_dep.expr) {
 			fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n",
-				prop->file->name, prop->lineno,
+				prop->filename, prop->lineno,
 				sym->name ? sym->name : "<choice>",
 				next_sym->name ? next_sym->name : "<choice>");
 		} else if (stack->expr == &sym->rev_dep.expr) {
 			fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n",
-				prop->file->name, prop->lineno,
+				prop->filename, prop->lineno,
 				sym->name ? sym->name : "<choice>",
 				next_sym->name ? next_sym->name : "<choice>");
 		} else if (stack->expr == &sym->implied.expr) {
 			fprintf(stderr, "%s:%d:\tsymbol %s is implied by %s\n",
-				prop->file->name, prop->lineno,
+				prop->filename, prop->lineno,
 				sym->name ? sym->name : "<choice>",
 				next_sym->name ? next_sym->name : "<choice>");
 		} else if (stack->expr) {
 			fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n",
-				prop->file->name, prop->lineno,
+				prop->filename, prop->lineno,
 				sym->name ? sym->name : "<choice>",
 				prop_get_type_name(prop->type),
 				next_sym->name ? next_sym->name : "<choice>");
 		} else {
 			fprintf(stderr, "%s:%d:\tsymbol %s %s is visible depending on %s\n",
-				prop->file->name, prop->lineno,
+				prop->filename, prop->lineno,
 				sym->name ? sym->name : "<choice>",
 				prop_get_type_name(prop->type),
 				next_sym->name ? next_sym->name : "<choice>");
-- 
2.40.1


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

* [PATCH 13/27] kconfig: replace file->name with name in zconf_nextfile()
  2024-02-02 15:57 [PATCH 00/27] kconfig: refactor lexer and parser code Masahiro Yamada
                   ` (11 preceding siblings ...)
  2024-02-02 15:58 ` [PATCH 12/27] kconfig: associate struct property " Masahiro Yamada
@ 2024-02-02 15:58 ` Masahiro Yamada
  2024-02-02 15:58 ` [PATCH 14/27] kconfig: do not delay the cur_filename update Masahiro Yamada
                   ` (14 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: Masahiro Yamada @ 2024-02-02 15:58 UTC (permalink / raw)
  To: linux-kbuild; +Cc: linux-kernel, Masahiro Yamada

The 'file->name' and 'name' are the same in this function.

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
---

 scripts/kconfig/lexer.l | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/scripts/kconfig/lexer.l b/scripts/kconfig/lexer.l
index 3b3893f673dc..35ad1b256470 100644
--- a/scripts/kconfig/lexer.l
+++ b/scripts/kconfig/lexer.l
@@ -420,10 +420,10 @@ void zconf_nextfile(const char *name)
 	buf->yylineno = yylineno;
 	buf->parent = current_buf;
 	current_buf = buf;
-	yyin = zconf_fopen(file->name);
+	yyin = zconf_fopen(name);
 	if (!yyin) {
 		fprintf(stderr, "%s:%d: can't open file \"%s\"\n",
-			cur_filename, cur_lineno, file->name);
+			cur_filename, cur_lineno, name);
 		exit(1);
 	}
 	yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
@@ -432,17 +432,17 @@ void zconf_nextfile(const char *name)
 	file->parent = current_file;
 
 	for (iter = current_file; iter; iter = iter->parent) {
-		if (!strcmp(iter->name, file->name)) {
+		if (!strcmp(iter->name, name)) {
 			fprintf(stderr,
 				"Recursive inclusion detected.\n"
 				"Inclusion path:\n"
-				"  current file : %s\n", file->name);
+				"  current file : %s\n", name);
 			iter = file;
 			do {
 				iter = iter->parent;
 				fprintf(stderr, "  included from: %s:%d\n",
 					iter->name, iter->lineno);
-			} while (strcmp(iter->name, file->name));
+			} while (strcmp(iter->name, name));
 			exit(1);
 		}
 	}
-- 
2.40.1


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

* [PATCH 14/27] kconfig: do not delay the cur_filename update
  2024-02-02 15:57 [PATCH 00/27] kconfig: refactor lexer and parser code Masahiro Yamada
                   ` (12 preceding siblings ...)
  2024-02-02 15:58 ` [PATCH 13/27] kconfig: replace file->name with name in zconf_nextfile() Masahiro Yamada
@ 2024-02-02 15:58 ` Masahiro Yamada
  2024-02-02 15:58 ` [PATCH 15/27] kconfig: replace remaining current_file->name with cur_filename Masahiro Yamada
                   ` (13 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: Masahiro Yamada @ 2024-02-02 15:58 UTC (permalink / raw)
  To: linux-kbuild; +Cc: linux-kernel, Masahiro Yamada

Currently, cur_filename is updated at the first token of each statement.
However, this seems unnecessary based on my understanding; the parser
can use the same variable as the lexer tracks.

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
---

 scripts/kconfig/lexer.l  | 17 +++++++----------
 scripts/kconfig/parser.y |  8 ++++++++
 2 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/scripts/kconfig/lexer.l b/scripts/kconfig/lexer.l
index 35ad1b256470..28e279cd5a22 100644
--- a/scripts/kconfig/lexer.l
+++ b/scripts/kconfig/lexer.l
@@ -274,24 +274,17 @@ repeat:
 	token = yylex1();
 
 	if (prev_token == T_EOL || prev_token == T_HELPTEXT) {
-		if (token == T_EOL) {
+		if (token == T_EOL)
 			/* Do not pass unneeded T_EOL to the parser. */
 			goto repeat;
-		} else {
+		else
 			/*
-			 * For the parser, update file/lineno at the first token
+			 * For the parser, update lineno at the first token
 			 * of each statement. Generally, \n is a statement
 			 * terminator in Kconfig, but it is not always true
 			 * because \n could be escaped by a backslash.
-			 *
-			 * FIXME:
-			 * cur_filename and cur_lineno are used even after
-			 * yyparse(); menu_finalize() calls menu_add_symbol().
-			 * This should be fixed.
 			 */
-			cur_filename = current_file ? current_file->name : "<none>";
 			cur_lineno = yylineno;
-		}
 	}
 
 	if (prev_prev_token == T_EOL && prev_token == T_WORD &&
@@ -407,6 +400,7 @@ void zconf_initscan(const char *name)
 	}
 
 	current_file = file_lookup(name);
+	cur_filename = current_file->name;
 	yylineno = 1;
 }
 
@@ -448,6 +442,7 @@ void zconf_nextfile(const char *name)
 	}
 
 	yylineno = 1;
+	cur_filename = file->name;
 	current_file = file;
 }
 
@@ -456,6 +451,8 @@ static void zconf_endfile(void)
 	struct buffer *tmp;
 
 	current_file = current_file->parent;
+	if (current_file)
+		cur_filename = current_file->name;
 
 	if (!current_buf)
 		return;
diff --git a/scripts/kconfig/parser.y b/scripts/kconfig/parser.y
index d1d05c8cd89d..e58c24d2e5ab 100644
--- a/scripts/kconfig/parser.y
+++ b/scripts/kconfig/parser.y
@@ -488,6 +488,14 @@ void conf_parse(const char *name)
 		yydebug = 1;
 	yyparse();
 
+	/*
+	 * FIXME:
+	 * cur_filename and cur_lineno are used even after yyparse();
+	 * menu_finalize() calls menu_add_symbol(). This should be fixed.
+	 */
+	cur_filename = "<none>";
+	cur_lineno = 0;
+
 	str_printf(&autoconf_cmd,
 		   "\n"
 		   "$(autoconfig): $(deps_config)\n"
-- 
2.40.1


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

* [PATCH 15/27] kconfig: replace remaining current_file->name with cur_filename
  2024-02-02 15:57 [PATCH 00/27] kconfig: refactor lexer and parser code Masahiro Yamada
                   ` (13 preceding siblings ...)
  2024-02-02 15:58 ` [PATCH 14/27] kconfig: do not delay the cur_filename update Masahiro Yamada
@ 2024-02-02 15:58 ` Masahiro Yamada
  2024-02-02 15:58 ` [PATCH 16/27] kconfig: move the file and lineno in struct file to struct buffer Masahiro Yamada
                   ` (12 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: Masahiro Yamada @ 2024-02-02 15:58 UTC (permalink / raw)
  To: linux-kbuild; +Cc: linux-kernel, Masahiro Yamada

Replace the remaining current_file->name in the lexer context.

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
---

 scripts/kconfig/lexer.l      | 4 ++--
 scripts/kconfig/preprocess.c | 8 ++++----
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/scripts/kconfig/lexer.l b/scripts/kconfig/lexer.l
index 28e279cd5a22..db2397c4e343 100644
--- a/scripts/kconfig/lexer.l
+++ b/scripts/kconfig/lexer.l
@@ -84,7 +84,7 @@ static void warn_ignored_character(char chr)
 {
 	fprintf(stderr,
 	        "%s:%d:warning: ignoring unsupported character '%c'\n",
-	        current_file->name, yylineno, chr);
+	        cur_filename, yylineno, chr);
 }
 %}
 
@@ -253,7 +253,7 @@ n	[A-Za-z0-9_-]
 
 	if (prev_token != T_EOL && prev_token != T_HELPTEXT)
 		fprintf(stderr, "%s:%d:warning: no new line at end of file\n",
-			current_file->name, yylineno);
+			cur_filename, yylineno);
 
 	if (current_file) {
 		zconf_endfile();
diff --git a/scripts/kconfig/preprocess.c b/scripts/kconfig/preprocess.c
index 12665b981c3e..69b806a6d8b7 100644
--- a/scripts/kconfig/preprocess.c
+++ b/scripts/kconfig/preprocess.c
@@ -9,6 +9,7 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "internal.h"
 #include "list.h"
 #include "lkc.h"
 #include "preprocess.h"
@@ -22,7 +23,7 @@ static void __attribute__((noreturn)) pperror(const char *format, ...)
 {
 	va_list ap;
 
-	fprintf(stderr, "%s:%d: ", current_file->name, yylineno);
+	fprintf(stderr, "%s:%d: ", cur_filename, yylineno);
 	va_start(ap, format);
 	vfprintf(stderr, format, ap);
 	va_end(ap);
@@ -123,7 +124,7 @@ static char *do_error_if(int argc, char *argv[])
 
 static char *do_filename(int argc, char *argv[])
 {
-	return xstrdup(current_file->name);
+	return xstrdup(cur_filename);
 }
 
 static char *do_info(int argc, char *argv[])
@@ -185,8 +186,7 @@ static char *do_shell(int argc, char *argv[])
 static char *do_warning_if(int argc, char *argv[])
 {
 	if (!strcmp(argv[0], "y"))
-		fprintf(stderr, "%s:%d: %s\n",
-			current_file->name, yylineno, argv[1]);
+		fprintf(stderr, "%s:%d: %s\n", cur_filename, yylineno, argv[1]);
 
 	return xstrdup("");
 }
-- 
2.40.1


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

* [PATCH 16/27] kconfig: move the file and lineno in struct file to struct buffer
  2024-02-02 15:57 [PATCH 00/27] kconfig: refactor lexer and parser code Masahiro Yamada
                   ` (14 preceding siblings ...)
  2024-02-02 15:58 ` [PATCH 15/27] kconfig: replace remaining current_file->name with cur_filename Masahiro Yamada
@ 2024-02-02 15:58 ` Masahiro Yamada
  2024-02-02 15:58 ` [PATCH 17/27] kconfig: make file::name a flexible array member Masahiro Yamada
                   ` (11 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: Masahiro Yamada @ 2024-02-02 15:58 UTC (permalink / raw)
  To: linux-kbuild; +Cc: linux-kernel, Masahiro Yamada

struct file has two link nodes, 'next' and 'parent'.

The former is used to link files in the 'file_list' linked list,
which manages the list of Kconfig files seen so far.

The latter is used to link files in the 'current_file' linked list,
which manages the inclusion ("source") tree.

The latter should be tracked together with the lexer state.

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
---

 scripts/kconfig/expr.h  |  3 ---
 scripts/kconfig/lexer.l | 50 ++++++++++++++++++-----------------------
 scripts/kconfig/menu.c  |  1 -
 3 files changed, 22 insertions(+), 32 deletions(-)

diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index 037db39c5bf0..85e0d1ab3c8a 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -19,9 +19,7 @@ extern "C" {
 
 struct file {
 	struct file *next;
-	struct file *parent;
 	const char *name;
-	int lineno;
 };
 
 typedef enum tristate {
@@ -278,7 +276,6 @@ struct jump_key {
 };
 
 extern struct file *file_list;
-extern struct file *current_file;
 
 extern struct symbol symbol_yes, symbol_no, symbol_mod;
 extern struct symbol *modules_sym;
diff --git a/scripts/kconfig/lexer.l b/scripts/kconfig/lexer.l
index db2397c4e343..71f651bb82ba 100644
--- a/scripts/kconfig/lexer.l
+++ b/scripts/kconfig/lexer.l
@@ -40,6 +40,8 @@ struct buffer {
 	struct buffer *parent;
 	YY_BUFFER_STATE state;
 	int yylineno;
+	const char *filename;
+	int source_lineno;
 };
 
 static struct buffer *current_buf;
@@ -255,7 +257,7 @@ n	[A-Za-z0-9_-]
 		fprintf(stderr, "%s:%d:warning: no new line at end of file\n",
 			cur_filename, yylineno);
 
-	if (current_file) {
+	if (current_buf) {
 		zconf_endfile();
 		return T_EOL;
 	}
@@ -399,19 +401,20 @@ void zconf_initscan(const char *name)
 		exit(1);
 	}
 
-	current_file = file_lookup(name);
-	cur_filename = current_file->name;
+	cur_filename = file_lookup(name)->name;
 	yylineno = 1;
 }
 
 void zconf_nextfile(const char *name)
 {
-	struct file *iter;
 	struct file *file = file_lookup(name);
 	struct buffer *buf = xmalloc(sizeof(*buf));
+	bool recur_include = false;
 
 	buf->state = YY_CURRENT_BUFFER;
 	buf->yylineno = yylineno;
+	buf->filename = cur_filename;
+	buf->source_lineno = cur_lineno;
 	buf->parent = current_buf;
 	current_buf = buf;
 	yyin = zconf_fopen(name);
@@ -422,45 +425,36 @@ void zconf_nextfile(const char *name)
 	}
 	yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
 
-	current_file->lineno = cur_lineno;
-	file->parent = current_file;
+	for (buf = current_buf; buf; buf = buf->parent) {
+		if (!strcmp(buf->filename, name))
+			recur_include = true;
+	}
 
-	for (iter = current_file; iter; iter = iter->parent) {
-		if (!strcmp(iter->name, name)) {
-			fprintf(stderr,
-				"Recursive inclusion detected.\n"
-				"Inclusion path:\n"
-				"  current file : %s\n", name);
-			iter = file;
-			do {
-				iter = iter->parent;
-				fprintf(stderr, "  included from: %s:%d\n",
-					iter->name, iter->lineno);
-			} while (strcmp(iter->name, name));
-			exit(1);
-		}
+	if (recur_include) {
+		fprintf(stderr,
+			"Recursive inclusion detected.\n"
+			"Inclusion path:\n"
+			"  current file : %s\n", name);
+
+		for (buf = current_buf; buf; buf = buf->parent)
+			fprintf(stderr, "  included from: %s:%d\n",
+				buf->filename, buf->source_lineno);
+		exit(1);
 	}
 
 	yylineno = 1;
 	cur_filename = file->name;
-	current_file = file;
 }
 
 static void zconf_endfile(void)
 {
 	struct buffer *tmp;
 
-	current_file = current_file->parent;
-	if (current_file)
-		cur_filename = current_file->name;
-
-	if (!current_buf)
-		return;
-
 	fclose(yyin);
 	yy_delete_buffer(YY_CURRENT_BUFFER);
 	yy_switch_to_buffer(current_buf->state);
 	yylineno = current_buf->yylineno;
+	cur_filename = current_buf->filename;
 	tmp = current_buf;
 	current_buf = current_buf->parent;
 	free(tmp);
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 0ded0b1830d0..b879576d1ab4 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -17,7 +17,6 @@ struct menu rootmenu;
 static struct menu **last_entry_ptr;
 
 struct file *file_list;
-struct file *current_file;
 
 void menu_warn(struct menu *menu, const char *fmt, ...)
 {
-- 
2.40.1


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

* [PATCH 17/27] kconfig: make file::name a flexible array member
  2024-02-02 15:57 [PATCH 00/27] kconfig: refactor lexer and parser code Masahiro Yamada
                   ` (15 preceding siblings ...)
  2024-02-02 15:58 ` [PATCH 16/27] kconfig: move the file and lineno in struct file to struct buffer Masahiro Yamada
@ 2024-02-02 15:58 ` Masahiro Yamada
  2024-02-02 15:58 ` [PATCH 18/27] kconfig: change file_lookup() to return the file name Masahiro Yamada
                   ` (10 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: Masahiro Yamada @ 2024-02-02 15:58 UTC (permalink / raw)
  To: linux-kbuild; +Cc: linux-kernel, Masahiro Yamada

Call malloc() just once to allocate needed memory.

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
---

 scripts/kconfig/expr.h | 2 +-
 scripts/kconfig/util.c | 7 +++++--
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index 85e0d1ab3c8a..760b1e681b43 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -19,7 +19,7 @@ extern "C" {
 
 struct file {
 	struct file *next;
-	const char *name;
+	char name[];
 };
 
 typedef enum tristate {
diff --git a/scripts/kconfig/util.c b/scripts/kconfig/util.c
index 958543bb0a37..2636dccea0c9 100644
--- a/scripts/kconfig/util.c
+++ b/scripts/kconfig/util.c
@@ -13,6 +13,7 @@
 struct file *file_lookup(const char *name)
 {
 	struct file *file;
+	size_t len;
 
 	for (file = file_list; file; file = file->next) {
 		if (!strcmp(name, file->name)) {
@@ -20,9 +21,11 @@ struct file *file_lookup(const char *name)
 		}
 	}
 
-	file = xmalloc(sizeof(*file));
+	len = strlen(name);
+	file = xmalloc(sizeof(*file) + len + 1);
 	memset(file, 0, sizeof(*file));
-	file->name = xstrdup(name);
+	memcpy(file->name, name, len);
+	file->name[len] = '\0';
 	file->next = file_list;
 	file_list = file;
 
-- 
2.40.1


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

* [PATCH 18/27] kconfig: change file_lookup() to return the file name
  2024-02-02 15:57 [PATCH 00/27] kconfig: refactor lexer and parser code Masahiro Yamada
                   ` (16 preceding siblings ...)
  2024-02-02 15:58 ` [PATCH 17/27] kconfig: make file::name a flexible array member Masahiro Yamada
@ 2024-02-02 15:58 ` Masahiro Yamada
  2024-02-02 15:58 ` [PATCH 19/27] kconfig: split list_head into a separate header Masahiro Yamada
                   ` (9 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: Masahiro Yamada @ 2024-02-02 15:58 UTC (permalink / raw)
  To: linux-kbuild; +Cc: linux-kernel, Masahiro Yamada

Currently, file_lookup() returns a pointer to (struct file), but the
callers use only file->name.

Make it return the ->name member directly.

This adjustment encapsulates struct file and file_list as internal
implementation.

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
---

 scripts/kconfig/expr.h  |  7 -------
 scripts/kconfig/lexer.l |  5 ++---
 scripts/kconfig/lkc.h   |  2 +-
 scripts/kconfig/menu.c  |  2 --
 scripts/kconfig/util.c  | 13 ++++++++++---
 5 files changed, 13 insertions(+), 16 deletions(-)

diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index 760b1e681b43..d667f9aa041e 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -17,11 +17,6 @@ extern "C" {
 #include <stdbool.h>
 #endif
 
-struct file {
-	struct file *next;
-	char name[];
-};
-
 typedef enum tristate {
 	no, mod, yes
 } tristate;
@@ -275,8 +270,6 @@ struct jump_key {
 	struct menu *target;
 };
 
-extern struct file *file_list;
-
 extern struct symbol symbol_yes, symbol_no, symbol_mod;
 extern struct symbol *modules_sym;
 extern int cdebug;
diff --git a/scripts/kconfig/lexer.l b/scripts/kconfig/lexer.l
index 71f651bb82ba..89544c3a1a29 100644
--- a/scripts/kconfig/lexer.l
+++ b/scripts/kconfig/lexer.l
@@ -401,13 +401,12 @@ void zconf_initscan(const char *name)
 		exit(1);
 	}
 
-	cur_filename = file_lookup(name)->name;
+	cur_filename = file_lookup(name);
 	yylineno = 1;
 }
 
 void zconf_nextfile(const char *name)
 {
-	struct file *file = file_lookup(name);
 	struct buffer *buf = xmalloc(sizeof(*buf));
 	bool recur_include = false;
 
@@ -443,7 +442,7 @@ void zconf_nextfile(const char *name)
 	}
 
 	yylineno = 1;
-	cur_filename = file->name;
+	cur_filename = file_lookup(name);
 }
 
 static void zconf_endfile(void)
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index d8249052f2e3..71afcbd56273 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -52,7 +52,7 @@ static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out)
 }
 
 /* util.c */
-struct file *file_lookup(const char *name);
+const char *file_lookup(const char *name);
 void *xmalloc(size_t size);
 void *xcalloc(size_t nmemb, size_t size);
 void *xrealloc(void *p, size_t size);
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index b879576d1ab4..f701382f8a69 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -16,8 +16,6 @@ static const char nohelp_text[] = "There is no help available for this option.";
 struct menu rootmenu;
 static struct menu **last_entry_ptr;
 
-struct file *file_list;
-
 void menu_warn(struct menu *menu, const char *fmt, ...)
 {
 	va_list ap;
diff --git a/scripts/kconfig/util.c b/scripts/kconfig/util.c
index 2636dccea0c9..610d64c01479 100644
--- a/scripts/kconfig/util.c
+++ b/scripts/kconfig/util.c
@@ -9,15 +9,22 @@
 #include <string.h>
 #include "lkc.h"
 
+struct file {
+	struct file *next;
+	char name[];
+};
+
+static struct file *file_list;
+
 /* file already present in list? If not add it */
-struct file *file_lookup(const char *name)
+const char *file_lookup(const char *name)
 {
 	struct file *file;
 	size_t len;
 
 	for (file = file_list; file; file = file->next) {
 		if (!strcmp(name, file->name)) {
-			return file;
+			return file->name;
 		}
 	}
 
@@ -31,7 +38,7 @@ struct file *file_lookup(const char *name)
 
 	str_printf(&autoconf_cmd, "\t%s \\\n", name);
 
-	return file;
+	return file->name;
 }
 
 /* Allocate initial growable string */
-- 
2.40.1


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

* [PATCH 19/27] kconfig: split list_head into a separate header
  2024-02-02 15:57 [PATCH 00/27] kconfig: refactor lexer and parser code Masahiro Yamada
                   ` (17 preceding siblings ...)
  2024-02-02 15:58 ` [PATCH 18/27] kconfig: change file_lookup() to return the file name Masahiro Yamada
@ 2024-02-02 15:58 ` Masahiro Yamada
  2024-02-02 15:58 ` [PATCH 20/27] kconfig: resync list.h Masahiro Yamada
                   ` (8 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: Masahiro Yamada @ 2024-02-02 15:58 UTC (permalink / raw)
  To: linux-kbuild; +Cc: linux-kernel, Masahiro Yamada

The struct list_head is often embedded in other structures, while other
code is used in C functions.

By separating struct list_head into its own header, other headers are no
longer required to include the entire list.h.

This is similar to the kernel space, where struct list_head is defined
in <linux/types.h> instead of <linux/list.h>.

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
---

 scripts/kconfig/expr.h       | 2 +-
 scripts/kconfig/list.h       | 8 ++------
 scripts/kconfig/list_types.h | 9 +++++++++
 scripts/kconfig/mconf.c      | 1 +
 scripts/kconfig/menu.c       | 1 +
 scripts/kconfig/nconf.c      | 1 +
 6 files changed, 15 insertions(+), 7 deletions(-)
 create mode 100644 scripts/kconfig/list_types.h

diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index d667f9aa041e..dd3350aed302 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -12,7 +12,7 @@ extern "C" {
 
 #include <assert.h>
 #include <stdio.h>
-#include "list.h"
+#include "list_types.h"
 #ifndef __cplusplus
 #include <stdbool.h>
 #endif
diff --git a/scripts/kconfig/list.h b/scripts/kconfig/list.h
index 45cb237ab7ef..babed0baf4ae 100644
--- a/scripts/kconfig/list.h
+++ b/scripts/kconfig/list.h
@@ -2,6 +2,8 @@
 #ifndef LIST_H
 #define LIST_H
 
+#include "list_types.h"
+
 /*
  * Copied from include/linux/...
  */
@@ -20,12 +22,6 @@
 	const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
 	(type *)( (char *)__mptr - offsetof(type,member) );})
 
-
-struct list_head {
-	struct list_head *next, *prev;
-};
-
-
 #define LIST_HEAD_INIT(name) { &(name), &(name) }
 
 #define LIST_HEAD(name) \
diff --git a/scripts/kconfig/list_types.h b/scripts/kconfig/list_types.h
new file mode 100644
index 000000000000..32899f424983
--- /dev/null
+++ b/scripts/kconfig/list_types.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef LIST_TYPES_H
+#define LIST_TYPES_H
+
+struct list_head {
+	struct list_head *next, *prev;
+};
+
+#endif /* LIST_TYPES_H */
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index 5df32148a869..f4bb391d50cf 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -19,6 +19,7 @@
 #include <signal.h>
 #include <unistd.h>
 
+#include "list.h"
 #include "lkc.h"
 #include "lxdialog/dialog.h"
 #include "mnconf-common.h"
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index f701382f8a69..696803d944e0 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -10,6 +10,7 @@
 
 #include "lkc.h"
 #include "internal.h"
+#include "list.h"
 
 static const char nohelp_text[] = "There is no help available for this option.";
 
diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c
index 1148163cfa7e..9d22b0f3197b 100644
--- a/scripts/kconfig/nconf.c
+++ b/scripts/kconfig/nconf.c
@@ -11,6 +11,7 @@
 #include <strings.h>
 #include <stdlib.h>
 
+#include "list.h"
 #include "lkc.h"
 #include "mnconf-common.h"
 #include "nconf.h"
-- 
2.40.1


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

* [PATCH 20/27] kconfig: resync list.h
  2024-02-02 15:57 [PATCH 00/27] kconfig: refactor lexer and parser code Masahiro Yamada
                   ` (18 preceding siblings ...)
  2024-02-02 15:58 ` [PATCH 19/27] kconfig: split list_head into a separate header Masahiro Yamada
@ 2024-02-02 15:58 ` Masahiro Yamada
  2024-02-02 15:58 ` [PATCH 21/27] kconfig: import more list macros and inline functions Masahiro Yamada
                   ` (7 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: Masahiro Yamada @ 2024-02-02 15:58 UTC (permalink / raw)
  To: linux-kbuild; +Cc: linux-kernel, Masahiro Yamada

Update the existing macros and inline functions based on
include/linux/list.h.

The variable name '_new' can be reverted to 'new' because this header
is no longer included from the C++ file, scripts/kconfig/qconf.cc.

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
---

 scripts/kconfig/list.h | 183 +++++++++++++++++++++++++++--------------
 1 file changed, 121 insertions(+), 62 deletions(-)

diff --git a/scripts/kconfig/list.h b/scripts/kconfig/list.h
index babed0baf4ae..2bce2b8f21d1 100644
--- a/scripts/kconfig/list.h
+++ b/scripts/kconfig/list.h
@@ -2,25 +2,39 @@
 #ifndef LIST_H
 #define LIST_H
 
+#include <stddef.h>
+
 #include "list_types.h"
 
-/*
- * Copied from include/linux/...
- */
-
-#undef offsetof
-#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+/* Are two types/vars the same type (ignoring qualifiers)? */
+#define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
 
 /**
  * container_of - cast a member of a structure out to the containing structure
- * @ptr:        the pointer to the member.
- * @type:       the type of the container struct this is embedded in.
- * @member:     the name of the member within the struct.
+ * @ptr:	the pointer to the member.
+ * @type:	the type of the container struct this is embedded in.
+ * @member:	the name of the member within the struct.
  *
  */
-#define container_of(ptr, type, member) ({                      \
-	const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
-	(type *)( (char *)__mptr - offsetof(type,member) );})
+#define container_of(ptr, type, member) ({				\
+	void *__mptr = (void *)(ptr);					\
+	_Static_assert(__same_type(*(ptr), ((type *)0)->member) ||	\
+		      __same_type(*(ptr), void),			\
+		      "pointer type mismatch in container_of()");	\
+	((type *)(__mptr - offsetof(type, member))); })
+
+#define LIST_POISON1  ((void *) 0x100)
+#define LIST_POISON2  ((void *) 0x122)
+
+/*
+ * Circular doubly linked list implementation.
+ *
+ * Some of the internal functions ("__xxx") are useful when
+ * manipulating whole lists rather than single entries, as
+ * sometimes we already know the next/prev entries and we can
+ * generate better code by using them directly rather than
+ * using the generic single-entry routines.
+ */
 
 #define LIST_HEAD_INIT(name) { &(name), &(name) }
 
@@ -28,45 +42,16 @@
 	struct list_head name = LIST_HEAD_INIT(name)
 
 /**
- * list_entry - get the struct for this entry
- * @ptr:	the &struct list_head pointer.
- * @type:	the type of the struct this is embedded in.
- * @member:	the name of the list_head within the struct.
+ * INIT_LIST_HEAD - Initialize a list_head structure
+ * @list: list_head structure to be initialized.
+ *
+ * Initializes the list_head to point to itself.  If it is a list header,
+ * the result is an empty list.
  */
-#define list_entry(ptr, type, member) \
-	container_of(ptr, type, member)
-
-/**
- * list_for_each_entry	-	iterate over list of given type
- * @pos:	the type * to use as a loop cursor.
- * @head:	the head for your list.
- * @member:	the name of the list_head within the struct.
- */
-#define list_for_each_entry(pos, head, member)				\
-	for (pos = list_entry((head)->next, typeof(*pos), member);	\
-	     &pos->member != (head); 	\
-	     pos = list_entry(pos->member.next, typeof(*pos), member))
-
-/**
- * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
- * @pos:	the type * to use as a loop cursor.
- * @n:		another type * to use as temporary storage
- * @head:	the head for your list.
- * @member:	the name of the list_head within the struct.
- */
-#define list_for_each_entry_safe(pos, n, head, member)			\
-	for (pos = list_entry((head)->next, typeof(*pos), member),	\
-		n = list_entry(pos->member.next, typeof(*pos), member);	\
-	     &pos->member != (head);					\
-	     pos = n, n = list_entry(n->member.next, typeof(*n), member))
-
-/**
- * list_empty - tests whether a list is empty
- * @head: the list to test.
- */
-static inline int list_empty(const struct list_head *head)
+static inline void INIT_LIST_HEAD(struct list_head *list)
 {
-	return head->next == head;
+	list->next = list;
+	list->prev = list;
 }
 
 /*
@@ -75,14 +60,14 @@ static inline int list_empty(const struct list_head *head)
  * This is only for internal list manipulation where we know
  * the prev/next entries already!
  */
-static inline void __list_add(struct list_head *_new,
+static inline void __list_add(struct list_head *new,
 			      struct list_head *prev,
 			      struct list_head *next)
 {
-	next->prev = _new;
-	_new->next = next;
-	_new->prev = prev;
-	prev->next = _new;
+	next->prev = new;
+	new->next = next;
+	new->prev = prev;
+	prev->next = new;
 }
 
 /**
@@ -93,9 +78,9 @@ static inline void __list_add(struct list_head *_new,
  * Insert a new entry before the specified head.
  * This is useful for implementing queues.
  */
-static inline void list_add_tail(struct list_head *_new, struct list_head *head)
+static inline void list_add_tail(struct list_head *new, struct list_head *head)
 {
-	__list_add(_new, head->prev, head);
+	__list_add(new, head->prev, head);
 }
 
 /*
@@ -111,8 +96,11 @@ static inline void __list_del(struct list_head *prev, struct list_head *next)
 	prev->next = next;
 }
 
-#define LIST_POISON1  ((void *) 0x00100100)
-#define LIST_POISON2  ((void *) 0x00200200)
+static inline void __list_del_entry(struct list_head *entry)
+{
+	__list_del(entry->prev, entry->next);
+}
+
 /**
  * list_del - deletes entry from list.
  * @entry: the element to delete from the list.
@@ -121,8 +109,79 @@ static inline void __list_del(struct list_head *prev, struct list_head *next)
  */
 static inline void list_del(struct list_head *entry)
 {
-	__list_del(entry->prev, entry->next);
-	entry->next = (struct list_head*)LIST_POISON1;
-	entry->prev = (struct list_head*)LIST_POISON2;
+	__list_del_entry(entry);
+	entry->next = LIST_POISON1;
+	entry->prev = LIST_POISON2;
 }
-#endif
+
+/**
+ * list_empty - tests whether a list is empty
+ * @head: the list to test.
+ */
+static inline int list_empty(const struct list_head *head)
+{
+	return head->next == head;
+}
+
+/**
+ * list_entry - get the struct for this entry
+ * @ptr:	the &struct list_head pointer.
+ * @type:	the type of the struct this is embedded in.
+ * @member:	the name of the list_head within the struct.
+ */
+#define list_entry(ptr, type, member) \
+	container_of(ptr, type, member)
+
+/**
+ * list_first_entry - get the first element from a list
+ * @ptr:	the list head to take the element from.
+ * @type:	the type of the struct this is embedded in.
+ * @member:	the name of the list_head within the struct.
+ *
+ * Note, that list is expected to be not empty.
+ */
+#define list_first_entry(ptr, type, member) \
+	list_entry((ptr)->next, type, member)
+
+/**
+ * list_next_entry - get the next element in list
+ * @pos:	the type * to cursor
+ * @member:	the name of the list_head within the struct.
+ */
+#define list_next_entry(pos, member) \
+	list_entry((pos)->member.next, typeof(*(pos)), member)
+
+/**
+ * list_entry_is_head - test if the entry points to the head of the list
+ * @pos:	the type * to cursor
+ * @head:	the head for your list.
+ * @member:	the name of the list_head within the struct.
+ */
+#define list_entry_is_head(pos, head, member)				\
+	(&pos->member == (head))
+
+/**
+ * list_for_each_entry - iterate over list of given type
+ * @pos:	the type * to use as a loop cursor.
+ * @head:	the head for your list.
+ * @member:	the name of the list_head within the struct.
+ */
+#define list_for_each_entry(pos, head, member)				\
+	for (pos = list_first_entry(head, typeof(*pos), member);	\
+	     !list_entry_is_head(pos, head, member);			\
+	     pos = list_next_entry(pos, member))
+
+/**
+ * list_for_each_entry_safe - iterate over list of given type. Safe against removal of list entry
+ * @pos:	the type * to use as a loop cursor.
+ * @n:		another type * to use as temporary storage
+ * @head:	the head for your list.
+ * @member:	the name of the list_head within the struct.
+ */
+#define list_for_each_entry_safe(pos, n, head, member)			\
+	for (pos = list_first_entry(head, typeof(*pos), member),	\
+		n = list_next_entry(pos, member);			\
+	     !list_entry_is_head(pos, head, member);			\
+	     pos = n, n = list_next_entry(n, member))
+
+#endif /* LIST_H */
-- 
2.40.1


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

* [PATCH 21/27] kconfig: import more list macros and inline functions
  2024-02-02 15:57 [PATCH 00/27] kconfig: refactor lexer and parser code Masahiro Yamada
                   ` (19 preceding siblings ...)
  2024-02-02 15:58 ` [PATCH 20/27] kconfig: resync list.h Masahiro Yamada
@ 2024-02-02 15:58 ` Masahiro Yamada
  2024-02-02 15:58 ` [PATCH 22/27] kconfig: add macros useful for hashtable Masahiro Yamada
                   ` (6 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: Masahiro Yamada @ 2024-02-02 15:58 UTC (permalink / raw)
  To: linux-kbuild; +Cc: linux-kernel, Masahiro Yamada

Import more macros and inline functions from include/linux/list.h
and include/linux/types.h.

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
---

 scripts/kconfig/list.h       | 69 ++++++++++++++++++++++++++++++++++++
 scripts/kconfig/list_types.h |  8 +++++
 2 files changed, 77 insertions(+)

diff --git a/scripts/kconfig/list.h b/scripts/kconfig/list.h
index 2bce2b8f21d1..882859ddf9f4 100644
--- a/scripts/kconfig/list.h
+++ b/scripts/kconfig/list.h
@@ -70,6 +70,19 @@ static inline void __list_add(struct list_head *new,
 	prev->next = new;
 }
 
+/**
+ * list_add - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it after
+ *
+ * Insert a new entry after the specified head.
+ * This is good for implementing stacks.
+ */
+static inline void list_add(struct list_head *new, struct list_head *head)
+{
+	__list_add(new, head, head->next);
+}
+
 /**
  * list_add_tail - add a new entry
  * @new: new entry to be added
@@ -114,6 +127,16 @@ static inline void list_del(struct list_head *entry)
 	entry->prev = LIST_POISON2;
 }
 
+/**
+ * list_is_head - tests whether @list is the list @head
+ * @list: the entry to test
+ * @head: the head of the list
+ */
+static inline int list_is_head(const struct list_head *list, const struct list_head *head)
+{
+	return list == head;
+}
+
 /**
  * list_empty - tests whether a list is empty
  * @head: the list to test.
@@ -184,4 +207,50 @@ static inline int list_empty(const struct list_head *head)
 	     !list_entry_is_head(pos, head, member);			\
 	     pos = n, n = list_next_entry(n, member))
 
+/*
+ * Double linked lists with a single pointer list head.
+ * Mostly useful for hash tables where the two pointer list head is
+ * too wasteful.
+ * You lose the ability to access the tail in O(1).
+ */
+
+#define HLIST_HEAD_INIT { .first = NULL }
+
+/**
+ * hlist_add_head - add a new entry at the beginning of the hlist
+ * @n: new entry to be added
+ * @h: hlist head to add it after
+ *
+ * Insert a new entry after the specified head.
+ * This is good for implementing stacks.
+ */
+static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
+{
+	struct hlist_node *first = h->first;
+
+	n->next = first;
+	if (first)
+		first->pprev = &n->next;
+	h->first = n;
+	n->pprev = &h->first;
+}
+
+#define hlist_entry(ptr, type, member) container_of(ptr, type, member)
+
+#define hlist_entry_safe(ptr, type, member) \
+	({ typeof(ptr) ____ptr = (ptr); \
+	   ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
+	})
+
+/**
+ * hlist_for_each_entry	- iterate over list of given type
+ * @pos:	the type * to use as a loop cursor.
+ * @head:	the head for your list.
+ * @member:	the name of the hlist_node within the struct.
+ */
+#define hlist_for_each_entry(pos, head, member)				\
+	for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member);\
+	     pos;							\
+	     pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
+
 #endif /* LIST_H */
diff --git a/scripts/kconfig/list_types.h b/scripts/kconfig/list_types.h
index 32899f424983..d935b7c5aa81 100644
--- a/scripts/kconfig/list_types.h
+++ b/scripts/kconfig/list_types.h
@@ -6,4 +6,12 @@ struct list_head {
 	struct list_head *next, *prev;
 };
 
+struct hlist_head {
+	struct hlist_node *first;
+};
+
+struct hlist_node {
+	struct hlist_node *next, **pprev;
+};
+
 #endif /* LIST_TYPES_H */
-- 
2.40.1


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

* [PATCH 22/27] kconfig: add macros useful for hashtable
  2024-02-02 15:57 [PATCH 00/27] kconfig: refactor lexer and parser code Masahiro Yamada
                   ` (20 preceding siblings ...)
  2024-02-02 15:58 ` [PATCH 21/27] kconfig: import more list macros and inline functions Masahiro Yamada
@ 2024-02-02 15:58 ` Masahiro Yamada
  2024-02-02 15:58 ` [PATCH 23/27] kconfig: move ARRAY_SIZE to a header Masahiro Yamada
                   ` (5 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: Masahiro Yamada @ 2024-02-02 15:58 UTC (permalink / raw)
  To: linux-kbuild; +Cc: linux-kernel, Masahiro Yamada

This is similar to include/linux/hashtable.h, but the implementation
has been simplified.

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
---

 scripts/kconfig/hashtable.h | 48 +++++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)
 create mode 100644 scripts/kconfig/hashtable.h

diff --git a/scripts/kconfig/hashtable.h b/scripts/kconfig/hashtable.h
new file mode 100644
index 000000000000..71724800d178
--- /dev/null
+++ b/scripts/kconfig/hashtable.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef HASHTABLE_H
+#define HASHTABLE_H
+
+#include "array_size.h"
+#include "list.h"
+
+#define HASH_SIZE(name) (ARRAY_SIZE(name))
+
+#define HASHTABLE_DECLARE(name, size)		struct hlist_head name[size]
+
+#define HASHTABLE_DEFINE(name, size)						\
+	HASHTABLE_DECLARE(name, size) =						\
+			{ [0 ... ((size) - 1)] = HLIST_HEAD_INIT }
+
+#define hash_head(table, key)		(&(table)[(key) % HASH_SIZE(table)])
+
+/**
+ * hash_add - add an object to a hashtable
+ * @table: hashtable to add to
+ * @node: the &struct hlist_node of the object to be added
+ * @key: the key of the object to be added
+ */
+#define hash_add(table, node, key)						\
+	hlist_add_head(node, hash_head(table, key))
+
+/**
+ * hash_for_each - iterate over a hashtable
+ * @table: hashtable to iterate
+ * @obj: the type * to use as a loop cursor for each entry
+ * @member: the name of the hlist_node within the struct
+ */
+#define hash_for_each(table, obj, member)				\
+	for (int bkt = 0; bkt < HASH_SIZE(table); bkt++)		\
+		hlist_for_each_entry(obj, &table[bkt], member)
+
+/**
+ * hash_for_each_possible - iterate over all possible objects hashing to the
+ * same bucket
+ * @table: hashtable to iterate
+ * @obj: the type * to use as a loop cursor for each entry
+ * @member: the name of the hlist_node within the struct
+ * @key: the key of the objects to iterate over
+ */
+#define hash_for_each_possible(table, obj, member, key)			\
+	hlist_for_each_entry(obj, hash_head(table, key), member)
+
+#endif /* HASHTABLE_H */
-- 
2.40.1


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

* [PATCH 23/27] kconfig: move ARRAY_SIZE to a header
  2024-02-02 15:57 [PATCH 00/27] kconfig: refactor lexer and parser code Masahiro Yamada
                   ` (21 preceding siblings ...)
  2024-02-02 15:58 ` [PATCH 22/27] kconfig: add macros useful for hashtable Masahiro Yamada
@ 2024-02-02 15:58 ` Masahiro Yamada
  2024-02-02 15:58 ` [PATCH 24/27] kconfig: move strhash() " Masahiro Yamada
                   ` (4 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: Masahiro Yamada @ 2024-02-02 15:58 UTC (permalink / raw)
  To: linux-kbuild; +Cc: linux-kernel, Masahiro Yamada

To use ARRAY_SIZE from other files, move it to its own header,
just like include/linux/array_size.h.

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
---

 scripts/kconfig/array_size.h | 11 +++++++++++
 scripts/kconfig/preprocess.c |  3 +--
 2 files changed, 12 insertions(+), 2 deletions(-)
 create mode 100644 scripts/kconfig/array_size.h

diff --git a/scripts/kconfig/array_size.h b/scripts/kconfig/array_size.h
new file mode 100644
index 000000000000..26ba78d867d1
--- /dev/null
+++ b/scripts/kconfig/array_size.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef ARRAY_SIZE_H
+#define ARRAY_SIZE_H
+
+/**
+ * ARRAY_SIZE - get the number of elements in array @arr
+ * @arr: array to be sized
+ */
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+
+#endif /* ARRAY_SIZE_H */
diff --git a/scripts/kconfig/preprocess.c b/scripts/kconfig/preprocess.c
index 69b806a6d8b7..f0a4a218c4a5 100644
--- a/scripts/kconfig/preprocess.c
+++ b/scripts/kconfig/preprocess.c
@@ -9,13 +9,12 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "array_size.h"
 #include "internal.h"
 #include "list.h"
 #include "lkc.h"
 #include "preprocess.h"
 
-#define ARRAY_SIZE(arr)		(sizeof(arr) / sizeof((arr)[0]))
-
 static char *expand_string_with_args(const char *in, int argc, char *argv[]);
 static char *expand_string(const char *in);
 
-- 
2.40.1


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

* [PATCH 24/27] kconfig: move strhash() to a header
  2024-02-02 15:57 [PATCH 00/27] kconfig: refactor lexer and parser code Masahiro Yamada
                   ` (22 preceding siblings ...)
  2024-02-02 15:58 ` [PATCH 23/27] kconfig: move ARRAY_SIZE to a header Masahiro Yamada
@ 2024-02-02 15:58 ` Masahiro Yamada
  2024-02-02 15:58 ` [PATCH 25/27] kconfig: convert linked list of files to hash table Masahiro Yamada
                   ` (3 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: Masahiro Yamada @ 2024-02-02 15:58 UTC (permalink / raw)
  To: linux-kbuild; +Cc: linux-kernel, Masahiro Yamada

Move strhash() to a header, so it can be used from other files.

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
---

 scripts/kconfig/symbol.c | 10 +---------
 scripts/kconfig/util.h   | 15 +++++++++++++++
 2 files changed, 16 insertions(+), 9 deletions(-)
 create mode 100644 scripts/kconfig/util.h

diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index dae630a74e50..518977c525de 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -10,6 +10,7 @@
 #include <regex.h>
 
 #include "lkc.h"
+#include "util.h"
 
 struct symbol symbol_yes = {
 	.name = "y",
@@ -803,15 +804,6 @@ bool sym_is_changeable(struct symbol *sym)
 	return sym->visible > sym->rev_dep.tri;
 }
 
-static unsigned strhash(const char *s)
-{
-	/* fnv32 hash */
-	unsigned hash = 2166136261U;
-	for (; *s; s++)
-		hash = (hash ^ *s) * 0x01000193;
-	return hash;
-}
-
 struct symbol *sym_lookup(const char *name, int flags)
 {
 	struct symbol *symbol;
diff --git a/scripts/kconfig/util.h b/scripts/kconfig/util.h
new file mode 100644
index 000000000000..d4e35bee6450
--- /dev/null
+++ b/scripts/kconfig/util.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef UTIL_H
+#define UTIL_H
+
+static unsigned int strhash(const char *s)
+{
+	/* fnv32 hash */
+	unsigned int hash = 2166136261U;
+
+	for (; *s; s++)
+		hash = (hash ^ *s) * 0x01000193;
+	return hash;
+}
+
+#endif /* UTIL_H */
-- 
2.40.1


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

* [PATCH 25/27] kconfig: convert linked list of files to hash table
  2024-02-02 15:57 [PATCH 00/27] kconfig: refactor lexer and parser code Masahiro Yamada
                   ` (23 preceding siblings ...)
  2024-02-02 15:58 ` [PATCH 24/27] kconfig: move strhash() " Masahiro Yamada
@ 2024-02-02 15:58 ` Masahiro Yamada
  2024-02-02 15:58 ` [PATCH 26/27] kconfig: use generic macros to implement symbol hashtable Masahiro Yamada
                   ` (2 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: Masahiro Yamada @ 2024-02-02 15:58 UTC (permalink / raw)
  To: linux-kbuild; +Cc: linux-kernel, Masahiro Yamada

Currently, a linked list is used to keep track of all the Kconfig
files that have ever been parsed. Every time the "source" statement
is encountered, the linked list is traversed to check if the file has
been opened before. This prevents the same file from being recorded
in include/config/auto.conf.cmd again.

Given 1500+ Kconfig files parsed, a hashtable is now a more optimal
data structure.

By the way, you may wonder why we check this in the first place.
It matters only when the same file is included multiple times.
In old days, such a use case was forbidden, but commit f094f8a1b273
("kconfig: allow multiple inclusion of the same file") provided a bit
more flexibility. Of course, it is almost hypothetical...

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
---

 scripts/kconfig/util.c | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/scripts/kconfig/util.c b/scripts/kconfig/util.c
index 610d64c01479..abd697ed8de7 100644
--- a/scripts/kconfig/util.c
+++ b/scripts/kconfig/util.c
@@ -7,34 +7,37 @@
 #include <stdarg.h>
 #include <stdlib.h>
 #include <string.h>
+
+#include "hashtable.h"
 #include "lkc.h"
+#include "util.h"
+
+/* hash table of all parsed Kconfig files */
+static HASHTABLE_DEFINE(file_hashtable, 1U << 11);
 
 struct file {
-	struct file *next;
+	struct hlist_node node;
 	char name[];
 };
 
-static struct file *file_list;
-
 /* file already present in list? If not add it */
 const char *file_lookup(const char *name)
 {
 	struct file *file;
 	size_t len;
+	int hash = strhash(name);
 
-	for (file = file_list; file; file = file->next) {
-		if (!strcmp(name, file->name)) {
+	hash_for_each_possible(file_hashtable, file, node, hash)
+		if (!strcmp(name, file->name))
 			return file->name;
-		}
-	}
 
 	len = strlen(name);
 	file = xmalloc(sizeof(*file) + len + 1);
 	memset(file, 0, sizeof(*file));
 	memcpy(file->name, name, len);
 	file->name[len] = '\0';
-	file->next = file_list;
-	file_list = file;
+
+	hash_add(file_hashtable, &file->node, hash);
 
 	str_printf(&autoconf_cmd, "\t%s \\\n", name);
 
-- 
2.40.1


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

* [PATCH 26/27] kconfig: use generic macros to implement symbol hashtable
  2024-02-02 15:57 [PATCH 00/27] kconfig: refactor lexer and parser code Masahiro Yamada
                   ` (24 preceding siblings ...)
  2024-02-02 15:58 ` [PATCH 25/27] kconfig: convert linked list of files to hash table Masahiro Yamada
@ 2024-02-02 15:58 ` Masahiro Yamada
  2024-02-02 15:58 ` [PATCH 27/27] kconfig: do not imply the type of choice value Masahiro Yamada
  2024-02-10 23:47 ` [PATCH 00/27] kconfig: refactor lexer and parser code Masahiro Yamada
  27 siblings, 0 replies; 29+ messages in thread
From: Masahiro Yamada @ 2024-02-02 15:58 UTC (permalink / raw)
  To: linux-kbuild; +Cc: linux-kernel, Masahiro Yamada

Use helper macros in hashtable.h for generic hashtable implementation.

We can git rid of the hash head index of for_all_symbols().

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
---

 scripts/kconfig/conf.c      | 12 ++++++------
 scripts/kconfig/confdata.c  | 25 ++++++++++++-------------
 scripts/kconfig/expr.h      |  9 ++++-----
 scripts/kconfig/internal.h  |  9 +++++++++
 scripts/kconfig/lkc_proto.h |  2 --
 scripts/kconfig/parser.y    |  5 +----
 scripts/kconfig/symbol.c    | 22 +++++++++++-----------
 7 files changed, 43 insertions(+), 41 deletions(-)

diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index 662a5e7c37c2..b5730061872b 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -14,6 +14,7 @@
 #include <sys/time.h>
 #include <errno.h>
 
+#include "internal.h"
 #include "lkc.h"
 
 static void conf(struct menu *menu);
@@ -171,7 +172,7 @@ enum conf_def_mode {
 static bool conf_set_all_new_symbols(enum conf_def_mode mode)
 {
 	struct symbol *sym, *csym;
-	int i, cnt;
+	int cnt;
 	/*
 	 * can't go as the default in switch-case below, otherwise gcc whines
 	 * about -Wmaybe-uninitialized
@@ -226,7 +227,7 @@ static bool conf_set_all_new_symbols(enum conf_def_mode mode)
 		}
 	}
 
-	for_all_symbols(i, sym) {
+	for_all_symbols(sym) {
 		if (sym_has_value(sym) || sym->flags & SYMBOL_VALID)
 			continue;
 		switch (sym_get_type(sym)) {
@@ -278,14 +279,14 @@ static bool conf_set_all_new_symbols(enum conf_def_mode mode)
 	 * and the rest to no.
 	 */
 	if (mode != def_random) {
-		for_all_symbols(i, csym) {
+		for_all_symbols(csym) {
 			if ((sym_is_choice(csym) && !sym_has_value(csym)) ||
 			    sym_is_choice_value(csym))
 				csym->flags |= SYMBOL_NEED_SET_CHOICE_VALUES;
 		}
 	}
 
-	for_all_symbols(i, csym) {
+	for_all_symbols(csym) {
 		if (sym_has_value(csym) || !sym_is_choice(csym))
 			continue;
 
@@ -304,9 +305,8 @@ static bool conf_set_all_new_symbols(enum conf_def_mode mode)
 static void conf_rewrite_tristates(tristate old_val, tristate new_val)
 {
 	struct symbol *sym;
-	int i;
 
-	for_all_symbols(i, sym) {
+	for_all_symbols(sym) {
 		if (sym_get_type(sym) == S_TRISTATE &&
 		    sym->def[S_DEF_USER].tri == old_val)
 			sym->def[S_DEF_USER].tri = new_val;
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index dafc572e7b7e..c5b6487d68ac 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -18,6 +18,7 @@
 #include <time.h>
 #include <unistd.h>
 
+#include "internal.h"
 #include "lkc.h"
 
 struct gstr autoconf_cmd;
@@ -322,7 +323,7 @@ int conf_read_simple(const char *name, int def)
 	size_t  line_asize = 0;
 	char *p, *val;
 	struct symbol *sym;
-	int i, def_flags;
+	int def_flags;
 	const char *warn_unknown, *sym_name;
 
 	warn_unknown = getenv("KCONFIG_WARN_UNKNOWN_SYMBOLS");
@@ -380,7 +381,7 @@ int conf_read_simple(const char *name, int def)
 	conf_warnings = 0;
 
 	def_flags = SYMBOL_DEF << def;
-	for_all_symbols(i, sym) {
+	for_all_symbols(sym) {
 		sym->flags |= SYMBOL_CHANGED;
 		sym->flags &= ~(def_flags|SYMBOL_VALID);
 		if (sym_is_choice(sym))
@@ -489,7 +490,6 @@ int conf_read(const char *name)
 {
 	struct symbol *sym;
 	int conf_unsaved = 0;
-	int i;
 
 	conf_set_changed(false);
 
@@ -500,7 +500,7 @@ int conf_read(const char *name)
 
 	sym_calc_value(modules_sym);
 
-	for_all_symbols(i, sym) {
+	for_all_symbols(sym) {
 		sym_calc_value(sym);
 		if (sym_is_choice(sym) || (sym->flags & SYMBOL_NO_WRITE))
 			continue;
@@ -524,7 +524,7 @@ int conf_read(const char *name)
 		/* maybe print value in verbose mode... */
 	}
 
-	for_all_symbols(i, sym) {
+	for_all_symbols(sym) {
 		if (sym_has_value(sym) && !sym_is_choice_value(sym)) {
 			/* Reset values of generates values, so they'll appear
 			 * as new, if they should become visible, but that
@@ -862,7 +862,6 @@ int conf_write(const char *name)
 	const char *str;
 	char tmpname[PATH_MAX + 1], oldname[PATH_MAX + 1];
 	char *env;
-	int i;
 	bool need_newline = false;
 
 	if (!name)
@@ -946,7 +945,7 @@ int conf_write(const char *name)
 	}
 	fclose(out);
 
-	for_all_symbols(i, sym)
+	for_all_symbols(sym)
 		sym->flags &= ~SYMBOL_WRITTEN;
 
 	if (*tmpname) {
@@ -1016,7 +1015,7 @@ static int conf_touch_deps(void)
 {
 	const char *name, *tmp;
 	struct symbol *sym;
-	int res, i;
+	int res;
 
 	name = conf_get_autoconfig_name();
 	tmp = strrchr(name, '/');
@@ -1030,7 +1029,7 @@ static int conf_touch_deps(void)
 	conf_read_simple(name, S_DEF_AUTO);
 	sym_calc_value(modules_sym);
 
-	for_all_symbols(i, sym) {
+	for_all_symbols(sym) {
 		sym_calc_value(sym);
 		if ((sym->flags & SYMBOL_NO_WRITE) || !sym->name)
 			continue;
@@ -1096,7 +1095,7 @@ static int __conf_write_autoconf(const char *filename,
 	char tmp[PATH_MAX];
 	FILE *file;
 	struct symbol *sym;
-	int ret, i;
+	int ret;
 
 	if (make_parent_dir(filename))
 		return -1;
@@ -1113,7 +1112,7 @@ static int __conf_write_autoconf(const char *filename,
 
 	conf_write_heading(file, comment_style);
 
-	for_all_symbols(i, sym)
+	for_all_symbols(sym)
 		if ((sym->flags & SYMBOL_WRITE) && sym->name)
 			print_symbol(file, sym);
 
@@ -1136,7 +1135,7 @@ int conf_write_autoconf(int overwrite)
 {
 	struct symbol *sym;
 	const char *autoconf_name = conf_get_autoconfig_name();
-	int ret, i;
+	int ret;
 
 	if (!overwrite && is_present(autoconf_name))
 		return 0;
@@ -1148,7 +1147,7 @@ int conf_write_autoconf(int overwrite)
 	if (conf_touch_deps())
 		return 1;
 
-	for_all_symbols(i, sym)
+	for_all_symbols(sym)
 		sym_calc_value(sym);
 
 	ret = __conf_write_autoconf(conf_get_autoheader_name(),
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index dd3350aed302..3bc375f1a1cd 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -17,6 +17,8 @@ extern "C" {
 #include <stdbool.h>
 #endif
 
+#include "list_types.h"
+
 typedef enum tristate {
 	no, mod, yes
 } tristate;
@@ -74,8 +76,8 @@ enum {
  * SYMBOL_CHOICE bit set in 'flags'.
  */
 struct symbol {
-	/* The next symbol in the same bucket in the symbol hash table */
-	struct symbol *next;
+	/* link node for the hash table */
+	struct hlist_node node;
 
 	/* The name of the symbol, e.g. "FOO" for 'config FOO' */
 	char *name;
@@ -124,8 +126,6 @@ struct symbol {
 	struct expr_value implied;
 };
 
-#define for_all_symbols(i, sym) for (i = 0; i < SYMBOL_HASHSIZE; i++) for (sym = symbol_hash[i]; sym; sym = sym->next)
-
 #define SYMBOL_CONST      0x0001  /* symbol is const */
 #define SYMBOL_CHECK      0x0008  /* used during dependency checking */
 #define SYMBOL_CHOICE     0x0010  /* start of a choice block (null name) */
@@ -150,7 +150,6 @@ struct symbol {
 #define SYMBOL_NEED_SET_CHOICE_VALUES  0x100000
 
 #define SYMBOL_MAXLENGTH	256
-#define SYMBOL_HASHSIZE		9973
 
 /* A property represent the config options that can be associated
  * with a config "symbol".
diff --git a/scripts/kconfig/internal.h b/scripts/kconfig/internal.h
index 788401cd5d6f..6c721c4cfd72 100644
--- a/scripts/kconfig/internal.h
+++ b/scripts/kconfig/internal.h
@@ -2,6 +2,15 @@
 #ifndef INTERNAL_H
 #define INTERNAL_H
 
+#include "hashtable.h"
+
+#define SYMBOL_HASHSIZE		(1U << 14)
+
+extern HASHTABLE_DECLARE(sym_hashtable, SYMBOL_HASHSIZE);
+
+#define for_all_symbols(sym) \
+	hash_for_each(sym_hashtable, sym, node)
+
 struct menu;
 
 extern struct menu *current_menu, *current_entry;
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h
index 94299e42402f..2807fa584c2b 100644
--- a/scripts/kconfig/lkc_proto.h
+++ b/scripts/kconfig/lkc_proto.h
@@ -18,8 +18,6 @@ void conf_set_message_callback(void (*fn)(const char *s));
 bool conf_errors(void);
 
 /* symbol.c */
-extern struct symbol * symbol_hash[SYMBOL_HASHSIZE];
-
 struct symbol * sym_lookup(const char *name, int flags);
 struct symbol * sym_find(const char *name);
 void print_symbol_for_listconfig(struct symbol *sym);
diff --git a/scripts/kconfig/parser.y b/scripts/kconfig/parser.y
index e58c24d2e5ab..112831da4f44 100644
--- a/scripts/kconfig/parser.y
+++ b/scripts/kconfig/parser.y
@@ -28,8 +28,6 @@ static void zconf_error(const char *err, ...);
 static bool zconf_endtoken(const char *tokenname,
 			   const char *expected_tokenname);
 
-struct symbol *symbol_hash[SYMBOL_HASHSIZE];
-
 struct menu *current_menu, *current_entry;
 
 %}
@@ -474,7 +472,6 @@ assign_val:
 void conf_parse(const char *name)
 {
 	struct symbol *sym;
-	int i;
 
 	autoconf_cmd = str_new();
 
@@ -517,7 +514,7 @@ void conf_parse(const char *name)
 	}
 
 	menu_finalize(&rootmenu);
-	for_all_symbols(i, sym) {
+	for_all_symbols(sym) {
 		if (sym_check_deps(sym))
 			yynerrs++;
 	}
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index 518977c525de..1290c6d2f8c2 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -9,6 +9,7 @@
 #include <string.h>
 #include <regex.h>
 
+#include "internal.h"
 #include "lkc.h"
 #include "util.h"
 
@@ -161,9 +162,8 @@ static void sym_set_changed(struct symbol *sym)
 static void sym_set_all_changed(void)
 {
 	struct symbol *sym;
-	int i;
 
-	for_all_symbols(i, sym)
+	for_all_symbols(sym)
 		sym_set_changed(sym);
 }
 
@@ -476,9 +476,8 @@ void sym_calc_value(struct symbol *sym)
 void sym_clear_all_valid(void)
 {
 	struct symbol *sym;
-	int i;
 
-	for_all_symbols(i, sym)
+	for_all_symbols(sym)
 		sym->flags &= ~SYMBOL_VALID;
 	conf_set_changed(true);
 	sym_calc_value(modules_sym);
@@ -804,6 +803,8 @@ bool sym_is_changeable(struct symbol *sym)
 	return sym->visible > sym->rev_dep.tri;
 }
 
+HASHTABLE_DEFINE(sym_hashtable, SYMBOL_HASHSIZE);
+
 struct symbol *sym_lookup(const char *name, int flags)
 {
 	struct symbol *symbol;
@@ -818,9 +819,9 @@ struct symbol *sym_lookup(const char *name, int flags)
 			case 'n': return &symbol_no;
 			}
 		}
-		hash = strhash(name) % SYMBOL_HASHSIZE;
+		hash = strhash(name);
 
-		for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
+		hash_for_each_possible(sym_hashtable, symbol, node, hash) {
 			if (symbol->name &&
 			    !strcmp(symbol->name, name) &&
 			    (flags ? symbol->flags & flags
@@ -839,8 +840,7 @@ struct symbol *sym_lookup(const char *name, int flags)
 	symbol->type = S_UNKNOWN;
 	symbol->flags = flags;
 
-	symbol->next = symbol_hash[hash];
-	symbol_hash[hash] = symbol;
+	hash_add(sym_hashtable, &symbol->node, hash);
 
 	return symbol;
 }
@@ -860,9 +860,9 @@ struct symbol *sym_find(const char *name)
 		case 'n': return &symbol_no;
 		}
 	}
-	hash = strhash(name) % SYMBOL_HASHSIZE;
+	hash = strhash(name);
 
-	for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
+	hash_for_each_possible(sym_hashtable, symbol, node, hash) {
 		if (symbol->name &&
 		    !strcmp(symbol->name, name) &&
 		    !(symbol->flags & SYMBOL_CONST))
@@ -922,7 +922,7 @@ struct symbol **sym_re_search(const char *pattern)
 	if (regcomp(&re, pattern, REG_EXTENDED|REG_ICASE))
 		return NULL;
 
-	for_all_symbols(i, sym) {
+	for_all_symbols(sym) {
 		if (sym->flags & SYMBOL_CONST || !sym->name)
 			continue;
 		if (regexec(&re, sym->name, 1, match, 0))
-- 
2.40.1


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

* [PATCH 27/27] kconfig: do not imply the type of choice value
  2024-02-02 15:57 [PATCH 00/27] kconfig: refactor lexer and parser code Masahiro Yamada
                   ` (25 preceding siblings ...)
  2024-02-02 15:58 ` [PATCH 26/27] kconfig: use generic macros to implement symbol hashtable Masahiro Yamada
@ 2024-02-02 15:58 ` Masahiro Yamada
  2024-02-10 23:47 ` [PATCH 00/27] kconfig: refactor lexer and parser code Masahiro Yamada
  27 siblings, 0 replies; 29+ messages in thread
From: Masahiro Yamada @ 2024-02-02 15:58 UTC (permalink / raw)
  To: linux-kbuild; +Cc: linux-kernel, Masahiro Yamada

Do not feed back the choice type to choice values.

Each choice value should explicitly specify 'bool' or 'tristate',
as all the Kconfig files already do. If the type were missing,
"config symbol defined without type" would be shown.

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
---

 scripts/kconfig/menu.c | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 696803d944e0..44465945d6b1 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -305,12 +305,6 @@ void menu_finalize(struct menu *parent)
 					}
 				}
 			}
-			/* set the type of the remaining choice values */
-			for (menu = parent->list; menu; menu = menu->next) {
-				current_entry = menu;
-				if (menu->sym && menu->sym->type == S_UNKNOWN)
-					menu_set_type(sym->type);
-			}
 
 			/*
 			 * Use the choice itself as the parent dependency of
-- 
2.40.1


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

* Re: [PATCH 00/27] kconfig: refactor lexer and parser code
  2024-02-02 15:57 [PATCH 00/27] kconfig: refactor lexer and parser code Masahiro Yamada
                   ` (26 preceding siblings ...)
  2024-02-02 15:58 ` [PATCH 27/27] kconfig: do not imply the type of choice value Masahiro Yamada
@ 2024-02-10 23:47 ` Masahiro Yamada
  27 siblings, 0 replies; 29+ messages in thread
From: Masahiro Yamada @ 2024-02-10 23:47 UTC (permalink / raw)
  To: linux-kbuild; +Cc: linux-kernel

On Sat, Feb 3, 2024 at 12:58 AM Masahiro Yamada <masahiroy@kernel.org> wrote:
>
> Random fixes, cleanups, etc.
>
> Masahiro Yamada (27):
>   kconfig: fix infinite loop when expanding a macro at the end of file
>   kconfig: fix off-by-one in zconf_error()
>   kconfig: remove orphan lookup_file() declaration
>   kconfig: remove compat_getline()
>   kconfig: remove unneeded sym_find() call in conf_parse()
>   kconfig: write Kconfig files to autoconf.cmd in order
>   kconfig: call env_write_dep() right after yyparse()
>   kconfig: split preprocessor prototypes into preprocess.h
>   kconfig: replace current_pos with separate cur_{filename,lineno}
>   kconfig: remove zconf_curname() and zconf_lineno()
>   kconfig: associate struct menu with file name directly
>   kconfig: associate struct property with file name directly
>   kconfig: replace file->name with name in zconf_nextfile()
>   kconfig: do not delay the cur_filename update
>   kconfig: replace remaining current_file->name with cur_filename
>   kconfig: move the file and lineno in struct file to struct buffer
>   kconfig: make file::name a flexible array member
>   kconfig: change file_lookup() to return the file name
>   kconfig: split list_head into a separate header
>   kconfig: resync list.h
>   kconfig: import more list macros and inline functions
>   kconfig: add macros useful for hashtable
>   kconfig: move ARRAY_SIZE to a header
>   kconfig: move strhash() to a header
>   kconfig: convert linked list of files to hash table
>   kconfig: use generic macros to implement symbol hashtable
>   kconfig: do not imply the type of choice value


Applied except 26/27.


26/27 breaks 'make testconfig'.
I will do a respin for 26/27 later.





>  scripts/kconfig/array_size.h |  11 ++
>  scripts/kconfig/conf.c       |  12 +-
>  scripts/kconfig/confdata.c   |  91 +++----------
>  scripts/kconfig/expr.h       |  24 +---
>  scripts/kconfig/hashtable.h  |  48 +++++++
>  scripts/kconfig/internal.h   |  12 ++
>  scripts/kconfig/lexer.l      | 100 +++++++-------
>  scripts/kconfig/list.h       | 254 ++++++++++++++++++++++++++---------
>  scripts/kconfig/list_types.h |  17 +++
>  scripts/kconfig/lkc.h        |   5 +-
>  scripts/kconfig/lkc_proto.h  |  15 ---
>  scripts/kconfig/mconf.c      |   1 +
>  scripts/kconfig/menu.c       |  24 ++--
>  scripts/kconfig/nconf.c      |   1 +
>  scripts/kconfig/parser.y     |  92 +++++++------
>  scripts/kconfig/preprocess.c |  23 ++--
>  scripts/kconfig/preprocess.h |  19 +++
>  scripts/kconfig/qconf.cc     |   2 +-
>  scripts/kconfig/symbol.c     |  46 +++----
>  scripts/kconfig/util.c       |  38 ++++--
>  scripts/kconfig/util.h       |  15 +++
>  21 files changed, 511 insertions(+), 339 deletions(-)
>  create mode 100644 scripts/kconfig/array_size.h
>  create mode 100644 scripts/kconfig/hashtable.h
>  create mode 100644 scripts/kconfig/list_types.h
>  create mode 100644 scripts/kconfig/preprocess.h
>  create mode 100644 scripts/kconfig/util.h
>
> --
> 2.40.1
>


-- 
Best Regards
Masahiro Yamada

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

end of thread, other threads:[~2024-02-10 23:48 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-02-02 15:57 [PATCH 00/27] kconfig: refactor lexer and parser code Masahiro Yamada
2024-02-02 15:57 ` [PATCH 01/27] kconfig: fix infinite loop when expanding a macro at the end of file Masahiro Yamada
2024-02-02 15:58 ` [PATCH 02/27] kconfig: fix off-by-one in zconf_error() Masahiro Yamada
2024-02-02 15:58 ` [PATCH 03/27] kconfig: remove orphan lookup_file() declaration Masahiro Yamada
2024-02-02 15:58 ` [PATCH 04/27] kconfig: remove compat_getline() Masahiro Yamada
2024-02-02 15:58 ` [PATCH 05/27] kconfig: remove unneeded sym_find() call in conf_parse() Masahiro Yamada
2024-02-02 15:58 ` [PATCH 06/27] kconfig: write Kconfig files to autoconf.cmd in order Masahiro Yamada
2024-02-02 15:58 ` [PATCH 07/27] kconfig: call env_write_dep() right after yyparse() Masahiro Yamada
2024-02-02 15:58 ` [PATCH 08/27] kconfig: split preprocessor prototypes into preprocess.h Masahiro Yamada
2024-02-02 15:58 ` [PATCH 09/27] kconfig: replace current_pos with separate cur_{filename,lineno} Masahiro Yamada
2024-02-02 15:58 ` [PATCH 10/27] kconfig: remove zconf_curname() and zconf_lineno() Masahiro Yamada
2024-02-02 15:58 ` [PATCH 11/27] kconfig: associate struct menu with file name directly Masahiro Yamada
2024-02-02 15:58 ` [PATCH 12/27] kconfig: associate struct property " Masahiro Yamada
2024-02-02 15:58 ` [PATCH 13/27] kconfig: replace file->name with name in zconf_nextfile() Masahiro Yamada
2024-02-02 15:58 ` [PATCH 14/27] kconfig: do not delay the cur_filename update Masahiro Yamada
2024-02-02 15:58 ` [PATCH 15/27] kconfig: replace remaining current_file->name with cur_filename Masahiro Yamada
2024-02-02 15:58 ` [PATCH 16/27] kconfig: move the file and lineno in struct file to struct buffer Masahiro Yamada
2024-02-02 15:58 ` [PATCH 17/27] kconfig: make file::name a flexible array member Masahiro Yamada
2024-02-02 15:58 ` [PATCH 18/27] kconfig: change file_lookup() to return the file name Masahiro Yamada
2024-02-02 15:58 ` [PATCH 19/27] kconfig: split list_head into a separate header Masahiro Yamada
2024-02-02 15:58 ` [PATCH 20/27] kconfig: resync list.h Masahiro Yamada
2024-02-02 15:58 ` [PATCH 21/27] kconfig: import more list macros and inline functions Masahiro Yamada
2024-02-02 15:58 ` [PATCH 22/27] kconfig: add macros useful for hashtable Masahiro Yamada
2024-02-02 15:58 ` [PATCH 23/27] kconfig: move ARRAY_SIZE to a header Masahiro Yamada
2024-02-02 15:58 ` [PATCH 24/27] kconfig: move strhash() " Masahiro Yamada
2024-02-02 15:58 ` [PATCH 25/27] kconfig: convert linked list of files to hash table Masahiro Yamada
2024-02-02 15:58 ` [PATCH 26/27] kconfig: use generic macros to implement symbol hashtable Masahiro Yamada
2024-02-02 15:58 ` [PATCH 27/27] kconfig: do not imply the type of choice value Masahiro Yamada
2024-02-10 23:47 ` [PATCH 00/27] kconfig: refactor lexer and parser code Masahiro Yamada

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox