[prev in list] [next in list] [prev in thread] [next in thread] 

List:       busybox
Subject:    [RFC PATCH SET] build system: update kconfig to bring new features and fixes
From:       Xabier Oneca  --  xOneca <xoneca () gmail ! com>
Date:       2021-05-18 21:57:41
Message-ID: CACkgH73X5HUoGe72GNs0YWJDrdJ9aJNMkuhG1hpNVVwjhked9Q () mail ! gmail ! com
[Download RAW message or body]

Hi,

I've been upgrading the Kconfig tools to a more modern version bought
from Linux sources. I've reached to a state where all seems to work,
but I would like to ask for feedback, and testers.

I just used the latest commit available, which at the time of starting
this journey was 5ffe04ccd69a. Actually there are more commits
available now; they can be applied in future patches.

I did not bring the testsuite for Kconfig, as I deem not interesting
for Busybox.

Also, some dependencies were updated. Mainly from scripts/ folder.
They conform the core of the build system, so almost all of the build
system is updated too. I tried to also update the main Makefile, but
it is heavily customized and could not get it to work, so I left it
for future patches.

The patch set changes can be summarized as follows:

- Patches 1-3 are little preparations. They don't seem to break the
build system.
- Patch 4 is to copy the relevant files from Linux repo to Busybox.
- Patch 5 gathers all the changes that need to be made to make the new
Kconfig again compatible with Busybox, and to recover the custom
functionality.

I've tested and seem to work the following make targets:
  config, nconfig, menuconfig, allnoconfig, defconfig,
freebsd_defconfig, all, doc, busybox, install, baseline, bloatcheck,
check, sizes, objsizes, bigdata, stksizes.

allyesconfig gives me errors and had to disable RPC, PAM, SELinux,
warnings-as-errors and fsanitize, for it to work both with old and new
build system.

Could not test cross-compiling, so it may be a possible failing point.

Let me know your impressions about this first version...

Cheers,

Xabier Oneca_,,_

["0001-build-system-quote-sourced-files-in-Config.in.patch" (application/x-patch)]

From b61598f9827b4a1e9be798b54e02481679d8ee25 Mon Sep 17 00:00:00 2001
From: Xabier Oneca <xoneca@gmail.com>
Date: Fri, 23 Apr 2021 17:58:55 +0200
Subject: [RFC PATCH 1/5] build system: quote sourced files in Config.in

Newer build system version from upstream needs file paths within quotes.

Signed-off-by: Xabier Oneca <xoneca@gmail.com>
---
 Config.in             | 44 +++++++++++++++++++++----------------------
 networking/Config.src |  2 +-
 util-linux/Config.src |  2 +-
 3 files changed, 24 insertions(+), 24 deletions(-)

diff --git a/Config.in b/Config.in
index a98a8b15b..d2ac89d5c 100644
--- a/Config.in
+++ b/Config.in
@@ -713,30 +713,30 @@ config EFENCE
 
 endchoice
 
-source libbb/Config.in
+source "libbb/Config.in"
 
 endmenu
 
 comment "Applets"
 
-source archival/Config.in
-source coreutils/Config.in
-source console-tools/Config.in
-source debianutils/Config.in
-source klibc-utils/Config.in
-source editors/Config.in
-source findutils/Config.in
-source init/Config.in
-source loginutils/Config.in
-source e2fsprogs/Config.in
-source modutils/Config.in
-source util-linux/Config.in
-source miscutils/Config.in
-source networking/Config.in
-source printutils/Config.in
-source mailutils/Config.in
-source procps/Config.in
-source runit/Config.in
-source selinux/Config.in
-source shell/Config.in
-source sysklogd/Config.in
+source "archival/Config.in"
+source "coreutils/Config.in"
+source "console-tools/Config.in"
+source "debianutils/Config.in"
+source "klibc-utils/Config.in"
+source "editors/Config.in"
+source "findutils/Config.in"
+source "init/Config.in"
+source "loginutils/Config.in"
+source "e2fsprogs/Config.in"
+source "modutils/Config.in"
+source "util-linux/Config.in"
+source "miscutils/Config.in"
+source "networking/Config.in"
+source "printutils/Config.in"
+source "mailutils/Config.in"
+source "procps/Config.in"
+source "runit/Config.in"
+source "selinux/Config.in"
+source "shell/Config.in"
+source "sysklogd/Config.in"
diff --git a/networking/Config.src b/networking/Config.src
index 04d644bc9..ba7d8a319 100644
--- a/networking/Config.src
+++ b/networking/Config.src
@@ -59,7 +59,7 @@ config FEATURE_TLS_SHA1
 
 INSERT
 
-source networking/udhcp/Config.in
+source "networking/udhcp/Config.in"
 
 config IFUPDOWN_UDHCPC_CMD_OPTIONS
 	string "ifup udhcpc command line options"
diff --git a/util-linux/Config.src b/util-linux/Config.src
index 0fad3e5c0..9cf8a356f 100644
--- a/util-linux/Config.src
+++ b/util-linux/Config.src
@@ -63,6 +63,6 @@ config FEATURE_MTAB_SUPPORT
 	About the only reason to use this is if you've removed /proc from
 	your kernel.
 
-source util-linux/volume_id/Config.in
+source "util-linux/volume_id/Config.in"
 
 endmenu
-- 
2.31.1


["0003-build-system-move-generated-headers-to-include-genet.patch" (application/x-patch)]

From dbe16ed1139797bdd8a7f84e126dd8c181bdb21c Mon Sep 17 00:00:00 2001
From: Xabier Oneca <xoneca@gmail.com>
Date: Fri, 23 Apr 2021 22:49:47 +0200
Subject: [RFC PATCH 3/5] build system: move generated headers to
 include/generated

Use this new folder for generated headers.

Moved:
- applets.h
- applet_tables.h
- bbconfigopts.h
- bbconfigopts_bz2.h
- common_bufsiz.h
- embedded_scripts.h
- NUM_APPLETS.h
- usage_compressed.h
- usage.h

Signed-off-by: Xabier Oneca <xoneca@gmail.com>
---
 Makefile                          | 28 +++++++++-------------------
 Makefile.custom                   |  8 ++++----
 applets/Kbuild.src                | 28 ++++++++++++++--------------
 applets/applet_tables.c           |  4 ++--
 applets/busybox.mkll              |  2 +-
 applets/busybox.mkscripts         |  2 +-
 applets/busybox.mksuid            |  2 +-
 applets/individual.c              |  2 +-
 applets/usage.c                   |  4 ++--
 applets/usage_pod.c               |  6 +++---
 archival/cpio.c                   |  2 +-
 archival/lzop.c                   |  2 +-
 archival/rpm.c                    |  2 +-
 archival/tar.c                    |  2 +-
 console-tools/dumpkmap.c          |  2 +-
 console-tools/resize.c            |  2 +-
 coreutils/cat.c                   |  2 +-
 coreutils/cksum.c                 |  2 +-
 coreutils/date.c                  |  2 +-
 coreutils/dd.c                    |  2 +-
 coreutils/du.c                    |  2 +-
 coreutils/expr.c                  |  2 +-
 coreutils/factor.c                |  2 +-
 coreutils/ls.c                    |  2 +-
 coreutils/od_bloaty.c             |  2 +-
 coreutils/split.c                 |  2 +-
 coreutils/stat.c                  |  2 +-
 coreutils/stty.c                  |  2 +-
 coreutils/sum.c                   |  2 +-
 coreutils/tail.c                  |  2 +-
 coreutils/tee.c                   |  2 +-
 debianutils/run_parts.c           |  2 +-
 debianutils/start_stop_daemon.c   |  2 +-
 e2fsprogs/fsck.c                  |  2 +-
 editors/diff.c                    |  2 +-
 editors/ed.c                      |  2 +-
 editors/sed.c                     |  2 +-
 findutils/find.c                  |  2 +-
 findutils/grep.c                  |  2 +-
 findutils/xargs.c                 |  2 +-
 include/.gitignore                | 12 +-----------
 include/applets.h.sh              |  4 ++--
 include/busybox.h                 |  2 +-
 init/bootchartd.c                 |  2 +-
 init/init.c                       |  2 +-
 libbb/Kbuild.src                  |  2 +-
 libbb/appletlib.c                 |  8 ++++----
 libbb/common_bufsiz.c             |  2 +-
 libbb/lineedit.c                  |  2 +-
 libbb/vfork_daemon_rexec.c        |  2 +-
 loginutils/login.c                |  2 +-
 make_single_applets.sh            | 10 +++++-----
 miscutils/bbconfig.c              |  4 ++--
 miscutils/bc.c                    |  2 +-
 miscutils/chat.c                  |  2 +-
 miscutils/conspy.c                |  2 +-
 miscutils/crond.c                 |  2 +-
 miscutils/dc.c                    |  2 +-
 miscutils/fbsplash.c              |  2 +-
 miscutils/hdparm.c                |  2 +-
 miscutils/inotifyd.c              |  2 +-
 miscutils/less.c                  |  2 +-
 miscutils/man.c                   |  2 +-
 miscutils/microcom.c              |  2 +-
 miscutils/ts.c                    |  2 +-
 networking/arp.c                  |  2 +-
 networking/arping.c               |  2 +-
 networking/brctl.c                |  2 +-
 networking/ftpd.c                 |  2 +-
 networking/ftpgetput.c            |  2 +-
 networking/httpd.c                |  2 +-
 networking/ifupdown.c             |  2 +-
 networking/inetd.c                |  2 +-
 networking/isrv_identd.c          |  2 +-
 networking/libiproute/ipaddress.c |  2 +-
 networking/libiproute/ipneigh.c   |  2 +-
 networking/libiproute/iproute.c   |  2 +-
 networking/nc.c                   |  2 +-
 networking/nslookup.c             |  2 +-
 networking/ping.c                 |  2 +-
 networking/slattach.c             |  2 +-
 networking/tc.c                   |  2 +-
 networking/tcpudp.c               |  2 +-
 networking/telnet.c               |  2 +-
 networking/telnetd.c              |  2 +-
 networking/tftp.c                 |  2 +-
 networking/udhcp/common.h         |  2 +-
 networking/zcip.c                 |  2 +-
 procps/fuser.c                    |  2 +-
 procps/nmeter.c                   |  2 +-
 procps/ps.c                       |  2 +-
 runit/runsv.c                     |  2 +-
 runit/runsvdir.c                  |  2 +-
 runit/sv.c                        |  2 +-
 runit/svlogd.c                    |  2 +-
 scripts/Makefile.IMA              |  4 ++--
 scripts/gen_build_files.sh        |  8 ++++----
 scripts/generate_BUFSIZ.sh        |  2 +-
 scripts/trylink                   |  2 +-
 selinux/setfiles.c                |  2 +-
 shell/Config.src                  |  2 +-
 shell/ash.c                       |  4 ++--
 shell/hush.c                      |  4 ++--
 size_single_applets.sh            |  6 +++---
 sysklogd/klogd.c                  |  2 +-
 sysklogd/logread.c                |  2 +-
 sysklogd/syslogd_and_logger.c     |  2 +-
 testsuite/all_sourcecode.tests    |  6 +++---
 util-linux/mdev.c                 |  2 +-
 util-linux/mkswap.c               |  2 +-
 util-linux/more.c                 |  2 +-
 util-linux/mount.c                |  2 +-
 util-linux/script.c               |  2 +-
 util-linux/swaponoff.c            |  2 +-
 util-linux/uevent.c               |  2 +-
 util-linux/umount.c               |  2 +-
 116 files changed, 163 insertions(+), 183 deletions(-)

diff --git a/Makefile b/Makefile
index b0e091d84..8ac800a83 100644
--- a/Makefile
+++ b/Makefile
@@ -522,7 +522,7 @@ include $(srctree)/Makefile.flags
 include/generated/autoconf.h: .kconfig.d .config $(wildcard $(srctree)/*/*.c) \
$(wildcard $(srctree)/*/*/*.c) | gen_build_files  $(Q)$(MAKE) -f $(srctree)/Makefile \
silentoldconfig  
-include/usage.h: gen_build_files
+include/generated/usage.h: gen_build_files
 
 else
 # Dummy target needed, because used as prerequisite
@@ -614,7 +614,7 @@ quiet_cmd_busybox__ ?= LINK    $@
       "$(libs-y)" \
       "$(LDLIBS)" \
       "$(CONFIG_EXTRA_LDLIBS)" \
-      && $(srctree)/scripts/generate_BUFSIZ.sh --post include/common_bufsiz.h
+      && $(srctree)/scripts/generate_BUFSIZ.sh --post \
include/generated/common_bufsiz.h  
 # Generate System.map
 quiet_cmd_sysmap = SYSMAP
@@ -846,14 +846,14 @@ export CPPFLAGS_busybox.lds += -P -C -U$(ARCH)
 #bbox# 	@ln -fsn asm-$(ARCH) $@
 
 # 	Split autoconf.h into include/linux/config/*
-quiet_cmd_gen_bbconfigopts = GEN     include/bbconfigopts.h
-      cmd_gen_bbconfigopts = $(srctree)/scripts/mkconfigs include/bbconfigopts.h \
                include/bbconfigopts_bz2.h
-quiet_cmd_gen_common_bufsiz = GEN     include/common_bufsiz.h
-      cmd_gen_common_bufsiz = $(srctree)/scripts/generate_BUFSIZ.sh \
include/common_bufsiz.h +quiet_cmd_gen_bbconfigopts = GEN     \
include/generated/bbconfigopts.h +      cmd_gen_bbconfigopts = \
$(srctree)/scripts/mkconfigs include/generated/bbconfigopts.h \
include/generated/bbconfigopts_bz2.h +quiet_cmd_gen_common_bufsiz = GEN     \
include/generated/common_bufsiz.h +      cmd_gen_common_bufsiz = \
$(srctree)/scripts/generate_BUFSIZ.sh include/generated/common_bufsiz.h  \
                quiet_cmd_split_autoconf   = SPLIT   include/generated/autoconf.h -> \
                include/config/*
       cmd_split_autoconf   = scripts/basic/split-include \
                include/generated/autoconf.h include/config
-quiet_cmd_gen_embedded_scripts = GEN     include/embedded_scripts.h
-      cmd_gen_embedded_scripts = $(srctree)/scripts/embedded_scripts \
include/embedded_scripts.h $(srctree)/embed $(srctree)/applets_sh \
+quiet_cmd_gen_embedded_scripts = GEN     include/generated/embedded_scripts.h +      \
cmd_gen_embedded_scripts = $(srctree)/scripts/embedded_scripts \
include/generated/embedded_scripts.h $(srctree)/embed $(srctree)/applets_sh  #bbox# \
piggybacked generation of few .h files  include/config/MARKER: \
scripts/basic/split-include include/generated/autoconf.h $(wildcard \
$(srctree)/embed/*) $(wildcard $(srctree)/applets_sh/*) \
$(srctree)/scripts/embedded_scripts  $(call cmd,split_autoconf)
@@ -972,18 +972,8 @@ CLEAN_FILES +=	busybox busybox_unstripped* busybox.links \
                 .tmp_kallsyms* .tmp_version .tmp_busybox* .tmp_System.map
 
 # Directories & files removed with 'make mrproper'
-MRPROPER_DIRS  += include/config include2
+MRPROPER_DIRS  += include/config include/generated include2
 MRPROPER_FILES += .config .config.old include/asm .version .old_version \
-		  include/NUM_APPLETS.h \
-		  include/common_bufsiz.h \
-		  include/generated/autoconf.h \
-		  include/bbconfigopts.h \
-		  include/bbconfigopts_bz2.h \
-		  include/embedded_scripts.h \
-		  include/usage_compressed.h \
-		  include/applet_tables.h \
-		  include/applets.h \
-		  include/usage.h \
 		  applets/usage \
 		  .kernelrelease Module.symvers tags TAGS cscope* \
 		  busybox_old
diff --git a/Makefile.custom b/Makefile.custom
index ba3afda03..61fabe2d8 100644
--- a/Makefile.custom
+++ b/Makefile.custom
@@ -2,12 +2,12 @@
 # Build system
 # ==========================================================================
 
-busybox.links: $(srctree)/applets/busybox.mkll \
$(objtree)/include/generated/autoconf.h include/applets.h +busybox.links: \
$(srctree)/applets/busybox.mkll $(objtree)/include/generated/autoconf.h \
include/generated/applets.h  $(Q)-$(SHELL) $^ > $@
 
-busybox.cfg.suid: $(srctree)/applets/busybox.mksuid \
$(objtree)/include/generated/autoconf.h include/applets.h +busybox.cfg.suid: \
$(srctree)/applets/busybox.mksuid $(objtree)/include/generated/autoconf.h \
include/generated/applets.h  $(Q)-SUID="yes" $(SHELL) $^ > $@
-busybox.cfg.nosuid: $(srctree)/applets/busybox.mksuid \
$(objtree)/include/generated/autoconf.h include/applets.h +busybox.cfg.nosuid: \
$(srctree)/applets/busybox.mksuid $(objtree)/include/generated/autoconf.h \
include/generated/applets.h  $(Q)-SUID="DROP" $(SHELL) $^ > $@
 
 .PHONY: install
@@ -141,7 +141,7 @@ disp_doc       = $($(quiet)cmd_doc)
 # sed adds newlines after "Options:" etc,
 # this is needed in order to get good BusyBox.{1,txt,html}
 docs/busybox.pod: $(srctree)/docs/busybox_header.pod \
-		include/usage.h \
+		include/generated/usage.h \
 		$(srctree)/docs/busybox_footer.pod \
 		applets/usage_pod
 	$(disp_doc)
diff --git a/applets/Kbuild.src b/applets/Kbuild.src
index 3aedbbffe..1a3baa798 100644
--- a/applets/Kbuild.src
+++ b/applets/Kbuild.src
@@ -25,33 +25,33 @@ endif
 HOSTCFLAGS_usage.o = -I$(srctree_slash)include -Iinclude
 HOSTCFLAGS_usage_pod.o = -I$(srctree_slash)include -Iinclude
 
-applets/applets.o: include/usage_compressed.h include/applet_tables.h
+applets/applets.o: include/generated/usage_compressed.h \
include/generated/applet_tables.h  
-applets/applet_tables: .config include/applets.h
-applets/usage:         .config include/applets.h
-applets/usage_pod:     .config include/applets.h include/applet_tables.h
+applets/applet_tables: .config include/generated/applets.h
+applets/usage:         .config include/generated/applets.h
+applets/usage_pod:     .config include/generated/applets.h \
include/generated/applet_tables.h  
-quiet_cmd_gen_usage_compressed = GEN     include/usage_compressed.h
-      cmd_gen_usage_compressed = $(srctree_slash)applets/usage_compressed \
include/usage_compressed.h applets +quiet_cmd_gen_usage_compressed = GEN     \
include/generated/usage_compressed.h +      cmd_gen_usage_compressed = \
$(srctree_slash)applets/usage_compressed include/generated/usage_compressed.h applets \
                
-include/usage_compressed.h: applets/usage $(srctree_slash)applets/usage_compressed
+include/generated/usage_compressed.h: applets/usage \
$(srctree_slash)applets/usage_compressed  $(call cmd,gen_usage_compressed)
 
-quiet_cmd_gen_applet_tables = GEN     include/applet_tables.h include/NUM_APPLETS.h
-      cmd_gen_applet_tables = applets/applet_tables include/applet_tables.h \
include/NUM_APPLETS.h +quiet_cmd_gen_applet_tables = GEN     \
include/generated/applet_tables.h include/generated/NUM_APPLETS.h +      \
cmd_gen_applet_tables = applets/applet_tables include/generated/applet_tables.h \
include/generated/NUM_APPLETS.h  
-include/NUM_APPLETS.h: applets/applet_tables
+include/generated/NUM_APPLETS.h: applets/applet_tables
 	$(call cmd,gen_applet_tables)
 
-# In fact, include/applet_tables.h depends only on applets/applet_tables,
-# and is generated by it. But specifying only it can run
+# In fact, include/generated/applet_tables.h depends only on
+# applets/applet_tables, and is generated by it. But specifying only it can run
 # applets/applet_tables twice, possibly in parallel.
 # We say that it also needs NUM_APPLETS.h
 #
 # Unfortunately, we need to list the same command,
 # and it can be executed twice (sequentially).
 # The alternative is to not list any command,
-# and then if include/applet_tables.h is deleted, it won't be rebuilt.
+# and then if include/generated/applet_tables.h is deleted, it won't be rebuilt.
 #
-include/applet_tables.h: include/NUM_APPLETS.h applets/applet_tables
+include/generated/applet_tables.h: include/generated/NUM_APPLETS.h \
applets/applet_tables  $(call cmd,gen_applet_tables)
diff --git a/applets/applet_tables.c b/applets/applet_tables.c
index da5461340..9e0e720a8 100644
--- a/applets/applet_tables.c
+++ b/applets/applet_tables.c
@@ -1,7 +1,7 @@
 /* vi: set sw=4 ts=4: */
 /*
  * Applet table generator.
- * Runs on host and produces include/applet_tables.h
+ * Runs on host and produces include/generated/applet_tables.h
  *
  * Copyright (C) 2007 Denys Vlasenko <vda.linux@googlemail.com>
  *
@@ -42,7 +42,7 @@ struct bb_applet {
 };
 
 /* Define struct bb_applet applets[] */
-#include "../include/applets.h"
+#include "../include/generated/applets.h"
 
 enum { NUM_APPLETS = ARRAY_SIZE(applets) };
 
diff --git a/applets/busybox.mkll b/applets/busybox.mkll
index acc8d1801..1257eb596 100755
--- a/applets/busybox.mkll
+++ b/applets/busybox.mkll
@@ -11,7 +11,7 @@ export LC_ALL=POSIX
 export LC_CTYPE=POSIX
 
 CONFIG_H=${1:-include/generated/autoconf.h}
-APPLETS_H=${2:-include/applets.h}
+APPLETS_H=${2:-include/generated/applets.h}
 $HOSTCC -E -DMAKE_LINKS -include $CONFIG_H $APPLETS_H |
   awk '/^[ \t]*LINK/{
 	dir=substr($2,7)
diff --git a/applets/busybox.mkscripts b/applets/busybox.mkscripts
index cf4148a58..8d4632afc 100755
--- a/applets/busybox.mkscripts
+++ b/applets/busybox.mkscripts
@@ -9,7 +9,7 @@ export LC_ALL=POSIX
 export LC_CTYPE=POSIX
 
 CONFIG_H=${1:-include/generated/autoconf.h}
-APPLETS_H=${2:-include/applets.h}
+APPLETS_H=${2:-include/generated/applets.h}
 $HOSTCC -E -DMAKE_SCRIPTS -include $CONFIG_H $APPLETS_H |
   awk '/^[ \t]*SCRIPT/{
 	print $2
diff --git a/applets/busybox.mksuid b/applets/busybox.mksuid
index 337dd7abd..a1ff7c9be 100755
--- a/applets/busybox.mksuid
+++ b/applets/busybox.mksuid
@@ -17,7 +17,7 @@ export LC_ALL=POSIX
 export LC_CTYPE=POSIX
 
 CONFIG_H=${1:-include/generated/autoconf.h}
-APPLETS_H=${2:-include/applets.h}
+APPLETS_H=${2:-include/generated/applets.h}
 DOT_CONFIG=${3:-.config}
 
 case ${SUID:-DROP} in
diff --git a/applets/individual.c b/applets/individual.c
index e94f26c93..fc102b4bf 100644
--- a/applets/individual.c
+++ b/applets/individual.c
@@ -9,7 +9,7 @@ const char *applet_name;
 
 #include <stdio.h>
 #include <stdlib.h>
-#include "usage.h"
+#include "generated/usage.h"
 
 int main(int argc, char **argv)
 {
diff --git a/applets/usage.c b/applets/usage.c
index e39fd146e..418b16f0b 100644
--- a/applets/usage.c
+++ b/applets/usage.c
@@ -21,13 +21,13 @@
 # define USE_FOR_MMU(...) __VA_ARGS__
 #endif
 
-#include "usage.h"
+#include "generated/usage.h"
 #define MAKE_USAGE(aname, usage) { aname, usage },
 static struct usage_data {
 	const char *aname;
 	const char *usage;
 } usage_array[] = {
-#include "applets.h"
+#include "generated/applets.h"
 };
 
 static int compare_func(const void *a, const void *b)
diff --git a/applets/usage_pod.c b/applets/usage_pod.c
index 4d5fe68ca..8ff156231 100644
--- a/applets/usage_pod.c
+++ b/applets/usage_pod.c
@@ -15,7 +15,7 @@
 #define SKIP_applet_main
 #define ALIGN1 /* nothing, just to placate applet_tables.h */
 #define ALIGN2 /* nothing, just to placate applet_tables.h */
-#include "applet_tables.h"
+#include "generated/applet_tables.h"
 
 /* Since we can't use platform.h, have to do this again by hand: */
 #if ENABLE_NOMMU
@@ -28,13 +28,13 @@
 # define USE_FOR_MMU(...) __VA_ARGS__
 #endif
 
-#include "usage.h"
+#include "generated/usage.h"
 #define MAKE_USAGE(aname, usage) { aname, usage },
 static struct usage_data {
 	const char *aname;
 	const char *usage;
 } usage_array[] = {
-#include "applets.h"
+#include "generated/applets.h"
 };
 
 static int compare_func(const void *a, const void *b)
diff --git a/archival/cpio.c b/archival/cpio.c
index 94303389e..b37986beb 100644
--- a/archival/cpio.c
+++ b/archival/cpio.c
@@ -142,7 +142,7 @@
  */
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #include "bb_archive.h"
 
 enum {
diff --git a/archival/lzop.c b/archival/lzop.c
index bdd21598c..3baf77d09 100644
--- a/archival/lzop.c
+++ b/archival/lzop.c
@@ -90,7 +90,7 @@
 //usage:     "\n	-F	Don't verify checksum"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #include "bb_archive.h"
 #include "liblzo_interface.h"
 
diff --git a/archival/rpm.c b/archival/rpm.c
index af8db99a6..b1831380d 100644
--- a/archival/rpm.c
+++ b/archival/rpm.c
@@ -17,7 +17,7 @@
 //kbuild:lib-$(CONFIG_RPM) += rpm.o
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #include "bb_archive.h"
 #include "rpm.h"
 
diff --git a/archival/tar.c b/archival/tar.c
index 9d4c7b662..583067b47 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -117,7 +117,7 @@
 
 #include <fnmatch.h>
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #include "bb_archive.h"
 /* FIXME: Stop using this non-standard feature */
 #ifndef FNM_LEADING_DIR
diff --git a/console-tools/dumpkmap.c b/console-tools/dumpkmap.c
index 3d8de6bed..b76fee917 100644
--- a/console-tools/dumpkmap.c
+++ b/console-tools/dumpkmap.c
@@ -27,7 +27,7 @@
 //usage:       "$ dumpkmap > keymap\n"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 /* From <linux/kd.h> */
 struct kbentry {
diff --git a/console-tools/resize.c b/console-tools/resize.c
index 59d468d48..ee2d0a5e0 100644
--- a/console-tools/resize.c
+++ b/console-tools/resize.c
@@ -34,7 +34,7 @@
 //usage:       "Resize the screen"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 #define ESC "\033"
 
diff --git a/coreutils/cat.c b/coreutils/cat.c
index 4b3414941..feac329ed 100644
--- a/coreutils/cat.c
+++ b/coreutils/cat.c
@@ -70,7 +70,7 @@
 //usage:       "110716.72 17.67"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 #if ENABLE_FEATURE_CATV
 /*
diff --git a/coreutils/cksum.c b/coreutils/cksum.c
index 633322bc7..7adbc5cee 100644
--- a/coreutils/cksum.c
+++ b/coreutils/cksum.c
@@ -23,7 +23,7 @@
 //usage:       "Calculate the CRC32 checksums of FILEs"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 /* This is a NOEXEC applet. Be very careful! */
 
diff --git a/coreutils/date.c b/coreutils/date.c
index 7061f1719..ad4726ef1 100644
--- a/coreutils/date.c
+++ b/coreutils/date.c
@@ -125,7 +125,7 @@
 //usage:       "Wed Apr 12 18:52:41 MDT 2000\n"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #if ENABLE_FEATURE_DATE_NANO
 # include <sys/syscall.h>
 #endif
diff --git a/coreutils/dd.c b/coreutils/dd.c
index a243f718b..5a8a93c7e 100644
--- a/coreutils/dd.c
+++ b/coreutils/dd.c
@@ -102,7 +102,7 @@
 //usage:       "4+0 records out\n"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 /* This is a NOEXEC applet. Be very careful! */
 
diff --git a/coreutils/du.c b/coreutils/du.c
index c8aedb6ef..62aeff125 100644
--- a/coreutils/du.c
+++ b/coreutils/du.c
@@ -72,7 +72,7 @@
 //usage:       "2417    .\n"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 enum {
 	OPT_a_files_too    = (1 << 0),
diff --git a/coreutils/expr.c b/coreutils/expr.c
index b247f08db..70091006f 100644
--- a/coreutils/expr.c
+++ b/coreutils/expr.c
@@ -78,7 +78,7 @@
 //usage:       "of characters matched or 0."
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #include "xregex.h"
 
 #if ENABLE_EXPR_MATH_SUPPORT_64
diff --git a/coreutils/factor.c b/coreutils/factor.c
index de8ea4e11..5fed0dbab 100644
--- a/coreutils/factor.c
+++ b/coreutils/factor.c
@@ -19,7 +19,7 @@
 //usage:       "Print prime factors"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 #if 0
 # define dbg(...) bb_error_msg(__VA_ARGS__)
diff --git a/coreutils/ls.c b/coreutils/ls.c
index 80ef92079..a9f0f6597 100644
--- a/coreutils/ls.c
+++ b/coreutils/ls.c
@@ -164,7 +164,7 @@
 //usage:	)
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #include "unicode.h"
 
 
diff --git a/coreutils/od_bloaty.c b/coreutils/od_bloaty.c
index 5b5e56a21..89a5b41b3 100644
--- a/coreutils/od_bloaty.c
+++ b/coreutils/od_bloaty.c
@@ -20,7 +20,7 @@
 
 
 /* #include "libbb.h" - done in od.c */
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #define assert(a) ((void)0)
 
 
diff --git a/coreutils/split.c b/coreutils/split.c
index 3fcfd95f2..d9b0651d9 100644
--- a/coreutils/split.c
+++ b/coreutils/split.c
@@ -41,7 +41,7 @@
 //usage:       "$ cat TODO | split -a 2 -l 2 TODO_\n"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 #if ENABLE_FEATURE_SPLIT_FANCY
 static const struct suffix_mult split_suffixes[] ALIGN_SUFFIX = {
diff --git a/coreutils/stat.c b/coreutils/stat.c
index a8393468e..0d59e2b2b 100644
--- a/coreutils/stat.c
+++ b/coreutils/stat.c
@@ -105,7 +105,7 @@
 //usage:	)
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 enum {
 	OPT_TERSE       = (1 << 0),
diff --git a/coreutils/stty.c b/coreutils/stty.c
index ba2b78317..7993e721f 100644
--- a/coreutils/stty.c
+++ b/coreutils/stty.c
@@ -35,7 +35,7 @@
  */
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 #ifndef _POSIX_VDISABLE
 # define _POSIX_VDISABLE ((unsigned char) 0)
diff --git a/coreutils/sum.c b/coreutils/sum.c
index 16ec44540..d098e2f72 100644
--- a/coreutils/sum.c
+++ b/coreutils/sum.c
@@ -30,7 +30,7 @@
 //usage:     "\n	-s	Use System V sum algorithm (512byte blocks)"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 enum { SUM_BSD, PRINT_NAME, SUM_SYSV };
 
diff --git a/coreutils/tail.c b/coreutils/tail.c
index 08fde6cdd..8f5dacc90 100644
--- a/coreutils/tail.c
+++ b/coreutils/tail.c
@@ -68,7 +68,7 @@
 //usage:       "nameserver 10.0.0.1\n"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 struct globals {
 	bool from_top;
diff --git a/coreutils/tee.c b/coreutils/tee.c
index e67296d43..b81d50643 100644
--- a/coreutils/tee.c
+++ b/coreutils/tee.c
@@ -53,7 +53,7 @@
 // ^^^^ this should set SIGPIPE to SIG_IGN. EPIPE is ignored (same as "warn-nopipe")
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 int tee_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int tee_main(int argc, char **argv)
diff --git a/debianutils/run_parts.c b/debianutils/run_parts.c
index 585a4b58f..cd27991bc 100644
--- a/debianutils/run_parts.c
+++ b/debianutils/run_parts.c
@@ -87,7 +87,7 @@
 //usage:       "+ shutdown -h +4m"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 struct globals {
 	char **names;
diff --git a/debianutils/start_stop_daemon.c b/debianutils/start_stop_daemon.c
index 68df44ae9..3d1193c82 100644
--- a/debianutils/start_stop_daemon.c
+++ b/debianutils/start_stop_daemon.c
@@ -119,7 +119,7 @@ Misc options:
 /* Override ENABLE_FEATURE_PIDFILE */
 #define WANT_PIDFILE 1
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 struct pid_list {
 	struct pid_list *next;
diff --git a/e2fsprogs/fsck.c b/e2fsprogs/fsck.c
index 96c1e51e0..1bfab954d 100644
--- a/e2fsprogs/fsck.c
+++ b/e2fsprogs/fsck.c
@@ -60,7 +60,7 @@
 //usage:     "\n	-t TYPE	List of filesystem types to check"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 /* "progress indicator" code is somewhat buggy and ext[23] specific.
  * We should be filesystem agnostic. IOW: there should be a well-defined
diff --git a/editors/diff.c b/editors/diff.c
index 1adc4cbc7..ae4ce6729 100644
--- a/editors/diff.c
+++ b/editors/diff.c
@@ -121,7 +121,7 @@
 //usage:     "\n	-w	Ignore all whitespace"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 #if 0
 # define dbg_error_msg(...) bb_error_msg(__VA_ARGS__)
diff --git a/editors/ed.c b/editors/ed.c
index c50faeefa..0d5bab8e9 100644
--- a/editors/ed.c
+++ b/editors/ed.c
@@ -22,7 +22,7 @@
 //usage:#define ed_full_usage ""
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 typedef struct LINE {
 	struct LINE *next;
diff --git a/editors/sed.c b/editors/sed.c
index d3444003e..7f30d9581 100644
--- a/editors/sed.c
+++ b/editors/sed.c
@@ -83,7 +83,7 @@
 //usage:       "bar\n"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #include "xregex.h"
 
 #if 0
diff --git a/findutils/find.c b/findutils/find.c
index 34e11ae26..9c0f8fa2e 100644
--- a/findutils/find.c
+++ b/findutils/find.c
@@ -354,7 +354,7 @@
 
 #include <fnmatch.h>
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #if ENABLE_FEATURE_FIND_REGEX
 # include "xregex.h"
 #endif
diff --git a/findutils/grep.c b/findutils/grep.c
index 10cca83e7..588b9586d 100644
--- a/findutils/grep.c
+++ b/findutils/grep.c
@@ -54,7 +54,7 @@
 //kbuild:lib-$(CONFIG_FGREP) += grep.o
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #include "xregex.h"
 
 
diff --git a/findutils/xargs.c b/findutils/xargs.c
index e2b3527f3..1d0e253a7 100644
--- a/findutils/xargs.c
+++ b/findutils/xargs.c
@@ -75,7 +75,7 @@
 //kbuild:lib-$(CONFIG_XARGS) += xargs.o
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 /* This is a NOEXEC applet. Be very careful! */
 
diff --git a/include/.gitignore b/include/.gitignore
index 7e36fe985..331fb4503 100644
--- a/include/.gitignore
+++ b/include/.gitignore
@@ -1,12 +1,2 @@
 /config
-
-/applets.h
-/applet_tables.h
-/generated/autoconf.h
-/bbconfigopts_bz2.h
-/bbconfigopts.h
-/embedded_scripts.h
-/NUM_APPLETS.h
-/usage_compressed.h
-/usage.h
-/common_bufsiz.h*
+/generated
diff --git a/include/applets.h.sh b/include/applets.h.sh
index be117cf84..60ffaac20 100755
--- a/include/applets.h.sh
+++ b/include/applets.h.sh
@@ -4,12 +4,12 @@
 # enabling it. Run it after applets.h is generated.
 
 # CONFIG_applet names
-grep ^IF_ applets.h | grep -v ^IF_FEATURE_ | sed 's/IF_\([A-Z0-9._-]*\)(.*/\1/' \
+grep ^IF_ generated/applets.h | grep -v ^IF_FEATURE_ | sed \
's/IF_\([A-Z0-9._-]*\)(.*/\1/' \  | sort | uniq \
 >applets_APP1
 
 # command line applet names
-grep ^IF_ applets.h | sed -e's/ //g' -e's/.*(\([a-z[][^,]*\),.*/\1/' \
+grep ^IF_ generated/applets.h | sed -e's/ //g' -e's/.*(\([a-z[][^,]*\),.*/\1/' \
 | grep -v '^bash$' \
 | grep -v '^sh$' \
 | tr a-z A-Z \
diff --git a/include/busybox.h b/include/busybox.h
index 6a003d544..cf1a91f14 100644
--- a/include/busybox.h
+++ b/include/busybox.h
@@ -11,7 +11,7 @@
 
 PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
 
-/* Defined in appletlib.c (by including generated applet_tables.h) */
+/* Defined in appletlib.c (by including generated/applet_tables.h) */
 /* Keep in sync with applets/applet_tables.c! */
 extern const char applet_names[] ALIGN1;
 extern int (*const applet_main[])(int argc, char **argv);
diff --git a/init/bootchartd.c b/init/bootchartd.c
index ae1ee9d9a..ed7d3dcc9 100644
--- a/init/bootchartd.c
+++ b/init/bootchartd.c
@@ -46,7 +46,7 @@
 //kbuild:lib-$(CONFIG_BOOTCHARTD) += bootchartd.o
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 /* After libbb.h, since it needs sys/types.h on some systems */
 #include <sys/utsname.h>
 
diff --git a/init/init.c b/init/init.c
index efab5dcb4..890abe14d 100644
--- a/init/init.c
+++ b/init/init.c
@@ -128,7 +128,7 @@
 #define DEBUG_SEGV_HANDLER 0
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #include <syslog.h>
 #ifdef __linux__
 # include <linux/vt.h>
diff --git a/libbb/Kbuild.src b/libbb/Kbuild.src
index 676300801..72abe4469 100644
--- a/libbb/Kbuild.src
+++ b/libbb/Kbuild.src
@@ -4,7 +4,7 @@
 #
 # Licensed under GPLv2, see file LICENSE in this source tree.
 
-libbb/appletlib.o: include/usage_compressed.h
+libbb/appletlib.o: include/generated/usage_compressed.h
 
 lib-y:=
 
diff --git a/libbb/appletlib.c b/libbb/appletlib.c
index 2feed64dd..2f7455b8b 100644
--- a/libbb/appletlib.c
+++ b/libbb/appletlib.c
@@ -40,11 +40,11 @@ static inline int *get_perrno(void) { return &errno; }
 
 /* Declare <applet>_main() */
 #define PROTOTYPES
-#include "applets.h"
+#include "generated/applets.h"
 #undef PROTOTYPES
 
 /* Include generated applet names, pointers to <applet>_main, etc */
-#include "applet_tables.h"
+#include "generated/applet_tables.h"
 /* ...and if applet_tables generator says we have only one applet... */
 #ifdef SINGLE_APPLET_MAIN
 # undef ENABLE_FEATURE_INDIVIDUAL
@@ -53,11 +53,11 @@ static inline int *get_perrno(void) { return &errno; }
 # define IF_FEATURE_INDIVIDUAL(...) __VA_ARGS__
 #endif
 
-#include "usage_compressed.h"
+#include "generated/usage_compressed.h"
 
 #if ENABLE_FEATURE_SH_EMBEDDED_SCRIPTS
 # define DEFINE_SCRIPT_DATA 1
-# include "embedded_scripts.h"
+# include "generated/embedded_scripts.h"
 #else
 # define NUM_SCRIPTS 0
 #endif
diff --git a/libbb/common_bufsiz.c b/libbb/common_bufsiz.c
index 6bc6d7bc9..eb4ebb594 100644
--- a/libbb/common_bufsiz.c
+++ b/libbb/common_bufsiz.c
@@ -43,7 +43,7 @@
 //kbuild:lib-y += common_bufsiz.o
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 #if !ENABLE_FEATURE_USE_BSS_TAIL
 
diff --git a/libbb/lineedit.c b/libbb/lineedit.c
index 68d19e127..d4ec36087 100644
--- a/libbb/lineedit.c
+++ b/libbb/lineedit.c
@@ -39,7 +39,7 @@
  * resulting in line wrap problems with long (multi-line) input.
  */
 #include "busybox.h"
-#include "NUM_APPLETS.h"
+#include "generated/NUM_APPLETS.h"
 #include "unicode.h"
 #ifndef _POSIX_VDISABLE
 # define _POSIX_VDISABLE '\0'
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c
index a49fe8e01..f5ebccadf 100644
--- a/libbb/vfork_daemon_rexec.c
+++ b/libbb/vfork_daemon_rexec.c
@@ -15,7 +15,7 @@
  * Licensed under GPLv2 or later, see file LICENSE in this source tree.
  */
 #include "busybox.h" /* uses applet tables */
-#include "NUM_APPLETS.h"
+#include "generated/NUM_APPLETS.h"
 
 #define NOFORK_SUPPORT ((NUM_APPLETS > 1) && (ENABLE_FEATURE_PREFER_APPLETS || \
ENABLE_FEATURE_SH_NOFORK))  #define NOEXEC_SUPPORT ((NUM_APPLETS > 1) && \
                (ENABLE_FEATURE_PREFER_APPLETS || ENABLE_FEATURE_SH_STANDALONE))
diff --git a/loginutils/login.c b/loginutils/login.c
index ce87e318a..9f24bc6b2 100644
--- a/loginutils/login.c
+++ b/loginutils/login.c
@@ -67,7 +67,7 @@
 //usage:	)
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #include <syslog.h>
 
 #if ENABLE_SELINUX
diff --git a/make_single_applets.sh b/make_single_applets.sh
index 7df53397e..7ec01734f 100755
--- a/make_single_applets.sh
+++ b/make_single_applets.sh
@@ -1,6 +1,6 @@
 #!/bin/sh
 # This script expects that the tree was built with the desired .config:
-# in particular, it expects that include/applets.h is generated already.
+# in particular, it expects that include/generated/applets.h is generated already.
 #
 # The script will try to rebuild each enabled applet in isolation.
 # All other options which chose general bbox config, applet features, etc,
@@ -9,9 +9,9 @@
 makeopts="-j9"
 
 # The list of all applet config symbols
-test -f include/applets.h || { echo "No include/applets.h file"; exit 1; }
+test -f include/generated/applets.h || { echo "No include/generated/applets.h file"; \
exit 1; }  apps="`
-grep ^IF_ include/applets.h \
+grep ^IF_ include/generated/applets.h \
 | grep -v '^IF_FEATURE_' \
 | sed 's/IF_\([A-Z0-9._-]*\)(.*/\1/' \
 | grep -v '^BUSYBOX$' \
@@ -67,11 +67,11 @@ for app; do
 		grep -i -e error: -e warning: busybox_make_${app}.log
 		echo "Build error for ${app}"
 		mv .config busybox_config_${app}
-	elif ! grep -q '^#define NUM_APPLETS 1$' include/NUM_APPLETS.h; then
+	elif ! grep -q '^#define NUM_APPLETS 1$' include/generated/NUM_APPLETS.h; then
 		grep -i -e error: -e warning: busybox_make_${app}.log
 		mv busybox busybox_${app}
 		fail=$((fail+1))
-		echo "NUM_APPLETS != 1 for ${app}: `cat include/NUM_APPLETS.h`"
+		echo "NUM_APPLETS != 1 for ${app}: `cat include/generated/NUM_APPLETS.h`"
 		mv .config busybox_config_${app}
 	else
 		if grep -q 'use larger COMMON_BUFSIZE' busybox_make_${app}.log; then
diff --git a/miscutils/bbconfig.c b/miscutils/bbconfig.c
index fe02516a8..cf911c10e 100644
--- a/miscutils/bbconfig.c
+++ b/miscutils/bbconfig.c
@@ -33,10 +33,10 @@
 //usage:       "Print the config file used by busybox build"
 
 #include "libbb.h"
-#include "bbconfigopts.h"
+#include "generated/bbconfigopts.h"
 #if ENABLE_FEATURE_COMPRESS_BBCONFIG
 # include "bb_archive.h"
-# include "bbconfigopts_bz2.h"
+# include "generated/bbconfigopts_bz2.h"
 #endif
 
 int bbconfig_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
diff --git a/miscutils/bc.c b/miscutils/bc.c
index dd9f4f8f1..71b7be51c 100644
--- a/miscutils/bc.c
+++ b/miscutils/bc.c
@@ -202,7 +202,7 @@
 //usage:       "64\n"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 #if !ENABLE_BC && !ENABLE_FEATURE_DC_BIG
 # include "dc.c"
diff --git a/miscutils/chat.c b/miscutils/chat.c
index 86a114df6..ec901ae6f 100644
--- a/miscutils/chat.c
+++ b/miscutils/chat.c
@@ -87,7 +87,7 @@
 //usage:       "chat '' ATZ OK ATD123456 CONNECT '' ogin: pppuser word: ppppass '~'"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 // default timeout: 45 sec
 #define DEFAULT_CHAT_TIMEOUT 45*1000
diff --git a/miscutils/conspy.c b/miscutils/conspy.c
index 21a498d0f..9cfadbdb0 100644
--- a/miscutils/conspy.c
+++ b/miscutils/conspy.c
@@ -40,7 +40,7 @@
 //usage:     "\n	-y LINE	Starting line"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #include <sys/kd.h>
 
 #define ESC "\033"
diff --git a/miscutils/crond.c b/miscutils/crond.c
index b74427351..bf1c23a58 100644
--- a/miscutils/crond.c
+++ b/miscutils/crond.c
@@ -76,7 +76,7 @@
 //usage:     "\n	-c DIR	Cron dir. Default:"CONFIG_FEATURE_CROND_DIR"/crontabs"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #include <syslog.h>
 
 #if 0
diff --git a/miscutils/dc.c b/miscutils/dc.c
index 42baa67ad..1b0981b46 100644
--- a/miscutils/dc.c
+++ b/miscutils/dc.c
@@ -6,7 +6,7 @@
 /* config/applet/usage bits are in bc.c */
 
 //#include "libbb.h"
-//#include "common_bufsiz.h"
+//#include "generated/common_bufsiz.h"
 #include <math.h>
 
 #if 0
diff --git a/miscutils/fbsplash.c b/miscutils/fbsplash.c
index 2934d8eb7..80ac2122a 100644
--- a/miscutils/fbsplash.c
+++ b/miscutils/fbsplash.c
@@ -58,7 +58,7 @@
 //usage:     "\n			commands: 'NN' (% for progress bar) or 'exit'"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #include <linux/fb.h>
 
 /* If you want logging messages on /tmp/fbsplash.log... */
diff --git a/miscutils/hdparm.c b/miscutils/hdparm.c
index 01b4e8e2e..616336d95 100644
--- a/miscutils/hdparm.c
+++ b/miscutils/hdparm.c
@@ -123,7 +123,7 @@
 //usage:     "\n	-z	Reread partition table"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 /* must be _after_ libbb.h: */
 #include <linux/hdreg.h>
 #include <sys/mount.h>
diff --git a/miscutils/inotifyd.c b/miscutils/inotifyd.c
index 8bff86ae5..65cbd967e 100644
--- a/miscutils/inotifyd.c
+++ b/miscutils/inotifyd.c
@@ -66,7 +66,7 @@
 //usage:     "\nWhen x event happens for all FILEs, inotifyd exits."
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #include <sys/inotify.h>
 
 static const char mask_names[] ALIGN1 =
diff --git a/miscutils/less.c b/miscutils/less.c
index 223c2558d..0ae439e9c 100644
--- a/miscutils/less.c
+++ b/miscutils/less.c
@@ -146,7 +146,7 @@
 #include <sched.h>  /* sched_yield() */
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #if ENABLE_FEATURE_LESS_REGEXP
 #include "xregex.h"
 #endif
diff --git a/miscutils/man.c b/miscutils/man.c
index 722f6641e..b2abe08c1 100644
--- a/miscutils/man.c
+++ b/miscutils/man.c
@@ -22,7 +22,7 @@
 //usage:     "\n$COLUMNS overrides output width"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 enum {
 	OPT_a = 1, /* all */
diff --git a/miscutils/microcom.c b/miscutils/microcom.c
index 399d4cf7f..87054323c 100644
--- a/miscutils/microcom.c
+++ b/miscutils/microcom.c
@@ -28,7 +28,7 @@
 //usage:     "\n	-X	Disable special meaning of NUL and Ctrl-X from stdin"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 // set raw tty mode
 static void xget1(int fd, struct termios *t, struct termios *oldt)
diff --git a/miscutils/ts.c b/miscutils/ts.c
index 6e5d77bda..2871439ec 100644
--- a/miscutils/ts.c
+++ b/miscutils/ts.c
@@ -16,7 +16,7 @@
 //usage:#define ts_full_usage ""
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 int ts_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int ts_main(int argc UNUSED_PARAM, char **argv)
diff --git a/networking/arp.c b/networking/arp.c
index 16783ab95..8e4900c25 100644
--- a/networking/arp.c
+++ b/networking/arp.c
@@ -41,7 +41,7 @@
 //usage:       "\n	-H HWTYPE	Hardware address type"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #include "inet_common.h"
 
 #include <arpa/inet.h>
diff --git a/networking/arping.c b/networking/arping.c
index d44d7d697..1ae317369 100644
--- a/networking/arping.c
+++ b/networking/arping.c
@@ -38,7 +38,7 @@
 #include <netpacket/packet.h>
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 /* We don't expect to see 1000+ seconds delay, unsigned is enough */
 #define MONOTONIC_US() ((unsigned)monotonic_us())
diff --git a/networking/brctl.c b/networking/brctl.c
index c83aac6e0..5a90b2da2 100644
--- a/networking/brctl.c
+++ b/networking/brctl.c
@@ -67,7 +67,7 @@
 //			hairpin BRIDGE IFACE on|off	Set hairpin on/off
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #include <linux/sockios.h>
 #include <net/if.h>
 
diff --git a/networking/ftpd.c b/networking/ftpd.c
index 6ca231c90..d520901b6 100644
--- a/networking/ftpd.c
+++ b/networking/ftpd.c
@@ -82,7 +82,7 @@
 //usage:     "\n	-t,-T N	Idle and absolute timeout"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #include <syslog.h>
 #include <netinet/tcp.h>
 
diff --git a/networking/ftpgetput.c b/networking/ftpgetput.c
index 30b3dabd1..c1f4ea68f 100644
--- a/networking/ftpgetput.c
+++ b/networking/ftpgetput.c
@@ -55,7 +55,7 @@
 //usage:     "\n	-P PORT"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 struct globals {
 	const char *user;
diff --git a/networking/httpd.c b/networking/httpd.c
index 56ab85b82..44a405248 100644
--- a/networking/httpd.c
+++ b/networking/httpd.c
@@ -285,7 +285,7 @@
 /* TODO: use TCP_CORK, parse_config() */
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #if ENABLE_PAM
 /* PAM may include <locale.h>. We may need to undefine bbox's stub define: */
 # undef setlocale
diff --git a/networking/ifupdown.c b/networking/ifupdown.c
index 737113dd4..4d5b65996 100644
--- a/networking/ifupdown.c
+++ b/networking/ifupdown.c
@@ -140,7 +140,7 @@
 
 #include <net/if.h>
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 /* After libbb.h, since it needs sys/types.h on some systems */
 #include <sys/utsname.h>
 #include <fnmatch.h>
diff --git a/networking/inetd.c b/networking/inetd.c
index e5352a555..c0852cae3 100644
--- a/networking/inetd.c
+++ b/networking/inetd.c
@@ -241,7 +241,7 @@
 #include <sys/un.h>
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 #if ENABLE_FEATURE_INETD_RPC
 # if defined(__UCLIBC__) && ! defined(__UCLIBC_HAS_RPC__)
diff --git a/networking/isrv_identd.c b/networking/isrv_identd.c
index f564d604a..12a7df00d 100644
--- a/networking/isrv_identd.c
+++ b/networking/isrv_identd.c
@@ -29,7 +29,7 @@
 //usage:     "\n	STRING	Ident answer string (default: nobody)"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #include <syslog.h>
 #include "isrv.h"
 
diff --git a/networking/libiproute/ipaddress.c b/networking/libiproute/ipaddress.c
index 17a838411..7736f2147 100644
--- a/networking/libiproute/ipaddress.c
+++ b/networking/libiproute/ipaddress.c
@@ -12,7 +12,7 @@
 #include <net/if_arp.h>
 
 #include "ip_common.h"  /* #include "libbb.h" is inside */
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #include "rt_names.h"
 #include "utils.h"
 
diff --git a/networking/libiproute/ipneigh.c b/networking/libiproute/ipneigh.c
index b9b4f4b31..1ecfff39b 100644
--- a/networking/libiproute/ipneigh.c
+++ b/networking/libiproute/ipneigh.c
@@ -7,7 +7,7 @@
  * Ported to Busybox by:  Curt Brune <curt@cumulusnetworks.com>
  */
 #include "ip_common.h"  /* #include "libbb.h" is inside */
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #include "rt_names.h"
 #include "utils.h"
 #include <linux/neighbour.h>
diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c
index 5a972f8b2..7a9a118bd 100644
--- a/networking/libiproute/iproute.c
+++ b/networking/libiproute/iproute.c
@@ -10,7 +10,7 @@
  * Kunihiro Ishiguro <kunihiro@zebra.org> 001102: rtnh_ifindex was not initialized
  */
 #include "ip_common.h"  /* #include "libbb.h" is inside */
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #include "rt_names.h"
 #include "utils.h"
 
diff --git a/networking/nc.c b/networking/nc.c
index 705b7356a..7723421f6 100644
--- a/networking/nc.c
+++ b/networking/nc.c
@@ -54,7 +54,7 @@
 //kbuild:lib-$(CONFIG_NETCAT) += nc.o
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #if ENABLE_NC_110_COMPAT
 # include "nc_bloaty.c"
 #else
diff --git a/networking/nslookup.c b/networking/nslookup.c
index c43ad46f3..081b63b6a 100644
--- a/networking/nslookup.c
+++ b/networking/nslookup.c
@@ -39,7 +39,7 @@
 //#include <arpa/inet.h>
 //#include <netdb.h>
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 
 #if !ENABLE_FEATURE_NSLOOKUP_BIG
diff --git a/networking/ping.c b/networking/ping.c
index 86d8088de..86bf309a3 100644
--- a/networking/ping.c
+++ b/networking/ping.c
@@ -128,7 +128,7 @@
 #endif
 #include <netinet/ip_icmp.h>
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 #ifdef __BIONIC__
 /* should be in netinet/ip_icmp.h */
diff --git a/networking/slattach.c b/networking/slattach.c
index 6d2a252fc..27d6f8a4a 100644
--- a/networking/slattach.c
+++ b/networking/slattach.c
@@ -37,7 +37,7 @@
 //usage:     "\n	-F	Disable RTS/CTS flow control"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #include "libiproute/utils.h" /* invarg_1_to_2() */
 
 struct globals {
diff --git a/networking/tc.c b/networking/tc.c
index 510684443..a242c18c5 100644
--- a/networking/tc.c
+++ b/networking/tc.c
@@ -43,7 +43,7 @@
 //usage:	"filter show [dev STRING] [root|parent CLASSID]"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 #include "libiproute/utils.h"
 #include "libiproute/ip_common.h"
diff --git a/networking/tcpudp.c b/networking/tcpudp.c
index 8c4afabf6..8d203cf5a 100644
--- a/networking/tcpudp.c
+++ b/networking/tcpudp.c
@@ -105,7 +105,7 @@
 //usage:     "\nUDPREMOTEHOST='hostname'"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 #ifdef __linux__
 /* from linux/netfilter_ipv4.h: */
diff --git a/networking/telnet.c b/networking/telnet.c
index 7a0253525..7c39bfe1b 100644
--- a/networking/telnet.c
+++ b/networking/telnet.c
@@ -72,7 +72,7 @@
 #include <arpa/telnet.h>
 #include <netinet/in.h>
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 #ifdef __BIONIC__
 /* should be in arpa/telnet.h */
diff --git a/networking/telnetd.c b/networking/telnetd.c
index 29f805de7..42d16f7f2 100644
--- a/networking/telnetd.c
+++ b/networking/telnetd.c
@@ -116,7 +116,7 @@
 #define DEBUG 0
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #include <syslog.h>
 
 #if DEBUG
diff --git a/networking/tftp.c b/networking/tftp.c
index 4b86ed9de..f2fbf52aa 100644
--- a/networking/tftp.c
+++ b/networking/tftp.c
@@ -124,7 +124,7 @@
 //usage:     "\n	-l	Log to syslog (inetd mode requires this)"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #include <syslog.h>
 
 #if ENABLE_FEATURE_TFTP_GET || ENABLE_FEATURE_TFTP_PUT
diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h
index cc0abd269..706001e51 100644
--- a/networking/udhcp/common.h
+++ b/networking/udhcp/common.h
@@ -9,7 +9,7 @@
 #define UDHCP_COMMON_H 1
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #include <netinet/udp.h>
 #include <netinet/ip.h>
 
diff --git a/networking/zcip.c b/networking/zcip.c
index 311dfbe4c..9d099627b 100644
--- a/networking/zcip.c
+++ b/networking/zcip.c
@@ -54,7 +54,7 @@
 //usage:     "\nexits only on I/O errors (link down etc)"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #include <netinet/ether.h>
 #include <net/if.h>
 #include <net/if_arp.h>
diff --git a/procps/fuser.c b/procps/fuser.c
index 191746751..dbb979ca3 100644
--- a/procps/fuser.c
+++ b/procps/fuser.c
@@ -29,7 +29,7 @@
 //usage:     "\n	-SIGNAL	Signal to send (default: KILL)"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 #define MAX_LINE 255
 
diff --git a/procps/nmeter.c b/procps/nmeter.c
index f08938654..418577033 100644
--- a/procps/nmeter.c
+++ b/procps/nmeter.c
@@ -53,7 +53,7 @@
 //  totalswap=134209536, freeswap=134209536, procs=157})
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 typedef unsigned long long ullong;
 
diff --git a/procps/ps.c b/procps/ps.c
index 711b180a0..cf086faf2 100644
--- a/procps/ps.c
+++ b/procps/ps.c
@@ -109,7 +109,7 @@
 //usage:       " 2990 andersen andersen R ps\n"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #ifdef __linux__
 # include <sys/sysinfo.h>
 #endif
diff --git a/runit/runsv.c b/runit/runsv.c
index ecab8cdf5..e96f14d7c 100644
--- a/runit/runsv.c
+++ b/runit/runsv.c
@@ -45,7 +45,7 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include <sys/file.h>
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #include "runit_lib.h"
 
 #if ENABLE_MONOTONIC_SYSCALL
diff --git a/runit/runsvdir.c b/runit/runsvdir.c
index 55dd47e0d..18b8fd414 100644
--- a/runit/runsvdir.c
+++ b/runit/runsvdir.c
@@ -57,7 +57,7 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include <sys/file.h>
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #include "runit_lib.h"
 
 #define MAXSERVICES 1000
diff --git a/runit/sv.c b/runit/sv.c
index 5c249ff95..c0949b9b4 100644
--- a/runit/sv.c
+++ b/runit/sv.c
@@ -192,7 +192,7 @@ Exit Codes
 
 #include <sys/file.h>
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #include "runit_lib.h"
 
 struct globals {
diff --git a/runit/svlogd.c b/runit/svlogd.c
index 294e31aca..b0926ae25 100644
--- a/runit/svlogd.c
+++ b/runit/svlogd.c
@@ -161,7 +161,7 @@ log message, you can use a pattern like this instead
 
 #include <sys/file.h>
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #include "runit_lib.h"
 
 #define LESS(a,b) ((int)((unsigned)(b) - (unsigned)(a)) > 0)
diff --git a/scripts/Makefile.IMA b/scripts/Makefile.IMA
index b9c60f57f..fb07f5e92 100644
--- a/scripts/Makefile.IMA
+++ b/scripts/Makefile.IMA
@@ -57,7 +57,7 @@ include Makefile.flags
 
 -include $(srctree)/arch/$(ARCH)/Makefile
 ifdef CONFIG_FEATURE_COMPRESS_USAGE
-usage_stuff = include/usage_compressed.h
+usage_stuff = include/generated/usage_compressed.h
 endif
 
 ifndef BB_VER
@@ -176,7 +176,7 @@ lib-all-y += $(patsubst %,libbb/%,$(sort $(lib-y)))
 lib-y:=
 
 comma:=,
-busybox_unstripped.o: $(usage_stuff) include/applet_tables.h include/NUM_APPLETS.h \
include/generated/autoconf.h +busybox_unstripped.o: $(usage_stuff) \
include/generated/applet_tables.h include/generated/NUM_APPLETS.h \
include/generated/autoconf.h  $(CC) $(CPPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) \
 		$(patsubst %,-Wl$(comma)%,$(LDFLAGS) $(EXTRA_LDFLAGS)) \
 		-DGCC_COMBINE=1 \
diff --git a/scripts/gen_build_files.sh b/scripts/gen_build_files.sh
index 92de681ac..5244a7dd5 100755
--- a/scripts/gen_build_files.sh
+++ b/scripts/gen_build_files.sh
@@ -66,15 +66,15 @@ generate()
 	fi
 }
 
-# (Re)generate include/applets.h
+# (Re)generate include/generated/applets.h
 sed -n 's@^//applet:@@p' "$srctree"/*/*.c "$srctree"/*/*/*.c \
 | generate \
 	"$srctree/include/applets.src.h" \
-	"include/applets.h" \
+	"include/generated/applets.h" \
 	"/* DO NOT EDIT. This file is generated from applets.src.h */" \
 	"$srctree/embed"
 
-# (Re)generate include/usage.h
+# (Re)generate include/generated/usage.h
 # We add line continuation backslash after each line,
 # and insert empty line before each line which doesn't start
 # with space or tab
@@ -87,7 +87,7 @@ sed -n -e 's@^//usage:\([ '"$TAB"'].*\)$@\1 \\@p' \
 	"$srctree"/*/*.c "$srctree"/*/*/*.c \
 | generate \
 	"$srctree/include/usage.src.h" \
-	"include/usage.h" \
+	"include/generated/usage.h" \
 	"/* DO NOT EDIT. This file is generated from usage.src.h */"
 
 # (Re)generate */Kbuild and */Config.in
diff --git a/scripts/generate_BUFSIZ.sh b/scripts/generate_BUFSIZ.sh
index 718788e0b..8aac7ffc8 100755
--- a/scripts/generate_BUFSIZ.sh
+++ b/scripts/generate_BUFSIZ.sh
@@ -1,7 +1,7 @@
 #!/bin/sh
 # Called from top-level directory a-la
 #
-# scripts/generate_BUFSIZ.sh include/common_bufsiz.h
+# scripts/generate_BUFSIZ.sh include/generated/common_bufsiz.h
 
 . ./.config || exit 1
 
diff --git a/scripts/trylink b/scripts/trylink
index c637fca6f..39833ca60 100755
--- a/scripts/trylink
+++ b/scripts/trylink
@@ -296,7 +296,7 @@ fi
 
 if test "$CONFIG_FEATURE_INDIVIDUAL" = y; then
     echo "Linking individual applets against libbusybox (see $sharedlib_dir/*)"
-    gcc -DNAME_MAIN -E -include include/generated/autoconf.h include/applets.h \
+    gcc -DNAME_MAIN -E -include include/generated/autoconf.h \
include/generated/applets.h \  | grep -v "^#" \
     | grep -v "^ *$" \
     > applet_lst.tmp
diff --git a/selinux/setfiles.c b/selinux/setfiles.c
index a617b95d8..fd383b6e6 100644
--- a/selinux/setfiles.c
+++ b/selinux/setfiles.c
@@ -78,7 +78,7 @@
 //usage:     "\n		if it has changed"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #if ENABLE_FEATURE_SETFILES_CHECK_OPTION
 #include <sepol/sepol.h>
 #endif
diff --git a/shell/Config.src b/shell/Config.src
index 5efbf9995..ea8539e0e 100644
--- a/shell/Config.src
+++ b/shell/Config.src
@@ -147,7 +147,7 @@ config FEATURE_SH_NOFORK
 	this is not possible in pipes).
 
 	This will be done only for some applets (those which are marked
-	NOFORK in include/applets.h).
+	NOFORK in include/generated/applets.h).
 
 	This may significantly speed up some shell scripts.
 
diff --git a/shell/ash.c b/shell/ash.c
index 6a16833b1..740863ca9 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -185,7 +185,7 @@
 #include <sys/utsname.h> /* for setting $HOSTNAME */
 #include "busybox.h" /* for applet_names */
 #if ENABLE_FEATURE_SH_EMBEDDED_SCRIPTS
-# include "embedded_scripts.h"
+# include "generated/embedded_scripts.h"
 #else
 # define NUM_SCRIPTS 0
 #endif
@@ -265,7 +265,7 @@ typedef long arith_t;
 # define CLEAR_RANDOM_T(rnd) ((void)0)
 #endif
 
-#include "NUM_APPLETS.h"
+#include "generated/NUM_APPLETS.h"
 #if NUM_APPLETS == 1
 /* STANDALONE does not make sense, and won't compile */
 # undef CONFIG_FEATURE_SH_STANDALONE
diff --git a/shell/hush.c b/shell/hush.c
index 144ad3edd..7d2f94a67 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -374,7 +374,7 @@
 #endif
 
 #if ENABLE_FEATURE_SH_EMBEDDED_SCRIPTS && !(ENABLE_ASH || ENABLE_SH_IS_ASH || \
                ENABLE_BASH_IS_ASH)
-# include "embedded_scripts.h"
+# include "generated/embedded_scripts.h"
 #else
 # define NUM_SCRIPTS 0
 #endif
@@ -420,7 +420,7 @@
 # define USE_FOR_MMU(...)
 #endif
 
-#include "NUM_APPLETS.h"
+#include "generated/NUM_APPLETS.h"
 #if NUM_APPLETS == 1
 /* STANDALONE does not make sense, and won't compile */
 # undef CONFIG_FEATURE_SH_STANDALONE
diff --git a/size_single_applets.sh b/size_single_applets.sh
index 4b70e761f..0f2fd79c1 100755
--- a/size_single_applets.sh
+++ b/size_single_applets.sh
@@ -8,9 +8,9 @@
 # CONFIG_EXTRA_LDFLAGS="-m32"
 
 # The list of all applet config symbols
-test -f include/applets.h || { echo "No include/applets.h file"; exit 1; }
+test -f include/generated/applets.h || { echo "No include/generated/applets.h file"; \
exit 1; }  apps="`
-grep ^IF_ include/applets.h \
+grep ^IF_ include/generated/applets.h \
 | grep -v ^IF_FEATURE_ \
 | sed 's/IF_\([A-Z0-9._-]*\)(.*/\1/' \
 | sort | uniq
@@ -42,7 +42,7 @@ for app; do
 	echo "# $app adds $((text-mintext))"
 done
 
-grep ^IF_ include/applets.h \
+grep ^IF_ include/generated/applets.h \
 | grep -v ^IF_FEATURE_ \
 | sed 's/, .*//' \
 | sed 's/\t//g' \
diff --git a/sysklogd/klogd.c b/sysklogd/klogd.c
index 82596bc0b..66d49d21b 100644
--- a/sysklogd/klogd.c
+++ b/sysklogd/klogd.c
@@ -57,7 +57,7 @@
 //usage:     "\n	-n	Run in foreground"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #include <syslog.h>
 
 
diff --git a/sysklogd/logread.c b/sysklogd/logread.c
index d5f8ca0a2..ffb2ec289 100644
--- a/sysklogd/logread.c
+++ b/sysklogd/logread.c
@@ -43,7 +43,7 @@
 //usage:     "\n	-F	Same as -f, but dump buffer first"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #include <sys/ipc.h>
 #include <sys/sem.h>
 #include <sys/shm.h>
diff --git a/sysklogd/syslogd_and_logger.c b/sysklogd/syslogd_and_logger.c
index 94d8273b6..77fa4ad7e 100644
--- a/sysklogd/syslogd_and_logger.c
+++ b/sysklogd/syslogd_and_logger.c
@@ -7,7 +7,7 @@
  * Licensed under GPLv2, see file LICENSE in this source tree.
  */
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #define SYSLOG_NAMES
 #define SYSLOG_NAMES_CONST
 #include <syslog.h>
diff --git a/testsuite/all_sourcecode.tests b/testsuite/all_sourcecode.tests
index 7dcbbe8f5..d7c1da1d1 100755
--- a/testsuite/all_sourcecode.tests
+++ b/testsuite/all_sourcecode.tests
@@ -12,7 +12,7 @@
 # if we don't have the sourcecode available, let's just bail
 #
 [ -s "$srcdir/../Makefile" ] || exit 0
-[ -s "$srcdir/../include/applets.h" ] || exit 0
+[ -s "$srcdir/../include/generated/applets.h" ] || exit 0
 
 
 #
@@ -23,7 +23,7 @@
 #       " as is this line"
 #       " but this one is broken as the \ is missing from above"
 #
-${CROSS_COMPILE}cpp -dD -P $srcdir/../include/usage.h \
+${CROSS_COMPILE}cpp -dD -P $srcdir/../include/generated/usage.h \
 	| sed -e '/^#define/d' -e '/^$/d' > src.usage.escaped
 testing "Usage strings escaped" "cat src.usage.escaped" "" "" ""
 rm -f src.usage.escaped
@@ -34,7 +34,7 @@ rm -f src.usage.escaped
 # applets won't be called properly.
 #
 sed -n -e 's:^//::' -e '/^IF_[A-Z]*(APPLET/{s:,.*::;s:.*(::;s:"::g;p}' \
-	$srcdir/../include/applets.h > applet.order.current
+	$srcdir/../include/generated/applets.h > applet.order.current
 LC_ALL=C sort applet.order.current > applet.order.correct
 testing "Applet order" "diff -u applet.order.current applet.order.correct" "" "" ""
 rm -f applet.order.current applet.order.correct
diff --git a/util-linux/mdev.c b/util-linux/mdev.c
index dbbcbc655..40497b364 100644
--- a/util-linux/mdev.c
+++ b/util-linux/mdev.c
@@ -112,7 +112,7 @@
 //usage:       "If /dev/mdev.log file exists, debug log will be appended to it."
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #include "xregex.h"
 #include <linux/netlink.h>
 #include <syslog.h>
diff --git a/util-linux/mkswap.c b/util-linux/mkswap.c
index 8fe5d0293..0733f7f32 100644
--- a/util-linux/mkswap.c
+++ b/util-linux/mkswap.c
@@ -37,7 +37,7 @@
 //usage:     "\n	-L LBL	Label"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 #if ENABLE_SELINUX
 static void mkswap_selinux_setcontext(int fd, const char *path)
diff --git a/util-linux/more.c b/util-linux/more.c
index eea69da06..26adc04d8 100644
--- a/util-linux/more.c
+++ b/util-linux/more.c
@@ -36,7 +36,7 @@
 //usage:       "$ dmesg | more\n"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 struct globals {
 	int tty_fileno;
diff --git a/util-linux/mount.c b/util-linux/mount.c
index 831dab9e2..e64aae463 100644
--- a/util-linux/mount.c
+++ b/util-linux/mount.c
@@ -233,7 +233,7 @@
 #define BB_MS_INVERTED_VALUE (1u << 31)
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #if ENABLE_FEATURE_MOUNT_LABEL
 # include "volume_id.h"
 #else
diff --git a/util-linux/script.c b/util-linux/script.c
index 963435335..503478e0d 100644
--- a/util-linux/script.c
+++ b/util-linux/script.c
@@ -42,7 +42,7 @@
 //however, in my test, "script" from util-linux-2.28 seems to also add '\r' bytes.
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 int script_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int script_main(int argc UNUSED_PARAM, char **argv)
diff --git a/util-linux/swaponoff.c b/util-linux/swaponoff.c
index e2ff4b5cc..21f3b0627 100644
--- a/util-linux/swaponoff.c
+++ b/util-linux/swaponoff.c
@@ -73,7 +73,7 @@
 //usage:     "\n	-a	Stop swapping on all swap devices"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #include <mntent.h>
 #ifndef __BIONIC__
 # include <sys/swap.h>
diff --git a/util-linux/uevent.c b/util-linux/uevent.c
index db11746d0..20c96b774 100644
--- a/util-linux/uevent.c
+++ b/util-linux/uevent.c
@@ -23,7 +23,7 @@
 //usage:   "\n""	# uevent mdev & mdev -s"
 
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 #include <linux/netlink.h>
 
 #define env ((char **)bb_common_bufsiz1)
diff --git a/util-linux/umount.c b/util-linux/umount.c
index 23da32868..dba8b467a 100644
--- a/util-linux/umount.c
+++ b/util-linux/umount.c
@@ -67,7 +67,7 @@
 # define MNT_DETACH 0x00000002
 #endif
 #include "libbb.h"
-#include "common_bufsiz.h"
+#include "generated/common_bufsiz.h"
 
 #if defined(__dietlibc__)
 // TODO: This does not belong here.
-- 
2.31.1


["0002-build-system-move-autoconf.h-to-include-generated.patch" (application/x-patch)]

From 1adeea9f7588e7b317d0be46b9e07c3fa2d883cb Mon Sep 17 00:00:00 2001
From: Xabier Oneca <xoneca@gmail.com>
Date: Fri, 23 Apr 2021 21:56:08 +0200
Subject: [RFC PATCH 2/5] build system: move autoconf.h to include/generated

Same as upstream (Linux) build system.

Signed-off-by: Xabier Oneca <xoneca@gmail.com>
---
 Makefile                   | 21 +++++++++++----------
 Makefile.custom            |  6 +++---
 Makefile.flags             |  2 +-
 applets/applet_tables.c    |  2 +-
 applets/busybox.mkll       |  2 +-
 applets/busybox.mkscripts  |  2 +-
 applets/busybox.mksuid     |  2 +-
 applets/usage.c            |  2 +-
 applets/usage_pod.c        |  2 +-
 include/.gitignore         |  2 +-
 scripts/Makefile.IMA       | 10 +++++-----
 scripts/basic/fixdep.c     |  2 +-
 scripts/kconfig/Makefile   |  4 ++--
 scripts/kconfig/confdata.c |  2 +-
 scripts/kconfig/util.c     |  4 ++--
 scripts/trylink            |  2 +-
 16 files changed, 34 insertions(+), 33 deletions(-)

diff --git a/Makefile b/Makefile
index ea182325d..b0e091d84 100644
--- a/Makefile
+++ b/Makefile
@@ -362,6 +362,7 @@ scripts/basic/%: scripts_basic ;
 # This target generates Kbuild's and Config.in's from *.c files
 PHONY += gen_build_files
 gen_build_files: $(wildcard $(srctree)/*/*.c) $(wildcard $(srctree)/*/*/*.c) \
$(wildcard $(srctree)/embed/*) +	$(Q)mkdir -p include/generated
 	$(Q)$(srctree)/scripts/gen_build_files.sh $(srctree) $(objtree)
 
 # bbox: we have helpers in applets/
@@ -435,12 +436,12 @@ ifeq ($(config-targets),1)
 export KBUILD_DEFCONFIG
 
 config: scripts_basic outputmakefile gen_build_files FORCE
-	$(Q)mkdir -p include
+	$(Q)mkdir -p include/generated
 	$(Q)$(MAKE) $(build)=scripts/kconfig $@
 	$(Q)$(MAKE) -C $(srctree) KBUILD_SRC= .kernelrelease
 
 %config: scripts_basic outputmakefile gen_build_files FORCE
-	$(Q)mkdir -p include
+	$(Q)mkdir -p include/generated
 	$(Q)$(MAKE) $(build)=scripts/kconfig $@
 	$(Q)$(MAKE) -C $(srctree) KBUILD_SRC= .kernelrelease
 
@@ -457,7 +458,7 @@ PHONY += scripts
 scripts: gen_build_files scripts_basic include/config/MARKER
 	$(Q)$(MAKE) $(build)=$(@)
 
-scripts_basic: include/autoconf.h
+scripts_basic: include/generated/autoconf.h
 
 # Objects we will link into busybox / subdirs we need to visit
 core-y		:= \
@@ -514,18 +515,18 @@ ifeq ($(dot-config),1)
 # Now we can define CFLAGS etc according to .config
 include $(srctree)/Makefile.flags
 
-# If .config is newer than include/autoconf.h, someone tinkered
+# If .config is newer than include/generated/autoconf.h, someone tinkered
 # with it and forgot to run make oldconfig.
 # If kconfig.d is missing then we are probarly in a cleaned tree so
 # we execute the config step to be sure to catch updated Kconfig files
-include/autoconf.h: .kconfig.d .config $(wildcard $(srctree)/*/*.c) $(wildcard \
$(srctree)/*/*/*.c) | gen_build_files +include/generated/autoconf.h: .kconfig.d \
.config $(wildcard $(srctree)/*/*.c) $(wildcard $(srctree)/*/*/*.c) | gen_build_files \
$(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig  
 include/usage.h: gen_build_files
 
 else
 # Dummy target needed, because used as prerequisite
-include/autoconf.h: ;
+include/generated/autoconf.h: ;
 endif
 
 # The all: target is the default when no target is given on the
@@ -849,12 +850,12 @@ quiet_cmd_gen_bbconfigopts = GEN     include/bbconfigopts.h
       cmd_gen_bbconfigopts = $(srctree)/scripts/mkconfigs include/bbconfigopts.h \
include/bbconfigopts_bz2.h  quiet_cmd_gen_common_bufsiz = GEN     \
                include/common_bufsiz.h
       cmd_gen_common_bufsiz = $(srctree)/scripts/generate_BUFSIZ.sh \
                include/common_bufsiz.h
-quiet_cmd_split_autoconf   = SPLIT   include/autoconf.h -> include/config/*
-      cmd_split_autoconf   = scripts/basic/split-include include/autoconf.h \
include/config +quiet_cmd_split_autoconf   = SPLIT   include/generated/autoconf.h -> \
include/config/* +      cmd_split_autoconf   = scripts/basic/split-include \
include/generated/autoconf.h include/config  quiet_cmd_gen_embedded_scripts = GEN     \
                include/embedded_scripts.h
       cmd_gen_embedded_scripts = $(srctree)/scripts/embedded_scripts \
include/embedded_scripts.h $(srctree)/embed $(srctree)/applets_sh  #bbox# piggybacked \
                generation of few .h files
-include/config/MARKER: scripts/basic/split-include include/autoconf.h $(wildcard \
$(srctree)/embed/*) $(wildcard $(srctree)/applets_sh/*) \
$(srctree)/scripts/embedded_scripts +include/config/MARKER: \
scripts/basic/split-include include/generated/autoconf.h $(wildcard \
$(srctree)/embed/*) $(wildcard $(srctree)/applets_sh/*) \
$(srctree)/scripts/embedded_scripts  $(call cmd,split_autoconf)
 	$(call cmd,gen_bbconfigopts)
 	$(call cmd,gen_common_bufsiz)
@@ -975,7 +976,7 @@ MRPROPER_DIRS  += include/config include2
 MRPROPER_FILES += .config .config.old include/asm .version .old_version \
 		  include/NUM_APPLETS.h \
 		  include/common_bufsiz.h \
-		  include/autoconf.h \
+		  include/generated/autoconf.h \
 		  include/bbconfigopts.h \
 		  include/bbconfigopts_bz2.h \
 		  include/embedded_scripts.h \
diff --git a/Makefile.custom b/Makefile.custom
index 6f679c4e1..ba3afda03 100644
--- a/Makefile.custom
+++ b/Makefile.custom
@@ -2,12 +2,12 @@
 # Build system
 # ==========================================================================
 
-busybox.links: $(srctree)/applets/busybox.mkll $(objtree)/include/autoconf.h \
include/applets.h +busybox.links: $(srctree)/applets/busybox.mkll \
$(objtree)/include/generated/autoconf.h include/applets.h  $(Q)-$(SHELL) $^ > $@
 
-busybox.cfg.suid: $(srctree)/applets/busybox.mksuid $(objtree)/include/autoconf.h \
include/applets.h +busybox.cfg.suid: $(srctree)/applets/busybox.mksuid \
$(objtree)/include/generated/autoconf.h include/applets.h  $(Q)-SUID="yes" $(SHELL) \
                $^ > $@
-busybox.cfg.nosuid: $(srctree)/applets/busybox.mksuid $(objtree)/include/autoconf.h \
include/applets.h +busybox.cfg.nosuid: $(srctree)/applets/busybox.mksuid \
$(objtree)/include/generated/autoconf.h include/applets.h  $(Q)-SUID="DROP" $(SHELL) \
$^ > $@  
 .PHONY: install
diff --git a/Makefile.flags b/Makefile.flags
index 667481983..207e9b0fc 100644
--- a/Makefile.flags
+++ b/Makefile.flags
@@ -12,7 +12,7 @@ CPPFLAGS += $(call cc-option,-std=gnu99,)
 CPPFLAGS += \
 	-Iinclude -Ilibbb \
 	$(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include -I$(srctree)/libbb) \
-	-include include/autoconf.h \
+	-include include/generated/autoconf.h \
 	-D_GNU_SOURCE -DNDEBUG \
 	$(if $(CONFIG_LFS),-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE \
                -D_FILE_OFFSET_BITS=64) \
 	-DBB_VER=$(squote)$(quote)$(BB_VER)$(quote)$(squote)
diff --git a/applets/applet_tables.c b/applets/applet_tables.c
index 66ef7e4ac..da5461340 100644
--- a/applets/applet_tables.c
+++ b/applets/applet_tables.c
@@ -24,7 +24,7 @@
 #define PATH_MAX 1024
 #endif
 
-#include "../include/autoconf.h"
+#include "../include/generated/autoconf.h"
 #include "../include/applet_metadata.h"
 
 struct bb_applet {
diff --git a/applets/busybox.mkll b/applets/busybox.mkll
index 68dbf2162..acc8d1801 100755
--- a/applets/busybox.mkll
+++ b/applets/busybox.mkll
@@ -10,7 +10,7 @@
 export LC_ALL=POSIX
 export LC_CTYPE=POSIX
 
-CONFIG_H=${1:-include/autoconf.h}
+CONFIG_H=${1:-include/generated/autoconf.h}
 APPLETS_H=${2:-include/applets.h}
 $HOSTCC -E -DMAKE_LINKS -include $CONFIG_H $APPLETS_H |
   awk '/^[ \t]*LINK/{
diff --git a/applets/busybox.mkscripts b/applets/busybox.mkscripts
index 935685cba..cf4148a58 100755
--- a/applets/busybox.mkscripts
+++ b/applets/busybox.mkscripts
@@ -8,7 +8,7 @@
 export LC_ALL=POSIX
 export LC_CTYPE=POSIX
 
-CONFIG_H=${1:-include/autoconf.h}
+CONFIG_H=${1:-include/generated/autoconf.h}
 APPLETS_H=${2:-include/applets.h}
 $HOSTCC -E -DMAKE_SCRIPTS -include $CONFIG_H $APPLETS_H |
   awk '/^[ \t]*SCRIPT/{
diff --git a/applets/busybox.mksuid b/applets/busybox.mksuid
index 6492c079a..337dd7abd 100755
--- a/applets/busybox.mksuid
+++ b/applets/busybox.mksuid
@@ -16,7 +16,7 @@
 export LC_ALL=POSIX
 export LC_CTYPE=POSIX
 
-CONFIG_H=${1:-include/autoconf.h}
+CONFIG_H=${1:-include/generated/autoconf.h}
 APPLETS_H=${2:-include/applets.h}
 DOT_CONFIG=${3:-.config}
 
diff --git a/applets/usage.c b/applets/usage.c
index 94520ff66..e39fd146e 100644
--- a/applets/usage.c
+++ b/applets/usage.c
@@ -8,7 +8,7 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include "autoconf.h"
+#include "generated/autoconf.h"
 
 /* Since we can't use platform.h, have to do this again by hand: */
 #if ENABLE_NOMMU
diff --git a/applets/usage_pod.c b/applets/usage_pod.c
index 9e6d3f0ee..4d5fe68ca 100644
--- a/applets/usage_pod.c
+++ b/applets/usage_pod.c
@@ -10,7 +10,7 @@
 #include <string.h>
 #include <stdio.h>
 
-#include "autoconf.h"
+#include "generated/autoconf.h"
 
 #define SKIP_applet_main
 #define ALIGN1 /* nothing, just to placate applet_tables.h */
diff --git a/include/.gitignore b/include/.gitignore
index 13a96e018..7e36fe985 100644
--- a/include/.gitignore
+++ b/include/.gitignore
@@ -2,7 +2,7 @@
 
 /applets.h
 /applet_tables.h
-/autoconf.h
+/generated/autoconf.h
 /bbconfigopts_bz2.h
 /bbconfigopts.h
 /embedded_scripts.h
diff --git a/scripts/Makefile.IMA b/scripts/Makefile.IMA
index 1e3005864..b9c60f57f 100644
--- a/scripts/Makefile.IMA
+++ b/scripts/Makefile.IMA
@@ -176,7 +176,7 @@ lib-all-y += $(patsubst %,libbb/%,$(sort $(lib-y)))
 lib-y:=
 
 comma:=,
-busybox_unstripped.o: $(usage_stuff) include/applet_tables.h include/NUM_APPLETS.h \
include/autoconf.h +busybox_unstripped.o: $(usage_stuff) include/applet_tables.h \
include/NUM_APPLETS.h include/generated/autoconf.h  $(CC) $(CPPFLAGS) $(CFLAGS) \
$(EXTRA_CFLAGS) \  $(patsubst %,-Wl$(comma)%,$(LDFLAGS) $(EXTRA_LDFLAGS)) \
 		-DGCC_COMBINE=1 \
@@ -197,14 +197,14 @@ busybox: busybox_unstripped.o
 	cp -f $(@)_unstripped $@
 	-$(STRIP) -s -R .note -R .comment -R .version $@
 
-# If .config is newer than include/autoconf.h, someone tinkered
+# If .config is newer than include/generated/autoconf.h, someone tinkered
 # with it and forgot to run make oldconfig.
-include/autoconf.h: .config
+include/generated/autoconf.h: .config
 	$(MAKE) -f $(srctree)/Makefile silentoldconfig
 
 # Override rules for host compile
-applets/usage: include/autoconf.h
+applets/usage: include/generated/autoconf.h
 	$(HOSTCC) -Wall -O2 -I$(srctree)/include -o applets/usage applets/usage.c
 
-applets/applet_tables: include/autoconf.h
+applets/applet_tables: include/generated/autoconf.h
 	$(HOSTCC) -Wall -O2 -I$(srctree)/include -o applets/applet_tables \
                applets/applet_tables.c
diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c
index 426b4888b..054c7512d 100644
--- a/scripts/basic/fixdep.c
+++ b/scripts/basic/fixdep.c
@@ -339,7 +339,7 @@ void parse_dep_file(void *map, size_t len)
 			p++;
 		}
 		memcpy(s, m, p-m); s[p-m] = 0;
-		if (strrcmp(s, "include/autoconf.h") &&
+		if (strrcmp(s, "include/generated/autoconf.h") &&
 		    strrcmp(s, "arch/um/include/uml-config.h") &&
 		    strrcmp(s, ".ver")) {
 			printf("  %s \\\n", s);
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 38bae809a..080714227 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -22,8 +22,8 @@ config: $(obj)/conf
 # make allnoconfig; sed -i -e '/CONFIG_TRUE/s/.*/CONFIG_TRUE=y/' .config; make
 # sometimes produce busybox with "true" applet still disabled.
 # This is caused by .config updated by sed having mtime which is still
-# equal to (not bigger than) include/autoconf.h's mtime,
-# and thus 2nd make does not regenerate include/autoconf.h.
+# equal to (not bigger than) include/generated/autoconf.h's mtime,
+# and thus 2nd make does not regenerate include/generated/autoconf.h.
 # Waiting for 1 second after non-interactive "make XXXXconfig"
 # prevents this from happening.
 #
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index 9976011a9..1abfebcb5 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -573,7 +573,7 @@ int conf_write(const char *name)
 	fclose(out);
 	if (out_h) {
 		fclose(out_h);
-		rename(".tmpconfig.h", "include/autoconf.h");
+		rename(".tmpconfig.h", "include/generated/autoconf.h");
 	}
 	if (!name || basename != conf_def_filename) {
 		if (!name)
diff --git a/scripts/kconfig/util.c b/scripts/kconfig/util.c
index 13369e6a1..57ebeb57a 100644
--- a/scripts/kconfig/util.c
+++ b/scripts/kconfig/util.c
@@ -46,9 +46,9 @@ int file_write_dep(const char *name)
 	}
 	fprintf(out,
 		"\n"
-		".config include/autoconf.h: $(deps_config)\n"
+		".config include/generated/autoconf.h: $(deps_config)\n"
 		"\n"
-		"include/autoconf.h: .config\n" /* bbox */
+		"include/generated/autoconf.h: .config\n" /* bbox */
 		"\n"
 		"$(deps_config):\n");
 	fclose(out);
diff --git a/scripts/trylink b/scripts/trylink
index 2255deee7..c637fca6f 100755
--- a/scripts/trylink
+++ b/scripts/trylink
@@ -296,7 +296,7 @@ fi
 
 if test "$CONFIG_FEATURE_INDIVIDUAL" = y; then
     echo "Linking individual applets against libbusybox (see $sharedlib_dir/*)"
-    gcc -DNAME_MAIN -E -include include/autoconf.h include/applets.h \
+    gcc -DNAME_MAIN -E -include include/generated/autoconf.h include/applets.h \
     | grep -v "^#" \
     | grep -v "^ *$" \
     > applet_lst.tmp
-- 
2.31.1


["0005-build-system-fixes-to-make-it-work-again.patch" (application/x-patch)]

From 464a4448681e2e176ad7f190d186b34d4ed6b7da Mon Sep 17 00:00:00 2001
From: Xabier Oneca <xoneca@gmail.com>
Date: Fri, 30 Apr 2021 00:50:08 +0200
Subject: [RFC PATCH 5/5] build system: fixes to make it work again

- Do not make parser regeneration mandatory. Use shipped files.
- Add ENABLE_FEATURE_xxx, IF_{,NOT_}FEATURE_xxx() defines for all symbols to
  autoconf.h.
- Remove autoconf splitting. It is now done by Kconfig.
- Bring back again customizations for fixdep.
- Move some includes from CPPFLAGS (in Makefile.flags) to KBUILD_CPPFLAGS (in
  main Makefile).
- Rename silentoldconfig to syncconfig in main Makefile, as the former one is no
  longer available.
- Bring back mtime granularity fix from Busybox. (Is this really needed?)
- Rename built-in.o to built-in.a.
- Use standard 'ar' instead of 'ar_and_symver' cmd to build built-in.a, as we
  need symbol table in archives.
- User prepare target instead of include/config/MARKER to piggyback generation
  of some headers.
- Generate applet_tables.h and NUM_APPLETS.h both in one go.
- Moved AUTOCONF_TIMESTAMP and GCC_VERSION to Config.in.
- Find Kbuild/Makefile files in objtree too. Most of them are generated.

Signed-off-by: Xabier Oneca <xoneca@gmail.com>
---
 Config.in                            |   14 +
 Makefile                             |  112 +-
 Makefile.flags                       |   10 -
 applets/Kbuild.src                   |   21 +-
 applets/applet_tables.c              |    6 +-
 libbb/messages.c                     |    2 +-
 scripts/Makefile.build               |    7 +-
 scripts/Makefile.host                |    4 +
 scripts/basic/fixdep.c               |   55 +-
 scripts/find_stray_common_vars       |    2 +-
 scripts/kconfig/.gitignore           |    3 +
 scripts/kconfig/Makefile             |   26 +-
 scripts/kconfig/confdata.c           |   20 +-
 scripts/kconfig/lexer.lex.c_shipped  | 4328 ++++++++++++++++++++++++++
 scripts/kconfig/parser.tab.c_shipped | 2200 +++++++++++++
 scripts/kconfig/parser.tab.h_shipped |  135 +
 scripts/kconfig/symbol.c             |    3 +-
 scripts/objsizes                     |    2 +-
 18 files changed, 6841 insertions(+), 109 deletions(-)
 create mode 100644 scripts/kconfig/lexer.lex.c_shipped
 create mode 100644 scripts/kconfig/parser.tab.c_shipped
 create mode 100644 scripts/kconfig/parser.tab.h_shipped

diff --git a/Config.in b/Config.in
index d2ac89d5c..7c8e17e35 100644
--- a/Config.in
+++ b/Config.in
@@ -9,6 +9,20 @@ config HAVE_DOT_CONFIG
 	bool
 	default y
 
+config AUTOCONF_TIMESTAMP
+	string
+	default "$(shell,TZ=GMT date ${SOURCE_DATE_EPOCH:+"--date=@$SOURCE_DATE_EPOCH"} \
'+%Y-%m-%d %H:%M:%S %Z')" +
+source "scripts/Kconfig.include"
+
+config CC_IS_GCC
+	def_bool $(success,test "$(cc-name)" = GCC)
+
+config GCC_VERSION
+	int
+	default $(cc-version) if CC_IS_GCC
+	default 0
+
 menu "Settings"
 
 config DESKTOP
diff --git a/Makefile b/Makefile
index 8ac800a83..e57e17a94 100644
--- a/Makefile
+++ b/Makefile
@@ -19,7 +19,7 @@ MAKEFLAGS += --no-print-directory
 # Most importantly: sub-Makefiles should only ever modify files in
 # their own directory. If in some directory we have a dependency on
 # a file in another dir (which doesn't happen often, but it's often
-# unavoidable when linking the built-in.o targets which finally
+# unavoidable when linking the built-in.a targets which finally
 # turn into busybox), we will call a sub make in that other dir, and
 # after that we are sure that everything which is in that other dir
 # is now up to date.
@@ -224,7 +224,9 @@ ifeq ($(MAKECMDGOALS),)
   KBUILD_MODULES := 1
 endif
 
-export KBUILD_MODULES KBUILD_BUILTIN
+need-builtin = $(KBUILD_MODULES)
+
+export KBUILD_MODULES KBUILD_BUILTIN need-builtin
 export KBUILD_CHECKSRC KBUILD_SRC KBUILD_EXTMOD
 
 # Beautify output
@@ -273,13 +275,13 @@ MAKEFLAGS += --include-dir=$(srctree)
 
 HOSTCC  	= gcc
 HOSTCXX  	= g++
-HOSTCFLAGS	:=
-HOSTCXXFLAGS	:=
+KBUILD_HOSTCFLAGS	:=
+KBUILD_HOSTCXXFLAGS	:=
 # We need some generic definitions
 include $(srctree)/scripts/Kbuild.include
 
-HOSTCFLAGS	+= $(call hostcc-option,-Wall -Wstrict-prototypes -O2 \
                -fomit-frame-pointer,)
-HOSTCXXFLAGS	+= -O2
+KBUILD_HOSTCFLAGS	+= -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
+KBUILD_HOSTCXXFLAGS	+= -O2
 
 # For maximum performance (+ possibly random breakage, uncomment
 # the following)
@@ -290,7 +292,7 @@ MAKEFLAGS += -rR
 
 AS		= $(CROSS_COMPILE)as
 CC		= $(CROSS_COMPILE)gcc
-LD		= $(CC) -nostdlib
+LD		= $(CROSS_COMPILE)ld
 CPP		= $(CC) -E
 AR		= $(CROSS_COMPILE)ar
 NM		= $(CROSS_COMPILE)nm
@@ -313,9 +315,6 @@ LDFLAGS_MODULE  = -r
 CFLAGS_KERNEL	=
 AFLAGS_KERNEL	=
 
-
-# Use LINUXINCLUDE when you must reference the include/ directory.
-# Needed to be compatible with the O= option
 CFLAGS		:= $(CFLAGS)
 # Added only to final link stage of busybox binary
 CFLAGS_busybox	:= $(CFLAGS_busybox)
@@ -329,9 +328,9 @@ KERNELRELEASE = $(shell cat .kernelrelease 2> /dev/null)
 KERNELVERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
 export	VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION \
-	ARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC \
+	ARCH CONFIG_SHELL HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE AS LD CC \
 	CPP AR NM STRIP OBJCOPY OBJDUMP MAKE AWK GENKSYMS PERL UTS_MACHINE \
-	HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS
+	HOSTCXX KBUILD_HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS
 
 export CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS
 export CFLAGS CFLAGS_KERNEL CFLAGS_MODULE
@@ -356,9 +355,6 @@ PHONY += scripts_basic
 scripts_basic:
 	$(Q)$(MAKE) $(build)=scripts/basic
 
-# To avoid any implicit rule to kick in, define an empty command.
-scripts/basic/%: scripts_basic ;
-
 # This target generates Kbuild's and Config.in's from *.c files
 PHONY += gen_build_files
 gen_build_files: $(wildcard $(srctree)/*/*.c) $(wildcard $(srctree)/*/*/*.c) \
$(wildcard $(srctree)/embed/*) @@ -369,7 +365,7 @@ gen_build_files: $(wildcard \
$(srctree)/*/*.c) $(wildcard $(srctree)/*/*/*.c) $(w  # we depend on scripts_basic, \
since scripts/basic/fixdep  # must be built before any other host prog
 PHONY += applets_dir
-applets_dir: scripts_basic gen_build_files include/config/MARKER
+applets_dir: scripts_basic gen_build_files
 	$(Q)$(MAKE) $(build)=applets
 
 applets/%: applets_dir ;
@@ -433,8 +429,11 @@ ifeq ($(config-targets),1)
 # KBUILD_DEFCONFIG may point out an alternative default configuration
 # used for 'make defconfig'
 -include $(srctree)/arch/$(ARCH)/Makefile
+KBUILD_DEFCONFIG ?= olddefconfig
 export KBUILD_DEFCONFIG
 
+export KBUILD_KCONFIG = $(srctree)/Config.in
+
 config: scripts_basic outputmakefile gen_build_files FORCE
 	$(Q)mkdir -p include/generated
 	$(Q)$(MAKE) $(build)=scripts/kconfig $@
@@ -450,12 +449,21 @@ else
 # Build targets only - this includes busybox, arch specific targets, clean
 # targets and others. In general all targets except *config targets.
 
+.config:
+	@echo >&2 '***'
+	@echo >&2 '*** Configuration file "$@" not found!'
+	@echo >&2 '***'
+	@echo >&2 '*** Please run some configurator (e.g. "make oldconfig" or'
+	@echo >&2 '*** "make menuconfig" or "make xconfig").'
+	@echo >&2 '***'
+	@/bin/false
+
 ifeq ($(KBUILD_EXTMOD),)
 # Additional helpers built in scripts/
 # Carefully list dependencies so we do not try to build scripts twice
 # in parallel
 PHONY += scripts
-scripts: gen_build_files scripts_basic include/config/MARKER
+scripts: gen_build_files scripts_basic
 	$(Q)$(MAKE) $(build)=$(@)
 
 scripts_basic: include/generated/autoconf.h
@@ -498,29 +506,30 @@ endif # KBUILD_EXTMOD
 
 ifeq ($(dot-config),1)
 # In this section, we need .config
-
-# Read in dependencies to all Kconfig* files, make sure to run
-# oldconfig if changes are detected.
--include .kconfig.d
-
 -include .config
 
-# If .config needs to be updated, it will be done via the dependency
-# that autoconf has on .config.
-# To avoid any implicit rule to kick in, define an empty command
-.config .kconfig.d: ;
-
 -include $(srctree)/arch/$(ARCH)/Makefile
 
 # Now we can define CFLAGS etc according to .config
 include $(srctree)/Makefile.flags
 
+BB_VER := $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
+KBUILD_CPPFLAGS := \
+	-Iinclude -Ilibbb \
+	$(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include -I$(srctree)/libbb) \
+	-include include/generated/autoconf.h \
+	-D_GNU_SOURCE -DNDEBUG \
+	$(if $(CONFIG_LFS),-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE \
-D_FILE_OFFSET_BITS=64) \ +	-DBB_VER='"$(BB_VER)"'
+
+KBUILD_CPPFLAGS += $(CPPFLAGS)
+KBUILD_CFLAGS += $(CFLAGS)
+export BB_VER KBUILD_CPPFLAGS KBUILD_CFLAGS
+
 # If .config is newer than include/generated/autoconf.h, someone tinkered
 # with it and forgot to run make oldconfig.
-# If kconfig.d is missing then we are probarly in a cleaned tree so
-# we execute the config step to be sure to catch updated Kconfig files
-include/generated/autoconf.h: .kconfig.d .config $(wildcard $(srctree)/*/*.c) \
                $(wildcard $(srctree)/*/*/*.c) | gen_build_files
-	$(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig
+include/generated/autoconf.h: .config $(wildcard $(srctree)/*/*.c) $(wildcard \
$(srctree)/*/*/*.c) | gen_build_files +	$(Q)$(MAKE) -f $(srctree)/Makefile syncconfig
 
 include/generated/usage.h: gen_build_files
 
@@ -568,15 +577,15 @@ busybox-alldirs	:= $(sort $(busybox-dirs) $(patsubst \
%/,%,$(filter %/, \  $(core-n) $(core-) $(libs-n) $(libs-) \
 		)))
 
-core-y		:= $(patsubst %/, %/built-in.o, $(core-y))
+core-y		:= $(patsubst %/, %/built-in.a, $(core-y))
 libs-y1		:= $(patsubst %/, %/lib.a, $(libs-y))
-libs-y2		:= $(patsubst %/, %/built-in.o, $(libs-y))
+libs-y2		:= $(patsubst %/, %/built-in.a, $(filter-out %.a, $(libs-y)))
 libs-y		:= $(libs-y1) $(libs-y2)
 
 # Build busybox
 # ---------------------------------------------------------------------------
 # busybox is build from the objects selected by $(busybox-init) and
-# $(busybox-main). Most are built-in.o files from top-level directories
+# $(busybox-main). Most are built-in.a files from top-level directories
 # in the kernel tree, others are specified in arch/$(ARCH)Makefile.
 # Ordering when linking is important, and $(busybox-init) must be first.
 #
@@ -587,7 +596,7 @@ libs-y		:= $(libs-y1) $(libs-y2)
 #   |   +--< init/version.o + more
 #   |
 #   +--< $(busybox-main)
-#   |    +--< driver/built-in.o mm/built-in.o + more
+#   |    +--< driver/built-in.a mm/built-in.a + more
 #   |
 #   +-< kallsyms.o (see description in CONFIG_KALLSYMS section)
 #
@@ -817,7 +826,7 @@ endif
 # prepare2 creates a makefile if using a separate output directory
 prepare2: prepare3 outputmakefile
 
-prepare1: prepare2 include/config/MARKER
+prepare1: prepare2
 ifneq ($(KBUILD_MODULES),)
 	$(Q)mkdir -p $(MODVERDIR)
 	$(Q)rm -f $(MODVERDIR)/*
@@ -845,25 +854,33 @@ export CPPFLAGS_busybox.lds += -P -C -U$(ARCH)
 #bbox# 	$(Q)if [ ! -d include ]; then mkdir -p include; fi;
 #bbox# 	@ln -fsn asm-$(ARCH) $@
 
-# 	Split autoconf.h into include/linux/config/*
+# Generate some files
+# ---------------------------------------------------------------------------
+
+#bbox# piggybacked generation of few .h files
+
 quiet_cmd_gen_bbconfigopts = GEN     include/generated/bbconfigopts.h
       cmd_gen_bbconfigopts = $(srctree)/scripts/mkconfigs \
include/generated/bbconfigopts.h include/generated/bbconfigopts_bz2.h +
+include/generated/bbconfigopts.h include/generated/bbconfigopts_bz2.h: \
$(srctree)/scripts/mkconfigs +	$(call cmd,gen_bbconfigopts)
+
 quiet_cmd_gen_common_bufsiz = GEN     include/generated/common_bufsiz.h
       cmd_gen_common_bufsiz = $(srctree)/scripts/generate_BUFSIZ.sh \
                include/generated/common_bufsiz.h
-quiet_cmd_split_autoconf   = SPLIT   include/generated/autoconf.h -> \
                include/config/*
-      cmd_split_autoconf   = scripts/basic/split-include \
include/generated/autoconf.h include/config +
+include/generated/common_bufsiz.h: $(srctree)/scripts/generate_BUFSIZ.sh
+	$(call cmd,gen_common_bufsiz)
+
 quiet_cmd_gen_embedded_scripts = GEN     include/generated/embedded_scripts.h
       cmd_gen_embedded_scripts = $(srctree)/scripts/embedded_scripts \
                include/generated/embedded_scripts.h $(srctree)/embed \
                $(srctree)/applets_sh
-#bbox# piggybacked generation of few .h files
-include/config/MARKER: scripts/basic/split-include include/generated/autoconf.h \
$(wildcard $(srctree)/embed/*) $(wildcard $(srctree)/applets_sh/*) \
                $(srctree)/scripts/embedded_scripts
-	$(call cmd,split_autoconf)
-	$(call cmd,gen_bbconfigopts)
-	$(call cmd,gen_common_bufsiz)
+
+include/generated/embedded_scripts.h: $(srctree)/scripts/embedded_scripts $(wildcard \
$(srctree)/embed/*) $(wildcard $(srctree)/applets_sh/*)  $(call \
                cmd,gen_embedded_scripts)
-	@touch $@
 
-# Generate some files
-# ---------------------------------------------------------------------------
+prepare: include/generated/autoconf.h \
+		include/generated/bbconfigopts.h include/generated/bbconfigopts_bz2.h \
+		include/generated/common_bufsiz.h \
+		include/generated/embedded_scripts.h
 
 # KERNELRELEASE can change from a few different places, meaning version.h
 # needs to be updated, so this check is forced on all builds
@@ -974,7 +991,6 @@ CLEAN_FILES +=	busybox busybox_unstripped* busybox.links \
 # Directories & files removed with 'make mrproper'
 MRPROPER_DIRS  += include/config include/generated include2
 MRPROPER_FILES += .config .config.old include/asm .version .old_version \
-		  applets/usage \
 		  .kernelrelease Module.symvers tags TAGS cscope* \
 		  busybox_old
 
diff --git a/Makefile.flags b/Makefile.flags
index 207e9b0fc..b88f9407f 100644
--- a/Makefile.flags
+++ b/Makefile.flags
@@ -2,21 +2,11 @@
 # Build system
 # ==========================================================================
 
-BB_VER = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
-export BB_VER
 SKIP_STRIP ?= n
 
 # -std=gnu99 needed for [U]LLONG_MAX on some systems
 CPPFLAGS += $(call cc-option,-std=gnu99,)
 
-CPPFLAGS += \
-	-Iinclude -Ilibbb \
-	$(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include -I$(srctree)/libbb) \
-	-include include/generated/autoconf.h \
-	-D_GNU_SOURCE -DNDEBUG \
-	$(if $(CONFIG_LFS),-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE \
                -D_FILE_OFFSET_BITS=64) \
-	-DBB_VER=$(squote)$(quote)$(BB_VER)$(quote)$(squote)
-
 CFLAGS += $(call cc-option,-Wall,)
 CFLAGS += $(call cc-option,-Wshadow,)
 CFLAGS += $(call cc-option,-Wwrite-strings,)
diff --git a/applets/Kbuild.src b/applets/Kbuild.src
index 1a3baa798..14ebfb740 100644
--- a/applets/Kbuild.src
+++ b/applets/Kbuild.src
@@ -7,10 +7,7 @@
 obj-y :=
 obj-y += applets.o
 
-hostprogs-y:=
-hostprogs-y += usage usage_pod applet_tables
-
-always:= $(hostprogs-y)
+hostprogs-always-y += usage usage_pod applet_tables
 
 # Generated files need additional love
 
@@ -22,6 +19,7 @@ else
 srctree_slash = $(srctree)/
 endif
 
+HOSTCFLAGS_applet_tables.o = -I$(srctree_slash)include -Iinclude
 HOSTCFLAGS_usage.o = -I$(srctree_slash)include -Iinclude
 HOSTCFLAGS_usage_pod.o = -I$(srctree_slash)include -Iinclude
 
@@ -40,18 +38,5 @@ include/generated/usage_compressed.h: applets/usage \
$(srctree_slash)applets/usag  quiet_cmd_gen_applet_tables = GEN     \
                include/generated/applet_tables.h include/generated/NUM_APPLETS.h
       cmd_gen_applet_tables = applets/applet_tables \
include/generated/applet_tables.h include/generated/NUM_APPLETS.h  
-include/generated/NUM_APPLETS.h: applets/applet_tables
-	$(call cmd,gen_applet_tables)
-
-# In fact, include/generated/applet_tables.h depends only on
-# applets/applet_tables, and is generated by it. But specifying only it can run
-# applets/applet_tables twice, possibly in parallel.
-# We say that it also needs NUM_APPLETS.h
-#
-# Unfortunately, we need to list the same command,
-# and it can be executed twice (sequentially).
-# The alternative is to not list any command,
-# and then if include/generated/applet_tables.h is deleted, it won't be rebuilt.
-#
-include/generated/applet_tables.h: include/generated/NUM_APPLETS.h \
applets/applet_tables +include/generated/applet_tables.h \
include/generated/NUM_APPLETS.h: applets/applet_tables  $(call cmd,gen_applet_tables)
diff --git a/applets/applet_tables.c b/applets/applet_tables.c
index 9e0e720a8..1da7bec49 100644
--- a/applets/applet_tables.c
+++ b/applets/applet_tables.c
@@ -24,8 +24,8 @@
 #define PATH_MAX 1024
 #endif
 
-#include "../include/generated/autoconf.h"
-#include "../include/applet_metadata.h"
+#include "generated/autoconf.h"
+#include "applet_metadata.h"
 
 struct bb_applet {
 	const char *name;
@@ -42,7 +42,7 @@ struct bb_applet {
 };
 
 /* Define struct bb_applet applets[] */
-#include "../include/generated/applets.h"
+#include "generated/applets.h"
 
 enum { NUM_APPLETS = ARRAY_SIZE(applets) };
 
diff --git a/libbb/messages.c b/libbb/messages.c
index 6914d5701..3f22f0c8e 100644
--- a/libbb/messages.c
+++ b/libbb/messages.c
@@ -8,7 +8,7 @@
 
 /* allow version to be extended, via CFLAGS */
 #ifndef BB_EXTRA_VERSION
-#define BB_EXTRA_VERSION " ("AUTOCONF_TIMESTAMP")"
+# define BB_EXTRA_VERSION " (" CONFIG_AUTOCONF_TIMESTAMP ")"
 #endif
 
 const char bb_banner[] ALIGN1 = "BusyBox v" BB_VER BB_EXTRA_VERSION;
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 1b6094a13..5d6a33315 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -38,7 +38,9 @@ subdir-ccflags-y :=
 include scripts/Kbuild.include
 
 # The filename Kbuild has precedence over Makefile
-kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
+# bbox: And objtree over srctree
+#kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
+kbuild-dir := $(if $(filter /%,$(src)),$(src),$(if $(wildcard \
$(objtree)/$(src)/Kbuild)$(wildcard \
$(objtree)/$(src)/Makefile),$(objtree)/$(src),$(srctree)/$(src)))  kbuild-file := \
$(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile)  \
include $(kbuild-file)  
@@ -403,7 +405,8 @@ quiet_cmd_ar_and_symver = AR      $@
       cmd_ar_and_symver = $(cmd_update_lto_symversions); $(cmd_ar_builtin)
 
 $(obj)/built-in.a: $(real-obj-y) FORCE
-	$(call if_changed,ar_and_symver)
+#bbox: Use standard AR. We need symbol table
+	$(call if_changed,ar)
 
 #
 # Rule to create modules.order file
diff --git a/scripts/Makefile.host b/scripts/Makefile.host
index 278b4d6ac..8bac91cd2 100644
--- a/scripts/Makefile.host
+++ b/scripts/Makefile.host
@@ -5,16 +5,20 @@
 quiet_cmd_flex = LEX     $@
       cmd_flex = $(LEX) -o$@ -L $<
 
+ifdef REGENERATE_PARSERS
 $(obj)/%.lex.c: $(src)/%.l FORCE
 	$(call if_changed,flex)
+endif
 
 # YACC
 # ---------------------------------------------------------------------------
 quiet_cmd_bison = YACC    $(basename $@).[ch]
       cmd_bison = $(YACC) -o $(basename $@).c --defines=$(basename $@).h -t -l $<
 
+ifdef REGENERATE_PARSERS
 $(obj)/%.tab.c $(obj)/%.tab.h: $(src)/%.y FORCE
 	$(call if_changed,bison)
+endif
 
 # ==========================================================================
 # Building binaries on the host system
diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c
index d98540552..bbdce3c56 100644
--- a/scripts/basic/fixdep.c
+++ b/scripts/basic/fixdep.c
@@ -236,25 +236,46 @@ static int str_ends_with(const char *s, int slen, const char \
*sub)  
 static void parse_config_file(const char *p)
 {
-	const char *q, *r;
-	const char *start = p;
-
-	while ((p = strstr(p, "CONFIG_"))) {
-		if (p > start && (isalnum(p[-1]) || p[-1] == '_')) {
-			p += 7;
+	/* modified for bbox */
+	size_t len = strlen(p);
+	const char *end_3 = p + len - 3; /* 3 == length of "IF_" */
+	const char *end_7 = p + len - 7;
+	const char *q;
+	int off;
+
+	for (; p <= end_3; p++) {
+		/* Find next identifier's beginning */
+		if (!(isalnum((unsigned char)*p) || *p == '_'))
 			continue;
+
+		/* Check it */
+		if (p < end_7 && p[6] == '_') {
+			if (!memcmp(p, "CONFIG", 6)) goto conf7;
+			if (!memcmp(p, "ENABLE", 6)) goto conf7;
+			if (!memcmp(p, "IF_NOT", 6)) goto conf7;
+		}
+		/* we have at least 3 chars because of p <= end_3 */
+		/*if (!memcmp(p, "IF_", 3)) ...*/
+		if (p[0] == 'I' && p[1] == 'F' && p[2] == '_') {
+			off = 3;
+			goto conf;
+		}
+
+		/* This identifier is not interesting, skip it */
+		while (p <= end_3 && (isalnum((unsigned char)*p) || *p == '_'))
+			p++;
+		continue;
+
+	conf7:	off = 7;
+	conf:
+		p += off;
+		for (q = p; q < end_3+3; q++) {
+			if (!(isalnum((unsigned char)*q) || *q == '_'))
+				break;
+		}
+		if (q != p) {
+			use_config(p, q - p);
 		}
-		p += 7;
-		q = p;
-		while (isalnum(*q) || *q == '_')
-			q++;
-		if (str_ends_with(p, q - p, "_MODULE"))
-			r = q - 7;
-		else
-			r = q;
-		if (r > p)
-			use_config(p, r - p);
-		p = q;
 	}
 }
 
diff --git a/scripts/find_stray_common_vars b/scripts/find_stray_common_vars
index 3a25d7a8d..adce73d30 100755
--- a/scripts/find_stray_common_vars
+++ b/scripts/find_stray_common_vars
@@ -3,7 +3,7 @@
 # Common variables are elusive, they don't show up in size output!
 # This script will show all commons in *.o, sorted by size
 
-find ! -path './scripts/*' -a ! -name built-in.o -a -name '*.o' \
+find . ! -path './scripts/*' -name '*.o' \
 | while read name; do
     b=`basename "$name"`
     nm "$name" | sed "s/^/$b: /"
diff --git a/scripts/kconfig/.gitignore b/scripts/kconfig/.gitignore
index c3d537cd0..ca0c18eda 100644
--- a/scripts/kconfig/.gitignore
+++ b/scripts/kconfig/.gitignore
@@ -2,6 +2,9 @@
 /qconf-moc.cc
 *conf-cfg
 
+lexer.lex.c
+parser.tab.[ch]
+
 #
 # configuration programs
 #
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 8c19b82c6..d114cbaed 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -59,8 +59,24 @@ simple-targets := oldconfig allnoconfig allyesconfig allmodconfig \
\  
 PHONY += $(simple-targets)
 
+# Mtime granularity problem.
+# It was observed that these commands:
+# make allnoconfig; sed -i -e '/CONFIG_TRUE/c CONFIG_TRUE=y' .config; make
+# sometimes produce busybox with "true" applet still disabled.
+# This is caused by .config updated by sed having mtime which is still
+# equal to (not bigger than) include/generated/autoconf.h's mtime,
+# and thus 2nd make does not regenerate include/generated/autoconf.h.
+# Waiting for 1 second after non-interactive "make XXXXconfig"
+# prevents this from happening.
+#
+# We'd like to detect whether filesystem we are on has coarse mtimes,
+# but can't do it yet, bbox ls hasn't got --full-time.
+#MTIME_IS_COARSE:=@ls --full-time -ld | grep -F .000 >/dev/null
+MTIME_IS_COARSE:=@true
+
 $(simple-targets): $(obj)/conf
 	$(Q)$< $(silent) --$@ $(Kconfig)
+	$(MTIME_IS_COARSE) && sleep 1
 
 PHONY += savedefconfig defconfig
 
@@ -68,18 +84,20 @@ savedefconfig: $(obj)/conf
 	$(Q)$< $(silent) --$@=defconfig $(Kconfig)
 
 defconfig: $(obj)/conf
-ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG)),)
+ifneq ($(wildcard $(srctree)/configs/$(KBUILD_DEFCONFIG)),)
 	@$(kecho) "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'"
-	$(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig)
+	$(Q)$< $(silent) --defconfig=configs/$(KBUILD_DEFCONFIG) $(Kconfig)
 else
 	@$(kecho) "*** Default configuration is based on target '$(KBUILD_DEFCONFIG)'"
 	$(Q)$(MAKE) -f $(srctree)/Makefile $(KBUILD_DEFCONFIG)
 endif
+	$(MTIME_IS_COARSE) && sleep 1
 
 %_defconfig: $(obj)/conf
-	$(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)
+	$(Q)$< $(silent) --defconfig=configs/$@ $(Kconfig)
+	$(MTIME_IS_COARSE) && sleep 1
 
-configfiles=$(wildcard $(srctree)/kernel/configs/$@ \
$(srctree)/arch/$(SRCARCH)/configs/$@) +configfiles=$(wildcard \
$(srctree)/kernel/configs/$@ $(srctree)/configs/$@)  
 %.config: $(obj)/conf
 	$(if $(call configfiles),, $(error No configuration exists for this target on this \
                architecture))
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index 2568dbe16..8af626a62 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -653,7 +653,12 @@ header_print_symbol(FILE *fp, struct symbol *sym, const char \
*value, void *arg)  
 		switch (*value) {
 		case 'n':
-			break;
+			/* bbox */
+			fprintf(fp, "#undef %s%s\n", CONFIG_, sym->name);
+			fprintf(fp, "#define ENABLE_%s 0\n", sym->name);
+			fprintf(fp, "#define IF_%s(...)\n", sym->name);
+			fprintf(fp, "#define IF_NOT_%s(...) __VA_ARGS__\n", sym->name);
+			return;
 		case 'm':
 			suffix = "_MODULE";
 			/* fall through */
@@ -678,9 +683,17 @@ header_print_symbol(FILE *fp, struct symbol *sym, const char \
*value, void *arg)  CONFIG_, sym->name, value);
 		break;
 	default:
-		break;
+		return;
 	}
 
+	/* bbox: additional defines */
+	fprintf(fp, "#define ENABLE_%s 1\n", sym->name);
+	fprintf(fp, "#ifdef MAKE_SUID\n");
+	fprintf(fp, "# define IF_%s(...) __VA_ARGS__ \"%s%s\"\n", sym->name, CONFIG_, \
sym->name); +	fprintf(fp, "#else\n");
+	fprintf(fp, "# define IF_%s(...) __VA_ARGS__\n", sym->name);
+	fprintf(fp, "#endif\n");
+	fprintf(fp, "#define IF_NOT_%s(...)\n", sym->name);
 }
 
 static void
@@ -1070,7 +1083,8 @@ int conf_write_autoconf(int overwrite)
 
 	for_all_symbols(i, sym) {
 		sym_calc_value(sym);
-		if (!(sym->flags & SYMBOL_WRITE) || !sym->name)
+		/* bbox: we want to see *all* symbols */
+		if (/* !(sym->flags & SYMBOL_WRITE) || */ !sym->name)
 			continue;
 
 		/* write symbols to auto.conf and autoconf.h */
diff --git a/scripts/kconfig/lexer.lex.c_shipped \
b/scripts/kconfig/lexer.lex.c_shipped new file mode 100644
index 000000000..c7ae3c16c
--- /dev/null
+++ b/scripts/kconfig/lexer.lex.c_shipped
@@ -0,0 +1,4328 @@
+
+#define  YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 6
+#define YY_FLEX_SUBMINOR_VERSION 4
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with  platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types. 
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t; 
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN               (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN              (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN              (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX               (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX              (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX              (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX              (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX             (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX             (4294967295U)
+#endif
+
+#ifndef SIZE_MAX
+#define SIZE_MAX               (~(size_t)0)
+#endif
+
+#endif /* ! C99 */
+
+#endif /* ! FLEXINT_H */
+
+/* begin standard C++ headers. */
+
+/* TODO: this is always defined, so inline it */
+#define yyconst const
+
+#if defined(__GNUC__) && __GNUC__ >= 3
+#define yynoreturn __attribute__((__noreturn__))
+#else
+#define yynoreturn
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an
+ *   integer in range [0..255] for use as an array index.
+ */
+#define YY_SC_TO_UI(c) ((YY_CHAR) (c))
+
+/* Enter a start condition.  This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN (yy_start) = 1 + 2 *
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state.  The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START (((yy_start) - 1) / 2)
+#define YYSTATE YY_START
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart( yyin  )
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k.
+ * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
+ * Ditto for the __ia64__ case accordingly.
+ */
+#define YY_BUF_SIZE 32768
+#else
+#define YY_BUF_SIZE 16384
+#endif /* __ia64__ */
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main \
buffer. + */
+#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+extern int yyleng;
+
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+    
+    /* Note: We specifically omit the test for yy_rule_can_match_eol because it \
requires +     *       access to the local variable yy_act. Since yyless() is a \
macro, it would break +     *       existing scanners that call yyless() from OUTSIDE \
yylex. +     *       One obvious solution it to make yy_act a global. I tried that, \
and saw +     *       a 5% performance hit in a non-yylineno scanner, because yy_act \
is +     *       normally declared as a register variable-- so it is not worth it.
+     */
+    #define  YY_LESS_LINENO(n) \
+            do { \
+                int yyl;\
+                for ( yyl = n; yyl < yyleng; ++yyl )\
+                    if ( yytext[yyl] == '\n' )\
+                        --yylineno;\
+            }while(0)
+    #define YY_LINENO_REWIND_TO(dst) \
+            do {\
+                const char *p;\
+                for ( p = yy_cp-1; p >= (dst); --p)\
+                    if ( *p == '\n' )\
+                        --yylineno;\
+            }while(0)
+    
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up yytext. */ \
+        int yyless_macro_arg = (n); \
+        YY_LESS_LINENO(yyless_macro_arg);\
+		*yy_cp = (yy_hold_char); \
+		YY_RESTORE_YY_MORE_OFFSET \
+		(yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+		YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+		} \
+	while ( 0 )
+#define unput(c) yyunput( c, (yytext_ptr)  )
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+	{
+	FILE *yy_input_file;
+
+	char *yy_ch_buf;		/* input buffer */
+	char *yy_buf_pos;		/* current position in input buffer */
+
+	/* Size of input buffer in bytes, not including room for EOB
+	 * characters.
+	 */
+	int yy_buf_size;
+
+	/* Number of characters read into yy_ch_buf, not including EOB
+	 * characters.
+	 */
+	int yy_n_chars;
+
+	/* Whether we "own" the buffer - i.e., we know we created it,
+	 * and can realloc() it to grow it, and should free() it to
+	 * delete it.
+	 */
+	int yy_is_our_buffer;
+
+	/* Whether this is an "interactive" input source; if so, and
+	 * if we're using stdio for input, then we want to use getc()
+	 * instead of fread(), to make sure we stop fetching input after
+	 * each newline.
+	 */
+	int yy_is_interactive;
+
+	/* Whether we're considered to be at the beginning of a line.
+	 * If so, '^' rules will be active on the next match, otherwise
+	 * not.
+	 */
+	int yy_at_bol;
+
+    int yy_bs_lineno; /**< The line count. */
+    int yy_bs_column; /**< The column count. */
+
+	/* Whether to try to fill the input buffer when we reach the
+	 * end of it.
+	 */
+	int yy_fill_buffer;
+
+	int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+	/* When an EOF's been seen but there's still some text to process
+	 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+	 * shouldn't try reading from the input source any more.  We might
+	 * still have a bunch of tokens to match, though, because of
+	 * possible backing-up.
+	 *
+	 * When we actually see the EOF, we change the status to "new"
+	 * (via yyrestart()), so that the user can continue scanning by
+	 * just pointing yyin at a new input file.
+	 */
+#define YY_BUFFER_EOF_PENDING 2
+
+	};
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+                          ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+                          : NULL)
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+static int yy_n_chars;		/* number of characters read into yy_ch_buf */
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = NULL;
+static int yy_init = 0;		/* whether we need to initialize */
+static int yy_start = 0;	/* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin.  A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart ( FILE *input_file  );
+void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer  );
+YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size  );
+void yy_delete_buffer ( YY_BUFFER_STATE b  );
+void yy_flush_buffer ( YY_BUFFER_STATE b  );
+void yypush_buffer_state ( YY_BUFFER_STATE new_buffer  );
+void yypop_buffer_state ( void );
+
+static void yyensure_buffer_stack ( void );
+static void yy_load_buffer_state ( void );
+static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file  );
+#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER )
+
+YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size  );
+YY_BUFFER_STATE yy_scan_string ( const char *yy_str  );
+YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len  );
+
+void *yyalloc ( yy_size_t  );
+void *yyrealloc ( void *, yy_size_t  );
+void yyfree ( void *  );
+
+#define yy_new_buffer yy_create_buffer
+#define yy_set_interactive(is_interactive) \
+	{ \
+	if ( ! YY_CURRENT_BUFFER ){ \
+        yyensure_buffer_stack (); \
+		YY_CURRENT_BUFFER_LVALUE =    \
+            yy_create_buffer( yyin, YY_BUF_SIZE ); \
+	} \
+	YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+	}
+#define yy_set_bol(at_bol) \
+	{ \
+	if ( ! YY_CURRENT_BUFFER ){\
+        yyensure_buffer_stack (); \
+		YY_CURRENT_BUFFER_LVALUE =    \
+            yy_create_buffer( yyin, YY_BUF_SIZE ); \
+	} \
+	YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+	}
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+#define yywrap() (/*CONSTCOND*/1)
+#define YY_SKIP_YYWRAP
+typedef flex_uint8_t YY_CHAR;
+
+FILE *yyin = NULL, *yyout = NULL;
+
+typedef int yy_state_type;
+
+extern int yylineno;
+int yylineno = 1;
+
+extern char *yytext;
+#ifdef yytext_ptr
+#undef yytext_ptr
+#endif
+#define yytext_ptr yytext
+
+static const flex_int16_t yy_nxt[][42] =
+    {
+    {
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0
+    },
+
+    {
+        9,   10,   11,   12,   13,   14,   15,   16,   17,   14,
+       18,   19,   20,   21,   22,   23,   24,   25,   26,   21,
+       27,   28,   29,   30,   31,   21,   21,   32,   33,   21,
+       34,   21,   35,   36,   37,   38,   39,   21,   40,   21,
+       21,   41
+
+    },
+
+    {
+        9,   10,   11,   12,   13,   14,   15,   16,   17,   14,
+       18,   19,   20,   21,   22,   23,   24,   25,   26,   21,
+       27,   28,   29,   30,   31,   21,   21,   32,   33,   21,
+       34,   21,   35,   36,   37,   38,   39,   21,   40,   21,
+       21,   41
+    },
+
+    {
+        9,   42,   43,   44,   42,   42,   42,   42,   42,   42,
+       42,   42,   42,   42,   42,   42,   42,   42,   42,   42,
+       42,   42,   42,   42,   42,   42,   42,   42,   42,   42,
+       42,   42,   42,   42,   42,   42,   42,   42,   42,   42,
+       42,   42
+
+    },
+
+    {
+        9,   42,   43,   44,   42,   42,   42,   42,   42,   42,
+       42,   42,   42,   42,   42,   42,   42,   42,   42,   42,
+       42,   42,   42,   42,   42,   42,   42,   42,   42,   42,
+       42,   42,   42,   42,   42,   42,   42,   42,   42,   42,
+       42,   42
+    },
+
+    {
+        9,   45,   46,   47,   45,   45,   45,   45,   45,   45,
+       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
+       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
+       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
+       45,   45
+
+    },
+
+    {
+        9,   45,   46,   47,   45,   45,   45,   45,   45,   45,
+       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
+       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
+       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
+       45,   45
+    },
+
+    {
+        9,   48,   48,   49,   48,   50,   48,   51,   48,   50,
+       48,   48,   48,   48,   48,   48,   48,   48,   52,   48,
+       48,   48,   48,   48,   48,   48,   48,   48,   48,   48,
+       48,   48,   48,   48,   48,   48,   48,   48,   48,   48,
+       48,   48
+
+    },
+
+    {
+        9,   48,   48,   49,   48,   50,   48,   51,   48,   50,
+       48,   48,   48,   48,   48,   48,   48,   48,   52,   48,
+       48,   48,   48,   48,   48,   48,   48,   48,   48,   48,
+       48,   48,   48,   48,   48,   48,   48,   48,   48,   48,
+       48,   48
+    },
+
+    {
+       -9,   -9,   -9,   -9,   -9,   -9,   -9,   -9,   -9,   -9,
+       -9,   -9,   -9,   -9,   -9,   -9,   -9,   -9,   -9,   -9,
+       -9,   -9,   -9,   -9,   -9,   -9,   -9,   -9,   -9,   -9,
+       -9,   -9,   -9,   -9,   -9,   -9,   -9,   -9,   -9,   -9,
+       -9,   -9
+
+    },
+
+    {
+        9,  -10,  -10,  -10,  -10,  -10,  -10,  -10,  -10,  -10,
+      -10,  -10,  -10,  -10,  -10,  -10,  -10,  -10,  -10,  -10,
+      -10,  -10,  -10,  -10,  -10,  -10,  -10,  -10,  -10,  -10,
+      -10,  -10,  -10,  -10,  -10,  -10,  -10,  -10,  -10,  -10,
+      -10,  -10
+    },
+
+    {
+        9,  -11,   53,  -11,  -11,  -11,  -11,  -11,  -11,  -11,
+      -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,
+      -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,
+      -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,
+      -11,  -11
+
+    },
+
+    {
+        9,  -12,  -12,  -12,  -12,  -12,  -12,  -12,  -12,  -12,
+      -12,  -12,  -12,  -12,  -12,  -12,  -12,  -12,  -12,  -12,
+      -12,  -12,  -12,  -12,  -12,  -12,  -12,  -12,  -12,  -12,
+      -12,  -12,  -12,  -12,  -12,  -12,  -12,  -12,  -12,  -12,
+      -12,  -12
+    },
+
+    {
+        9,  -13,  -13,  -13,  -13,  -13,  -13,  -13,  -13,  -13,
+      -13,  -13,  -13,  -13,  -13,  -13,   54,  -13,  -13,  -13,
+      -13,  -13,  -13,  -13,  -13,  -13,  -13,  -13,  -13,  -13,
+      -13,  -13,  -13,  -13,  -13,  -13,  -13,  -13,  -13,  -13,
+      -13,  -13
+
+    },
+
+    {
+        9,  -14,  -14,  -14,  -14,  -14,  -14,  -14,  -14,  -14,
+      -14,  -14,  -14,  -14,  -14,  -14,  -14,  -14,  -14,  -14,
+      -14,  -14,  -14,  -14,  -14,  -14,  -14,  -14,  -14,  -14,
+      -14,  -14,  -14,  -14,  -14,  -14,  -14,  -14,  -14,  -14,
+      -14,  -14
+    },
+
+    {
+        9,   55,   55,  -15,   55,   55,   55,   55,   55,   55,
+       55,   55,   55,   55,   55,   55,   55,   55,   55,   55,
+       55,   55,   55,   55,   55,   55,   55,   55,   55,   55,
+       55,   55,   55,   55,   55,   55,   55,   55,   55,   55,
+       55,   55
+
+    },
+
+    {
+        9,  -16,  -16,  -16,  -16,  -16,  -16,   56,  -16,  -16,
+      -16,  -16,  -16,   56,  -16,  -16,  -16,  -16,  -16,   56,
+       56,   56,   56,   56,   56,   56,   56,   56,   56,   56,
+       56,   56,   56,   56,   56,   56,   56,   56,   56,   56,
+       56,  -16
+    },
+
+    {
+        9,  -17,  -17,  -17,  -17,  -17,  -17,  -17,   57,  -17,
+      -17,  -17,  -17,  -17,  -17,  -17,  -17,  -17,  -17,  -17,
+      -17,  -17,  -17,  -17,  -17,  -17,  -17,  -17,  -17,  -17,
+      -17,  -17,  -17,  -17,  -17,  -17,  -17,  -17,  -17,  -17,
+      -17,  -17
+
+    },
+
+    {
+        9,  -18,  -18,  -18,  -18,  -18,  -18,  -18,  -18,  -18,
+      -18,  -18,  -18,  -18,  -18,  -18,  -18,  -18,  -18,  -18,
+      -18,  -18,  -18,  -18,  -18,  -18,  -18,  -18,  -18,  -18,
+      -18,  -18,  -18,  -18,  -18,  -18,  -18,  -18,  -18,  -18,
+      -18,  -18
+    },
+
+    {
+        9,  -19,  -19,  -19,  -19,  -19,  -19,  -19,  -19,  -19,
+      -19,  -19,  -19,  -19,  -19,  -19,  -19,  -19,  -19,  -19,
+      -19,  -19,  -19,  -19,  -19,  -19,  -19,  -19,  -19,  -19,
+      -19,  -19,  -19,  -19,  -19,  -19,  -19,  -19,  -19,  -19,
+      -19,  -19
+
+    },
+
+    {
+        9,  -20,  -20,  -20,  -20,  -20,  -20,  -20,  -20,  -20,
+      -20,  -20,  -20,  -20,  -20,  -20,   58,  -20,  -20,  -20,
+      -20,  -20,  -20,  -20,  -20,  -20,  -20,  -20,  -20,  -20,
+      -20,  -20,  -20,  -20,  -20,  -20,  -20,  -20,  -20,  -20,
+      -20,  -20
+    },
+
+    {
+        9,  -21,  -21,  -21,  -21,  -21,  -21,   56,  -21,  -21,
+      -21,  -21,  -21,   59,  -21,  -21,  -21,  -21,  -21,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,  -21
+
+    },
+
+    {
+        9,  -22,  -22,  -22,  -22,  -22,  -22,  -22,  -22,  -22,
+      -22,  -22,  -22,  -22,  -22,  -22,   60,  -22,  -22,  -22,
+      -22,  -22,  -22,  -22,  -22,  -22,  -22,  -22,  -22,  -22,
+      -22,  -22,  -22,  -22,  -22,  -22,  -22,  -22,  -22,  -22,
+      -22,  -22
+    },
+
+    {
+        9,  -23,  -23,  -23,  -23,  -23,  -23,  -23,  -23,  -23,
+      -23,  -23,  -23,  -23,  -23,  -23,   61,  -23,  -23,  -23,
+      -23,  -23,  -23,  -23,  -23,  -23,  -23,  -23,  -23,  -23,
+      -23,  -23,  -23,  -23,  -23,  -23,  -23,  -23,  -23,  -23,
+      -23,  -23
+
+    },
+
+    {
+        9,  -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,
+      -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,
+      -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,
+      -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,
+      -24,  -24
+    },
+
+    {
+        9,  -25,  -25,  -25,  -25,  -25,  -25,  -25,  -25,  -25,
+      -25,  -25,  -25,  -25,  -25,  -25,   62,  -25,  -25,  -25,
+      -25,  -25,  -25,  -25,  -25,  -25,  -25,  -25,  -25,  -25,
+      -25,  -25,  -25,  -25,  -25,  -25,  -25,  -25,  -25,  -25,
+      -25,  -25
+
+    },
+
+    {
+        9,  -26,  -26,   63,  -26,  -26,  -26,  -26,  -26,  -26,
+      -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,
+      -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,
+      -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,
+      -26,  -26
+    },
+
+    {
+        9,  -27,  -27,  -27,  -27,  -27,  -27,   56,  -27,  -27,
+      -27,  -27,  -27,   59,  -27,  -27,  -27,  -27,  -27,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   64,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,  -27
+
+    },
+
+    {
+        9,  -28,  -28,  -28,  -28,  -28,  -28,   56,  -28,  -28,
+      -28,  -28,  -28,   59,  -28,  -28,  -28,  -28,  -28,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   65,   59,   59,   59,   59,   59,   59,   59,
+       59,  -28
+    },
+
+    {
+        9,  -29,  -29,  -29,  -29,  -29,  -29,   56,  -29,  -29,
+      -29,  -29,  -29,   59,  -29,  -29,  -29,  -29,  -29,   59,
+       59,   59,   59,   59,   59,   59,   59,   66,   59,   59,
+       59,   59,   67,   59,   59,   59,   59,   59,   59,   59,
+       59,  -29
+
+    },
+
+    {
+        9,  -30,  -30,  -30,  -30,  -30,  -30,   56,  -30,  -30,
+      -30,  -30,  -30,   59,  -30,  -30,  -30,  -30,  -30,   59,
+       59,   59,   59,   59,   68,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,  -30
+    },
+
+    {
+        9,  -31,  -31,  -31,  -31,  -31,  -31,   56,  -31,  -31,
+      -31,  -31,  -31,   59,  -31,  -31,  -31,  -31,  -31,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   69,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,  -31
+
+    },
+
+    {
+        9,  -32,  -32,  -32,  -32,  -32,  -32,   56,  -32,  -32,
+      -32,  -32,  -32,   59,  -32,  -32,  -32,  -32,  -32,   59,
+       59,   59,   59,   59,   70,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,  -32
+    },
+
+    {
+        9,  -33,  -33,  -33,  -33,  -33,  -33,   56,  -33,  -33,
+      -33,  -33,  -33,   59,  -33,  -33,  -33,  -33,  -33,   59,
+       59,   59,   59,   59,   59,   71,   59,   59,   59,   59,
+       72,   73,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,  -33
+
+    },
+
+    {
+        9,  -34,  -34,  -34,  -34,  -34,  -34,   56,  -34,  -34,
+      -34,  -34,  -34,   59,  -34,  -34,  -34,  -34,  -34,   59,
+       74,   59,   59,   59,   75,   59,   59,   59,   59,   59,
+       59,   59,   76,   59,   59,   59,   59,   59,   59,   59,
+       59,  -34
+    },
+
+    {
+        9,  -35,  -35,  -35,  -35,  -35,  -35,   56,  -35,  -35,
+      -35,  -35,  -35,   59,  -35,  -35,  -35,  -35,  -35,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   77,   59,   78,   59,   59,   59,   59,   59,   59,
+       59,  -35
+
+    },
+
+    {
+        9,  -36,  -36,  -36,  -36,  -36,  -36,   56,  -36,  -36,
+      -36,  -36,  -36,   59,  -36,  -36,  -36,  -36,  -36,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   79,   59,   59,   59,   59,   59,
+       59,  -36
+    },
+
+    {
+        9,  -37,  -37,  -37,  -37,  -37,  -37,   56,  -37,  -37,
+      -37,  -37,  -37,   59,  -37,  -37,  -37,  -37,  -37,   59,
+       80,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,  -37
+
+    },
+
+    {
+        9,  -38,  -38,  -38,  -38,  -38,  -38,   56,  -38,  -38,
+      -38,  -38,  -38,   59,  -38,  -38,  -38,  -38,  -38,   59,
+       59,   59,   59,   59,   81,   59,   59,   59,   59,   59,
+       59,   59,   82,   59,   59,   59,   83,   59,   59,   59,
+       59,  -38
+    },
+
+    {
+        9,  -39,  -39,  -39,  -39,  -39,  -39,   56,  -39,  -39,
+      -39,  -39,  -39,   59,  -39,  -39,  -39,  -39,  -39,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   84,   59,   59,   59,   59,   59,
+       59,  -39
+
+    },
+
+    {
+        9,  -40,  -40,  -40,  -40,  -40,  -40,   56,  -40,  -40,
+      -40,  -40,  -40,   59,  -40,  -40,  -40,  -40,  -40,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   85,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,  -40
+    },
+
+    {
+        9,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,
+      -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,
+      -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,
+      -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,
+      -41,   86
+
+    },
+
+    {
+        9,   87,   88,  -42,   87,   87,   87,   87,   87,   87,
+       87,   87,   87,   87,   87,   87,   87,   87,   87,   87,
+       87,   87,   87,   87,   87,   87,   87,   87,   87,   87,
+       87,   87,   87,   87,   87,   87,   87,   87,   87,   87,
+       87,   87
+    },
+
+    {
+        9,  -43,  -43,  -43,  -43,  -43,  -43,  -43,  -43,  -43,
+      -43,  -43,  -43,  -43,  -43,  -43,  -43,  -43,  -43,  -43,
+      -43,  -43,  -43,  -43,  -43,  -43,  -43,  -43,  -43,  -43,
+      -43,  -43,  -43,  -43,  -43,  -43,  -43,  -43,  -43,  -43,
+      -43,  -43
+
+    },
+
+    {
+        9,  -44,  -44,  -44,  -44,  -44,  -44,  -44,  -44,  -44,
+      -44,  -44,  -44,  -44,  -44,  -44,  -44,  -44,  -44,  -44,
+      -44,  -44,  -44,  -44,  -44,  -44,  -44,  -44,  -44,  -44,
+      -44,  -44,  -44,  -44,  -44,  -44,  -44,  -44,  -44,  -44,
+      -44,  -44
+    },
+
+    {
+        9,   89,   89,  -45,   89,   89,   89,   89,   89,   89,
+       89,   89,   89,   89,   89,   89,   89,   89,   89,   89,
+       89,   89,   89,   89,   89,   89,   89,   89,   89,   89,
+       89,   89,   89,   89,   89,   89,   89,   89,   89,   89,
+       89,   89
+
+    },
+
+    {
+        9,  -46,   90,   91,  -46,  -46,  -46,  -46,  -46,  -46,
+      -46,  -46,  -46,  -46,  -46,  -46,  -46,  -46,  -46,  -46,
+      -46,  -46,  -46,  -46,  -46,  -46,  -46,  -46,  -46,  -46,
+      -46,  -46,  -46,  -46,  -46,  -46,  -46,  -46,  -46,  -46,
+      -46,  -46
+    },
+
+    {
+        9,   92,  -47,  -47,   92,   92,   92,   92,   92,   92,
+       92,   92,   92,   92,   92,   92,   92,   92,   92,   92,
+       92,   92,   92,   92,   92,   92,   92,   92,   92,   92,
+       92,   92,   92,   92,   92,   92,   92,   92,   92,   92,
+       92,   92
+
+    },
+
+    {
+        9,   93,   93,  -48,   93,  -48,   93,  -48,   93,  -48,
+       93,   93,   93,   93,   93,   93,   93,   93,  -48,   93,
+       93,   93,   93,   93,   93,   93,   93,   93,   93,   93,
+       93,   93,   93,   93,   93,   93,   93,   93,   93,   93,
+       93,   93
+    },
+
+    {
+        9,  -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,
+      -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,
+      -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,
+      -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,
+      -49,  -49
+
+    },
+
+    {
+        9,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,
+      -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,
+      -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,
+      -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,
+      -50,  -50
+    },
+
+    {
+        9,   94,   94,  -51,   94,   94,   94,   94,   94,   94,
+       94,   94,   94,   94,   94,   94,   94,   94,   94,   94,
+       94,   94,   94,   94,   94,   94,   94,   94,   94,   94,
+       94,   94,   94,   94,   94,   94,   94,   94,   94,   94,
+       94,   94
+
+    },
+
+    {
+        9,   95,   95,  -52,   95,   95,   95,   95,   95,   95,
+       95,   95,   95,   95,   95,   95,   95,   95,   95,   95,
+       95,   95,   95,   95,   95,   95,   95,   95,   95,   95,
+       95,   95,   95,   95,   95,   95,   95,   95,   95,   95,
+       95,   95
+    },
+
+    {
+        9,  -53,   53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,
+      -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,
+      -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,
+      -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,
+      -53,  -53
+
+    },
+
+    {
+        9,  -54,  -54,  -54,  -54,  -54,  -54,  -54,  -54,  -54,
+      -54,  -54,  -54,  -54,  -54,  -54,  -54,  -54,  -54,  -54,
+      -54,  -54,  -54,  -54,  -54,  -54,  -54,  -54,  -54,  -54,
+      -54,  -54,  -54,  -54,  -54,  -54,  -54,  -54,  -54,  -54,
+      -54,  -54
+    },
+
+    {
+        9,   55,   55,  -55,   55,   55,   55,   55,   55,   55,
+       55,   55,   55,   55,   55,   55,   55,   55,   55,   55,
+       55,   55,   55,   55,   55,   55,   55,   55,   55,   55,
+       55,   55,   55,   55,   55,   55,   55,   55,   55,   55,
+       55,   55
+
+    },
+
+    {
+        9,  -56,  -56,  -56,  -56,  -56,  -56,   56,  -56,  -56,
+      -56,  -56,  -56,   56,  -56,  -56,  -56,  -56,  -56,   56,
+       56,   56,   56,   56,   56,   56,   56,   56,   56,   56,
+       56,   56,   56,   56,   56,   56,   56,   56,   56,   56,
+       56,  -56
+    },
+
+    {
+        9,  -57,  -57,  -57,  -57,  -57,  -57,  -57,  -57,  -57,
+      -57,  -57,  -57,  -57,  -57,  -57,  -57,  -57,  -57,  -57,
+      -57,  -57,  -57,  -57,  -57,  -57,  -57,  -57,  -57,  -57,
+      -57,  -57,  -57,  -57,  -57,  -57,  -57,  -57,  -57,  -57,
+      -57,  -57
+
+    },
+
+    {
+        9,  -58,  -58,  -58,  -58,  -58,  -58,  -58,  -58,  -58,
+      -58,  -58,  -58,  -58,  -58,  -58,  -58,  -58,  -58,  -58,
+      -58,  -58,  -58,  -58,  -58,  -58,  -58,  -58,  -58,  -58,
+      -58,  -58,  -58,  -58,  -58,  -58,  -58,  -58,  -58,  -58,
+      -58,  -58
+    },
+
+    {
+        9,  -59,  -59,  -59,  -59,  -59,  -59,   56,  -59,  -59,
+      -59,  -59,  -59,   59,  -59,  -59,  -59,  -59,  -59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,  -59
+
+    },
+
+    {
+        9,  -60,  -60,  -60,  -60,  -60,  -60,  -60,  -60,  -60,
+      -60,  -60,  -60,  -60,  -60,  -60,  -60,  -60,  -60,  -60,
+      -60,  -60,  -60,  -60,  -60,  -60,  -60,  -60,  -60,  -60,
+      -60,  -60,  -60,  -60,  -60,  -60,  -60,  -60,  -60,  -60,
+      -60,  -60
+    },
+
+    {
+        9,  -61,  -61,  -61,  -61,  -61,  -61,  -61,  -61,  -61,
+      -61,  -61,  -61,  -61,  -61,  -61,  -61,  -61,  -61,  -61,
+      -61,  -61,  -61,  -61,  -61,  -61,  -61,  -61,  -61,  -61,
+      -61,  -61,  -61,  -61,  -61,  -61,  -61,  -61,  -61,  -61,
+      -61,  -61
+
+    },
+
+    {
+        9,  -62,  -62,  -62,  -62,  -62,  -62,  -62,  -62,  -62,
+      -62,  -62,  -62,  -62,  -62,  -62,  -62,  -62,  -62,  -62,
+      -62,  -62,  -62,  -62,  -62,  -62,  -62,  -62,  -62,  -62,
+      -62,  -62,  -62,  -62,  -62,  -62,  -62,  -62,  -62,  -62,
+      -62,  -62
+    },
+
+    {
+        9,  -63,  -63,  -63,  -63,  -63,  -63,  -63,  -63,  -63,
+      -63,  -63,  -63,  -63,  -63,  -63,  -63,  -63,  -63,  -63,
+      -63,  -63,  -63,  -63,  -63,  -63,  -63,  -63,  -63,  -63,
+      -63,  -63,  -63,  -63,  -63,  -63,  -63,  -63,  -63,  -63,
+      -63,  -63
+
+    },
+
+    {
+        9,  -64,  -64,  -64,  -64,  -64,  -64,   56,  -64,  -64,
+      -64,  -64,  -64,   59,  -64,  -64,  -64,  -64,  -64,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   96,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,  -64
+    },
+
+    {
+        9,  -65,  -65,  -65,  -65,  -65,  -65,   56,  -65,  -65,
+      -65,  -65,  -65,   59,  -65,  -65,  -65,  -65,  -65,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   97,   59,   59,   59,   59,   59,   59,   59,
+       59,  -65
+
+    },
+
+    {
+        9,  -66,  -66,  -66,  -66,  -66,  -66,   56,  -66,  -66,
+      -66,  -66,  -66,   59,  -66,  -66,  -66,  -66,  -66,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   98,   59,   59,   59,   59,   59,   59,   59,
+       59,  -66
+    },
+
+    {
+        9,  -67,  -67,  -67,  -67,  -67,  -67,   56,  -67,  -67,
+      -67,  -67,  -67,   59,  -67,  -67,  -67,  -67,  -67,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       99,  100,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,  -67
+
+    },
+
+    {
+        9,  -68,  -68,  -68,  -68,  -68,  -68,   56,  -68,  -68,
+      -68,  -68,  -68,   59,  -68,  -68,  -68,  -68,  -68,   59,
+       59,   59,   59,   59,   59,  101,   59,   59,   59,   59,
+       59,   59,   59,  102,   59,   59,   59,   59,   59,   59,
+       59,  -68
+    },
+
+    {
+        9,  -69,  -69,  -69,  -69,  -69,  -69,   56,  -69,  -69,
+      -69,  -69,  -69,   59,  -69,  -69,  -69,  -69,  -69,   59,
+       59,   59,   59,  103,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,  -69
+
+    },
+
+    {
+        9,  -70,  -70,  -70,  -70,  -70,  -70,   56,  -70,  -70,
+      -70,  -70,  -70,   59,  -70,  -70,  -70,  -70,  -70,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,  104,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,  105,
+       59,  -70
+    },
+
+    {
+        9,  -71,  -71,  -71,  -71,  -71,  -71,   56,  -71,  -71,
+      -71,  -71,  -71,   59,  -71,  -71,  -71,  -71,  -71,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,  -71
+
+    },
+
+    {
+        9,  -72,  -72,  -72,  -72,  -72,  -72,   56,  -72,  -72,
+      -72,  -72,  -72,   59,  -72,  -72,  -72,  -72,  -72,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,  106,   59,   59,   59,   59,   59,   59,
+       59,  -72
+    },
+
+    {
+        9,  -73,  -73,  -73,  -73,  -73,  -73,   56,  -73,  -73,
+      -73,  -73,  -73,   59,  -73,  -73,  -73,  -73,  -73,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,  107,   59,   59,   59,
+       59,  -73
+
+    },
+
+    {
+        9,  -74,  -74,  -74,  -74,  -74,  -74,   56,  -74,  -74,
+      -74,  -74,  -74,   59,  -74,  -74,  -74,  -74,  -74,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,  108,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,  -74
+    },
+
+    {
+        9,  -75,  -75,  -75,  -75,  -75,  -75,   56,  -75,  -75,
+      -75,  -75,  -75,   59,  -75,  -75,  -75,  -75,  -75,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,  109,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,  -75
+
+    },
+
+    {
+        9,  -76,  -76,  -76,  -76,  -76,  -76,   56,  -76,  -76,
+      -76,  -76,  -76,   59,  -76,  -76,  -76,  -76,  -76,   59,
+       59,   59,   59,  110,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,  -76
+    },
+
+    {
+        9,  -77,  -77,  -77,  -77,  -77,  -77,   56,  -77,  -77,
+      -77,  -77,  -77,   59,  -77,  -77,  -77,  -77,  -77,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,  -77
+
+    },
+
+    {
+        9,  -78,  -78,  -78,  -78,  -78,  -78,   56,  -78,  -78,
+      -78,  -78,  -78,   59,  -78,  -78,  -78,  -78,  -78,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,  111,   59,   59,   59,
+       59,  -78
+    },
+
+    {
+        9,  -79,  -79,  -79,  -79,  -79,  -79,   56,  -79,  -79,
+      -79,  -79,  -79,   59,  -79,  -79,  -79,  -79,  -79,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,  112,   59,   59,   59,   59,   59,   59,   59,
+       59,  -79
+
+    },
+
+    {
+        9,  -80,  -80,  -80,  -80,  -80,  -80,   56,  -80,  -80,
+      -80,  -80,  -80,   59,  -80,  -80,  -80,  -80,  -80,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,  113,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,  -80
+    },
+
+    {
+        9,  -81,  -81,  -81,  -81,  -81,  -81,   56,  -81,  -81,
+      -81,  -81,  -81,   59,  -81,  -81,  -81,  -81,  -81,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,  114,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,  -81
+
+    },
+
+    {
+        9,  -82,  -82,  -82,  -82,  -82,  -82,   56,  -82,  -82,
+      -82,  -82,  -82,   59,  -82,  -82,  -82,  -82,  -82,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,  115,   59,   59,
+       59,  -82
+    },
+
+    {
+        9,  -83,  -83,  -83,  -83,  -83,  -83,   56,  -83,  -83,
+      -83,  -83,  -83,   59,  -83,  -83,  -83,  -83,  -83,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,  116,   59,   59,   59,   59,   59,
+       59,  -83
+
+    },
+
+    {
+        9,  -84,  -84,  -84,  -84,  -84,  -84,   56,  -84,  -84,
+      -84,  -84,  -84,   59,  -84,  -84,  -84,  -84,  -84,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,  117,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,  -84
+    },
+
+    {
+        9,  -85,  -85,  -85,  -85,  -85,  -85,   56,  -85,  -85,
+      -85,  -85,  -85,   59,  -85,  -85,  -85,  -85,  -85,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,  118,   59,   59,   59,   59,
+       59,  -85
+
+    },
+
+    {
+        9,  -86,  -86,  -86,  -86,  -86,  -86,  -86,  -86,  -86,
+      -86,  -86,  -86,  -86,  -86,  -86,  -86,  -86,  -86,  -86,
+      -86,  -86,  -86,  -86,  -86,  -86,  -86,  -86,  -86,  -86,
+      -86,  -86,  -86,  -86,  -86,  -86,  -86,  -86,  -86,  -86,
+      -86,  -86
+    },
+
+    {
+        9,   87,   88,  -87,   87,   87,   87,   87,   87,   87,
+       87,   87,   87,   87,   87,   87,   87,   87,   87,   87,
+       87,   87,   87,   87,   87,   87,   87,   87,   87,   87,
+       87,   87,   87,   87,   87,   87,   87,   87,   87,   87,
+       87,   87
+
+    },
+
+    {
+        9,   88,   88,  -88,   88,   88,   88,   88,   88,   88,
+       88,   88,   88,   88,   88,   88,   88,   88,   88,   88,
+       88,   88,   88,   88,   88,   88,   88,   88,   88,   88,
+       88,   88,   88,   88,   88,   88,   88,   88,   88,   88,
+       88,   88
+    },
+
+    {
+        9,   89,   89,  -89,   89,   89,   89,   89,   89,   89,
+       89,   89,   89,   89,   89,   89,   89,   89,   89,   89,
+       89,   89,   89,   89,   89,   89,   89,   89,   89,   89,
+       89,   89,   89,   89,   89,   89,   89,   89,   89,   89,
+       89,   89
+
+    },
+
+    {
+        9,  -90,   90,   91,  -90,  -90,  -90,  -90,  -90,  -90,
+      -90,  -90,  -90,  -90,  -90,  -90,  -90,  -90,  -90,  -90,
+      -90,  -90,  -90,  -90,  -90,  -90,  -90,  -90,  -90,  -90,
+      -90,  -90,  -90,  -90,  -90,  -90,  -90,  -90,  -90,  -90,
+      -90,  -90
+    },
+
+    {
+        9,   92,  -91,  -91,   92,   92,   92,   92,   92,   92,
+       92,   92,   92,   92,   92,   92,   92,   92,   92,   92,
+       92,   92,   92,   92,   92,   92,   92,   92,   92,   92,
+       92,   92,   92,   92,   92,   92,   92,   92,   92,   92,
+       92,   92
+
+    },
+
+    {
+        9,  -92,  -92,  -92,  -92,  -92,  -92,  -92,  -92,  -92,
+      -92,  -92,  -92,  -92,  -92,  -92,  -92,  -92,  -92,  -92,
+      -92,  -92,  -92,  -92,  -92,  -92,  -92,  -92,  -92,  -92,
+      -92,  -92,  -92,  -92,  -92,  -92,  -92,  -92,  -92,  -92,
+      -92,  -92
+    },
+
+    {
+        9,   93,   93,  -93,   93,  -93,   93,  -93,   93,  -93,
+       93,   93,   93,   93,   93,   93,   93,   93,  -93,   93,
+       93,   93,   93,   93,   93,   93,   93,   93,   93,   93,
+       93,   93,   93,   93,   93,   93,   93,   93,   93,   93,
+       93,   93
+
+    },
+
+    {
+        9,   94,   94,  -94,   94,   94,   94,   94,   94,   94,
+       94,   94,   94,   94,   94,   94,   94,   94,   94,   94,
+       94,   94,   94,   94,   94,   94,   94,   94,   94,   94,
+       94,   94,   94,   94,   94,   94,   94,   94,   94,   94,
+       94,   94
+    },
+
+    {
+        9,  -95,  -95,  -95,  -95,  -95,  -95,  -95,  -95,  -95,
+      -95,  -95,  -95,  -95,  -95,  -95,  -95,  -95,  -95,  -95,
+      -95,  -95,  -95,  -95,  -95,  -95,  -95,  -95,  -95,  -95,
+      -95,  -95,  -95,  -95,  -95,  -95,  -95,  -95,  -95,  -95,
+      -95,  -95
+
+    },
+
+    {
+        9,  -96,  -96,  -96,  -96,  -96,  -96,   56,  -96,  -96,
+      -96,  -96,  -96,   59,  -96,  -96,  -96,  -96,  -96,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,  119,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,  -96
+    },
+
+    {
+        9,  -97,  -97,  -97,  -97,  -97,  -97,   56,  -97,  -97,
+      -97,  -97,  -97,   59,  -97,  -97,  -97,  -97,  -97,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,  120,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,  -97
+
+    },
+
+    {
+        9,  -98,  -98,  -98,  -98,  -98,  -98,   56,  -98,  -98,
+      -98,  -98,  -98,   59,  -98,  -98,  -98,  -98,  -98,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,  121,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,  -98
+    },
+
+    {
+        9,  -99,  -99,  -99,  -99,  -99,  -99,   56,  -99,  -99,
+      -99,  -99,  -99,   59,  -99,  -99,  -99,  -99,  -99,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+      122,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,  -99
+
+    },
+
+    {
+        9, -100, -100, -100, -100, -100, -100,   56, -100, -100,
+     -100, -100, -100,   59, -100, -100, -100, -100, -100,   59,
+       59,   59,   59,   59,   59,  123,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -100
+    },
+
+    {
+        9, -101, -101, -101, -101, -101, -101,   56, -101, -101,
+     -101, -101, -101,   59, -101, -101, -101, -101, -101,  124,
+      125,   59,  126,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -101
+
+    },
+
+    {
+        9, -102, -102, -102, -102, -102, -102,   56, -102, -102,
+     -102, -102, -102,   59, -102, -102, -102, -102, -102,   59,
+       59,   59,   59,   59,  127,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -102
+    },
+
+    {
+        9, -103, -103, -103, -103, -103, -103,   56, -103, -103,
+     -103, -103, -103,   59, -103, -103, -103, -103, -103,   59,
+       59,   59,  128,   59,   59,   59,   59,   59,  129,   59,
+      130,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -103
+
+    },
+
+    {
+        9, -104, -104, -104, -104, -104, -104,   56, -104, -104,
+     -104, -104, -104,   59, -104, -104, -104, -104, -104,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,  131,   59,   59,   59,   59,   59,   59,
+       59, -104
+    },
+
+    {
+        9, -105, -105, -105, -105, -105, -105,   56, -105, -105,
+     -105, -105, -105,   59, -105, -105, -105, -105, -105,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -105
+
+    },
+
+    {
+        9, -106, -106, -106, -106, -106, -106,   56, -106, -106,
+     -106, -106, -106,   59, -106, -106, -106, -106, -106,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,  132,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -106
+    },
+
+    {
+        9, -107, -107, -107, -107, -107, -107,   56, -107, -107,
+     -107, -107, -107,   59, -107, -107, -107, -107, -107,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -107
+
+    },
+
+    {
+        9, -108, -108, -108, -108, -108, -108,   56, -108, -108,
+     -108, -108, -108,   59, -108, -108, -108, -108, -108,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,  133,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -108
+    },
+
+    {
+        9, -109, -109, -109, -109, -109, -109,   56, -109, -109,
+     -109, -109, -109,   59, -109, -109, -109, -109, -109,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,  134,   59,   59,
+       59, -109
+
+    },
+
+    {
+        9, -110, -110, -110, -110, -110, -110,   56, -110, -110,
+     -110, -110, -110,   59, -110, -110, -110, -110, -110,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,  135,   59,   59,
+       59, -110
+    },
+
+    {
+        9, -111, -111, -111, -111, -111, -111,   56, -111, -111,
+     -111, -111, -111,   59, -111, -111, -111, -111, -111,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,  136,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -111
+
+    },
+
+    {
+        9, -112, -112, -112, -112, -112, -112,   56, -112, -112,
+     -112, -112, -112,   59, -112, -112, -112, -112, -112,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+      137,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -112
+    },
+
+    {
+        9, -113, -113, -113, -113, -113, -113,   56, -113, -113,
+     -113, -113, -113,   59, -113, -113, -113, -113, -113,   59,
+       59,   59,   59,   59,   59,   59,  138,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -113
+
+    },
+
+    {
+        9, -114, -114, -114, -114, -114, -114,   56, -114, -114,
+     -114, -114, -114,   59, -114, -114, -114, -114, -114,   59,
+       59,   59,   59,   59,  139,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -114
+    },
+
+    {
+        9, -115, -115, -115, -115, -115, -115,   56, -115, -115,
+     -115, -115, -115,   59, -115, -115, -115, -115, -115,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,  140,   59,   59,   59,   59,   59,
+       59, -115
+
+    },
+
+    {
+        9, -116, -116, -116, -116, -116, -116,   56, -116, -116,
+     -116, -116, -116,   59, -116, -116, -116, -116, -116,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,  141,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -116
+    },
+
+    {
+        9, -117, -117, -117, -117, -117, -117,   56, -117, -117,
+     -117, -117, -117,   59, -117, -117, -117, -117, -117,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,  142,   59,   59,   59,   59,
+       59, -117
+
+    },
+
+    {
+        9, -118, -118, -118, -118, -118, -118,   56, -118, -118,
+     -118, -118, -118,   59, -118, -118, -118, -118, -118,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,  143,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -118
+    },
+
+    {
+        9, -119, -119, -119, -119, -119, -119,   56, -119, -119,
+     -119, -119, -119,   59, -119, -119, -119, -119, -119,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,  144,   59,   59,   59,   59,   59,   59,   59,
+       59, -119
+
+    },
+
+    {
+        9, -120, -120, -120, -120, -120, -120,   56, -120, -120,
+     -120, -120, -120,   59, -120, -120, -120, -120, -120,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -120
+    },
+
+    {
+        9, -121, -121, -121, -121, -121, -121,   56, -121, -121,
+     -121, -121, -121,   59, -121, -121, -121, -121, -121,   59,
+       59,   59,  145,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -121
+
+    },
+
+    {
+        9, -122, -122, -122, -122, -122, -122,   56, -122, -122,
+     -122, -122, -122,   59, -122, -122, -122, -122, -122,   59,
+       59,   59,   59,   59,  146,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -122
+    },
+
+    {
+        9, -123, -123, -123, -123, -123, -123,   56, -123, -123,
+     -123, -123, -123,   59, -123, -123, -123, -123, -123,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,  147,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -123
+
+    },
+
+    {
+        9, -124, -124, -124, -124, -124, -124,   56, -124, -124,
+     -124, -124, -124,   59, -124, -124, -124, -124, -124,   59,
+       59,  148,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,  149,   59,   59,   59,
+       59, -124
+    },
+
+    {
+        9, -125, -125, -125, -125, -125, -125,   56, -125, -125,
+     -125, -125, -125,   59, -125, -125, -125, -125, -125,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,  150,   59,   59,
+       59, -125
+
+    },
+
+    {
+        9, -126, -126, -126, -126, -126, -126,   56, -126, -126,
+     -126, -126, -126,   59, -126, -126, -126, -126, -126,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,  151,   59,   59,   59,   59,   59,   59,   59,
+       59, -126
+    },
+
+    {
+        9, -127, -127, -127, -127, -127, -127,   56, -127, -127,
+     -127, -127, -127,   59, -127, -127, -127, -127, -127,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,  152,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -127
+
+    },
+
+    {
+        9, -128, -128, -128, -128, -128, -128,   56, -128, -128,
+     -128, -128, -128,   59, -128, -128, -128, -128, -128,   59,
+       59,   59,   59,   59,   59,   59,   59,  153,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -128
+    },
+
+    {
+        9, -129, -129, -129, -129, -129, -129,   56, -129, -129,
+     -129, -129, -129,   59, -129, -129, -129, -129, -129,   59,
+       59,   59,   59,   59,   59,  154,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -129
+
+    },
+
+    {
+        9, -130, -130, -130, -130, -130, -130,   56, -130, -130,
+     -130, -130, -130,   59, -130, -130, -130, -130, -130,   59,
+       59,   59,   59,   59,  155,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -130
+    },
+
+    {
+        9, -131, -131, -131, -131, -131, -131,   56, -131, -131,
+     -131, -131, -131,   59, -131, -131, -131, -131, -131,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -131
+
+    },
+
+    {
+        9, -132, -132, -132, -132, -132, -132,   56, -132, -132,
+     -132, -132, -132,   59, -132, -132, -132, -132, -132,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+      156, -132
+    },
+
+    {
+        9, -133, -133, -133, -133, -133, -133,   56, -133, -133,
+     -133, -133, -133,   59, -133, -133, -133, -133, -133,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+      157,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -133
+
+    },
+
+    {
+        9, -134, -134, -134, -134, -134, -134,   56, -134, -134,
+     -134, -134, -134,   59, -134, -134, -134, -134, -134,   59,
+       59,   59,  158,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -134
+    },
+
+    {
+        9, -135, -135, -135, -135, -135, -135,   56, -135, -135,
+     -135, -135, -135,   59, -135, -135, -135, -135, -135,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,  159,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -135
+
+    },
+
+    {
+        9, -136, -136, -136, -136, -136, -136,   56, -136, -136,
+     -136, -136, -136,   59, -136, -136, -136, -136, -136,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,  160,   59,   59,   59,   59,   59,   59,   59,
+       59, -136
+    },
+
+    {
+        9, -137, -137, -137, -137, -137, -137,   56, -137, -137,
+     -137, -137, -137,   59, -137, -137, -137, -137, -137,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,  161,   59,   59,   59,   59,   59,   59,
+       59, -137
+
+    },
+
+    {
+        9, -138, -138, -138, -138, -138, -138,   56, -138, -138,
+     -138, -138, -138,   59, -138, -138, -138, -138, -138,   59,
+       59,   59,   59,   59,  162,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -138
+    },
+
+    {
+        9, -139, -139, -139, -139, -139, -139,   56, -139, -139,
+     -139, -139, -139,   59, -139, -139, -139, -139, -139,   59,
+       59,   59,  163,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -139
+
+    },
+
+    {
+        9, -140, -140, -140, -140, -140, -140,   56, -140, -140,
+     -140, -140, -140,   59, -140, -140, -140, -140, -140,   59,
+       59,   59,  164,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -140
+    },
+
+    {
+        9, -141, -141, -141, -141, -141, -141,   56, -141, -141,
+     -141, -141, -141,   59, -141, -141, -141, -141, -141,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,  165,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -141
+
+    },
+
+    {
+        9, -142, -142, -142, -142, -142, -142,   56, -142, -142,
+     -142, -142, -142,   59, -142, -142, -142, -142, -142,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,  166,   59,   59,   59,
+       59, -142
+    },
+
+    {
+        9, -143, -143, -143, -143, -143, -143,   56, -143, -143,
+     -143, -143, -143,   59, -143, -143, -143, -143, -143,   59,
+       59,  167,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -143
+
+    },
+
+    {
+        9, -144, -144, -144, -144, -144, -144,   56, -144, -144,
+     -144, -144, -144,   59, -144, -144, -144, -144, -144,   59,
+       59,   59,  168,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -144
+    },
+
+    {
+        9, -145, -145, -145, -145, -145, -145,   56, -145, -145,
+     -145, -145, -145,   59, -145, -145, -145, -145, -145,   59,
+       59,   59,   59,   59,  169,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -145
+
+    },
+
+    {
+        9, -146, -146, -146, -146, -146, -146,   56, -146, -146,
+     -146, -146, -146,   59, -146, -146, -146, -146, -146,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,  170,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -146
+    },
+
+    {
+        9, -147, -147, -147, -147, -147, -147,   56, -147, -147,
+     -147, -147, -147,   59, -147, -147, -147, -147, -147,   59,
+       59,   59,   59,   59,   59,   59,  171,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -147
+
+    },
+
+    {
+        9, -148, -148, -148, -148, -148, -148,   56, -148, -148,
+     -148, -148, -148,   59, -148, -148, -148, -148, -148,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,  172,   59,   59,   59,   59,   59,   59,   59,
+       59, -148
+    },
+
+    {
+        9, -149, -149, -149, -149, -149, -149,   56, -149, -149,
+     -149, -149, -149,   59, -149, -149, -149, -149, -149,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,  173,   59,   59,   59,   59,   59,
+       59, -149
+
+    },
+
+    {
+        9, -150, -150, -150, -150, -150, -150,   56, -150, -150,
+     -150, -150, -150,   59, -150, -150, -150, -150, -150,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,  174,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -150
+    },
+
+    {
+        9, -151, -151, -151, -151, -151, -151,   56, -151, -151,
+     -151, -151, -151,   59, -151, -151, -151, -151, -151,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,  175,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -151
+
+    },
+
+    {
+        9, -152, -152, -152, -152, -152, -152,   56, -152, -152,
+     -152, -152, -152,   59, -152, -152, -152, -152, -152,   59,
+       59,   59,   59,  176,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -152
+    },
+
+    {
+        9, -153, -153, -153, -153, -153, -153,   56, -153, -153,
+     -153, -153, -153,   59, -153, -153, -153, -153, -153,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,  177,   59,   59,   59,   59,   59,   59,   59,
+       59, -153
+
+    },
+
+    {
+        9, -154, -154, -154, -154, -154, -154,   56, -154, -154,
+     -154, -154, -154,   59, -154, -154, -154, -154, -154,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -154
+    },
+
+    {
+        9, -155, -155, -155, -155, -155, -155,   56, -155, -155,
+     -155, -155, -155,   59, -155, -155, -155, -155, -155,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,  178,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -155
+
+    },
+
+    {
+        9, -156, -156, -156, -156, -156, -156,   56, -156, -156,
+     -156, -156, -156,   59, -156, -156, -156, -156, -156,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -156
+    },
+
+    {
+        9, -157, -157, -157, -157, -157, -157,   56, -157, -157,
+     -157, -157, -157,   59, -157, -157, -157, -157, -157,   59,
+       59,   59,   59,   59,  179,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -157
+
+    },
+
+    {
+        9, -158, -158, -158, -158, -158, -158,   56, -158, -158,
+     -158, -158, -158,   59, -158, -158, -158, -158, -158,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,  180,   59,   59,   59,   59,   59,   59,   59,
+       59, -158
+    },
+
+    {
+        9, -159, -159, -159, -159, -159, -159,   56, -159, -159,
+     -159, -159, -159,   59, -159, -159, -159, -159, -159,   59,
+       59,   59,   59,   59,  181,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -159
+
+    },
+
+    {
+        9, -160, -160, -160, -160, -160, -160,   56, -160, -160,
+     -160, -160, -160,   59, -160, -160, -160, -160, -160,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,  182,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -160
+    },
+
+    {
+        9, -161, -161, -161, -161, -161, -161,   56, -161, -161,
+     -161, -161, -161,   59, -161, -161, -161, -161, -161,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,  183,   59,   59,   59,
+       59, -161
+
+    },
+
+    {
+        9, -162, -162, -162, -162, -162, -162,   56, -162, -162,
+     -162, -162, -162,   59, -162, -162, -162, -162, -162,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -162
+    },
+
+    {
+        9, -163, -163, -163, -163, -163, -163,   56, -163, -163,
+     -163, -163, -163,   59, -163, -163, -163, -163, -163,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,  184,   59,   59,   59,
+       59, -163
+
+    },
+
+    {
+        9, -164, -164, -164, -164, -164, -164,   56, -164, -164,
+     -164, -164, -164,   59, -164, -164, -164, -164, -164,   59,
+       59,   59,   59,   59,  185,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -164
+    },
+
+    {
+        9, -165, -165, -165, -165, -165, -165,   56, -165, -165,
+     -165, -165, -165,   59, -165, -165, -165, -165, -165,   59,
+       59,   59,   59,   59,   59,   59,  186,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -165
+
+    },
+
+    {
+        9, -166, -166, -166, -166, -166, -166,   56, -166, -166,
+     -166, -166, -166,   59, -166, -166, -166, -166, -166,   59,
+      187,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -166
+    },
+
+    {
+        9, -167, -167, -167, -167, -167, -167,   56, -167, -167,
+     -167, -167, -167,   59, -167, -167, -167, -167, -167,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,  188,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -167
+
+    },
+
+    {
+        9, -168, -168, -168, -168, -168, -168,   56, -168, -168,
+     -168, -168, -168,   59, -168, -168, -168, -168, -168,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,  189,   59,   59,   59,   59,   59,   59,   59,
+       59, -168
+    },
+
+    {
+        9, -169, -169, -169, -169, -169, -169,   56, -169, -169,
+     -169, -169, -169,   59, -169, -169, -169, -169, -169,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -169
+
+    },
+
+    {
+        9, -170, -170, -170, -170, -170, -170,   56, -170, -170,
+     -170, -170, -170,   59, -170, -170, -170, -170, -170,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,  190,   59,   59,   59,
+       59, -170
+    },
+
+    {
+        9, -171, -171, -171, -171, -171, -171,   56, -171, -171,
+     -171, -171, -171,   59, -171, -171, -171, -171, -171,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -171
+
+    },
+
+    {
+        9, -172, -172, -172, -172, -172, -172,   56, -172, -172,
+     -172, -172, -172,   59, -172, -172, -172, -172, -172,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,  191,   59,   59,   59,   59,   59,   59,   59,
+       59, -172
+    },
+
+    {
+        9, -173, -173, -173, -173, -173, -173,   56, -173, -173,
+     -173, -173, -173,   59, -173, -173, -173, -173, -173,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,  192,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -173
+
+    },
+
+    {
+        9, -174, -174, -174, -174, -174, -174,   56, -174, -174,
+     -174, -174, -174,   59, -174, -174, -174, -174, -174,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,  193,   59,   59,   59,
+       59, -174
+    },
+
+    {
+        9, -175, -175, -175, -175, -175, -175,   56, -175, -175,
+     -175, -175, -175,   59, -175, -175, -175, -175, -175,   59,
+       59,   59,   59,   59,   59,  194,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -175
+
+    },
+
+    {
+        9, -176, -176, -176, -176, -176, -176,   56, -176, -176,
+     -176, -176, -176,   59, -176, -176, -176, -176, -176,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,  195,   59,   59,   59,   59,
+       59, -176
+    },
+
+    {
+        9, -177, -177, -177, -177, -177, -177,   56, -177, -177,
+     -177, -177, -177,   59, -177, -177, -177, -177, -177,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,  196,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -177
+
+    },
+
+    {
+        9, -178, -178, -178, -178, -178, -178,   56, -178, -178,
+     -178, -178, -178,   59, -178, -178, -178, -178, -178,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,  197,   59,   59,
+       59, -178
+    },
+
+    {
+        9, -179, -179, -179, -179, -179, -179,   56, -179, -179,
+     -179, -179, -179,   59, -179, -179, -179, -179, -179,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,  198,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -179
+
+    },
+
+    {
+        9, -180, -180, -180, -180, -180, -180,   56, -180, -180,
+     -180, -180, -180,   59, -180, -180, -180, -180, -180,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,  199,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -180
+    },
+
+    {
+        9, -181, -181, -181, -181, -181, -181,   56, -181, -181,
+     -181, -181, -181,   59, -181, -181, -181, -181, -181,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,  200,   59,   59,   59,   59,
+       59, -181
+
+    },
+
+    {
+        9, -182, -182, -182, -182, -182, -182,   56, -182, -182,
+     -182, -182, -182,   59, -182, -182, -182, -182, -182,   59,
+      201,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -182
+    },
+
+    {
+        9, -183, -183, -183, -183, -183, -183,   56, -183, -183,
+     -183, -183, -183,   59, -183, -183, -183, -183, -183,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -183
+
+    },
+
+    {
+        9, -184, -184, -184, -184, -184, -184,   56, -184, -184,
+     -184, -184, -184,   59, -184, -184, -184, -184, -184,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -184
+    },
+
+    {
+        9, -185, -185, -185, -185, -185, -185,   56, -185, -185,
+     -185, -185, -185,   59, -185, -185, -185, -185, -185,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -185
+
+    },
+
+    {
+        9, -186, -186, -186, -186, -186, -186,   56, -186, -186,
+     -186, -186, -186,   59, -186, -186, -186, -186, -186,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -186
+    },
+
+    {
+        9, -187, -187, -187, -187, -187, -187,   56, -187, -187,
+     -187, -187, -187,   59, -187, -187, -187, -187, -187,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,  202,   59,   59,   59,
+       59, -187
+
+    },
+
+    {
+        9, -188, -188, -188, -188, -188, -188,   56, -188, -188,
+     -188, -188, -188,   59, -188, -188, -188, -188, -188,   59,
+       59,   59,   59,   59,  203,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -188
+    },
+
+    {
+        9, -189, -189, -189, -189, -189, -189,   56, -189, -189,
+     -189, -189, -189,   59, -189, -189, -189, -189, -189,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,  204,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -189
+
+    },
+
+    {
+        9, -190, -190, -190, -190, -190, -190,   56, -190, -190,
+     -190, -190, -190,   59, -190, -190, -190, -190, -190,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -190
+    },
+
+    {
+        9, -191, -191, -191, -191, -191, -191,   56, -191, -191,
+     -191, -191, -191,   59, -191, -191, -191, -191, -191,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,  205,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -191
+
+    },
+
+    {
+        9, -192, -192, -192, -192, -192, -192,   56, -192, -192,
+     -192, -192, -192,   59, -192, -192, -192, -192, -192,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,  206,   59,   59,   59,   59,
+       59, -192
+    },
+
+    {
+        9, -193, -193, -193, -193, -193, -193,   56, -193, -193,
+     -193, -193, -193,   59, -193, -193, -193, -193, -193,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -193
+
+    },
+
+    {
+        9, -194, -194, -194, -194, -194, -194,   56, -194, -194,
+     -194, -194, -194,   59, -194, -194, -194, -194, -194,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,  207,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -194
+    },
+
+    {
+        9, -195, -195, -195, -195, -195, -195,   56, -195, -195,
+     -195, -195, -195,   59, -195, -195, -195, -195, -195,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -195
+
+    },
+
+    {
+        9, -196, -196, -196, -196, -196, -196,   56, -196, -196,
+     -196, -196, -196,   59, -196, -196, -196, -196, -196,   59,
+       59,   59,  208,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -196
+    },
+
+    {
+        9, -197, -197, -197, -197, -197, -197,   56, -197, -197,
+     -197, -197, -197,   59, -197, -197, -197, -197, -197,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -197
+
+    },
+
+    {
+        9, -198, -198, -198, -198, -198, -198,   56, -198, -198,
+     -198, -198, -198,   59, -198, -198, -198, -198, -198,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,  209,   59,   59,
+       59, -198
+    },
+
+    {
+        9, -199, -199, -199, -199, -199, -199,   56, -199, -199,
+     -199, -199, -199,   59, -199, -199, -199, -199, -199,   59,
+       59,   59,   59,   59,   59,  210,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -199
+
+    },
+
+    {
+        9, -200, -200, -200, -200, -200, -200,   56, -200, -200,
+     -200, -200, -200,   59, -200, -200, -200, -200, -200,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -200
+    },
+
+    {
+        9, -201, -201, -201, -201, -201, -201,   56, -201, -201,
+     -201, -201, -201,   59, -201, -201, -201, -201, -201,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,  211,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -201
+
+    },
+
+    {
+        9, -202, -202, -202, -202, -202, -202,   56, -202, -202,
+     -202, -202, -202,   59, -202, -202, -202, -202, -202,   59,
+       59,   59,   59,   59,  212,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -202
+    },
+
+    {
+        9, -203, -203, -203, -203, -203, -203,   56, -203, -203,
+     -203, -203, -203,   59, -203, -203, -203, -203, -203,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -203
+
+    },
+
+    {
+        9, -204, -204, -204, -204, -204, -204,   56, -204, -204,
+     -204, -204, -204,   59, -204, -204, -204, -204, -204,   59,
+       59,   59,   59,   59,   59,  213,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -204
+    },
+
+    {
+        9, -205, -205, -205, -205, -205, -205,   56, -205, -205,
+     -205, -205, -205,   59, -205, -205, -205, -205, -205,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -205
+
+    },
+
+    {
+        9, -206, -206, -206, -206, -206, -206,   56, -206, -206,
+     -206, -206, -206,   59, -206, -206, -206, -206, -206,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,  214,   59,   59,   59,
+       59, -206
+    },
+
+    {
+        9, -207, -207, -207, -207, -207, -207,   56, -207, -207,
+     -207, -207, -207,   59, -207, -207, -207, -207, -207,   59,
+       59,   59,   59,   59,   59,   59,  215,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -207
+
+    },
+
+    {
+        9, -208, -208, -208, -208, -208, -208,   56, -208, -208,
+     -208, -208, -208,   59, -208, -208, -208, -208, -208,   59,
+       59,   59,   59,   59,  216,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -208
+    },
+
+    {
+        9, -209, -209, -209, -209, -209, -209,   56, -209, -209,
+     -209, -209, -209,   59, -209, -209, -209, -209, -209,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -209
+
+    },
+
+    {
+        9, -210, -210, -210, -210, -210, -210,   56, -210, -210,
+     -210, -210, -210,   59, -210, -210, -210, -210, -210,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,  217,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -210
+    },
+
+    {
+        9, -211, -211, -211, -211, -211, -211,   56, -211, -211,
+     -211, -211, -211,   59, -211, -211, -211, -211, -211,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -211
+
+    },
+
+    {
+        9, -212, -212, -212, -212, -212, -212,   56, -212, -212,
+     -212, -212, -212,   59, -212, -212, -212, -212, -212,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -212
+    },
+
+    {
+        9, -213, -213, -213, -213, -213, -213,   56, -213, -213,
+     -213, -213, -213,   59, -213, -213, -213, -213, -213,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,  218,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -213
+
+    },
+
+    {
+        9, -214, -214, -214, -214, -214, -214,   56, -214, -214,
+     -214, -214, -214,   59, -214, -214, -214, -214, -214,   59,
+      219,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -214
+    },
+
+    {
+        9, -215, -215, -215, -215, -215, -215,   56, -215, -215,
+     -215, -215, -215,   59, -215, -215, -215, -215, -215,  220,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -215
+
+    },
+
+    {
+        9, -216, -216, -216, -216, -216, -216,   56, -216, -216,
+     -216, -216, -216,   59, -216, -216, -216, -216, -216,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -216
+    },
+
+    {
+        9, -217, -217, -217, -217, -217, -217,   56, -217, -217,
+     -217, -217, -217,   59, -217, -217, -217, -217, -217,   59,
+       59,   59,   59,   59,   59,   59,  221,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -217
+
+    },
+
+    {
+        9, -218, -218, -218, -218, -218, -218,   56, -218, -218,
+     -218, -218, -218,   59, -218, -218, -218, -218, -218,   59,
+       59,   59,   59,   59,   59,   59,  222,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -218
+    },
+
+    {
+        9, -219, -219, -219, -219, -219, -219,   56, -219, -219,
+     -219, -219, -219,   59, -219, -219, -219, -219, -219,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,  223,   59,   59,   59,
+       59, -219
+
+    },
+
+    {
+        9, -220, -220, -220, -220, -220, -220,   56, -220, -220,
+     -220, -220, -220,   59, -220, -220, -220, -220, -220,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,  224,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -220
+    },
+
+    {
+        9, -221, -221, -221, -221, -221, -221,   56, -221, -221,
+     -221, -221, -221,   59, -221, -221, -221, -221, -221,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -221
+
+    },
+
+    {
+        9, -222, -222, -222, -222, -222, -222,   56, -222, -222,
+     -222, -222, -222,   59, -222, -222, -222, -222, -222,  225,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -222
+    },
+
+    {
+        9, -223, -223, -223, -223, -223, -223,   56, -223, -223,
+     -223, -223, -223,   59, -223, -223, -223, -223, -223,   59,
+       59,   59,   59,   59,  226,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -223
+
+    },
+
+    {
+        9, -224, -224, -224, -224, -224, -224,   56, -224, -224,
+     -224, -224, -224,   59, -224, -224, -224, -224, -224,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,  227,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -224
+    },
+
+    {
+        9, -225, -225, -225, -225, -225, -225,   56, -225, -225,
+     -225, -225, -225,   59, -225, -225, -225, -225, -225,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+      228, -225
+
+    },
+
+    {
+        9, -226, -226, -226, -226, -226, -226,   56, -226, -226,
+     -226, -226, -226,   59, -226, -226, -226, -226, -226,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -226
+    },
+
+    {
+        9, -227, -227, -227, -227, -227, -227,   56, -227, -227,
+     -227, -227, -227,   59, -227, -227, -227, -227, -227,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,  229,   59,   59,   59,   59,
+       59, -227
+
+    },
+
+    {
+        9, -228, -228, -228, -228, -228, -228,   56, -228, -228,
+     -228, -228, -228,   59, -228, -228, -228, -228, -228,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -228
+    },
+
+    {
+        9, -229, -229, -229, -229, -229, -229,   56, -229, -229,
+     -229, -229, -229,   59, -229, -229, -229, -229, -229,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,  230,   59,   59,   59,
+       59, -229
+
+    },
+
+    {
+        9, -230, -230, -230, -230, -230, -230,   56, -230, -230,
+     -230, -230, -230,   59, -230, -230, -230, -230, -230,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   59,
+       59, -230
+    },
+
+    } ;
+
+static yy_state_type yy_get_previous_state ( void );
+static yy_state_type yy_try_NUL_trans ( yy_state_type current_state  );
+static int yy_get_next_buffer ( void );
+static void yynoreturn yy_fatal_error ( const char* msg  );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+	(yytext_ptr) = yy_bp; \
+	yyleng = (int) (yy_cp - yy_bp); \
+	(yy_hold_char) = *yy_cp; \
+	*yy_cp = '\0'; \
+	(yy_c_buf_p) = yy_cp;
+#define YY_NUM_RULES 66
+#define YY_END_OF_BUFFER 67
+/* This struct is not used in this scanner,
+   but its presence is necessary. */
+struct yy_trans_info
+	{
+	flex_int32_t yy_verify;
+	flex_int32_t yy_nxt;
+	};
+static const flex_int16_t yy_accept[231] =
+    {   0,
+        2,    2,    0,    0,    0,    0,    0,    0,   67,   53,
+        2,    4,   45,   50,    1,   52,   53,   46,   47,   53,
+       51,   53,   41,   39,   43,   53,   51,   51,   51,   51,
+       51,   51,   51,   51,   51,   51,   51,   51,   51,   51,
+       53,   54,   56,   55,   65,   62,   64,   58,   61,   60,
+       57,   59,    2,   40,    1,   52,   38,   49,   51,   48,
+       42,   44,    3,   51,   51,   51,   51,   51,   51,   51,
+       20,   51,   51,   51,   51,   51,   27,   51,   51,   51,
+       51,   51,   51,   51,   51,   37,   54,   54,   65,   62,
+       64,   63,   58,   57,   59,   51,   51,   51,   51,   51,
+
+       51,   51,   51,   51,   19,   51,   22,   51,   51,   51,
+       51,   51,   51,   51,   51,   51,   51,   51,   51,    6,
+       51,   51,   51,   51,   51,   51,   51,   51,   51,   51,
+       18,   51,   51,   24,   51,   51,   51,   51,   51,   51,
+       51,   51,   51,   51,   51,   51,   51,   51,   51,   51,
+       51,   51,   51,   16,   51,   21,   51,   51,   51,   51,
+       51,   31,   51,   51,   51,   51,   51,   51,    7,   51,
+        9,   51,   51,   51,   51,   51,   51,   51,   51,   51,
+       51,   28,   30,   32,   33,   34,   51,   51,   51,    8,
+       51,   51,   12,   51,   14,   51,   17,   51,   51,   26,
+
+       51,   51,   36,   51,   10,   51,   51,   51,   23,   51,
+       29,   35,   51,   51,   51,   15,   51,   51,   51,   51,
+       25,   51,   51,   51,   51,   11,   51,    5,   51,   13
+    } ;
+
+static const YY_CHAR yy_ec[256] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    2,    4,    5,    6,    7,    1,    8,    9,   10,
+       11,    1,   12,    1,   13,    1,    1,   13,   13,   13,
+       13,   13,   13,   13,   13,   13,   13,   14,    1,   15,
+       16,   17,    1,    1,   13,   13,   13,   13,   13,   13,
+       13,   13,   13,   13,   13,   13,   13,   13,   13,   13,
+       13,   13,   13,   13,   13,   13,   13,   13,   13,   13,
+        1,   18,    1,    1,   19,    1,   20,   21,   22,   23,
+
+       24,   25,   26,   27,   28,   13,   13,   29,   30,   31,
+       32,   33,   13,   34,   35,   36,   37,   38,   13,   39,
+       40,   13,    1,   41,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1
+    } ;
+
+/* Table of booleans, true if rule could match eol. */
+static const flex_int32_t yy_rule_can_match_eol[67] =
+    {   0,
+0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 
+    0, 1, 0, 1, 1, 0, 0,     };
+
+extern int yy_flex_debug;
+int yy_flex_debug = 0;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ */
+
+#include <assert.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "lkc.h"
+#include "parser.tab.h"
+
+#define YY_DECL		static int yylex1(void)
+
+#define START_STRSIZE	16
+
+static struct {
+	struct file *file;
+	int lineno;
+} current_pos;
+
+static int prev_prev_token = T_EOL;
+static int prev_token = T_EOL;
+static char *text;
+static int text_size, text_asize;
+
+struct buffer {
+	struct buffer *parent;
+	YY_BUFFER_STATE state;
+};
+
+static struct buffer *current_buf;
+
+static int last_ts, first_ts;
+
+static char *expand_token(const char *in, size_t n);
+static void append_expanded_string(const char *in);
+static void zconf_endhelp(void);
+static void zconf_endfile(void);
+
+static void new_string(void)
+{
+	text = xmalloc(START_STRSIZE);
+	text_asize = START_STRSIZE;
+	text_size = 0;
+	*text = 0;
+}
+
+static void append_string(const char *str, int size)
+{
+	int new_size = text_size + size + 1;
+	if (new_size > text_asize) {
+		new_size += START_STRSIZE - 1;
+		new_size &= -START_STRSIZE;
+		text = xrealloc(text, new_size);
+		text_asize = new_size;
+	}
+	memcpy(text + text_size, str, size);
+	text_size += size;
+	text[text_size] = 0;
+}
+
+static void alloc_string(const char *str, int size)
+{
+	text = xmalloc(size + 1);
+	memcpy(text, str, size);
+	text[size] = 0;
+}
+
+static void warn_ignored_character(char chr)
+{
+	fprintf(stderr,
+	        "%s:%d:warning: ignoring unsupported character '%c'\n",
+	        current_file->name, yylineno, chr);
+}
+
+#define INITIAL 0
+#define ASSIGN_VAL 1
+#define HELP 2
+#define STRING 3
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+static int yy_init_globals ( void );
+
+/* Accessor methods to globals.
+   These are made visible to non-reentrant scanners for convenience. */
+
+int yylex_destroy ( void );
+
+int yyget_debug ( void );
+
+void yyset_debug ( int debug_flag  );
+
+YY_EXTRA_TYPE yyget_extra ( void );
+
+void yyset_extra ( YY_EXTRA_TYPE user_defined  );
+
+FILE *yyget_in ( void );
+
+void yyset_in  ( FILE * _in_str  );
+
+FILE *yyget_out ( void );
+
+void yyset_out  ( FILE * _out_str  );
+
+			int yyget_leng ( void );
+
+char *yyget_text ( void );
+
+int yyget_lineno ( void );
+
+void yyset_lineno ( int _line_number  );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap ( void );
+#else
+extern int yywrap ( void );
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+    
+    static void yyunput ( int c, char *buf_ptr  );
+    
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy ( char *, const char *, int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen ( const char * );
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput ( void );
+#else
+static int input ( void );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k */
+#define YY_READ_BUF_SIZE 16384
+#else
+#define YY_READ_BUF_SIZE 8192
+#endif /* __ia64__ */
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0)
+#endif
+
+/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+	errno=0; \
+	while ( (result = (int) read( fileno(yyin), buf, (yy_size_t) max_size )) < 0 ) \
+	{ \
+		if( errno != EINTR) \
+		{ \
+			YY_FATAL_ERROR( "input in flex scanner failed" ); \
+			break; \
+		} \
+		errno=0; \
+		clearerr(yyin); \
+	}\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int yylex (void);
+
+#define YY_DECL int yylex (void)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK /*LINTED*/break;
+#endif
+
+#define YY_RULE_SETUP \
+	YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+	yy_state_type yy_current_state;
+	char *yy_cp, *yy_bp;
+	int yy_act;
+    
+	if ( !(yy_init) )
+		{
+		(yy_init) = 1;
+
+#ifdef YY_USER_INIT
+		YY_USER_INIT;
+#endif
+
+		if ( ! (yy_start) )
+			(yy_start) = 1;	/* first start state */
+
+		if ( ! yyin )
+			yyin = stdin;
+
+		if ( ! yyout )
+			yyout = stdout;
+
+		if ( ! YY_CURRENT_BUFFER ) {
+			yyensure_buffer_stack ();
+			YY_CURRENT_BUFFER_LVALUE =
+				yy_create_buffer( yyin, YY_BUF_SIZE );
+		}
+
+		yy_load_buffer_state(  );
+		}
+
+	{
+
+	int str = 0;
+	int ts, i;
+
+	while ( /*CONSTCOND*/1 )		/* loops until end-of-file is reached */
+		{
+		yy_cp = (yy_c_buf_p);
+
+		/* Support of yytext. */
+		*yy_cp = (yy_hold_char);
+
+		/* yy_bp points to the position in yy_ch_buf of the start of
+		 * the current run.
+		 */
+		yy_bp = yy_cp;
+
+		yy_current_state = (yy_start);
+yy_match:
+		while ( (yy_current_state = yy_nxt[yy_current_state][ yy_ec[YY_SC_TO_UI(*yy_cp)]  \
]) > 0 ) +			++yy_cp;
+
+		yy_current_state = -yy_current_state;
+
+yy_find_action:
+		yy_act = yy_accept[yy_current_state];
+
+		YY_DO_BEFORE_ACTION;
+
+		if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )
+			{
+			int yyl;
+			for ( yyl = 0; yyl < yyleng; ++yyl )
+				if ( yytext[yyl] == '\n' )
+					
+    yylineno++;
+;
+			}
+
+do_action:	/* This label is used only to access EOF actions. */
+
+		switch ( yy_act )
+	{ /* beginning of action switch */
+case 1:
+YY_RULE_SETUP
+/* ignore comment */
+	YY_BREAK
+case 2:
+YY_RULE_SETUP
+/* whitespaces */
+	YY_BREAK
+case 3:
+/* rule 3 can match eol */
+YY_RULE_SETUP
+/* escaped new line */
+	YY_BREAK
+case 4:
+/* rule 4 can match eol */
+YY_RULE_SETUP
+return T_EOL;
+	YY_BREAK
+case 5:
+YY_RULE_SETUP
+return T_ALLNOCONFIG_Y;
+	YY_BREAK
+case 6:
+YY_RULE_SETUP
+return T_BOOL;
+	YY_BREAK
+case 7:
+YY_RULE_SETUP
+return T_CHOICE;
+	YY_BREAK
+case 8:
+YY_RULE_SETUP
+return T_COMMENT;
+	YY_BREAK
+case 9:
+YY_RULE_SETUP
+return T_CONFIG;
+	YY_BREAK
+case 10:
+YY_RULE_SETUP
+return T_DEF_BOOL;
+	YY_BREAK
+case 11:
+YY_RULE_SETUP
+return T_DEF_TRISTATE;
+	YY_BREAK
+case 12:
+YY_RULE_SETUP
+return T_DEFAULT;
+	YY_BREAK
+case 13:
+YY_RULE_SETUP
+return T_DEFCONFIG_LIST;
+	YY_BREAK
+case 14:
+YY_RULE_SETUP
+return T_DEPENDS;
+	YY_BREAK
+case 15:
+YY_RULE_SETUP
+return T_ENDCHOICE;
+	YY_BREAK
+case 16:
+YY_RULE_SETUP
+return T_ENDIF;
+	YY_BREAK
+case 17:
+YY_RULE_SETUP
+return T_ENDMENU;
+	YY_BREAK
+case 18:
+YY_RULE_SETUP
+return T_HELP;
+	YY_BREAK
+case 19:
+YY_RULE_SETUP
+return T_HEX;
+	YY_BREAK
+case 20:
+YY_RULE_SETUP
+return T_IF;
+	YY_BREAK
+case 21:
+YY_RULE_SETUP
+return T_IMPLY;
+	YY_BREAK
+case 22:
+YY_RULE_SETUP
+return T_INT;
+	YY_BREAK
+case 23:
+YY_RULE_SETUP
+return T_MAINMENU;
+	YY_BREAK
+case 24:
+YY_RULE_SETUP
+return T_MENU;
+	YY_BREAK
+case 25:
+YY_RULE_SETUP
+return T_MENUCONFIG;
+	YY_BREAK
+case 26:
+YY_RULE_SETUP
+return T_MODULES;
+	YY_BREAK
+case 27:
+YY_RULE_SETUP
+return T_ON;
+	YY_BREAK
+case 28:
+YY_RULE_SETUP
+return T_OPTION;
+	YY_BREAK
+case 29:
+YY_RULE_SETUP
+return T_OPTIONAL;
+	YY_BREAK
+case 30:
+YY_RULE_SETUP
+return T_PROMPT;
+	YY_BREAK
+case 31:
+YY_RULE_SETUP
+return T_RANGE;
+	YY_BREAK
+case 32:
+YY_RULE_SETUP
+return T_SELECT;
+	YY_BREAK
+case 33:
+YY_RULE_SETUP
+return T_SOURCE;
+	YY_BREAK
+case 34:
+YY_RULE_SETUP
+return T_STRING;
+	YY_BREAK
+case 35:
+YY_RULE_SETUP
+return T_TRISTATE;
+	YY_BREAK
+case 36:
+YY_RULE_SETUP
+return T_VISIBLE;
+	YY_BREAK
+case 37:
+YY_RULE_SETUP
+return T_OR;
+	YY_BREAK
+case 38:
+YY_RULE_SETUP
+return T_AND;
+	YY_BREAK
+case 39:
+YY_RULE_SETUP
+return T_EQUAL;
+	YY_BREAK
+case 40:
+YY_RULE_SETUP
+return T_UNEQUAL;
+	YY_BREAK
+case 41:
+YY_RULE_SETUP
+return T_LESS;
+	YY_BREAK
+case 42:
+YY_RULE_SETUP
+return T_LESS_EQUAL;
+	YY_BREAK
+case 43:
+YY_RULE_SETUP
+return T_GREATER;
+	YY_BREAK
+case 44:
+YY_RULE_SETUP
+return T_GREATER_EQUAL;
+	YY_BREAK
+case 45:
+YY_RULE_SETUP
+return T_NOT;
+	YY_BREAK
+case 46:
+YY_RULE_SETUP
+return T_OPEN_PAREN;
+	YY_BREAK
+case 47:
+YY_RULE_SETUP
+return T_CLOSE_PAREN;
+	YY_BREAK
+case 48:
+YY_RULE_SETUP
+return T_COLON_EQUAL;
+	YY_BREAK
+case 49:
+YY_RULE_SETUP
+return T_PLUS_EQUAL;
+	YY_BREAK
+case 50:
+YY_RULE_SETUP
+{
+				str = yytext[0];
+				new_string();
+				BEGIN(STRING);
+			}
+	YY_BREAK
+case 51:
+YY_RULE_SETUP
+{
+				alloc_string(yytext, yyleng);
+				yylval.string = text;
+				return T_WORD;
+			}
+	YY_BREAK
+case 52:
+YY_RULE_SETUP
+{
+				/* this token includes at least one '$' */
+				yylval.string = expand_token(yytext, yyleng);
+				if (strlen(yylval.string))
+					return T_WORD;
+				free(yylval.string);
+			}
+	YY_BREAK
+case 53:
+YY_RULE_SETUP
+warn_ignored_character(*yytext);
+	YY_BREAK
+
+case 54:
+YY_RULE_SETUP
+{
+		alloc_string(yytext, yyleng);
+		yylval.string = text;
+		return T_ASSIGN_VAL;
+	}
+	YY_BREAK
+case 55:
+/* rule 55 can match eol */
+YY_RULE_SETUP
+{ BEGIN(INITIAL); return T_EOL; }
+	YY_BREAK
+case 56:
+YY_RULE_SETUP
+
+	YY_BREAK
+
+case 57:
+YY_RULE_SETUP
+append_expanded_string(yytext);
+	YY_BREAK
+case 58:
+YY_RULE_SETUP
+{
+		append_string(yytext, yyleng);
+	}
+	YY_BREAK
+case 59:
+YY_RULE_SETUP
+{
+		append_string(yytext + 1, yyleng - 1);
+	}
+	YY_BREAK
+case 60:
+YY_RULE_SETUP
+{
+		if (str == yytext[0]) {
+			BEGIN(INITIAL);
+			yylval.string = text;
+			return T_WORD_QUOTE;
+		} else
+			append_string(yytext, 1);
+	}
+	YY_BREAK
+case 61:
+/* rule 61 can match eol */
+YY_RULE_SETUP
+{
+		fprintf(stderr,
+			"%s:%d:warning: multi-line strings not supported\n",
+			zconf_curname(), zconf_lineno());
+		unput('\n');
+		BEGIN(INITIAL);
+		yylval.string = text;
+		return T_WORD_QUOTE;
+	}
+	YY_BREAK
+case YY_STATE_EOF(STRING):
+{
+		BEGIN(INITIAL);
+		yylval.string = text;
+		return T_WORD_QUOTE;
+	}
+	YY_BREAK
+
+case 62:
+YY_RULE_SETUP
+{
+		ts = 0;
+		for (i = 0; i < yyleng; i++) {
+			if (yytext[i] == '\t')
+				ts = (ts & ~7) + 8;
+			else
+				ts++;
+		}
+		last_ts = ts;
+		if (first_ts) {
+			if (ts < first_ts) {
+				zconf_endhelp();
+				return T_HELPTEXT;
+			}
+			ts -= first_ts;
+			while (ts > 8) {
+				append_string("        ", 8);
+				ts -= 8;
+			}
+			append_string("        ", ts);
+		}
+	}
+	YY_BREAK
+case 63:
+/* rule 63 can match eol */
+*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */
+YY_LINENO_REWIND_TO(yy_cp - 1);
+(yy_c_buf_p) = yy_cp -= 1;
+YY_DO_BEFORE_ACTION; /* set up yytext again */
+YY_RULE_SETUP
+{
+		zconf_endhelp();
+		return T_HELPTEXT;
+	}
+	YY_BREAK
+case 64:
+/* rule 64 can match eol */
+YY_RULE_SETUP
+{
+		append_string("\n", 1);
+	}
+	YY_BREAK
+case 65:
+YY_RULE_SETUP
+{
+		while (yyleng) {
+			if ((yytext[yyleng-1] != ' ') && (yytext[yyleng-1] != '\t'))
+				break;
+			yyleng--;
+		}
+		append_string(yytext, yyleng);
+		if (!first_ts)
+			first_ts = last_ts;
+	}
+	YY_BREAK
+case YY_STATE_EOF(HELP):
+{
+		zconf_endhelp();
+		return T_HELPTEXT;
+	}
+	YY_BREAK
+
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(ASSIGN_VAL):
+{
+	BEGIN(INITIAL);
+
+	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);
+
+	if (current_file) {
+		zconf_endfile();
+		return T_EOL;
+	}
+	fclose(yyin);
+	yyterminate();
+}
+	YY_BREAK
+case 66:
+YY_RULE_SETUP
+YY_FATAL_ERROR( "flex scanner jammed" );
+	YY_BREAK
+
+	case YY_END_OF_BUFFER:
+		{
+		/* Amount of text matched not including the EOB char. */
+		int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+
+		/* Undo the effects of YY_DO_BEFORE_ACTION. */
+		*yy_cp = (yy_hold_char);
+		YY_RESTORE_YY_MORE_OFFSET
+
+		if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+			{
+			/* We're scanning a new file or input source.  It's
+			 * possible that this happened because the user
+			 * just pointed yyin at a new source and called
+			 * yylex().  If so, then we have to assure
+			 * consistency between YY_CURRENT_BUFFER and our
+			 * globals.  Here is the right place to do so, because
+			 * this is the first action (other than possibly a
+			 * back-up) that will match for the new input source.
+			 */
+			(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+			YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+			}
+
+		/* Note that here we test for yy_c_buf_p "<=" to the position
+		 * of the first EOB in the buffer, since yy_c_buf_p will
+		 * already have been incremented past the NUL character
+		 * (since all states make transitions on EOB to the
+		 * end-of-buffer state).  Contrast this with the test
+		 * in input().
+		 */
+		if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+			{ /* This was really a NUL. */
+			yy_state_type yy_next_state;
+
+			(yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+
+			yy_current_state = yy_get_previous_state(  );
+
+			/* Okay, we're now positioned to make the NUL
+			 * transition.  We couldn't have
+			 * yy_get_previous_state() go ahead and do it
+			 * for us because it doesn't know how to deal
+			 * with the possibility of jamming (and we don't
+			 * want to build jamming into it because then it
+			 * will run more slowly).
+			 */
+
+			yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+			yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+
+			if ( yy_next_state )
+				{
+				/* Consume the NUL. */
+				yy_cp = ++(yy_c_buf_p);
+				yy_current_state = yy_next_state;
+				goto yy_match;
+				}
+
+			else
+				{
+				yy_cp = (yy_c_buf_p);
+				goto yy_find_action;
+				}
+			}
+
+		else switch ( yy_get_next_buffer(  ) )
+			{
+			case EOB_ACT_END_OF_FILE:
+				{
+				(yy_did_buffer_switch_on_eof) = 0;
+
+				if ( yywrap(  ) )
+					{
+					/* Note: because we've taken care in
+					 * yy_get_next_buffer() to have set up
+					 * yytext, we can now set up
+					 * yy_c_buf_p so that if some total
+					 * hoser (like flex itself) wants to
+					 * call the scanner after we return the
+					 * YY_NULL, it'll still work - another
+					 * YY_NULL will get returned.
+					 */
+					(yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+
+					yy_act = YY_STATE_EOF(YY_START);
+					goto do_action;
+					}
+
+				else
+					{
+					if ( ! (yy_did_buffer_switch_on_eof) )
+						YY_NEW_FILE;
+					}
+				break;
+				}
+
+			case EOB_ACT_CONTINUE_SCAN:
+				(yy_c_buf_p) =
+					(yytext_ptr) + yy_amount_of_matched_text;
+
+				yy_current_state = yy_get_previous_state(  );
+
+				yy_cp = (yy_c_buf_p);
+				yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+				goto yy_match;
+
+			case EOB_ACT_LAST_MATCH:
+				(yy_c_buf_p) =
+				&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+
+				yy_current_state = yy_get_previous_state(  );
+
+				yy_cp = (yy_c_buf_p);
+				yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+				goto yy_find_action;
+			}
+		break;
+		}
+
+	default:
+		YY_FATAL_ERROR(
+			"fatal flex scanner internal error--no action found" );
+	} /* end of action switch */
+		} /* end of scanning one token */
+	} /* end of user's declarations */
+} /* end of yylex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ *	EOB_ACT_LAST_MATCH -
+ *	EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ *	EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (void)
+{
+    	char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+	char *source = (yytext_ptr);
+	int number_to_move, i;
+	int ret_val;
+
+	if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+		YY_FATAL_ERROR(
+		"fatal flex scanner internal error--end of buffer missed" );
+
+	if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+		{ /* Don't try to fill the buffer, so this is an EOF. */
+		if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+			{
+			/* We matched a single character, the EOB, so
+			 * treat this as a final EOF.
+			 */
+			return EOB_ACT_END_OF_FILE;
+			}
+
+		else
+			{
+			/* We matched some text prior to the EOB, first
+			 * process it.
+			 */
+			return EOB_ACT_LAST_MATCH;
+			}
+		}
+
+	/* Try to read more data. */
+
+	/* First move last chars to start of buffer. */
+	number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1);
+
+	for ( i = 0; i < number_to_move; ++i )
+		*(dest++) = *(source++);
+
+	if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+		/* don't do the read, it's not guaranteed to return an EOF,
+		 * just force an EOF
+		 */
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+
+	else
+		{
+			int num_to_read =
+			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+		while ( num_to_read <= 0 )
+			{ /* Not enough room in the buffer - grow it. */
+
+			/* just a shorter name for the current buffer */
+			YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
+
+			int yy_c_buf_p_offset =
+				(int) ((yy_c_buf_p) - b->yy_ch_buf);
+
+			if ( b->yy_is_our_buffer )
+				{
+				int new_size = b->yy_buf_size * 2;
+
+				if ( new_size <= 0 )
+					b->yy_buf_size += b->yy_buf_size / 8;
+				else
+					b->yy_buf_size *= 2;
+
+				b->yy_ch_buf = (char *)
+					/* Include room in for 2 EOB chars. */
+					yyrealloc( (void *) b->yy_ch_buf,
+							 (yy_size_t) (b->yy_buf_size + 2)  );
+				}
+			else
+				/* Can't grow it, we don't own it. */
+				b->yy_ch_buf = NULL;
+
+			if ( ! b->yy_ch_buf )
+				YY_FATAL_ERROR(
+				"fatal error - scanner input buffer overflow" );
+
+			(yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+			num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+						number_to_move - 1;
+
+			}
+
+		if ( num_to_read > YY_READ_BUF_SIZE )
+			num_to_read = YY_READ_BUF_SIZE;
+
+		/* Read in more data. */
+		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+			(yy_n_chars), num_to_read );
+
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+		}
+
+	if ( (yy_n_chars) == 0 )
+		{
+		if ( number_to_move == YY_MORE_ADJ )
+			{
+			ret_val = EOB_ACT_END_OF_FILE;
+			yyrestart( yyin  );
+			}
+
+		else
+			{
+			ret_val = EOB_ACT_LAST_MATCH;
+			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+				YY_BUFFER_EOF_PENDING;
+			}
+		}
+
+	else
+		ret_val = EOB_ACT_CONTINUE_SCAN;
+
+	if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+		/* Extend the array by 50%, plus the number we really need. */
+		int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
+		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc(
+			(void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size  );
+		if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+			YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+		/* "- 2" to take care of EOB's */
+		YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2);
+	}
+
+	(yy_n_chars) += number_to_move;
+	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+	(yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+	return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+    static yy_state_type yy_get_previous_state (void)
+{
+	yy_state_type yy_current_state;
+	char *yy_cp;
+    
+	yy_current_state = (yy_start);
+
+	for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+		{
+		yy_current_state = yy_nxt[yy_current_state][(*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : \
1)]; +		}
+
+	return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ *	next_state = yy_try_NUL_trans( current_state );
+ */
+    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state )
+{
+	int yy_is_jam;
+    
+	yy_current_state = yy_nxt[yy_current_state][1];
+	yy_is_jam = (yy_current_state <= 0);
+
+		return yy_is_jam ? 0 : yy_current_state;
+}
+
+#ifndef YY_NO_UNPUT
+
+    static void yyunput (int c, char * yy_bp )
+{
+	char *yy_cp;
+    
+    yy_cp = (yy_c_buf_p);
+
+	/* undo effects of setting up yytext */
+	*yy_cp = (yy_hold_char);
+
+	if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+		{ /* need to shift things up to make room */
+		/* +2 for EOB chars. */
+		int number_to_move = (yy_n_chars) + 2;
+		char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+					YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+		char *source =
+				&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+		while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+			*--dest = *--source;
+
+		yy_cp += (int) (dest - source);
+		yy_bp += (int) (dest - source);
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+			(yy_n_chars) = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+		if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+			YY_FATAL_ERROR( "flex scanner push-back overflow" );
+		}
+
+	*--yy_cp = (char) c;
+
+    if ( c == '\n' ){
+        --yylineno;
+    }
+
+	(yytext_ptr) = yy_bp;
+	(yy_hold_char) = *yy_cp;
+	(yy_c_buf_p) = yy_cp;
+}
+
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+    static int yyinput (void)
+#else
+    static int input  (void)
+#endif
+
+{
+	int c;
+    
+	*(yy_c_buf_p) = (yy_hold_char);
+
+	if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+		{
+		/* yy_c_buf_p now points to the character we want to return.
+		 * If this occurs *before* the EOB characters, then it's a
+		 * valid NUL; if not, then we've hit the end of the buffer.
+		 */
+		if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+			/* This was really a NUL. */
+			*(yy_c_buf_p) = '\0';
+
+		else
+			{ /* need more input */
+			int offset = (int) ((yy_c_buf_p) - (yytext_ptr));
+			++(yy_c_buf_p);
+
+			switch ( yy_get_next_buffer(  ) )
+				{
+				case EOB_ACT_LAST_MATCH:
+					/* This happens because yy_g_n_b()
+					 * sees that we've accumulated a
+					 * token and flags that we need to
+					 * try matching the token before
+					 * proceeding.  But for input(),
+					 * there's no matching to consider.
+					 * So convert the EOB_ACT_LAST_MATCH
+					 * to EOB_ACT_END_OF_FILE.
+					 */
+
+					/* Reset buffer status. */
+					yyrestart( yyin );
+
+					/*FALLTHROUGH*/
+
+				case EOB_ACT_END_OF_FILE:
+					{
+					if ( yywrap(  ) )
+						return 0;
+
+					if ( ! (yy_did_buffer_switch_on_eof) )
+						YY_NEW_FILE;
+#ifdef __cplusplus
+					return yyinput();
+#else
+					return input();
+#endif
+					}
+
+				case EOB_ACT_CONTINUE_SCAN:
+					(yy_c_buf_p) = (yytext_ptr) + offset;
+					break;
+				}
+			}
+		}
+
+	c = *(unsigned char *) (yy_c_buf_p);	/* cast for 8-bit char's */
+	*(yy_c_buf_p) = '\0';	/* preserve yytext */
+	(yy_hold_char) = *++(yy_c_buf_p);
+
+	if ( c == '\n' )
+		
+    yylineno++;
+;
+
+	return c;
+}
+#endif	/* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ * 
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+    void yyrestart  (FILE * input_file )
+{
+    
+	if ( ! YY_CURRENT_BUFFER ){
+        yyensure_buffer_stack ();
+		YY_CURRENT_BUFFER_LVALUE =
+            yy_create_buffer( yyin, YY_BUF_SIZE );
+	}
+
+	yy_init_buffer( YY_CURRENT_BUFFER, input_file );
+	yy_load_buffer_state(  );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ * 
+ */
+    void yy_switch_to_buffer  (YY_BUFFER_STATE  new_buffer )
+{
+    
+	/* TODO. We should be able to replace this entire function body
+	 * with
+	 *		yypop_buffer_state();
+	 *		yypush_buffer_state(new_buffer);
+     */
+	yyensure_buffer_stack ();
+	if ( YY_CURRENT_BUFFER == new_buffer )
+		return;
+
+	if ( YY_CURRENT_BUFFER )
+		{
+		/* Flush out information for old buffer. */
+		*(yy_c_buf_p) = (yy_hold_char);
+		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+		}
+
+	YY_CURRENT_BUFFER_LVALUE = new_buffer;
+	yy_load_buffer_state(  );
+
+	/* We don't actually know whether we did this switch during
+	 * EOF (yywrap()) processing, but the only time this flag
+	 * is looked at is after yywrap() is called, so it's safe
+	 * to go ahead and always set it.
+	 */
+	(yy_did_buffer_switch_on_eof) = 1;
+}
+
+static void yy_load_buffer_state  (void)
+{
+    	(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+	(yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+	yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+	(yy_hold_char) = *(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c \
YY_BUF_SIZE. + * 
+ * @return the allocated buffer state.
+ */
+    YY_BUFFER_STATE yy_create_buffer  (FILE * file, int  size )
+{
+	YY_BUFFER_STATE b;
+    
+	b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state )  );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+	b->yy_buf_size = size;
+
+	/* yy_ch_buf has to be 2 characters longer than the size given because
+	 * we need to put in 2 end-of-buffer characters.
+	 */
+	b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2)  );
+	if ( ! b->yy_ch_buf )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+	b->yy_is_our_buffer = 1;
+
+	yy_init_buffer( b, file );
+
+	return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with yy_create_buffer()
+ * 
+ */
+    void yy_delete_buffer (YY_BUFFER_STATE  b )
+{
+    
+	if ( ! b )
+		return;
+
+	if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+		YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+	if ( b->yy_is_our_buffer )
+		yyfree( (void *) b->yy_ch_buf  );
+
+	yyfree( (void *) b  );
+}
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a yyrestart() or at EOF.
+ */
+    static void yy_init_buffer  (YY_BUFFER_STATE  b, FILE * file )
+
+{
+	int oerrno = errno;
+    
+	yy_flush_buffer( b );
+
+	b->yy_input_file = file;
+	b->yy_fill_buffer = 1;
+
+    /* If b is the current buffer, then yy_init_buffer was _probably_
+     * called from yyrestart() or through yy_get_next_buffer.
+     * In that case, we don't want to reset the lineno or column.
+     */
+    if (b != YY_CURRENT_BUFFER){
+        b->yy_bs_lineno = 1;
+        b->yy_bs_column = 0;
+    }
+
+        b->yy_is_interactive = 0;
+    
+	errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ * 
+ */
+    void yy_flush_buffer (YY_BUFFER_STATE  b )
+{
+    	if ( ! b )
+		return;
+
+	b->yy_n_chars = 0;
+
+	/* We always need two end-of-buffer characters.  The first causes
+	 * a transition to the end-of-buffer state.  The second causes
+	 * a jam in that state.
+	 */
+	b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+	b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+	b->yy_buf_pos = &b->yy_ch_buf[0];
+
+	b->yy_at_bol = 1;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	if ( b == YY_CURRENT_BUFFER )
+		yy_load_buffer_state(  );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ *  the current state. This function will allocate the stack
+ *  if necessary.
+ *  @param new_buffer The new state.
+ *  
+ */
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
+{
+    	if (new_buffer == NULL)
+		return;
+
+	yyensure_buffer_stack();
+
+	/* This block is copied from yy_switch_to_buffer. */
+	if ( YY_CURRENT_BUFFER )
+		{
+		/* Flush out information for old buffer. */
+		*(yy_c_buf_p) = (yy_hold_char);
+		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+		}
+
+	/* Only push if top exists. Otherwise, replace top. */
+	if (YY_CURRENT_BUFFER)
+		(yy_buffer_stack_top)++;
+	YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+	/* copied from yy_switch_to_buffer. */
+	yy_load_buffer_state(  );
+	(yy_did_buffer_switch_on_eof) = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ *  The next element becomes the new top.
+ *  
+ */
+void yypop_buffer_state (void)
+{
+    	if (!YY_CURRENT_BUFFER)
+		return;
+
+	yy_delete_buffer(YY_CURRENT_BUFFER );
+	YY_CURRENT_BUFFER_LVALUE = NULL;
+	if ((yy_buffer_stack_top) > 0)
+		--(yy_buffer_stack_top);
+
+	if (YY_CURRENT_BUFFER) {
+		yy_load_buffer_state(  );
+		(yy_did_buffer_switch_on_eof) = 1;
+	}
+}
+
+/* Allocates the stack if it does not exist.
+ *  Guarantees space for at least one push.
+ */
+static void yyensure_buffer_stack (void)
+{
+	yy_size_t num_to_alloc;
+    
+	if (!(yy_buffer_stack)) {
+
+		/* First allocation is just for 2 elements, since we don't know if this
+		 * scanner will even need a stack. We use 2 instead of 1 to avoid an
+		 * immediate realloc on the next call.
+         */
+      num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
+		(yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
+								(num_to_alloc * sizeof(struct yy_buffer_state*)
+								);
+		if ( ! (yy_buffer_stack) )
+			YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+		memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+		(yy_buffer_stack_max) = num_to_alloc;
+		(yy_buffer_stack_top) = 0;
+		return;
+	}
+
+	if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+		/* Increase the buffer to prepare for a possible push. */
+		yy_size_t grow_size = 8 /* arbitrary grow size */;
+
+		num_to_alloc = (yy_buffer_stack_max) + grow_size;
+		(yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
+								((yy_buffer_stack),
+								num_to_alloc * sizeof(struct yy_buffer_state*)
+								);
+		if ( ! (yy_buffer_stack) )
+			YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+		/* zero only the new slots.*/
+		memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct \
yy_buffer_state*)); +		(yy_buffer_stack_max) = num_to_alloc;
+	}
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character \
buffer. + * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ * 
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
+{
+	YY_BUFFER_STATE b;
+    
+	if ( size < 2 ||
+	     base[size-2] != YY_END_OF_BUFFER_CHAR ||
+	     base[size-1] != YY_END_OF_BUFFER_CHAR )
+		/* They forgot to leave room for the EOB's. */
+		return NULL;
+
+	b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state )  );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+	b->yy_buf_size = (int) (size - 2);	/* "- 2" to take care of EOB's */
+	b->yy_buf_pos = b->yy_ch_buf = base;
+	b->yy_is_our_buffer = 0;
+	b->yy_input_file = NULL;
+	b->yy_n_chars = b->yy_buf_size;
+	b->yy_is_interactive = 0;
+	b->yy_at_bol = 1;
+	b->yy_fill_buffer = 0;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	yy_switch_to_buffer( b  );
+
+	return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to yylex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ * 
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ *       yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE yy_scan_string (const char * yystr )
+{
+    
+	return yy_scan_bytes( yystr, (int) strlen(yystr) );
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to yylex() \
will + * scan from a @e copy of @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
+ * 
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_bytes  (const char * yybytes, int  _yybytes_len )
+{
+	YY_BUFFER_STATE b;
+	char *buf;
+	yy_size_t n;
+	int i;
+    
+	/* Get memory for full buffer, including space for trailing EOB's. */
+	n = (yy_size_t) (_yybytes_len + 2);
+	buf = (char *) yyalloc( n  );
+	if ( ! buf )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+	for ( i = 0; i < _yybytes_len; ++i )
+		buf[i] = yybytes[i];
+
+	buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+	b = yy_scan_buffer( buf, n );
+	if ( ! b )
+		YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+	/* It's okay to grow etc. this buffer, and we should throw it
+	 * away when we're done.
+	 */
+	b->yy_is_our_buffer = 1;
+
+	return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yynoreturn yy_fatal_error (const char* msg )
+{
+			fprintf( stderr, "%s\n", msg );
+	exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up yytext. */ \
+        int yyless_macro_arg = (n); \
+        YY_LESS_LINENO(yyless_macro_arg);\
+		yytext[yyleng] = (yy_hold_char); \
+		(yy_c_buf_p) = yytext + yyless_macro_arg; \
+		(yy_hold_char) = *(yy_c_buf_p); \
+		*(yy_c_buf_p) = '\0'; \
+		yyleng = yyless_macro_arg; \
+		} \
+	while ( 0 )
+
+/* Accessor  methods (get/set functions) to struct members. */
+
+/** Get the current line number.
+ * 
+ */
+int yyget_lineno  (void)
+{
+    
+    return yylineno;
+}
+
+/** Get the input stream.
+ * 
+ */
+FILE *yyget_in  (void)
+{
+        return yyin;
+}
+
+/** Get the output stream.
+ * 
+ */
+FILE *yyget_out  (void)
+{
+        return yyout;
+}
+
+/** Get the length of the current token.
+ * 
+ */
+int yyget_leng  (void)
+{
+        return yyleng;
+}
+
+/** Get the current token.
+ * 
+ */
+
+char *yyget_text  (void)
+{
+        return yytext;
+}
+
+/** Set the current line number.
+ * @param _line_number line number
+ * 
+ */
+void yyset_lineno (int  _line_number )
+{
+    
+    yylineno = _line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param _in_str A readable stream.
+ * 
+ * @see yy_switch_to_buffer
+ */
+void yyset_in (FILE *  _in_str )
+{
+        yyin = _in_str ;
+}
+
+void yyset_out (FILE *  _out_str )
+{
+        yyout = _out_str ;
+}
+
+int yyget_debug  (void)
+{
+        return yy_flex_debug;
+}
+
+void yyset_debug (int  _bdebug )
+{
+        yy_flex_debug = _bdebug ;
+}
+
+static int yy_init_globals (void)
+{
+        /* Initialization is the same as for the non-reentrant scanner.
+     * This function is called from yylex_destroy(), so don't allocate here.
+     */
+
+    /* We do not touch yylineno unless the option is enabled. */
+    yylineno =  1;
+    
+    (yy_buffer_stack) = NULL;
+    (yy_buffer_stack_top) = 0;
+    (yy_buffer_stack_max) = 0;
+    (yy_c_buf_p) = NULL;
+    (yy_init) = 0;
+    (yy_start) = 0;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+    yyin = stdin;
+    yyout = stdout;
+#else
+    yyin = NULL;
+    yyout = NULL;
+#endif
+
+    /* For future reference: Set errno on error, since we are called by
+     * yylex_init()
+     */
+    return 0;
+}
+
+/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+int yylex_destroy  (void)
+{
+    
+    /* Pop the buffer stack, destroying each element. */
+	while(YY_CURRENT_BUFFER){
+		yy_delete_buffer( YY_CURRENT_BUFFER  );
+		YY_CURRENT_BUFFER_LVALUE = NULL;
+		yypop_buffer_state();
+	}
+
+	/* Destroy the stack itself. */
+	yyfree((yy_buffer_stack) );
+	(yy_buffer_stack) = NULL;
+
+    /* Reset the globals. This is important in a non-reentrant scanner so the next \
time +     * yylex() is called, initialization will occur. */
+    yy_init_globals( );
+
+    return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, const char * s2, int n )
+{
+		
+	int i;
+	for ( i = 0; i < n; ++i )
+		s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (const char * s )
+{
+	int n;
+	for ( n = 0; s[n]; ++n )
+		;
+
+	return n;
+}
+#endif
+
+void *yyalloc (yy_size_t  size )
+{
+			return malloc(size);
+}
+
+void *yyrealloc  (void * ptr, yy_size_t  size )
+{
+		
+	/* The cast to (char *) in the following accommodates both
+	 * implementations that use char* generic pointers, and those
+	 * that use void* generic pointers.  It works with the latter
+	 * because both ANSI C and C++ allow castless assignment from
+	 * any pointer type to void*, and deal with argument conversions
+	 * as though doing an assignment.
+	 */
+	return realloc(ptr, size);
+}
+
+void yyfree (void * ptr )
+{
+			free( (char *) ptr );	/* see yyrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+/* second stage lexer */
+int yylex(void)
+{
+	int token;
+
+repeat:
+	token = yylex1();
+
+	if (prev_token == T_EOL || prev_token == T_HELPTEXT) {
+		if (token == T_EOL) {
+			/* Do not pass unneeded T_EOL to the parser. */
+			goto repeat;
+		} else {
+			/*
+			 * For the parser, update file/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.
+			 */
+			current_pos.file = current_file;
+			current_pos.lineno = yylineno;
+		}
+	}
+
+	if (prev_prev_token == T_EOL && prev_token == T_WORD &&
+	    (token == T_EQUAL || token == T_COLON_EQUAL || token == T_PLUS_EQUAL))
+		BEGIN(ASSIGN_VAL);
+
+	prev_prev_token = prev_token;
+	prev_token = token;
+
+	return token;
+}
+
+static char *expand_token(const char *in, size_t n)
+{
+	char *out;
+	int c;
+	char c2;
+	const char *rest, *end;
+
+	new_string();
+	append_string(in, n);
+
+	/* get the whole line because we do not know the end of token. */
+	while ((c = input()) != EOF) {
+		if (c == '\n') {
+			unput(c);
+			break;
+		}
+		c2 = c;
+		append_string(&c2, 1);
+	}
+
+	rest = text;
+	out = expand_one_token(&rest);
+
+	/* push back unused characters to the input stream */
+	end = rest + strlen(rest);
+	while (end > rest)
+		unput(*--end);
+
+	free(text);
+
+	return out;
+}
+
+static void append_expanded_string(const char *str)
+{
+	const char *end;
+	char *res;
+
+	str++;
+
+	res = expand_dollar(&str);
+
+	/* push back unused characters to the input stream */
+	end = str + strlen(str);
+	while (end > str)
+		unput(*--end);
+
+	append_string(res, strlen(res));
+
+	free(res);
+}
+
+void zconf_starthelp(void)
+{
+	new_string();
+	last_ts = first_ts = 0;
+	BEGIN(HELP);
+}
+
+static void zconf_endhelp(void)
+{
+	yylval.string = text;
+	BEGIN(INITIAL);
+}
+
+/*
+ * Try to open specified file with following names:
+ * ./name
+ * $(srctree)/name
+ * The latter is used when srctree is separate from objtree
+ * when compiling the kernel.
+ * Return NULL if file is not found.
+ */
+FILE *zconf_fopen(const char *name)
+{
+	char *env, fullname[PATH_MAX+1];
+	FILE *f;
+
+	f = fopen(name, "r");
+	if (!f && name != NULL && name[0] != '/') {
+		env = getenv(SRCTREE);
+		if (env) {
+			snprintf(fullname, sizeof(fullname),
+				 "%s/%s", env, name);
+			f = fopen(fullname, "r");
+		}
+	}
+	return f;
+}
+
+void zconf_initscan(const char *name)
+{
+	yyin = zconf_fopen(name);
+	if (!yyin) {
+		fprintf(stderr, "can't find file %s\n", name);
+		exit(1);
+	}
+
+	current_buf = xmalloc(sizeof(*current_buf));
+	memset(current_buf, 0, sizeof(*current_buf));
+
+	current_file = file_lookup(name);
+	yylineno = 1;
+}
+
+void zconf_nextfile(const char *name)
+{
+	struct file *iter;
+	struct file *file = file_lookup(name);
+	struct buffer *buf = xmalloc(sizeof(*buf));
+	memset(buf, 0, sizeof(*buf));
+
+	current_buf->state = YY_CURRENT_BUFFER;
+	yyin = zconf_fopen(file->name);
+	if (!yyin) {
+		fprintf(stderr, "%s:%d: can't open file \"%s\"\n",
+			zconf_curname(), zconf_lineno(), file->name);
+		exit(1);
+	}
+	yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
+	buf->parent = current_buf;
+	current_buf = buf;
+
+	current_file->lineno = yylineno;
+	file->parent = current_file;
+
+	for (iter = current_file; iter; iter = iter->parent) {
+		if (!strcmp(iter->name, file->name)) {
+			fprintf(stderr,
+				"Recursive inclusion detected.\n"
+				"Inclusion path:\n"
+				"  current file : %s\n", file->name);
+			iter = file;
+			do {
+				iter = iter->parent;
+				fprintf(stderr, "  included from: %s:%d\n",
+					iter->name, iter->lineno - 1);
+			} while (strcmp(iter->name, file->name));
+			exit(1);
+		}
+	}
+
+	yylineno = 1;
+	current_file = file;
+}
+
+static void zconf_endfile(void)
+{
+	struct buffer *parent;
+
+	current_file = current_file->parent;
+	if (current_file)
+		yylineno = current_file->lineno;
+
+	parent = current_buf->parent;
+	if (parent) {
+		fclose(yyin);
+		yy_delete_buffer(YY_CURRENT_BUFFER);
+		yy_switch_to_buffer(parent->state);
+	}
+	free(current_buf);
+	current_buf = parent;
+}
+
+int zconf_lineno(void)
+{
+	return current_pos.lineno;
+}
+
+const char *zconf_curname(void)
+{
+	return current_pos.file ? current_pos.file->name : "<none>";
+}
+
diff --git a/scripts/kconfig/parser.tab.c_shipped \
b/scripts/kconfig/parser.tab.c_shipped new file mode 100644
index 000000000..ee68d4976
--- /dev/null
+++ b/scripts/kconfig/parser.tab.c_shipped
@@ -0,0 +1,2200 @@
+/* A Bison parser, made by GNU Bison 3.7.6.  */
+
+/* Bison implementation for Yacc-like parsers in C
+
+   Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
+   Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+/* As a special exception, you may create a larger work that contains
+   part or all of the Bison parser skeleton and distribute that work
+   under terms of your choice, so long as that work isn't itself a
+   parser generator using the skeleton or a modified version thereof
+   as a parser skeleton.  Alternatively, if you modify or redistribute
+   the parser skeleton itself, you may (at your option) remove this
+   special exception, which will cause the skeleton and the resulting
+   Bison output files to be licensed under the GNU General Public
+   License without this special exception.
+
+   This special exception was added by the Free Software Foundation in
+   version 2.2 of Bison.  */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+   simplifying the original so-called "semantic" parser.  */
+
+/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
+   especially those whose name start with YY_ or yy_.  They are
+   private implementation details that can be changed or removed.  */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+   infringing on user name space.  This should be done even for local
+   variables, as they might otherwise be expanded by user macros.
+   There are some unavoidable exceptions within include files to
+   define necessary library symbols; they are noted "INFRINGES ON
+   USER NAME SPACE" below.  */
+
+/* Identify Bison output, and Bison version.  */
+#define YYBISON 30706
+
+/* Bison version string.  */
+#define YYBISON_VERSION "3.7.6"
+
+/* Skeleton name.  */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers.  */
+#define YYPURE 0
+
+/* Push parsers.  */
+#define YYPUSH 0
+
+/* Pull parsers.  */
+#define YYPULL 1
+
+
+
+
+/* First part of user prologue.  */
+
+
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+
+#include "lkc.h"
+
+#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
+
+#define PRINTD		0x0001
+#define DEBUG_PARSE	0x0002
+
+int cdebug = PRINTD;
+
+static void yyerror(const char *err);
+static void zconfprint(const char *err, ...);
+static void zconf_error(const char *err, ...);
+static bool zconf_endtoken(const char *tokenname,
+			   const char *expected_tokenname);
+
+struct symbol *symbol_hash[SYMBOL_HASHSIZE];
+
+static struct menu *current_menu, *current_entry;
+
+
+
+# ifndef YY_CAST
+#  ifdef __cplusplus
+#   define YY_CAST(Type, Val) static_cast<Type> (Val)
+#   define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast<Type> (Val)
+#  else
+#   define YY_CAST(Type, Val) ((Type) (Val))
+#   define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val))
+#  endif
+# endif
+# ifndef YY_NULLPTR
+#  if defined __cplusplus
+#   if 201103L <= __cplusplus
+#    define YY_NULLPTR nullptr
+#   else
+#    define YY_NULLPTR 0
+#   endif
+#  else
+#   define YY_NULLPTR ((void*)0)
+#  endif
+# endif
+
+#include "parser.tab.h"
+/* Symbol kind.  */
+enum yysymbol_kind_t
+{
+  YYSYMBOL_YYEMPTY = -2,
+  YYSYMBOL_YYEOF = 0,                      /* "end of file"  */
+  YYSYMBOL_YYerror = 1,                    /* error  */
+  YYSYMBOL_YYUNDEF = 2,                    /* "invalid token"  */
+  YYSYMBOL_T_HELPTEXT = 3,                 /* T_HELPTEXT  */
+  YYSYMBOL_T_WORD = 4,                     /* T_WORD  */
+  YYSYMBOL_T_WORD_QUOTE = 5,               /* T_WORD_QUOTE  */
+  YYSYMBOL_T_ALLNOCONFIG_Y = 6,            /* T_ALLNOCONFIG_Y  */
+  YYSYMBOL_T_BOOL = 7,                     /* T_BOOL  */
+  YYSYMBOL_T_CHOICE = 8,                   /* T_CHOICE  */
+  YYSYMBOL_T_CLOSE_PAREN = 9,              /* T_CLOSE_PAREN  */
+  YYSYMBOL_T_COLON_EQUAL = 10,             /* T_COLON_EQUAL  */
+  YYSYMBOL_T_COMMENT = 11,                 /* T_COMMENT  */
+  YYSYMBOL_T_CONFIG = 12,                  /* T_CONFIG  */
+  YYSYMBOL_T_DEFAULT = 13,                 /* T_DEFAULT  */
+  YYSYMBOL_T_DEFCONFIG_LIST = 14,          /* T_DEFCONFIG_LIST  */
+  YYSYMBOL_T_DEF_BOOL = 15,                /* T_DEF_BOOL  */
+  YYSYMBOL_T_DEF_TRISTATE = 16,            /* T_DEF_TRISTATE  */
+  YYSYMBOL_T_DEPENDS = 17,                 /* T_DEPENDS  */
+  YYSYMBOL_T_ENDCHOICE = 18,               /* T_ENDCHOICE  */
+  YYSYMBOL_T_ENDIF = 19,                   /* T_ENDIF  */
+  YYSYMBOL_T_ENDMENU = 20,                 /* T_ENDMENU  */
+  YYSYMBOL_T_HELP = 21,                    /* T_HELP  */
+  YYSYMBOL_T_HEX = 22,                     /* T_HEX  */
+  YYSYMBOL_T_IF = 23,                      /* T_IF  */
+  YYSYMBOL_T_IMPLY = 24,                   /* T_IMPLY  */
+  YYSYMBOL_T_INT = 25,                     /* T_INT  */
+  YYSYMBOL_T_MAINMENU = 26,                /* T_MAINMENU  */
+  YYSYMBOL_T_MENU = 27,                    /* T_MENU  */
+  YYSYMBOL_T_MENUCONFIG = 28,              /* T_MENUCONFIG  */
+  YYSYMBOL_T_MODULES = 29,                 /* T_MODULES  */
+  YYSYMBOL_T_ON = 30,                      /* T_ON  */
+  YYSYMBOL_T_OPEN_PAREN = 31,              /* T_OPEN_PAREN  */
+  YYSYMBOL_T_OPTION = 32,                  /* T_OPTION  */
+  YYSYMBOL_T_OPTIONAL = 33,                /* T_OPTIONAL  */
+  YYSYMBOL_T_PLUS_EQUAL = 34,              /* T_PLUS_EQUAL  */
+  YYSYMBOL_T_PROMPT = 35,                  /* T_PROMPT  */
+  YYSYMBOL_T_RANGE = 36,                   /* T_RANGE  */
+  YYSYMBOL_T_SELECT = 37,                  /* T_SELECT  */
+  YYSYMBOL_T_SOURCE = 38,                  /* T_SOURCE  */
+  YYSYMBOL_T_STRING = 39,                  /* T_STRING  */
+  YYSYMBOL_T_TRISTATE = 40,                /* T_TRISTATE  */
+  YYSYMBOL_T_VISIBLE = 41,                 /* T_VISIBLE  */
+  YYSYMBOL_T_EOL = 42,                     /* T_EOL  */
+  YYSYMBOL_T_ASSIGN_VAL = 43,              /* T_ASSIGN_VAL  */
+  YYSYMBOL_T_OR = 44,                      /* T_OR  */
+  YYSYMBOL_T_AND = 45,                     /* T_AND  */
+  YYSYMBOL_T_EQUAL = 46,                   /* T_EQUAL  */
+  YYSYMBOL_T_UNEQUAL = 47,                 /* T_UNEQUAL  */
+  YYSYMBOL_T_LESS = 48,                    /* T_LESS  */
+  YYSYMBOL_T_LESS_EQUAL = 49,              /* T_LESS_EQUAL  */
+  YYSYMBOL_T_GREATER = 50,                 /* T_GREATER  */
+  YYSYMBOL_T_GREATER_EQUAL = 51,           /* T_GREATER_EQUAL  */
+  YYSYMBOL_T_NOT = 52,                     /* T_NOT  */
+  YYSYMBOL_YYACCEPT = 53,                  /* $accept  */
+  YYSYMBOL_input = 54,                     /* input  */
+  YYSYMBOL_mainmenu_stmt = 55,             /* mainmenu_stmt  */
+  YYSYMBOL_stmt_list = 56,                 /* stmt_list  */
+  YYSYMBOL_stmt_list_in_choice = 57,       /* stmt_list_in_choice  */
+  YYSYMBOL_config_entry_start = 58,        /* config_entry_start  */
+  YYSYMBOL_config_stmt = 59,               /* config_stmt  */
+  YYSYMBOL_menuconfig_entry_start = 60,    /* menuconfig_entry_start  */
+  YYSYMBOL_menuconfig_stmt = 61,           /* menuconfig_stmt  */
+  YYSYMBOL_config_option_list = 62,        /* config_option_list  */
+  YYSYMBOL_config_option = 63,             /* config_option  */
+  YYSYMBOL_choice = 64,                    /* choice  */
+  YYSYMBOL_choice_entry = 65,              /* choice_entry  */
+  YYSYMBOL_choice_end = 66,                /* choice_end  */
+  YYSYMBOL_choice_stmt = 67,               /* choice_stmt  */
+  YYSYMBOL_choice_option_list = 68,        /* choice_option_list  */
+  YYSYMBOL_choice_option = 69,             /* choice_option  */
+  YYSYMBOL_type = 70,                      /* type  */
+  YYSYMBOL_logic_type = 71,                /* logic_type  */
+  YYSYMBOL_default = 72,                   /* default  */
+  YYSYMBOL_if_entry = 73,                  /* if_entry  */
+  YYSYMBOL_if_end = 74,                    /* if_end  */
+  YYSYMBOL_if_stmt = 75,                   /* if_stmt  */
+  YYSYMBOL_if_stmt_in_choice = 76,         /* if_stmt_in_choice  */
+  YYSYMBOL_menu = 77,                      /* menu  */
+  YYSYMBOL_menu_entry = 78,                /* menu_entry  */
+  YYSYMBOL_menu_end = 79,                  /* menu_end  */
+  YYSYMBOL_menu_stmt = 80,                 /* menu_stmt  */
+  YYSYMBOL_menu_option_list = 81,          /* menu_option_list  */
+  YYSYMBOL_source_stmt = 82,               /* source_stmt  */
+  YYSYMBOL_comment = 83,                   /* comment  */
+  YYSYMBOL_comment_stmt = 84,              /* comment_stmt  */
+  YYSYMBOL_comment_option_list = 85,       /* comment_option_list  */
+  YYSYMBOL_help_start = 86,                /* help_start  */
+  YYSYMBOL_help = 87,                      /* help  */
+  YYSYMBOL_depends = 88,                   /* depends  */
+  YYSYMBOL_visible = 89,                   /* visible  */
+  YYSYMBOL_prompt_stmt_opt = 90,           /* prompt_stmt_opt  */
+  YYSYMBOL_end = 91,                       /* end  */
+  YYSYMBOL_if_expr = 92,                   /* if_expr  */
+  YYSYMBOL_expr = 93,                      /* expr  */
+  YYSYMBOL_nonconst_symbol = 94,           /* nonconst_symbol  */
+  YYSYMBOL_symbol = 95,                    /* symbol  */
+  YYSYMBOL_word_opt = 96,                  /* word_opt  */
+  YYSYMBOL_assignment_stmt = 97,           /* assignment_stmt  */
+  YYSYMBOL_assign_op = 98,                 /* assign_op  */
+  YYSYMBOL_assign_val = 99                 /* assign_val  */
+};
+typedef enum yysymbol_kind_t yysymbol_kind_t;
+
+
+
+
+#ifdef short
+# undef short
+#endif
+
+/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure
+   <limits.h> and (if available) <stdint.h> are included
+   so that the code can choose integer types of a good width.  */
+
+#ifndef __PTRDIFF_MAX__
+# include <limits.h> /* INFRINGES ON USER NAME SPACE */
+# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
+#  include <stdint.h> /* INFRINGES ON USER NAME SPACE */
+#  define YY_STDINT_H
+# endif
+#endif
+
+/* Narrow types that promote to a signed type and that can represent a
+   signed or unsigned integer of at least N bits.  In tables they can
+   save space and decrease cache pressure.  Promoting to a signed type
+   helps avoid bugs in integer arithmetic.  */
+
+#ifdef __INT_LEAST8_MAX__
+typedef __INT_LEAST8_TYPE__ yytype_int8;
+#elif defined YY_STDINT_H
+typedef int_least8_t yytype_int8;
+#else
+typedef signed char yytype_int8;
+#endif
+
+#ifdef __INT_LEAST16_MAX__
+typedef __INT_LEAST16_TYPE__ yytype_int16;
+#elif defined YY_STDINT_H
+typedef int_least16_t yytype_int16;
+#else
+typedef short yytype_int16;
+#endif
+
+/* Work around bug in HP-UX 11.23, which defines these macros
+   incorrectly for preprocessor constants.  This workaround can likely
+   be removed in 2023, as HPE has promised support for HP-UX 11.23
+   (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of
+   <https://h20195.www2.hpe.com/V2/getpdf.aspx/4AA4-7673ENW.pdf>.  */
+#ifdef __hpux
+# undef UINT_LEAST8_MAX
+# undef UINT_LEAST16_MAX
+# define UINT_LEAST8_MAX 255
+# define UINT_LEAST16_MAX 65535
+#endif
+
+#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__
+typedef __UINT_LEAST8_TYPE__ yytype_uint8;
+#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \
+       && UINT_LEAST8_MAX <= INT_MAX)
+typedef uint_least8_t yytype_uint8;
+#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX
+typedef unsigned char yytype_uint8;
+#else
+typedef short yytype_uint8;
+#endif
+
+#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__
+typedef __UINT_LEAST16_TYPE__ yytype_uint16;
+#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \
+       && UINT_LEAST16_MAX <= INT_MAX)
+typedef uint_least16_t yytype_uint16;
+#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX
+typedef unsigned short yytype_uint16;
+#else
+typedef int yytype_uint16;
+#endif
+
+#ifndef YYPTRDIFF_T
+# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__
+#  define YYPTRDIFF_T __PTRDIFF_TYPE__
+#  define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__
+# elif defined PTRDIFF_MAX
+#  ifndef ptrdiff_t
+#   include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+#  endif
+#  define YYPTRDIFF_T ptrdiff_t
+#  define YYPTRDIFF_MAXIMUM PTRDIFF_MAX
+# else
+#  define YYPTRDIFF_T long
+#  define YYPTRDIFF_MAXIMUM LONG_MAX
+# endif
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+#  define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+#  define YYSIZE_T size_t
+# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
+#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYSIZE_T size_t
+# else
+#  define YYSIZE_T unsigned
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM                                  \
+  YY_CAST (YYPTRDIFF_T,                                 \
+           (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1)  \
+            ? YYPTRDIFF_MAXIMUM                         \
+            : YY_CAST (YYSIZE_T, -1)))
+
+#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X))
+
+
+/* Stored state numbers (used for stacks). */
+typedef yytype_uint8 yy_state_t;
+
+/* State numbers in computations.  */
+typedef int yy_state_fast_t;
+
+#ifndef YY_
+# if defined YYENABLE_NLS && YYENABLE_NLS
+#  if ENABLE_NLS
+#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+#   define YY_(Msgid) dgettext ("bison-runtime", Msgid)
+#  endif
+# endif
+# ifndef YY_
+#  define YY_(Msgid) Msgid
+# endif
+#endif
+
+
+#ifndef YY_ATTRIBUTE_PURE
+# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__)
+#  define YY_ATTRIBUTE_PURE __attribute__ ((__pure__))
+# else
+#  define YY_ATTRIBUTE_PURE
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE_UNUSED
+# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__)
+#  define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__))
+# else
+#  define YY_ATTRIBUTE_UNUSED
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E.  */
+#if ! defined lint || defined __GNUC__
+# define YY_USE(E) ((void) (E))
+#else
+# define YY_USE(E) /* empty */
+#endif
+
+#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+/* Suppress an incorrect diagnostic about yylval being uninitialized.  */
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN                            \
+    _Pragma ("GCC diagnostic push")                                     \
+    _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")              \
+    _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END      \
+    _Pragma ("GCC diagnostic pop")
+#else
+# define YY_INITIAL_VALUE(Value) Value
+#endif
+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END
+#endif
+#ifndef YY_INITIAL_VALUE
+# define YY_INITIAL_VALUE(Value) /* Nothing. */
+#endif
+
+#if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__
+# define YY_IGNORE_USELESS_CAST_BEGIN                          \
+    _Pragma ("GCC diagnostic push")                            \
+    _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"")
+# define YY_IGNORE_USELESS_CAST_END            \
+    _Pragma ("GCC diagnostic pop")
+#endif
+#ifndef YY_IGNORE_USELESS_CAST_BEGIN
+# define YY_IGNORE_USELESS_CAST_BEGIN
+# define YY_IGNORE_USELESS_CAST_END
+#endif
+
+
+#define YY_ASSERT(E) ((void) (0 && (E)))
+
+#if !defined yyoverflow
+
+/* The parser invokes alloca or malloc; define the necessary symbols.  */
+
+# ifdef YYSTACK_USE_ALLOCA
+#  if YYSTACK_USE_ALLOCA
+#   ifdef __GNUC__
+#    define YYSTACK_ALLOC __builtin_alloca
+#   elif defined __BUILTIN_VA_ARG_INCR
+#    include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+#   elif defined _AIX
+#    define YYSTACK_ALLOC __alloca
+#   elif defined _MSC_VER
+#    include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+#    define alloca _alloca
+#   else
+#    define YYSTACK_ALLOC alloca
+#    if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
+#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+      /* Use EXIT_SUCCESS as a witness for stdlib.h.  */
+#     ifndef EXIT_SUCCESS
+#      define EXIT_SUCCESS 0
+#     endif
+#    endif
+#   endif
+#  endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+   /* Pacify GCC's 'empty if-body' warning.  */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+    /* The OS might guarantee only one guard page at the bottom of the stack,
+       and a page size can be as small as 4096 bytes.  So we cannot safely
+       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
+       to allow for a few compiler-allocated temporary stack slots.  */
+#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+#  endif
+# else
+#  define YYSTACK_ALLOC YYMALLOC
+#  define YYSTACK_FREE YYFREE
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+#   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+#  endif
+#  if (defined __cplusplus && ! defined EXIT_SUCCESS \
+       && ! ((defined YYMALLOC || defined malloc) \
+             && (defined YYFREE || defined free)))
+#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#   ifndef EXIT_SUCCESS
+#    define EXIT_SUCCESS 0
+#   endif
+#  endif
+#  ifndef YYMALLOC
+#   define YYMALLOC malloc
+#   if ! defined malloc && ! defined EXIT_SUCCESS
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+#  ifndef YYFREE
+#   define YYFREE free
+#   if ! defined free && ! defined EXIT_SUCCESS
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+# endif
+#endif /* !defined yyoverflow */
+
+#if (! defined yyoverflow \
+     && (! defined __cplusplus \
+         || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member.  */
+union yyalloc
+{
+  yy_state_t yyss_alloc;
+  YYSTYPE yyvs_alloc;
+};
+
+/* The size of the maximum gap between one aligned stack and the next.  */
+# define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+   N elements.  */
+# define YYSTACK_BYTES(N) \
+     ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \
+      + YYSTACK_GAP_MAXIMUM)
+
+# define YYCOPY_NEEDED 1
+
+/* Relocate STACK from its old location to the new one.  The
+   local variables YYSIZE and YYSTACKSIZE give the old and new number of
+   elements in the stack, and YYPTR gives the new location of the
+   stack.  Advance YYPTR to a properly aligned location for the next
+   stack.  */
+# define YYSTACK_RELOCATE(Stack_alloc, Stack)                           \
+    do                                                                  \
+      {                                                                 \
+        YYPTRDIFF_T yynewbytes;                                         \
+        YYCOPY (&yyptr->Stack_alloc, Stack, yysize);                    \
+        Stack = &yyptr->Stack_alloc;                                    \
+        yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \
+        yyptr += yynewbytes / YYSIZEOF (*yyptr);                        \
+      }                                                                 \
+    while (0)
+
+#endif
+
+#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
+/* Copy COUNT objects from SRC to DST.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined __GNUC__ && 1 < __GNUC__
+#   define YYCOPY(Dst, Src, Count) \
+      __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src)))
+#  else
+#   define YYCOPY(Dst, Src, Count)              \
+      do                                        \
+        {                                       \
+          YYPTRDIFF_T yyi;                      \
+          for (yyi = 0; yyi < (Count); yyi++)   \
+            (Dst)[yyi] = (Src)[yyi];            \
+        }                                       \
+      while (0)
+#  endif
+# endif
+#endif /* !YYCOPY_NEEDED */
+
+/* YYFINAL -- State number of the termination state.  */
+#define YYFINAL  6
+/* YYLAST -- Last index in YYTABLE.  */
+#define YYLAST   190
+
+/* YYNTOKENS -- Number of terminals.  */
+#define YYNTOKENS  53
+/* YYNNTS -- Number of nonterminals.  */
+#define YYNNTS  47
+/* YYNRULES -- Number of rules.  */
+#define YYNRULES  107
+/* YYNSTATES -- Number of states.  */
+#define YYNSTATES  189
+
+/* YYMAXUTOK -- Last valid token kind.  */
+#define YYMAXUTOK   307
+
+
+/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
+   as returned by yylex, with out-of-bounds checking.  */
+#define YYTRANSLATE(YYX)                                \
+  (0 <= (YYX) && (YYX) <= YYMAXUTOK                     \
+   ? YY_CAST (yysymbol_kind_t, yytranslate[YYX])        \
+   : YYSYMBOL_YYUNDEF)
+
+/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
+   as returned by yylex.  */
+static const yytype_int8 yytranslate[] =
+{
+       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
+       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
+      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
+      35,    36,    37,    38,    39,    40,    41,    42,    43,    44,
+      45,    46,    47,    48,    49,    50,    51,    52
+};
+
+#if YYDEBUG
+  /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
+static const yytype_int16 yyrline[] =
+{
+       0,   111,   111,   111,   115,   120,   122,   123,   124,   125,
+     126,   127,   128,   129,   130,   131,   134,   136,   137,   138,
+     139,   144,   151,   156,   163,   172,   174,   175,   176,   179,
+     187,   193,   203,   209,   215,   221,   226,   231,   238,   248,
+     253,   261,   264,   266,   267,   268,   271,   277,   284,   290,
+     298,   299,   300,   301,   304,   305,   308,   309,   310,   314,
+     322,   330,   333,   338,   345,   350,   358,   361,   363,   364,
+     367,   376,   383,   386,   388,   393,   399,   417,   424,   431,
+     433,   438,   439,   440,   443,   444,   447,   448,   449,   450,
+     451,   452,   453,   454,   455,   456,   457,   461,   463,   464,
+     467,   468,   472,   475,   476,   477,   481,   482
+};
+#endif
+
+/** Accessing symbol of state STATE.  */
+#define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State])
+
+#if YYDEBUG || 0
+/* The user-facing name of the symbol whose (internal) number is
+   YYSYMBOL.  No bounds checking.  */
+static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED;
+
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
+static const char *const yytname[] =
+{
+  "\"end of file\"", "error", "\"invalid token\"", "T_HELPTEXT", "T_WORD",
+  "T_WORD_QUOTE", "T_ALLNOCONFIG_Y", "T_BOOL", "T_CHOICE", "T_CLOSE_PAREN",
+  "T_COLON_EQUAL", "T_COMMENT", "T_CONFIG", "T_DEFAULT",
+  "T_DEFCONFIG_LIST", "T_DEF_BOOL", "T_DEF_TRISTATE", "T_DEPENDS",
+  "T_ENDCHOICE", "T_ENDIF", "T_ENDMENU", "T_HELP", "T_HEX", "T_IF",
+  "T_IMPLY", "T_INT", "T_MAINMENU", "T_MENU", "T_MENUCONFIG", "T_MODULES",
+  "T_ON", "T_OPEN_PAREN", "T_OPTION", "T_OPTIONAL", "T_PLUS_EQUAL",
+  "T_PROMPT", "T_RANGE", "T_SELECT", "T_SOURCE", "T_STRING", "T_TRISTATE",
+  "T_VISIBLE", "T_EOL", "T_ASSIGN_VAL", "T_OR", "T_AND", "T_EQUAL",
+  "T_UNEQUAL", "T_LESS", "T_LESS_EQUAL", "T_GREATER", "T_GREATER_EQUAL",
+  "T_NOT", "$accept", "input", "mainmenu_stmt", "stmt_list",
+  "stmt_list_in_choice", "config_entry_start", "config_stmt",
+  "menuconfig_entry_start", "menuconfig_stmt", "config_option_list",
+  "config_option", "choice", "choice_entry", "choice_end", "choice_stmt",
+  "choice_option_list", "choice_option", "type", "logic_type", "default",
+  "if_entry", "if_end", "if_stmt", "if_stmt_in_choice", "menu",
+  "menu_entry", "menu_end", "menu_stmt", "menu_option_list", "source_stmt",
+  "comment", "comment_stmt", "comment_option_list", "help_start", "help",
+  "depends", "visible", "prompt_stmt_opt", "end", "if_expr", "expr",
+  "nonconst_symbol", "symbol", "word_opt", "assignment_stmt", "assign_op",
+  "assign_val", YY_NULLPTR
+};
+
+static const char *
+yysymbol_name (yysymbol_kind_t yysymbol)
+{
+  return yytname[yysymbol];
+}
+#endif
+
+#ifdef YYPRINT
+/* YYTOKNUM[NUM] -- (External) token number corresponding to the
+   (internal) symbol number NUM (which must be that of a token).  */
+static const yytype_int16 yytoknum[] =
+{
+       0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
+     265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
+     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
+     285,   286,   287,   288,   289,   290,   291,   292,   293,   294,
+     295,   296,   297,   298,   299,   300,   301,   302,   303,   304,
+     305,   306,   307
+};
+#endif
+
+#define YYPACT_NINF (-64)
+
+#define yypact_value_is_default(Yyn) \
+  ((Yyn) == YYPACT_NINF)
+
+#define YYTABLE_NINF (-4)
+
+#define yytable_value_is_error(Yyn) \
+  0
+
+  /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+     STATE-NUM.  */
+static const yytype_int16 yypact[] =
+{
+      -5,    18,    24,   -64,    33,   -13,   -64,    58,    -6,    17,
+      35,    44,    49,    12,    50,    49,    52,   -64,   -64,   -64,
+     -64,   -64,   -64,   -64,   -64,   -64,   -64,   -64,   -64,   -64,
+     -64,   -64,   -64,   -64,   -64,    30,   -64,   -64,   -64,    32,
+     -64,    38,    42,   -64,    46,   -64,    12,    12,    34,   -64,
+     117,    47,    48,    53,   109,   109,   122,   158,    90,     5,
+      90,    60,   -64,   -64,    57,   -64,   -64,   -64,    23,   -64,
+     -64,    12,    12,    15,    15,    15,    15,    15,    15,   -64,
+     -64,   -64,   -64,   -64,   -64,   -64,    62,    61,   -64,    49,
+     -64,    36,    95,    15,    49,   -64,   -64,   -64,    99,   -64,
+      12,   108,   -64,   -64,    49,    70,   114,   -64,    99,   -64,
+     -64,    72,    78,    79,    81,   -64,   -64,   -64,   -64,   -64,
+     -64,   -64,   -64,   104,   -64,   -64,   -64,   -64,   -64,   -64,
+     -64,    87,   -64,   -64,   -64,   -64,   -64,   -64,   -64,    12,
+     -64,   104,    94,    96,    98,   104,    15,   104,   104,   100,
+      29,   -64,   104,   -64,   104,   110,   -64,   -64,   -64,   -64,
+     158,    12,   119,   129,   130,   -64,   -64,   -64,   137,   104,
+     138,   -64,   -64,   140,   141,   142,   -64,   -64,     3,   -64,
+     -64,   -64,   -64,   143,   -64,   -64,   -64,   -64,   -64
+};
+
+  /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
+     Performed when YYTABLE does not specify something else to do.  Zero
+     means the default is an error.  */
+static const yytype_int8 yydefact[] =
+{
+       5,     0,     0,     5,     0,     0,     1,     0,     0,     0,
+     100,     0,     0,     0,     0,     0,     0,    25,     9,    25,
+      12,    42,    16,     7,     5,    10,    67,     5,    11,    13,
+      73,     8,     6,     4,    15,     0,   104,   105,   103,   106,
+     101,     0,     0,    97,     0,    99,     0,     0,     0,    98,
+      86,     0,     0,     0,    22,    24,    39,     0,     0,    64,
+       0,    72,    14,   107,     0,    38,    71,    21,     0,    94,
+      59,     0,     0,     0,     0,     0,     0,     0,     0,    63,
+      23,    70,    54,    56,    57,    58,     0,     0,    52,     0,
+      51,     0,     0,     0,     0,    53,    55,    26,    79,    50,
+       0,     0,    28,    27,     0,     0,     0,    43,    79,    45,
+      44,     0,     0,     0,     0,    18,    41,    16,    19,    17,
+      40,    61,    60,    84,    69,    68,    66,    65,    74,   102,
+      93,    95,    96,    91,    92,    87,    88,    89,    90,     0,
+      75,    84,     0,     0,     0,    84,     0,    84,    84,     0,
+      84,    76,    84,    48,    84,     0,    20,    82,    83,    81,
+       0,     0,     0,     0,     0,    37,    36,    35,     0,    84,
+       0,    80,    29,     0,     0,     0,    47,    62,    85,    78,
+      77,    33,    30,     0,    32,    31,    49,    46,    34
+};
+
+  /* YYPGOTO[NTERM-NUM].  */
+static const yytype_int16 yypgoto[] =
+{
+     -64,   -64,   -64,     4,    20,   -64,   -55,   -64,   -64,   131,
+     -64,   -64,   -64,   -64,   -64,   -64,   -64,   -64,   132,   -64,
+     -54,    26,   -64,   -64,   -64,   -64,   -64,   -64,   -64,   -64,
+     -64,   -53,   -64,   -64,   133,   -21,   -64,    82,   -51,     6,
+     -46,    -7,   -63,   -64,   -64,   -64,   -64
+};
+
+  /* YYDEFGOTO[NTERM-NUM].  */
+static const yytype_uint8 yydefgoto[] =
+{
+       0,     2,     3,     4,    57,    17,    18,    19,    20,    54,
+      97,    21,    22,   116,    23,    56,   107,    98,    99,   100,
+      24,   121,    25,   118,    26,    27,   126,    28,    59,    29,
+      30,    31,    61,   101,   102,   103,   125,   149,   122,   162,
+      48,    49,    50,    41,    32,    39,    64
+};
+
+  /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
+     positive, shift that token.  If negative, reduce the rule whose
+     number is the opposite.  If YYTABLE_NINF, syntax error.  */
+static const yytype_int16 yytable[] =
+{
+      68,    69,   115,   117,   119,    44,   120,     7,    52,   127,
+     133,   134,   135,   136,   137,   138,    43,    45,    35,    43,
+      45,     1,    86,     5,     6,   131,   132,    36,    58,    33,
+     146,    60,   130,    -3,     8,   110,    34,     9,   124,    40,
+     128,    10,   142,    46,    11,    12,   123,    71,    72,    42,
+     143,    37,   161,    43,   150,    51,    13,    53,    -2,     8,
+      14,    15,     9,    38,    47,   144,    10,    71,    72,    11,
+      12,    16,    62,    71,    72,    63,    70,    86,    71,    72,
+      65,    13,   141,   169,    66,    14,    15,   147,    67,    79,
+      80,     8,   139,   163,     9,    81,    16,   152,    10,   129,
+     145,    11,    12,   140,   148,   115,   117,   119,   112,   113,
+     114,   151,   153,    13,   156,   178,    82,    14,    15,   154,
+     157,   158,    83,   159,    84,    85,    86,   161,    16,    82,
+      87,    88,    72,    89,    90,   104,   165,   160,   166,    86,
+     167,    91,   172,    87,    92,    93,    94,   164,    95,    96,
+      55,   168,   176,   170,   171,   105,   173,   106,   174,   111,
+     175,   179,    96,    73,    74,    75,    76,    77,    78,    11,
+      12,   180,   181,    71,    72,   183,   112,   113,   114,   182,
+     184,    13,   185,   186,   187,   188,   177,     0,   108,   109,
+     155
+};
+
+static const yytype_int16 yycheck[] =
+{
+      46,    47,    57,    57,    57,    12,    57,     3,    15,    60,
+      73,    74,    75,    76,    77,    78,     4,     5,     1,     4,
+       5,    26,    17,     5,     0,    71,    72,    10,    24,    42,
+      93,    27,     9,     0,     1,    56,    42,     4,    59,     4,
+      61,     8,     6,    31,    11,    12,    41,    44,    45,     5,
+      14,    34,    23,     4,   100,     5,    23,     5,     0,     1,
+      27,    28,     4,    46,    52,    29,     8,    44,    45,    11,
+      12,    38,    42,    44,    45,    43,    42,    17,    44,    45,
+      42,    23,    89,   146,    42,    27,    28,    94,    42,    42,
+      42,     1,    30,   139,     4,    42,    38,   104,     8,    42,
+       5,    11,    12,    42,     5,   160,   160,   160,    18,    19,
+      20,     3,    42,    23,    42,   161,     7,    27,    28,     5,
+      42,    42,    13,    42,    15,    16,    17,    23,    38,     7,
+      21,    22,    45,    24,    25,    13,    42,   117,    42,    17,
+      42,    32,    42,    21,    35,    36,    37,   141,    39,    40,
+      19,   145,    42,   147,   148,    33,   150,    35,   152,     1,
+     154,    42,    40,    46,    47,    48,    49,    50,    51,    11,
+      12,    42,    42,    44,    45,   169,    18,    19,    20,    42,
+      42,    23,    42,    42,    42,    42,   160,    -1,    56,    56,
+     108
+};
+
+  /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+     symbol of state STATE-NUM.  */
+static const yytype_int8 yystos[] =
+{
+       0,    26,    54,    55,    56,     5,     0,    56,     1,     4,
+       8,    11,    12,    23,    27,    28,    38,    58,    59,    60,
+      61,    64,    65,    67,    73,    75,    77,    78,    80,    82,
+      83,    84,    97,    42,    42,     1,    10,    34,    46,    98,
+       4,    96,     5,     4,    94,     5,    31,    52,    93,    94,
+      95,     5,    94,     5,    62,    62,    68,    57,    56,    81,
+      56,    85,    42,    43,    99,    42,    42,    42,    93,    93,
+      42,    44,    45,    46,    47,    48,    49,    50,    51,    42,
+      42,    42,     7,    13,    15,    16,    17,    21,    22,    24,
+      25,    32,    35,    36,    37,    39,    40,    63,    70,    71,
+      72,    86,    87,    88,    13,    33,    35,    69,    71,    87,
+      88,     1,    18,    19,    20,    59,    66,    73,    76,    84,
+      91,    74,    91,    41,    88,    89,    79,    91,    88,    42,
+       9,    93,    93,    95,    95,    95,    95,    95,    95,    30,
+      42,    94,     6,    14,    29,     5,    95,    94,     5,    90,
+      93,     3,    94,    42,     5,    90,    42,    42,    42,    42,
+      57,    23,    92,    93,    92,    42,    42,    42,    92,    95,
+      92,    92,    42,    92,    92,    92,    42,    74,    93,    42,
+      42,    42,    42,    92,    42,    42,    42,    42,    42
+};
+
+  /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const yytype_int8 yyr1[] =
+{
+       0,    53,    54,    54,    55,    56,    56,    56,    56,    56,
+      56,    56,    56,    56,    56,    56,    57,    57,    57,    57,
+      57,    58,    59,    60,    61,    62,    62,    62,    62,    63,
+      63,    63,    63,    63,    63,    63,    63,    63,    64,    65,
+      66,    67,    68,    68,    68,    68,    69,    69,    69,    69,
+      70,    70,    70,    70,    71,    71,    72,    72,    72,    73,
+      74,    75,    76,    77,    78,    79,    80,    81,    81,    81,
+      82,    83,    84,    85,    85,    86,    87,    88,    89,    90,
+      90,    91,    91,    91,    92,    92,    93,    93,    93,    93,
+      93,    93,    93,    93,    93,    93,    93,    94,    95,    95,
+      96,    96,    97,    98,    98,    98,    99,    99
+};
+
+  /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.  */
+static const yytype_int8 yyr2[] =
+{
+       0,     2,     2,     1,     3,     0,     2,     2,     2,     2,
+       2,     2,     2,     2,     4,     3,     0,     2,     2,     2,
+       3,     3,     2,     3,     2,     0,     2,     2,     2,     3,
+       4,     4,     4,     4,     5,     3,     3,     3,     3,     2,
+       1,     3,     0,     2,     2,     2,     4,     3,     2,     4,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     3,
+       1,     3,     3,     3,     2,     1,     3,     0,     2,     2,
+       3,     3,     2,     0,     2,     2,     2,     4,     3,     0,
+       2,     2,     2,     2,     0,     2,     1,     3,     3,     3,
+       3,     3,     3,     3,     2,     3,     3,     1,     1,     1,
+       0,     1,     4,     1,     1,     1,     0,     1
+};
+
+
+enum { YYENOMEM = -2 };
+
+#define yyerrok         (yyerrstatus = 0)
+#define yyclearin       (yychar = YYEMPTY)
+
+#define YYACCEPT        goto yyacceptlab
+#define YYABORT         goto yyabortlab
+#define YYERROR         goto yyerrorlab
+
+
+#define YYRECOVERING()  (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value)                                    \
+  do                                                              \
+    if (yychar == YYEMPTY)                                        \
+      {                                                           \
+        yychar = (Token);                                         \
+        yylval = (Value);                                         \
+        YYPOPSTACK (yylen);                                       \
+        yystate = *yyssp;                                         \
+        goto yybackup;                                            \
+      }                                                           \
+    else                                                          \
+      {                                                           \
+        yyerror (YY_("syntax error: cannot back up")); \
+        YYERROR;                                                  \
+      }                                                           \
+  while (0)
+
+/* Backward compatibility with an undocumented macro.
+   Use YYerror or YYUNDEF. */
+#define YYERRCODE YYUNDEF
+
+
+/* Enable debugging if requested.  */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args)                        \
+do {                                            \
+  if (yydebug)                                  \
+    YYFPRINTF Args;                             \
+} while (0)
+
+/* This macro is provided for backward compatibility. */
+# ifndef YY_LOCATION_PRINT
+#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+
+
+# define YY_SYMBOL_PRINT(Title, Kind, Value, Location)                    \
+do {                                                                      \
+  if (yydebug)                                                            \
+    {                                                                     \
+      YYFPRINTF (stderr, "%s ", Title);                                   \
+      yy_symbol_print (stderr,                                            \
+                  Kind, Value); \
+      YYFPRINTF (stderr, "\n");                                           \
+    }                                                                     \
+} while (0)
+
+
+/*-----------------------------------.
+| Print this symbol's value on YYO.  |
+`-----------------------------------*/
+
+static void
+yy_symbol_value_print (FILE *yyo,
+                       yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep)
+{
+  FILE *yyoutput = yyo;
+  YY_USE (yyoutput);
+  if (!yyvaluep)
+    return;
+# ifdef YYPRINT
+  if (yykind < YYNTOKENS)
+    YYPRINT (yyo, yytoknum[yykind], *yyvaluep);
+# endif
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+  YY_USE (yykind);
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
+}
+
+
+/*---------------------------.
+| Print this symbol on YYO.  |
+`---------------------------*/
+
+static void
+yy_symbol_print (FILE *yyo,
+                 yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep)
+{
+  YYFPRINTF (yyo, "%s %s (",
+             yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind));
+
+  yy_symbol_value_print (yyo, yykind, yyvaluep);
+  YYFPRINTF (yyo, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included).                                                   |
+`------------------------------------------------------------------*/
+
+static void
+yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop)
+{
+  YYFPRINTF (stderr, "Stack now");
+  for (; yybottom <= yytop; yybottom++)
+    {
+      int yybot = *yybottom;
+      YYFPRINTF (stderr, " %d", yybot);
+    }
+  YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top)                            \
+do {                                                            \
+  if (yydebug)                                                  \
+    yy_stack_print ((Bottom), (Top));                           \
+} while (0)
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced.  |
+`------------------------------------------------*/
+
+static void
+yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp,
+                 int yyrule)
+{
+  int yylno = yyrline[yyrule];
+  int yynrhs = yyr2[yyrule];
+  int yyi;
+  YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n",
+             yyrule - 1, yylno);
+  /* The symbols being reduced.  */
+  for (yyi = 0; yyi < yynrhs; yyi++)
+    {
+      YYFPRINTF (stderr, "   $%d = ", yyi + 1);
+      yy_symbol_print (stderr,
+                       YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]),
+                       &yyvsp[(yyi + 1) - (yynrhs)]);
+      YYFPRINTF (stderr, "\n");
+    }
+}
+
+# define YY_REDUCE_PRINT(Rule)          \
+do {                                    \
+  if (yydebug)                          \
+    yy_reduce_print (yyssp, yyvsp, Rule); \
+} while (0)
+
+/* Nonzero means print parse trace.  It is left uninitialized so that
+   multiple parsers can coexist.  */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args) ((void) 0)
+# define YY_SYMBOL_PRINT(Title, Kind, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks.  */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+   if the built-in stack extension method is used).
+
+   Do not make this value too large; the results are undefined if
+   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+   evaluated with infinite-precision integer arithmetic.  */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+
+
+
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol.  |
+`-----------------------------------------------*/
+
+static void
+yydestruct (const char *yymsg,
+            yysymbol_kind_t yykind, YYSTYPE *yyvaluep)
+{
+  YY_USE (yyvaluep);
+  if (!yymsg)
+    yymsg = "Deleting";
+  YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp);
+
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+  switch (yykind)
+    {
+    case YYSYMBOL_choice_entry: /* choice_entry  */
+            {
+	fprintf(stderr, "%s:%d: missing end statement for this entry\n",
+		((*yyvaluep).menu)->file->name, ((*yyvaluep).menu)->lineno);
+	if (current_menu == ((*yyvaluep).menu))
+		menu_end_menu();
+}
+        break;
+
+    case YYSYMBOL_if_entry: /* if_entry  */
+            {
+	fprintf(stderr, "%s:%d: missing end statement for this entry\n",
+		((*yyvaluep).menu)->file->name, ((*yyvaluep).menu)->lineno);
+	if (current_menu == ((*yyvaluep).menu))
+		menu_end_menu();
+}
+        break;
+
+    case YYSYMBOL_menu_entry: /* menu_entry  */
+            {
+	fprintf(stderr, "%s:%d: missing end statement for this entry\n",
+		((*yyvaluep).menu)->file->name, ((*yyvaluep).menu)->lineno);
+	if (current_menu == ((*yyvaluep).menu))
+		menu_end_menu();
+}
+        break;
+
+      default:
+        break;
+    }
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
+}
+
+
+/* Lookahead token kind.  */
+int yychar;
+
+/* The semantic value of the lookahead symbol.  */
+YYSTYPE yylval;
+/* Number of syntax errors so far.  */
+int yynerrs;
+
+
+
+
+/*----------.
+| yyparse.  |
+`----------*/
+
+int
+yyparse (void)
+{
+    yy_state_fast_t yystate = 0;
+    /* Number of tokens to shift before error messages enabled.  */
+    int yyerrstatus = 0;
+
+    /* Refer to the stacks through separate pointers, to allow yyoverflow
+       to reallocate them elsewhere.  */
+
+    /* Their size.  */
+    YYPTRDIFF_T yystacksize = YYINITDEPTH;
+
+    /* The state stack: array, bottom, top.  */
+    yy_state_t yyssa[YYINITDEPTH];
+    yy_state_t *yyss = yyssa;
+    yy_state_t *yyssp = yyss;
+
+    /* The semantic value stack: array, bottom, top.  */
+    YYSTYPE yyvsa[YYINITDEPTH];
+    YYSTYPE *yyvs = yyvsa;
+    YYSTYPE *yyvsp = yyvs;
+
+  int yyn;
+  /* The return value of yyparse.  */
+  int yyresult;
+  /* Lookahead symbol kind.  */
+  yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY;
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+
+
+
+#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))
+
+  /* The number of symbols on the RHS of the reduced rule.
+     Keep to zero when no symbol should be popped.  */
+  int yylen = 0;
+
+  YYDPRINTF ((stderr, "Starting parse\n"));
+
+  yychar = YYEMPTY; /* Cause a token to be read.  */
+  goto yysetstate;
+
+
+/*------------------------------------------------------------.
+| yynewstate -- push a new state, which is found in yystate.  |
+`------------------------------------------------------------*/
+yynewstate:
+  /* In all cases, when you get here, the value and location stacks
+     have just been pushed.  So pushing a state here evens the stacks.  */
+  yyssp++;
+
+
+/*--------------------------------------------------------------------.
+| yysetstate -- set current state (the top of the stack) to yystate.  |
+`--------------------------------------------------------------------*/
+yysetstate:
+  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+  YY_ASSERT (0 <= yystate && yystate < YYNSTATES);
+  YY_IGNORE_USELESS_CAST_BEGIN
+  *yyssp = YY_CAST (yy_state_t, yystate);
+  YY_IGNORE_USELESS_CAST_END
+  YY_STACK_PRINT (yyss, yyssp);
+
+  if (yyss + yystacksize - 1 <= yyssp)
+#if !defined yyoverflow && !defined YYSTACK_RELOCATE
+    goto yyexhaustedlab;
+#else
+    {
+      /* Get the current used size of the three stacks, in elements.  */
+      YYPTRDIFF_T yysize = yyssp - yyss + 1;
+
+# if defined yyoverflow
+      {
+        /* Give user a chance to reallocate the stack.  Use copies of
+           these so that the &'s don't force the real ones into
+           memory.  */
+        yy_state_t *yyss1 = yyss;
+        YYSTYPE *yyvs1 = yyvs;
+
+        /* Each stack pointer address is followed by the size of the
+           data in use in that stack, in bytes.  This used to be a
+           conditional around just the two extra args, but that might
+           be undefined if yyoverflow is a macro.  */
+        yyoverflow (YY_("memory exhausted"),
+                    &yyss1, yysize * YYSIZEOF (*yyssp),
+                    &yyvs1, yysize * YYSIZEOF (*yyvsp),
+                    &yystacksize);
+        yyss = yyss1;
+        yyvs = yyvs1;
+      }
+# else /* defined YYSTACK_RELOCATE */
+      /* Extend the stack our own way.  */
+      if (YYMAXDEPTH <= yystacksize)
+        goto yyexhaustedlab;
+      yystacksize *= 2;
+      if (YYMAXDEPTH < yystacksize)
+        yystacksize = YYMAXDEPTH;
+
+      {
+        yy_state_t *yyss1 = yyss;
+        union yyalloc *yyptr =
+          YY_CAST (union yyalloc *,
+                   YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize))));
+        if (! yyptr)
+          goto yyexhaustedlab;
+        YYSTACK_RELOCATE (yyss_alloc, yyss);
+        YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+#  undef YYSTACK_RELOCATE
+        if (yyss1 != yyssa)
+          YYSTACK_FREE (yyss1);
+      }
+# endif
+
+      yyssp = yyss + yysize - 1;
+      yyvsp = yyvs + yysize - 1;
+
+      YY_IGNORE_USELESS_CAST_BEGIN
+      YYDPRINTF ((stderr, "Stack size increased to %ld\n",
+                  YY_CAST (long, yystacksize)));
+      YY_IGNORE_USELESS_CAST_END
+
+      if (yyss + yystacksize - 1 <= yyssp)
+        YYABORT;
+    }
+#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
+
+  if (yystate == YYFINAL)
+    YYACCEPT;
+
+  goto yybackup;
+
+
+/*-----------.
+| yybackup.  |
+`-----------*/
+yybackup:
+  /* Do appropriate processing given the current state.  Read a
+     lookahead token if we need one and don't already have one.  */
+
+  /* First try to decide what to do without reference to lookahead token.  */
+  yyn = yypact[yystate];
+  if (yypact_value_is_default (yyn))
+    goto yydefault;
+
+  /* Not known => get a lookahead token if don't already have one.  */
+
+  /* YYCHAR is either empty, or end-of-input, or a valid lookahead.  */
+  if (yychar == YYEMPTY)
+    {
+      YYDPRINTF ((stderr, "Reading a token\n"));
+      yychar = yylex ();
+    }
+
+  if (yychar <= YYEOF)
+    {
+      yychar = YYEOF;
+      yytoken = YYSYMBOL_YYEOF;
+      YYDPRINTF ((stderr, "Now at end of input.\n"));
+    }
+  else if (yychar == YYerror)
+    {
+      /* The scanner already issued an error message, process directly
+         to error recovery.  But do not keep the error token as
+         lookahead, it is too special and may lead us to an endless
+         loop in error recovery. */
+      yychar = YYUNDEF;
+      yytoken = YYSYMBOL_YYerror;
+      goto yyerrlab1;
+    }
+  else
+    {
+      yytoken = YYTRANSLATE (yychar);
+      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+    }
+
+  /* If the proper action on seeing token YYTOKEN is to reduce or to
+     detect an error, take that action.  */
+  yyn += yytoken;
+  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+    goto yydefault;
+  yyn = yytable[yyn];
+  if (yyn <= 0)
+    {
+      if (yytable_value_is_error (yyn))
+        goto yyerrlab;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+
+  /* Count tokens shifted since error; after three, turn off error
+     status.  */
+  if (yyerrstatus)
+    yyerrstatus--;
+
+  /* Shift the lookahead token.  */
+  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+  yystate = yyn;
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+  *++yyvsp = yylval;
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
+
+  /* Discard the shifted token.  */
+  yychar = YYEMPTY;
+  goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state.  |
+`-----------------------------------------------------------*/
+yydefault:
+  yyn = yydefact[yystate];
+  if (yyn == 0)
+    goto yyerrlab;
+  goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- do a reduction.  |
+`-----------------------------*/
+yyreduce:
+  /* yyn is the number of a rule to reduce with.  */
+  yylen = yyr2[yyn];
+
+  /* If YYLEN is nonzero, implement the default value of the action:
+     '$$ = $1'.
+
+     Otherwise, the following line sets YYVAL to garbage.
+     This behavior is undocumented and Bison
+     users should not rely upon it.  Assigning to YYVAL
+     unconditionally makes the parser a bit smaller, and it avoids a
+     GCC warning that YYVAL may be used uninitialized.  */
+  yyval = yyvsp[1-yylen];
+
+
+  YY_REDUCE_PRINT (yyn);
+  switch (yyn)
+    {
+  case 4: /* mainmenu_stmt: T_MAINMENU T_WORD_QUOTE T_EOL  */
+{
+	menu_add_prompt(P_MENU, (yyvsp[-1].string), NULL);
+}
+    break;
+
+  case 14: /* stmt_list: stmt_list T_WORD error T_EOL  */
+                                        { zconf_error("unknown statement \"%s\"", \
(yyvsp[-2].string)); } +    break;
+
+  case 15: /* stmt_list: stmt_list error T_EOL  */
+                                        { zconf_error("invalid statement"); }
+    break;
+
+  case 20: /* stmt_list_in_choice: stmt_list_in_choice error T_EOL  */
+                                                { zconf_error("invalid statement"); \
} +    break;
+
+  case 21: /* config_entry_start: T_CONFIG nonconst_symbol T_EOL  */
+{
+	(yyvsp[-1].symbol)->flags |= SYMBOL_OPTIONAL;
+	menu_add_entry((yyvsp[-1].symbol));
+	printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), \
(yyvsp[-1].symbol)->name); +}
+    break;
+
+  case 22: /* config_stmt: config_entry_start config_option_list  */
+{
+	printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
+}
+    break;
+
+  case 23: /* menuconfig_entry_start: T_MENUCONFIG nonconst_symbol T_EOL  */
+{
+	(yyvsp[-1].symbol)->flags |= SYMBOL_OPTIONAL;
+	menu_add_entry((yyvsp[-1].symbol));
+	printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), \
(yyvsp[-1].symbol)->name); +}
+    break;
+
+  case 24: /* menuconfig_stmt: menuconfig_entry_start config_option_list  */
+{
+	if (current_entry->prompt)
+		current_entry->prompt->type = P_MENU;
+	else
+		zconfprint("warning: menuconfig statement without prompt");
+	printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
+}
+    break;
+
+  case 29: /* config_option: type prompt_stmt_opt T_EOL  */
+{
+	menu_set_type((yyvsp[-2].type));
+	printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
+		zconf_curname(), zconf_lineno(),
+		(yyvsp[-2].type));
+}
+    break;
+
+  case 30: /* config_option: T_PROMPT T_WORD_QUOTE if_expr T_EOL  */
+{
+	menu_add_prompt(P_PROMPT, (yyvsp[-2].string), (yyvsp[-1].expr));
+	printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
+}
+    break;
+
+  case 31: /* config_option: default expr if_expr T_EOL  */
+{
+	menu_add_expr(P_DEFAULT, (yyvsp[-2].expr), (yyvsp[-1].expr));
+	if ((yyvsp[-3].type) != S_UNKNOWN)
+		menu_set_type((yyvsp[-3].type));
+	printd(DEBUG_PARSE, "%s:%d:default(%u)\n",
+		zconf_curname(), zconf_lineno(),
+		(yyvsp[-3].type));
+}
+    break;
+
+  case 32: /* config_option: T_SELECT nonconst_symbol if_expr T_EOL  */
+{
+	menu_add_symbol(P_SELECT, (yyvsp[-2].symbol), (yyvsp[-1].expr));
+	printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
+}
+    break;
+
+  case 33: /* config_option: T_IMPLY nonconst_symbol if_expr T_EOL  */
+{
+	menu_add_symbol(P_IMPLY, (yyvsp[-2].symbol), (yyvsp[-1].expr));
+	printd(DEBUG_PARSE, "%s:%d:imply\n", zconf_curname(), zconf_lineno());
+}
+    break;
+
+  case 34: /* config_option: T_RANGE symbol symbol if_expr T_EOL  */
+{
+	menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,(yyvsp[-3].symbol), \
(yyvsp[-2].symbol)), (yyvsp[-1].expr)); +	printd(DEBUG_PARSE, "%s:%d:range\n", \
zconf_curname(), zconf_lineno()); +}
+    break;
+
+  case 35: /* config_option: T_OPTION T_MODULES T_EOL  */
+{
+	menu_add_option_modules();
+}
+    break;
+
+  case 36: /* config_option: T_OPTION T_DEFCONFIG_LIST T_EOL  */
+{
+	menu_add_option_defconfig_list();
+}
+    break;
+
+  case 37: /* config_option: T_OPTION T_ALLNOCONFIG_Y T_EOL  */
+{
+	menu_add_option_allnoconfig_y();
+}
+    break;
+
+  case 38: /* choice: T_CHOICE word_opt T_EOL  */
+{
+	struct symbol *sym = sym_lookup((yyvsp[-1].string), SYMBOL_CHOICE);
+	sym->flags |= SYMBOL_NO_WRITE;
+	menu_add_entry(sym);
+	menu_add_expr(P_CHOICE, NULL, NULL);
+	free((yyvsp[-1].string));
+	printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno());
+}
+    break;
+
+  case 39: /* choice_entry: choice choice_option_list  */
+{
+	(yyval.menu) = menu_add_menu();
+}
+    break;
+
+  case 40: /* choice_end: end  */
+{
+	if (zconf_endtoken((yyvsp[0].string), "choice")) {
+		menu_end_menu();
+		printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno());
+	}
+}
+    break;
+
+  case 46: /* choice_option: T_PROMPT T_WORD_QUOTE if_expr T_EOL  */
+{
+	menu_add_prompt(P_PROMPT, (yyvsp[-2].string), (yyvsp[-1].expr));
+	printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
+}
+    break;
+
+  case 47: /* choice_option: logic_type prompt_stmt_opt T_EOL  */
+{
+	menu_set_type((yyvsp[-2].type));
+	printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
+	       zconf_curname(), zconf_lineno(), (yyvsp[-2].type));
+}
+    break;
+
+  case 48: /* choice_option: T_OPTIONAL T_EOL  */
+{
+	current_entry->sym->flags |= SYMBOL_OPTIONAL;
+	printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno());
+}
+    break;
+
+  case 49: /* choice_option: T_DEFAULT nonconst_symbol if_expr T_EOL  */
+{
+	menu_add_symbol(P_DEFAULT, (yyvsp[-2].symbol), (yyvsp[-1].expr));
+	printd(DEBUG_PARSE, "%s:%d:default\n",
+	       zconf_curname(), zconf_lineno());
+}
+    break;
+
+  case 51: /* type: T_INT  */
+                                { (yyval.type) = S_INT; }
+    break;
+
+  case 52: /* type: T_HEX  */
+                                { (yyval.type) = S_HEX; }
+    break;
+
+  case 53: /* type: T_STRING  */
+                                { (yyval.type) = S_STRING; }
+    break;
+
+  case 54: /* logic_type: T_BOOL  */
+                                { (yyval.type) = S_BOOLEAN; }
+    break;
+
+  case 55: /* logic_type: T_TRISTATE  */
+                                { (yyval.type) = S_TRISTATE; }
+    break;
+
+  case 56: /* default: T_DEFAULT  */
+                                { (yyval.type) = S_UNKNOWN; }
+    break;
+
+  case 57: /* default: T_DEF_BOOL  */
+                                { (yyval.type) = S_BOOLEAN; }
+    break;
+
+  case 58: /* default: T_DEF_TRISTATE  */
+                                { (yyval.type) = S_TRISTATE; }
+    break;
+
+  case 59: /* if_entry: T_IF expr T_EOL  */
+{
+	printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
+	menu_add_entry(NULL);
+	menu_add_dep((yyvsp[-1].expr));
+	(yyval.menu) = menu_add_menu();
+}
+    break;
+
+  case 60: /* if_end: end  */
+{
+	if (zconf_endtoken((yyvsp[0].string), "if")) {
+		menu_end_menu();
+		printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno());
+	}
+}
+    break;
+
+  case 63: /* menu: T_MENU T_WORD_QUOTE T_EOL  */
+{
+	menu_add_entry(NULL);
+	menu_add_prompt(P_MENU, (yyvsp[-1].string), NULL);
+	printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
+}
+    break;
+
+  case 64: /* menu_entry: menu menu_option_list  */
+{
+	(yyval.menu) = menu_add_menu();
+}
+    break;
+
+  case 65: /* menu_end: end  */
+{
+	if (zconf_endtoken((yyvsp[0].string), "menu")) {
+		menu_end_menu();
+		printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno());
+	}
+}
+    break;
+
+  case 70: /* source_stmt: T_SOURCE T_WORD_QUOTE T_EOL  */
+{
+	printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), \
(yyvsp[-1].string)); +	zconf_nextfile((yyvsp[-1].string));
+	free((yyvsp[-1].string));
+}
+    break;
+
+  case 71: /* comment: T_COMMENT T_WORD_QUOTE T_EOL  */
+{
+	menu_add_entry(NULL);
+	menu_add_prompt(P_COMMENT, (yyvsp[-1].string), NULL);
+	printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno());
+}
+    break;
+
+  case 75: /* help_start: T_HELP T_EOL  */
+{
+	printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno());
+	zconf_starthelp();
+}
+    break;
+
+  case 76: /* help: help_start T_HELPTEXT  */
+{
+	if (current_entry->help) {
+		free(current_entry->help);
+		zconfprint("warning: '%s' defined with more than one help text -- only the last \
one will be used", +			   current_entry->sym->name ?: "<choice>");
+	}
+
+	/* Is the help text empty or all whitespace? */
+	if ((yyvsp[0].string)[strspn((yyvsp[0].string), " \f\n\r\t\v")] == '\0')
+		zconfprint("warning: '%s' defined with blank help text",
+			   current_entry->sym->name ?: "<choice>");
+
+	current_entry->help = (yyvsp[0].string);
+}
+    break;
+
+  case 77: /* depends: T_DEPENDS T_ON expr T_EOL  */
+{
+	menu_add_dep((yyvsp[-1].expr));
+	printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
+}
+    break;
+
+  case 78: /* visible: T_VISIBLE if_expr T_EOL  */
+{
+	menu_add_visibility((yyvsp[-1].expr));
+}
+    break;
+
+  case 80: /* prompt_stmt_opt: T_WORD_QUOTE if_expr  */
+{
+	menu_add_prompt(P_PROMPT, (yyvsp[-1].string), (yyvsp[0].expr));
+}
+    break;
+
+  case 81: /* end: T_ENDMENU T_EOL  */
+                                { (yyval.string) = "menu"; }
+    break;
+
+  case 82: /* end: T_ENDCHOICE T_EOL  */
+                                { (yyval.string) = "choice"; }
+    break;
+
+  case 83: /* end: T_ENDIF T_EOL  */
+                                { (yyval.string) = "if"; }
+    break;
+
+  case 84: /* if_expr: %empty  */
+                                        { (yyval.expr) = NULL; }
+    break;
+
+  case 85: /* if_expr: T_IF expr  */
+                                        { (yyval.expr) = (yyvsp[0].expr); }
+    break;
+
+  case 86: /* expr: symbol  */
+                                                { (yyval.expr) = \
expr_alloc_symbol((yyvsp[0].symbol)); } +    break;
+
+  case 87: /* expr: symbol T_LESS symbol  */
+                                                { (yyval.expr) = \
expr_alloc_comp(E_LTH, (yyvsp[-2].symbol), (yyvsp[0].symbol)); } +    break;
+
+  case 88: /* expr: symbol T_LESS_EQUAL symbol  */
+                                                { (yyval.expr) = \
expr_alloc_comp(E_LEQ, (yyvsp[-2].symbol), (yyvsp[0].symbol)); } +    break;
+
+  case 89: /* expr: symbol T_GREATER symbol  */
+                                                { (yyval.expr) = \
expr_alloc_comp(E_GTH, (yyvsp[-2].symbol), (yyvsp[0].symbol)); } +    break;
+
+  case 90: /* expr: symbol T_GREATER_EQUAL symbol  */
+                                                { (yyval.expr) = \
expr_alloc_comp(E_GEQ, (yyvsp[-2].symbol), (yyvsp[0].symbol)); } +    break;
+
+  case 91: /* expr: symbol T_EQUAL symbol  */
+                                                { (yyval.expr) = \
expr_alloc_comp(E_EQUAL, (yyvsp[-2].symbol), (yyvsp[0].symbol)); } +    break;
+
+  case 92: /* expr: symbol T_UNEQUAL symbol  */
+                                                { (yyval.expr) = \
expr_alloc_comp(E_UNEQUAL, (yyvsp[-2].symbol), (yyvsp[0].symbol)); } +    break;
+
+  case 93: /* expr: T_OPEN_PAREN expr T_CLOSE_PAREN  */
+                                                { (yyval.expr) = (yyvsp[-1].expr); }
+    break;
+
+  case 94: /* expr: T_NOT expr  */
+                                                { (yyval.expr) = \
expr_alloc_one(E_NOT, (yyvsp[0].expr)); } +    break;
+
+  case 95: /* expr: expr T_OR expr  */
+                                                { (yyval.expr) = \
expr_alloc_two(E_OR, (yyvsp[-2].expr), (yyvsp[0].expr)); } +    break;
+
+  case 96: /* expr: expr T_AND expr  */
+                                                { (yyval.expr) = \
expr_alloc_two(E_AND, (yyvsp[-2].expr), (yyvsp[0].expr)); } +    break;
+
+  case 97: /* nonconst_symbol: T_WORD  */
+                        { (yyval.symbol) = sym_lookup((yyvsp[0].string), 0); \
free((yyvsp[0].string)); } +    break;
+
+  case 99: /* symbol: T_WORD_QUOTE  */
+                        { (yyval.symbol) = sym_lookup((yyvsp[0].string), \
SYMBOL_CONST); free((yyvsp[0].string)); } +    break;
+
+  case 100: /* word_opt: %empty  */
+                                        { (yyval.string) = NULL; }
+    break;
+
+  case 102: /* assignment_stmt: T_WORD assign_op assign_val T_EOL  */
+                                                        { \
variable_add((yyvsp[-3].string), (yyvsp[-1].string), (yyvsp[-2].flavor)); \
free((yyvsp[-3].string)); free((yyvsp[-1].string)); } +    break;
+
+  case 103: /* assign_op: T_EQUAL  */
+                        { (yyval.flavor) = VAR_RECURSIVE; }
+    break;
+
+  case 104: /* assign_op: T_COLON_EQUAL  */
+                        { (yyval.flavor) = VAR_SIMPLE; }
+    break;
+
+  case 105: /* assign_op: T_PLUS_EQUAL  */
+                        { (yyval.flavor) = VAR_APPEND; }
+    break;
+
+  case 106: /* assign_val: %empty  */
+                                { (yyval.string) = xstrdup(""); }
+    break;
+
+
+
+      default: break;
+    }
+  /* User semantic actions sometimes alter yychar, and that requires
+     that yytoken be updated with the new translation.  We take the
+     approach of translating immediately before every use of yytoken.
+     One alternative is translating here after every semantic action,
+     but that translation would be missed if the semantic action invokes
+     YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
+     if it invokes YYBACKUP.  In the case of YYABORT or YYACCEPT, an
+     incorrect destructor might then be invoked immediately.  In the
+     case of YYERROR or YYBACKUP, subsequent parser actions might lead
+     to an incorrect destructor call or verbose syntax error message
+     before the lookahead is translated.  */
+  YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc);
+
+  YYPOPSTACK (yylen);
+  yylen = 0;
+
+  *++yyvsp = yyval;
+
+  /* Now 'shift' the result of the reduction.  Determine what state
+     that goes to, based on the state we popped back to and the rule
+     number reduced by.  */
+  {
+    const int yylhs = yyr1[yyn] - YYNTOKENS;
+    const int yyi = yypgoto[yylhs] + *yyssp;
+    yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp
+               ? yytable[yyi]
+               : yydefgoto[yylhs]);
+  }
+
+  goto yynewstate;
+
+
+/*--------------------------------------.
+| yyerrlab -- here on detecting error.  |
+`--------------------------------------*/
+yyerrlab:
+  /* Make sure we have latest lookahead translation.  See comments at
+     user semantic actions for why this is necessary.  */
+  yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar);
+  /* If not already recovering from an error, report this error.  */
+  if (!yyerrstatus)
+    {
+      ++yynerrs;
+      yyerror (YY_("syntax error"));
+    }
+
+  if (yyerrstatus == 3)
+    {
+      /* If just tried and failed to reuse lookahead token after an
+         error, discard it.  */
+
+      if (yychar <= YYEOF)
+        {
+          /* Return failure if at end of input.  */
+          if (yychar == YYEOF)
+            YYABORT;
+        }
+      else
+        {
+          yydestruct ("Error: discarding",
+                      yytoken, &yylval);
+          yychar = YYEMPTY;
+        }
+    }
+
+  /* Else will try to reuse lookahead token after shifting the error
+     token.  */
+  goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR.  |
+`---------------------------------------------------*/
+yyerrorlab:
+  /* Pacify compilers when the user code never invokes YYERROR and the
+     label yyerrorlab therefore never appears in user code.  */
+  if (0)
+    YYERROR;
+
+  /* Do not reclaim the symbols of the rule whose action triggered
+     this YYERROR.  */
+  YYPOPSTACK (yylen);
+  yylen = 0;
+  YY_STACK_PRINT (yyss, yyssp);
+  yystate = *yyssp;
+  goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR.  |
+`-------------------------------------------------------------*/
+yyerrlab1:
+  yyerrstatus = 3;      /* Each real token shifted decrements this.  */
+
+  /* Pop stack until we find a state that shifts the error token.  */
+  for (;;)
+    {
+      yyn = yypact[yystate];
+      if (!yypact_value_is_default (yyn))
+        {
+          yyn += YYSYMBOL_YYerror;
+          if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror)
+            {
+              yyn = yytable[yyn];
+              if (0 < yyn)
+                break;
+            }
+        }
+
+      /* Pop the current state because it cannot handle the error token.  */
+      if (yyssp == yyss)
+        YYABORT;
+
+
+      yydestruct ("Error: popping",
+                  YY_ACCESSING_SYMBOL (yystate), yyvsp);
+      YYPOPSTACK (1);
+      yystate = *yyssp;
+      YY_STACK_PRINT (yyss, yyssp);
+    }
+
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+  *++yyvsp = yylval;
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
+
+
+  /* Shift the error token.  */
+  YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp);
+
+  yystate = yyn;
+  goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here.  |
+`-------------------------------------*/
+yyacceptlab:
+  yyresult = 0;
+  goto yyreturn;
+
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here.  |
+`-----------------------------------*/
+yyabortlab:
+  yyresult = 1;
+  goto yyreturn;
+
+
+#if !defined yyoverflow
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here.  |
+`-------------------------------------------------*/
+yyexhaustedlab:
+  yyerror (YY_("memory exhausted"));
+  yyresult = 2;
+  goto yyreturn;
+#endif
+
+
+/*-------------------------------------------------------.
+| yyreturn -- parsing is finished, clean up and return.  |
+`-------------------------------------------------------*/
+yyreturn:
+  if (yychar != YYEMPTY)
+    {
+      /* Make sure we have latest lookahead translation.  See comments at
+         user semantic actions for why this is necessary.  */
+      yytoken = YYTRANSLATE (yychar);
+      yydestruct ("Cleanup: discarding lookahead",
+                  yytoken, &yylval);
+    }
+  /* Do not reclaim the symbols of the rule whose action triggered
+     this YYABORT or YYACCEPT.  */
+  YYPOPSTACK (yylen);
+  YY_STACK_PRINT (yyss, yyssp);
+  while (yyssp != yyss)
+    {
+      yydestruct ("Cleanup: popping",
+                  YY_ACCESSING_SYMBOL (+*yyssp), yyvsp);
+      YYPOPSTACK (1);
+    }
+#ifndef yyoverflow
+  if (yyss != yyssa)
+    YYSTACK_FREE (yyss);
+#endif
+
+  return yyresult;
+}
+
+
+
+void conf_parse(const char *name)
+{
+	struct symbol *sym;
+	int i;
+
+	zconf_initscan(name);
+
+	_menu_init();
+
+	if (getenv("ZCONF_DEBUG"))
+		yydebug = 1;
+	yyparse();
+
+	/* Variables are expanded in the parse phase. We can free them here. */
+	variable_all_del();
+
+	if (yynerrs)
+		exit(1);
+	if (!modules_sym)
+		modules_sym = sym_find( "n" );
+
+	if (!menu_has_prompt(&rootmenu)) {
+		current_entry = &rootmenu;
+		menu_add_prompt(P_MENU, "Main menu", NULL);
+	}
+
+	menu_finalize(&rootmenu);
+	for_all_symbols(i, sym) {
+		if (sym_check_deps(sym))
+			yynerrs++;
+	}
+	if (yynerrs)
+		exit(1);
+	sym_set_change_count(1);
+}
+
+static bool zconf_endtoken(const char *tokenname,
+			   const char *expected_tokenname)
+{
+	if (strcmp(tokenname, expected_tokenname)) {
+		zconf_error("unexpected '%s' within %s block",
+			    tokenname, expected_tokenname);
+		yynerrs++;
+		return false;
+	}
+	if (current_menu->file != current_file) {
+		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,
+			expected_tokenname);
+		yynerrs++;
+		return false;
+	}
+	return true;
+}
+
+static void zconfprint(const char *err, ...)
+{
+	va_list ap;
+
+	fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
+	va_start(ap, err);
+	vfprintf(stderr, err, ap);
+	va_end(ap);
+	fprintf(stderr, "\n");
+}
+
+static void zconf_error(const char *err, ...)
+{
+	va_list ap;
+
+	yynerrs++;
+	fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
+	va_start(ap, err);
+	vfprintf(stderr, err, ap);
+	va_end(ap);
+	fprintf(stderr, "\n");
+}
+
+static void yyerror(const char *err)
+{
+	fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
+}
+
+static void print_quoted_string(FILE *out, const char *str)
+{
+	const char *p;
+	int len;
+
+	putc('"', out);
+	while ((p = strchr(str, '"'))) {
+		len = p - str;
+		if (len)
+			fprintf(out, "%.*s", len, str);
+		fputs("\\\"", out);
+		str = p + 1;
+	}
+	fputs(str, out);
+	putc('"', out);
+}
+
+static void print_symbol(FILE *out, struct menu *menu)
+{
+	struct symbol *sym = menu->sym;
+	struct property *prop;
+
+	if (sym_is_choice(sym))
+		fprintf(out, "\nchoice\n");
+	else
+		fprintf(out, "\nconfig %s\n", sym->name);
+	switch (sym->type) {
+	case S_BOOLEAN:
+		fputs("  bool\n", out);
+		break;
+	case S_TRISTATE:
+		fputs("  tristate\n", out);
+		break;
+	case S_STRING:
+		fputs("  string\n", out);
+		break;
+	case S_INT:
+		fputs("  integer\n", out);
+		break;
+	case S_HEX:
+		fputs("  hex\n", out);
+		break;
+	default:
+		fputs("  ???\n", out);
+		break;
+	}
+	for (prop = sym->prop; prop; prop = prop->next) {
+		if (prop->menu != menu)
+			continue;
+		switch (prop->type) {
+		case P_PROMPT:
+			fputs("  prompt ", out);
+			print_quoted_string(out, prop->text);
+			if (!expr_is_yes(prop->visible.expr)) {
+				fputs(" if ", out);
+				expr_fprint(prop->visible.expr, out);
+			}
+			fputc('\n', out);
+			break;
+		case P_DEFAULT:
+			fputs( "  default ", out);
+			expr_fprint(prop->expr, out);
+			if (!expr_is_yes(prop->visible.expr)) {
+				fputs(" if ", out);
+				expr_fprint(prop->visible.expr, out);
+			}
+			fputc('\n', out);
+			break;
+		case P_CHOICE:
+			fputs("  #choice value\n", out);
+			break;
+		case P_SELECT:
+			fputs( "  select ", out);
+			expr_fprint(prop->expr, out);
+			fputc('\n', out);
+			break;
+		case P_IMPLY:
+			fputs( "  imply ", out);
+			expr_fprint(prop->expr, out);
+			fputc('\n', out);
+			break;
+		case P_RANGE:
+			fputs( "  range ", out);
+			expr_fprint(prop->expr, out);
+			fputc('\n', out);
+			break;
+		case P_MENU:
+			fputs( "  menu ", out);
+			print_quoted_string(out, prop->text);
+			fputc('\n', out);
+			break;
+		case P_SYMBOL:
+			fputs( "  symbol ", out);
+			fprintf(out, "%s\n", prop->menu->sym->name);
+			break;
+		default:
+			fprintf(out, "  unknown prop %d!\n", prop->type);
+			break;
+		}
+	}
+	if (menu->help) {
+		int len = strlen(menu->help);
+		while (menu->help[--len] == '\n')
+			menu->help[len] = 0;
+		fprintf(out, "  help\n%s\n", menu->help);
+	}
+}
+
+void zconfdump(FILE *out)
+{
+	struct property *prop;
+	struct symbol *sym;
+	struct menu *menu;
+
+	menu = rootmenu.list;
+	while (menu) {
+		if ((sym = menu->sym))
+			print_symbol(out, menu);
+		else if ((prop = menu->prompt)) {
+			switch (prop->type) {
+			case P_COMMENT:
+				fputs("\ncomment ", out);
+				print_quoted_string(out, prop->text);
+				fputs("\n", out);
+				break;
+			case P_MENU:
+				fputs("\nmenu ", out);
+				print_quoted_string(out, prop->text);
+				fputs("\n", out);
+				break;
+			default:
+				;
+			}
+			if (!expr_is_yes(prop->visible.expr)) {
+				fputs("  depends ", out);
+				expr_fprint(prop->visible.expr, out);
+				fputc('\n', out);
+			}
+		}
+
+		if (menu->list)
+			menu = menu->list;
+		else if (menu->next)
+			menu = menu->next;
+		else while ((menu = menu->parent)) {
+			if (menu->prompt && menu->prompt->type == P_MENU)
+				fputs("\nendmenu\n", out);
+			if (menu->next) {
+				menu = menu->next;
+				break;
+			}
+		}
+	}
+}
+
+#include "menu.c"
diff --git a/scripts/kconfig/parser.tab.h_shipped \
b/scripts/kconfig/parser.tab.h_shipped new file mode 100644
index 000000000..5b112fc3e
--- /dev/null
+++ b/scripts/kconfig/parser.tab.h_shipped
@@ -0,0 +1,135 @@
+/* A Bison parser, made by GNU Bison 3.7.6.  */
+
+/* Bison interface for Yacc-like parsers in C
+
+   Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
+   Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+/* As a special exception, you may create a larger work that contains
+   part or all of the Bison parser skeleton and distribute that work
+   under terms of your choice, so long as that work isn't itself a
+   parser generator using the skeleton or a modified version thereof
+   as a parser skeleton.  Alternatively, if you modify or redistribute
+   the parser skeleton itself, you may (at your option) remove this
+   special exception, which will cause the skeleton and the resulting
+   Bison output files to be licensed under the GNU General Public
+   License without this special exception.
+
+   This special exception was added by the Free Software Foundation in
+   version 2.2 of Bison.  */
+
+/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
+   especially those whose name start with YY_ or yy_.  They are
+   private implementation details that can be changed or removed.  */
+
+#ifndef YY_YY_SCRIPTS_KCONFIG_PARSER_TAB_H_INCLUDED
+# define YY_YY_SCRIPTS_KCONFIG_PARSER_TAB_H_INCLUDED
+/* Debug traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 1
+#endif
+#if YYDEBUG
+extern int yydebug;
+#endif
+
+/* Token kinds.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+  enum yytokentype
+  {
+    YYEMPTY = -2,
+    YYEOF = 0,                     /* "end of file"  */
+    YYerror = 256,                 /* error  */
+    YYUNDEF = 257,                 /* "invalid token"  */
+    T_HELPTEXT = 258,              /* T_HELPTEXT  */
+    T_WORD = 259,                  /* T_WORD  */
+    T_WORD_QUOTE = 260,            /* T_WORD_QUOTE  */
+    T_ALLNOCONFIG_Y = 261,         /* T_ALLNOCONFIG_Y  */
+    T_BOOL = 262,                  /* T_BOOL  */
+    T_CHOICE = 263,                /* T_CHOICE  */
+    T_CLOSE_PAREN = 264,           /* T_CLOSE_PAREN  */
+    T_COLON_EQUAL = 265,           /* T_COLON_EQUAL  */
+    T_COMMENT = 266,               /* T_COMMENT  */
+    T_CONFIG = 267,                /* T_CONFIG  */
+    T_DEFAULT = 268,               /* T_DEFAULT  */
+    T_DEFCONFIG_LIST = 269,        /* T_DEFCONFIG_LIST  */
+    T_DEF_BOOL = 270,              /* T_DEF_BOOL  */
+    T_DEF_TRISTATE = 271,          /* T_DEF_TRISTATE  */
+    T_DEPENDS = 272,               /* T_DEPENDS  */
+    T_ENDCHOICE = 273,             /* T_ENDCHOICE  */
+    T_ENDIF = 274,                 /* T_ENDIF  */
+    T_ENDMENU = 275,               /* T_ENDMENU  */
+    T_HELP = 276,                  /* T_HELP  */
+    T_HEX = 277,                   /* T_HEX  */
+    T_IF = 278,                    /* T_IF  */
+    T_IMPLY = 279,                 /* T_IMPLY  */
+    T_INT = 280,                   /* T_INT  */
+    T_MAINMENU = 281,              /* T_MAINMENU  */
+    T_MENU = 282,                  /* T_MENU  */
+    T_MENUCONFIG = 283,            /* T_MENUCONFIG  */
+    T_MODULES = 284,               /* T_MODULES  */
+    T_ON = 285,                    /* T_ON  */
+    T_OPEN_PAREN = 286,            /* T_OPEN_PAREN  */
+    T_OPTION = 287,                /* T_OPTION  */
+    T_OPTIONAL = 288,              /* T_OPTIONAL  */
+    T_PLUS_EQUAL = 289,            /* T_PLUS_EQUAL  */
+    T_PROMPT = 290,                /* T_PROMPT  */
+    T_RANGE = 291,                 /* T_RANGE  */
+    T_SELECT = 292,                /* T_SELECT  */
+    T_SOURCE = 293,                /* T_SOURCE  */
+    T_STRING = 294,                /* T_STRING  */
+    T_TRISTATE = 295,              /* T_TRISTATE  */
+    T_VISIBLE = 296,               /* T_VISIBLE  */
+    T_EOL = 297,                   /* T_EOL  */
+    T_ASSIGN_VAL = 298,            /* T_ASSIGN_VAL  */
+    T_OR = 299,                    /* T_OR  */
+    T_AND = 300,                   /* T_AND  */
+    T_EQUAL = 301,                 /* T_EQUAL  */
+    T_UNEQUAL = 302,               /* T_UNEQUAL  */
+    T_LESS = 303,                  /* T_LESS  */
+    T_LESS_EQUAL = 304,            /* T_LESS_EQUAL  */
+    T_GREATER = 305,               /* T_GREATER  */
+    T_GREATER_EQUAL = 306,         /* T_GREATER_EQUAL  */
+    T_NOT = 307                    /* T_NOT  */
+  };
+  typedef enum yytokentype yytoken_kind_t;
+#endif
+
+/* Value type.  */
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+union YYSTYPE
+{
+
+	char *string;
+	struct symbol *symbol;
+	struct expr *expr;
+	struct menu *menu;
+	enum symbol_type type;
+	enum variable_flavor flavor;
+
+
+};
+typedef union YYSTYPE YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+
+extern YYSTYPE yylval;
+
+int yyparse (void);
+
+#endif /* !YY_YY_SCRIPTS_KCONFIG_PARSER_TAB_H_INCLUDED  */
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index fe38e6fd2..c2d8e0eba 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -86,7 +86,8 @@ static struct property *sym_get_default_prop(struct symbol *sym)
 
 	for_all_defaults(sym, prop) {
 		prop->visible.tri = expr_calc_value(prop->visible.expr);
-		if (prop->visible.tri != no)
+		/* bbox: we need the default value for all symbols */
+		/* if (prop->visible.tri != no) */
 			return prop;
 	}
 	return NULL;
diff --git a/scripts/objsizes b/scripts/objsizes
index 6df0c4fac..9b297dd16 100755
--- a/scripts/objsizes
+++ b/scripts/objsizes
@@ -6,7 +6,7 @@ t_bss=0
 
 printf "%9s %11s %9s %9s %s\n" "text+data" "text+rodata" rwdata bss filename
 
-find -name '*.o' | grep -v '^\./scripts/' | grep -vF built-in.o \
+find . -name '*.o' | grep -v '^\./scripts/' \
 | sed 's:^\./::' | xargs "${CROSS_COMPILE}size" | grep '^ *[0-9]' \
 | {
 while read text data bss dec hex filename; do
-- 
2.31.1


["0004-build-system-update-kconfig-and-some-dependencies-wi.patch" (application/x-patch)]

From 1ec5e55dc66d732a542080944fc8150303a68c35 Mon Sep 17 00:00:00 2001
From: Xabier Oneca <xoneca@gmail.com>
Date: Fri, 30 Apr 2021 00:43:55 +0200
Subject: [RFC PATCH 4/5] build system: update kconfig and some dependencies
 with upstream

Update Kconfig with upstream (Linux) version 5ffe04ccd69a. Testsuite is not
included.

The code is taken as-is, without any Busybox customizations, so it does still
not build.

Also updated some dependencies. Mainly from scripts/ folder.

Signed-off-by: Xabier Oneca <xoneca@gmail.com>
---
 scripts/Kbuild.include                     |  342 ++-
 scripts/Kconfig.include                    |   59 +
 scripts/Makefile.build                     |  602 +++--
 scripts/Makefile.clean                     |   76 +-
 scripts/Makefile.host                      |  139 +-
 scripts/Makefile.lib                       |  516 ++++-
 scripts/basic/.gitignore                   |    4 +-
 scripts/basic/Makefile                     |   21 +-
 scripts/basic/docproc.c                    |  400 ----
 scripts/basic/fixdep.c                     |  456 ++--
 scripts/basic/split-include.c              |  228 --
 scripts/cc-version.sh                      |   82 +
 scripts/gcc-version.sh                     |   29 +-
 scripts/kconfig/.gitignore                 |   15 +-
 scripts/kconfig/Makefile                   |  379 ++--
 scripts/kconfig/POTFILES.in                |    5 -
 scripts/kconfig/check.sh                   |   13 -
 scripts/kconfig/conf.c                     |  643 +++---
 scripts/kconfig/confdata.c                 | 1538 +++++++++----
 scripts/kconfig/expr.c                     |  566 +++--
 scripts/kconfig/expr.h                     |  244 +-
 scripts/kconfig/gconf-cfg.sh               |   30 +
 scripts/kconfig/gconf.c                    |  375 ++--
 scripts/kconfig/gconf.glade                |   35 +-
 scripts/kconfig/images.c                   |   34 +-
 scripts/kconfig/images.h                   |   33 +
 scripts/kconfig/kconfig_load.c             |   35 -
 scripts/kconfig/kxgettext.c                |  227 --
 scripts/kconfig/lex.zconf.c_shipped        | 2325 --------------------
 scripts/kconfig/lexer.l                    |  470 ++++
 scripts/kconfig/list.h                     |  132 ++
 scripts/kconfig/lkc.h                      |  144 +-
 scripts/kconfig/lkc_proto.h                |   76 +-
 scripts/kconfig/lxdialog/.gitignore        |    4 -
 scripts/kconfig/lxdialog/BIG.FAT.WARNING   |    6 +-
 scripts/kconfig/lxdialog/Makefile          |   21 -
 scripts/kconfig/lxdialog/check-lxdialog.sh |   91 -
 scripts/kconfig/lxdialog/checklist.c       |  208 +-
 scripts/kconfig/lxdialog/colors.h          |  154 --
 scripts/kconfig/lxdialog/dialog.h          |  195 +-
 scripts/kconfig/lxdialog/inputbox.c        |  197 +-
 scripts/kconfig/lxdialog/lxdialog.c        |  204 --
 scripts/kconfig/lxdialog/menubox.c         |  226 +-
 scripts/kconfig/lxdialog/msgbox.c          |   71 -
 scripts/kconfig/lxdialog/textbox.c         |  522 ++---
 scripts/kconfig/lxdialog/util.c            |  614 ++++--
 scripts/kconfig/lxdialog/yesno.c           |   45 +-
 scripts/kconfig/mconf-cfg.sh               |   52 +
 scripts/kconfig/mconf.c                    | 1166 +++++-----
 scripts/kconfig/menu.c                     |  657 +++++-
 scripts/kconfig/merge_config.sh            |  189 ++
 scripts/kconfig/nconf-cfg.sh               |   50 +
 scripts/kconfig/nconf.c                    | 1555 +++++++++++++
 scripts/kconfig/nconf.gui.c                |  664 ++++++
 scripts/kconfig/nconf.h                    |   92 +
 scripts/kconfig/{zconf.y => parser.y}      |  498 +++--
 scripts/kconfig/preprocess.c               |  574 +++++
 scripts/kconfig/qconf-cfg.sh               |   24 +
 scripts/kconfig/qconf.cc                   | 2056 ++++++++++-------
 scripts/kconfig/qconf.h                    |  310 +--
 scripts/kconfig/streamline_config.pl       |  704 ++++++
 scripts/kconfig/symbol.c                   |  870 ++++++--
 scripts/kconfig/util.c                     |  122 +-
 scripts/kconfig/zconf.gperf                |   43 -
 scripts/kconfig/zconf.hash.c_shipped       |  220 --
 scripts/kconfig/zconf.l                    |  355 ---
 scripts/kconfig/zconf.tab.c_shipped        | 2171 ------------------
 scripts/ld-version.sh                      |   79 +
 scripts/mkmakefile                         |   34 +-
 69 files changed, 13433 insertions(+), 11883 deletions(-)
 create mode 100644 scripts/Kconfig.include
 delete mode 100644 scripts/basic/docproc.c
 delete mode 100644 scripts/basic/split-include.c
 create mode 100755 scripts/cc-version.sh
 delete mode 100644 scripts/kconfig/POTFILES.in
 delete mode 100755 scripts/kconfig/check.sh
 create mode 100755 scripts/kconfig/gconf-cfg.sh
 create mode 100644 scripts/kconfig/images.h
 delete mode 100644 scripts/kconfig/kconfig_load.c
 delete mode 100644 scripts/kconfig/kxgettext.c
 delete mode 100644 scripts/kconfig/lex.zconf.c_shipped
 create mode 100644 scripts/kconfig/lexer.l
 create mode 100644 scripts/kconfig/list.h
 delete mode 100644 scripts/kconfig/lxdialog/.gitignore
 delete mode 100644 scripts/kconfig/lxdialog/Makefile
 delete mode 100755 scripts/kconfig/lxdialog/check-lxdialog.sh
 delete mode 100644 scripts/kconfig/lxdialog/colors.h
 delete mode 100644 scripts/kconfig/lxdialog/lxdialog.c
 delete mode 100644 scripts/kconfig/lxdialog/msgbox.c
 create mode 100755 scripts/kconfig/mconf-cfg.sh
 create mode 100755 scripts/kconfig/merge_config.sh
 create mode 100755 scripts/kconfig/nconf-cfg.sh
 create mode 100644 scripts/kconfig/nconf.c
 create mode 100644 scripts/kconfig/nconf.gui.c
 create mode 100644 scripts/kconfig/nconf.h
 rename scripts/kconfig/{zconf.y => parser.y} (54%)
 create mode 100644 scripts/kconfig/preprocess.c
 create mode 100755 scripts/kconfig/qconf-cfg.sh
 create mode 100755 scripts/kconfig/streamline_config.pl
 delete mode 100644 scripts/kconfig/zconf.gperf
 delete mode 100644 scripts/kconfig/zconf.hash.c_shipped
 delete mode 100644 scripts/kconfig/zconf.l
 delete mode 100644 scripts/kconfig/zconf.tab.c_shipped
 create mode 100755 scripts/ld-version.sh

diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index 5b4db5c2c..509e0856d 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -1,109 +1,177 @@
+# SPDX-License-Identifier: GPL-2.0
 ####
 # kbuild: Generic definitions
 
-# Convinient variables
+# Convenient variables
 comma   := ,
-squote  := '
 quote   := "
+squote  := '
 empty   :=
 space   := $(empty) $(empty)
+space_escape := _-_SPACE_-_
+pound := \#
+
+###
+# Name of target with a '.' as filename prefix. foo/bar.o => foo/.bar.o
+dot-target = $(dir $@).$(notdir $@)
 
 ###
-# The temporary file to save gcc -MD generated dependencies must not
+# The temporary file to save gcc -MMD generated dependencies must not
 # contain a comma
-depfile = $(subst $(comma),_,$(@D)/.$(@F).d)
+depfile = $(subst $(comma),_,$(dot-target).d)
+
+###
+# filename of target with directory and extension stripped
+basetarget = $(basename $(notdir $@))
+
+###
+# real prerequisites without phony targets
+real-prereqs = $(filter-out $(PHONY), $^)
 
 ###
 # Escape single quote for use in echo statements
 escsq = $(subst $(squote),'\$(squote)',$1)
 
+###
+# Quote a string to pass it to C files. foo => '"foo"'
+stringify = $(squote)$(quote)$1$(quote)$(squote)
+
+###
+# Easy method for doing a status message
+       kecho := :
+ quiet_kecho := echo
+silent_kecho := :
+kecho := $($(quiet)kecho)
+
 ###
 # filechk is used to check if the content of a generated file is updated.
 # Sample usage:
-# define filechk_sample
-#	echo $KERNELRELEASE
-# endef
-# version.h : Makefile
+#
+# filechk_sample = echo $(KERNELRELEASE)
+# version.h: FORCE
 #	$(call filechk,sample)
+#
 # The rule defined shall write to stdout the content of the new file.
 # The existing file will be compared with the new one.
 # - If no file exist it is created
 # - If the content differ the new file is used
 # - If they are equal no change, and no timestamp update
-# - stdin is piped in from the first prerequisite ($<) so one has
-#   to specify a valid file as first prerequisite (often the kbuild file)
 define filechk
-	$(Q)set -e;				\
-	echo '  CHK     $@';			\
-	mkdir -p $(dir $@);			\
-	$(filechk_$(1)) < $< > $@.tmp;		\
-	if [ -r $@ ] && cmp -s $@ $@.tmp; then	\
-		rm -f $@.tmp;			\
-	else					\
-		echo '  UPD     $@';		\
-		mv -f $@.tmp $@;		\
+	$(Q)set -e;						\
+	mkdir -p $(dir $@);					\
+	trap "rm -f $(dot-target).tmp" EXIT;			\
+	{ $(filechk_$(1)); } > $(dot-target).tmp;		\
+	if [ ! -r $@ ] || ! cmp -s $@ $(dot-target).tmp; then	\
+		$(kecho) '  UPD     $@';			\
+		mv -f $(dot-target).tmp $@;			\
 	fi
 endef
 
 ######
 # gcc support functions
-# See documentation in Documentation/kbuild/makefiles.txt
+# See documentation in Documentation/kbuild/makefiles.rst
+
+# cc-cross-prefix
+# Usage: CROSS_COMPILE := $(call cc-cross-prefix, m68k-linux-gnu- m68k-linux-)
+# Return first <prefix> where a <prefix>gcc is found in PATH.
+# If no gcc found in PATH with listed prefixes return nothing
+#
+# Note: '2>/dev/null' is here to force Make to invoke a shell. Otherwise, it
+# would try to directly execute the shell builtin 'command'. This workaround
+# should be kept for a long time since this issue was fixed only after the
+# GNU Make 4.2.1 release.
+cc-cross-prefix = $(firstword $(foreach c, $(1), \
+			$(if $(shell command -v -- $(c)gcc 2>/dev/null), $(c))))
+
+# output directory for tests below
+TMPOUT = $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/).tmp_$$$$
+
+# try-run
+# Usage: option = $(call try-run, $(CC)...-o "$$TMP",option-ok,otherwise)
+# Exit code chooses option. "$$TMP" serves as a temporary file and is
+# automatically cleaned up.
+try-run = $(shell set -e;		\
+	TMP=$(TMPOUT)/tmp;		\
+	TMPO=$(TMPOUT)/tmp.o;		\
+	mkdir -p $(TMPOUT);		\
+	trap "rm -rf $(TMPOUT)" EXIT;	\
+	if ($(1)) >/dev/null 2>&1;	\
+	then echo "$(2)";		\
+	else echo "$(3)";		\
+	fi)
 
 # as-option
-# Usage: cflags-y += $(call as-option, -Wa$(comma)-isa=foo,)
+# Usage: cflags-y += $(call as-option,-Wa$(comma)-isa=foo,)
 
-as-option = $(shell if $(CC) $(CFLAGS) $(1) -Wa,-Z -c -o /dev/null \
-	     -xassembler /dev/null > /dev/null 2>&1; then echo "$(1)"; \
-	     else echo "$(2)"; fi ;)
+as-option = $(call try-run,\
+	$(CC) $(KBUILD_CFLAGS) $(1) -c -x assembler /dev/null -o "$$TMP",$(1),$(2))
 
-# cc-option
-# Usage: cflags-y += $(call cc-option, -march=winchip-c6, -march=i586)
+# as-instr
+# Usage: cflags-y += $(call as-instr,instr,option1,option2)
 
-cc-option = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \
-             > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;)
+as-instr = $(call try-run,\
+	printf "%b\n" "$(1)" | $(CC) $(KBUILD_AFLAGS) -c -x assembler -o "$$TMP" \
-,$(2),$(3))  
-# hostcc-option
-# Usage: hostcflags-y += $(call hostcc-option, -march=winchip-c6, -march=i586)
+# __cc-option
+# Usage: MY_CFLAGS += $(call \
__cc-option,$(CC),$(MY_CFLAGS),-march=winchip-c6,-march=i586) +__cc-option = $(call \
try-run,\ +	$(1) -Werror $(2) $(3) -c -x c /dev/null -o "$$TMP",$(3),$(4))
 
-hostcc-option = $(shell if $(HOSTCC) $(HOSTCFLAGS) $(1) -S -o /dev/null -xc \
                /dev/null \
-             > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;)
+# cc-option
+# Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586)
 
-# cc-option-yn
-# Usage: flag := $(call cc-option-yn, -march=winchip-c6)
-cc-option-yn = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \
-                > /dev/null 2>&1; then echo "y"; else echo "n"; fi;)
+cc-option = $(call __cc-option, $(CC),\
+	$(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS),$(1),$(2))
 
-# cc-option-align
-# Prefix align with either -falign or -malign
-cc-option-align = $(subst -functions=0,,\
-	$(call cc-option,-falign-functions=0,-malign-functions=0))
+# cc-option-yn
+# Usage: flag := $(call cc-option-yn,-march=winchip-c6)
+cc-option-yn = $(call try-run,\
+	$(CC) -Werror $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -x c /dev/null -o \
"$$TMP",y,n)  
-# cc-version
-# Usage gcc-ver := $(call cc-version, $(CC))
-cc-version = $(shell PATH="$(PATH)" $(CONFIG_SHELL) \
                $(srctree)/scripts/gcc-version.sh \
-              $(if $(1), $(1), $(CC)))
+# cc-disable-warning
+# Usage: cflags-y += $(call cc-disable-warning,unused-but-set-variable)
+cc-disable-warning = $(call try-run,\
+	$(CC) -Werror $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) -W$(strip $(1)) -c -x c /dev/null \
-o "$$TMP",-Wno-$(strip $(1)))  
 # cc-ifversion
 # Usage:  EXTRA_CFLAGS += $(call cc-ifversion, -lt, 0402, -O1)
-cc-ifversion = $(shell if [ $(call cc-version, $(CC)) $(1) $(2) ]; then \
-                       echo $(3); fi;)
+cc-ifversion = $(shell [ $(CONFIG_GCC_VERSION)0 $(1) $(2)000 ] && echo $(3) || echo \
$(4)) +
+# ld-option
+# Usage: KBUILD_LDFLAGS += $(call ld-option, -X, -Y)
+ld-option = $(call try-run, $(LD) $(KBUILD_LDFLAGS) $(1) -v,$(1),$(2),$(3))
+
+# ld-ifversion
+# Usage:  $(call ld-ifversion, -ge, 22252, y)
+ld-ifversion = $(shell [ $(CONFIG_LD_VERSION)0 $(1) $(2)0 ] && echo $(3) || echo \
$(4)) +
+######
 
 ###
 # Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj=
 # Usage:
 # $(Q)$(MAKE) $(build)=dir
-build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj
+build := -f $(srctree)/scripts/Makefile.build obj
 
-# Prefix -I with $(srctree) if it is not an absolute path
-addtree = $(if $(filter-out -I/%,$(1)),$(patsubst -I%,-I$(srctree)/%,$(1))) $(1)
-# Find all -I options and call addtree
-flags = $(foreach o,$($(1)),$(if $(filter -I%,$(o)),$(call addtree,$(o)),$(o)))
+###
+# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.dtbinst obj=
+# Usage:
+# $(Q)$(MAKE) $(dtbinst)=dir
+dtbinst := -f $(srctree)/scripts/Makefile.dtbinst obj
 
-# If quiet is set, only print short version of command
-cmd = @$(echo-cmd) $(cmd_$(1))
+###
+# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.clean obj=
+# Usage:
+# $(Q)$(MAKE) $(clean)=dir
+clean := -f $(srctree)/scripts/Makefile.clean obj
 
-# Add $(obj)/ for paths that is not absolute
-objectify = $(foreach o,$(1),$(if $(filter /%,$(o)),$(o),$(obj)/$(o)))
+# echo command.
+# Short version is used, if $(quiet) equals `quiet_', otherwise full one.
+echo-cmd = $(if $($(quiet)cmd_$(1)),\
+	echo '  $(call escsq,$($(quiet)cmd_$(1)))$(echo-why)';)
+
+# printing commands
+cmd = @set -e; $(echo-cmd) $(cmd_$(1))
 
 ###
 # if_changed      - execute command if any prerequisite is newer than
@@ -111,45 +179,141 @@ objectify = $(foreach o,$(1),$(if $(filter \
/%,$(o)),$(o),$(obj)/$(o)))  # if_changed_dep  - as if_changed, but uses fixdep to \
reveal dependencies  #                   including used config symbols
 # if_changed_rule - as if_changed but execute rule instead
-# See Documentation/kbuild/makefiles.txt for more info
+# See Documentation/kbuild/makefiles.rst for more info
 
 ifneq ($(KBUILD_NOCMDDEP),1)
-# Check if both arguments has same arguments. Result in empty string if equal
-# User may override this check using make KBUILD_NOCMDDEP=1
-arg-check = $(strip $(filter-out $(1), $(2)) $(filter-out $(2), $(1)) )
+# Check if both commands are the same including their order. Result is empty
+# string if equal. User may override this check using make KBUILD_NOCMDDEP=1
+cmd-check = $(filter-out $(subst $(space),$(space_escape),$(strip $(cmd_$@))), \
+                         $(subst $(space),$(space_escape),$(strip $(cmd_$1))))
+else
+cmd-check = $(if $(strip $(cmd_$@)),,1)
 endif
 
-# echo command. Short version is $(quiet) equals quiet, otherwise full command
-echo-cmd = $(if $($(quiet)cmd_$(1)), \
-	echo '  $(call escsq,$($(quiet)cmd_$(1)))';)
+# Replace >$< with >$$< to preserve $ when reloading the .cmd file
+# (needed for make)
+# Replace >#< with >$(pound)< to avoid starting a comment in the .cmd file
+# (needed for make)
+# Replace >'< with >'\''< to be able to enclose the whole string in '...'
+# (needed for the shell)
+make-cmd = $(call escsq,$(subst $(pound),$$(pound),$(subst $$,$$$$,$(cmd_$(1)))))
 
-make-cmd = $(subst \#,\\\#,$(subst $$,$$$$,$(call escsq,$(cmd_$(1)))))
+# Find any prerequisites that are newer than target or that do not exist.
+# (This is not true for now; $? should contain any non-existent prerequisites,
+# but it does not work as expected when .SECONDARY is present. This seems a bug
+# of GNU Make.)
+# PHONY targets skipped in both cases.
+newer-prereqs = $(filter-out $(PHONY),$?)
 
-# function to only execute the passed command if necessary
-# >'< substitution is for echo to work, >$< substitution to preserve $ when \
                reloading .cmd file
-# note: when using inline perl scripts [perl -e '...$$t=1;...'] in $(cmd_xxx) double \
                $$ your perl vars
-#
-if_changed = $(if $(strip $(filter-out $(PHONY),$?)          \
-		$(call arg-check, $(cmd_$(1)), $(cmd_$@)) ), \
-	@set -e; \
-	$(echo-cmd) $(cmd_$(1)); \
-	echo 'cmd_$@ := $(make-cmd)' > $(@D)/.$(@F).cmd)
-
-# execute the command and also postprocess generated .d dependencies
-# file
-if_changed_dep = $(if $(strip $(filter-out $(PHONY),$?)  \
-		$(filter-out FORCE $(wildcard $^),$^)    \
-	$(call arg-check, $(cmd_$(1)), $(cmd_$@)) ),     \
-	@set -e; \
-	$(echo-cmd) $(cmd_$(1)); \
-	scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(@D)/.$(@F).tmp; \
-	rm -f $(depfile); \
-	mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd)
+# Execute command if command has changed or prerequisite(s) are updated.
+if_changed = $(if $(newer-prereqs)$(cmd-check),                              \
+	$(cmd);                                                              \
+	printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd, @:)
+
+# Execute the command and also postprocess generated .d dependencies file.
+if_changed_dep = $(if $(newer-prereqs)$(cmd-check),$(cmd_and_fixdep),@:)
+
+cmd_and_fixdep =                                                             \
+	$(cmd);                                                              \
+	scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(dot-target).cmd;\
+	rm -f $(depfile)
 
 # Usage: $(call if_changed_rule,foo)
-# will check if $(cmd_foo) changed, or any of the prequisites changed,
-# and if so will execute $(rule_foo)
-if_changed_rule = $(if $(strip $(filter-out $(PHONY),$?)            \
-			$(call arg-check, $(cmd_$(1)), $(cmd_$@)) ),\
-			@set -e; \
-			$(rule_$(1)))
+# Will check if $(cmd_foo) or any of the prerequisites changed,
+# and if so will execute $(rule_foo).
+if_changed_rule = $(if $(newer-prereqs)$(cmd-check),$(rule_$(1)),@:)
+
+###
+# why - tell why a target got built
+#       enabled by make V=2
+#       Output (listed in the order they are checked):
+#          (1) - due to target is PHONY
+#          (2) - due to target missing
+#          (3) - due to: file1.h file2.h
+#          (4) - due to command line change
+#          (5) - due to missing .cmd file
+#          (6) - due to target not in $(targets)
+# (1) PHONY targets are always build
+# (2) No target, so we better build it
+# (3) Prerequisite is newer than target
+# (4) The command line stored in the file named dir/.target.cmd
+#     differed from actual command line. This happens when compiler
+#     options changes
+# (5) No dir/.target.cmd file (used to store command line)
+# (6) No dir/.target.cmd file and target not listed in $(targets)
+#     This is a good hint that there is a bug in the kbuild file
+ifeq ($(KBUILD_VERBOSE),2)
+why =                                                                        \
+    $(if $(filter $@, $(PHONY)),- due to target is PHONY,                    \
+        $(if $(wildcard $@),                                                 \
+            $(if $(newer-prereqs),- due to: $(newer-prereqs),                \
+                $(if $(cmd-check),                                           \
+                    $(if $(cmd_$@),- due to command line change,             \
+                        $(if $(filter $@, $(targets)),                       \
+                            - due to missing .cmd file,                      \
+                            - due to $(notdir $@) not in $$(targets)         \
+                         )                                                   \
+                     )                                                       \
+                 )                                                           \
+             ),                                                              \
+             - due to target missing                                         \
+         )                                                                   \
+     )
+
+echo-why = $(call escsq, $(strip $(why)))
+endif
+
+###############################################################################
+#
+# When a Kconfig string contains a filename, it is suitable for
+# passing to shell commands. It is surrounded by double-quotes, and
+# any double-quotes or backslashes within it are escaped by
+# backslashes.
+#
+# This is no use for dependencies or $(wildcard). We need to strip the
+# surrounding quotes and the escaping from quotes and backslashes, and
+# we *do* need to escape any spaces in the string. So, for example:
+#
+# Usage: $(eval $(call config_filename,FOO))
+#
+# Defines FOO_FILENAME based on the contents of the CONFIG_FOO option,
+# transformed as described above to be suitable for use within the
+# makefile.
+#
+# Also, if the filename is a relative filename and exists in the source
+# tree but not the build tree, define FOO_SRCPREFIX as $(srctree)/ to
+# be prefixed to *both* command invocation and dependencies.
+#
+# Note: We also print the filenames in the quiet_cmd_foo text, and
+# perhaps ought to have a version specially escaped for that purpose.
+# But it's only cosmetic, and $(patsubst "%",%,$(CONFIG_FOO)) is good
+# enough.  It'll strip the quotes in the common case where there's no
+# space and it's a simple filename, and it'll retain the quotes when
+# there's a space. There are some esoteric cases in which it'll print
+# the wrong thing, but we don't really care. The actual dependencies
+# and commands *do* get it right, with various combinations of single
+# and double quotes, backslashes and spaces in the filenames.
+#
+###############################################################################
+#
+define config_filename
+ifneq ($$(CONFIG_$(1)),"")
+$(1)_FILENAME := $$(subst \\,\,$$(subst \$$(quote),$$(quote),$$(subst \
$$(space_escape),\$$(space),$$(patsubst "%",%,$$(subst \
$$(space),$$(space_escape),$$(CONFIG_$(1))))))) +ifneq ($$(patsubst /%,%,$$(firstword \
$$($(1)_FILENAME))),$$(firstword $$($(1)_FILENAME))) +else
+ifeq ($$(wildcard $$($(1)_FILENAME)),)
+ifneq ($$(wildcard $$(srctree)/$$($(1)_FILENAME)),)
+$(1)_SRCPREFIX := $(srctree)/
+endif
+endif
+endif
+endif
+endef
+#
+###############################################################################
+
+# delete partially updated (i.e. corrupted) files on error
+.DELETE_ON_ERROR:
+
+# do not delete intermediate files automatically
+.SECONDARY:
diff --git a/scripts/Kconfig.include b/scripts/Kconfig.include
new file mode 100644
index 000000000..58fdb5308
--- /dev/null
+++ b/scripts/Kconfig.include
@@ -0,0 +1,59 @@
+# SPDX-License-Identifier: GPL-2.0-only
+# Kconfig helper macros
+
+# Convenient variables
+comma       := ,
+quote       := "
+squote      := '
+empty       :=
+space       := $(empty) $(empty)
+dollar      := $
+right_paren := )
+left_paren  := (
+
+# $(if-success,<command>,<then>,<else>)
+# Return <then> if <command> exits with 0, <else> otherwise.
+if-success = $(shell,{ $(1); } >/dev/null 2>&1 && echo "$(2)" || echo "$(3)")
+
+# $(success,<command>)
+# Return y if <command> exits with 0, n otherwise
+success = $(if-success,$(1),y,n)
+
+# $(failure,<command>)
+# Return n if <command> exits with 0, y otherwise
+failure = $(if-success,$(1),n,y)
+
+# $(cc-option,<flag>)
+# Return y if the compiler supports <flag>, n otherwise
+cc-option = $(success,mkdir .tmp_$$$$; trap "rm -rf .tmp_$$$$" EXIT; $(CC) -Werror \
$(CLANG_FLAGS) $(1) -c -x c /dev/null -o .tmp_$$$$/tmp.o) +
+# $(ld-option,<flag>)
+# Return y if the linker supports <flag>, n otherwise
+ld-option = $(success,$(LD) -v $(1))
+
+# $(as-instr,<instr>)
+# Return y if the assembler supports <instr>, n otherwise
+as-instr = $(success,printf "%b\n" "$(1)" | $(CC) $(CLANG_FLAGS) -c -x assembler -o \
/dev/null -) +
+# check if $(CC) and $(LD) exist
+$(error-if,$(failure,command -v $(CC)),compiler '$(CC)' not found)
+$(error-if,$(failure,command -v $(LD)),linker '$(LD)' not found)
+
+# Get the compiler name, version, and error out if it is not supported.
+cc-info := $(shell,$(srctree)/scripts/cc-version.sh $(CC))
+$(error-if,$(success,test -z "$(cc-info)"),Sorry$(comma) this compiler is not \
supported.) +cc-name := $(shell,set -- $(cc-info) && echo $1)
+cc-version := $(shell,set -- $(cc-info) && echo $2)
+
+# Get the linker name, version, and error out if it is not supported.
+ld-info := $(shell,$(srctree)/scripts/ld-version.sh $(LD))
+$(error-if,$(success,test -z "$(ld-info)"),Sorry$(comma) this linker is not \
supported.) +ld-name := $(shell,set -- $(ld-info) && echo $1)
+ld-version := $(shell,set -- $(ld-info) && echo $2)
+
+# machine bit flags
+#  $(m32-flag): -m32 if the compiler supports it, or an empty string otherwise.
+#  $(m64-flag): -m64 if the compiler supports it, or an empty string otherwise.
+cc-option-bit = $(if-success,$(CC) -Werror $(1) -E -x c /dev/null -o /dev/null,$(1))
+m32-flag := $(cc-option-bit,-m32)
+m64-flag := $(cc-option-bit,-m64)
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 5eac45f91..1b6094a13 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
 # ==========================================================================
 # Building
 # ==========================================================================
@@ -7,316 +8,513 @@ src := $(obj)
 PHONY := __build
 __build:
 
-# Read .config if it exist, otherwise ignore
--include .config
+# Init all relevant variables used in kbuild files so
+# 1) they have correct type
+# 2) they do not inherit any value from the environment
+obj-y :=
+obj-m :=
+lib-y :=
+lib-m :=
+always-y :=
+always-m :=
+targets :=
+subdir-y :=
+subdir-m :=
+EXTRA_AFLAGS   :=
+EXTRA_CFLAGS   :=
+EXTRA_CPPFLAGS :=
+EXTRA_LDFLAGS  :=
+asflags-y  :=
+ccflags-y  :=
+cppflags-y :=
+ldflags-y  :=
+
+subdir-asflags-y :=
+subdir-ccflags-y :=
+
+# Read auto.conf if it exists, otherwise ignore
+-include include/config/auto.conf
 
 include scripts/Kbuild.include
 
 # The filename Kbuild has precedence over Makefile
-# bbox: we also try to include Kbuild file in obj tree first
 kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
-include $(if $(wildcard $(src)/Kbuild), $(src)/Kbuild, \
-		$(if $(wildcard $(kbuild-dir)/Kbuild), $(kbuild-dir)/Kbuild, \
-			$(kbuild-dir)/Makefile \
-		) \
-	)
+kbuild-file := $(if $(wildcard \
$(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile) +include \
$(kbuild-file)  
 include scripts/Makefile.lib
 
-ifdef host-progs
-ifneq ($(hostprogs-y),$(host-progs))
-$(warning kbuild: $(obj)/Makefile - Usage of host-progs is deprecated. Please \
                replace with hostprogs-y!)
-hostprogs-y += $(host-progs)
-endif
-endif
-
-# Do not include host rules unles needed
-ifneq ($(hostprogs-y)$(hostprogs-m),)
+# Do not include hostprogs rules unless needed.
+# $(sort ...) is used here to remove duplicated words and excessive spaces.
+hostprogs := $(sort $(hostprogs))
+ifneq ($(hostprogs),)
 include scripts/Makefile.host
 endif
 
-ifneq ($(KBUILD_SRC),)
-# Create output directory if not already present
-_dummy := $(shell [ -d $(obj) ] || mkdir -p $(obj))
-
-# Create directories for object files if directory does not exist
-# Needed when obj-y := dir/file.o syntax is used
-_dummy := $(foreach d,$(obj-dirs), $(shell [ -d $(d) ] || mkdir -p $(d)))
+# Do not include userprogs rules unless needed.
+# $(sort ...) is used here to remove duplicated words and excessive spaces.
+userprogs := $(sort $(userprogs))
+ifneq ($(userprogs),)
+include scripts/Makefile.userprogs
 endif
 
-
-ifdef EXTRA_TARGETS
-$(warning kbuild: $(obj)/Makefile - Usage of EXTRA_TARGETS is obsolete in 2.6. \
Please fix!) +ifndef obj
+$(warning kbuild: Makefile.build is included improperly)
 endif
 
-ifdef build-targets
-$(warning kbuild: $(obj)/Makefile - Usage of build-targets is obsolete in 2.6. \
Please fix!) +ifeq ($(need-modorder),)
+ifneq ($(obj-m),)
+$(warning $(patsubst %.o,'%.ko',$(obj-m)) will not be built even though obj-m is \
specified.) +$(warning You cannot use subdir-y/m to visit a module Makefile. Use \
obj-y/m instead.)  endif
-
-ifdef export-objs
-$(warning kbuild: $(obj)/Makefile - Usage of export-objs is obsolete in 2.6. Please \
fix!)  endif
 
-ifdef O_TARGET
-$(warning kbuild: $(obj)/Makefile - Usage of O_TARGET := $(O_TARGET) is obsolete in \
                2.6. Please fix!)
-endif
+# ===========================================================================
 
-ifdef L_TARGET
-$(error kbuild: $(obj)/Makefile - Use of L_TARGET is replaced by lib-y in 2.6. \
                Please fix!)
-endif
+# subdir-builtin and subdir-modorder may contain duplications. Use $(sort ...)
+subdir-builtin := $(sort $(filter %/built-in.a, $(real-obj-y)))
+subdir-modorder := $(sort $(filter %/modules.order, $(obj-m)))
 
-ifdef list-multi
-$(warning kbuild: $(obj)/Makefile - list-multi := $(list-multi) is obsolete in 2.6. \
                Please fix!)
-endif
+targets-for-builtin := $(extra-y)
 
-ifndef obj
-$(warning kbuild: Makefile.build is included improperly)
+ifneq ($(strip $(lib-y) $(lib-m) $(lib-)),)
+targets-for-builtin += $(obj)/lib.a
 endif
 
-# ===========================================================================
-
-ifneq ($(strip $(lib-y) $(lib-m) $(lib-n) $(lib-)),)
-lib-target := $(obj)/lib.a
+ifdef need-builtin
+targets-for-builtin += $(obj)/built-in.a
 endif
 
-ifneq ($(strip $(obj-y) $(obj-m) $(obj-n) $(obj-) $(lib-target)),)
-builtin-target := $(obj)/built-in.o
-endif
+targets-for-modules := $(patsubst %.o, %.mod, $(filter %.o, $(obj-m)))
 
-# We keep a list of all modules in $(MODVERDIR)
+ifdef need-modorder
+targets-for-modules += $(obj)/modules.order
+endif
 
-__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
-	 $(if $(KBUILD_MODULES),$(obj-m)) \
-	 $(subdir-ym) $(always)
-	@:
+targets += $(targets-for-builtin) $(targets-for-modules)
 
 # Linus' kernel sanity checking tool
-ifneq ($(KBUILD_CHECKSRC),0)
-  ifeq ($(KBUILD_CHECKSRC),2)
-    quiet_cmd_force_checksrc = CHECK   $<
-          cmd_force_checksrc = $(CHECK) $(CHECKFLAGS) $(c_flags) $< ;
-  else
-      quiet_cmd_checksrc     = CHECK   $<
-            cmd_checksrc     = $(CHECK) $(CHECKFLAGS) $(c_flags) $< ;
-  endif
+ifeq ($(KBUILD_CHECKSRC),1)
+  quiet_cmd_checksrc       = CHECK   $<
+        cmd_checksrc       = $(CHECK) $(CHECKFLAGS) $(c_flags) $<
+else ifeq ($(KBUILD_CHECKSRC),2)
+  quiet_cmd_force_checksrc = CHECK   $<
+        cmd_force_checksrc = $(CHECK) $(CHECKFLAGS) $(c_flags) $<
 endif
 
+ifneq ($(KBUILD_EXTRA_WARN),)
+  cmd_checkdoc = $(srctree)/scripts/kernel-doc -none $<
+endif
 
 # Compile C sources (.c)
 # ---------------------------------------------------------------------------
 
-# Default is built-in, unless we know otherwise
-modkern_cflags := $(CFLAGS_KERNEL)
-quiet_modtag := $(empty)   $(empty)
-
-$(real-objs-m)        : modkern_cflags := $(CFLAGS_MODULE)
-$(real-objs-m:.o=.i)  : modkern_cflags := $(CFLAGS_MODULE)
-$(real-objs-m:.o=.s)  : modkern_cflags := $(CFLAGS_MODULE)
-$(real-objs-m:.o=.lst): modkern_cflags := $(CFLAGS_MODULE)
+quiet_cmd_cc_s_c = CC $(quiet_modtag)  $@
+      cmd_cc_s_c = $(CC) $(filter-out $(DEBUG_CFLAGS) $(CC_FLAGS_LTO), $(c_flags)) \
-fverbose-asm -S -o $@ $<  
-$(real-objs-m)        : quiet_modtag := [M]
-$(real-objs-m:.o=.i)  : quiet_modtag := [M]
-$(real-objs-m:.o=.s)  : quiet_modtag := [M]
-$(real-objs-m:.o=.lst): quiet_modtag := [M]
+$(obj)/%.s: $(src)/%.c FORCE
+	$(call if_changed_dep,cc_s_c)
 
-$(obj-m)              : quiet_modtag := [M]
+quiet_cmd_cpp_i_c = CPP $(quiet_modtag) $@
+cmd_cpp_i_c       = $(CPP) $(c_flags) -o $@ $<
 
-# Default for not multi-part modules
-modname = $(*F)
+$(obj)/%.i: $(src)/%.c FORCE
+	$(call if_changed_dep,cpp_i_c)
 
-$(multi-objs-m)         : modname = $(modname-multi)
-$(multi-objs-m:.o=.i)   : modname = $(modname-multi)
-$(multi-objs-m:.o=.s)   : modname = $(modname-multi)
-$(multi-objs-m:.o=.lst) : modname = $(modname-multi)
-$(multi-objs-y)         : modname = $(modname-multi)
-$(multi-objs-y:.o=.i)   : modname = $(modname-multi)
-$(multi-objs-y:.o=.s)   : modname = $(modname-multi)
-$(multi-objs-y:.o=.lst) : modname = $(modname-multi)
+# These mirror gensymtypes_S and co below, keep them in synch.
+cmd_gensymtypes_c =                                                         \
+    $(CPP) -D__GENKSYMS__ $(c_flags) $< |                                   \
+    scripts/genksyms/genksyms $(if $(1), -T $(2))                           \
+     $(patsubst y,-R,$(CONFIG_MODULE_REL_CRCS))                             \
+     $(if $(KBUILD_PRESERVE),-p)                                            \
+     -r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null))
 
-quiet_cmd_cc_s_c = CC $(quiet_modtag)  $@
-cmd_cc_s_c       = $(CC) $(c_flags) -fverbose-asm -S -o $@ $<
+quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@
+cmd_cc_symtypes_c =                                                         \
+    $(call cmd_gensymtypes_c,true,$@) >/dev/null;                           \
+    test -s $@ || rm -f $@
 
-%.s: %.c FORCE
-	$(call if_changed_dep,cc_s_c)
+$(obj)/%.symtypes : $(src)/%.c FORCE
+	$(call cmd,cc_symtypes_c)
 
-quiet_cmd_cc_i_c = CPP $(quiet_modtag) $@
-cmd_cc_i_c       = $(CPP) $(c_flags)   -o $@ $<
+# LLVM assembly
+# Generate .ll files from .c
+quiet_cmd_cc_ll_c = CC $(quiet_modtag)  $@
+      cmd_cc_ll_c = $(CC) $(c_flags) -emit-llvm -S -o $@ $<
 
-%.i: %.c FORCE
-	$(call if_changed_dep,cc_i_c)
+$(obj)/%.ll: $(src)/%.c FORCE
+	$(call if_changed_dep,cc_ll_c)
 
 # C (.c) files
 # The C file is compiled and updated dependency information is generated.
 # (See cmd_cc_o_c + relevant part of rule_cc_o_c)
 
 quiet_cmd_cc_o_c = CC $(quiet_modtag)  $@
+      cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
 
-ifndef CONFIG_MODVERSIONS
-cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
-
-else
+ifdef CONFIG_MODVERSIONS
 # When module versioning is enabled the following steps are executed:
-# o compile a .tmp_<file>.o from <file>.c
-# o if .tmp_<file>.o doesn't contain a __ksymtab version, i.e. does
-#   not export symbols, we just rename .tmp_<file>.o to <file>.o and
-#   are done.
+# o compile a <file>.o from <file>.c
+# o if <file>.o doesn't contain a __ksymtab version, i.e. does
+#   not export symbols, it's done.
 # o otherwise, we calculate symbol versions using the good old
 #   genksyms on the preprocessed source and postprocess them in a way
 #   that they are usable as a linker script
-# o generate <file>.o from .tmp_<file>.o using the linker to
+# o generate .tmp_<file>.o from <file>.o using the linker to
 #   replace the unresolved symbols __crc_exported_symbol with
 #   the actual value of the checksum generated by genksyms
+# o remove .tmp_<file>.o to <file>.o
+
+ifdef CONFIG_LTO_CLANG
+# Generate .o.symversions files for each .o with exported symbols, and link these
+# to the kernel and/or modules at the end.
+cmd_modversions_c =								\
+	if $(NM) $@ 2>/dev/null | grep -q __ksymtab; then			\
+		$(call cmd_gensymtypes_c,$(KBUILD_SYMTYPES),$(@:.o=.symtypes))	\
+		    > $@.symversions;						\
+	fi;
+else
+cmd_modversions_c =								\
+	if $(OBJDUMP) -h $@ | grep -q __ksymtab; then				\
+		$(call cmd_gensymtypes_c,$(KBUILD_SYMTYPES),$(@:.o=.symtypes))	\
+		    > $(@D)/.tmp_$(@F:.o=.ver);					\
+										\
+		$(LD) $(KBUILD_LDFLAGS) -r -o $(@D)/.tmp_$(@F) $@ 		\
+			-T $(@D)/.tmp_$(@F:.o=.ver);				\
+		mv -f $(@D)/.tmp_$(@F) $@;					\
+		rm -f $(@D)/.tmp_$(@F:.o=.ver);					\
+	fi
+endif
+endif
 
-cmd_cc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $<
-cmd_modversions =							\
-	if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then	\
-		$(CPP) -D__GENKSYMS__ $(c_flags) $<			\
-		| $(GENKSYMS) -a $(ARCH)				\
-		> $(@D)/.tmp_$(@F:.o=.ver);				\
-									\
-		$(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) 		\
-			-T $(@D)/.tmp_$(@F:.o=.ver);			\
-		rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver);	\
-	else								\
-		mv -f $(@D)/.tmp_$(@F) $@;				\
+ifdef CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT
+# compiler will not generate __mcount_loc use recordmcount or recordmcount.pl
+ifdef BUILD_C_RECORDMCOUNT
+ifeq ("$(origin RECORDMCOUNT_WARN)", "command line")
+  RECORDMCOUNT_FLAGS = -w
+endif
+# Due to recursion, we must skip empty.o.
+# The empty.o file is created in the make process in order to determine
+# the target endianness and word size. It is made before all other C
+# files, including recordmcount.
+sub_cmd_record_mcount =					\
+	if [ $(@) != "scripts/mod/empty.o" ]; then	\
+		$(objtree)/scripts/recordmcount $(RECORDMCOUNT_FLAGS) "$(@)";	\
 	fi;
+recordmcount_source := $(srctree)/scripts/recordmcount.c \
+		    $(srctree)/scripts/recordmcount.h
+else
+sub_cmd_record_mcount = perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \
+	"$(if $(CONFIG_CPU_BIG_ENDIAN),big,little)" \
+	"$(if $(CONFIG_64BIT),64,32)" \
+	"$(OBJDUMP)" "$(OBJCOPY)" "$(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS)" \
+	"$(LD) $(KBUILD_LDFLAGS)" "$(NM)" "$(RM)" "$(MV)" \
+	"$(if $(part-of-module),1,0)" "$(@)";
+recordmcount_source := $(srctree)/scripts/recordmcount.pl
+endif # BUILD_C_RECORDMCOUNT
+cmd_record_mcount = $(if $(findstring $(strip $(CC_FLAGS_FTRACE)),$(_c_flags)),	\
+	$(sub_cmd_record_mcount))
+endif # CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT
+
+ifdef CONFIG_STACK_VALIDATION
+ifndef CONFIG_LTO_CLANG
+ifneq ($(SKIP_STACK_VALIDATION),1)
+
+__objtool_obj := $(objtree)/tools/objtool/objtool
+
+# 'OBJECT_FILES_NON_STANDARD := y': skip objtool checking for a directory
+# 'OBJECT_FILES_NON_STANDARD_foo.o := 'y': skip objtool checking for a file
+# 'OBJECT_FILES_NON_STANDARD_foo.o := 'n': override directory skip for a file
+cmd_objtool = $(if $(patsubst y%,, \
+	$(OBJECT_FILES_NON_STANDARD_$(basetarget).o)$(OBJECT_FILES_NON_STANDARD)n), \
+	$(__objtool_obj) $(objtool_args) $@)
+objtool_obj = $(if $(patsubst y%,, \
+	$(OBJECT_FILES_NON_STANDARD_$(basetarget).o)$(OBJECT_FILES_NON_STANDARD)n), \
+	$(__objtool_obj))
+
+endif # SKIP_STACK_VALIDATION
+endif # CONFIG_LTO_CLANG
+endif # CONFIG_STACK_VALIDATION
+
+# Rebuild all objects when objtool changes, or is enabled/disabled.
+objtool_dep = $(objtool_obj)					\
+	      $(wildcard include/config/orc/unwinder.h		\
+			 include/config/stack/validation.h)
+
+ifdef CONFIG_TRIM_UNUSED_KSYMS
+cmd_gen_ksymdeps = \
+	$(CONFIG_SHELL) $(srctree)/scripts/gen_ksymdeps.sh $@ >> $(dot-target).cmd
+
+# List module undefined symbols
+undefined_syms = $(NM) $< | $(AWK) '$$1 == "U" { printf("%s%s", x++ ? " " : "", $$2) \
}';  endif
 
 define rule_cc_o_c
-	$(call echo-cmd,checksrc) $(cmd_checksrc)			  \
-	$(call echo-cmd,cc_o_c) $(cmd_cc_o_c);				  \
-	$(cmd_modversions)						  \
-	scripts/basic/fixdep $(depfile) $@ '$(call make-cmd,cc_o_c)' > $(@D)/.$(@F).tmp;  \
-	rm -f $(depfile);						  \
-	mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd
+	$(call cmd_and_fixdep,cc_o_c)
+	$(call cmd,gen_ksymdeps)
+	$(call cmd,checksrc)
+	$(call cmd,checkdoc)
+	$(call cmd,objtool)
+	$(call cmd,modversions_c)
+	$(call cmd,record_mcount)
 endef
 
-# Built-in and composite module parts
+define rule_as_o_S
+	$(call cmd_and_fixdep,as_o_S)
+	$(call cmd,gen_ksymdeps)
+	$(call cmd,objtool)
+	$(call cmd,modversions_S)
+endef
 
-%.o: %.c FORCE
-	$(call cmd,force_checksrc)
+# Built-in and composite module parts
+$(obj)/%.o: $(src)/%.c $(recordmcount_source) $(objtool_dep) FORCE
 	$(call if_changed_rule,cc_o_c)
+	$(call cmd,force_checksrc)
 
-# Single-part modules are special since we need to mark them in $(MODVERDIR)
+cmd_mod = { \
+	echo $(if $($*-objs)$($*-y)$($*-m), $(addprefix $(obj)/, $($*-objs) $($*-y) \
$($*-m)), $(@:.mod=.o)); \ +	$(undefined_syms) echo; \
+	} > $@
 
-$(single-used-m): %.o: %.c FORCE
-	$(call cmd,force_checksrc)
-	$(call if_changed_rule,cc_o_c)
-	@{ echo $(@:.o=.ko); echo $@; } > $(MODVERDIR)/$(@F:.o=.mod)
+$(obj)/%.mod: $(obj)/%.o FORCE
+	$(call if_changed,mod)
 
 quiet_cmd_cc_lst_c = MKLST   $@
       cmd_cc_lst_c = $(CC) $(c_flags) -g -c -o $*.o $< && \
 		     $(CONFIG_SHELL) $(srctree)/scripts/makelst $*.o \
 				     System.map $(OBJDUMP) > $@
 
-%.lst: %.c FORCE
+$(obj)/%.lst: $(src)/%.c FORCE
 	$(call if_changed_dep,cc_lst_c)
 
 # Compile assembler sources (.S)
 # ---------------------------------------------------------------------------
 
-modkern_aflags := $(AFLAGS_KERNEL)
-
-$(real-objs-m)      : modkern_aflags := $(AFLAGS_MODULE)
-$(real-objs-m:.o=.s): modkern_aflags := $(AFLAGS_MODULE)
-
-quiet_cmd_as_s_S = CPP $(quiet_modtag) $@
-cmd_as_s_S       = $(CPP) $(a_flags)   -o $@ $<
-
-%.s: %.S FORCE
-	$(call if_changed_dep,as_s_S)
+# .S file exports must have their C prototypes defined in asm/asm-prototypes.h
+# or a file that it includes, in order to get versioned symbols. We build a
+# dummy C file that includes asm-prototypes and the EXPORT_SYMBOL lines from
+# the .S file (with trailing ';'), and run genksyms on that, to extract vers.
+#
+# This is convoluted. The .S file must first be preprocessed to run guards and
+# expand names, then the resulting exports must be constructed into plain
+# EXPORT_SYMBOL(symbol); to build our dummy C file, and that gets preprocessed
+# to make the genksyms input.
+#
+# These mirror gensymtypes_c and co above, keep them in synch.
+cmd_gensymtypes_S =                                                         \
+   { echo "\#include <linux/kernel.h>" ;                                    \
+     echo "\#include <asm/asm-prototypes.h>" ;                              \
+    $(CPP) $(a_flags) $< |                                                  \
+     grep "\<___EXPORT_SYMBOL\>" |                                          \
+     sed 's/.*___EXPORT_SYMBOL[[:space:]]*\([a-zA-Z0-9_]*\)[[:space:]]*,.*/EXPORT_SYMBOL(\1);/' \
; } | \ +    $(CPP) -D__GENKSYMS__ $(c_flags) -xc - |                                \
\ +    scripts/genksyms/genksyms $(if $(1), -T $(2))                           \
+     $(patsubst y,-R,$(CONFIG_MODULE_REL_CRCS))                             \
+     $(if $(KBUILD_PRESERVE),-p)                                            \
+     -r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null))
+
+quiet_cmd_cc_symtypes_S = SYM $(quiet_modtag) $@
+cmd_cc_symtypes_S =                                                         \
+    $(call cmd_gensymtypes_S,true,$@) >/dev/null;                           \
+    test -s $@ || rm -f $@
+
+$(obj)/%.symtypes : $(src)/%.S FORCE
+	$(call cmd,cc_symtypes_S)
+
+
+quiet_cmd_cpp_s_S = CPP $(quiet_modtag) $@
+cmd_cpp_s_S       = $(CPP) $(a_flags) -o $@ $<
+
+$(obj)/%.s: $(src)/%.S FORCE
+	$(call if_changed_dep,cpp_s_S)
 
 quiet_cmd_as_o_S = AS $(quiet_modtag)  $@
-cmd_as_o_S       = $(CC) $(a_flags) -c -o $@ $<
+      cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $<
+
+ifdef CONFIG_ASM_MODVERSIONS
+
+# versioning matches the C process described above, with difference that
+# we parse asm-prototypes.h C header to get function definitions.
+
+cmd_modversions_S =								\
+	if $(OBJDUMP) -h $@ | grep -q __ksymtab; then				\
+		$(call cmd_gensymtypes_S,$(KBUILD_SYMTYPES),$(@:.o=.symtypes))	\
+		    > $(@D)/.tmp_$(@F:.o=.ver);					\
+										\
+		$(LD) $(KBUILD_LDFLAGS) -r -o $(@D)/.tmp_$(@F) $@ 		\
+			-T $(@D)/.tmp_$(@F:.o=.ver);				\
+		mv -f $(@D)/.tmp_$(@F) $@;					\
+		rm -f $(@D)/.tmp_$(@F:.o=.ver);					\
+	fi
+endif
 
-%.o: %.S FORCE
-	$(call if_changed_dep,as_o_S)
+$(obj)/%.o: $(src)/%.S $(objtool_dep) FORCE
+	$(call if_changed_rule,as_o_S)
 
-targets += $(real-objs-y) $(real-objs-m) $(lib-y)
-targets += $(extra-y) $(MAKECMDGOALS) $(always)
+targets += $(filter-out $(subdir-builtin), $(real-obj-y))
+targets += $(filter-out $(subdir-modorder), $(real-obj-m))
+targets += $(lib-y) $(always-y) $(MAKECMDGOALS)
 
 # Linker scripts preprocessor (.lds.S -> .lds)
 # ---------------------------------------------------------------------------
 quiet_cmd_cpp_lds_S = LDS     $@
-      cmd_cpp_lds_S = $(CPP) $(cpp_flags) -D__ASSEMBLY__ -o $@ $<
+      cmd_cpp_lds_S = $(CPP) $(cpp_flags) -P -U$(ARCH) \
+	                     -D__ASSEMBLY__ -DLINKER_SCRIPT -o $@ $<
 
-%.lds: %.lds.S FORCE
+$(obj)/%.lds: $(src)/%.lds.S FORCE
 	$(call if_changed_dep,cpp_lds_S)
 
+# ASN.1 grammar
+# ---------------------------------------------------------------------------
+quiet_cmd_asn1_compiler = ASN.1   $(basename $@).[ch]
+      cmd_asn1_compiler = $(objtree)/scripts/asn1_compiler $< \
+				$(basename $@).c $(basename $@).h
+
+$(obj)/%.asn1.c $(obj)/%.asn1.h: $(src)/%.asn1 $(objtree)/scripts/asn1_compiler
+	$(call cmd,asn1_compiler)
+
 # Build the compiled-in targets
 # ---------------------------------------------------------------------------
 
 # To build objects in subdirs, we need to descend into the directories
-$(sort $(subdir-obj-y)): $(subdir-ym) ;
+$(subdir-builtin): $(obj)/%/built-in.a: $(obj)/% ;
+$(subdir-modorder): $(obj)/%/modules.order: $(obj)/% ;
+
+# combine symversions for later processing
+quiet_cmd_update_lto_symversions = SYMVER  $@
+ifeq ($(CONFIG_LTO_CLANG) $(CONFIG_MODVERSIONS),y y)
+      cmd_update_lto_symversions =					\
+	rm -f $@.symversions						\
+	$(foreach n, $(filter-out FORCE,$^),				\
+		$(if $(wildcard $(n).symversions),			\
+			; cat $(n).symversions >> $@.symversions))
+else
+      cmd_update_lto_symversions = echo >/dev/null
+endif
 
 #
-# Rule to compile a set of .o files into one .o file
+# Rule to compile a set of .o files into one .a file (without symbol table)
 #
-ifdef builtin-target
-quiet_cmd_link_o_target = LD      $@
-# If the list of objects to link is empty, just create an empty built-in.o
-# -nostdlib is added to make "make LD=gcc ..." work (some people use that)
-cmd_link_o_target = $(if $(strip $(obj-y)),\
-		$(LD) -nostdlib $(ld_flags) -r -o $@ $(filter $(obj-y), $^),\
-		rm -f $@; $(AR) rcs $@)
 
-$(builtin-target): $(obj-y) FORCE
-	$(call if_changed,link_o_target)
+quiet_cmd_ar_builtin = AR      $@
+      cmd_ar_builtin = rm -f $@; $(AR) cDPrST $@ $(real-prereqs)
 
-targets += $(builtin-target)
-endif # builtin-target
+quiet_cmd_ar_and_symver = AR      $@
+      cmd_ar_and_symver = $(cmd_update_lto_symversions); $(cmd_ar_builtin)
+
+$(obj)/built-in.a: $(real-obj-y) FORCE
+	$(call if_changed,ar_and_symver)
 
 #
-# Rule to compile a set of .o files into one .a file
+# Rule to create modules.order file
 #
-ifdef lib-target
-quiet_cmd_link_l_target = AR      $@
-cmd_link_l_target = rm -f $@; $(AR) $(EXTRA_ARFLAGS) rcs $@ $(lib-y)
+# Create commands to either record .ko file or cat modules.order from
+# a subdirectory
+# Add $(obj-m) as the prerequisite to avoid updating the timestamp of
+# modules.order unless contained modules are updated.
 
-$(lib-target): $(lib-y) FORCE
-	$(call if_changed,link_l_target)
+cmd_modules_order = { $(foreach m, $(real-prereqs), \
+	$(if $(filter %/modules.order, $m), cat $m, echo $(patsubst %.o,%.ko,$m));) :; } \
+	| $(AWK) '!x[$$0]++' - > $@
 
-targets += $(lib-target)
-endif
+$(obj)/modules.order: $(obj-m) FORCE
+	$(call if_changed,modules_order)
 
 #
-# Rule to link composite objects
+# Rule to compile a set of .o files into one .a file (with symbol table)
 #
-#  Composite objects are specified in kbuild makefile as follows:
-#    <composite-object>-objs := <list of .o files>
-#  or
-#    <composite-object>-y    := <list of .o files>
-link_multi_deps =                     \
-$(filter $(addprefix $(obj)/,         \
-$($(subst $(obj)/,,$(@:.o=-objs)))    \
-$($(subst $(obj)/,,$(@:.o=-y)))), $^)
-
-quiet_cmd_link_multi-y = LD      $@
-cmd_link_multi-y = $(LD) $(ld_flags) -r -o $@ $(link_multi_deps)
-
+quiet_cmd_ar_lib = AR      $@
+      cmd_ar_lib = $(cmd_update_lto_symversions); $(cmd_ar)
+
+$(obj)/lib.a: $(lib-y) FORCE
+	$(call if_changed,ar_lib)
+
+# NOTE:
+# Do not replace $(filter %.o,^) with $(real-prereqs). When a single object
+# module is turned into a multi object module, $^ will contain header file
+# dependencies recorded in the .*.cmd file.
+ifdef CONFIG_LTO_CLANG
+quiet_cmd_link_multi-m = AR [M]  $@
+cmd_link_multi-m =						\
+	$(cmd_update_lto_symversions);				\
+	rm -f $@; 						\
+	$(AR) cDPrsT $@ $(filter %.o,$^)
+else
 quiet_cmd_link_multi-m = LD [M]  $@
-cmd_link_multi-m = $(LD) $(ld_flags) $(LDFLAGS_MODULE) -o $@ $(link_multi_deps)
-
-# We would rather have a list of rules like
-# 	foo.o: $(foo-objs)
-# but that's not so easy, so we rather make all composite objects depend
-# on the set of all their parts
-$(multi-used-y) : %.o: $(multi-objs-y) FORCE
-	$(call if_changed,link_multi-y)
+      cmd_link_multi-m = $(LD) $(ld_flags) -r -o $@ $(filter %.o,$^)
+endif
 
-$(multi-used-m) : %.o: $(multi-objs-m) FORCE
+$(multi-used-m): FORCE
 	$(call if_changed,link_multi-m)
-	@{ echo $(@:.o=.ko); echo $(link_multi_deps); } > $(MODVERDIR)/$(@F:.o=.mod)
+$(call multi_depend, $(multi-used-m), .o, -objs -y -m)
+
+targets += $(multi-used-m)
+targets := $(filter-out $(PHONY), $(targets))
+
+# Add intermediate targets:
+# When building objects with specific suffix patterns, add intermediate
+# targets that the final targets are derived from.
+intermediate_targets = $(foreach sfx, $(2), \
+				$(patsubst %$(strip $(1)),%$(sfx), \
+					$(filter %$(strip $(1)), $(targets))))
+# %.asn1.o <- %.asn1.[ch] <- %.asn1
+# %.dtb.o <- %.dtb.S <- %.dtb <- %.dts
+# %.lex.o <- %.lex.c <- %.l
+# %.tab.o <- %.tab.[ch] <- %.y
+targets += $(call intermediate_targets, .asn1.o, .asn1.c .asn1.h) \
+	   $(call intermediate_targets, .dtb.o, .dtb.S .dtb) \
+	   $(call intermediate_targets, .lex.o, .lex.c) \
+	   $(call intermediate_targets, .tab.o, .tab.c .tab.h)
+
+# Build
+# ---------------------------------------------------------------------------
+
+ifdef single-build
+
+KBUILD_SINGLE_TARGETS := $(filter $(obj)/%, $(KBUILD_SINGLE_TARGETS))
+
+curdir-single := $(sort $(foreach x, $(KBUILD_SINGLE_TARGETS), \
+			$(if $(filter $(x) $(basename $(x)).o, $(targets)), $(x))))
+
+# Handle single targets without any rule: show "Nothing to be done for ..." or
+# "No rule to make target ..." depending on whether the target exists.
+unknown-single := $(filter-out $(addsuffix /%, $(subdir-ym)), \
+			$(filter-out $(curdir-single), $(KBUILD_SINGLE_TARGETS)))
 
-targets += $(multi-used-y) $(multi-used-m)
+single-subdirs := $(foreach d, $(subdir-ym), \
+			$(if $(filter $(d)/%, $(KBUILD_SINGLE_TARGETS)), $(d)))
 
+__build: $(curdir-single) $(single-subdirs)
+ifneq ($(unknown-single),)
+	$(Q)$(MAKE) -f /dev/null $(unknown-single)
+endif
+	@:
+
+ifeq ($(curdir-single),)
+# Nothing to do in this directory. Do not include any .*.cmd file for speed-up
+targets :=
+else
+targets += $(curdir-single)
+endif
+
+else
+
+__build: $(if $(KBUILD_BUILTIN), $(targets-for-builtin)) \
+	 $(if $(KBUILD_MODULES), $(targets-for-modules)) \
+	 $(subdir-ym) $(always-y)
+	@:
+
+endif
 
 # Descending
 # ---------------------------------------------------------------------------
 
 PHONY += $(subdir-ym)
 $(subdir-ym):
-	$(Q)$(MAKE) $(build)=$@
+	$(Q)$(MAKE) $(build)=$@ \
+	$(if $(filter $@/, $(KBUILD_SINGLE_TARGETS)),single-build=) \
+	need-builtin=$(if $(filter $@/built-in.a, $(subdir-builtin)),1) \
+	need-modorder=$(if $(filter $@/modules.order, $(subdir-modorder)),1)
 
 # Add FORCE to the prequisites of a target to force it to be always rebuilt.
 # ---------------------------------------------------------------------------
@@ -330,15 +528,17 @@ FORCE:
 # optimization, we don't need to read them if the target does not
 # exist, we will rebuild anyway in that case.
 
-targets := $(wildcard $(sort $(targets)))
-cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd))
-
-ifneq ($(cmd_files),)
-  include $(cmd_files)
-endif
+existing-targets := $(wildcard $(sort $(targets)))
 
+-include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd)
 
-# Declare the contents of the .PHONY variable as phony.  We keep that
-# information in a variable se we can use it in if_changed and friends.
+# Create directories for object files if they do not exist
+obj-dirs := $(sort $(patsubst %/,%, $(dir $(targets))))
+# If targets exist, their directories apparently exist. Skip mkdir.
+existing-dirs := $(sort $(patsubst %/,%, $(dir $(existing-targets))))
+obj-dirs := $(strip $(filter-out $(existing-dirs), $(obj-dirs)))
+ifneq ($(obj-dirs),)
+$(shell mkdir -p $(obj-dirs))
+endif
 
 .PHONY: $(PHONY)
diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean
index 03e397f42..22a8172bc 100644
--- a/scripts/Makefile.clean
+++ b/scripts/Makefile.clean
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
 # ==========================================================================
 # Cleaning up
 # ==========================================================================
@@ -7,75 +8,50 @@ src := $(obj)
 PHONY := __clean
 __clean:
 
-# Shorthand for $(Q)$(MAKE) scripts/Makefile.clean obj=dir
-# Usage:
-# $(Q)$(MAKE) $(clean)=dir
-clean := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.clean obj
+include scripts/Kbuild.include
 
 # The filename Kbuild has precedence over Makefile
 kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
--include $(if $(wildcard $(kbuild-dir)/Kbuild), $(kbuild-dir)/Kbuild, \
$(kbuild-dir)/Makefile) +include $(if $(wildcard $(kbuild-dir)/Kbuild), \
$(kbuild-dir)/Kbuild, $(kbuild-dir)/Makefile)  
 # Figure out what we need to build from the various variables
 # ==========================================================================
 
-__subdir-y	:= $(patsubst %/,%,$(filter %/, $(obj-y)))
-subdir-y	+= $(__subdir-y)
-__subdir-m	:= $(patsubst %/,%,$(filter %/, $(obj-m)))
-subdir-m	+= $(__subdir-m)
-__subdir-n	:= $(patsubst %/,%,$(filter %/, $(obj-n)))
-subdir-n	+= $(__subdir-n)
-__subdir-	:= $(patsubst %/,%,$(filter %/, $(obj-)))
-subdir-		+= $(__subdir-)
-
-# Subdirectories we need to descend into
-
-subdir-ym	:= $(sort $(subdir-y) $(subdir-m))
-subdir-ymn      := $(sort $(subdir-ym) $(subdir-n) $(subdir-))
+subdir-ymn := $(sort $(subdir-y) $(subdir-m) $(subdir-) \
+		$(patsubst %/,%, $(filter %/, $(obj-y) $(obj-m) $(obj-))))
 
 # Add subdir path
 
 subdir-ymn	:= $(addprefix $(obj)/,$(subdir-ymn))
 
-# build a list of files to remove, usually releative to the current
+# build a list of files to remove, usually relative to the current
 # directory
 
-__clean-files	:= $(extra-y) $(EXTRA_TARGETS) $(always) \
-		   $(targets) $(clean-files)             \
-		   $(host-progs)                         \
-		   $(hostprogs-y) $(hostprogs-m) $(hostprogs-)
-
-# as clean-files is given relative to the current directory, this adds
-# a $(obj) prefix, except for absolute paths
+__clean-files	:= \
+	$(clean-files) $(targets) $(hostprogs) $(userprogs) \
+	$(extra-y) $(extra-m) $(extra-) \
+	$(always-y) $(always-m) $(always-) \
+	$(hostprogs-always-y) $(hostprogs-always-m) $(hostprogs-always-) \
+	$(userprogs-always-y) $(userprogs-always-m) $(userprogs-always-)
 
-__clean-files   := $(wildcard                                               \
-                   $(addprefix $(obj)/, $(filter-out /%, $(__clean-files))) \
-		   $(filter /%, $(__clean-files)))
+__clean-files   := $(filter-out $(no-clean-files), $(__clean-files))
 
-# as clean-dirs is given relative to the current directory, this adds
-# a $(obj) prefix, except for absolute paths
+# clean-files is given relative to the current directory, unless it
+# starts with $(objtree)/ (which means "./", so do not add "./" unless
+# you want to delete a file from the toplevel object directory).
 
-__clean-dirs    := $(wildcard                                               \
-                   $(addprefix $(obj)/, $(filter-out /%, $(clean-dirs)))    \
-		   $(filter /%, $(clean-dirs)))
+__clean-files   := $(wildcard                                               \
+		   $(addprefix $(obj)/, $(filter-out $(objtree)/%, $(__clean-files))) \
+		   $(filter $(objtree)/%, $(__clean-files)))
 
 # ==========================================================================
 
-quiet_cmd_clean    = CLEAN   $(obj)
-      cmd_clean    = rm -f $(__clean-files)
-quiet_cmd_cleandir = CLEAN   $(__clean-dirs)
-      cmd_cleandir = rm -rf $(__clean-dirs)
-
+quiet_cmd_clean = CLEAN   $(obj)
+      cmd_clean = rm -rf $(__clean-files)
 
 __clean: $(subdir-ymn)
 ifneq ($(strip $(__clean-files)),)
-	+$(call cmd,clean)
-endif
-ifneq ($(strip $(__clean-dirs)),)
-	+$(call cmd,cleandir)
-endif
-ifneq ($(strip $(clean-rule)),)
-	+$(clean-rule)
+	$(call cmd,clean)
 endif
 	@:
 
@@ -91,12 +67,4 @@ PHONY += $(subdir-ymn)
 $(subdir-ymn):
 	$(Q)$(MAKE) $(clean)=$@
 
-# If quiet is set, only print short version of command
-
-cmd = @$(if $($(quiet)cmd_$(1)),echo '  $($(quiet)cmd_$(1))' &&) $(cmd_$(1))
-
-
-# Declare the contents of the .PHONY variable as phony.  We keep that
-# information in a variable se we can use it in if_changed and friends.
-
 .PHONY: $(PHONY)
diff --git a/scripts/Makefile.host b/scripts/Makefile.host
index 2e628508d..278b4d6ac 100644
--- a/scripts/Makefile.host
+++ b/scripts/Makefile.host
@@ -1,96 +1,87 @@
+# SPDX-License-Identifier: GPL-2.0
+
+# LEX
+# ---------------------------------------------------------------------------
+quiet_cmd_flex = LEX     $@
+      cmd_flex = $(LEX) -o$@ -L $<
+
+$(obj)/%.lex.c: $(src)/%.l FORCE
+	$(call if_changed,flex)
+
+# YACC
+# ---------------------------------------------------------------------------
+quiet_cmd_bison = YACC    $(basename $@).[ch]
+      cmd_bison = $(YACC) -o $(basename $@).c --defines=$(basename $@).h -t -l $<
+
+$(obj)/%.tab.c $(obj)/%.tab.h: $(src)/%.y FORCE
+	$(call if_changed,bison)
+
 # ==========================================================================
 # Building binaries on the host system
 # Binaries are used during the compilation of the kernel, for example
 # to preprocess a data file.
 #
-# Both C and C++ is supported, but preferred language is C for such utilities.
+# Both C and C++ are supported, but preferred language is C for such utilities.
 #
-# Samle syntax (see Documentation/kbuild/makefile.txt for reference)
-# hostprogs-y := bin2hex
+# Sample syntax (see Documentation/kbuild/makefiles.rst for reference)
+# hostprogs := bin2hex
 # Will compile bin2hex.c and create an executable named bin2hex
 #
-# hostprogs-y    := lxdialog
+# hostprogs     := lxdialog
 # lxdialog-objs := checklist.o lxdialog.o
 # Will compile lxdialog.c and checklist.c, and then link the executable
 # lxdialog, based on checklist.o and lxdialog.o
 #
-# hostprogs-y      := qconf
+# hostprogs       := qconf
 # qconf-cxxobjs   := qconf.o
 # qconf-objs      := menu.o
 # Will compile qconf as a C++ program, and menu as a C program.
 # They are linked as C++ code to the executable qconf
 
-# hostprogs-y := conf
-# conf-objs  := conf.o libkconfig.so
-# libkconfig-objs := expr.o type.o
-# Will create a shared library named libkconfig.so that consist of
-# expr.o and type.o (they are both compiled as C code and the object file
-# are made as position independent code).
-# conf.c is compiled as a c program, and conf.o is linked together with
-# libkconfig.so as the executable conf.
-# Note: Shared libraries consisting of C++ files are not supported
-
-__hostprogs := $(sort $(hostprogs-y)$(hostprogs-m))
-
-# hostprogs-y := tools/build may have been specified. Retreive directory
-obj-dirs += $(foreach f,$(__hostprogs), $(if $(dir $(f)),$(dir $(f))))
-obj-dirs := $(strip $(sort $(filter-out ./,$(obj-dirs))))
-
-
 # C code
 # Executables compiled from a single .c file
-host-csingle	:= $(foreach m,$(__hostprogs),$(if $($(m)-objs),,$(m)))
+host-csingle	:= $(foreach m,$(hostprogs), \
+			$(if $($(m)-objs)$($(m)-cxxobjs),,$(m)))
 
 # C executables linked based on several .o files
-host-cmulti	:= $(foreach m,$(__hostprogs),\
+host-cmulti	:= $(foreach m,$(hostprogs),\
 		   $(if $($(m)-cxxobjs),,$(if $($(m)-objs),$(m))))
 
 # Object (.o) files compiled from .c files
-host-cobjs	:= $(sort $(foreach m,$(__hostprogs),$($(m)-objs)))
+host-cobjs	:= $(sort $(foreach m,$(hostprogs),$($(m)-objs)))
 
 # C++ code
-# C++ executables compiled from at least on .cc file
+# C++ executables compiled from at least one .cc file
 # and zero or more .c files
-host-cxxmulti	:= $(foreach m,$(__hostprogs),$(if $($(m)-cxxobjs),$(m)))
+host-cxxmulti	:= $(foreach m,$(hostprogs),$(if $($(m)-cxxobjs),$(m)))
 
 # C++ Object (.o) files compiled from .cc files
 host-cxxobjs	:= $(sort $(foreach m,$(host-cxxmulti),$($(m)-cxxobjs)))
 
-# Shared libaries (only .c supported)
-# Shared libraries (.so) - all .so files referenced in "xxx-objs"
-host-cshlib	:= $(sort $(filter %.so, $(host-cobjs)))
-# Remove .so files from "xxx-objs"
-host-cobjs	:= $(filter-out %.so,$(host-cobjs))
-
-#Object (.o) files used by the shared libaries
-host-cshobjs	:= $(sort $(foreach m,$(host-cshlib),$($(m:.so=-objs))))
-
-__hostprogs     := $(addprefix $(obj)/,$(__hostprogs))
 host-csingle	:= $(addprefix $(obj)/,$(host-csingle))
 host-cmulti	:= $(addprefix $(obj)/,$(host-cmulti))
 host-cobjs	:= $(addprefix $(obj)/,$(host-cobjs))
 host-cxxmulti	:= $(addprefix $(obj)/,$(host-cxxmulti))
 host-cxxobjs	:= $(addprefix $(obj)/,$(host-cxxobjs))
-host-cshlib	:= $(addprefix $(obj)/,$(host-cshlib))
-host-cshobjs	:= $(addprefix $(obj)/,$(host-cshobjs))
-obj-dirs        := $(addprefix $(obj)/,$(obj-dirs))
 
 #####
 # Handle options to gcc. Support building with separate output directory
 
-_hostc_flags   = $(HOSTCFLAGS)   $(HOST_EXTRACFLAGS)   $(HOSTCFLAGS_$(*F).o)
-_hostcxx_flags = $(HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS) $(HOSTCXXFLAGS_$(*F).o)
+_hostc_flags   = $(KBUILD_HOSTCFLAGS)   $(HOST_EXTRACFLAGS)   \
+                 $(HOSTCFLAGS_$(target-stem).o)
+_hostcxx_flags = $(KBUILD_HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS) \
+                 $(HOSTCXXFLAGS_$(target-stem).o)
 
-ifeq ($(KBUILD_SRC),)
-__hostc_flags	= $(_hostc_flags)
-__hostcxx_flags	= $(_hostcxx_flags)
-else
-__hostc_flags	= -I$(obj) $(call flags,_hostc_flags)
-__hostcxx_flags	= -I$(obj) $(call flags,_hostcxx_flags)
+# $(objtree)/$(obj) for including generated headers from checkin source files
+ifeq ($(KBUILD_EXTMOD),)
+ifdef building_out_of_srctree
+_hostc_flags   += -I $(objtree)/$(obj)
+_hostcxx_flags += -I $(objtree)/$(obj)
+endif
 endif
 
-hostc_flags    = -Wp,-MD,$(depfile) $(__hostc_flags)
-hostcxx_flags  = -Wp,-MD,$(depfile) $(__hostcxx_flags)
+hostc_flags    = -Wp,-MMD,$(depfile) $(_hostc_flags)
+hostcxx_flags  = -Wp,-MMD,$(depfile) $(_hostcxx_flags)
 
 #####
 # Compile programs on the host
@@ -98,58 +89,44 @@ hostcxx_flags  = -Wp,-MD,$(depfile) $(__hostcxx_flags)
 # Create executable from a single .c file
 # host-csingle -> Executable
 quiet_cmd_host-csingle 	= HOSTCC  $@
-      cmd_host-csingle	= $(HOSTCC) $(hostc_flags) -o $@ $< \
-			  $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F))
-$(host-csingle): %: %.c FORCE
+      cmd_host-csingle	= $(HOSTCC) $(hostc_flags) $(KBUILD_HOSTLDFLAGS) -o $@ $< \
+		$(KBUILD_HOSTLDLIBS) $(HOSTLDLIBS_$(target-stem))
+$(host-csingle): $(obj)/%: $(src)/%.c FORCE
 	$(call if_changed_dep,host-csingle)
 
 # Link an executable based on list of .o files, all plain c
 # host-cmulti -> executable
 quiet_cmd_host-cmulti	= HOSTLD  $@
-      cmd_host-cmulti	= $(HOSTCC) $(HOSTLDFLAGS) -o $@ \
-			  $(addprefix $(obj)/,$($(@F)-objs)) \
-			  $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F))
-$(host-cmulti): %: $(host-cobjs) $(host-cshlib) FORCE
+      cmd_host-cmulti	= $(HOSTCC) $(KBUILD_HOSTLDFLAGS) -o $@ \
+			  $(addprefix $(obj)/, $($(target-stem)-objs)) \
+			  $(KBUILD_HOSTLDLIBS) $(HOSTLDLIBS_$(target-stem))
+$(host-cmulti): FORCE
 	$(call if_changed,host-cmulti)
+$(call multi_depend, $(host-cmulti), , -objs)
 
 # Create .o file from a single .c file
 # host-cobjs -> .o
 quiet_cmd_host-cobjs	= HOSTCC  $@
       cmd_host-cobjs	= $(HOSTCC) $(hostc_flags) -c -o $@ $<
-$(host-cobjs): %.o: %.c FORCE
+$(host-cobjs): $(obj)/%.o: $(src)/%.c FORCE
 	$(call if_changed_dep,host-cobjs)
 
 # Link an executable based on list of .o files, a mixture of .c and .cc
 # host-cxxmulti -> executable
 quiet_cmd_host-cxxmulti	= HOSTLD  $@
-      cmd_host-cxxmulti	= $(HOSTCXX) $(HOSTLDFLAGS) -o $@ \
+      cmd_host-cxxmulti	= $(HOSTCXX) $(KBUILD_HOSTLDFLAGS) -o $@ \
 			  $(foreach o,objs cxxobjs,\
-			  $(addprefix $(obj)/,$($(@F)-$(o)))) \
-			  $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F))
-$(host-cxxmulti): %: $(host-cobjs) $(host-cxxobjs) $(host-cshlib) FORCE
+			  $(addprefix $(obj)/, $($(target-stem)-$(o)))) \
+			  $(KBUILD_HOSTLDLIBS) $(HOSTLDLIBS_$(target-stem))
+$(host-cxxmulti): FORCE
 	$(call if_changed,host-cxxmulti)
+$(call multi_depend, $(host-cxxmulti), , -objs -cxxobjs)
 
 # Create .o file from a single .cc (C++) file
 quiet_cmd_host-cxxobjs	= HOSTCXX $@
       cmd_host-cxxobjs	= $(HOSTCXX) $(hostcxx_flags) -c -o $@ $<
-$(host-cxxobjs): %.o: %.cc FORCE
+$(host-cxxobjs): $(obj)/%.o: $(src)/%.cc FORCE
 	$(call if_changed_dep,host-cxxobjs)
 
-# Compile .c file, create position independent .o file
-# host-cshobjs -> .o
-quiet_cmd_host-cshobjs	= HOSTCC  -fPIC $@
-      cmd_host-cshobjs	= $(HOSTCC) $(hostc_flags) -fPIC -c -o $@ $<
-$(host-cshobjs): %.o: %.c FORCE
-	$(call if_changed_dep,host-cshobjs)
-
-# Link a shared library, based on position independent .o files
-# *.o -> .so shared library (host-cshlib)
-quiet_cmd_host-cshlib	= HOSTLLD -shared $@
-      cmd_host-cshlib	= $(HOSTCC) $(HOSTLDFLAGS) -shared -o $@ \
-			  $(addprefix $(obj)/,$($(@F:.so=-objs))) \
-			  $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F))
-$(host-cshlib): %: $(host-cshobjs) FORCE
-	$(call if_changed,host-cshlib)
-
-targets += $(host-csingle)  $(host-cmulti) $(host-cobjs)\
-	   $(host-cxxmulti) $(host-cxxobjs) $(host-cshlib) $(host-cshobjs)
+targets += $(host-csingle) $(host-cmulti) $(host-cobjs) \
+	   $(host-cxxmulti) $(host-cxxobjs)
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index d8d768a28..48d206c24 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -1,132 +1,241 @@
-# Backward compatibility - to be removed...
-extra-y	+= $(EXTRA_TARGETS)
+# SPDX-License-Identifier: GPL-2.0
+# Backward compatibility
+asflags-y  += $(EXTRA_AFLAGS)
+ccflags-y  += $(EXTRA_CFLAGS)
+cppflags-y += $(EXTRA_CPPFLAGS)
+ldflags-y  += $(EXTRA_LDFLAGS)
+
+# flags that take effect in current and sub directories
+KBUILD_AFLAGS += $(subdir-asflags-y)
+KBUILD_CFLAGS += $(subdir-ccflags-y)
+
 # Figure out what we need to build from the various variables
 # ===========================================================================
 
 # When an object is listed to be built compiled-in and modular,
 # only build the compiled-in version
-
 obj-m := $(filter-out $(obj-y),$(obj-m))
 
 # Libraries are always collected in one lib file.
 # Filter out objects already built-in
-
 lib-y := $(filter-out $(obj-y), $(sort $(lib-y) $(lib-m)))
 
-
-# Handle objects in subdirs
-# ---------------------------------------------------------------------------
-# o if we encounter foo/ in $(obj-y), replace it by foo/built-in.o
-#   and add the directory to the list of dirs to descend into: $(subdir-y)
-# o if we encounter foo/ in $(obj-m), remove it from $(obj-m)
-#   and add the directory to the list of dirs to descend into: $(subdir-m)
-
-__subdir-y	:= $(patsubst %/,%,$(filter %/, $(obj-y)))
-subdir-y	+= $(__subdir-y)
-__subdir-m	:= $(patsubst %/,%,$(filter %/, $(obj-m)))
-subdir-m	+= $(__subdir-m)
-obj-y		:= $(patsubst %/, %/built-in.o, $(obj-y))
-obj-m		:= $(filter-out %/, $(obj-m))
-
 # Subdirectories we need to descend into
+subdir-ym := $(sort $(subdir-y) $(subdir-m) \
+			$(patsubst %/,%, $(filter %/, $(obj-y) $(obj-m))))
 
-subdir-ym	:= $(sort $(subdir-y) $(subdir-m))
-
-# if $(foo-objs) exists, foo.o is a composite object
-multi-used-y := $(sort $(foreach m,$(obj-y), $(if $(strip $($(m:.o=-objs)) \
                $($(m:.o=-y))), $(m))))
-multi-used-m := $(sort $(foreach m,$(obj-m), $(if $(strip $($(m:.o=-objs)) \
                $($(m:.o=-y))), $(m))))
-multi-used   := $(multi-used-y) $(multi-used-m)
-single-used-m := $(sort $(filter-out $(multi-used-m),$(obj-m)))
+# Handle objects in subdirs:
+# - If we encounter foo/ in $(obj-y), replace it by foo/built-in.a and
+#   foo/modules.order
+# - If we encounter foo/ in $(obj-m), replace it by foo/modules.order
+#
+# Generate modules.order to determine modorder. Unfortunately, we don't have
+# information about ordering between -y and -m subdirs. Just put -y's first.
 
-# Build list of the parts of our composite objects, our composite
-# objects depend on those (obviously)
-multi-objs-y := $(foreach m, $(multi-used-y), $($(m:.o=-objs)) $($(m:.o=-y)))
-multi-objs-m := $(foreach m, $(multi-used-m), $($(m:.o=-objs)) $($(m:.o=-y)))
-multi-objs   := $(multi-objs-y) $(multi-objs-m)
+ifdef need-modorder
+obj-m := $(patsubst %/,%/modules.order, $(filter %/, $(obj-y)) $(obj-m))
+else
+obj-m := $(filter-out %/, $(obj-m))
+endif
 
-# $(subdir-obj-y) is the list of objects in $(obj-y) which do not live
-# in the local directory
-subdir-obj-y := $(foreach o,$(obj-y),$(if $(filter-out $(o),$(notdir $(o))),$(o)))
+ifdef need-builtin
+obj-y		:= $(patsubst %/, %/built-in.a, $(obj-y))
+else
+obj-y		:= $(filter-out %/, $(obj-y))
+endif
 
-# $(obj-dirs) is a list of directories that contain object files
-obj-dirs := $(dir $(multi-objs) $(subdir-obj-y))
+# Expand $(foo-objs) $(foo-y) by calling $(call suffix-search,foo.o,-objs -y)
+suffix-search = $(foreach s,$(2),$($(1:.o=$s)))
+# If $(foo-objs), $(foo-y), $(foo-m), or $(foo-) exists, foo.o is a composite object
+multi-search = $(sort $(foreach m,$(1), $(if $(strip $(call suffix-search,$(m),$(2) \
-)), $(m)))) +multi-used-y := $(call multi-search,$(obj-y),-objs -y)
+multi-used-m := $(call multi-search,$(obj-m),-objs -y -m)
+multi-used   := $(multi-used-y) $(multi-used-m)
 
-# Replace multi-part objects by their individual parts, look at local dir only
-real-objs-y := $(foreach m, $(filter-out $(subdir-obj-y), $(obj-y)), $(if $(strip \
                $($(m:.o=-objs)) $($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m))) \
                $(extra-y)
-real-objs-m := $(foreach m, $(obj-m), $(if $(strip $($(m:.o=-objs)) \
$($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m))) +# Replace multi-part objects by \
their individual parts, +# including built-in.a from subdirectories
+real-search = $(foreach m,$(1), $(if $(strip $(call suffix-search,$(m),$(2) \
-)),$(call suffix-search,$(m),$(2)),$(m))) +real-obj-y := $(call real-search, \
$(obj-y),-objs -y) +real-obj-m := $(call real-search, $(obj-m),-objs -y -m)
+
+always-y += $(always-m)
+
+# hostprogs-always-y += foo
+# ... is a shorthand for
+# hostprogs += foo
+# always-y  += foo
+hostprogs += $(hostprogs-always-y) $(hostprogs-always-m)
+always-y += $(hostprogs-always-y) $(hostprogs-always-m)
+
+# userprogs-always-y is likewise.
+userprogs += $(userprogs-always-y) $(userprogs-always-m)
+always-y += $(userprogs-always-y) $(userprogs-always-m)
+
+# DTB
+# If CONFIG_OF_ALL_DTBS is enabled, all DT blobs are built
+always-y			+= $(dtb-y)
+always-$(CONFIG_OF_ALL_DTBS)	+= $(dtb-)
+
+ifneq ($(CHECK_DTBS),)
+always-y += $(patsubst %.dtb,%.dt.yaml, $(dtb-y))
+always-y += $(patsubst %.dtbo,%.dt.yaml, $(dtb-y))
+always-$(CONFIG_OF_ALL_DTBS) += $(patsubst %.dtb,%.dt.yaml, $(dtb-))
+always-$(CONFIG_OF_ALL_DTBS) += $(patsubst %.dtbo,%.dt.yaml, $(dtb-))
+endif
 
 # Add subdir path
 
 extra-y		:= $(addprefix $(obj)/,$(extra-y))
-always		:= $(addprefix $(obj)/,$(always))
+always-y	:= $(addprefix $(obj)/,$(always-y))
 targets		:= $(addprefix $(obj)/,$(targets))
-obj-y		:= $(addprefix $(obj)/,$(obj-y))
 obj-m		:= $(addprefix $(obj)/,$(obj-m))
 lib-y		:= $(addprefix $(obj)/,$(lib-y))
-subdir-obj-y	:= $(addprefix $(obj)/,$(subdir-obj-y))
-real-objs-y	:= $(addprefix $(obj)/,$(real-objs-y))
-real-objs-m	:= $(addprefix $(obj)/,$(real-objs-m))
-single-used-m	:= $(addprefix $(obj)/,$(single-used-m))
-multi-used-y	:= $(addprefix $(obj)/,$(multi-used-y))
+real-obj-y	:= $(addprefix $(obj)/,$(real-obj-y))
+real-obj-m	:= $(addprefix $(obj)/,$(real-obj-m))
 multi-used-m	:= $(addprefix $(obj)/,$(multi-used-m))
-multi-objs-y	:= $(addprefix $(obj)/,$(multi-objs-y))
-multi-objs-m	:= $(addprefix $(obj)/,$(multi-objs-m))
 subdir-ym	:= $(addprefix $(obj)/,$(subdir-ym))
-obj-dirs	:= $(addprefix $(obj)/,$(obj-dirs))
+
+# Finds the multi-part object the current object will be linked into.
+# If the object belongs to two or more multi-part objects, list them all.
+modname-multi = $(sort $(foreach m,$(multi-used),\
+		$(if $(filter $*.o, $($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-m))),$(m:.o=))))
+
+__modname = $(if $(modname-multi),$(modname-multi),$(basetarget))
+
+modname = $(subst $(space),:,$(__modname))
+modfile = $(addprefix $(obj)/,$(__modname))
+
+# target with $(obj)/ and its suffix stripped
+target-stem = $(basename $(patsubst $(obj)/%,%,$@))
 
 # These flags are needed for modversions and compiling, so we define them here
-# already
-# $(modname_flags) #defines KBUILD_MODNAME as the name of the module it will
+# $(modname_flags) defines KBUILD_MODNAME as the name of the module it will
 # end up in (or would, if it gets compiled in)
-# Note: It's possible that one object gets potentially linked into more
-#       than one module. In that case KBUILD_MODNAME will be set to foo_bar,
-#       where foo and bar are the name of the modules.
-name-fix = $(squote)$(quote)$(subst $(comma),_,$(subst -,_,$1))$(quote)$(squote)
-basename_flags = -DKBUILD_BASENAME=$(call name-fix,$(*F))
-modname_flags  = $(if $(filter 1,$(words $(modname))),\
-                 -DKBUILD_MODNAME=$(call name-fix,$(modname)))
-
-_c_flags       = $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$(*F).o)
-_a_flags       = $(AFLAGS) $(EXTRA_AFLAGS) $(AFLAGS_$(*F).o)
-_cpp_flags     = $(CPPFLAGS) $(EXTRA_CPPFLAGS) $(CPPFLAGS_$(@F))
-
-# If building the kernel in a separate objtree expand all occurrences
-# of -Idir to -I$(srctree)/dir except for absolute paths (starting with '/').
-
-ifeq ($(KBUILD_SRC),)
-__c_flags	= $(_c_flags)
-__a_flags	= $(_a_flags)
-__cpp_flags     = $(_cpp_flags)
-else
+name-fix-token = $(subst $(comma),_,$(subst -,_,$1))
+name-fix = $(call stringify,$(call name-fix-token,$1))
+basename_flags = -DKBUILD_BASENAME=$(call name-fix,$(basetarget))
+modname_flags  = -DKBUILD_MODNAME=$(call name-fix,$(modname)) \
+		 -D__KBUILD_MODNAME=kmod_$(call name-fix-token,$(modname))
+modfile_flags  = -DKBUILD_MODFILE=$(call stringify,$(modfile))
+
+_c_flags       = $(filter-out $(CFLAGS_REMOVE_$(target-stem).o), \
+                     $(filter-out $(ccflags-remove-y), \
+                         $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(ccflags-y)) \
+                     $(CFLAGS_$(target-stem).o))
+_a_flags       = $(filter-out $(AFLAGS_REMOVE_$(target-stem).o), \
+                     $(filter-out $(asflags-remove-y), \
+                         $(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) $(asflags-y)) \
+                     $(AFLAGS_$(target-stem).o))
+_cpp_flags     = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(target-stem).lds)
+
+#
+# Enable gcov profiling flags for a file, directory or for all files depending
+# on variables GCOV_PROFILE_obj.o, GCOV_PROFILE and CONFIG_GCOV_PROFILE_ALL
+# (in this order)
+#
+ifeq ($(CONFIG_GCOV_KERNEL),y)
+_c_flags += $(if $(patsubst n%,, \
+		$(GCOV_PROFILE_$(basetarget).o)$(GCOV_PROFILE)$(CONFIG_GCOV_PROFILE_ALL)), \
+		$(CFLAGS_GCOV))
+endif
 
-# -I$(obj) locates generated .h files
-# $(call addtree,-I$(obj)) locates .h files in srctree, from generated .c files
-#   and locates generated .h files
-# FIXME: Replace both with specific CFLAGS* statements in the makefiles
-__c_flags	= $(call addtree,-I$(obj)) $(call flags,_c_flags)
-__a_flags	=                          $(call flags,_a_flags)
-__cpp_flags     =                          $(call flags,_cpp_flags)
+#
+# Enable address sanitizer flags for kernel except some files or directories
+# we don't want to check (depends on variables KASAN_SANITIZE_obj.o, KASAN_SANITIZE)
+#
+ifeq ($(CONFIG_KASAN),y)
+ifneq ($(CONFIG_KASAN_HW_TAGS),y)
+_c_flags += $(if $(patsubst n%,, \
+		$(KASAN_SANITIZE_$(basetarget).o)$(KASAN_SANITIZE)y), \
+		$(CFLAGS_KASAN), $(CFLAGS_KASAN_NOSANITIZE))
+endif
 endif
 
-c_flags        = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(CPPFLAGS) \
-		 $(__c_flags) $(modkern_cflags) \
+ifeq ($(CONFIG_UBSAN),y)
+_c_flags += $(if $(patsubst n%,, \
+		$(UBSAN_SANITIZE_$(basetarget).o)$(UBSAN_SANITIZE)$(CONFIG_UBSAN_SANITIZE_ALL)), \
+		$(CFLAGS_UBSAN))
+endif
+
+ifeq ($(CONFIG_KCOV),y)
+_c_flags += $(if $(patsubst n%,, \
+	$(KCOV_INSTRUMENT_$(basetarget).o)$(KCOV_INSTRUMENT)$(CONFIG_KCOV_INSTRUMENT_ALL)), \
\ +	$(CFLAGS_KCOV))
+endif
+
+#
+# Enable KCSAN flags except some files or directories we don't want to check
+# (depends on variables KCSAN_SANITIZE_obj.o, KCSAN_SANITIZE)
+#
+ifeq ($(CONFIG_KCSAN),y)
+_c_flags += $(if $(patsubst n%,, \
+	$(KCSAN_SANITIZE_$(basetarget).o)$(KCSAN_SANITIZE)y), \
+	$(CFLAGS_KCSAN))
+endif
+
+# $(srctree)/$(src) for including checkin headers from generated source files
+# $(objtree)/$(obj) for including generated headers from checkin source files
+ifeq ($(KBUILD_EXTMOD),)
+ifdef building_out_of_srctree
+_c_flags   += -I $(srctree)/$(src) -I $(objtree)/$(obj)
+_a_flags   += -I $(srctree)/$(src) -I $(objtree)/$(obj)
+_cpp_flags += -I $(srctree)/$(src) -I $(objtree)/$(obj)
+endif
+endif
+
+part-of-module = $(if $(filter $(basename $@).o, $(real-obj-m)),y)
+quiet_modtag = $(if $(part-of-module),[M],   )
+
+modkern_cflags =                                          \
+	$(if $(part-of-module),                           \
+		$(KBUILD_CFLAGS_MODULE) $(CFLAGS_MODULE), \
+		$(KBUILD_CFLAGS_KERNEL) $(CFLAGS_KERNEL) $(modfile_flags))
+
+modkern_aflags = $(if $(part-of-module),				\
+			$(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE),	\
+			$(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL))
+
+c_flags        = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE)     \
+		 $(_c_flags) $(modkern_cflags)                           \
 		 $(basename_flags) $(modname_flags)
 
-a_flags        = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(CPPFLAGS) \
-		 $(__a_flags) $(modkern_aflags)
+a_flags        = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE)     \
+		 $(_a_flags) $(modkern_aflags)
 
-cpp_flags      = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(__cpp_flags)
+cpp_flags      = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE)     \
+		 $(_cpp_flags)
 
-# Seems to be a wrong thing to do. LDFLAGS contains gcc's flags,
-# yet ld_flags is fed to ld.
-#ld_flags       = $(LDFLAGS) $(EXTRA_LDFLAGS)
-# Remove the -Wl, prefix from linker options normally passed through gcc
-ld_flags       = $(filter-out -Wl$(comma)%,$(LDFLAGS) $(EXTRA_LDFLAGS))
+ld_flags       = $(KBUILD_LDFLAGS) $(ldflags-y) $(LDFLAGS_$(@F))
 
+DTC_INCLUDE    := $(srctree)/scripts/dtc/include-prefixes
 
-# Finds the multi-part object the current object will be linked into
-modname-multi = $(sort $(foreach m,$(multi-used),\
-		$(if $(filter $(subst $(obj)/,,$*.o), $($(m:.o=-objs)) $($(m:.o=-y))),$(m:.o=))))
+dtc_cpp_flags  = -Wp,-MMD,$(depfile).pre.tmp -nostdinc                    \
+		 $(addprefix -I,$(DTC_INCLUDE))                          \
+		 -undef -D__DTS__
+
+# Objtool arguments are also needed for modfinal with LTO, so we define
+# then here to avoid duplication.
+objtool_args =								\
+	$(if $(CONFIG_UNWINDER_ORC),orc generate,check)			\
+	$(if $(part-of-module), --module,)				\
+	$(if $(CONFIG_FRAME_POINTER),, --no-fp)				\
+	$(if $(or $(CONFIG_GCOV_KERNEL),$(CONFIG_LTO_CLANG)), 		\
+		--no-unreachable,)					\
+	$(if $(CONFIG_RETPOLINE), --retpoline,)				\
+	$(if $(CONFIG_X86_SMAP), --uaccess,)				\
+	$(if $(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL), --mcount,)
+
+# Useful for describing the dependency of composite objects
+# Usage:
+#   $(call multi_depend, multi_used_targets, suffix_to_remove, suffix_to_add)
+define multi_depend
+$(foreach m, $(notdir $1), \
+	$(eval $(obj)/$m: \
+	$(addprefix $(obj)/, $(foreach s, $3, $($(m:%$(strip $2)=%$(s)))))))
+endef
+
+quiet_cmd_copy = COPY    $@
+      cmd_copy = cp $< $@
 
 # Shipped files
 # ===========================================================================
@@ -134,7 +243,7 @@ modname-multi = $(sort $(foreach m,$(multi-used),\
 quiet_cmd_shipped = SHIPPED $@
 cmd_shipped = cat $< > $@
 
-$(obj)/%:: $(src)/%_shipped
+$(obj)/%: $(src)/%_shipped
 	$(call cmd,shipped)
 
 # Commands useful for building a boot image
@@ -145,17 +254,20 @@ $(obj)/%:: $(src)/%_shipped
 #	target: source(s) FORCE
 #		$(if_changed,ld/objcopy/gzip)
 #
-#	and add target to EXTRA_TARGETS so that we know we have to
+#	and add target to 'targets' so that we know we have to
 #	read in the saved command line
 
 # Linking
 # ---------------------------------------------------------------------------
 
-# TODO: LDFLAGS usually is supposed to contain gcc's flags, not ld's.
-# but here we feed them to ld!
 quiet_cmd_ld = LD      $@
-cmd_ld = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LDFLAGS_$(@F)) \
-	       $(filter-out FORCE,$^) -o $@
+      cmd_ld = $(LD) $(ld_flags) $(real-prereqs) -o $@
+
+# Archive
+# ---------------------------------------------------------------------------
+
+quiet_cmd_ar = AR      $@
+      cmd_ar = rm -f $@; $(AR) cDPrsT $@ $(real-prereqs)
 
 # Objcopy
 # ---------------------------------------------------------------------------
@@ -167,4 +279,212 @@ cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) \
$< $@  # ---------------------------------------------------------------------------
 
 quiet_cmd_gzip = GZIP    $@
-cmd_gzip = gzip -f -9 < $< > $@
+      cmd_gzip = cat $(real-prereqs) | $(KGZIP) -n -f -9 > $@
+
+# DTC
+# ---------------------------------------------------------------------------
+DTC ?= $(objtree)/scripts/dtc/dtc
+DTC_FLAGS += -Wno-interrupt_provider
+
+# Disable noisy checks by default
+ifeq ($(findstring 1,$(KBUILD_EXTRA_WARN)),)
+DTC_FLAGS += -Wno-unit_address_vs_reg \
+	-Wno-unit_address_format \
+	-Wno-avoid_unnecessary_addr_size \
+	-Wno-alias_paths \
+	-Wno-graph_child_address \
+	-Wno-simple_bus_reg \
+	-Wno-unique_unit_address \
+	-Wno-pci_device_reg
+endif
+
+ifneq ($(findstring 2,$(KBUILD_EXTRA_WARN)),)
+DTC_FLAGS += -Wnode_name_chars_strict \
+	-Wproperty_name_chars_strict \
+	-Winterrupt_provider
+endif
+
+DTC_FLAGS += $(DTC_FLAGS_$(basetarget))
+
+# Generate an assembly file to wrap the output of the device tree compiler
+quiet_cmd_dt_S_dtb= DTB     $@
+cmd_dt_S_dtb=						\
+{							\
+	echo '\#include <asm-generic/vmlinux.lds.h>'; 	\
+	echo '.section .dtb.init.rodata,"a"';		\
+	echo '.balign STRUCT_ALIGNMENT';		\
+	echo '.global __dtb_$(subst -,_,$(*F))_begin';	\
+	echo '__dtb_$(subst -,_,$(*F))_begin:';		\
+	echo '.incbin "$<" ';				\
+	echo '__dtb_$(subst -,_,$(*F))_end:';		\
+	echo '.global __dtb_$(subst -,_,$(*F))_end';	\
+	echo '.balign STRUCT_ALIGNMENT'; 		\
+} > $@
+
+$(obj)/%.dtb.S: $(obj)/%.dtb FORCE
+	$(call if_changed,dt_S_dtb)
+
+quiet_cmd_dtc = DTC     $@
+cmd_dtc = $(HOSTCC) -E $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \
+	$(DTC) -o $@ -b 0 \
+		$(addprefix -i,$(dir $<) $(DTC_INCLUDE)) $(DTC_FLAGS) \
+		-d $(depfile).dtc.tmp $(dtc-tmp) ; \
+	cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile)
+
+$(obj)/%.dtb: $(src)/%.dts $(DTC) FORCE
+	$(call if_changed_dep,dtc)
+
+$(obj)/%.dtbo: $(src)/%.dts $(DTC) FORCE
+	$(call if_changed_dep,dtc)
+
+DT_CHECKER ?= dt-validate
+DT_BINDING_DIR := Documentation/devicetree/bindings
+# DT_TMP_SCHEMA may be overridden from Documentation/devicetree/bindings/Makefile
+DT_TMP_SCHEMA ?= $(objtree)/$(DT_BINDING_DIR)/processed-schema.json
+
+quiet_cmd_dtb_check =	CHECK   $@
+      cmd_dtb_check =	$(DT_CHECKER) -u $(srctree)/$(DT_BINDING_DIR) -p \
$(DT_TMP_SCHEMA) $@ +
+define rule_dtc
+	$(call cmd_and_fixdep,dtc)
+	$(call cmd,dtb_check)
+endef
+
+$(obj)/%.dt.yaml: $(src)/%.dts $(DTC) $(DT_TMP_SCHEMA) FORCE
+	$(call if_changed_rule,dtc)
+
+dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp)
+
+# Bzip2
+# ---------------------------------------------------------------------------
+
+# Bzip2 and LZMA do not include size in file... so we have to fake that;
+# append the size as a 32-bit littleendian number as gzip does.
+size_append = printf $(shell						\
+dec_size=0;								\
+for F in $(real-prereqs); do					\
+	fsize=$$($(CONFIG_SHELL) $(srctree)/scripts/file-size.sh $$F);	\
+	dec_size=$$(expr $$dec_size + $$fsize);				\
+done;									\
+printf "%08x\n" $$dec_size |						\
+	sed 's/\(..\)/\1 /g' | {					\
+		read ch0 ch1 ch2 ch3;					\
+		for ch in $$ch3 $$ch2 $$ch1 $$ch0; do			\
+			printf '%s%03o' '\\' $$((0x$$ch)); 		\
+		done;							\
+	}								\
+)
+
+quiet_cmd_bzip2 = BZIP2   $@
+      cmd_bzip2 = { cat $(real-prereqs) | $(KBZIP2) -9; $(size_append); } > $@
+
+# Lzma
+# ---------------------------------------------------------------------------
+
+quiet_cmd_lzma = LZMA    $@
+      cmd_lzma = { cat $(real-prereqs) | $(LZMA) -9; $(size_append); } > $@
+
+quiet_cmd_lzo = LZO     $@
+      cmd_lzo = { cat $(real-prereqs) | $(KLZOP) -9; $(size_append); } > $@
+
+quiet_cmd_lz4 = LZ4     $@
+      cmd_lz4 = { cat $(real-prereqs) | $(LZ4) -l -c1 stdin stdout; \
+                  $(size_append); } > $@
+
+# U-Boot mkimage
+# ---------------------------------------------------------------------------
+
+MKIMAGE := $(srctree)/scripts/mkuboot.sh
+
+# SRCARCH just happens to match slightly more than ARCH (on sparc), so reduces
+# the number of overrides in arch makefiles
+UIMAGE_ARCH ?= $(SRCARCH)
+UIMAGE_COMPRESSION ?= $(if $(2),$(2),none)
+UIMAGE_OPTS-y ?=
+UIMAGE_TYPE ?= kernel
+UIMAGE_LOADADDR ?= arch_must_set_this
+UIMAGE_ENTRYADDR ?= $(UIMAGE_LOADADDR)
+UIMAGE_NAME ?= 'Linux-$(KERNELRELEASE)'
+
+quiet_cmd_uimage = UIMAGE  $@
+      cmd_uimage = $(BASH) $(MKIMAGE) -A $(UIMAGE_ARCH) -O linux \
+			-C $(UIMAGE_COMPRESSION) $(UIMAGE_OPTS-y) \
+			-T $(UIMAGE_TYPE) \
+			-a $(UIMAGE_LOADADDR) -e $(UIMAGE_ENTRYADDR) \
+			-n $(UIMAGE_NAME) -d $< $@
+
+# XZ
+# ---------------------------------------------------------------------------
+# Use xzkern to compress the kernel image and xzmisc to compress other things.
+#
+# xzkern uses a big LZMA2 dictionary since it doesn't increase memory usage
+# of the kernel decompressor. A BCJ filter is used if it is available for
+# the target architecture. xzkern also appends uncompressed size of the data
+# using size_append. The .xz format has the size information available at
+# the end of the file too, but it's in more complex format and it's good to
+# avoid changing the part of the boot code that reads the uncompressed size.
+# Note that the bytes added by size_append will make the xz tool think that
+# the file is corrupt. This is expected.
+#
+# xzmisc doesn't use size_append, so it can be used to create normal .xz
+# files. xzmisc uses smaller LZMA2 dictionary than xzkern, because a very
+# big dictionary would increase the memory usage too much in the multi-call
+# decompression mode. A BCJ filter isn't used either.
+quiet_cmd_xzkern = XZKERN  $@
+      cmd_xzkern = { cat $(real-prereqs) | sh $(srctree)/scripts/xz_wrap.sh; \
+                     $(size_append); } > $@
+
+quiet_cmd_xzmisc = XZMISC  $@
+      cmd_xzmisc = cat $(real-prereqs) | $(XZ) --check=crc32 --lzma2=dict=1MiB > $@
+
+# ZSTD
+# ---------------------------------------------------------------------------
+# Appends the uncompressed size of the data using size_append. The .zst
+# format has the size information available at the beginning of the file too,
+# but it's in a more complex format and it's good to avoid changing the part
+# of the boot code that reads the uncompressed size.
+#
+# Note that the bytes added by size_append will make the zstd tool think that
+# the file is corrupt. This is expected.
+#
+# zstd uses a maximum window size of 8 MB. zstd22 uses a maximum window size of
+# 128 MB. zstd22 is used for kernel compression because it is decompressed in a
+# single pass, so zstd doesn't need to allocate a window buffer. When streaming
+# decompression is used, like initramfs decompression, zstd22 should likely not
+# be used because it would require zstd to allocate a 128 MB buffer.
+
+quiet_cmd_zstd = ZSTD    $@
+      cmd_zstd = { cat $(real-prereqs) | $(ZSTD) -19; $(size_append); } > $@
+
+quiet_cmd_zstd22 = ZSTD22  $@
+      cmd_zstd22 = { cat $(real-prereqs) | $(ZSTD) -22 --ultra; $(size_append); } > \
$@ +
+# ASM offsets
+# ---------------------------------------------------------------------------
+
+# Default sed regexp - multiline due to syntax constraints
+#
+# Use [:space:] because LLVM's integrated assembler inserts <tab> around
+# the .ascii directive whereas GCC keeps the <space> as-is.
+define sed-offsets
+	's:^[[:space:]]*\.ascii[[:space:]]*"\(.*\)".*:\1:; \
+	/^->/{s:->#\(.*\):/* \1 */:; \
+	s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; \
+	s:->::; p;}'
+endef
+
+# Use filechk to avoid rebuilds when a header changes, but the resulting file
+# does not
+define filechk_offsets
+	 echo "#ifndef $2"; \
+	 echo "#define $2"; \
+	 echo "/*"; \
+	 echo " * DO NOT MODIFY."; \
+	 echo " *"; \
+	 echo " * This file was generated by Kbuild"; \
+	 echo " */"; \
+	 echo ""; \
+	 sed -ne $(sed-offsets) < $<; \
+	 echo ""; \
+	 echo "#endif"
+endef
diff --git a/scripts/basic/.gitignore b/scripts/basic/.gitignore
index d91e941a4..98ae1f509 100644
--- a/scripts/basic/.gitignore
+++ b/scripts/basic/.gitignore
@@ -1,4 +1,2 @@
-hash
+# SPDX-License-Identifier: GPL-2.0-only
 fixdep
-docproc
-split-include
diff --git a/scripts/basic/Makefile b/scripts/basic/Makefile
index 119f079cf..eeb6a38c5 100644
--- a/scripts/basic/Makefile
+++ b/scripts/basic/Makefile
@@ -1,18 +1,5 @@
-###
-# Makefile.basic list the most basic programs used during the build process.
-# The programs listed herein is what is needed to do the basic stuff,
-# such as splitting .config and fix dependency file.
-# This initial step is needed to avoid files to be recompiled
-# when busybox configuration changes (which is what happens when
-# .config is included by main Makefile.
-# ---------------------------------------------------------------------------
-# fixdep: 	 Used to generate dependency information during build process
-# split-include: Divide all config symbols up in a number of files in
-#                include/config/...
-# docproc:	 Used in Documentation/docbook
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# fixdep: used to generate dependency information during build process
 
-hostprogs-y	:= fixdep split-include docproc
-always		:= $(hostprogs-y)
-
-# fixdep is needed to compile other host programs
-$(addprefix $(obj)/,$(filter-out fixdep,$(always))): $(obj)/fixdep
+hostprogs-always-y	+= fixdep
diff --git a/scripts/basic/docproc.c b/scripts/basic/docproc.c
deleted file mode 100644
index 4464e1874..000000000
--- a/scripts/basic/docproc.c
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
- *	docproc is a simple preprocessor for the template files
- *      used as placeholders for the kernel internal documentation.
- *	docproc is used for documentation-frontend and
- *      dependency-generator.
- *	The two usages have in common that they require
- *	some knowledge of the .tmpl syntax, therefore they
- *	are kept together.
- *
- *	documentation-frontend
- *		Scans the template file and call kernel-doc for
- *		all occurrences of ![EIF]file
- *		Beforehand each referenced file are scanned for
- *		any exported sympols "EXPORT_SYMBOL()" statements.
- *		This is used to create proper -function and
- *		-nofunction arguments in calls to kernel-doc.
- *		Usage: docproc doc file.tmpl
- *
- *	dependency-generator:
- *		Scans the template file and list all files
- *		referenced in a format recognized by make.
- *		Usage:	docproc depend file.tmpl
- *		Writes dependency information to stdout
- *		in the following format:
- *		file.tmpl src.c	src2.c
- *		The filenames are obtained from the following constructs:
- *		!Efilename
- *		!Ifilename
- *		!Dfilename
- *		!Ffilename
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <unistd.h>
-#include <limits.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-//bbox disabled: #include <alloca.h>
-
-/* exitstatus is used to keep track of any failing calls to kernel-doc,
- * but execution continues. */
-int exitstatus = 0;
-
-typedef void DFL(char *);
-DFL *defaultline;
-
-typedef void FILEONLY(char * file);
-FILEONLY *internalfunctions;
-FILEONLY *externalfunctions;
-FILEONLY *symbolsonly;
-
-typedef void FILELINE(char * file, char * line);
-FILELINE * singlefunctions;
-FILELINE * entity_system;
-
-#define MAXLINESZ     2048
-#define MAXFILES      250
-#define KERNELDOCPATH "scripts/"
-#define KERNELDOC     "kernel-doc"
-#define DOCBOOK       "-docbook"
-#define FUNCTION      "-function"
-#define NOFUNCTION    "-nofunction"
-
-void usage (void)
-{
-	fprintf(stderr, "Usage: docproc {doc|depend} file\n");
-	fprintf(stderr, "Input is read from file.tmpl. Output is sent to stdout\n");
-	fprintf(stderr, "doc: frontend when generating kernel documentation\n");
-	fprintf(stderr, "depend: generate list of files referenced within file\n");
-}
-
-/*
- * Execute kernel-doc with parameters givin in svec
- */
-void exec_kernel_doc(char **svec)
-{
-	pid_t pid;
-	int ret;
-	char *real_filename;
-	int rflen;
-
-	/* Make sure output generated so far are flushed */
-	fflush(stdout);
-	switch(pid=fork()) {
-		case -1:
-			perror("vfork"+1);
-			exit(1);
-		case  0:
-			rflen  = strlen(getenv("SRCTREE"));
-			rflen += strlen(KERNELDOCPATH KERNELDOC);
-			real_filename = alloca(rflen + 1);
-			strcpy(real_filename, getenv("SRCTREE"));
-			strcat(real_filename, KERNELDOCPATH KERNELDOC);
-			execvp(real_filename, svec);
-			fprintf(stderr, "exec ");
-			perror(real_filename);
-			exit(1);
-		default:
-			waitpid(pid, &ret ,0);
-	}
-	if (WIFEXITED(ret))
-		exitstatus |= WEXITSTATUS(ret);
-	else
-		exitstatus = 0xff;
-}
-
-/* Types used to create list of all exported symbols in a number of files */
-struct symbols
-{
-	char *name;
-};
-
-struct symfile
-{
-	char *filename;
-	struct symbols *symbollist;
-	int symbolcnt;
-};
-
-struct symfile symfilelist[MAXFILES];
-int symfilecnt = 0;
-
-void add_new_symbol(struct symfile *sym, char * symname)
-{
-	sym->symbollist =
-	  realloc(sym->symbollist, (sym->symbolcnt + 1) * sizeof(char *));
-	sym->symbollist[sym->symbolcnt++].name = strdup(symname);
-}
-
-/* Add a filename to the list */
-struct symfile * add_new_file(char * filename)
-{
-	symfilelist[symfilecnt++].filename = strdup(filename);
-	return &symfilelist[symfilecnt - 1];
-}
-/* Check if file already are present in the list */
-struct symfile * filename_exist(char * filename)
-{
-	int i;
-	for (i=0; i < symfilecnt; i++)
-		if (strcmp(symfilelist[i].filename, filename) == 0)
-			return &symfilelist[i];
-	return NULL;
-}
-
-/*
- * List all files referenced within the template file.
- * Files are separated by tabs.
- */
-void adddep(char * file)		   { printf("\t%s", file); }
-void adddep2(char * file, char * line)     { line = line; adddep(file); }
-void noaction(char * line)		   { line = line; }
-void noaction2(char * file, char * line)   { file = file; line = line; }
-
-/* Echo the line without further action */
-void printline(char * line)               { printf("%s", line); }
-
-/*
- * Find all symbols exported with EXPORT_SYMBOL and EXPORT_SYMBOL_GPL
- * in filename.
- * All symbols located are stored in symfilelist.
- */
-void find_export_symbols(char * filename)
-{
-	FILE * fp;
-	struct symfile *sym;
-	char line[MAXLINESZ];
-	if (filename_exist(filename) == NULL) {
-		int rflen = strlen(getenv("SRCTREE")) + strlen(filename);
-		char *real_filename = alloca(rflen + 1);
-		strcpy(real_filename, getenv("SRCTREE"));
-		strcat(real_filename, filename);
-		sym = add_new_file(filename);
-		fp = fopen(real_filename, "r");
-		if (fp == NULL)
-		{
-			fprintf(stderr, "docproc: ");
-			perror(real_filename);
-		}
-		while (fgets(line, MAXLINESZ, fp)) {
-			unsigned char *p;
-			unsigned char *e;
-			if (((p = (unsigned char *)strstr(line, "EXPORT_SYMBOL_GPL")) != 0) ||
-			    ((p = (unsigned char *)strstr(line, "EXPORT_SYMBOL")) != 0)) {
-				/* Skip EXPORT_SYMBOL{_GPL} */
-				while (isalnum(*p) || *p == '_')
-					p++;
-				/* Remove paranteses and additional ws */
-				while (isspace(*p))
-					p++;
-				if (*p != '(')
-					continue; /* Syntax error? */
-				else
-					p++;
-				while (isspace(*p))
-					p++;
-				e = p;
-				while (isalnum(*e) || *e == '_')
-					e++;
-				*e = '\0';
-				add_new_symbol(sym, (char*)p);
-			}
-		}
-		fclose(fp);
-	}
-}
-
-/*
- * Document all external or internal functions in a file.
- * Call kernel-doc with following parameters:
- * kernel-doc -docbook -nofunction function_name1 filename
- * function names are obtained from all the src files
- * by find_export_symbols.
- * intfunc uses -nofunction
- * extfunc uses -function
- */
-void docfunctions(char * filename, char * type)
-{
-	int i,j;
-	int symcnt = 0;
-	int idx = 0;
-	char **vec;
-
-	for (i=0; i <= symfilecnt; i++)
-		symcnt += symfilelist[i].symbolcnt;
-	vec = malloc((2 + 2 * symcnt + 2) * sizeof(char*));
-	if (vec == NULL) {
-		perror("docproc: ");
-		exit(1);
-	}
-	vec[idx++] = KERNELDOC;
-	vec[idx++] = DOCBOOK;
-	for (i=0; i < symfilecnt; i++) {
-		struct symfile * sym = &symfilelist[i];
-		for (j=0; j < sym->symbolcnt; j++) {
-			vec[idx++]     = type;
-			vec[idx++] = sym->symbollist[j].name;
-		}
-	}
-	vec[idx++]     = filename;
-	vec[idx] = NULL;
-	printf("<!-- %s -->\n", filename);
-	exec_kernel_doc(vec);
-	fflush(stdout);
-	free(vec);
-}
-void intfunc(char * filename) {	docfunctions(filename, NOFUNCTION); }
-void extfunc(char * filename) { docfunctions(filename, FUNCTION);   }
-
-/*
- * Document specific function(s) in a file.
- * Call kernel-doc with the following parameters:
- * kernel-doc -docbook -function function1 [-function function2]
- */
-void singfunc(char * filename, char * line)
-{
-	char *vec[200]; /* Enough for specific functions */
-	int i, idx = 0;
-	int startofsym = 1;
-	vec[idx++] = KERNELDOC;
-	vec[idx++] = DOCBOOK;
-
-	/* Split line up in individual parameters preceded by FUNCTION */
-	for (i=0; line[i]; i++) {
-		if (isspace((unsigned char) line[i])) {
-			line[i] = '\0';
-			startofsym = 1;
-			continue;
-		}
-		if (startofsym) {
-			startofsym = 0;
-			vec[idx++] = FUNCTION;
-			vec[idx++] = &line[i];
-		}
-	}
-	vec[idx++] = filename;
-	vec[idx] = NULL;
-	exec_kernel_doc(vec);
-}
-
-/*
- * Parse file, calling action specific functions for:
- * 1) Lines containing !E
- * 2) Lines containing !I
- * 3) Lines containing !D
- * 4) Lines containing !F
- * 5) Default lines - lines not matching the above
- */
-void parse_file(FILE *infile)
-{
-	char line[MAXLINESZ];
-	unsigned char * s;
-	while (fgets(line, MAXLINESZ, infile)) {
-		if (line[0] == '!') {
-			s = (unsigned char *)line + 2;
-			switch (line[1]) {
-				case 'E':
-					while (*s && !isspace(*s)) s++;
-					*s = '\0';
-					externalfunctions(line+2);
-					break;
-				case 'I':
-					while (*s && !isspace(*s)) s++;
-					*s = '\0';
-					internalfunctions(line+2);
-					break;
-				case 'D':
-					while (*s && !isspace(*s)) s++;
-					*s = '\0';
-					symbolsonly(line+2);
-					break;
-				case 'F':
-					/* filename */
-					while (*s && !isspace(*s)) s++;
-					*s++ = '\0';
-					/* function names */
-					while (isspace(*s))
-						s++;
-					singlefunctions(line +2, (char*)s);
-					break;
-				default:
-					defaultline(line);
-			}
-		}
-		else {
-			defaultline(line);
-		}
-	}
-	fflush(stdout);
-}
-
-
-int main(int argc, char **argv)
-{
-	FILE * infile;
-	if (argc != 3) {
-		usage();
-		exit(1);
-	}
-	/* Open file, exit on error */
-	infile = fopen(argv[2], "r");
-	if (infile == NULL) {
-		fprintf(stderr, "docproc: ");
-		perror(argv[2]);
-		exit(2);
-	}
-
-	if (strcmp("doc", argv[1]) == 0)
-	{
-		/* Need to do this in two passes.
-		 * First pass is used to collect all symbols exported
-		 * in the various files.
-		 * Second pass generate the documentation.
-		 * This is required because function are declared
-		 * and exported in different files :-((
-		 */
-		/* Collect symbols */
-		defaultline       = noaction;
-		internalfunctions = find_export_symbols;
-		externalfunctions = find_export_symbols;
-		symbolsonly       = find_export_symbols;
-		singlefunctions   = noaction2;
-		parse_file(infile);
-
-		/* Rewind to start from beginning of file again */
-		fseek(infile, 0, SEEK_SET);
-		defaultline       = printline;
-		internalfunctions = intfunc;
-		externalfunctions = extfunc;
-		symbolsonly       = printline;
-		singlefunctions   = singfunc;
-
-		parse_file(infile);
-	}
-	else if (strcmp("depend", argv[1]) == 0)
-	{
-		/* Create first part of dependency chain
-		 * file.tmpl */
-		printf("%s\t", argv[2]);
-		defaultline       = noaction;
-		internalfunctions = adddep;
-		externalfunctions = adddep;
-		symbolsonly       = adddep;
-		singlefunctions   = adddep2;
-		parse_file(infile);
-		printf("\n");
-	}
-	else
-	{
-		fprintf(stderr, "Unknown option: %s\n", argv[1]);
-		exit(1);
-	}
-	fclose(infile);
-	fflush(stdout);
-	return exitstatus;
-}
diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c
index 054c7512d..d98540552 100644
--- a/scripts/basic/fixdep.c
+++ b/scripts/basic/fixdep.c
@@ -16,24 +16,25 @@
  * tells make when to remake a file.
  *
  * To use this list as-is however has the drawback that virtually
- * every file in the kernel includes <linux/config.h> which then again
- * includes <linux/autoconf.h>
+ * every file in the kernel includes autoconf.h.
  *
- * If the user re-runs make *config, linux/autoconf.h will be
+ * If the user re-runs make *config, autoconf.h will be
  * regenerated.  make notices that and will rebuild every file which
  * includes autoconf.h, i.e. basically all files. This is extremely
  * annoying if the user just changed CONFIG_HIS_DRIVER from n to m.
  *
  * So we play the same trick that "mkdep" played before. We replace
- * the dependency on linux/autoconf.h by a dependency on every config
- * option which is mentioned in any of the listed prequisites.
+ * the dependency on autoconf.h by a dependency on every config
+ * option which is mentioned in any of the listed prerequisites.
  *
- * To be exact, split-include populates a tree in include/config/,
- * e.g. include/config/his/driver.h, which contains the #define/#undef
- * for the CONFIG_HIS_DRIVER option.
+ * kconfig populates a tree in include/config/ with an empty file
+ * for each config symbol and when the configuration is updated
+ * the files representing changed config options are touched
+ * which then let make pick up the changes and the files that use
+ * the config symbols are rebuilt.
  *
  * So if the user changes his CONFIG_HIS_DRIVER option, only the objects
- * which depend on "include/linux/config/his/driver.h" will be rebuilt,
+ * which depend on "include/config/his/driver.h" will be rebuilt,
  * so most likely only his driver ;-)
  *
  * The idea above dates, by the way, back to Michael E Chastain, AFAIK.
@@ -72,17 +73,11 @@
  *   cmd_<target> = <cmdline>
  *
  * and then basically copies the .<target>.d file to stdout, in the
- * process filtering out the dependency on linux/autoconf.h and adding
+ * process filtering out the dependency on autoconf.h and adding
  * dependencies on include/config/my/option.h for every
- * CONFIG_MY_OPTION encountered in any of the prequisites.
+ * CONFIG_MY_OPTION encountered in any of the prerequisites.
  *
- * It will also filter out all the dependencies on *.ver. We need
- * to make sure that the generated version checksum are globally up
- * to date before even starting the recursive build, so it's too late
- * at this point anyway.
- *
- * The algorithm to grep for "CONFIG_..." is bit unusual, but should
- * be fast ;-) We don't even try to really parse the header files, but
+ * We don't even try to really parse the header files, but
  * merely grep, i.e. if CONFIG_FOO is mentioned in a comment, it will
  * be picked up as well. It's not a problem with respect to
  * correctness, since that can only give too many dependencies, thus
@@ -93,86 +88,104 @@
  * (Note: it'd be easy to port over the complete mkdep state machine,
  *  but I don't think the added complexity is worth it)
  */
-/*
- * Note 2: if somebody writes HELLO_CONFIG_BOOM in a file, it will depend onto
- * CONFIG_BOOM. This could seem a bug (not too hard to fix), but please do not
- * fix it! Some UserModeLinux files (look at arch/um/) call CONFIG_BOOM as
- * UML_CONFIG_BOOM, to avoid conflicts with /usr/include/linux/autoconf.h,
- * through arch/um/include/uml-config.h; this fixdep "bug" makes sure that
- * those files will have correct dependencies.
- */
 
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <sys/mman.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <string.h>
+#include <stdarg.h>
 #include <stdlib.h>
 #include <stdio.h>
-#include <limits.h>
 #include <ctype.h>
-#include <arpa/inet.h>
-//bbox disabled: #include <alloca.h>
-
-/* bbox: not needed
-#define INT_CONF ntohl(0x434f4e46)
-#define INT_ONFI ntohl(0x4f4e4649)
-#define INT_NFIG ntohl(0x4e464947)
-#define INT_FIG_ ntohl(0x4649475f)
-*/
-
-char *target;
-char *depfile;
-char *cmdline;
-
-void usage(void)
 
+static void usage(void)
 {
 	fprintf(stderr, "Usage: fixdep <depfile> <target> <cmdline>\n");
 	exit(1);
 }
 
 /*
- * Print out the commandline prefixed with cmd_<target filename> :=
+ * In the intended usage of this program, the stdout is redirected to .*.cmd
+ * files. The return value of printf() and putchar() must be checked to catch
+ * any error, e.g. "No space left on device".
  */
-void print_cmdline(void)
+static void xprintf(const char *format, ...)
 {
-	printf("cmd_%s := %s\n\n", target, cmdline);
+	va_list ap;
+	int ret;
+
+	va_start(ap, format);
+	ret = vprintf(format, ap);
+	if (ret < 0) {
+		perror("fixdep");
+		exit(1);
+	}
+	va_end(ap);
 }
 
-char * str_config  = NULL;
-int    size_config = 0;
-int    len_config  = 0;
+static void xputchar(int c)
+{
+	int ret;
+
+	ret = putchar(c);
+	if (ret == EOF) {
+		perror("fixdep");
+		exit(1);
+	}
+}
 
 /*
- * Grow the configuration string to a desired length.
- * Usually the first growth is plenty.
+ * Print out a dependency path from a symbol name
  */
-void grow_config(int len)
+static void print_dep(const char *m, int slen, const char *dir)
 {
-	while (len_config + len > size_config) {
-		if (size_config == 0)
-			size_config = 2048;
-		str_config = realloc(str_config, size_config *= 2);
-		if (str_config == NULL)
-			{ perror("fixdep:malloc"); exit(1); }
+	int c, prev_c = '/', i;
+
+	xprintf("    $(wildcard %s/", dir);
+	for (i = 0; i < slen; i++) {
+		c = m[i];
+		if (c == '_')
+			c = '/';
+		else
+			c = tolower(c);
+		if (c != '/' || prev_c != '/')
+			xputchar(c);
+		prev_c = c;
 	}
+	xprintf(".h) \\\n");
 }
 
+struct item {
+	struct item	*next;
+	unsigned int	len;
+	unsigned int	hash;
+	char		name[];
+};
+
+#define HASHSZ 256
+static struct item *hashtab[HASHSZ];
 
+static unsigned int strhash(const char *str, unsigned int sz)
+{
+	/* fnv32 hash */
+	unsigned int i, hash = 2166136261U;
+
+	for (i = 0; i < sz; i++)
+		hash = (hash ^ str[i]) * 0x01000193;
+	return hash;
+}
 
 /*
  * Lookup a value in the configuration string.
  */
-int is_defined_config(const char * name, int len)
+static int is_defined_config(const char *name, int len, unsigned int hash)
 {
-	const char * pconfig;
-	const char * plast = str_config + len_config - len;
-	for ( pconfig = str_config + 1; pconfig < plast; pconfig++ ) {
-		if (pconfig[ -1] == '\n'
-		&&  pconfig[len] == '\n'
-		&&  !memcmp(pconfig, name, len))
+	struct item *aux;
+
+	for (aux = hashtab[hash % HASHSZ]; aux; aux = aux->next) {
+		if (aux->hash == hash && aux->len == len &&
+		    memcmp(aux->name, name, len) == 0)
 			return 1;
 	}
 	return 0;
@@ -181,224 +194,198 @@ int is_defined_config(const char * name, int len)
 /*
  * Add a new value to the configuration string.
  */
-void define_config(const char * name, int len)
+static void define_config(const char *name, int len, unsigned int hash)
 {
-	grow_config(len + 1);
-
-	memcpy(str_config+len_config, name, len);
-	len_config += len;
-	str_config[len_config++] = '\n';
-}
+	struct item *aux = malloc(sizeof(*aux) + len);
 
-/*
- * Clear the set of configuration strings.
- */
-void clear_config(void)
-{
-	len_config = 0;
-	define_config("", 0);
+	if (!aux) {
+		perror("fixdep:malloc");
+		exit(1);
+	}
+	memcpy(aux->name, name, len);
+	aux->len = len;
+	aux->hash = hash;
+	aux->next = hashtab[hash % HASHSZ];
+	hashtab[hash % HASHSZ] = aux;
 }
 
 /*
  * Record the use of a CONFIG_* word.
  */
-void use_config(char *m, int slen)
+static void use_config(const char *m, int slen)
 {
-	char *s = alloca(slen+1);
-	char *p;
+	unsigned int hash = strhash(m, slen);
 
-	if (is_defined_config(m, slen))
+	if (is_defined_config(m, slen, hash))
 	    return;
 
-	define_config(m, slen);
-
-	memcpy(s, m, slen); s[slen] = 0;
-
-	for (p = s; p < s + slen; p++) {
-		if (*p == '_')
-			*p = '/';
-		else
-			*p = tolower((int)*p);
-	}
-	printf("    $(wildcard include/config/%s.h) \\\n", s);
+	define_config(m, slen, hash);
+	print_dep(m, slen, "include/config");
 }
 
-void parse_config_file(char *map, size_t len)
+/* test if s ends in sub */
+static int str_ends_with(const char *s, int slen, const char *sub)
 {
-	/* modified for bbox */
-	unsigned char *end_3 = (unsigned char *)map + len - 3; /* 3 == length of "IF_" */
-	unsigned char *end_7 = (unsigned char *)map + len - 7;
-	unsigned char *p = (unsigned char *)map;
-	unsigned char *q;
-	int off;
-
-	for (; p <= end_3; p++) {
-		/* Find next identifier's beginning */
-		if (!(isalnum(*p) || *p == '_'))
-			continue;
+	int sublen = strlen(sub);
 
-		/* Check it */
-		if (p < end_7 && p[6] == '_') {
-			if (!memcmp(p, "CONFIG", 6)) goto conf7;
-			if (!memcmp(p, "ENABLE", 6)) goto conf7;
-			if (!memcmp(p, "IF_NOT", 6)) goto conf7;
-		}
-		/* we have at least 3 chars because of p <= end_3 */
-		/*if (!memcmp(p, "IF_", 3)) ...*/
-		if (p[0] == 'I' && p[1] == 'F' && p[2] == '_') {
-			off = 3;
-			goto conf;
-		}
+	if (sublen > slen)
+		return 0;
 
-		/* This identifier is not interesting, skip it */
-		while (p <= end_3 && (isalnum(*p) || *p == '_'))
-			p++;
-		continue;
-
-	conf7:	off = 7;
-	conf:
-		p += off;
-		for (q = p; q < end_3+3; q++) {
-			if (!(isalnum(*q) || *q == '_'))
-				break;
-		}
-		if (q != p) {
-			use_config((char*)p, q - p);
-		}
-	}
+	return !memcmp(s + slen - sublen, sub, sublen);
 }
 
-/* test is s ends in sub */
-int strrcmp(char *s, char *sub)
+static void parse_config_file(const char *p)
 {
-	int slen = strlen(s);
-	int sublen = strlen(sub);
-
-	if (sublen > slen)
-		return 1;
+	const char *q, *r;
+	const char *start = p;
 
-	return memcmp(s + slen - sublen, sub, sublen);
+	while ((p = strstr(p, "CONFIG_"))) {
+		if (p > start && (isalnum(p[-1]) || p[-1] == '_')) {
+			p += 7;
+			continue;
+		}
+		p += 7;
+		q = p;
+		while (isalnum(*q) || *q == '_')
+			q++;
+		if (str_ends_with(p, q - p, "_MODULE"))
+			r = q - 7;
+		else
+			r = q;
+		if (r > p)
+			use_config(p, r - p);
+		p = q;
+	}
 }
 
-void do_config_file(char *filename)
+static void *read_file(const char *filename)
 {
 	struct stat st;
 	int fd;
-	void *map;
+	char *buf;
 
 	fd = open(filename, O_RDONLY);
 	if (fd < 0) {
-		fprintf(stderr, "fixdep: ");
+		fprintf(stderr, "fixdep: error opening file: ");
 		perror(filename);
 		exit(2);
 	}
-	fstat(fd, &st);
-	if (st.st_size == 0) {
-		close(fd);
-		return;
+	if (fstat(fd, &st) < 0) {
+		fprintf(stderr, "fixdep: error fstat'ing file: ");
+		perror(filename);
+		exit(2);
 	}
-	map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
-	if ((long) map == -1) {
-		perror("fixdep: mmap");
-		close(fd);
-		return;
+	buf = malloc(st.st_size + 1);
+	if (!buf) {
+		perror("fixdep: malloc");
+		exit(2);
 	}
+	if (read(fd, buf, st.st_size) != st.st_size) {
+		perror("fixdep: read");
+		exit(2);
+	}
+	buf[st.st_size] = '\0';
+	close(fd);
 
-	parse_config_file(map, st.st_size);
-
-	munmap(map, st.st_size);
+	return buf;
+}
 
-	close(fd);
+/* Ignore certain dependencies */
+static int is_ignored_file(const char *s, int len)
+{
+	return str_ends_with(s, len, "include/generated/autoconf.h") ||
+	       str_ends_with(s, len, "include/generated/autoksyms.h");
 }
 
-void parse_dep_file(void *map, size_t len)
+/*
+ * Important: The below generated source_foo.o and deps_foo.o variable
+ * assignments are parsed not only by make, but also by the rather simple
+ * parser in scripts/mod/sumversion.c.
+ */
+static void parse_dep_file(char *m, const char *target)
 {
-	char *m = map;
-	char *end = m + len;
 	char *p;
-	char *s = alloca(len);
-
-	p = memchr(m, ':', len);
-	if (!p) {
-		fprintf(stderr, "fixdep: parse error\n");
-		exit(1);
-	}
-	memcpy(s, m, p-m); s[p-m] = 0;
-	printf("deps_%s := \\\n", target);
-	m = p+1;
+	int is_last, is_target;
+	int saw_any_target = 0;
+	int is_first_dep = 0;
+	void *buf;
+
+	while (1) {
+		/* Skip any "white space" */
+		while (*m == ' ' || *m == '\\' || *m == '\n')
+			m++;
 
-	clear_config();
+		if (!*m)
+			break;
 
-	while (m < end) {
-		while (m < end && (*m == ' ' || *m == '\\' || *m == '\n' || *m == '\r'))
-			m++;
+		/* Find next "white space" */
 		p = m;
-		while (p < end && *p != ' ') p++;
-		if (p == end) {
-			do p--; while (!isalnum((unsigned char)*p));
+		while (*p && *p != ' ' && *p != '\\' && *p != '\n')
 			p++;
+		is_last = (*p == '\0');
+		/* Is the token we found a target name? */
+		is_target = (*(p-1) == ':');
+		/* Don't write any target names into the dependency file */
+		if (is_target) {
+			/* The /next/ file is the first dependency */
+			is_first_dep = 1;
+		} else if (!is_ignored_file(m, p - m)) {
+			*p = '\0';
+
+			/*
+			 * Do not list the source file as dependency, so that
+			 * kbuild is not confused if a .c file is rewritten
+			 * into .S or vice versa. Storing it in source_* is
+			 * needed for modpost to compute srcversions.
+			 */
+			if (is_first_dep) {
+				/*
+				 * If processing the concatenation of multiple
+				 * dependency files, only process the first
+				 * target name, which will be the original
+				 * source name, and ignore any other target
+				 * names, which will be intermediate temporary
+				 * files.
+				 */
+				if (!saw_any_target) {
+					saw_any_target = 1;
+					xprintf("source_%s := %s\n\n",
+						target, m);
+					xprintf("deps_%s := \\\n", target);
+				}
+				is_first_dep = 0;
+			} else {
+				xprintf("  %s \\\n", m);
+			}
+
+			buf = read_file(m);
+			parse_config_file(buf);
+			free(buf);
 		}
-		memcpy(s, m, p-m); s[p-m] = 0;
-		if (strrcmp(s, "include/generated/autoconf.h") &&
-		    strrcmp(s, "arch/um/include/uml-config.h") &&
-		    strrcmp(s, ".ver")) {
-			printf("  %s \\\n", s);
-			do_config_file(s);
-		}
-		m = p + 1;
-	}
-	printf("\n%s: $(deps_%s)\n\n", target, target);
-	printf("$(deps_%s):\n", target);
-}
 
-void print_deps(void)
-{
-	struct stat st;
-	int fd;
-	void *map;
+		if (is_last)
+			break;
 
-	fd = open(depfile, O_RDONLY);
-	if (fd < 0) {
-		fprintf(stderr, "fixdep: ");
-		perror(depfile);
-		exit(2);
-	}
-	fstat(fd, &st);
-	if (st.st_size == 0) {
-		fprintf(stderr,"fixdep: %s is empty\n",depfile);
-		close(fd);
-		return;
-	}
-	map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
-	if ((long) map == -1) {
-		perror("fixdep: mmap");
-		close(fd);
-		return;
+		/*
+		 * Start searching for next token immediately after the first
+		 * "whitespace" character that follows this token.
+		 */
+		m = p + 1;
 	}
 
-	parse_dep_file(map, st.st_size);
-
-	munmap(map, st.st_size);
-
-	close(fd);
-}
-
-void traps(void)
-{
-/* bbox: not needed
-	static char test[] __attribute__((aligned(sizeof(int)))) = "CONF";
-
-	if (*(int *)test != INT_CONF) {
-		fprintf(stderr, "fixdep: sizeof(int) != 4 or wrong endianess? %#x\n",
-			*(int *)test);
-		exit(2);
+	if (!saw_any_target) {
+		fprintf(stderr, "fixdep: parse error; no targets found\n");
+		exit(1);
 	}
-*/
+
+	xprintf("\n%s: $(deps_%s)\n\n", target, target);
+	xprintf("$(deps_%s):\n", target);
 }
 
-int main(int argc, char **argv)
+int main(int argc, char *argv[])
 {
-	traps();
+	const char *depfile, *target, *cmdline;
+	void *buf;
 
 	if (argc != 4)
 		usage();
@@ -407,8 +394,11 @@ int main(int argc, char **argv)
 	target = argv[2];
 	cmdline = argv[3];
 
-	print_cmdline();
-	print_deps();
+	xprintf("cmd_%s := %s\n\n", target, cmdline);
+
+	buf = read_file(depfile);
+	parse_dep_file(buf, target);
+	free(buf);
 
 	return 0;
 }
diff --git a/scripts/basic/split-include.c b/scripts/basic/split-include.c
deleted file mode 100644
index 6ef29195e..000000000
--- a/scripts/basic/split-include.c
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * split-include.c
- *
- * Copyright abandoned, Michael Chastain, <mailto:mec@shout.net>.
- * This is a C version of syncdep.pl by Werner Almesberger.
- *
- * This program takes autoconf.h as input and outputs a directory full
- * of one-line include files, merging onto the old values.
- *
- * Think of the configuration options as key-value pairs.  Then there
- * are five cases:
- *
- *    key      old value   new value   action
- *
- *    KEY-1    VALUE-1     VALUE-1     leave file alone
- *    KEY-2    VALUE-2A    VALUE-2B    write VALUE-2B into file
- *    KEY-3    -           VALUE-3     write VALUE-3  into file
- *    KEY-4    VALUE-4     -           write an empty file
- *    KEY-5    (empty)     -           leave old empty file alone
- */
-
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#define ERROR_EXIT(strExit)						\
-    {									\
-	const int errnoSave = errno;					\
-	fprintf(stderr, "%s: ", str_my_name);				\
-	errno = errnoSave;						\
-	perror((strExit));						\
-	exit(1);							\
-    }
-
-
-
-int main(int argc, const char * argv [])
-{
-    const char * str_my_name;
-    const char * str_file_autoconf;
-    const char * str_dir_config;
-
-    FILE * fp_config;
-    FILE * fp_target;
-    FILE * fp_find;
-
-    int buffer_size;
-
-    char * line;
-    char * old_line;
-    char * list_target;
-    char * ptarget;
-
-    struct stat stat_buf;
-
-    /* Check arg count. */
-    if (argc != 3)
-    {
-	fprintf(stderr, "%s: wrong number of arguments.\n", argv[0]);
-	exit(1);
-    }
-
-    str_my_name       = argv[0];
-    str_file_autoconf = argv[1];
-    str_dir_config    = argv[2];
-
-    /* Find a buffer size. */
-    if (stat(str_file_autoconf, &stat_buf) != 0)
-	ERROR_EXIT(str_file_autoconf);
-    buffer_size = 2 * stat_buf.st_size + 4096;
-
-    /* Allocate buffers. */
-    if ( (line        = malloc(buffer_size)) == NULL
-    ||   (old_line    = malloc(buffer_size)) == NULL
-    ||   (list_target = malloc(buffer_size)) == NULL )
-	ERROR_EXIT(str_file_autoconf);
-
-    /* Open autoconfig file. */
-    if ((fp_config = fopen(str_file_autoconf, "r")) == NULL)
-	ERROR_EXIT(str_file_autoconf);
-
-    /* Make output directory if needed. */
-    if (stat(str_dir_config, &stat_buf) != 0)
-    {
-	if (mkdir(str_dir_config, 0755) != 0)
-	    ERROR_EXIT(str_dir_config);
-    }
-
-    /* Change to output directory. */
-    if (chdir(str_dir_config) != 0)
-	ERROR_EXIT(str_dir_config);
-
-    /* Put initial separator into target list. */
-    ptarget = list_target;
-    *ptarget++ = '\n';
-
-    /* Read config lines. */
-    while (fgets(line, buffer_size, fp_config))
-    {
-	const char * str_config;
-	int is_same;
-	int itarget;
-
-	if (line[0] != '#')
-	    continue;
-	if ((str_config = strstr(line, " CONFIG_")) == NULL)
-	    continue;
-
-	/* We found #define CONFIG_foo or #undef CONFIG_foo.
-	 * Make the output file name. */
-	str_config += sizeof(" CONFIG_") - 1;
-	for (itarget = 0; !isspace((unsigned char)str_config[itarget]); itarget++)
-	{
-	    int c = (unsigned char) str_config[itarget];
-	    if (isupper(c)) c = tolower(c);
-	    if (c == '_')   c = '/';
-	    ptarget[itarget] = c;
-	}
-	ptarget[itarget++] = '.';
-	ptarget[itarget++] = 'h';
-	ptarget[itarget++] = '\0';
-
-	/* Check for existing file. */
-	is_same = 0;
-	if ((fp_target = fopen(ptarget, "r")) != NULL)
-	{
-	    if (!fgets(old_line, buffer_size, fp_target) && ferror(fp_target))
-		ERROR_EXIT(ptarget);
-	    if (fclose(fp_target) != 0)
-		ERROR_EXIT(ptarget);
-	    if (!strcmp(line, old_line))
-		is_same = 1;
-	}
-
-	if (!is_same)
-	{
-	    /* Auto-create directories. */
-	    int islash;
-	    for (islash = 0; islash < itarget; islash++)
-	    {
-		if (ptarget[islash] == '/')
-		{
-		    ptarget[islash] = '\0';
-		    if (stat(ptarget, &stat_buf) != 0
-		    &&  mkdir(ptarget, 0755)     != 0)
-			ERROR_EXIT( ptarget );
-		    ptarget[islash] = '/';
-		}
-	    }
-
-	    /* Write the file. */
-	    if ((fp_target = fopen(ptarget,  "w")) == NULL)
-		ERROR_EXIT(ptarget);
-	    fputs(line, fp_target);
-	    if (ferror(fp_target) || fclose(fp_target) != 0)
-		ERROR_EXIT(ptarget);
-	}
-
-	/* Update target list */
-	ptarget += itarget;
-	*(ptarget-1) = '\n';
-    }
-
-    /*
-     * Close autoconfig file.
-     * Terminate the target list.
-     */
-    if (fclose(fp_config) != 0)
-	ERROR_EXIT(str_file_autoconf);
-    *ptarget = '\0';
-
-    /*
-     * Fix up existing files which have no new value.
-     * This is Case 4 and Case 5.
-     *
-     * I re-read the tree and filter it against list_target.
-     * This is crude.  But it avoids data copies.  Also, list_target
-     * is compact and contiguous, so it easily fits into cache.
-     *
-     * Notice that list_target contains strings separated by \n,
-     * with a \n before the first string and after the last.
-     * fgets gives the incoming names a terminating \n.
-     * So by having an initial \n, strstr will find exact matches.
-     */
-
-    fp_find = popen("find * -type f -name \"*.h\" -print", "r");
-    if (fp_find == 0)
-	ERROR_EXIT( "find" );
-
-    line[0] = '\n';
-    while (fgets(line+1, buffer_size, fp_find))
-    {
-	if (strstr(list_target, line) == NULL)
-	{
-	    /*
-	     * This is an old file with no CONFIG_* flag in autoconf.h.
-	     */
-
-	    /* First strip the \n. */
-	    line[strlen(line)-1] = '\0';
-
-	    /* Grab size. */
-	    if (stat(line+1, &stat_buf) != 0)
-		ERROR_EXIT(line);
-
-	    /* If file is not empty, make it empty and give it a fresh date. */
-	    if (stat_buf.st_size != 0)
-	    {
-		if ((fp_target = fopen(line+1, "w")) == NULL)
-		    ERROR_EXIT(line);
-		if (fclose(fp_target) != 0)
-		    ERROR_EXIT(line);
-	    }
-	}
-    }
-
-    if (pclose(fp_find) != 0)
-	ERROR_EXIT("find");
-
-    return 0;
-}
diff --git a/scripts/cc-version.sh b/scripts/cc-version.sh
new file mode 100755
index 000000000..3f2ee885b
--- /dev/null
+++ b/scripts/cc-version.sh
@@ -0,0 +1,82 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+#
+# Print the compiler name and its version in a 5 or 6-digit form.
+# Also, perform the minimum version check.
+
+set -e
+
+# When you raise the minimum compiler version, please update
+# Documentation/process/changes.rst as well.
+gcc_min_version=4.9.0
+clang_min_version=10.0.1
+icc_min_version=16.0.3 # temporary
+
+# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63293
+# https://lore.kernel.org/r/20210107111841.GN1551@shell.armlinux.org.uk
+if [ "$SRCARCH" = arm64 ]; then
+	gcc_min_version=5.1.0
+fi
+
+# Print the compiler name and some version components.
+get_compiler_info()
+{
+	cat <<- EOF | "$@" -E -P -x c - 2>/dev/null
+	#if defined(__clang__)
+	Clang	__clang_major__  __clang_minor__  __clang_patchlevel__
+	#elif defined(__INTEL_COMPILER)
+	ICC	__INTEL_COMPILER  __INTEL_COMPILER_UPDATE
+	#elif defined(__GNUC__)
+	GCC	__GNUC__  __GNUC_MINOR__  __GNUC_PATCHLEVEL__
+	#else
+	unknown
+	#endif
+	EOF
+}
+
+# Convert the version string x.y.z to a canonical 5 or 6-digit form.
+get_canonical_version()
+{
+	IFS=.
+	set -- $1
+	echo $((10000 * $1 + 100 * $2 + $3))
+}
+
+# $@ instead of $1 because multiple words might be given, e.g. CC="ccache gcc".
+orig_args="$@"
+set -- $(get_compiler_info "$@")
+
+name=$1
+
+case "$name" in
+GCC)
+	version=$2.$3.$4
+	min_version=$gcc_min_version
+	;;
+Clang)
+	version=$2.$3.$4
+	min_version=$clang_min_version
+	;;
+ICC)
+	version=$(($2 / 100)).$(($2 % 100)).$3
+	min_version=$icc_min_version
+	;;
+*)
+	echo "$orig_args: unknown compiler" >&2
+	exit 1
+	;;
+esac
+
+cversion=$(get_canonical_version $version)
+min_cversion=$(get_canonical_version $min_version)
+
+if [ "$cversion" -lt "$min_cversion" ]; then
+	echo >&2 "***"
+	echo >&2 "*** Compiler is too old."
+	echo >&2 "***   Your $name version:    $version"
+	echo >&2 "***   Minimum $name version: $min_version"
+	echo >&2 "***"
+	exit 1
+fi
+
+echo $name $cversion
diff --git a/scripts/gcc-version.sh b/scripts/gcc-version.sh
index 0eb27c7a6..11bb90984 100755
--- a/scripts/gcc-version.sh
+++ b/scripts/gcc-version.sh
@@ -1,12 +1,33 @@
 #!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
 #
-# gcc-version gcc-command
+# gcc-version [-p] gcc-command
 #
 # Prints the gcc version of `gcc-command' in a canonical 4-digit form
 # such as `0295' for gcc-2.95, `0303' for gcc-3.3, etc.
 #
+# With the -p option, prints the patchlevel as well, for example `029503' for
+# gcc-2.95.3, `030301' for gcc-3.3.1, etc.
+#
+
+if [ "$1" = "-p" ] ; then
+	with_patchlevel=1;
+	shift;
+fi
 
 compiler="$*"
-# tr -d '\r': fix up msdos-style line endings (Cygwin et al)
-MAJ_MIN=$(echo __GNUC__ __GNUC_MINOR__ | $compiler -E -xc - | tr -d '\r' | tail -n \
                1)
-printf '%02d%02d\n' $MAJ_MIN
+
+if [ ${#compiler} -eq 0 ]; then
+	echo "Error: No compiler specified."
+	printf "Usage:\n\t$0 <gcc-command>\n"
+	exit 1
+fi
+
+MAJOR=$(echo __GNUC__ | $compiler -E -x c - | tail -n 1)
+MINOR=$(echo __GNUC_MINOR__ | $compiler -E -x c - | tail -n 1)
+if [ "x$with_patchlevel" != "x" ] ; then
+	PATCHLEVEL=$(echo __GNUC_PATCHLEVEL__ | $compiler -E -x c - | tail -n 1)
+	printf "%02d%02d%02d\\n" $MAJOR $MINOR $PATCHLEVEL
+else
+	printf "%02d%02d\\n" $MAJOR $MINOR
+fi
diff --git a/scripts/kconfig/.gitignore b/scripts/kconfig/.gitignore
index b49584c93..c3d537cd0 100644
--- a/scripts/kconfig/.gitignore
+++ b/scripts/kconfig/.gitignore
@@ -1,19 +1,12 @@
-#
-# Generated files
-#
-config*
-lex.*.c
-*.tab.c
-*.tab.h
-zconf.hash.c
-*.moc
-lkc_defs.h
+# SPDX-License-Identifier: GPL-2.0-only
+/qconf-moc.cc
+*conf-cfg
 
 #
 # configuration programs
 #
 conf
 mconf
+nconf
 qconf
 gconf
-kxgettext
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 080714227..8c19b82c6 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -1,271 +1,198 @@
+# SPDX-License-Identifier: GPL-2.0
 # ===========================================================================
 # Kernel configuration targets
 # These targets are used from top-level makefile
 
-PHONY += oldconfig xconfig gconfig menuconfig config silentoldconfig \
update-po-config +ifdef KBUILD_KCONFIG
+Kconfig := $(KBUILD_KCONFIG)
+else
+Kconfig := Kconfig
+endif
 
-xconfig: $(obj)/qconf
-	$< Config.in
+ifeq ($(quiet),silent_)
+silent := -s
+endif
 
-gconfig: $(obj)/gconf
-	$< Config.in
+# We need this, in case the user has it in its environment
+unexport CONFIG_
+
+config-prog	:= conf
+menuconfig-prog	:= mconf
+nconfig-prog	:= nconf
+gconfig-prog	:= gconf
+xconfig-prog	:= qconf
+
+define config_rule
+PHONY += $(1)
+$(1): $(obj)/$($(1)-prog)
+	$(Q)$$< $(silent) $(Kconfig)
+
+PHONY += build_$(1)
+build_$(1): $(obj)/$($(1)-prog)
+endef
+
+$(foreach c, config menuconfig nconfig gconfig xconfig, $(eval $(call \
config_rule,$(c)))) +
+PHONY += localmodconfig localyesconfig
+localyesconfig localmodconfig: $(obj)/conf
+	$(Q)$(PERL) $(srctree)/$(src)/streamline_config.pl --$@ $(srctree) $(Kconfig) > \
.tmp.config +	$(Q)if [ -f .config ]; then 				\
+		cmp -s .tmp.config .config ||			\
+		(mv -f .config .config.old.1;			\
+		 mv -f .tmp.config .config;			\
+		 $< $(silent) --oldconfig $(Kconfig);		\
+		 mv -f .config.old.1 .config.old)		\
+	else							\
+		mv -f .tmp.config .config;			\
+		$< $(silent) --oldconfig $(Kconfig);		\
+	fi
+	$(Q)rm -f .tmp.config
 
-menuconfig: $(obj)/mconf
-	$(Q)$(MAKE) $(build)=scripts/kconfig/lxdialog
-	$< Config.in
+# These targets map 1:1 to the commandline options of 'conf'
+#
+# Note:
+#  syncconfig has become an internal implementation detail and is now
+#  deprecated for external use
+simple-targets := oldconfig allnoconfig allyesconfig allmodconfig \
+	alldefconfig randconfig listnewconfig olddefconfig syncconfig \
+	helpnewconfig yes2modconfig mod2yesconfig
 
-config: $(obj)/conf
-	$< Config.in
+PHONY += $(simple-targets)
 
-# Mtime granularity problem.
-# It was observed that these commands:
-# make allnoconfig; sed -i -e '/CONFIG_TRUE/s/.*/CONFIG_TRUE=y/' .config; make
-# sometimes produce busybox with "true" applet still disabled.
-# This is caused by .config updated by sed having mtime which is still
-# equal to (not bigger than) include/generated/autoconf.h's mtime,
-# and thus 2nd make does not regenerate include/generated/autoconf.h.
-# Waiting for 1 second after non-interactive "make XXXXconfig"
-# prevents this from happening.
-#
-# We'd like to detect whether filesystem we are on has coarse mtimes,
-# but can't do it yet, bbox ls hasn't got --full-time.
-#MTIME_IS_COARSE:=@ls --full-time -ld | grep -F .000 >/dev/null
-MTIME_IS_COARSE:=@true
-
-oldconfig: $(obj)/conf
-	$< -o Config.in
-	$(MTIME_IS_COARSE) && sleep 1
-
-silentoldconfig: $(obj)/conf
-	$< -s Config.in
-	$(MTIME_IS_COARSE) && sleep 1
-
-update-po-config: $(obj)/kxgettext
-	xgettext --default-domain=linux \
-          --add-comments --keyword=_ --keyword=N_ \
-          --files-from=scripts/kconfig/POTFILES.in \
-          --output scripts/kconfig/config.pot
-	$(Q)ln -fs Kconfig_i386 arch/um/Kconfig_arch
-	$(Q)for i in `ls arch/`; \
-	do \
-	  scripts/kconfig/kxgettext arch/$$i/Kconfig \
-	    | msguniq -o scripts/kconfig/linux_$${i}.pot; \
-	done
-	$(Q)msgcat scripts/kconfig/config.pot \
-	  `find scripts/kconfig/ -type f -name linux_*.pot` \
-	  --output scripts/kconfig/linux_raw.pot
-	$(Q)msguniq --sort-by-file scripts/kconfig/linux_raw.pot \
-	    --output scripts/kconfig/linux.pot
-	$(Q)rm -f arch/um/Kconfig_arch
-	$(Q)rm -f scripts/kconfig/linux_*.pot scripts/kconfig/config.pot
-
-PHONY += randconfig allyesconfig allnoconfig allmodconfig defconfig
-
-randconfig: $(obj)/conf
-	$< -r Config.in
-	$(MTIME_IS_COARSE) && sleep 1
-
-allyesconfig: $(obj)/conf
-	$< -y Config.in
-	$(MTIME_IS_COARSE) && sleep 1
-
-allnoconfig: $(obj)/conf
-	$< -n Config.in
-	$(MTIME_IS_COARSE) && sleep 1
-
-allmodconfig: $(obj)/conf
-	$< -m Config.in
-	$(MTIME_IS_COARSE) && sleep 1
+$(simple-targets): $(obj)/conf
+	$(Q)$< $(silent) --$@ $(Kconfig)
+
+PHONY += savedefconfig defconfig
+
+savedefconfig: $(obj)/conf
+	$(Q)$< $(silent) --$@=defconfig $(Kconfig)
 
 defconfig: $(obj)/conf
-ifeq ($(KBUILD_DEFCONFIG),)
-	$< -d Config.in
+ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG)),)
+	@$(kecho) "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'"
+	$(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig)
 else
-	@echo *** Default configuration is based on '$(KBUILD_DEFCONFIG)'
-	$(Q)$< -D $(KBUILD_DEFCONFIG) Config.in
+	@$(kecho) "*** Default configuration is based on target '$(KBUILD_DEFCONFIG)'"
+	$(Q)$(MAKE) -f $(srctree)/Makefile $(KBUILD_DEFCONFIG)
 endif
-	$(MTIME_IS_COARSE) && sleep 1
 
 %_defconfig: $(obj)/conf
-	$(Q)$< -D configs/$@ Config.in
-	$(MTIME_IS_COARSE) && sleep 1
+	$(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)
+
+configfiles=$(wildcard $(srctree)/kernel/configs/$@ \
$(srctree)/arch/$(SRCARCH)/configs/$@) +
+%.config: $(obj)/conf
+	$(if $(call configfiles),, $(error No configuration exists for this target on this \
architecture)) +	$(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m \
.config $(configfiles) +	$(Q)$(MAKE) -f $(srctree)/Makefile olddefconfig
+
+PHONY += tinyconfig
+tinyconfig:
+	$(Q)$(MAKE) -f $(srctree)/Makefile allnoconfig tiny.config
+
+# CHECK: -o cache_dir=<path> working?
+PHONY += testconfig
+testconfig: $(obj)/conf
+	$(Q)$(PYTHON3) -B -m pytest $(srctree)/$(src)/tests \
+	-o cache_dir=$(abspath $(obj)/tests/.cache) \
+	$(if $(findstring 1,$(KBUILD_VERBOSE)),--capture=no)
+clean-files += tests/.cache
 
 # Help text used by make help
 help:
 	@echo  '  config	  - Update current config utilising a line-oriented program'
+	@echo  '  nconfig         - Update current config utilising a ncurses menu based \
program'  @echo  '  menuconfig	  - Update current config utilising a menu based \
                program'
-	@echo  '  xconfig	  - Update current config utilising a QT based front-end'
-	@echo  '  gconfig	  - Update current config utilising a GTK based front-end'
+	@echo  '  xconfig	  - Update current config utilising a Qt based front-end'
+	@echo  '  gconfig	  - Update current config utilising a GTK+ based front-end'
 	@echo  '  oldconfig	  - Update current config utilising a provided .config as base'
-	@echo  '  randconfig	  - New config with random answer to all options'
-	@echo  '  defconfig	  - New config with default answer to all options'
-	@echo  '  allmodconfig	  - New config selecting modules when possible'
-	@echo  '  allyesconfig	  - New config where all options are accepted with yes'
+	@echo  '  localmodconfig  - Update current config disabling modules not loaded'
+	@echo  '                    except those preserved by LMC_KEEP environment \
variable' +	@echo  '  localyesconfig  - Update current config converting local mods \
to core' +	@echo  '                    except those preserved by LMC_KEEP environment \
variable' +	@echo  '  defconfig	  - New config with default from ARCH supplied \
defconfig' +	@echo  '  savedefconfig   - Save current config as ./defconfig (minimal \
config)'  @echo  '  allnoconfig	  - New config where all options are answered with \
no' +	@echo  '  allyesconfig	  - New config where all options are accepted with yes'
+	@echo  '  allmodconfig	  - New config selecting modules when possible'
+	@echo  '  alldefconfig    - New config with all symbols set to default'
+	@echo  '  randconfig	  - New config with random answer to all options'
+	@echo  '  yes2modconfig	  - Change answers from yes to mod if possible'
+	@echo  '  mod2yesconfig	  - Change answers from mod to yes if possible'
+	@echo  '  listnewconfig   - List new options'
+	@echo  '  helpnewconfig   - List new options and help text'
+	@echo  '  olddefconfig	  - Same as oldconfig but sets new symbols to their'
+	@echo  '                    default value without prompting'
+	@echo  '  tinyconfig	  - Configure the tiniest possible kernel'
+	@echo  '  testconfig	  - Run Kconfig unit tests (requires python3 and pytest)'
 
 # ===========================================================================
-# Shared Makefile for the various kconfig executables:
-# conf:	  Used for defconfig, oldconfig and related targets
-# mconf:  Used for the mconfig target.
-#         Utilizes the lxdialog package
-# qconf:  Used for the xconfig target
-#         Based on QT which needs to be installed to compile it
-# gconf:  Used for the gconfig target
-#         Based on GTK which needs to be installed to compile it
 # object files used by all kconfig flavours
+common-objs	:= confdata.o expr.o lexer.lex.o parser.tab.o preprocess.o \
+		   symbol.o util.o
 
-hostprogs-y	:= conf mconf qconf gconf kxgettext
-conf-objs	:= conf.o  zconf.tab.o
-mconf-objs	:= mconf.o zconf.tab.o
-kxgettext-objs	:= kxgettext.o zconf.tab.o
+$(obj)/lexer.lex.o: $(obj)/parser.tab.h
+HOSTCFLAGS_lexer.lex.o	:= -I $(srctree)/$(src)
+HOSTCFLAGS_parser.tab.o	:= -I $(srctree)/$(src)
 
-ifeq ($(MAKECMDGOALS),xconfig)
-	qconf-target := 1
-endif
-ifeq ($(MAKECMDGOALS),gconfig)
-	gconf-target := 1
-endif
+# conf: Used for defconfig, oldconfig and related targets
+hostprogs	+= conf
+conf-objs	:= conf.o $(common-objs)
 
+# nconf: Used for the nconfig target based on ncurses
+hostprogs	+= nconf
+nconf-objs	:= nconf.o nconf.gui.o $(common-objs)
 
-ifeq ($(qconf-target),1)
-qconf-cxxobjs	:= qconf.o
-qconf-objs	:= kconfig_load.o zconf.tab.o
-endif
+HOSTLDLIBS_nconf	= $(shell . $(obj)/nconf-cfg && echo $$libs)
+HOSTCFLAGS_nconf.o	= $(shell . $(obj)/nconf-cfg && echo $$cflags)
+HOSTCFLAGS_nconf.gui.o	= $(shell . $(obj)/nconf-cfg && echo $$cflags)
 
-ifeq ($(gconf-target),1)
-gconf-objs	:= gconf.o kconfig_load.o zconf.tab.o
-endif
-
-clean-files	:= lkc_defs.h qconf.moc .tmp_qtcheck \
-		   .tmp_gtkcheck zconf.tab.c lex.zconf.c zconf.hash.c
-subdir- += lxdialog
-
-# Add environment specific flags
-HOST_EXTRACFLAGS += $(shell $(CONFIG_SHELL) $(srctree)/$(src)/check.sh $(HOSTCC) \
                $(HOSTCFLAGS))
-
-# generated files seem to need this to find local include files
-HOSTCFLAGS_lex.zconf.o	:= -I$(src)
-HOSTCFLAGS_zconf.tab.o	:= -I$(src)
-
-HOSTLOADLIBES_qconf	= $(KC_QT_LIBS) -ldl
-HOSTCXXFLAGS_qconf.o	= $(KC_QT_CFLAGS) -D LKC_DIRECT_LINK
-
-HOSTLOADLIBES_gconf	= `pkg-config --libs gtk+-2.0 gmodule-2.0 libglade-2.0` -ldl
-HOSTCFLAGS_gconf.o	= `pkg-config --cflags gtk+-2.0 gmodule-2.0 libglade-2.0` \
-                          -D LKC_DIRECT_LINK
-
-$(obj)/qconf.o: $(obj)/.tmp_qtcheck
-
-ifeq ($(qconf-target),1)
-$(obj)/.tmp_qtcheck: $(src)/Makefile
--include $(obj)/.tmp_qtcheck
-
-# QT needs some extra effort...
-$(obj)/.tmp_qtcheck:
-	@set -e; echo "  CHECK   qt"; dir=""; pkg=""; \
-	pkg-config --exists qt 2> /dev/null && pkg=qt; \
-	pkg-config --exists qt-mt 2> /dev/null && pkg=qt-mt; \
-	if [ -n "$$pkg" ]; then \
-	  cflags="\$$(shell pkg-config $$pkg --cflags)"; \
-	  libs="\$$(shell pkg-config $$pkg --libs)"; \
-	  moc="\$$(shell pkg-config $$pkg --variable=prefix)/bin/moc"; \
-	  dir="$$(pkg-config $$pkg --variable=prefix)"; \
-	else \
-	  for d in $$QTDIR /usr/share/qt* /usr/lib/qt*; do \
-	    if [ -f $$d/include/qconfig.h ]; then dir=$$d; break; fi; \
-	  done; \
-	  if [ -z "$$dir" ]; then \
-	    echo "*"; \
-	    echo "* Unable to find the QT installation. Please make sure that"; \
-	    echo "* the QT development package is correctly installed and"; \
-	    echo "* either install pkg-config or set the QTDIR environment"; \
-	    echo "* variable to the correct location."; \
-	    echo "*"; \
-	    false; \
-	  fi; \
-	  libpath=$$dir/lib; lib=qt; osdir=""; \
-	  $(HOSTCXX) -print-multi-os-directory > /dev/null 2>&1 && \
-	    osdir=x$$($(HOSTCXX) -print-multi-os-directory); \
-	  test -d $$libpath/$$osdir && libpath=$$libpath/$$osdir; \
-	  test -f $$libpath/libqt-mt.so && lib=qt-mt; \
-	  cflags="-I$$dir/include"; \
-	  libs="-L$$libpath -Wl,-rpath,$$libpath -l$$lib"; \
-	  moc="$$dir/bin/moc"; \
-	fi; \
-	if [ ! -x $$dir/bin/moc -a -x /usr/bin/moc ]; then \
-	  echo "*"; \
-	  echo "* Unable to find $$dir/bin/moc, using /usr/bin/moc instead."; \
-	  echo "*"; \
-	  moc="/usr/bin/moc"; \
-	fi; \
-	echo "KC_QT_CFLAGS=$$cflags" > $@; \
-	echo "KC_QT_LIBS=$$libs" >> $@; \
-	echo "KC_QT_MOC=$$moc" >> $@
-endif
+$(obj)/nconf.o $(obj)/nconf.gui.o: $(obj)/nconf-cfg
 
-$(obj)/gconf.o: $(obj)/.tmp_gtkcheck
-
-ifeq ($(gconf-target),1)
--include $(obj)/.tmp_gtkcheck
-
-# GTK needs some extra effort, too...
-$(obj)/.tmp_gtkcheck:
-	@if `pkg-config --exists gtk+-2.0 gmodule-2.0 libglade-2.0`; then		\
-		if `pkg-config --atleast-version=2.0.0 gtk+-2.0`; then			\
-			touch $@;								\
-		else									\
-			echo "*"; 							\
-			echo "* GTK+ is present but version >= 2.0.0 is required.";	\
-			echo "*";							\
-			false;								\
-		fi									\
-	else										\
-		echo "*"; 								\
-		echo "* Unable to find the GTK+ installation. Please make sure that"; 	\
-		echo "* the GTK+ 2.0 development package is correctly installed..."; 	\
-		echo "* You need gtk+-2.0, glib-2.0 and libglade-2.0."; 		\
-		echo "*"; 								\
-		false;									\
-	fi
-endif
+# mconf: Used for the menuconfig target based on lxdialog
+hostprogs	+= mconf
+lxdialog	:= $(addprefix lxdialog/, \
+		     checklist.o inputbox.o menubox.o textbox.o util.o yesno.o)
+mconf-objs	:= mconf.o $(lxdialog) $(common-objs)
 
-$(obj)/zconf.tab.o: $(obj)/lex.zconf.c $(obj)/zconf.hash.c
+HOSTLDLIBS_mconf = $(shell . $(obj)/mconf-cfg && echo $$libs)
+$(foreach f, mconf.o $(lxdialog), \
+  $(eval HOSTCFLAGS_$f = $$(shell . $(obj)/mconf-cfg && echo $$$$cflags)))
 
-$(obj)/kconfig_load.o: $(obj)/lkc_defs.h
+$(addprefix $(obj)/, mconf.o $(lxdialog)): $(obj)/mconf-cfg
 
-$(obj)/qconf.o: $(obj)/qconf.moc $(obj)/lkc_defs.h
+# qconf: Used for the xconfig target based on Qt
+hostprogs	+= qconf
+qconf-cxxobjs	:= qconf.o qconf-moc.o
+qconf-objs	:= images.o $(common-objs)
 
-$(obj)/gconf.o: $(obj)/lkc_defs.h
+HOSTLDLIBS_qconf	= $(shell . $(obj)/qconf-cfg && echo $$libs)
+HOSTCXXFLAGS_qconf.o	= $(shell . $(obj)/qconf-cfg && echo $$cflags)
+HOSTCXXFLAGS_qconf-moc.o = $(shell . $(obj)/qconf-cfg && echo $$cflags)
 
-$(obj)/%.moc: $(src)/%.h
-	$(KC_QT_MOC) -i $< -o $@
+$(obj)/qconf.o: $(obj)/qconf-cfg
 
-$(obj)/lkc_defs.h: $(src)/lkc_proto.h
-	sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/'
+quiet_cmd_moc = MOC     $@
+      cmd_moc = $(shell . $(obj)/qconf-cfg && echo $$moc) $< -o $@
 
+$(obj)/qconf-moc.cc: $(src)/qconf.h $(obj)/qconf-cfg FORCE
+	$(call if_changed,moc)
 
-###
-# The following requires flex/bison/gperf
-# By default we use the _shipped versions, uncomment the following line if
-# you are modifying the flex/bison src.
-# LKC_GENPARSER := 1
+targets += qconf-moc.cc
 
-ifdef LKC_GENPARSER
+# gconf: Used for the gconfig target based on GTK+
+hostprogs	+= gconf
+gconf-objs	:= gconf.o images.o $(common-objs)
 
-$(obj)/zconf.tab.c: $(src)/zconf.y
-$(obj)/lex.zconf.c: $(src)/zconf.l
-$(obj)/zconf.hash.c: $(src)/zconf.gperf
+HOSTLDLIBS_gconf    = $(shell . $(obj)/gconf-cfg && echo $$libs)
+HOSTCFLAGS_gconf.o  = $(shell . $(obj)/gconf-cfg && echo $$cflags)
 
-%.tab.c: %.y
-	bison -l -b $* -p $(notdir $*) $<
-	cp $@ $@_shipped
+$(obj)/gconf.o: $(obj)/gconf-cfg
 
-lex.%.c: %.l
-	flex -L -P$(notdir $*) -o$@ $<
-	cp $@ $@_shipped
+# check if necessary packages are available, and configure build flags
+filechk_conf_cfg = $(CONFIG_SHELL) $<
 
-%.hash.c: %.gperf
-	gperf < $< > $@
-	cp $@ $@_shipped
+$(obj)/%conf-cfg: $(src)/%conf-cfg.sh FORCE
+	$(call filechk,conf_cfg)
 
-endif
+clean-files += *conf-cfg
diff --git a/scripts/kconfig/POTFILES.in b/scripts/kconfig/POTFILES.in
deleted file mode 100644
index cc94e46a7..000000000
--- a/scripts/kconfig/POTFILES.in
+++ /dev/null
@@ -1,5 +0,0 @@
-scripts/kconfig/mconf.c
-scripts/kconfig/conf.c
-scripts/kconfig/confdata.c
-scripts/kconfig/gconf.c
-scripts/kconfig/qconf.cc
diff --git a/scripts/kconfig/check.sh b/scripts/kconfig/check.sh
deleted file mode 100755
index 15fc29421..000000000
--- a/scripts/kconfig/check.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/sh
-# Needed for systems without gettext
-$* -xc -o /dev/null - > /dev/null 2>&1 << EOF
-#include <libintl.h>
-int main()
-{
-	gettext("");
-	return 0;
-}
-EOF
-if [ ! "$?" -eq "0"  ]; then
-	echo -DKBUILD_NO_NLS;
-fi
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index 39ec1cdb6..957d2a083 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -1,50 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
- * Released under the terms of the GNU GPL v2.0.
  */
 
-#define _XOPEN_SOURCE 700
-
 #include <ctype.h>
-#include <stdlib.h>
+#include <limits.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
-#include <unistd.h>
 #include <time.h>
-#include <sys/stat.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <sys/time.h>
+#include <errno.h>
 
-#define LKC_DIRECT_LINK
 #include "lkc.h"
 
 static void conf(struct menu *menu);
 static void check_conf(struct menu *menu);
 
-enum {
-	ask_all,
-	ask_new,
-	ask_silent,
-	set_default,
-	set_yes,
-	set_mod,
-	set_no,
-	set_random
-} input_mode = ask_all;
-char *defconfig_file;
+enum input_mode {
+	oldaskconfig,
+	syncconfig,
+	oldconfig,
+	allnoconfig,
+	allyesconfig,
+	allmodconfig,
+	alldefconfig,
+	randconfig,
+	defconfig,
+	savedefconfig,
+	listnewconfig,
+	helpnewconfig,
+	olddefconfig,
+	yes2modconfig,
+	mod2yesconfig,
+};
+static enum input_mode input_mode = oldaskconfig;
 
 static int indent = 1;
-static int valid_stdin = 1;
+static int tty_stdio;
+static int sync_kconfig;
 static int conf_cnt;
-static char line[128];
+static char line[PATH_MAX];
 static struct menu *rootEntry;
 
-static char nohelp_text[] = N_("Sorry, no help available for this option yet.\n");
+static void print_help(struct menu *menu)
+{
+	struct gstr help = str_new();
+
+	menu_get_ext_help(menu, &help);
+
+	printf("\n%s\n", str_get(&help));
+	str_free(&help);
+}
 
 static void strip(char *str)
 {
 	char *p = str;
 	int l;
 
-	while ((isspace((unsigned char)*p)))
+	while ((isspace(*p)))
 		p++;
 	l = strlen(p);
 	if (p != str)
@@ -52,165 +68,53 @@ static void strip(char *str)
 	if (!l)
 		return;
 	p = str + l - 1;
-	while ((isspace((unsigned char)*p)))
+	while ((isspace(*p)))
 		*p-- = 0;
 }
 
-static void check_stdin(void)
+/* Helper function to facilitate fgets() by Jean Sacren. */
+static void xfgets(char *str, int size, FILE *in)
 {
-	if (!valid_stdin && input_mode == ask_silent) {
-		printf(_("aborted!\n\n"));
-		printf(_("Console input/output is redirected. "));
-		printf(_("Run 'make oldconfig' to update configuration.\n\n"));
-		exit(1);
-	}
+	if (!fgets(str, size, in))
+		fprintf(stderr, "\nError in reading or end of file.\n");
+
+	if (!tty_stdio)
+		printf("%s", str);
 }
 
-static void conf_askvalue(struct symbol *sym, const char *def)
+static int conf_askvalue(struct symbol *sym, const char *def)
 {
-	enum symbol_type type = sym_get_type(sym);
-	tristate val;
-
 	if (!sym_has_value(sym))
 		printf("(NEW) ");
 
 	line[0] = '\n';
 	line[1] = 0;
-	line[2] = 0;
 
-	if (!sym_is_changable(sym)) {
+	if (!sym_is_changeable(sym)) {
 		printf("%s\n", def);
-		return;
-	}
-
-	// If autoconf run (allnoconfig and such), reset bool and tristates:
-	// "select ITEM" sets ITEM=y and then parent item might have been
-	// reset to "n" later. Try to set ITEM to "n" on the second run.
-	if (type == S_BOOLEAN || type == S_TRISTATE) {
-		switch (input_mode) {
-		case set_yes:
-			if (sym_tristate_within_range(sym, yes)) {
-				line[0] = 'y';
-				line[1] = '\n';
-				printf("%s", line);
-				return;
-			}
-		case set_mod:
-			if (type == S_TRISTATE) {
-				if (sym_tristate_within_range(sym, mod)) {
-					line[0] = 'm';
-					line[1] = '\n';
-					printf("%s", line);
-					return;
-				}
-			} else {
-				if (sym_tristate_within_range(sym, yes)) {
-					line[0] = 'y';
-					line[1] = '\n';
-					printf("%s", line);
-					return;
-				}
-			}
-		case set_no:
-			if (sym_tristate_within_range(sym, no)) {
-				line[0] = 'n';
-				line[1] = '\n';
-				printf("%s", line);
-				return;
-			}
-		default: // placate compiler
-			break;
-		}
+		line[0] = '\n';
+		line[1] = 0;
+		return 0;
 	}
 
 	switch (input_mode) {
-	case set_no:
-	case set_mod:
-	case set_yes:
-	case set_random:
+	case oldconfig:
+	case syncconfig:
 		if (sym_has_value(sym)) {
 			printf("%s\n", def);
-			return;
-		}
-		break;
-	case ask_new:
-	case ask_silent:
-		if (sym_has_value(sym)) {
-			printf("%s\n", def);
-			return;
+			return 0;
 		}
-		check_stdin();
-	case ask_all:
-		fflush(stdout);
-		if (!fgets(line, 128, stdin))
-			exit(1);
-		return;
-	case set_default:
-		printf("%s\n", def);
-		return;
+		/* fall through */
 	default:
+		fflush(stdout);
+		xfgets(line, sizeof(line), stdin);
 		break;
 	}
 
-	switch (type) {
-	case S_INT:
-	case S_HEX:
-	case S_STRING:
-		printf("%s\n", def);
-		return;
-	default:
-		;
-	}
-	switch (input_mode) {
-	case set_yes:
-		if (sym_tristate_within_range(sym, yes)) {
-			line[0] = 'y';
-			line[1] = '\n';
-			line[2] = 0;
-			break;
-		}
-	case set_mod:
-		if (type == S_TRISTATE) {
-			if (sym_tristate_within_range(sym, mod)) {
-				line[0] = 'm';
-				line[1] = '\n';
-				line[2] = 0;
-				break;
-			}
-		} else {
-			if (sym_tristate_within_range(sym, yes)) {
-				line[0] = 'y';
-				line[1] = '\n';
-				line[2] = 0;
-				break;
-			}
-		}
-	case set_no:
-		if (sym_tristate_within_range(sym, no)) {
-			line[0] = 'n';
-			line[1] = '\n';
-			line[2] = 0;
-			break;
-		}
-	case set_random:
-		do {
-			val = (tristate)(random() % 3);
-		} while (!sym_tristate_within_range(sym, val));
-		switch (val) {
-		case no: line[0] = 'n'; break;
-		case mod: line[0] = 'm'; break;
-		case yes: line[0] = 'y'; break;
-		}
-		line[1] = '\n';
-		line[2] = 0;
-		break;
-	default:
-		break;
-	}
-	printf("%s", line);
+	return 1;
 }
 
-int conf_string(struct menu *menu)
+static int conf_string(struct menu *menu)
 {
 	struct symbol *sym = menu->sym;
 	const char *def;
@@ -219,19 +123,21 @@ int conf_string(struct menu *menu)
 		printf("%*s%s ", indent - 1, "", menu->prompt->text);
 		printf("(%s) ", sym->name);
 		def = sym_get_string_value(sym);
-		if (sym_get_string_value(sym))
+		if (def)
 			printf("[%s] ", def);
-		conf_askvalue(sym, def);
+		if (!conf_askvalue(sym, def))
+			return 0;
 		switch (line[0]) {
 		case '\n':
 			break;
 		case '?':
 			/* print help */
 			if (line[1] == '\n') {
-				printf("\n%s\n", menu->sym->help ? menu->sym->help : nohelp_text);
+				print_help(menu);
 				def = NULL;
 				break;
 			}
+			/* fall through */
 		default:
 			line[strlen(line)-1] = 0;
 			def = line;
@@ -245,7 +151,6 @@ static int conf_sym(struct menu *menu)
 {
 	struct symbol *sym = menu->sym;
 	tristate oldval, newval;
-	const char *help;
 
 	while (1) {
 		printf("%*s%s ", indent - 1, "", menu->prompt->text);
@@ -270,10 +175,9 @@ static int conf_sym(struct menu *menu)
 			printf("/m");
 		if (oldval != yes && sym_tristate_within_range(sym, yes))
 			printf("/y");
-		if (sym->help)
-			printf("/?");
-		printf("] ");
-		conf_askvalue(sym, sym_get_string_value(sym));
+		printf("/?] ");
+		if (!conf_askvalue(sym, sym_get_string_value(sym)))
+			return 0;
 		strip(line);
 
 		switch (line[0]) {
@@ -306,10 +210,7 @@ static int conf_sym(struct menu *menu)
 		if (sym_set_tristate_value(sym, newval))
 			return 0;
 help:
-		help = nohelp_text;
-		if (sym->help)
-			help = sym->help;
-		printf("\n%s\n", help);
+		print_help(menu);
 	}
 }
 
@@ -321,7 +222,7 @@ static int conf_choice(struct menu *menu)
 
 	sym = menu->sym;
 	is_new = !sym_has_value(sym);
-	if (sym_is_changable(sym)) {
+	if (sym_is_changeable(sym)) {
 		conf_sym(menu);
 		sym_calc_value(sym);
 		switch (sym_get_tristate_value(sym)) {
@@ -376,44 +277,32 @@ static int conf_choice(struct menu *menu)
 			printf("[1]: 1\n");
 			goto conf_childs;
 		}
-		printf("[1-%d", cnt);
-		if (sym->help)
-			printf("?");
-		printf("]: ");
+		printf("[1-%d?]: ", cnt);
 		switch (input_mode) {
-		case ask_new:
-		case ask_silent:
+		case oldconfig:
+		case syncconfig:
 			if (!is_new) {
 				cnt = def;
 				printf("%d\n", cnt);
 				break;
 			}
-			check_stdin();
-		case ask_all:
+			/* fall through */
+		case oldaskconfig:
 			fflush(stdout);
-			if (!fgets(line, 128, stdin))
-				exit(1);
+			xfgets(line, sizeof(line), stdin);
 			strip(line);
 			if (line[0] == '?') {
-				printf("\n%s\n", menu->sym->help ?
-					menu->sym->help : nohelp_text);
+				print_help(menu);
 				continue;
 			}
 			if (!line[0])
 				cnt = def;
-			else if (isdigit((unsigned char)line[0]))
+			else if (isdigit(line[0]))
 				cnt = atoi(line);
 			else
 				continue;
 			break;
-		case set_random:
-			def = (random() % cnt) + 1;
-		case set_default:
-		case set_yes:
-		case set_mod:
-		case set_no:
-			cnt = def;
-			printf("%d\n", cnt);
+		default:
 			break;
 		}
 
@@ -426,15 +315,14 @@ static int conf_choice(struct menu *menu)
 		}
 		if (!child)
 			continue;
-		if (strlen(line) > 0 && line[strlen(line) - 1] == '?') {
-			printf("\n%s\n", child->sym->help ?
-				child->sym->help : nohelp_text);
+		if (line[0] && line[strlen(line) - 1] == '?') {
+			print_help(child);
 			continue;
 		}
 		sym_set_choice_value(sym, child->sym);
-		if (child->list) {
+		for (child = child->list; child; child = child->next) {
 			indent += 2;
-			conf(child->list);
+			conf(child);
 			indent -= 2;
 		}
 		return 1;
@@ -457,10 +345,15 @@ static void conf(struct menu *menu)
 
 		switch (prop->type) {
 		case P_MENU:
-			if (input_mode == ask_silent && rootEntry != menu) {
+			/*
+			 * Except in oldaskconfig mode, we show only menus that
+			 * contain new symbols.
+			 */
+			if (input_mode != oldaskconfig && rootEntry != menu) {
 				check_conf(menu);
 				return;
 			}
+			/* fall through */
 		case P_COMMENT:
 			prompt = menu_get_prompt(menu);
 			if (prompt)
@@ -512,13 +405,37 @@ static void check_conf(struct menu *menu)
 		return;
 
 	sym = menu->sym;
-	if (sym && !sym_has_value(sym)) {
-		if (sym_is_changable(sym) ||
-		    (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) {
+	if (sym && !sym_has_value(sym) &&
+	    (sym_is_changeable(sym) ||
+	     (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes))) {
+
+		switch (input_mode) {
+		case listnewconfig:
+			if (sym->name) {
+				const char *str;
+
+				if (sym->type == S_STRING) {
+					str = sym_get_string_value(sym);
+					str = sym_escape_string_value(str);
+					printf("%s%s=%s\n", CONFIG_, sym->name, str);
+					free((void *)str);
+				} else {
+					str = sym_get_string_value(sym);
+					printf("%s%s=%s\n", CONFIG_, sym->name, str);
+				}
+			}
+			break;
+		case helpnewconfig:
+			printf("-----\n");
+			print_help(menu);
+			printf("-----\n");
+			break;
+		default:
 			if (!conf_cnt++)
-				printf(_("*\n* Restart config...\n*\n"));
+				printf("*\n* Restart config...\n*\n");
 			rootEntry = menu_get_parent_menu(menu);
 			conf(rootEntry);
+			break;
 		}
 	}
 
@@ -526,136 +443,274 @@ static void check_conf(struct menu *menu)
 		check_conf(child);
 }
 
+static struct option long_opts[] = {
+	{"oldaskconfig",    no_argument,       NULL, oldaskconfig},
+	{"oldconfig",       no_argument,       NULL, oldconfig},
+	{"syncconfig",      no_argument,       NULL, syncconfig},
+	{"defconfig",       required_argument, NULL, defconfig},
+	{"savedefconfig",   required_argument, NULL, savedefconfig},
+	{"allnoconfig",     no_argument,       NULL, allnoconfig},
+	{"allyesconfig",    no_argument,       NULL, allyesconfig},
+	{"allmodconfig",    no_argument,       NULL, allmodconfig},
+	{"alldefconfig",    no_argument,       NULL, alldefconfig},
+	{"randconfig",      no_argument,       NULL, randconfig},
+	{"listnewconfig",   no_argument,       NULL, listnewconfig},
+	{"helpnewconfig",   no_argument,       NULL, helpnewconfig},
+	{"olddefconfig",    no_argument,       NULL, olddefconfig},
+	{"yes2modconfig",   no_argument,       NULL, yes2modconfig},
+	{"mod2yesconfig",   no_argument,       NULL, mod2yesconfig},
+	{NULL, 0, NULL, 0}
+};
+
+static void conf_usage(const char *progname)
+{
+
+	printf("Usage: %s [-s] [option] <kconfig-file>\n", progname);
+	printf("[option] is _one_ of the following:\n");
+	printf("  --listnewconfig         List new options\n");
+	printf("  --helpnewconfig         List new options and help text\n");
+	printf("  --oldaskconfig          Start a new configuration using a line-oriented \
program\n"); +	printf("  --oldconfig             Update a configuration using a \
provided .config as base\n"); +	printf("  --syncconfig            Similar to \
oldconfig but generates configuration in\n" +	       "                          \
include/{generated/,config/}\n"); +	printf("  --olddefconfig          Same as \
oldconfig but sets new symbols to their default value\n"); +	printf("  --defconfig \
<file>      New config with default defined in <file>\n"); +	printf("  \
--savedefconfig <file>  Save the minimal current configuration to <file>\n"); \
+	printf("  --allnoconfig           New config where all options are answered with \
no\n"); +	printf("  --allyesconfig          New config where all options are answered \
with yes\n"); +	printf("  --allmodconfig          New config where all options are \
answered with mod\n"); +	printf("  --alldefconfig          New config with all \
symbols set to default\n"); +	printf("  --randconfig            New config with \
random answer to all options\n"); +	printf("  --yes2modconfig         Change answers \
from yes to mod if possible\n"); +	printf("  --mod2yesconfig         Change answers \
from mod to yes if possible\n"); +	printf("  (If none of the above is given, \
--oldaskconfig is the default)\n"); +}
+
 int main(int ac, char **av)
 {
-	int i = 1;
-	const char *name;
-	struct stat tmpstat;
-
-	if (ac > i && av[i][0] == '-') {
-		switch (av[i++][1]) {
-		case 'o':
-			input_mode = ask_new;
-			break;
-		case 's':
-			input_mode = ask_silent;
-			valid_stdin = isatty(0); //bbox: && isatty(1) && isatty(2);
+	const char *progname = av[0];
+	int opt;
+	const char *name, *defconfig_file = NULL /* gcc uninit */;
+	int no_conf_write = 0;
+
+	tty_stdio = isatty(0) && isatty(1);
+
+	while ((opt = getopt_long(ac, av, "hs", long_opts, NULL)) != -1) {
+		if (opt == 's') {
+			conf_set_message_callback(NULL);
+			continue;
+		}
+		input_mode = (enum input_mode)opt;
+		switch (opt) {
+		case syncconfig:
+			/*
+			 * syncconfig is invoked during the build stage.
+			 * Suppress distracting "configuration written to ..."
+			 */
+			conf_set_message_callback(NULL);
+			sync_kconfig = 1;
 			break;
-		case 'd':
-			input_mode = set_default;
+		case defconfig:
+		case savedefconfig:
+			defconfig_file = optarg;
 			break;
-		case 'D':
-			input_mode = set_default;
-			defconfig_file = av[i++];
-			if (!defconfig_file) {
-				printf(_("%s: No default config file specified\n"),
-					av[0]);
-				exit(1);
+		case randconfig:
+		{
+			struct timeval now;
+			unsigned int seed;
+			char *seed_env;
+
+			/*
+			 * Use microseconds derived seed,
+			 * compensate for systems where it may be zero
+			 */
+			gettimeofday(&now, NULL);
+			seed = (unsigned int)((now.tv_sec + 1) * (now.tv_usec + 1));
+
+			seed_env = getenv("KCONFIG_SEED");
+			if( seed_env && *seed_env ) {
+				char *endp;
+				int tmp = (int)strtol(seed_env, &endp, 0);
+				if (*endp == '\0') {
+					seed = tmp;
+				}
 			}
+			fprintf( stderr, "KCONFIG_SEED=0x%X\n", seed );
+			srand(seed);
 			break;
-		case 'n':
-			input_mode = set_no;
-			break;
-		case 'm':
-			input_mode = set_mod;
-			break;
-		case 'y':
-			input_mode = set_yes;
-			break;
-		case 'r':
-			input_mode = set_random;
-			srandom(time(NULL));
+		}
+		case oldaskconfig:
+		case oldconfig:
+		case allnoconfig:
+		case allyesconfig:
+		case allmodconfig:
+		case alldefconfig:
+		case listnewconfig:
+		case helpnewconfig:
+		case olddefconfig:
+		case yes2modconfig:
+		case mod2yesconfig:
 			break;
 		case 'h':
-		case '?':
-			fprintf(stderr, "See README for usage info\n");
-			exit(0);
+			conf_usage(progname);
+			exit(1);
+			break;
 		}
 	}
-	name = av[i];
-	if (!name) {
-		printf(_("%s: Kconfig file missing\n"), av[0]);
+	if (ac == optind) {
+		fprintf(stderr, "%s: Kconfig file missing\n", av[0]);
+		conf_usage(progname);
+		exit(1);
 	}
+	name = av[optind];
 	conf_parse(name);
 	//zconfdump(stdout);
+
 	switch (input_mode) {
-	case set_default:
-		if (!defconfig_file)
-			defconfig_file = conf_get_default_confname();
+	case defconfig:
 		if (conf_read(defconfig_file)) {
-			printf("***\n"
-				"*** Can't find default configuration \"%s\"!\n"
-				"***\n", defconfig_file);
-			exit(1);
-		}
-		break;
-	case ask_silent:
-		if (stat(".config", &tmpstat)) {
-			printf(_("***\n"
-				"*** You have not yet configured busybox!\n"
+			fprintf(stderr,
 				"***\n"
-				"*** Please run some configurator (e.g. \"make oldconfig\" or\n"
-				"*** \"make menuconfig\" or \"make defconfig\").\n"
-				"***\n"));
+				  "*** Can't find default configuration \"%s\"!\n"
+				  "***\n",
+				defconfig_file);
 			exit(1);
 		}
-	case ask_all:
-	case ask_new:
+		break;
+	case savedefconfig:
+	case syncconfig:
+	case oldaskconfig:
+	case oldconfig:
+	case listnewconfig:
+	case helpnewconfig:
+	case olddefconfig:
+	case yes2modconfig:
+	case mod2yesconfig:
 		conf_read(NULL);
 		break;
-	case set_no:
-	case set_mod:
-	case set_yes:
-	case set_random:
+	case allnoconfig:
+	case allyesconfig:
+	case allmodconfig:
+	case alldefconfig:
+	case randconfig:
 		name = getenv("KCONFIG_ALLCONFIG");
-		if (name && !stat(name, &tmpstat)) {
-			conf_read_simple(name);
+		if (!name)
+			break;
+		if ((strcmp(name, "") != 0) && (strcmp(name, "1") != 0)) {
+			if (conf_read_simple(name, S_DEF_USER)) {
+				fprintf(stderr,
+					"*** Can't read seed configuration \"%s\"!\n",
+					name);
+				exit(1);
+			}
 			break;
 		}
 		switch (input_mode) {
-		case set_no:	 name = "allno.config"; break;
-		case set_mod:	 name = "allmod.config"; break;
-		case set_yes:	 name = "allyes.config"; break;
-		case set_random: name = "allrandom.config"; break;
+		case allnoconfig:	name = "allno.config"; break;
+		case allyesconfig:	name = "allyes.config"; break;
+		case allmodconfig:	name = "allmod.config"; break;
+		case alldefconfig:	name = "alldef.config"; break;
+		case randconfig:	name = "allrandom.config"; break;
 		default: break;
 		}
-		if (!stat(name, &tmpstat))
-			conf_read_simple(name);
-		else if (!stat("all.config", &tmpstat))
-			conf_read_simple("all.config");
+		if (conf_read_simple(name, S_DEF_USER) &&
+		    conf_read_simple("all.config", S_DEF_USER)) {
+			fprintf(stderr,
+				"*** KCONFIG_ALLCONFIG set, but no \"%s\" or \"all.config\" file found\n",
+				name);
+			exit(1);
+		}
 		break;
 	default:
 		break;
 	}
 
-	if (input_mode != ask_silent) {
+	if (sync_kconfig) {
+		name = getenv("KCONFIG_NOSILENTUPDATE");
+		if (name && *name) {
+			if (conf_get_changed()) {
+				fprintf(stderr,
+					"\n*** The configuration requires explicit update.\n\n");
+				return 1;
+			}
+			no_conf_write = 1;
+		}
+	}
+
+	switch (input_mode) {
+	case allnoconfig:
+		conf_set_all_new_symbols(def_no);
+		break;
+	case allyesconfig:
+		conf_set_all_new_symbols(def_yes);
+		break;
+	case allmodconfig:
+		conf_set_all_new_symbols(def_mod);
+		break;
+	case alldefconfig:
+		conf_set_all_new_symbols(def_default);
+		break;
+	case randconfig:
+		/* Really nothing to do in this loop */
+		while (conf_set_all_new_symbols(def_random)) ;
+		break;
+	case defconfig:
+		conf_set_all_new_symbols(def_default);
+		break;
+	case savedefconfig:
+		break;
+	case yes2modconfig:
+		conf_rewrite_mod_or_yes(def_y2m);
+		break;
+	case mod2yesconfig:
+		conf_rewrite_mod_or_yes(def_m2y);
+		break;
+	case oldaskconfig:
 		rootEntry = &rootmenu;
 		conf(&rootmenu);
-		// If autoconf run (allnoconfig and such), run it twice:
-		// "select ITEM" sets ITEM=y and then parent item
-		// is reset to "n" later. Second run sets ITEM to "n".
-		// Example: ADDUSER selects LONG_OPTS.
-		// allnoconfig must set _both_ to "n".
-		// Before, LONG_OPTS remained "y".
-		if (input_mode == set_no
-		 || input_mode == set_mod
-		 || input_mode == set_yes
-		) {
-			rootEntry = &rootmenu;
-			conf(&rootmenu);
+		input_mode = oldconfig;
+		/* fall through */
+	case oldconfig:
+	case listnewconfig:
+	case helpnewconfig:
+	case syncconfig:
+		/* Update until a loop caused no more changes */
+		do {
+			conf_cnt = 0;
+			check_conf(&rootmenu);
+		} while (conf_cnt);
+		break;
+	case olddefconfig:
+	default:
+		break;
+	}
+
+	if (input_mode == savedefconfig) {
+		if (conf_write_defconfig(defconfig_file)) {
+			fprintf(stderr, "n*** Error while saving defconfig to: %s\n\n",
+				defconfig_file);
+			return 1;
 		}
-		if (input_mode == ask_all) {
-			input_mode = ask_silent;
-			valid_stdin = 1;
+	} else if (input_mode != listnewconfig && input_mode != helpnewconfig) {
+		if (!no_conf_write && conf_write(NULL)) {
+			fprintf(stderr, "\n*** Error during writing of the configuration.\n\n");
+			exit(1);
+		}
+
+		/*
+		 * Create auto.conf if it does not exist.
+		 * This prevents GNU Make 4.1 or older from emitting
+		 * "include/config/auto.conf: No such file or directory"
+		 * in the top-level Makefile
+		 *
+		 * syncconfig always creates or updates auto.conf because it is
+		 * used during the build.
+		 */
+		if (conf_write_autoconf(sync_kconfig) && sync_kconfig) {
+			fprintf(stderr,
+				"\n*** Error during sync of the configuration.\n\n");
+			return 1;
 		}
-	}
-	do {
-		conf_cnt = 0;
-		check_conf(&rootmenu);
-	} while (conf_cnt);
-	if (conf_write(NULL)) {
-		fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n"));
-		return 1;
 	}
 	return 0;
 }
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index 1abfebcb5..2568dbe16 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -1,35 +1,183 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
- * Released under the terms of the GNU GPL v2.0.
  */
 
+#include <sys/mman.h>
 #include <sys/stat.h>
+#include <sys/types.h>
 #include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
 #include <unistd.h>
 
-#define LKC_DIRECT_LINK
 #include "lkc.h"
 
-static void conf_warning(const char *fmt, ...)
-	__attribute__ ((format (printf, 1, 2)));
+/* return true if 'path' exists, false otherwise */
+static bool is_present(const char *path)
+{
+	struct stat st;
 
-static const char *conf_filename;
-static int conf_lineno, conf_warnings, conf_unsaved;
+	return !stat(path, &st);
+}
+
+/* return true if 'path' exists and it is a directory, false otherwise */
+static bool is_dir(const char *path)
+{
+	struct stat st;
+
+	if (stat(path, &st))
+		return 0;
+
+	return S_ISDIR(st.st_mode);
+}
+
+/* return true if the given two files are the same, false otherwise */
+static bool is_same(const char *file1, const char *file2)
+{
+	int fd1, fd2;
+	struct stat st1, st2;
+	void *map1, *map2;
+	bool ret = false;
+
+	fd1 = open(file1, O_RDONLY);
+	if (fd1 < 0)
+		return ret;
+
+	fd2 = open(file2, O_RDONLY);
+	if (fd2 < 0)
+		goto close1;
+
+	ret = fstat(fd1, &st1);
+	if (ret)
+		goto close2;
+	ret = fstat(fd2, &st2);
+	if (ret)
+		goto close2;
 
-const char conf_def_filename[] = ".config";
+	if (st1.st_size != st2.st_size)
+		goto close2;
 
-const char conf_defname[] = "/dev/null"; //bbox
+	map1 = mmap(NULL, st1.st_size, PROT_READ, MAP_PRIVATE, fd1, 0);
+	if (map1 == MAP_FAILED)
+		goto close2;
 
-const char *conf_confnames[] = {
-	conf_def_filename,
-	conf_defname,
-	NULL,
+	map2 = mmap(NULL, st2.st_size, PROT_READ, MAP_PRIVATE, fd2, 0);
+	if (map2 == MAP_FAILED)
+		goto close2;
+
+	if (bcmp(map1, map2, st1.st_size))
+		goto close2;
+
+	ret = true;
+close2:
+	close(fd2);
+close1:
+	close(fd1);
+
+	return ret;
+}
+
+/*
+ * Create the parent directory of the given path.
+ *
+ * For example, if 'include/config/auto.conf' is given, create 'include/config'.
+ */
+static int make_parent_dir(const char *path)
+{
+	char tmp[PATH_MAX + 1];
+	char *p;
+
+	strncpy(tmp, path, sizeof(tmp));
+	tmp[sizeof(tmp) - 1] = 0;
+
+	/* Remove the base name. Just return if nothing is left */
+	p = strrchr(tmp, '/');
+	if (!p)
+		return 0;
+	*(p + 1) = 0;
+
+	/* Just in case it is an absolute path */
+	p = tmp;
+	while (*p == '/')
+		p++;
+
+	while ((p = strchr(p, '/'))) {
+		*p = 0;
+
+		/* skip if the directory exists */
+		if (!is_dir(tmp) && mkdir(tmp, 0755))
+			return -1;
+
+		*p = '/';
+		while (*p == '/')
+			p++;
+	}
+
+	return 0;
+}
+
+static char depfile_path[PATH_MAX];
+static size_t depfile_prefix_len;
+
+/* touch depfile for symbol 'name' */
+static int conf_touch_dep(const char *name)
+{
+	int fd, ret;
+	const char *s;
+	char *d, c;
+
+	/* check overflow: prefix + name + ".h" + '\0' must fit in buffer. */
+	if (depfile_prefix_len + strlen(name) + 3 > sizeof(depfile_path))
+		return -1;
+
+	d = depfile_path + depfile_prefix_len;
+	s = name;
+
+	while ((c = *s++))
+		*d++ = (c == '_') ? '/' : tolower(c);
+	strcpy(d, ".h");
+
+	/* Assume directory path already exists. */
+	fd = open(depfile_path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+	if (fd == -1) {
+		if (errno != ENOENT)
+			return -1;
+
+		ret = make_parent_dir(depfile_path);
+		if (ret)
+			return ret;
+
+		/* Try it again. */
+		fd = open(depfile_path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+		if (fd == -1)
+			return -1;
+	}
+	close(fd);
+
+	return 0;
+}
+
+struct conf_printer {
+	void (*print_symbol)(FILE *, struct symbol *, const char *, void *);
+	void (*print_comment)(FILE *, const char *, void *);
 };
 
+static void conf_warning(const char *fmt, ...)
+	__attribute__ ((format (printf, 1, 2)));
+
+static void conf_message(const char *fmt, ...)
+	__attribute__ ((format (printf, 1, 2)));
+
+static const char *conf_filename;
+static int conf_lineno, conf_warnings;
+
 static void conf_warning(const char *fmt, ...)
 {
 	va_list ap;
@@ -41,384 +189,681 @@ static void conf_warning(const char *fmt, ...)
 	conf_warnings++;
 }
 
-static char *conf_expand_value(const char *in)
+static void conf_default_message_callback(const char *s)
 {
-	struct symbol *sym;
-	const char *src;
-	static char res_value[SYMBOL_MAXLENGTH];
-	char *dst, name[SYMBOL_MAXLENGTH];
-
-	res_value[0] = 0;
-	dst = name;
-	while ((src = strchr(in, '$'))) {
-		strncat(res_value, in, src - in);
-		src++;
-		dst = name;
-		while (isalnum((unsigned char)*src) || *src == '_')
-			*dst++ = *src++;
-		*dst = 0;
-		sym = sym_lookup(name, 0);
-		sym_calc_value(sym);
-		strcat(res_value, sym_get_string_value(sym));
-		in = src;
+	printf("#\n# ");
+	printf("%s", s);
+	printf("\n#\n");
+}
+
+static void (*conf_message_callback)(const char *s) =
+	conf_default_message_callback;
+void conf_set_message_callback(void (*fn)(const char *s))
+{
+	conf_message_callback = fn;
+}
+
+static void conf_message(const char *fmt, ...)
+{
+	va_list ap;
+	char buf[4096];
+
+	if (!conf_message_callback)
+		return;
+
+	va_start(ap, fmt);
+
+	vsnprintf(buf, sizeof(buf), fmt, ap);
+	conf_message_callback(buf);
+	va_end(ap);
+}
+
+const char *conf_get_configname(void)
+{
+	char *name = getenv("KCONFIG_CONFIG");
+
+	return name ? name : ".config";
+}
+
+static const char *conf_get_autoconfig_name(void)
+{
+	char *name = getenv("KCONFIG_AUTOCONFIG");
+
+	return name ? name : "include/config/auto.conf";
+}
+
+static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
+{
+	char *p2;
+
+	switch (sym->type) {
+	case S_TRISTATE:
+		if (p[0] == 'm') {
+			sym->def[def].tri = mod;
+			sym->flags |= def_flags;
+			break;
+		}
+		/* fall through */
+	case S_BOOLEAN:
+		if (p[0] == 'y') {
+			sym->def[def].tri = yes;
+			sym->flags |= def_flags;
+			break;
+		}
+		if (p[0] == 'n') {
+			sym->def[def].tri = no;
+			sym->flags |= def_flags;
+			break;
+		}
+		if (def != S_DEF_AUTO)
+			conf_warning("symbol value '%s' invalid for %s",
+				     p, sym->name);
+		return 1;
+	case S_STRING:
+		if (*p++ != '"')
+			break;
+		for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) {
+			if (*p2 == '"') {
+				*p2 = 0;
+				break;
+			}
+			memmove(p2, p2 + 1, strlen(p2));
+		}
+		if (!p2) {
+			if (def != S_DEF_AUTO)
+				conf_warning("invalid string found");
+			return 1;
+		}
+		/* fall through */
+	case S_INT:
+	case S_HEX:
+		if (sym_string_valid(sym, p)) {
+			sym->def[def].val = xstrdup(p);
+			sym->flags |= def_flags;
+		} else {
+			if (def != S_DEF_AUTO)
+				conf_warning("symbol value '%s' invalid for %s",
+					     p, sym->name);
+			return 1;
+		}
+		break;
+	default:
+		;
 	}
-	strcat(res_value, in);
+	return 0;
+}
+
+#define LINE_GROWTH 16
+static int add_byte(int c, char **lineptr, size_t slen, size_t *n)
+{
+	char *nline;
+	size_t new_size = slen + 1;
+	if (new_size > *n) {
+		new_size += LINE_GROWTH - 1;
+		new_size *= 2;
+		nline = xrealloc(*lineptr, new_size);
+		if (!nline)
+			return -1;
 
-	return res_value;
+		*lineptr = nline;
+		*n = new_size;
+	}
+
+	(*lineptr)[slen] = c;
+
+	return 0;
 }
 
-char *conf_get_default_confname(void)
+static ssize_t compat_getline(char **lineptr, size_t *n, FILE *stream)
 {
-	struct stat buf;
-	static char *fullname = NULL;
-	char *env, *name;
+	char *line = *lineptr;
+	size_t slen = 0;
 
-	name = conf_expand_value(conf_defname);
-	env = getenv(SRCTREE);
-	if (env) {
-		fullname = realloc(fullname, strlen(env) + strlen(name) + 2);
-		sprintf(fullname, "%s/%s", env, name);
-		if (!stat(fullname, &buf))
-			return fullname;
+	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++;
+		}
 	}
-	return name;
+
+e_out:
+	line[slen-1] = '\0';
+	*lineptr = line;
+	return -1;
 }
 
-int conf_read_simple(const char *name)
+int conf_read_simple(const char *name, int def)
 {
 	FILE *in = NULL;
-	char line[1024];
+	char   *line = NULL;
+	size_t  line_asize = 0;
 	char *p, *p2;
 	struct symbol *sym;
-	int i;
+	int i, def_flags;
 
 	if (name) {
 		in = zconf_fopen(name);
 	} else {
-		const char **names = conf_confnames;
-		while ((name = *names++)) {
-			name = conf_expand_value(name);
+		struct property *prop;
+
+		name = conf_get_configname();
+		in = zconf_fopen(name);
+		if (in)
+			goto load;
+		sym_add_change_count(1);
+		if (!sym_defconfig_list)
+			return 1;
+
+		for_all_defaults(sym_defconfig_list, prop) {
+			if (expr_calc_value(prop->visible.expr) == no ||
+			    prop->expr->type != E_SYMBOL)
+				continue;
+			sym_calc_value(prop->expr->left.sym);
+			name = sym_get_string_value(prop->expr->left.sym);
 			in = zconf_fopen(name);
 			if (in) {
-				printf(_("#\n"
-				         "# using defaults found in %s\n"
-				         "#\n"), name);
-				break;
+				conf_message("using defaults found in %s",
+					 name);
+				goto load;
 			}
 		}
 	}
 	if (!in)
 		return 1;
 
+load:
 	conf_filename = name;
 	conf_lineno = 0;
 	conf_warnings = 0;
-	conf_unsaved = 0;
 
+	def_flags = SYMBOL_DEF << def;
 	for_all_symbols(i, sym) {
-		sym->flags |= SYMBOL_NEW | SYMBOL_CHANGED;
+		sym->flags |= SYMBOL_CHANGED;
+		sym->flags &= ~(def_flags|SYMBOL_VALID);
 		if (sym_is_choice(sym))
-			sym->flags &= ~SYMBOL_NEW;
-		sym->flags &= ~SYMBOL_VALID;
+			sym->flags |= def_flags;
 		switch (sym->type) {
 		case S_INT:
 		case S_HEX:
 		case S_STRING:
-			free(sym->user.val);
+			if (sym->def[def].val)
+				free(sym->def[def].val);
+			/* fall through */
 		default:
-			sym->user.val = NULL;
-			sym->user.tri = no;
+			sym->def[def].val = NULL;
+			sym->def[def].tri = no;
 		}
 	}
 
-	while (fgets(line, sizeof(line), in)) {
+	while (compat_getline(&line, &line_asize, in) != -1) {
 		conf_lineno++;
 		sym = NULL;
-		switch (line[0]) {
-		case '#':
-			if (memcmp(line + 2, "CONFIG_", 7))
+		if (line[0] == '#') {
+			if (memcmp(line + 2, CONFIG_, strlen(CONFIG_)))
 				continue;
-			p = strchr(line + 9, ' ');
+			p = strchr(line + 2 + strlen(CONFIG_), ' ');
 			if (!p)
 				continue;
 			*p++ = 0;
 			if (strncmp(p, "is not set", 10))
 				continue;
-			sym = sym_find(line + 9);
-			if (!sym) {
-				conf_warning("trying to assign nonexistent symbol %s", line + 9);
-				break;
-			} else if (!(sym->flags & SYMBOL_NEW)) {
-				conf_warning("trying to reassign symbol %s", sym->name);
-				break;
+			if (def == S_DEF_USER) {
+				sym = sym_find(line + 2 + strlen(CONFIG_));
+				if (!sym) {
+					sym_add_change_count(1);
+					continue;
+				}
+			} else {
+				sym = sym_lookup(line + 2 + strlen(CONFIG_), 0);
+				if (sym->type == S_UNKNOWN)
+					sym->type = S_BOOLEAN;
+			}
+			if (sym->flags & def_flags) {
+				conf_warning("override: reassigning to symbol %s", sym->name);
 			}
 			switch (sym->type) {
 			case S_BOOLEAN:
 			case S_TRISTATE:
-				sym->user.tri = no;
-				sym->flags &= ~SYMBOL_NEW;
+				sym->def[def].tri = no;
+				sym->flags |= def_flags;
 				break;
 			default:
 				;
 			}
-			break;
-		case 'C':
-			if (memcmp(line, "CONFIG_", 7)) {
-				conf_warning("unexpected data");
-				continue;
-			}
-			p = strchr(line + 7, '=');
+		} else if (memcmp(line, CONFIG_, strlen(CONFIG_)) == 0) {
+			p = strchr(line + strlen(CONFIG_), '=');
 			if (!p)
 				continue;
 			*p++ = 0;
 			p2 = strchr(p, '\n');
-			if (p2)
-				*p2 = 0;
-			sym = sym_find(line + 7);
+			if (p2) {
+				*p2-- = 0;
+				if (*p2 == '\r')
+					*p2 = 0;
+			}
+
+			sym = sym_find(line + strlen(CONFIG_));
 			if (!sym) {
-				conf_warning("trying to assign nonexistent symbol %s", line + 7);
-				break;
-			} else if (!(sym->flags & SYMBOL_NEW)) {
-				conf_warning("trying to reassign symbol %s", sym->name);
-				break;
+				if (def == S_DEF_AUTO)
+					/*
+					 * Reading from include/config/auto.conf
+					 * If CONFIG_FOO previously existed in
+					 * auto.conf but it is missing now,
+					 * include/config/foo.h must be touched.
+					 */
+					conf_touch_dep(line + strlen(CONFIG_));
+				else
+					sym_add_change_count(1);
+				continue;
 			}
-			switch (sym->type) {
-			case S_TRISTATE:
-				if (p[0] == 'm') {
-					sym->user.tri = mod;
-					sym->flags &= ~SYMBOL_NEW;
-					break;
-				}
-			case S_BOOLEAN:
-				if (p[0] == 'y') {
-					sym->user.tri = yes;
-					sym->flags &= ~SYMBOL_NEW;
-					break;
-				}
-				if (p[0] == 'n') {
-					sym->user.tri = no;
-					sym->flags &= ~SYMBOL_NEW;
-					break;
-				}
-				conf_warning("symbol value '%s' invalid for %s", p, sym->name);
-				break;
-			case S_STRING:
-				if (*p++ != '"')
-					break;
-				for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) {
-					if (*p2 == '"') {
-						*p2 = 0;
-						break;
-					}
-					memmove(p2, p2 + 1, strlen(p2));
-				}
-				if (!p2) {
-					conf_warning("invalid string found");
-					continue;
-				}
-			case S_INT:
-			case S_HEX:
-				if (sym_string_valid(sym, p)) {
-					sym->user.val = strdup(p);
-					sym->flags &= ~SYMBOL_NEW;
-				} else {
-					if (p[0]) /* bbox */
-						conf_warning("symbol value '%s' invalid for %s", p, sym->name);
-					continue;
-				}
-				break;
-			default:
-				;
+
+			if (sym->flags & def_flags) {
+				conf_warning("override: reassigning to symbol %s", sym->name);
 			}
-			break;
-		case '\n':
-			break;
-		default:
-			conf_warning("unexpected data");
+			if (conf_set_sym_val(sym, def, def_flags, p))
+				continue;
+		} else {
+			if (line[0] != '\r' && line[0] != '\n')
+				conf_warning("unexpected data: %.*s",
+					     (int)strcspn(line, "\r\n"), line);
+
 			continue;
 		}
+
 		if (sym && sym_is_choice_value(sym)) {
 			struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
-			switch (sym->user.tri) {
+			switch (sym->def[def].tri) {
 			case no:
 				break;
 			case mod:
-				if (cs->user.tri == yes) {
+				if (cs->def[def].tri == yes) {
 					conf_warning("%s creates inconsistent choice state", sym->name);
-					cs->flags |= SYMBOL_NEW;
+					cs->flags &= ~def_flags;
 				}
 				break;
 			case yes:
-				if (cs->user.tri != no) {
-					conf_warning("%s creates inconsistent choice state", sym->name);
-					cs->flags |= SYMBOL_NEW;
-				} else
-					cs->user.val = sym;
+				if (cs->def[def].tri != no)
+					conf_warning("override: %s changes choice state", sym->name);
+				cs->def[def].val = sym;
 				break;
 			}
-			cs->user.tri = E_OR(cs->user.tri, sym->user.tri);
+			cs->def[def].tri = EXPR_OR(cs->def[def].tri, sym->def[def].tri);
 		}
 	}
+	free(line);
 	fclose(in);
-
-	if (modules_sym)
-		sym_calc_value(modules_sym);
 	return 0;
 }
 
 int conf_read(const char *name)
 {
 	struct symbol *sym;
-	struct property *prop;
-	struct expr *e;
+	int conf_unsaved = 0;
 	int i;
 
-	if (conf_read_simple(name))
+	sym_set_change_count(0);
+
+	if (conf_read_simple(name, S_DEF_USER)) {
+		sym_calc_value(modules_sym);
 		return 1;
+	}
+
+	sym_calc_value(modules_sym);
 
 	for_all_symbols(i, sym) {
 		sym_calc_value(sym);
-		if (sym_is_choice(sym) || (sym->flags & SYMBOL_AUTO))
-			goto sym_ok;
+		if (sym_is_choice(sym) || (sym->flags & SYMBOL_NO_WRITE))
+			continue;
 		if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) {
 			/* check that calculated value agrees with saved value */
 			switch (sym->type) {
 			case S_BOOLEAN:
 			case S_TRISTATE:
-				if (sym->user.tri != sym_get_tristate_value(sym))
-					break;
-				if (!sym_is_choice(sym))
-					goto sym_ok;
+				if (sym->def[S_DEF_USER].tri == sym_get_tristate_value(sym))
+					continue;
+				break;
 			default:
-				if (!strcmp(sym->curr.val, sym->user.val))
-					goto sym_ok;
+				if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val))
+					continue;
 				break;
 			}
 		} else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE))
 			/* no previous value and not saved */
-			goto sym_ok;
+			continue;
 		conf_unsaved++;
 		/* maybe print value in verbose mode... */
-	sym_ok:
+	}
+
+	for_all_symbols(i, sym) {
 		if (sym_has_value(sym) && !sym_is_choice_value(sym)) {
-			if (sym->visible == no)
-				sym->flags |= SYMBOL_NEW;
+			/* Reset values of generates values, so they'll appear
+			 * as new, if they should become visible, but that
+			 * doesn't quite work if the Kconfig and the saved
+			 * configuration disagree.
+			 */
+			if (sym->visible == no && !conf_unsaved)
+				sym->flags &= ~SYMBOL_DEF_USER;
 			switch (sym->type) {
 			case S_STRING:
 			case S_INT:
 			case S_HEX:
-				if (!sym_string_within_range(sym, sym->user.val)) {
-					sym->flags |= SYMBOL_NEW;
-					sym->flags &= ~SYMBOL_VALID;
-				}
+				/* Reset a string value if it's out of range */
+				if (sym_string_within_range(sym, sym->def[S_DEF_USER].val))
+					break;
+				sym->flags &= ~(SYMBOL_VALID|SYMBOL_DEF_USER);
+				conf_unsaved++;
+				break;
 			default:
 				break;
 			}
 		}
-		if (!sym_is_choice(sym))
-			continue;
-		prop = sym_get_choice_prop(sym);
-		for (e = prop->expr; e; e = e->left.expr)
-			if (e->right.sym->visible != no)
-				sym->flags |= e->right.sym->flags & SYMBOL_NEW;
 	}
 
-	sym_change_count = conf_warnings || conf_unsaved;
+	sym_add_change_count(conf_warnings || conf_unsaved);
 
 	return 0;
 }
 
+/*
+ * Kconfig configuration printer
+ *
+ * This printer is used when generating the resulting configuration after
+ * kconfig invocation and `defconfig' files. Unset symbol might be omitted by
+ * passing a non-NULL argument to the printer.
+ *
+ */
+static void
+kconfig_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg)
+{
+
+	switch (sym->type) {
+	case S_BOOLEAN:
+	case S_TRISTATE:
+		if (*value == 'n') {
+			bool skip_unset = (arg != NULL);
+
+			if (!skip_unset)
+				fprintf(fp, "# %s%s is not set\n",
+				    CONFIG_, sym->name);
+			return;
+		}
+		break;
+	default:
+		break;
+	}
+
+	fprintf(fp, "%s%s=%s\n", CONFIG_, sym->name, value);
+}
+
+static void
+kconfig_print_comment(FILE *fp, const char *value, void *arg)
+{
+	const char *p = value;
+	size_t l;
+
+	for (;;) {
+		l = strcspn(p, "\n");
+		fprintf(fp, "#");
+		if (l) {
+			fprintf(fp, " ");
+			xfwrite(p, l, 1, fp);
+			p += l;
+		}
+		fprintf(fp, "\n");
+		if (*p++ == '\0')
+			break;
+	}
+}
+
+static struct conf_printer kconfig_printer_cb =
+{
+	.print_symbol = kconfig_print_symbol,
+	.print_comment = kconfig_print_comment,
+};
+
+/*
+ * Header printer
+ *
+ * This printer is used when generating the `include/generated/autoconf.h' file.
+ */
+static void
+header_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg)
+{
+
+	switch (sym->type) {
+	case S_BOOLEAN:
+	case S_TRISTATE: {
+		const char *suffix = "";
+
+		switch (*value) {
+		case 'n':
+			break;
+		case 'm':
+			suffix = "_MODULE";
+			/* fall through */
+		default:
+			fprintf(fp, "#define %s%s%s 1\n",
+			    CONFIG_, sym->name, suffix);
+		}
+		break;
+	}
+	case S_HEX: {
+		const char *prefix = "";
+
+		if (value[0] != '0' || (value[1] != 'x' && value[1] != 'X'))
+			prefix = "0x";
+		fprintf(fp, "#define %s%s %s%s\n",
+		    CONFIG_, sym->name, prefix, value);
+		break;
+	}
+	case S_STRING:
+	case S_INT:
+		fprintf(fp, "#define %s%s %s\n",
+		    CONFIG_, sym->name, value);
+		break;
+	default:
+		break;
+	}
+
+}
+
+static void
+header_print_comment(FILE *fp, const char *value, void *arg)
+{
+	const char *p = value;
+	size_t l;
+
+	fprintf(fp, "/*\n");
+	for (;;) {
+		l = strcspn(p, "\n");
+		fprintf(fp, " *");
+		if (l) {
+			fprintf(fp, " ");
+			xfwrite(p, l, 1, fp);
+			p += l;
+		}
+		fprintf(fp, "\n");
+		if (*p++ == '\0')
+			break;
+	}
+	fprintf(fp, " */\n");
+}
+
+static struct conf_printer header_printer_cb =
+{
+	.print_symbol = header_print_symbol,
+	.print_comment = header_print_comment,
+};
+
+static void conf_write_symbol(FILE *fp, struct symbol *sym,
+			      struct conf_printer *printer, void *printer_arg)
+{
+	const char *str;
+
+	switch (sym->type) {
+	case S_UNKNOWN:
+		break;
+	case S_STRING:
+		str = sym_get_string_value(sym);
+		str = sym_escape_string_value(str);
+		printer->print_symbol(fp, sym, str, printer_arg);
+		free((void *)str);
+		break;
+	default:
+		str = sym_get_string_value(sym);
+		printer->print_symbol(fp, sym, str, printer_arg);
+	}
+}
+
+static void
+conf_write_heading(FILE *fp, struct conf_printer *printer, void *printer_arg)
+{
+	char buf[256];
+
+	snprintf(buf, sizeof(buf),
+	    "\n"
+	    "Automatically generated file; DO NOT EDIT.\n"
+	    "%s\n",
+	    rootmenu.prompt->text);
+
+	printer->print_comment(fp, buf, printer_arg);
+}
+
+/*
+ * Write out a minimal config.
+ * All values that has default values are skipped as this is redundant.
+ */
+int conf_write_defconfig(const char *filename)
+{
+	struct symbol *sym;
+	struct menu *menu;
+	FILE *out;
+
+	out = fopen(filename, "w");
+	if (!out)
+		return 1;
+
+	sym_clear_all_valid();
+
+	/* Traverse all menus to find all relevant symbols */
+	menu = rootmenu.list;
+
+	while (menu != NULL)
+	{
+		sym = menu->sym;
+		if (sym == NULL) {
+			if (!menu_is_visible(menu))
+				goto next_menu;
+		} else if (!sym_is_choice(sym)) {
+			sym_calc_value(sym);
+			if (!(sym->flags & SYMBOL_WRITE))
+				goto next_menu;
+			sym->flags &= ~SYMBOL_WRITE;
+			/* If we cannot change the symbol - skip */
+			if (!sym_is_changeable(sym))
+				goto next_menu;
+			/* If symbol equals to default value - skip */
+			if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0)
+				goto next_menu;
+
+			/*
+			 * If symbol is a choice value and equals to the
+			 * default for a choice - skip.
+			 * But only if value is bool and equal to "y" and
+			 * choice is not "optional".
+			 * (If choice is "optional" then all values can be "n")
+			 */
+			if (sym_is_choice_value(sym)) {
+				struct symbol *cs;
+				struct symbol *ds;
+
+				cs = prop_get_symbol(sym_get_choice_prop(sym));
+				ds = sym_choice_default(cs);
+				if (!sym_is_optional(cs) && sym == ds) {
+					if ((sym->type == S_BOOLEAN) &&
+					    sym_get_tristate_value(sym) == yes)
+						goto next_menu;
+				}
+			}
+			conf_write_symbol(out, sym, &kconfig_printer_cb, NULL);
+		}
+next_menu:
+		if (menu->list != NULL) {
+			menu = menu->list;
+		}
+		else if (menu->next != NULL) {
+			menu = menu->next;
+		} else {
+			while ((menu = menu->parent)) {
+				if (menu->next != NULL) {
+					menu = menu->next;
+					break;
+				}
+			}
+		}
+	}
+	fclose(out);
+	return 0;
+}
+
 int conf_write(const char *name)
 {
-	FILE *out, *out_h;
+	FILE *out;
 	struct symbol *sym;
 	struct menu *menu;
-	const char *basename;
-	char dirname[128];
-	char tmpname[256];
-	char newname[256];
-	int type, l;
 	const char *str;
-	time_t now;
-	int use_timestamp = 1;
+	char tmpname[PATH_MAX + 1], oldname[PATH_MAX + 1];
 	char *env;
+	int i;
+	bool need_newline = false;
+
+	if (!name)
+		name = conf_get_configname();
+
+	if (!*name) {
+		fprintf(stderr, "config name is empty\n");
+		return -1;
+	}
 
-	dirname[0] = 0;
-	if (name && name[0]) {
-		struct stat st;
-		char *slash;
-
-		if (!stat(name, &st) && S_ISDIR(st.st_mode)) {
-			strcpy(dirname, name);
-			strcat(dirname, "/");
-			basename = conf_def_filename;
-		} else if ((slash = strrchr(name, '/'))) {
-			int size = slash - name + 1;
-			memcpy(dirname, name, size);
-			dirname[size] = 0;
-			if (slash[1])
-				basename = slash + 1;
-			else
-				basename = conf_def_filename;
-		} else
-			basename = name;
-	} else
-		basename = conf_def_filename;
-
-	sprintf(newname, "%s.tmpconfig.%d", dirname, (int)getpid());
-	out = fopen(newname, "w");
+	if (is_dir(name)) {
+		fprintf(stderr, "%s: Is a directory\n", name);
+		return -1;
+	}
+
+	if (make_parent_dir(name))
+		return -1;
+
+	env = getenv("KCONFIG_OVERWRITECONFIG");
+	if (env && *env) {
+		*tmpname = 0;
+		out = fopen(name, "w");
+	} else {
+		snprintf(tmpname, sizeof(tmpname), "%s.%d.tmp",
+			 name, (int)getpid());
+		out = fopen(tmpname, "w");
+	}
 	if (!out)
 		return 1;
-	out_h = NULL;
-	if (!name) {
-		out_h = fopen(".tmpconfig.h", "w");
-		if (!out_h)
-			return 1;
-		file_write_dep(NULL);
-	}
-	sym = sym_lookup("KERNELVERSION", 0);
-	sym_calc_value(sym);
-	time(&now);
-	env = getenv("KCONFIG_NOTIMESTAMP");
-	if (env && *env)
-		use_timestamp = 0;
-
-	fprintf(out, _("#\n"
-		       "# Automatically generated make config: don't edit\n"
-		       "# Busybox version: %s\n"
-		       "%s%s"
-		       "#\n"),
-		     sym_get_string_value(sym),
-		     use_timestamp ? "# " : "",
-		     use_timestamp ? ctime(&now) : "");
-	if (out_h) {
-		char buf[sizeof("#define AUTOCONF_TIMESTAMP "
-				"\"YYYY-MM-DD HH:MM:SS some_timezone\"\n")];
-		buf[0] = '\0';
-		if (use_timestamp) {
-			size_t ret = \
-				strftime(buf, sizeof(buf), "#define AUTOCONF_TIMESTAMP "
-					"\"%Y-%m-%d %H:%M:%S %Z\"\n", localtime(&now));
-			/* if user has Factory timezone or some other odd install, the
-			 * %Z above will overflow the string leaving us with undefined
-			 * results ... so let's try again without the timezone.
-			 */
-			if (ret == 0)
-				strftime(buf, sizeof(buf), "#define AUTOCONF_TIMESTAMP "
-					"\"%Y-%m-%d %H:%M:%S\"\n", localtime(&now));
-		} else { /* bbox */
-			strcpy(buf, "#define AUTOCONF_TIMESTAMP \"\"\n");
-		}
-		fprintf(out_h, "/*\n"
-			       " * Automatically generated C config: don't edit\n"
-			       " * Busybox version: %s\n"
-			       " */\n"
-			       "%s"
-			       "\n",
-			       sym_get_string_value(sym),
-			       buf);
-	}
-	if (!sym_change_count)
+
+	conf_write_heading(out, &kconfig_printer_cb, NULL);
+
+	if (!conf_get_changed())
 		sym_clear_all_valid();
 
 	menu = rootmenu.list;
@@ -432,131 +877,21 @@ int conf_write(const char *name)
 				     "#\n"
 				     "# %s\n"
 				     "#\n", str);
-			if (out_h)
-				fprintf(out_h, "\n"
-					       "/*\n"
-					       " * %s\n"
-					       " */\n", str);
-		} else if (!(sym->flags & SYMBOL_CHOICE)) {
+			need_newline = false;
+		} else if (!(sym->flags & SYMBOL_CHOICE) &&
+			   !(sym->flags & SYMBOL_WRITTEN)) {
 			sym_calc_value(sym);
-/* bbox: we want to see all syms
 			if (!(sym->flags & SYMBOL_WRITE))
 				goto next;
-*/
-			sym->flags &= ~SYMBOL_WRITE;
-			type = sym->type;
-			if (type == S_TRISTATE) {
-				sym_calc_value(modules_sym);
-				if (modules_sym->curr.tri == no)
-					type = S_BOOLEAN;
-			}
-			switch (type) {
-			case S_BOOLEAN:
-			case S_TRISTATE:
-				switch (sym_get_tristate_value(sym)) {
-				case no:
-					fprintf(out, "# CONFIG_%s is not set\n", sym->name);
-					if (out_h) {
-						fprintf(out_h, "#undef CONFIG_%s\n", sym->name);
-						/* bbox */
-						fprintf(out_h, "#define ENABLE_%s 0\n", sym->name);
-						fprintf(out_h, "#define IF_%s(...)\n", sym->name);
-						fprintf(out_h, "#define IF_NOT_%s(...) __VA_ARGS__\n", sym->name);
-					}
-					break;
-				case mod:
-					fprintf(out, "CONFIG_%s=m\n", sym->name);
-					if (out_h)
-						fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name);
-					break;
-				case yes:
-					fprintf(out, "CONFIG_%s=y\n", sym->name);
-					if (out_h) {
-						fprintf(out_h, "#define CONFIG_%s 1\n", sym->name);
-						/* bbox */
-						fprintf(out_h, "#define ENABLE_%s 1\n", sym->name);
-						fprintf(out_h, "#ifdef MAKE_SUID\n");
-						fprintf(out_h, "# define IF_%s(...) __VA_ARGS__ \"CONFIG_%s\"\n", sym->name, \
                sym->name);
-						fprintf(out_h, "#else\n");
-						fprintf(out_h, "# define IF_%s(...) __VA_ARGS__\n", sym->name);
-						fprintf(out_h, "#endif\n");
-						fprintf(out_h, "#define IF_NOT_%s(...)\n", sym->name);
-					}
-					break;
-				}
-				break;
-			case S_STRING:
-				// fix me
-				str = sym_get_string_value(sym);
-				fprintf(out, "CONFIG_%s=\"", sym->name);
-				if (out_h)
-					fprintf(out_h, "#define CONFIG_%s \"", sym->name);
-				do {
-					l = strcspn(str, "\"\\");
-					if (l) {
-						fwrite(str, l, 1, out);
-						if (out_h)
-							fwrite(str, l, 1, out_h);
-					}
-					str += l;
-					while (*str == '\\' || *str == '"') {
-						fprintf(out, "\\%c", *str);
-						if (out_h)
-							fprintf(out_h, "\\%c", *str);
-						str++;
-					}
-				} while (*str);
-				fputs("\"\n", out);
-				if (out_h) {
-					fputs("\"\n", out_h);
-					/* bbox */
-					fprintf(out_h, "#define ENABLE_%s 1\n", sym->name);
-					fprintf(out_h, "#ifdef MAKE_SUID\n");
-					fprintf(out_h, "# define IF_%s(...) __VA_ARGS__ \"CONFIG_%s\"\n", sym->name, \
                sym->name);
-					fprintf(out_h, "#else\n");
-					fprintf(out_h, "# define IF_%s(...) __VA_ARGS__\n", sym->name);
-					fprintf(out_h, "#endif\n");
-					fprintf(out_h, "#define IF_NOT_%s(...)\n", sym->name);
-				}
-				break;
-			case S_HEX:
-				str = sym_get_string_value(sym);
-				if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
-					fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
-					if (out_h) {
-						fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str);
-						/* bbox */
-						fprintf(out_h, "#define ENABLE_%s 1\n", sym->name);
-						fprintf(out_h, "#ifdef MAKE_SUID\n");
-						fprintf(out_h, "# define IF_%s(...) __VA_ARGS__ \"CONFIG_%s\"\n", sym->name, \
                sym->name);
-						fprintf(out_h, "#else\n");
-						fprintf(out_h, "# define IF_%s(...) __VA_ARGS__\n", sym->name);
-						fprintf(out_h, "#endif\n");
-						fprintf(out_h, "#define IF_NOT_%s(...)\n", sym->name);
-					}
-					break;
-				}
-			case S_INT:
-				str = sym_get_string_value(sym);
-				if (!str[0])
-					str = "0";
-				fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
-				if (out_h) {
-					fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str);
-					/* bbox */
-					fprintf(out_h, "#define ENABLE_%s 1\n", sym->name);
-					fprintf(out_h, "#ifdef MAKE_SUID\n");
-					fprintf(out_h, "# define IF_%s(...) __VA_ARGS__ \"CONFIG_%s\"\n", sym->name, \
                sym->name);
-					fprintf(out_h, "#else\n");
-					fprintf(out_h, "# define IF_%s(...) __VA_ARGS__\n", sym->name);
-					fprintf(out_h, "#endif\n");
-					fprintf(out_h, "#define IF_NOT_%s(...)\n", sym->name);
-				}
-				break;
+			if (need_newline) {
+				fprintf(out, "\n");
+				need_newline = false;
 			}
+			sym->flags |= SYMBOL_WRITTEN;
+			conf_write_symbol(out, sym, &kconfig_printer_cb, NULL);
 		}
 
-	next:
+next:
 		if (menu->list) {
 			menu = menu->list;
 			continue;
@@ -564,6 +899,12 @@ int conf_write(const char *name)
 		if (menu->next)
 			menu = menu->next;
 		else while ((menu = menu->parent)) {
+			if (!menu->sym && menu_is_visible(menu) &&
+			    menu != &rootmenu) {
+				str = menu_get_prompt(menu);
+				fprintf(out, "# end of %s\n", str);
+				need_newline = true;
+			}
 			if (menu->next) {
 				menu = menu->next;
 				break;
@@ -571,21 +912,428 @@ int conf_write(const char *name)
 		}
 	}
 	fclose(out);
-	if (out_h) {
-		fclose(out_h);
-		rename(".tmpconfig.h", "include/generated/autoconf.h");
-	}
-	if (!name || basename != conf_def_filename) {
-		if (!name)
-			name = conf_def_filename;
-		sprintf(tmpname, "%s.old", name);
-		rename(name, tmpname);
-	}
-	sprintf(tmpname, "%s%s", dirname, basename);
-	if (rename(newname, tmpname))
+
+	for_all_symbols(i, sym)
+		sym->flags &= ~SYMBOL_WRITTEN;
+
+	if (*tmpname) {
+		if (is_same(name, tmpname)) {
+			conf_message("No change to %s", name);
+			unlink(tmpname);
+			sym_set_change_count(0);
+			return 0;
+		}
+
+		snprintf(oldname, sizeof(oldname), "%s.old", name);
+		rename(name, oldname);
+		if (rename(tmpname, name))
+			return 1;
+	}
+
+	conf_message("configuration written to %s", name);
+
+	sym_set_change_count(0);
+
+	return 0;
+}
+
+/* write a dependency file as used by kbuild to track dependencies */
+static int conf_write_dep(const char *name)
+{
+	struct file *file;
+	FILE *out;
+
+	out = fopen("..config.tmp", "w");
+	if (!out)
 		return 1;
+	fprintf(out, "deps_config := \\\n");
+	for (file = file_list; file; file = file->next) {
+		if (file->next)
+			fprintf(out, "\t%s \\\n", file->name);
+		else
+			fprintf(out, "\t%s\n", file->name);
+	}
+	fprintf(out, "\n%s: \\\n"
+		     "\t$(deps_config)\n\n", conf_get_autoconfig_name());
+
+	env_write_dep(out, conf_get_autoconfig_name());
 
-	sym_change_count = 0;
+	fprintf(out, "\n$(deps_config): ;\n");
+	fclose(out);
 
+	if (make_parent_dir(name))
+		return 1;
+	rename("..config.tmp", name);
 	return 0;
 }
+
+static int conf_touch_deps(void)
+{
+	const char *name;
+	struct symbol *sym;
+	int res, i;
+
+	strcpy(depfile_path, "include/config/");
+	depfile_prefix_len = strlen(depfile_path);
+
+	name = conf_get_autoconfig_name();
+	conf_read_simple(name, S_DEF_AUTO);
+	sym_calc_value(modules_sym);
+
+	for_all_symbols(i, sym) {
+		sym_calc_value(sym);
+		if ((sym->flags & SYMBOL_NO_WRITE) || !sym->name)
+			continue;
+		if (sym->flags & SYMBOL_WRITE) {
+			if (sym->flags & SYMBOL_DEF_AUTO) {
+				/*
+				 * symbol has old and new value,
+				 * so compare them...
+				 */
+				switch (sym->type) {
+				case S_BOOLEAN:
+				case S_TRISTATE:
+					if (sym_get_tristate_value(sym) ==
+					    sym->def[S_DEF_AUTO].tri)
+						continue;
+					break;
+				case S_STRING:
+				case S_HEX:
+				case S_INT:
+					if (!strcmp(sym_get_string_value(sym),
+						    sym->def[S_DEF_AUTO].val))
+						continue;
+					break;
+				default:
+					break;
+				}
+			} else {
+				/*
+				 * If there is no old value, only 'no' (unset)
+				 * is allowed as new value.
+				 */
+				switch (sym->type) {
+				case S_BOOLEAN:
+				case S_TRISTATE:
+					if (sym_get_tristate_value(sym) == no)
+						continue;
+					break;
+				default:
+					break;
+				}
+			}
+		} else if (!(sym->flags & SYMBOL_DEF_AUTO))
+			/* There is neither an old nor a new value. */
+			continue;
+		/* else
+		 *	There is an old value, but no new value ('no' (unset)
+		 *	isn't saved in auto.conf, so the old value is always
+		 *	different from 'no').
+		 */
+
+		res = conf_touch_dep(sym->name);
+		if (res)
+			return res;
+	}
+
+	return 0;
+}
+
+int conf_write_autoconf(int overwrite)
+{
+	struct symbol *sym;
+	const char *name;
+	const char *autoconf_name = conf_get_autoconfig_name();
+	FILE *out, *out_h;
+	int i;
+
+	if (!overwrite && is_present(autoconf_name))
+		return 0;
+
+	conf_write_dep("include/config/auto.conf.cmd");
+
+	if (conf_touch_deps())
+		return 1;
+
+	out = fopen(".tmpconfig", "w");
+	if (!out)
+		return 1;
+
+	out_h = fopen(".tmpconfig.h", "w");
+	if (!out_h) {
+		fclose(out);
+		return 1;
+	}
+
+	conf_write_heading(out, &kconfig_printer_cb, NULL);
+	conf_write_heading(out_h, &header_printer_cb, NULL);
+
+	for_all_symbols(i, sym) {
+		sym_calc_value(sym);
+		if (!(sym->flags & SYMBOL_WRITE) || !sym->name)
+			continue;
+
+		/* write symbols to auto.conf and autoconf.h */
+		conf_write_symbol(out, sym, &kconfig_printer_cb, (void *)1);
+		conf_write_symbol(out_h, sym, &header_printer_cb, NULL);
+	}
+	fclose(out);
+	fclose(out_h);
+
+	name = getenv("KCONFIG_AUTOHEADER");
+	if (!name)
+		name = "include/generated/autoconf.h";
+	if (make_parent_dir(name))
+		return 1;
+	if (rename(".tmpconfig.h", name))
+		return 1;
+
+	if (make_parent_dir(autoconf_name))
+		return 1;
+	/*
+	 * This must be the last step, kbuild has a dependency on auto.conf
+	 * and this marks the successful completion of the previous steps.
+	 */
+	if (rename(".tmpconfig", autoconf_name))
+		return 1;
+
+	return 0;
+}
+
+static int sym_change_count;
+static void (*conf_changed_callback)(void);
+
+void sym_set_change_count(int count)
+{
+	int _sym_change_count = sym_change_count;
+	sym_change_count = count;
+	if (conf_changed_callback &&
+	    (bool)_sym_change_count != (bool)count)
+		conf_changed_callback();
+}
+
+void sym_add_change_count(int count)
+{
+	sym_set_change_count(count + sym_change_count);
+}
+
+bool conf_get_changed(void)
+{
+	return sym_change_count;
+}
+
+void conf_set_changed_callback(void (*fn)(void))
+{
+	conf_changed_callback = fn;
+}
+
+static bool randomize_choice_values(struct symbol *csym)
+{
+	struct property *prop;
+	struct symbol *sym;
+	struct expr *e;
+	int cnt, def;
+
+	/*
+	 * If choice is mod then we may have more items selected
+	 * and if no then no-one.
+	 * In both cases stop.
+	 */
+	if (csym->curr.tri != yes)
+		return false;
+
+	prop = sym_get_choice_prop(csym);
+
+	/* count entries in choice block */
+	cnt = 0;
+	expr_list_for_each_sym(prop->expr, e, sym)
+		cnt++;
+
+	/*
+	 * find a random value and set it to yes,
+	 * set the rest to no so we have only one set
+	 */
+	def = (rand() % cnt);
+
+	cnt = 0;
+	expr_list_for_each_sym(prop->expr, e, sym) {
+		if (def == cnt++) {
+			sym->def[S_DEF_USER].tri = yes;
+			csym->def[S_DEF_USER].val = sym;
+		}
+		else {
+			sym->def[S_DEF_USER].tri = no;
+		}
+		sym->flags |= SYMBOL_DEF_USER;
+		/* clear VALID to get value calculated */
+		sym->flags &= ~SYMBOL_VALID;
+	}
+	csym->flags |= SYMBOL_DEF_USER;
+	/* clear VALID to get value calculated */
+	csym->flags &= ~(SYMBOL_VALID);
+
+	return true;
+}
+
+void set_all_choice_values(struct symbol *csym)
+{
+	struct property *prop;
+	struct symbol *sym;
+	struct expr *e;
+
+	prop = sym_get_choice_prop(csym);
+
+	/*
+	 * Set all non-assinged choice values to no
+	 */
+	expr_list_for_each_sym(prop->expr, e, sym) {
+		if (!sym_has_value(sym))
+			sym->def[S_DEF_USER].tri = no;
+	}
+	csym->flags |= SYMBOL_DEF_USER;
+	/* clear VALID to get value calculated */
+	csym->flags &= ~(SYMBOL_VALID | SYMBOL_NEED_SET_CHOICE_VALUES);
+}
+
+bool conf_set_all_new_symbols(enum conf_def_mode mode)
+{
+	struct symbol *sym, *csym;
+	int i, cnt, pby, pty, ptm;	/* pby: probability of bool     = y
+					 * pty: probability of tristate = y
+					 * ptm: probability of tristate = m
+					 */
+
+	pby = 50; pty = ptm = 33; /* can't go as the default in switch-case
+				   * below, otherwise gcc whines about
+				   * -Wmaybe-uninitialized */
+	if (mode == def_random) {
+		int n, p[3];
+		char *env = getenv("KCONFIG_PROBABILITY");
+		n = 0;
+		while( env && *env ) {
+			char *endp;
+			int tmp = strtol( env, &endp, 10 );
+			if( tmp >= 0 && tmp <= 100 ) {
+				p[n++] = tmp;
+			} else {
+				errno = ERANGE;
+				perror( "KCONFIG_PROBABILITY" );
+				exit( 1 );
+			}
+			env = (*endp == ':') ? endp+1 : endp;
+			if( n >=3 ) {
+				break;
+			}
+		}
+		switch( n ) {
+		case 1:
+			pby = p[0]; ptm = pby/2; pty = pby-ptm;
+			break;
+		case 2:
+			pty = p[0]; ptm = p[1]; pby = pty + ptm;
+			break;
+		case 3:
+			pby = p[0]; pty = p[1]; ptm = p[2];
+			break;
+		}
+
+		if( pty+ptm > 100 ) {
+			errno = ERANGE;
+			perror( "KCONFIG_PROBABILITY" );
+			exit( 1 );
+		}
+	}
+	bool has_changed = false;
+
+	for_all_symbols(i, sym) {
+		if (sym_has_value(sym) || (sym->flags & SYMBOL_VALID))
+			continue;
+		switch (sym_get_type(sym)) {
+		case S_BOOLEAN:
+		case S_TRISTATE:
+			has_changed = true;
+			switch (mode) {
+			case def_yes:
+				sym->def[S_DEF_USER].tri = yes;
+				break;
+			case def_mod:
+				sym->def[S_DEF_USER].tri = mod;
+				break;
+			case def_no:
+				if (sym->flags & SYMBOL_ALLNOCONFIG_Y)
+					sym->def[S_DEF_USER].tri = yes;
+				else
+					sym->def[S_DEF_USER].tri = no;
+				break;
+			case def_random:
+				sym->def[S_DEF_USER].tri = no;
+				cnt = rand() % 100;
+				if (sym->type == S_TRISTATE) {
+					if (cnt < pty)
+						sym->def[S_DEF_USER].tri = yes;
+					else if (cnt < (pty+ptm))
+						sym->def[S_DEF_USER].tri = mod;
+				} else if (cnt < pby)
+					sym->def[S_DEF_USER].tri = yes;
+				break;
+			default:
+				continue;
+			}
+			if (!(sym_is_choice(sym) && mode == def_random))
+				sym->flags |= SYMBOL_DEF_USER;
+			break;
+		default:
+			break;
+		}
+
+	}
+
+	sym_clear_all_valid();
+
+	/*
+	 * We have different type of choice blocks.
+	 * If curr.tri equals to mod then we can select several
+	 * choice symbols in one block.
+	 * In this case we do nothing.
+	 * If curr.tri equals yes then only one symbol can be
+	 * selected in a choice block and we set it to yes,
+	 * and the rest to no.
+	 */
+	if (mode != def_random) {
+		for_all_symbols(i, 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) {
+		if (sym_has_value(csym) || !sym_is_choice(csym))
+			continue;
+
+		sym_calc_value(csym);
+		if (mode == def_random)
+			has_changed |= randomize_choice_values(csym);
+		else {
+			set_all_choice_values(csym);
+			has_changed = true;
+		}
+	}
+
+	return has_changed;
+}
+
+void conf_rewrite_mod_or_yes(enum conf_def_mode mode)
+{
+	struct symbol *sym;
+	int i;
+	tristate old_val = (mode == def_y2m) ? yes : mod;
+	tristate new_val = (mode == def_y2m) ? mod : yes;
+
+	for_all_symbols(i, sym) {
+		if (sym_get_type(sym) == S_TRISTATE &&
+		    sym->def[S_DEF_USER].tri == old_val)
+			sym->def[S_DEF_USER].tri = new_val;
+	}
+	sym_clear_all_valid();
+}
diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c
index 6f39e7a25..81ebf8108 100644
--- a/scripts/kconfig/expr.c
+++ b/scripts/kconfig/expr.c
@@ -1,21 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
- * Released under the terms of the GNU GPL v2.0.
  */
 
+#include <ctype.h>
+#include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
-#define LKC_DIRECT_LINK
 #include "lkc.h"
 
 #define DEBUG_EXPR	0
 
+static struct expr *expr_eliminate_yn(struct expr *e);
+
 struct expr *expr_alloc_symbol(struct symbol *sym)
 {
-	struct expr *e = malloc(sizeof(*e));
-	memset(e, 0, sizeof(*e));
+	struct expr *e = xcalloc(1, sizeof(*e));
 	e->type = E_SYMBOL;
 	e->left.sym = sym;
 	return e;
@@ -23,8 +25,7 @@ struct expr *expr_alloc_symbol(struct symbol *sym)
 
 struct expr *expr_alloc_one(enum expr_type type, struct expr *ce)
 {
-	struct expr *e = malloc(sizeof(*e));
-	memset(e, 0, sizeof(*e));
+	struct expr *e = xcalloc(1, sizeof(*e));
 	e->type = type;
 	e->left.expr = ce;
 	return e;
@@ -32,8 +33,7 @@ struct expr *expr_alloc_one(enum expr_type type, struct expr *ce)
 
 struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2)
 {
-	struct expr *e = malloc(sizeof(*e));
-	memset(e, 0, sizeof(*e));
+	struct expr *e = xcalloc(1, sizeof(*e));
 	e->type = type;
 	e->left.expr = e1;
 	e->right.expr = e2;
@@ -42,8 +42,7 @@ struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, \
struct expr *e  
 struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol \
*s2)  {
-	struct expr *e = malloc(sizeof(*e));
-	memset(e, 0, sizeof(*e));
+	struct expr *e = xcalloc(1, sizeof(*e));
 	e->type = type;
 	e->left.sym = s1;
 	e->right.sym = s2;
@@ -64,14 +63,14 @@ struct expr *expr_alloc_or(struct expr *e1, struct expr *e2)
 	return e2 ? expr_alloc_two(E_OR, e1, e2) : e1;
 }
 
-struct expr *expr_copy(struct expr *org)
+struct expr *expr_copy(const struct expr *org)
 {
 	struct expr *e;
 
 	if (!org)
 		return NULL;
 
-	e = malloc(sizeof(*org));
+	e = xmalloc(sizeof(*org));
 	memcpy(e, org, sizeof(*org));
 	switch (org->type) {
 	case E_SYMBOL:
@@ -81,18 +80,22 @@ struct expr *expr_copy(struct expr *org)
 		e->left.expr = expr_copy(org->left.expr);
 		break;
 	case E_EQUAL:
+	case E_GEQ:
+	case E_GTH:
+	case E_LEQ:
+	case E_LTH:
 	case E_UNEQUAL:
 		e->left.sym = org->left.sym;
 		e->right.sym = org->right.sym;
 		break;
 	case E_AND:
 	case E_OR:
-	case E_CHOICE:
+	case E_LIST:
 		e->left.expr = expr_copy(org->left.expr);
 		e->right.expr = expr_copy(org->right.expr);
 		break;
 	default:
-		printf("can't copy type %d\n", e->type);
+		fprintf(stderr, "can't copy type %d\n", e->type);
 		free(e);
 		e = NULL;
 		break;
@@ -111,8 +114,12 @@ void expr_free(struct expr *e)
 		break;
 	case E_NOT:
 		expr_free(e->left.expr);
-		return;
+		break;
 	case E_EQUAL:
+	case E_GEQ:
+	case E_GTH:
+	case E_LEQ:
+	case E_LTH:
 	case E_UNEQUAL:
 		break;
 	case E_OR:
@@ -121,7 +128,7 @@ void expr_free(struct expr *e)
 		expr_free(e->right.expr);
 		break;
 	default:
-		printf("how to free type %d?\n", e->type);
+		fprintf(stderr, "how to free type %d?\n", e->type);
 		break;
 	}
 	free(e);
@@ -132,8 +139,18 @@ static int trans_count;
 #define e1 (*ep1)
 #define e2 (*ep2)
 
+/*
+ * expr_eliminate_eq() helper.
+ *
+ * Walks the two expression trees given in 'ep1' and 'ep2'. Any node that does
+ * not have type 'type' (E_OR/E_AND) is considered a leaf, and is compared
+ * against all other leaves. Two equal leaves are both replaced with either 'y'
+ * or 'n' as appropriate for 'type', to be eliminated later.
+ */
 static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct expr \
**ep2)  {
+	/* Recurse down to leaves */
+
 	if (e1->type == type) {
 		__expr_eliminate_eq(type, &e1->left.expr, &e2);
 		__expr_eliminate_eq(type, &e1->right.expr, &e2);
@@ -144,11 +161,18 @@ static void __expr_eliminate_eq(enum expr_type type, struct \
expr **ep1, struct e  __expr_eliminate_eq(type, &e1, &e2->right.expr);
 		return;
 	}
+
+	/* e1 and e2 are leaves. Compare them. */
+
 	if (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
-	    e1->left.sym == e2->left.sym && (e1->left.sym->flags & (SYMBOL_YES|SYMBOL_NO)))
+	    e1->left.sym == e2->left.sym &&
+	    (e1->left.sym == &symbol_yes || e1->left.sym == &symbol_no))
 		return;
 	if (!expr_eq(e1, e2))
 		return;
+
+	/* e1 and e2 are equal leaves. Prepare them for elimination. */
+
 	trans_count++;
 	expr_free(e1); expr_free(e2);
 	switch (type) {
@@ -165,6 +189,35 @@ static void __expr_eliminate_eq(enum expr_type type, struct expr \
**ep1, struct e  }
 }
 
+/*
+ * Rewrites the expressions 'ep1' and 'ep2' to remove operands common to both.
+ * Example reductions:
+ *
+ *	ep1: A && B           ->  ep1: y
+ *	ep2: A && B && C      ->  ep2: C
+ *
+ *	ep1: A || B           ->  ep1: n
+ *	ep2: A || B || C      ->  ep2: C
+ *
+ *	ep1: A && (B && FOO)  ->  ep1: FOO
+ *	ep2: (BAR && B) && A  ->  ep2: BAR
+ *
+ *	ep1: A && (B || C)    ->  ep1: y
+ *	ep2: (C || B) && A    ->  ep2: y
+ *
+ * Comparisons are done between all operands at the same "level" of && or ||.
+ * For example, in the expression 'e1 && (e2 || e3) && (e4 || e5)', the
+ * following operands will be compared:
+ *
+ *	- 'e1', 'e2 || e3', and 'e4 || e5', against each other
+ *	- e2 against e3
+ *	- e4 against e5
+ *
+ * Parentheses are irrelevant within a single level. 'e1 && (e2 && e3)' and
+ * '(e1 && e2) && e3' are both a single level.
+ *
+ * See __expr_eliminate_eq() as well.
+ */
 void expr_eliminate_eq(struct expr **ep1, struct expr **ep2)
 {
 	if (!e1 || !e2)
@@ -190,14 +243,31 @@ void expr_eliminate_eq(struct expr **ep1, struct expr **ep2)
 #undef e1
 #undef e2
 
+/*
+ * Returns true if 'e1' and 'e2' are equal, after minor simplification. Two
+ * &&/|| expressions are considered equal if every operand in one expression
+ * equals some operand in the other (operands do not need to appear in the same
+ * order), recursively.
+ */
 int expr_eq(struct expr *e1, struct expr *e2)
 {
 	int res, old_count;
 
+	/*
+	 * A NULL expr is taken to be yes, but there's also a different way to
+	 * represent yes. expr_is_yes() checks for either representation.
+	 */
+	if (!e1 || !e2)
+		return expr_is_yes(e1) && expr_is_yes(e2);
+
 	if (e1->type != e2->type)
 		return 0;
 	switch (e1->type) {
 	case E_EQUAL:
+	case E_GEQ:
+	case E_GTH:
+	case E_LEQ:
+	case E_LTH:
 	case E_UNEQUAL:
 		return e1->left.sym == e2->left.sym && e1->right.sym == e2->right.sym;
 	case E_SYMBOL:
@@ -216,7 +286,7 @@ int expr_eq(struct expr *e1, struct expr *e2)
 		expr_free(e2);
 		trans_count = old_count;
 		return res;
-	case E_CHOICE:
+	case E_LIST:
 	case E_RANGE:
 	case E_NONE:
 		/* panic */;
@@ -232,7 +302,18 @@ int expr_eq(struct expr *e1, struct expr *e2)
 	return 0;
 }
 
-struct expr *expr_eliminate_yn(struct expr *e)
+/*
+ * Recursively performs the following simplifications in-place (as well as the
+ * corresponding simplifications with swapped operands):
+ *
+ *	expr && n  ->  n
+ *	expr && y  ->  expr
+ *	expr || n  ->  expr
+ *	expr || y  ->  y
+ *
+ * Returns the optimized expression.
+ */
+static struct expr *expr_eliminate_yn(struct expr *e)
 {
 	struct expr *tmp;
 
@@ -347,7 +428,7 @@ struct expr *expr_trans_bool(struct expr *e)
 /*
  * e1 || e2 -> ?
  */
-struct expr *expr_join_or(struct expr *e1, struct expr *e2)
+static struct expr *expr_join_or(struct expr *e1, struct expr *e2)
 {
 	struct expr *tmp;
 	struct symbol *sym1, *sym2;
@@ -411,7 +492,7 @@ struct expr *expr_join_or(struct expr *e1, struct expr *e2)
 	return NULL;
 }
 
-struct expr *expr_join_and(struct expr *e1, struct expr *e2)
+static struct expr *expr_join_and(struct expr *e1, struct expr *e2)
 {
 	struct expr *tmp;
 	struct symbol *sym1, *sym2;
@@ -505,12 +586,21 @@ struct expr *expr_join_and(struct expr *e1, struct expr *e2)
 	return NULL;
 }
 
+/*
+ * expr_eliminate_dups() helper.
+ *
+ * Walks the two expression trees given in 'ep1' and 'ep2'. Any node that does
+ * not have type 'type' (E_OR/E_AND) is considered a leaf, and is compared
+ * against all other leaves to look for simplifications.
+ */
 static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr \
**ep2)  {
 #define e1 (*ep1)
 #define e2 (*ep2)
 	struct expr *tmp;
 
+	/* Recurse down to leaves */
+
 	if (e1->type == type) {
 		expr_eliminate_dups1(type, &e1->left.expr, &e2);
 		expr_eliminate_dups1(type, &e1->right.expr, &e2);
@@ -521,6 +611,9 @@ static void expr_eliminate_dups1(enum expr_type type, struct expr \
**ep1, struct  expr_eliminate_dups1(type, &e1, &e2->right.expr);
 		return;
 	}
+
+	/* e1 and e2 are leaves. Compare and process them. */
+
 	if (e1 == e2)
 		return;
 
@@ -557,62 +650,17 @@ static void expr_eliminate_dups1(enum expr_type type, struct \
expr **ep1, struct  #undef e2
 }
 
-static void expr_eliminate_dups2(enum expr_type type, struct expr **ep1, struct expr \
                **ep2)
-{
-#define e1 (*ep1)
-#define e2 (*ep2)
-	struct expr *tmp, *tmp1, *tmp2;
-
-	if (e1->type == type) {
-		expr_eliminate_dups2(type, &e1->left.expr, &e2);
-		expr_eliminate_dups2(type, &e1->right.expr, &e2);
-		return;
-	}
-	if (e2->type == type) {
-		expr_eliminate_dups2(type, &e1, &e2->left.expr);
-		expr_eliminate_dups2(type, &e1, &e2->right.expr);
-	}
-	if (e1 == e2)
-		return;
-
-	switch (e1->type) {
-	case E_OR:
-		expr_eliminate_dups2(e1->type, &e1, &e1);
-		// (FOO || BAR) && (!FOO && !BAR) -> n
-		tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1)));
-		tmp2 = expr_copy(e2);
-		tmp = expr_extract_eq_and(&tmp1, &tmp2);
-		if (expr_is_yes(tmp1)) {
-			expr_free(e1);
-			e1 = expr_alloc_symbol(&symbol_no);
-			trans_count++;
-		}
-		expr_free(tmp2);
-		expr_free(tmp1);
-		expr_free(tmp);
-		break;
-	case E_AND:
-		expr_eliminate_dups2(e1->type, &e1, &e1);
-		// (FOO && BAR) || (!FOO || !BAR) -> y
-		tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1)));
-		tmp2 = expr_copy(e2);
-		tmp = expr_extract_eq_or(&tmp1, &tmp2);
-		if (expr_is_no(tmp1)) {
-			expr_free(e1);
-			e1 = expr_alloc_symbol(&symbol_yes);
-			trans_count++;
-		}
-		expr_free(tmp2);
-		expr_free(tmp1);
-		expr_free(tmp);
-		break;
-	default:
-		;
-	}
-#undef e1
-#undef e2
-}
-
+/*
+ * Rewrites 'e' in-place to remove ("join") duplicate and other redundant
+ * operands.
+ *
+ * Example simplifications:
+ *
+ *	A || B || A    ->  A || B
+ *	A && B && A=y  ->  A=y && B
+ *
+ * Returns the deduplicated expression.
+ */
 struct expr *expr_eliminate_dups(struct expr *e)
 {
 	int oldcount;
@@ -625,11 +673,11 @@ struct expr *expr_eliminate_dups(struct expr *e)
 		switch (e->type) {
 		case E_OR: case E_AND:
 			expr_eliminate_dups1(e->type, &e, &e);
-			expr_eliminate_dups2(e->type, &e, &e);
 		default:
 			;
 		}
 		if (!trans_count)
+			/* No simplifications done in this pass. We're done */
 			break;
 		e = expr_eliminate_yn(e);
 	}
@@ -637,6 +685,12 @@ struct expr *expr_eliminate_dups(struct expr *e)
 	return e;
 }
 
+/*
+ * Performs various simplifications involving logical operators and
+ * comparisons.
+ *
+ * Allocates and returns a new expression.
+ */
 struct expr *expr_transform(struct expr *e)
 {
 	struct expr *tmp;
@@ -645,9 +699,13 @@ struct expr *expr_transform(struct expr *e)
 		return NULL;
 	switch (e->type) {
 	case E_EQUAL:
+	case E_GEQ:
+	case E_GTH:
+	case E_LEQ:
+	case E_LTH:
 	case E_UNEQUAL:
 	case E_SYMBOL:
-	case E_CHOICE:
+	case E_LIST:
 		break;
 	default:
 		e->left.expr = expr_transform(e->left.expr);
@@ -717,6 +775,22 @@ struct expr *expr_transform(struct expr *e)
 			e = tmp;
 			e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL;
 			break;
+		case E_LEQ:
+		case E_GEQ:
+			// !a<='x' -> a>'x'
+			tmp = e->left.expr;
+			free(e);
+			e = tmp;
+			e->type = e->type == E_LEQ ? E_GTH : E_LTH;
+			break;
+		case E_LTH:
+		case E_GTH:
+			// !a<'x' -> a>='x'
+			tmp = e->left.expr;
+			free(e);
+			e = tmp;
+			e->type = e->type == E_LTH ? E_GEQ : E_LEQ;
+			break;
 		case E_OR:
 			// !(a || b) -> !a && !b
 			tmp = e->left.expr;
@@ -787,6 +861,10 @@ int expr_contains_symbol(struct expr *dep, struct symbol *sym)
 	case E_SYMBOL:
 		return dep->left.sym == sym;
 	case E_EQUAL:
+	case E_GEQ:
+	case E_GTH:
+	case E_LEQ:
+	case E_LTH:
 	case E_UNEQUAL:
 		return dep->left.sym == sym ||
 		       dep->right.sym == sym;
@@ -824,60 +902,23 @@ bool expr_depends_symbol(struct expr *dep, struct symbol *sym)
 	default:
 		;
 	}
-	return false;
-}
-
-struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2)
-{
-	struct expr *tmp = NULL;
-	expr_extract_eq(E_AND, &tmp, ep1, ep2);
-	if (tmp) {
-		*ep1 = expr_eliminate_yn(*ep1);
-		*ep2 = expr_eliminate_yn(*ep2);
-	}
-	return tmp;
-}
-
-struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2)
-{
-	struct expr *tmp = NULL;
-	expr_extract_eq(E_OR, &tmp, ep1, ep2);
-	if (tmp) {
-		*ep1 = expr_eliminate_yn(*ep1);
-		*ep2 = expr_eliminate_yn(*ep2);
-	}
-	return tmp;
-}
-
-void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, \
                struct expr **ep2)
-{
-#define e1 (*ep1)
-#define e2 (*ep2)
-	if (e1->type == type) {
-		expr_extract_eq(type, ep, &e1->left.expr, &e2);
-		expr_extract_eq(type, ep, &e1->right.expr, &e2);
-		return;
-	}
-	if (e2->type == type) {
-		expr_extract_eq(type, ep, ep1, &e2->left.expr);
-		expr_extract_eq(type, ep, ep1, &e2->right.expr);
-		return;
-	}
-	if (expr_eq(e1, e2)) {
-		*ep = *ep ? expr_alloc_two(type, *ep, e1) : e1;
-		expr_free(e2);
-		if (type == E_AND) {
-			e1 = expr_alloc_symbol(&symbol_yes);
-			e2 = expr_alloc_symbol(&symbol_yes);
-		} else if (type == E_OR) {
-			e1 = expr_alloc_symbol(&symbol_no);
-			e2 = expr_alloc_symbol(&symbol_no);
-		}
-	}
-#undef e1
-#undef e2
+ 	return false;
 }
 
+/*
+ * Inserts explicit comparisons of type 'type' to symbol 'sym' into the
+ * expression 'e'.
+ *
+ * Examples transformations for type == E_UNEQUAL, sym == &symbol_no:
+ *
+ *	A              ->  A!=n
+ *	!A             ->  A=n
+ *	A && B         ->  !(A=n || B=n)
+ *	A || B         ->  !(A=n && B=n)
+ *	A && (B || C)  ->  !(A=n || (B=n && C=n))
+ *
+ * Allocates and returns a new expression.
+ */
 struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol \
*sym)  {
 	struct expr *e1, *e2;
@@ -912,6 +953,10 @@ struct expr *expr_trans_compare(struct expr *e, enum expr_type \
type, struct symb  case E_NOT:
 		return expr_trans_compare(e->left.expr, type == E_EQUAL ? E_UNEQUAL : E_EQUAL, \
sym);  case E_UNEQUAL:
+	case E_LTH:
+	case E_LEQ:
+	case E_GTH:
+	case E_GEQ:
 	case E_EQUAL:
 		if (type == E_EQUAL) {
 			if (sym == &symbol_yes)
@@ -931,7 +976,7 @@ struct expr *expr_trans_compare(struct expr *e, enum expr_type \
type, struct symb  break;
 	case E_SYMBOL:
 		return expr_alloc_comp(type, e->left.sym, sym);
-	case E_CHOICE:
+	case E_LIST:
 	case E_RANGE:
 	case E_NONE:
 		/* panic */;
@@ -939,10 +984,56 @@ struct expr *expr_trans_compare(struct expr *e, enum expr_type \
type, struct symb  return NULL;
 }
 
+enum string_value_kind {
+	k_string,
+	k_signed,
+	k_unsigned,
+};
+
+union string_value {
+	unsigned long long u;
+	signed long long s;
+};
+
+static enum string_value_kind expr_parse_string(const char *str,
+						enum symbol_type type,
+						union string_value *val)
+{
+	char *tail;
+	enum string_value_kind kind;
+
+	errno = 0;
+	switch (type) {
+	case S_BOOLEAN:
+	case S_TRISTATE:
+		val->s = !strcmp(str, "n") ? 0 :
+			 !strcmp(str, "m") ? 1 :
+			 !strcmp(str, "y") ? 2 : -1;
+		return k_signed;
+	case S_INT:
+		val->s = strtoll(str, &tail, 10);
+		kind = k_signed;
+		break;
+	case S_HEX:
+		val->u = strtoull(str, &tail, 16);
+		kind = k_unsigned;
+		break;
+	default:
+		val->s = strtoll(str, &tail, 0);
+		kind = k_signed;
+		break;
+	}
+	return !errno && !*tail && tail > str && isxdigit(tail[-1])
+	       ? kind : k_string;
+}
+
 tristate expr_calc_value(struct expr *e)
 {
 	tristate val1, val2;
 	const char *str1, *str2;
+	enum string_value_kind k1 = k_string, k2 = k_string;
+	union string_value lval = {}, rval = {};
+	int res;
 
 	if (!e)
 		return yes;
@@ -954,40 +1045,73 @@ tristate expr_calc_value(struct expr *e)
 	case E_AND:
 		val1 = expr_calc_value(e->left.expr);
 		val2 = expr_calc_value(e->right.expr);
-		return E_AND(val1, val2);
+		return EXPR_AND(val1, val2);
 	case E_OR:
 		val1 = expr_calc_value(e->left.expr);
 		val2 = expr_calc_value(e->right.expr);
-		return E_OR(val1, val2);
+		return EXPR_OR(val1, val2);
 	case E_NOT:
 		val1 = expr_calc_value(e->left.expr);
-		return E_NOT(val1);
+		return EXPR_NOT(val1);
 	case E_EQUAL:
-		sym_calc_value(e->left.sym);
-		sym_calc_value(e->right.sym);
-		str1 = sym_get_string_value(e->left.sym);
-		str2 = sym_get_string_value(e->right.sym);
-		return !strcmp(str1, str2) ? yes : no;
+	case E_GEQ:
+	case E_GTH:
+	case E_LEQ:
+	case E_LTH:
 	case E_UNEQUAL:
-		sym_calc_value(e->left.sym);
-		sym_calc_value(e->right.sym);
-		str1 = sym_get_string_value(e->left.sym);
-		str2 = sym_get_string_value(e->right.sym);
-		return !strcmp(str1, str2) ? no : yes;
+		break;
 	default:
 		printf("expr_calc_value: %d?\n", e->type);
 		return no;
 	}
+
+	sym_calc_value(e->left.sym);
+	sym_calc_value(e->right.sym);
+	str1 = sym_get_string_value(e->left.sym);
+	str2 = sym_get_string_value(e->right.sym);
+
+	if (e->left.sym->type != S_STRING || e->right.sym->type != S_STRING) {
+		k1 = expr_parse_string(str1, e->left.sym->type, &lval);
+		k2 = expr_parse_string(str2, e->right.sym->type, &rval);
+	}
+
+	if (k1 == k_string || k2 == k_string)
+		res = strcmp(str1, str2);
+	else if (k1 == k_unsigned || k2 == k_unsigned)
+		res = (lval.u > rval.u) - (lval.u < rval.u);
+	else /* if (k1 == k_signed && k2 == k_signed) */
+		res = (lval.s > rval.s) - (lval.s < rval.s);
+
+	switch(e->type) {
+	case E_EQUAL:
+		return res ? no : yes;
+	case E_GEQ:
+		return res >= 0 ? yes : no;
+	case E_GTH:
+		return res > 0 ? yes : no;
+	case E_LEQ:
+		return res <= 0 ? yes : no;
+	case E_LTH:
+		return res < 0 ? yes : no;
+	case E_UNEQUAL:
+		return res ? yes : no;
+	default:
+		printf("expr_calc_value: relation %d?\n", e->type);
+		return no;
+	}
 }
 
-int expr_compare_type(enum expr_type t1, enum expr_type t2)
+static int expr_compare_type(enum expr_type t1, enum expr_type t2)
 {
-#if 0
-	return 1;
-#else
 	if (t1 == t2)
 		return 0;
 	switch (t1) {
+	case E_LEQ:
+	case E_LTH:
+	case E_GEQ:
+	case E_GTH:
+		if (t2 == E_EQUAL || t2 == E_UNEQUAL)
+			return 1;
 	case E_EQUAL:
 	case E_UNEQUAL:
 		if (t2 == E_NOT)
@@ -999,9 +1123,9 @@ int expr_compare_type(enum expr_type t1, enum expr_type t2)
 		if (t2 == E_OR)
 			return 1;
 	case E_OR:
-		if (t2 == E_CHOICE)
+		if (t2 == E_LIST)
 			return 1;
-	case E_CHOICE:
+	case E_LIST:
 		if (t2 == 0)
 			return 1;
 	default:
@@ -1009,78 +1133,103 @@ int expr_compare_type(enum expr_type t1, enum expr_type t2)
 	}
 	printf("[%dgt%d?]", t1, t2);
 	return 0;
-#endif
 }
 
-void expr_print(struct expr *e, void (*fn)(void *, const char *), void *data, int \
prevtoken) +void expr_print(struct expr *e,
+		void (*fn)(void *, struct symbol *, const char *),
+		void *data, int prevtoken)
 {
 	if (!e) {
-		fn(data, "y");
+		fn(data, NULL, "y");
 		return;
 	}
 
 	if (expr_compare_type(prevtoken, e->type) > 0)
-		fn(data, "(");
+		fn(data, NULL, "(");
 	switch (e->type) {
 	case E_SYMBOL:
 		if (e->left.sym->name)
-			fn(data, e->left.sym->name);
+			fn(data, e->left.sym, e->left.sym->name);
 		else
-			fn(data, "<choice>");
+			fn(data, NULL, "<choice>");
 		break;
 	case E_NOT:
-		fn(data, "!");
+		fn(data, NULL, "!");
 		expr_print(e->left.expr, fn, data, E_NOT);
 		break;
 	case E_EQUAL:
-		fn(data, e->left.sym->name);
-		fn(data, "=");
-		fn(data, e->right.sym->name);
+		if (e->left.sym->name)
+			fn(data, e->left.sym, e->left.sym->name);
+		else
+			fn(data, NULL, "<choice>");
+		fn(data, NULL, "=");
+		fn(data, e->right.sym, e->right.sym->name);
+		break;
+	case E_LEQ:
+	case E_LTH:
+		if (e->left.sym->name)
+			fn(data, e->left.sym, e->left.sym->name);
+		else
+			fn(data, NULL, "<choice>");
+		fn(data, NULL, e->type == E_LEQ ? "<=" : "<");
+		fn(data, e->right.sym, e->right.sym->name);
+		break;
+	case E_GEQ:
+	case E_GTH:
+		if (e->left.sym->name)
+			fn(data, e->left.sym, e->left.sym->name);
+		else
+			fn(data, NULL, "<choice>");
+		fn(data, NULL, e->type == E_GEQ ? ">=" : ">");
+		fn(data, e->right.sym, e->right.sym->name);
 		break;
 	case E_UNEQUAL:
-		fn(data, e->left.sym->name);
-		fn(data, "!=");
-		fn(data, e->right.sym->name);
+		if (e->left.sym->name)
+			fn(data, e->left.sym, e->left.sym->name);
+		else
+			fn(data, NULL, "<choice>");
+		fn(data, NULL, "!=");
+		fn(data, e->right.sym, e->right.sym->name);
 		break;
 	case E_OR:
 		expr_print(e->left.expr, fn, data, E_OR);
-		fn(data, " || ");
+		fn(data, NULL, " || ");
 		expr_print(e->right.expr, fn, data, E_OR);
 		break;
 	case E_AND:
 		expr_print(e->left.expr, fn, data, E_AND);
-		fn(data, " && ");
+		fn(data, NULL, " && ");
 		expr_print(e->right.expr, fn, data, E_AND);
 		break;
-	case E_CHOICE:
-		fn(data, e->right.sym->name);
+	case E_LIST:
+		fn(data, e->right.sym, e->right.sym->name);
 		if (e->left.expr) {
-			fn(data, " ^ ");
-			expr_print(e->left.expr, fn, data, E_CHOICE);
+			fn(data, NULL, " ^ ");
+			expr_print(e->left.expr, fn, data, E_LIST);
 		}
 		break;
 	case E_RANGE:
-		fn(data, "[");
-		fn(data, e->left.sym->name);
-		fn(data, " ");
-		fn(data, e->right.sym->name);
-		fn(data, "]");
+		fn(data, NULL, "[");
+		fn(data, e->left.sym, e->left.sym->name);
+		fn(data, NULL, " ");
+		fn(data, e->right.sym, e->right.sym->name);
+		fn(data, NULL, "]");
 		break;
 	default:
 	  {
 		char buf[32];
 		sprintf(buf, "<unknown type %d>", e->type);
-		fn(data, buf);
+		fn(data, NULL, buf);
 		break;
 	  }
 	}
 	if (expr_compare_type(prevtoken, e->type) > 0)
-		fn(data, ")");
+		fn(data, NULL, ")");
 }
 
-static void expr_print_file_helper(void *data, const char *str)
+static void expr_print_file_helper(void *data, struct symbol *sym, const char *str)
 {
-	fwrite(str, strlen(str), 1, data);
+	xfwrite(str, strlen(str), 1, data);
 }
 
 void expr_fprint(struct expr *e, FILE *out)
@@ -1088,12 +1237,67 @@ void expr_fprint(struct expr *e, FILE *out)
 	expr_print(e, expr_print_file_helper, out, E_NONE);
 }
 
-static void expr_print_gstr_helper(void *data, const char *str)
+static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *str)
 {
-	str_append((struct gstr*)data, str);
+	struct gstr *gs = (struct gstr*)data;
+	const char *sym_str = NULL;
+
+	if (sym)
+		sym_str = sym_get_string_value(sym);
+
+	if (gs->max_width) {
+		unsigned extra_length = strlen(str);
+		const char *last_cr = strrchr(gs->s, '\n');
+		unsigned last_line_length;
+
+		if (sym_str)
+			extra_length += 4 + strlen(sym_str);
+
+		if (!last_cr)
+			last_cr = gs->s;
+
+		last_line_length = strlen(gs->s) - (last_cr - gs->s);
+
+		if ((last_line_length + extra_length) > gs->max_width)
+			str_append(gs, "\\\n");
+	}
+
+	str_append(gs, str);
+	if (sym && sym->type != S_UNKNOWN)
+		str_printf(gs, " [=%s]", sym_str);
 }
 
 void expr_gstr_print(struct expr *e, struct gstr *gs)
 {
 	expr_print(e, expr_print_gstr_helper, gs, E_NONE);
 }
+
+/*
+ * Transform the top level "||" tokens into newlines and prepend each
+ * line with a minus. This makes expressions much easier to read.
+ * Suitable for reverse dependency expressions.
+ */
+static void expr_print_revdep(struct expr *e,
+			      void (*fn)(void *, struct symbol *, const char *),
+			      void *data, tristate pr_type, const char **title)
+{
+	if (e->type == E_OR) {
+		expr_print_revdep(e->left.expr, fn, data, pr_type, title);
+		expr_print_revdep(e->right.expr, fn, data, pr_type, title);
+	} else if (expr_calc_value(e) == pr_type) {
+		if (*title) {
+			fn(data, NULL, *title);
+			*title = NULL;
+		}
+
+		fn(data, NULL, "  - ");
+		expr_print(e, fn, data, E_NONE);
+		fn(data, NULL, "\n");
+	}
+}
+
+void expr_gstr_print_revdep(struct expr *e, struct gstr *gs,
+			    tristate pr_type, const char *title)
+{
+	expr_print_revdep(e, expr_print_gstr_helper, gs, pr_type, &title);
+}
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index 1b36ef18c..5c3443692 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -1,6 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
- * Released under the terms of the GNU GPL v2.0.
  */
 
 #ifndef EXPR_H
@@ -10,7 +10,9 @@
 extern "C" {
 #endif
 
+#include <assert.h>
 #include <stdio.h>
+#include "list.h"
 #ifndef __cplusplus
 #include <stdbool.h>
 #endif
@@ -18,21 +20,18 @@ extern "C" {
 struct file {
 	struct file *next;
 	struct file *parent;
-	char *name;
+	const char *name;
 	int lineno;
-	int flags;
 };
 
-#define FILE_BUSY		0x0001
-#define FILE_SCANNED		0x0002
-#define FILE_PRINTED		0x0004
-
 typedef enum tristate {
 	no, mod, yes
 } tristate;
 
 enum expr_type {
-	E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_CHOICE, E_SYMBOL, E_RANGE
+	E_NONE, E_OR, E_AND, E_NOT,
+	E_EQUAL, E_UNEQUAL, E_LTH, E_LEQ, E_GTH, E_GEQ,
+	E_LIST, E_SYMBOL, E_RANGE
 };
 
 union expr_data {
@@ -45,9 +44,12 @@ struct expr {
 	union expr_data left, right;
 };
 
-#define E_OR(dep1, dep2)	(((dep1)>(dep2))?(dep1):(dep2))
-#define E_AND(dep1, dep2)	(((dep1)<(dep2))?(dep1):(dep2))
-#define E_NOT(dep)		(2-(dep))
+#define EXPR_OR(dep1, dep2)	(((dep1)>(dep2))?(dep1):(dep2))
+#define EXPR_AND(dep1, dep2)	(((dep1)<(dep2))?(dep1):(dep2))
+#define EXPR_NOT(dep)		(2-(dep))
+
+#define expr_list_for_each_sym(l, e, s) \
+	for (e = (l); e && (s = e->right.sym); e = e->left.expr)
 
 struct expr_value {
 	struct expr *expr;
@@ -60,59 +62,144 @@ struct symbol_value {
 };
 
 enum symbol_type {
-	S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER
+	S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING
 };
 
+/* enum values are used as index to symbol.def[] */
+enum {
+	S_DEF_USER,		/* main user value */
+	S_DEF_AUTO,		/* values read from auto.conf */
+	S_DEF_DEF3,		/* Reserved for UI usage */
+	S_DEF_DEF4,		/* Reserved for UI usage */
+	S_DEF_COUNT
+};
+
+/*
+ * Represents a configuration symbol.
+ *
+ * Choices are represented as a special kind of symbol and have the
+ * SYMBOL_CHOICE bit set in 'flags'.
+ */
 struct symbol {
+	/* The next symbol in the same bucket in the symbol hash table */
 	struct symbol *next;
+
+	/* The name of the symbol, e.g. "FOO" for 'config FOO' */
 	char *name;
-	char *help;
+
+	/* S_BOOLEAN, S_TRISTATE, ... */
 	enum symbol_type type;
-	struct symbol_value curr, user;
+
+	/*
+	 * The calculated value of the symbol. The SYMBOL_VALID bit is set in
+	 * 'flags' when this is up to date. Note that this value might differ
+	 * from the user value set in e.g. a .config file, due to visibility.
+	 */
+	struct symbol_value curr;
+
+	/*
+	 * Values for the symbol provided from outside. def[S_DEF_USER] holds
+	 * the .config value.
+	 */
+	struct symbol_value def[S_DEF_COUNT];
+
+	/*
+	 * An upper bound on the tristate value the user can set for the symbol
+	 * if it is a boolean or tristate. Calculated from prompt dependencies,
+	 * which also inherit dependencies from enclosing menus, choices, and
+	 * ifs. If 'n', the user value will be ignored.
+	 *
+	 * Symbols lacking prompts always have visibility 'n'.
+	 */
 	tristate visible;
+
+	/* SYMBOL_* flags */
 	int flags;
+
+	/* List of properties. See prop_type. */
 	struct property *prop;
-	struct expr *dep, *dep2;
+
+	/* Dependencies from enclosing menus, choices, and ifs */
+	struct expr_value dir_dep;
+
+	/* Reverse dependencies through being selected by other symbols */
 	struct expr_value rev_dep;
+
+	/*
+	 * "Weak" reverse dependencies through being implied by other symbols
+	 */
+	struct expr_value implied;
 };
 
-#define for_all_symbols(i, sym) for (i = 0; i < 257; i++) for (sym = symbol_hash[i]; \
                sym; sym = sym->next) if (sym->type != S_OTHER)
-
-#define SYMBOL_YES		0x0001
-#define SYMBOL_MOD		0x0002
-#define SYMBOL_NO		0x0004
-#define SYMBOL_CONST		0x0007
-#define SYMBOL_CHECK		0x0008
-#define SYMBOL_CHOICE		0x0010
-#define SYMBOL_CHOICEVAL	0x0020
-#define SYMBOL_PRINTED		0x0040
-#define SYMBOL_VALID		0x0080
-#define SYMBOL_OPTIONAL		0x0100
-#define SYMBOL_WRITE		0x0200
-#define SYMBOL_CHANGED		0x0400
-#define SYMBOL_NEW		0x0800
-#define SYMBOL_AUTO		0x1000
-#define SYMBOL_CHECKED		0x2000
-#define SYMBOL_WARNED		0x8000
+#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) */
+#define SYMBOL_CHOICEVAL  0x0020  /* used as a value in a choice block */
+#define SYMBOL_VALID      0x0080  /* set when symbol.curr is calculated */
+#define SYMBOL_OPTIONAL   0x0100  /* choice is optional - values can be 'n' */
+#define SYMBOL_WRITE      0x0200  /* write symbol to file (KCONFIG_CONFIG) */
+#define SYMBOL_CHANGED    0x0400  /* ? */
+#define SYMBOL_WRITTEN    0x0800  /* track info to avoid double-write to .config */
+#define SYMBOL_NO_WRITE   0x1000  /* Symbol for internal use only; it will not be \
written */ +#define SYMBOL_CHECKED    0x2000  /* used during dependency checking */
+#define SYMBOL_WARNED     0x8000  /* warning has been issued */
+
+/* Set when symbol.def[] is used */
+#define SYMBOL_DEF        0x10000  /* First bit of SYMBOL_DEF */
+#define SYMBOL_DEF_USER   0x10000  /* symbol.def[S_DEF_USER] is valid */
+#define SYMBOL_DEF_AUTO   0x20000  /* symbol.def[S_DEF_AUTO] is valid */
+#define SYMBOL_DEF3       0x40000  /* symbol.def[S_DEF_3] is valid */
+#define SYMBOL_DEF4       0x80000  /* symbol.def[S_DEF_4] is valid */
+
+/* choice values need to be set before calculating this symbol value */
+#define SYMBOL_NEED_SET_CHOICE_VALUES  0x100000
+
+/* Set symbol to y if allnoconfig; used for symbols that hide others */
+#define SYMBOL_ALLNOCONFIG_Y 0x200000
 
 #define SYMBOL_MAXLENGTH	256
-#define SYMBOL_HASHSIZE		257
-#define SYMBOL_HASHMASK		0xff
+#define SYMBOL_HASHSIZE		9973
 
+/* A property represent the config options that can be associated
+ * with a config "symbol".
+ * Sample:
+ * config FOO
+ *         default y
+ *         prompt "foo prompt"
+ *         select BAR
+ * config BAZ
+ *         int "BAZ Value"
+ *         range 1..255
+ *
+ * Please, also check parser.y:print_symbol() when modifying the
+ * list of property types!
+ */
 enum prop_type {
-	P_UNKNOWN, P_PROMPT, P_COMMENT, P_MENU, P_DEFAULT, P_CHOICE, P_SELECT, P_RANGE
+	P_UNKNOWN,
+	P_PROMPT,   /* prompt "foo prompt" or "BAZ Value" */
+	P_COMMENT,  /* text associated with a comment */
+	P_MENU,     /* prompt associated with a menu or menuconfig symbol */
+	P_DEFAULT,  /* default y */
+	P_CHOICE,   /* choice value */
+	P_SELECT,   /* select BAR */
+	P_IMPLY,    /* imply BAR */
+	P_RANGE,    /* range 7..100 (for a symbol) */
+	P_SYMBOL,   /* where a symbol is defined */
 };
 
 struct property {
-	struct property *next;
-	struct symbol *sym;
-	enum prop_type type;
-	const char *text;
+	struct property *next;     /* next property - null if last */
+	enum prop_type type;       /* type of property */
+	const char *text;          /* the prompt value - P_PROMPT, P_MENU, P_COMMENT */
 	struct expr_value visible;
-	struct expr *expr;
-	struct menu *menu;
-	struct file *file;
-	int lineno;
+	struct expr *expr;         /* the optional conditional part of the 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 */
+	int lineno;                /* what lineno was this property defined */
 };
 
 #define for_all_properties(sym, st, tok) \
@@ -124,24 +211,77 @@ struct property {
 	for (st = sym->prop; st; st = st->next) \
 		if (st->text)
 
+/*
+ * Represents a node in the menu tree, as seen in e.g. menuconfig (though used
+ * for all front ends). Each symbol, menu, etc. defined in the Kconfig files
+ * gets a node. A symbol defined in multiple locations gets one node at each
+ * location.
+ */
 struct menu {
+	/* The next menu node at the same level */
 	struct menu *next;
+
+	/* The parent menu node, corresponding to e.g. a menu or choice */
 	struct menu *parent;
+
+	/* The first child menu node, for e.g. menus and choices */
 	struct menu *list;
+
+	/*
+	 * The symbol associated with the menu node. Choices are implemented as
+	 * a special kind of symbol. NULL for menus, comments, and ifs.
+	 */
 	struct symbol *sym;
+
+	/*
+	 * The prompt associated with the node. This holds the prompt for a
+	 * symbol as well as the text for a menu or comment, along with the
+	 * type (P_PROMPT, P_MENU, etc.)
+	 */
 	struct property *prompt;
+
+	/*
+	 * 'visible if' dependencies. If more than one is given, they will be
+	 * ANDed together.
+	 */
+	struct expr *visibility;
+
+	/*
+	 * Ordinary dependencies from e.g. 'depends on' and 'if', ANDed
+	 * together
+	 */
 	struct expr *dep;
+
+	/* MENU_* flags */
 	unsigned int flags;
-	//char *help;
+
+	/* Any help text associated with the node */
+	char *help;
+
+	/* The location where the menu node appears in the Kconfig files */
 	struct file *file;
 	int lineno;
+
+	/* For use by front ends that need to store auxiliary data */
 	void *data;
 };
 
+/*
+ * Set on a menu node when the corresponding symbol changes state in some way.
+ * Can be checked by front ends.
+ */
 #define MENU_CHANGED		0x0001
+
 #define MENU_ROOT		0x0002
 
-#ifndef SWIG
+struct jump_key {
+	struct list_head entries;
+	size_t offset;
+	struct menu *target;
+	int index;
+};
+
+#define JUMP_NB			9
 
 extern struct file *file_list;
 extern struct file *current_file;
@@ -149,6 +289,7 @@ struct file *lookup_file(const char *name);
 
 extern struct symbol symbol_yes, symbol_no, symbol_mod;
 extern struct symbol *modules_sym;
+extern struct symbol *sym_defconfig_list;
 extern int cdebug;
 struct expr *expr_alloc_symbol(struct symbol *sym);
 struct expr *expr_alloc_one(enum expr_type type, struct expr *ce);
@@ -156,25 +297,23 @@ struct expr *expr_alloc_two(enum expr_type type, struct expr \
*e1, struct expr *e  struct expr *expr_alloc_comp(enum expr_type type, struct symbol \
*s1, struct symbol *s2);  struct expr *expr_alloc_and(struct expr *e1, struct expr \
*e2);  struct expr *expr_alloc_or(struct expr *e1, struct expr *e2);
-struct expr *expr_copy(struct expr *org);
+struct expr *expr_copy(const struct expr *org);
 void expr_free(struct expr *e);
-int expr_eq(struct expr *e1, struct expr *e2);
 void expr_eliminate_eq(struct expr **ep1, struct expr **ep2);
+int expr_eq(struct expr *e1, struct expr *e2);
 tristate expr_calc_value(struct expr *e);
-struct expr *expr_eliminate_yn(struct expr *e);
 struct expr *expr_trans_bool(struct expr *e);
 struct expr *expr_eliminate_dups(struct expr *e);
 struct expr *expr_transform(struct expr *e);
 int expr_contains_symbol(struct expr *dep, struct symbol *sym);
 bool expr_depends_symbol(struct expr *dep, struct symbol *sym);
-struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2);
-struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2);
-void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, \
struct expr **ep2);  struct expr *expr_trans_compare(struct expr *e, enum expr_type \
type, struct symbol *sym);  
 void expr_fprint(struct expr *e, FILE *out);
 struct gstr; /* forward */
 void expr_gstr_print(struct expr *e, struct gstr *gs);
+void expr_gstr_print_revdep(struct expr *e, struct gstr *gs,
+			    tristate pr_type, const char *title);
 
 static inline int expr_is_yes(struct expr *e)
 {
@@ -185,7 +324,6 @@ static inline int expr_is_no(struct expr *e)
 {
 	return e && (e->type == E_SYMBOL && e->left.sym == &symbol_no);
 }
-#endif
 
 #ifdef __cplusplus
 }
diff --git a/scripts/kconfig/gconf-cfg.sh b/scripts/kconfig/gconf-cfg.sh
new file mode 100755
index 000000000..480ecd8b9
--- /dev/null
+++ b/scripts/kconfig/gconf-cfg.sh
@@ -0,0 +1,30 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+
+PKG="gtk+-2.0 gmodule-2.0 libglade-2.0"
+
+if [ -z "$(command -v pkg-config)" ]; then
+	echo >&2 "*"
+	echo >&2 "* 'make gconfig' requires 'pkg-config'. Please install it."
+	echo >&2 "*"
+	exit 1
+fi
+
+if ! pkg-config --exists $PKG; then
+	echo >&2 "*"
+	echo >&2 "* Unable to find the GTK+ installation. Please make sure that"
+	echo >&2 "* the GTK+ 2.0 development package is correctly installed."
+	echo >&2 "* You need $PKG"
+	echo >&2 "*"
+	exit 1
+fi
+
+if ! pkg-config --atleast-version=2.0.0 gtk+-2.0; then
+	echo >&2 "*"
+	echo >&2 "* GTK+ is present but version >= 2.0.0 is required."
+	echo >&2 "*"
+	exit 1
+fi
+
+echo cflags=\"$(pkg-config --cflags $PKG)\"
+echo libs=\"$(pkg-config --libs $PKG)\"
diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c
index 9bab17d91..5527482c3 100644
--- a/scripts/kconfig/gconf.c
+++ b/scripts/kconfig/gconf.c
@@ -1,17 +1,15 @@
-/* Hey EMACS -*- linux-c -*- */
+// SPDX-License-Identifier: GPL-2.0
 /*
- *
  * Copyright (C) 2002-2003 Romain Lievin <roms@tilp.info>
- * Released under the terms of the GNU GPL v2.0.
- *
  */
 
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
 #endif
 
+#include <stdlib.h>
 #include "lkc.h"
-#include "images.c"
+#include "images.h"
 
 #include <glade/glade.h>
 #include <gtk/gtk.h>
@@ -20,9 +18,9 @@
 
 #include <stdio.h>
 #include <string.h>
+#include <strings.h>
 #include <unistd.h>
 #include <time.h>
-#include <stdlib.h>
 
 //#define DEBUG
 
@@ -30,18 +28,16 @@ enum {
 	SINGLE_VIEW, SPLIT_VIEW, FULL_VIEW
 };
 
+enum {
+	OPT_NORMAL, OPT_ALL, OPT_PROMPT
+};
+
 static gint view_mode = FULL_VIEW;
 static gboolean show_name = TRUE;
 static gboolean show_range = TRUE;
 static gboolean show_value = TRUE;
-static gboolean show_all = FALSE;
-static gboolean show_debug = FALSE;
 static gboolean resizeable = FALSE;
-
-static gboolean config_changed = FALSE;
-
-static char nohelp_text[] =
-    N_("Sorry, no help available for this option yet.\n");
+static int opt_mode = OPT_NORMAL;
 
 GtkWidget *main_wnd = NULL;
 GtkWidget *tree1_w = NULL;	// left  frame
@@ -50,6 +46,8 @@ GtkWidget *text_w = NULL;
 GtkWidget *hpaned = NULL;
 GtkWidget *vpaned = NULL;
 GtkWidget *back_btn = NULL;
+GtkWidget *save_btn = NULL;
+GtkWidget *save_menu_item = NULL;
 
 GtkTextTag *tag1, *tag2;
 GdkColor color;
@@ -75,51 +73,16 @@ static void display_tree_part(void);
 static void update_tree(struct menu *src, GtkTreeIter * dst);
 static void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row);
 static gchar **fill_row(struct menu *menu);
-
+static void conf_changed(void);
 
 /* Helping/Debugging Functions */
-
-
-const char *dbg_print_stype(int val)
-{
-	static char buf[256];
-
-	memset(buf, 0, 256);
-
-	if (val == S_UNKNOWN)
-		strcpy(buf, "unknown");
-	if (val == S_BOOLEAN)
-		strcpy(buf, "boolean");
-	if (val == S_TRISTATE)
-		strcpy(buf, "tristate");
-	if (val == S_INT)
-		strcpy(buf, "int");
-	if (val == S_HEX)
-		strcpy(buf, "hex");
-	if (val == S_STRING)
-		strcpy(buf, "string");
-	if (val == S_OTHER)
-		strcpy(buf, "other");
-
 #ifdef DEBUG
-	printf("%s", buf);
-#endif
-
-	return buf;
-}
-
-const char *dbg_print_flags(int val)
+static const char *dbg_sym_flags(int val)
 {
 	static char buf[256];
 
-	memset(buf, 0, 256);
+	bzero(buf, 256);
 
-	if (val & SYMBOL_YES)
-		strcat(buf, "yes/");
-	if (val & SYMBOL_MOD)
-		strcat(buf, "mod/");
-	if (val & SYMBOL_NO)
-		strcat(buf, "no/");
 	if (val & SYMBOL_CONST)
 		strcat(buf, "const/");
 	if (val & SYMBOL_CHECK)
@@ -128,8 +91,6 @@ const char *dbg_print_flags(int val)
 		strcat(buf, "choice/");
 	if (val & SYMBOL_CHOICEVAL)
 		strcat(buf, "choiceval/");
-	if (val & SYMBOL_PRINTED)
-		strcat(buf, "printed/");
 	if (val & SYMBOL_VALID)
 		strcat(buf, "valid/");
 	if (val & SYMBOL_OPTIONAL)
@@ -138,48 +99,17 @@ const char *dbg_print_flags(int val)
 		strcat(buf, "write/");
 	if (val & SYMBOL_CHANGED)
 		strcat(buf, "changed/");
-	if (val & SYMBOL_NEW)
-		strcat(buf, "new/");
-	if (val & SYMBOL_AUTO)
-		strcat(buf, "auto/");
+	if (val & SYMBOL_NO_WRITE)
+		strcat(buf, "no_write/");
 
 	buf[strlen(buf) - 1] = '\0';
-#ifdef DEBUG
-	printf("%s", buf);
-#endif
 
 	return buf;
 }
-
-const char *dbg_print_ptype(int val)
-{
-	static char buf[256];
-
-	memset(buf, 0, 256);
-
-	if (val == P_UNKNOWN)
-		strcpy(buf, "unknown");
-	if (val == P_PROMPT)
-		strcpy(buf, "prompt");
-	if (val == P_COMMENT)
-		strcpy(buf, "comment");
-	if (val == P_MENU)
-		strcpy(buf, "menu");
-	if (val == P_DEFAULT)
-		strcpy(buf, "default");
-	if (val == P_CHOICE)
-		strcpy(buf, "choice");
-
-#ifdef DEBUG
-	printf("%s", buf);
 #endif
 
-	return buf;
-}
-
-
-void replace_button_icon(GladeXML * xml, GdkDrawable * window,
-			 GtkStyle * style, gchar * btn_name, gchar ** xpm)
+static void replace_button_icon(GladeXML *xml, GdkDrawable *window,
+				GtkStyle *style, gchar *btn_name, gchar **xpm)
 {
 	GdkPixmap *pixmap;
 	GdkBitmap *mask;
@@ -197,17 +127,16 @@ void replace_button_icon(GladeXML * xml, GdkDrawable * window,
 }
 
 /* Main Window Initialization */
-void init_main_window(const gchar * glade_file)
+static void init_main_window(const gchar *glade_file)
 {
 	GladeXML *xml;
 	GtkWidget *widget;
 	GtkTextBuffer *txtbuf;
-	char title[256];
 	GtkStyle *style;
 
 	xml = glade_xml_new(glade_file, "window1", NULL);
 	if (!xml)
-		g_error(_("GUI loading failed !\n"));
+		g_error("GUI loading failed !\n");
 	glade_xml_signal_autoconnect(xml);
 
 	main_wnd = glade_xml_get_widget(xml, "window1");
@@ -232,17 +161,13 @@ void init_main_window(const gchar * glade_file)
 	gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget,
 				       show_value);
 
+	save_btn = glade_xml_get_widget(xml, "button3");
+	save_menu_item = glade_xml_get_widget(xml, "save1");
+	conf_set_changed_callback(conf_changed);
+
 	style = gtk_widget_get_style(main_wnd);
 	widget = glade_xml_get_widget(xml, "toolbar1");
 
-#if 0	/* Use stock Gtk icons instead */
-	replace_button_icon(xml, main_wnd->window, style,
-			    "button1", (gchar **) xpm_back);
-	replace_button_icon(xml, main_wnd->window, style,
-			    "button2", (gchar **) xpm_load);
-	replace_button_icon(xml, main_wnd->window, style,
-			    "button3", (gchar **) xpm_save);
-#endif
 	replace_button_icon(xml, main_wnd->window, style,
 			    "button4", (gchar **) xpm_single_view);
 	replace_button_icon(xml, main_wnd->window, style,
@@ -250,22 +175,6 @@ void init_main_window(const gchar * glade_file)
 	replace_button_icon(xml, main_wnd->window, style,
 			    "button6", (gchar **) xpm_tree_view);
 
-#if 0
-	switch (view_mode) {
-	case SINGLE_VIEW:
-		widget = glade_xml_get_widget(xml, "button4");
-		g_signal_emit_by_name(widget, "clicked");
-		break;
-	case SPLIT_VIEW:
-		widget = glade_xml_get_widget(xml, "button5");
-		g_signal_emit_by_name(widget, "clicked");
-		break;
-	case FULL_VIEW:
-		widget = glade_xml_get_widget(xml, "button6");
-		g_signal_emit_by_name(widget, "clicked");
-		break;
-	}
-#endif
 	txtbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w));
 	tag1 = gtk_text_buffer_create_tag(txtbuf, "mytag1",
 					  "foreground", "red",
@@ -275,14 +184,12 @@ void init_main_window(const gchar * glade_file)
 					  /*"style", PANGO_STYLE_OBLIQUE, */
 					  NULL);
 
-	sprintf(title, _("BusyBox %s Configuration"),
-		getenv("KERNELVERSION"));
-	gtk_window_set_title(GTK_WINDOW(main_wnd), title);
+	gtk_window_set_title(GTK_WINDOW(main_wnd), rootmenu.prompt->text);
 
 	gtk_widget_show(main_wnd);
 }
 
-void init_tree_model(void)
+static void init_tree_model(void)
 {
 	gint i;
 
@@ -312,7 +219,7 @@ void init_tree_model(void)
 	model1 = GTK_TREE_MODEL(tree1);
 }
 
-void init_left_tree(void)
+static void init_left_tree(void)
 {
 	GtkTreeView *view = GTK_TREE_VIEW(tree1_w);
 	GtkCellRenderer *renderer;
@@ -321,11 +228,11 @@ void init_left_tree(void)
 
 	gtk_tree_view_set_model(view, model1);
 	gtk_tree_view_set_headers_visible(view, TRUE);
-	gtk_tree_view_set_rules_hint(view, FALSE);
+	gtk_tree_view_set_rules_hint(view, TRUE);
 
 	column = gtk_tree_view_column_new();
 	gtk_tree_view_append_column(view, column);
-	gtk_tree_view_column_set_title(column, _("Options"));
+	gtk_tree_view_column_set_title(column, "Options");
 
 	renderer = gtk_cell_renderer_toggle_new();
 	gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
@@ -353,10 +260,8 @@ void init_left_tree(void)
 static void renderer_edited(GtkCellRendererText * cell,
 			    const gchar * path_string,
 			    const gchar * new_text, gpointer user_data);
-static void renderer_toggled(GtkCellRendererToggle * cellrenderertoggle,
-			     gchar * arg1, gpointer user_data);
 
-void init_right_tree(void)
+static void init_right_tree(void)
 {
 	GtkTreeView *view = GTK_TREE_VIEW(tree2_w);
 	GtkCellRenderer *renderer;
@@ -366,11 +271,11 @@ void init_right_tree(void)
 
 	gtk_tree_view_set_model(view, model2);
 	gtk_tree_view_set_headers_visible(view, TRUE);
-	gtk_tree_view_set_rules_hint(view, FALSE);
+	gtk_tree_view_set_rules_hint(view, TRUE);
 
 	column = gtk_tree_view_column_new();
 	gtk_tree_view_append_column(view, column);
-	gtk_tree_view_column_set_title(column, _("Options"));
+	gtk_tree_view_column_set_title(column, "Options");
 
 	renderer = gtk_cell_renderer_pixbuf_new();
 	gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
@@ -388,8 +293,6 @@ void init_right_tree(void)
 					    "inconsistent", COL_BTNINC,
 					    "visible", COL_BTNVIS,
 					    "radio", COL_BTNRAD, NULL);
-	/*g_signal_connect(G_OBJECT(renderer), "toggled",
-	   G_CALLBACK(renderer_toggled), NULL); */
 	renderer = gtk_cell_renderer_text_new();
 	gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
 					renderer, FALSE);
@@ -401,7 +304,7 @@ void init_right_tree(void)
 
 	renderer = gtk_cell_renderer_text_new();
 	gtk_tree_view_insert_column_with_attributes(view, -1,
-						    _("Name"), renderer,
+						    "Name", renderer,
 						    "text", COL_NAME,
 						    "foreground-gdk",
 						    COL_COLOR, NULL);
@@ -425,7 +328,7 @@ void init_right_tree(void)
 						    COL_COLOR, NULL);
 	renderer = gtk_cell_renderer_text_new();
 	gtk_tree_view_insert_column_with_attributes(view, -1,
-						    _("Value"), renderer,
+						    "Value", renderer,
 						    "text", COL_VALUE,
 						    "editable",
 						    COL_EDIT,
@@ -465,18 +368,9 @@ static void text_insert_help(struct menu *menu)
 	GtkTextBuffer *buffer;
 	GtkTextIter start, end;
 	const char *prompt = menu_get_prompt(menu);
-	gchar *name;
-	const char *help = _(nohelp_text);
+	struct gstr help = str_new();
 
-	if (!menu->sym)
-		help = "";
-	else if (menu->sym->help)
-		help = _(menu->sym->help);
-
-	if (menu->sym && menu->sym->name)
-		name = g_strdup_printf(_(menu->sym->name));
-	else
-		name = g_strdup("");
+	menu_get_ext_help(menu, &help);
 
 	buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w));
 	gtk_text_buffer_get_bounds(buffer, &start, &end);
@@ -486,14 +380,11 @@ static void text_insert_help(struct menu *menu)
 	gtk_text_buffer_get_end_iter(buffer, &end);
 	gtk_text_buffer_insert_with_tags(buffer, &end, prompt, -1, tag1,
 					 NULL);
-	gtk_text_buffer_insert_at_cursor(buffer, " ", 1);
-	gtk_text_buffer_get_end_iter(buffer, &end);
-	gtk_text_buffer_insert_with_tags(buffer, &end, name, -1, tag1,
-					 NULL);
 	gtk_text_buffer_insert_at_cursor(buffer, "\n\n", 2);
 	gtk_text_buffer_get_end_iter(buffer, &end);
-	gtk_text_buffer_insert_with_tags(buffer, &end, help, -1, tag2,
+	gtk_text_buffer_insert_with_tags(buffer, &end, str_get(&help), -1, tag2,
 					 NULL);
+	str_free(&help);
 }
 
 
@@ -520,17 +411,17 @@ static void text_insert_msg(const char *title, const char \
*message)  
 /* Main Windows Callbacks */
 
-void on_save1_activate(GtkMenuItem * menuitem, gpointer user_data);
+void on_save_activate(GtkMenuItem * menuitem, gpointer user_data);
 gboolean on_window1_delete_event(GtkWidget * widget, GdkEvent * event,
 				 gpointer user_data)
 {
 	GtkWidget *dialog, *label;
 	gint result;
 
-	if (config_changed == FALSE)
+	if (!conf_get_changed())
 		return FALSE;
 
-	dialog = gtk_dialog_new_with_buttons(_("Warning !"),
+	dialog = gtk_dialog_new_with_buttons("Warning !",
 					     GTK_WINDOW(main_wnd),
 					     (GtkDialogFlags)
 					     (GTK_DIALOG_MODAL |
@@ -544,14 +435,14 @@ gboolean on_window1_delete_event(GtkWidget * widget, GdkEvent * \
event,  gtk_dialog_set_default_response(GTK_DIALOG(dialog),
 					GTK_RESPONSE_CANCEL);
 
-	label = gtk_label_new(_("\nSave configuration ?\n"));
+	label = gtk_label_new("\nSave configuration ?\n");
 	gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
 	gtk_widget_show(label);
 
 	result = gtk_dialog_run(GTK_DIALOG(dialog));
 	switch (result) {
 	case GTK_RESPONSE_YES:
-		on_save1_activate(NULL, NULL);
+		on_save_activate(NULL, NULL);
 		return FALSE;
 	case GTK_RESPONSE_NO:
 		return FALSE;
@@ -604,7 +495,7 @@ load_filename(GtkFileSelection * file_selector, gpointer \
user_data)  (user_data));
 
 	if (conf_read(fn))
-		text_insert_msg(_("Error"), _("Unable to load configuration !"));
+		text_insert_msg("Error", "Unable to load configuration !");
 	else
 		display_tree(&rootmenu);
 }
@@ -613,7 +504,7 @@ void on_load1_activate(GtkMenuItem * menuitem, gpointer \
user_data)  {
 	GtkWidget *fs;
 
-	fs = gtk_file_selection_new(_("Load file..."));
+	fs = gtk_file_selection_new("Load file...");
 	g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button),
 			 "clicked",
 			 G_CALLBACK(load_filename), (gpointer) fs);
@@ -629,12 +520,11 @@ void on_load1_activate(GtkMenuItem * menuitem, gpointer \
user_data)  }
 
 
-void on_save1_activate(GtkMenuItem * menuitem, gpointer user_data)
+void on_save_activate(GtkMenuItem * menuitem, gpointer user_data)
 {
 	if (conf_write(NULL))
-		text_insert_msg(_("Error"), _("Unable to save configuration !"));
-
-	config_changed = FALSE;
+		text_insert_msg("Error", "Unable to save configuration !");
+	conf_write_autoconf(0);
 }
 
 
@@ -647,7 +537,7 @@ store_filename(GtkFileSelection * file_selector, gpointer \
user_data)  (user_data));
 
 	if (conf_write(fn))
-		text_insert_msg(_("Error"), _("Unable to save configuration !"));
+		text_insert_msg("Error", "Unable to save configuration !");
 
 	gtk_widget_destroy(GTK_WIDGET(user_data));
 }
@@ -656,7 +546,7 @@ void on_save_as1_activate(GtkMenuItem * menuitem, gpointer \
user_data)  {
 	GtkWidget *fs;
 
-	fs = gtk_file_selection_new(_("Save file as..."));
+	fs = gtk_file_selection_new("Save file as...");
 	g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button),
 			 "clicked",
 			 G_CALLBACK(store_filename), (gpointer) fs);
@@ -720,28 +610,37 @@ void on_show_data1_activate(GtkMenuItem * menuitem, gpointer \
user_data)  
 
 void
-on_show_all_options1_activate(GtkMenuItem * menuitem, gpointer user_data)
+on_set_option_mode1_activate(GtkMenuItem *menuitem, gpointer user_data)
 {
-	show_all = GTK_CHECK_MENU_ITEM(menuitem)->active;
+	opt_mode = OPT_NORMAL;
+	gtk_tree_store_clear(tree2);
+	display_tree(&rootmenu);	/* instead of update_tree to speed-up */
+}
 
+
+void
+on_set_option_mode2_activate(GtkMenuItem *menuitem, gpointer user_data)
+{
+	opt_mode = OPT_ALL;
 	gtk_tree_store_clear(tree2);
-	display_tree(&rootmenu);	// instead of update_tree to speed-up
+	display_tree(&rootmenu);	/* instead of update_tree to speed-up */
 }
 
 
 void
-on_show_debug_info1_activate(GtkMenuItem * menuitem, gpointer user_data)
+on_set_option_mode3_activate(GtkMenuItem *menuitem, gpointer user_data)
 {
-	show_debug = GTK_CHECK_MENU_ITEM(menuitem)->active;
-	update_tree(&rootmenu, NULL);
+	opt_mode = OPT_PROMPT;
+	gtk_tree_store_clear(tree2);
+	display_tree(&rootmenu);	/* instead of update_tree to speed-up */
 }
 
 
 void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data)
 {
 	GtkWidget *dialog;
-	const gchar *intro_text = _(
-	    "Welcome to gkc, the GTK+ graphical configuration tool.\n"
+	const gchar *intro_text =
+	    "Welcome to gkc, the GTK+ graphical configuration tool\n"
 	    "For each option, a blank box indicates the feature is disabled, a\n"
 	    "check indicates it is enabled, and a dot indicates that it is to\n"
 	    "be compiled as a module.  Clicking on the box will cycle through the three \
states.\n" @@ -754,13 +653,13 @@ void on_introduction1_activate(GtkMenuItem * \
menuitem, gpointer user_data)  "are interested in, you can still view the help of a \
grayed-out\n"  "option.\n"
 	    "\n"
-	    "Toggling Show Debug Info under the Options menu will show\n"
-	    "the dependencies, which you can then match by examining other options.");
+	    "Toggling Show Debug Info under the Options menu will show \n"
+	    "the dependencies, which you can then match by examining other options.";
 
 	dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
 					GTK_DIALOG_DESTROY_WITH_PARENT,
 					GTK_MESSAGE_INFO,
-					GTK_BUTTONS_CLOSE, intro_text);
+					GTK_BUTTONS_CLOSE, "%s", intro_text);
 	g_signal_connect_swapped(GTK_OBJECT(dialog), "response",
 				 G_CALLBACK(gtk_widget_destroy),
 				 GTK_OBJECT(dialog));
@@ -772,13 +671,13 @@ void on_about1_activate(GtkMenuItem * menuitem, gpointer \
user_data)  {
 	GtkWidget *dialog;
 	const gchar *about_text =
-	    _("gkc is copyright (c) 2002 Romain Lievin <roms@lpg.ticalc.org>.\n"
-	      "Based on the source code from Roman Zippel.\n");
+	    "gkc is copyright (c) 2002 Romain Lievin <roms@lpg.ticalc.org>.\n"
+	      "Based on the source code from Roman Zippel.\n";
 
 	dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
 					GTK_DIALOG_DESTROY_WITH_PARENT,
 					GTK_MESSAGE_INFO,
-					GTK_BUTTONS_CLOSE, about_text);
+					GTK_BUTTONS_CLOSE, "%s", about_text);
 	g_signal_connect_swapped(GTK_OBJECT(dialog), "response",
 				 G_CALLBACK(gtk_widget_destroy),
 				 GTK_OBJECT(dialog));
@@ -790,14 +689,14 @@ void on_license1_activate(GtkMenuItem * menuitem, gpointer \
user_data)  {
 	GtkWidget *dialog;
 	const gchar *license_text =
-	    _("gkc is released under the terms of the GNU GPL v2.\n"
+	    "gkc is released under the terms of the GNU GPL v2.\n"
 	      "For more information, please see the source code or\n"
-	      "visit http://www.fsf.org/licenses/licenses.html\n");
+	      "visit http://www.fsf.org/licenses/licenses.html\n";
 
 	dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
 					GTK_DIALOG_DESTROY_WITH_PARENT,
 					GTK_MESSAGE_INFO,
-					GTK_BUTTONS_CLOSE, license_text);
+					GTK_BUTTONS_CLOSE, "%s", license_text);
 	g_signal_connect_swapped(GTK_OBJECT(dialog), "response",
 				 G_CALLBACK(gtk_widget_destroy),
 				 GTK_OBJECT(dialog));
@@ -826,16 +725,9 @@ void on_load_clicked(GtkButton * button, gpointer user_data)
 }
 
 
-void on_save_clicked(GtkButton * button, gpointer user_data)
-{
-	on_save1_activate(NULL, user_data);
-}
-
-
 void on_single_clicked(GtkButton * button, gpointer user_data)
 {
 	view_mode = SINGLE_VIEW;
-	gtk_paned_set_position(GTK_PANED(hpaned), 0);
 	gtk_widget_hide(tree1_w);
 	current = &rootmenu;
 	display_tree_part();
@@ -861,7 +753,6 @@ void on_split_clicked(GtkButton * button, gpointer user_data)
 void on_full_clicked(GtkButton * button, gpointer user_data)
 {
 	view_mode = FULL_VIEW;
-	gtk_paned_set_position(GTK_PANED(hpaned), 0);
 	gtk_widget_hide(tree1_w);
 	if (tree2)
 		gtk_tree_store_clear(tree2);
@@ -906,7 +797,6 @@ static void renderer_edited(GtkCellRendererText * cell,
 
 	sym_set_string_value(sym, new_def);
 
-	config_changed = TRUE;
 	update_tree(&rootmenu, NULL);
 
 	gtk_tree_path_free(path);
@@ -916,7 +806,7 @@ static void renderer_edited(GtkCellRendererText * cell,
 static void change_sym_value(struct menu *menu, gint col)
 {
 	struct symbol *sym = menu->sym;
-	tristate oldval, newval;
+	tristate newval;
 
 	if (!sym)
 		return;
@@ -933,11 +823,9 @@ static void change_sym_value(struct menu *menu, gint col)
 	switch (sym_get_type(sym)) {
 	case S_BOOLEAN:
 	case S_TRISTATE:
-		oldval = sym_get_tristate_value(sym);
 		if (!sym_tristate_within_range(sym, newval))
 			newval = yes;
 		sym_set_tristate_value(sym, newval);
-		config_changed = TRUE;
 		if (view_mode == FULL_VIEW)
 			update_tree(&rootmenu, NULL);
 		else if (view_mode == SPLIT_VIEW) {
@@ -971,35 +859,6 @@ static void toggle_sym_value(struct menu *menu)
 		display_tree_part();	//fixme: keep exp/coll
 }
 
-static void renderer_toggled(GtkCellRendererToggle * cell,
-			     gchar * path_string, gpointer user_data)
-{
-	GtkTreePath *path, *sel_path = NULL;
-	GtkTreeIter iter, sel_iter;
-	GtkTreeSelection *sel;
-	struct menu *menu;
-
-	path = gtk_tree_path_new_from_string(path_string);
-	if (!gtk_tree_model_get_iter(model2, &iter, path))
-		return;
-
-	sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree2_w));
-	if (gtk_tree_selection_get_selected(sel, NULL, &sel_iter))
-		sel_path = gtk_tree_model_get_path(model2, &sel_iter);
-	if (!sel_path)
-		goto out1;
-	if (gtk_tree_path_compare(path, sel_path))
-		goto out2;
-
-	gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
-	toggle_sym_value(menu);
-
-      out2:
-	gtk_tree_path_free(sel_path);
-      out1:
-	gtk_tree_path_free(path);
-}
-
 static gint column2index(GtkTreeViewColumn * column)
 {
 	gint i;
@@ -1055,7 +914,7 @@ on_treeview2_button_press_event(GtkWidget * widget,
 			current = menu;
 			display_tree_part();
 			gtk_widget_set_sensitive(back_btn, TRUE);
-		} else if ((col == COL_OPTION)) {
+		} else if (col == COL_OPTION) {
 			toggle_sym_value(menu);
 			gtk_tree_view_expand_row(view, path, TRUE);
 		}
@@ -1187,15 +1046,16 @@ static gchar **fill_row(struct menu *menu)
 
 	for (i = COL_OPTION; i <= COL_COLOR; i++)
 		g_free(row[i]);
-	memset(row, 0, sizeof(row));
+	bzero(row, sizeof(row));
 
 	row[COL_OPTION] =
 	    g_strdup_printf("%s %s", menu_get_prompt(menu),
-			    sym ? (sym->
-				   flags & SYMBOL_NEW ? "(NEW)" : "") :
-			    "");
+			    sym && !sym_has_value(sym) ? "(NEW)" : "");
 
-	if (show_all && !menu_is_visible(menu))
+	if (opt_mode == OPT_ALL && !menu_is_visible(menu))
+		row[COL_COLOR] = g_strdup("DarkGray");
+	else if (opt_mode == OPT_PROMPT &&
+			menu_has_prompt(menu) && !menu_is_visible(menu))
 		row[COL_COLOR] = g_strdup("DarkGray");
 	else
 		row[COL_COLOR] = g_strdup("Black");
@@ -1254,6 +1114,7 @@ static gchar **fill_row(struct menu *menu)
 			row[COL_BTNVIS] = GINT_TO_POINTER(TRUE);
 		if (sym_is_choice(sym))
 			break;
+		/* fall through */
 	case S_TRISTATE:
 		val = sym_get_tristate_value(sym);
 		switch (val) {
@@ -1350,8 +1211,8 @@ static GtkTreeIter found;
 /*
  * Find a menu in the GtkTree starting at parent.
  */
-GtkTreeIter *gtktree_iter_find_node(GtkTreeIter * parent,
-				    struct menu *tofind)
+static GtkTreeIter *gtktree_iter_find_node(GtkTreeIter *parent,
+					   struct menu *tofind)
 {
 	GtkTreeIter iter;
 	GtkTreeIter *child = &iter;
@@ -1392,7 +1253,6 @@ static void update_tree(struct menu *src, GtkTreeIter * dst)
 	gboolean valid;
 	GtkTreeIter *sibling;
 	struct symbol *sym;
-	struct property *prop;
 	struct menu *menu1, *menu2;
 
 	if (src == &rootmenu)
@@ -1401,7 +1261,6 @@ static void update_tree(struct menu *src, GtkTreeIter * dst)
 	valid = gtk_tree_model_iter_children(model2, child2, dst);
 	for (child1 = src->list; child1; child1 = child1->next) {
 
-		prop = child1->prompt;
 		sym = child1->sym;
 
 	      reparse:
@@ -1418,16 +1277,20 @@ static void update_tree(struct menu *src, GtkTreeIter * dst)
 		       menu2 ? menu_get_prompt(menu2) : "nil");
 #endif
 
-		if (!menu_is_visible(child1) && !show_all) {	// remove node
+		if ((opt_mode == OPT_NORMAL && !menu_is_visible(child1)) ||
+		    (opt_mode == OPT_PROMPT && !menu_has_prompt(child1)) ||
+		    (opt_mode == OPT_ALL    && !menu_get_prompt(child1))) {
+
+			/* remove node */
 			if (gtktree_iter_find_node(dst, menu1) != NULL) {
 				memcpy(&tmp, child2, sizeof(GtkTreeIter));
 				valid = gtk_tree_model_iter_next(model2,
 								 child2);
 				gtk_tree_store_remove(tree2, &tmp);
 				if (!valid)
-					return;	// next parent
+					return;		/* next parent */
 				else
-					goto reparse;	// next child
+					goto reparse;	/* next child */
 			} else
 				continue;
 		}
@@ -1496,17 +1359,19 @@ static void display_tree(struct menu *menu)
 		    && (tree == tree2))
 			continue;
 
-		if (menu_is_visible(child) || show_all)
+		if ((opt_mode == OPT_NORMAL && menu_is_visible(child)) ||
+		    (opt_mode == OPT_PROMPT && menu_has_prompt(child)) ||
+		    (opt_mode == OPT_ALL    && menu_get_prompt(child)))
 			place_node(child, fill_row(child));
 #ifdef DEBUG
 		printf("%*c%s: ", indent, ' ', menu_get_prompt(child));
 		printf("%s", child->flags & MENU_ROOT ? "rootmenu | " : "");
-		dbg_print_ptype(ptype);
+		printf("%s", prop_get_type_name(ptype));
 		printf(" | ");
 		if (sym) {
-			dbg_print_stype(sym->type);
+			printf("%s", sym_type_name(sym->type));
 			printf(" | ");
-			dbg_print_flags(sym->flags);
+			printf("%s", dbg_sym_flags(sym->flags));
 			printf("\n");
 		} else
 			printf("\n");
@@ -1518,6 +1383,12 @@ static void display_tree(struct menu *menu)
 		if (((menu != &rootmenu) && !(menu->flags & MENU_ROOT))
 		    || (view_mode == FULL_VIEW)
 		    || (view_mode == SPLIT_VIEW))*/
+
+		/* Change paned position if the view is not in 'split mode' */
+		if (view_mode == SINGLE_VIEW || view_mode == FULL_VIEW) {
+			gtk_paned_set_position(GTK_PANED(hpaned), 0);
+		}
+
 		if (((view_mode == SINGLE_VIEW) && (menu->flags & MENU_ROOT))
 		    || (view_mode == FULL_VIEW)
 		    || (view_mode == SPLIT_VIEW)) {
@@ -1552,7 +1423,7 @@ static void display_list(void)
 	tree = tree2;
 }
 
-void fixup_rootmenu(struct menu *menu)
+static void fixup_rootmenu(struct menu *menu)
 {
 	struct menu *child;
 	static int menu_cnt = 0;
@@ -1576,14 +1447,6 @@ int main(int ac, char *av[])
 	char *env;
 	gchar *glade_file;
 
-#ifndef LKC_DIRECT_LINK
-	kconfig_load();
-#endif
-
-	bindtextdomain(PACKAGE, LOCALEDIR);
-	bind_textdomain_codeset(PACKAGE, "UTF-8");
-	textdomain(PACKAGE);
-
 	/* GTK stuffs */
 	gtk_set_locale();
 	gtk_init(&ac, &av);
@@ -1601,21 +1464,18 @@ int main(int ac, char *av[])
 	else
 		glade_file = g_strconcat(g_get_current_dir(), "/", av[0], ".glade", NULL);
 
-	/* Load the interface and connect signals */
-	init_main_window(glade_file);
-	init_tree_model();
-	init_left_tree();
-	init_right_tree();
-
 	/* Conf stuffs */
 	if (ac > 1 && av[1][0] == '-') {
 		switch (av[1][1]) {
 		case 'a':
 			//showAll = 1;
 			break;
+		case 's':
+			conf_set_message_callback(NULL);
+			break;
 		case 'h':
 		case '?':
-			printf("%s <config>\n", av[0]);
+			printf("%s [-s] <config>\n", av[0]);
 			exit(0);
 		}
 		name = av[2];
@@ -1626,6 +1486,12 @@ int main(int ac, char *av[])
 	fixup_rootmenu(&rootmenu);
 	conf_read(NULL);
 
+	/* Load the interface and connect signals */
+	init_main_window(glade_file);
+	init_tree_model();
+	init_left_tree();
+	init_right_tree();
+
 	switch (view_mode) {
 	case SINGLE_VIEW:
 		display_tree_part();
@@ -1642,3 +1508,10 @@ int main(int ac, char *av[])
 
 	return 0;
 }
+
+static void conf_changed(void)
+{
+	bool changed = conf_get_changed();
+	gtk_widget_set_sensitive(save_btn, changed);
+	gtk_widget_set_sensitive(save_menu_item, changed);
+}
diff --git a/scripts/kconfig/gconf.glade b/scripts/kconfig/gconf.glade
index f8744ed64..aa483cb32 100644
--- a/scripts/kconfig/gconf.glade
+++ b/scripts/kconfig/gconf.glade
@@ -1,5 +1,4 @@
 <?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
 
 <glade-interface>
 
@@ -70,7 +69,7 @@
 		      <property name="tooltip" translatable="yes">Save the config in \
.config</property>  <property name="label" translatable="yes">_Save</property>
 		      <property name="use_underline">True</property>
-		      <signal name="activate" handler="on_save1_activate"/>
+		      <signal name="activate" handler="on_save_activate"/>
 		      <accelerator key="S" modifiers="GDK_CONTROL_MASK" signal="activate"/>
 
 		      <child internal-child="image">
@@ -190,26 +189,40 @@
 		  </child>
 
 		  <child>
-		    <widget class="GtkCheckMenuItem" id="show_all_options1">
+		    <widget class="GtkRadioMenuItem" id="set_option_mode1">
+		      <property name="visible">True</property>
+		      <property name="tooltip" translatable="yes">Show normal options</property>
+		      <property name="label" translatable="yes">Show normal options</property>
+		      <property name="use_underline">True</property>
+		      <property name="active">True</property>
+		      <signal name="activate" handler="on_set_option_mode1_activate"/>
+		    </widget>
+		  </child>
+
+		  <child>
+		    <widget class="GtkRadioMenuItem" id="set_option_mode2">
 		      <property name="visible">True</property>
 		      <property name="tooltip" translatable="yes">Show all options</property>
 		      <property name="label" translatable="yes">Show all _options</property>
 		      <property name="use_underline">True</property>
 		      <property name="active">False</property>
-		      <signal name="activate" handler="on_show_all_options1_activate"/>
+		      <property name="group">set_option_mode1</property>
+		      <signal name="activate" handler="on_set_option_mode2_activate"/>
 		    </widget>
 		  </child>
 
 		  <child>
-		    <widget class="GtkCheckMenuItem" id="show_debug_info1">
+		    <widget class="GtkRadioMenuItem" id="set_option_mode3">
 		      <property name="visible">True</property>
-		      <property name="tooltip" translatable="yes">Show masked options</property>
-		      <property name="label" translatable="yes">Show _debug info</property>
+		      <property name="tooltip" translatable="yes">Show all options with \
prompts</property> +		      <property name="label" translatable="yes">Show all prompt \
options</property>  <property name="use_underline">True</property>
 		      <property name="active">False</property>
-		      <signal name="activate" handler="on_show_debug_info1_activate"/>
+		      <property name="group">set_option_mode1</property>
+		      <signal name="activate" handler="on_set_option_mode3_activate"/>
 		    </widget>
 		  </child>
+
 		</widget>
 	      </child>
 	    </widget>
@@ -380,7 +393,7 @@
 		  <property name="visible_horizontal">True</property>
 		  <property name="visible_vertical">True</property>
 		  <property name="is_important">False</property>
-		  <signal name="clicked" handler="on_save_clicked"/>
+		  <signal name="clicked" handler="on_save_activate"/>
 		</widget>
 		<packing>
 		  <property name="expand">False</property>
@@ -547,7 +560,7 @@
 		  <property name="headers_visible">True</property>
 		  <property name="rules_hint">False</property>
 		  <property name="reorderable">False</property>
-		  <property name="enable_search">True</property>
+		  <property name="enable_search">False</property>
 		  <signal name="cursor_changed" handler="on_treeview2_cursor_changed" \
                last_modification_time="Sun, 12 Jan 2003 15:58:22 GMT"/>
 		  <signal name="button_press_event" handler="on_treeview1_button_press_event" \
                last_modification_time="Sun, 12 Jan 2003 16:03:52 GMT"/>
 		  <signal name="key_press_event" handler="on_treeview2_key_press_event" \
last_modification_time="Sun, 12 Jan 2003 16:11:44 GMT"/> @@ -582,7 +595,7 @@
 		      <property name="headers_visible">True</property>
 		      <property name="rules_hint">False</property>
 		      <property name="reorderable">False</property>
-		      <property name="enable_search">True</property>
+		      <property name="enable_search">False</property>
 		      <signal name="cursor_changed" handler="on_treeview2_cursor_changed" \
                last_modification_time="Sun, 12 Jan 2003 15:57:55 GMT"/>
 		      <signal name="button_press_event" handler="on_treeview2_button_press_event" \
                last_modification_time="Sun, 12 Jan 2003 15:57:58 GMT"/>
 		      <signal name="key_press_event" handler="on_treeview2_key_press_event" \
                last_modification_time="Sun, 12 Jan 2003 15:58:01 GMT"/>
diff --git a/scripts/kconfig/images.c b/scripts/kconfig/images.c
index d4f84bd4a..2f9afffa5 100644
--- a/scripts/kconfig/images.c
+++ b/scripts/kconfig/images.c
@@ -1,9 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
- * Released under the terms of the GNU GPL v2.0.
  */
 
-static const char *xpm_load[] = {
+#include "images.h"
+
+const char * const xpm_load[] = {
 "22 22 5 1",
 ". c None",
 "# c #000000",
@@ -33,7 +35,7 @@ static const char *xpm_load[] = {
 "###############.......",
 "......................"};
 
-static const char *xpm_save[] = {
+const char * const xpm_save[] = {
 "22 22 5 1",
 ". c None",
 "# c #000000",
@@ -63,7 +65,7 @@ static const char *xpm_save[] = {
 "..##################..",
 "......................"};
 
-static const char *xpm_back[] = {
+const char * const xpm_back[] = {
 "22 22 3 1",
 ". c None",
 "# c #000083",
@@ -91,7 +93,7 @@ static const char *xpm_back[] = {
 "......................",
 "......................"};
 
-static const char *xpm_tree_view[] = {
+const char * const xpm_tree_view[] = {
 "22 22 2 1",
 ". c None",
 "# c #000000",
@@ -118,7 +120,7 @@ static const char *xpm_tree_view[] = {
 "......................",
 "......................"};
 
-static const char *xpm_single_view[] = {
+const char * const xpm_single_view[] = {
 "22 22 2 1",
 ". c None",
 "# c #000000",
@@ -145,7 +147,7 @@ static const char *xpm_single_view[] = {
 "......................",
 "......................"};
 
-static const char *xpm_split_view[] = {
+const char * const xpm_split_view[] = {
 "22 22 2 1",
 ". c None",
 "# c #000000",
@@ -172,7 +174,7 @@ static const char *xpm_split_view[] = {
 "......................",
 "......................"};
 
-static const char *xpm_symbol_no[] = {
+const char * const xpm_symbol_no[] = {
 "12 12 2 1",
 "  c white",
 ". c black",
@@ -189,7 +191,7 @@ static const char *xpm_symbol_no[] = {
 " .......... ",
 "            "};
 
-static const char *xpm_symbol_mod[] = {
+const char * const xpm_symbol_mod[] = {
 "12 12 2 1",
 "  c white",
 ". c black",
@@ -206,7 +208,7 @@ static const char *xpm_symbol_mod[] = {
 " .......... ",
 "            "};
 
-static const char *xpm_symbol_yes[] = {
+const char * const xpm_symbol_yes[] = {
 "12 12 2 1",
 "  c white",
 ". c black",
@@ -223,7 +225,7 @@ static const char *xpm_symbol_yes[] = {
 " .......... ",
 "            "};
 
-static const char *xpm_choice_no[] = {
+const char * const xpm_choice_no[] = {
 "12 12 2 1",
 "  c white",
 ". c black",
@@ -240,7 +242,7 @@ static const char *xpm_choice_no[] = {
 "    ....    ",
 "            "};
 
-static const char *xpm_choice_yes[] = {
+const char * const xpm_choice_yes[] = {
 "12 12 2 1",
 "  c white",
 ". c black",
@@ -257,7 +259,7 @@ static const char *xpm_choice_yes[] = {
 "    ....    ",
 "            "};
 
-static const char *xpm_menu[] = {
+const char * const xpm_menu[] = {
 "12 12 2 1",
 "  c white",
 ". c black",
@@ -274,7 +276,7 @@ static const char *xpm_menu[] = {
 " .......... ",
 "            "};
 
-static const char *xpm_menu_inv[] = {
+const char * const xpm_menu_inv[] = {
 "12 12 2 1",
 "  c white",
 ". c black",
@@ -291,7 +293,7 @@ static const char *xpm_menu_inv[] = {
 " .......... ",
 "            "};
 
-static const char *xpm_menuback[] = {
+const char * const xpm_menuback[] = {
 "12 12 2 1",
 "  c white",
 ". c black",
@@ -308,7 +310,7 @@ static const char *xpm_menuback[] = {
 " .......... ",
 "            "};
 
-static const char *xpm_void[] = {
+const char * const xpm_void[] = {
 "12 12 2 1",
 "  c white",
 ". c black",
diff --git a/scripts/kconfig/images.h b/scripts/kconfig/images.h
new file mode 100644
index 000000000..7212dec20
--- /dev/null
+++ b/scripts/kconfig/images.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ */
+
+#ifndef IMAGES_H
+#define IMAGES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern const char * const xpm_load[];
+extern const char * const xpm_save[];
+extern const char * const xpm_back[];
+extern const char * const xpm_tree_view[];
+extern const char * const xpm_single_view[];
+extern const char * const xpm_split_view[];
+extern const char * const xpm_symbol_no[];
+extern const char * const xpm_symbol_mod[];
+extern const char * const xpm_symbol_yes[];
+extern const char * const xpm_choice_no[];
+extern const char * const xpm_choice_yes[];
+extern const char * const xpm_menu[];
+extern const char * const xpm_menu_inv[];
+extern const char * const xpm_menuback[];
+extern const char * const xpm_void[];
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* IMAGES_H */
diff --git a/scripts/kconfig/kconfig_load.c b/scripts/kconfig/kconfig_load.c
deleted file mode 100644
index 5e87dd555..000000000
--- a/scripts/kconfig/kconfig_load.c
+++ /dev/null
@@ -1,35 +0,0 @@
-#include <dlfcn.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "lkc.h"
-
-#define P(name,type,arg)	type (*name ## _p) arg
-#include "lkc_proto.h"
-#undef P
-
-void kconfig_load(void)
-{
-	void *handle;
-	char *error;
-
-	handle = dlopen("./libkconfig.so", RTLD_LAZY);
-	if (!handle) {
-		handle = dlopen("./scripts/kconfig/libkconfig.so", RTLD_LAZY);
-		if (!handle) {
-			fprintf(stderr, "%s\n", dlerror());
-			exit(1);
-		}
-	}
-
-#define P(name,type,arg)			\
-{						\
-	name ## _p = dlsym(handle, #name);	\
-	if ((error = dlerror()))  {		\
-		fprintf(stderr, "%s\n", error);	\
-		exit(1);			\
-	}					\
-}
-#include "lkc_proto.h"
-#undef P
-}
diff --git a/scripts/kconfig/kxgettext.c b/scripts/kconfig/kxgettext.c
deleted file mode 100644
index abee55ca6..000000000
--- a/scripts/kconfig/kxgettext.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Arnaldo Carvalho de Melo <acme@conectiva.com.br>, 2005
- *
- * Released under the terms of the GNU GPL v2.0
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#define LKC_DIRECT_LINK
-#include "lkc.h"
-
-static char *escape(const char* text, char *bf, int len)
-{
-	char *bfp = bf;
-	int multiline = strchr(text, '\n') != NULL;
-	int eol = 0;
-	int textlen = strlen(text);
-
-	if ((textlen > 0) && (text[textlen-1] == '\n'))
-		eol = 1;
-
-	*bfp++ = '"';
-	--len;
-
-	if (multiline) {
-		*bfp++ = '"';
-		*bfp++ = '\n';
-		*bfp++ = '"';
-		len -= 3;
-	}
-
-	while (*text != '\0' && len > 1) {
-		if (*text == '"')
-			*bfp++ = '\\';
-		else if (*text == '\n') {
-			*bfp++ = '\\';
-			*bfp++ = 'n';
-			*bfp++ = '"';
-			*bfp++ = '\n';
-			*bfp++ = '"';
-			len -= 5;
-			++text;
-			goto next;
-		}
-		*bfp++ = *text++;
-next:
-		--len;
-	}
-
-	if (multiline && eol)
-		bfp -= 3;
-
-	*bfp++ = '"';
-	*bfp = '\0';
-
-	return bf;
-}
-
-struct file_line {
-	struct file_line *next;
-	char*		 file;
-	int		 lineno;
-};
-
-static struct file_line *file_line__new(char *file, int lineno)
-{
-	struct file_line *self = malloc(sizeof(*self));
-
-	if (self == NULL)
-		goto out;
-
-	self->file   = file;
-	self->lineno = lineno;
-	self->next   = NULL;
-out:
-	return self;
-}
-
-struct message {
-	const char	 *msg;
-	const char	 *option;
-	struct message	 *next;
-	struct file_line *files;
-};
-
-static struct message *message__list;
-
-static struct message *message__new(const char *msg, char *option, char *file, int \
                lineno)
-{
-	struct message *self = malloc(sizeof(*self));
-
-	if (self == NULL)
-		goto out;
-
-	self->files = file_line__new(file, lineno);
-	if (self->files == NULL)
-		goto out_fail;
-
-	self->msg = strdup(msg);
-	if (self->msg == NULL)
-		goto out_fail_msg;
-
-	self->option = option;
-	self->next = NULL;
-out:
-	return self;
-out_fail_msg:
-	free(self->files);
-out_fail:
-	free(self);
-	self = NULL;
-	goto out;
-}
-
-static struct message *mesage__find(const char *msg)
-{
-	struct message *m = message__list;
-
-	while (m != NULL) {
-		if (strcmp(m->msg, msg) == 0)
-			break;
-		m = m->next;
-	}
-
-	return m;
-}
-
-static int message__add_file_line(struct message *self, char *file, int lineno)
-{
-	int rc = -1;
-	struct file_line *fl = file_line__new(file, lineno);
-
-	if (fl == NULL)
-		goto out;
-
-	fl->next    = self->files;
-	self->files = fl;
-	rc = 0;
-out:
-	return rc;
-}
-
-static int message__add(const char *msg, char *option, char *file, int lineno)
-{
-	int rc = 0;
-	char bf[16384];
-	char *escaped = escape(msg, bf, sizeof(bf));
-	struct message *m = mesage__find(escaped);
-
-	if (m != NULL)
-		rc = message__add_file_line(m, file, lineno);
-	else {
-		m = message__new(escaped, option, file, lineno);
-
-		if (m != NULL) {
-			m->next	      = message__list;
-			message__list = m;
-		} else
-			rc = -1;
-	}
-	return rc;
-}
-
-void menu_build_message_list(struct menu *menu)
-{
-	struct menu *child;
-
-	message__add(menu_get_prompt(menu), NULL,
-		     menu->file == NULL ? "Root Menu" : menu->file->name,
-		     menu->lineno);
-
-	if (menu->sym != NULL && menu->sym->help != NULL)
-		message__add(menu->sym->help, menu->sym->name,
-			     menu->file == NULL ? "Root Menu" : menu->file->name,
-			     menu->lineno);
-
-	for (child = menu->list; child != NULL; child = child->next)
-		if (child->prompt != NULL)
-			menu_build_message_list(child);
-}
-
-static void message__print_file_lineno(struct message *self)
-{
-	struct file_line *fl = self->files;
-
-	putchar('\n');
-	if (self->option != NULL)
-		printf("# %s:00000\n", self->option);
-
-	printf("#: %s:%d", fl->file, fl->lineno);
-	fl = fl->next;
-
-	while (fl != NULL) {
-		printf(", %s:%d", fl->file, fl->lineno);
-		fl = fl->next;
-	}
-
-	putchar('\n');
-}
-
-static void message__print_gettext_msgid_msgstr(struct message *self)
-{
-	message__print_file_lineno(self);
-
-	printf("msgid %s\n"
-	       "msgstr \"\"\n", self->msg);
-}
-
-void menu__xgettext(void)
-{
-	struct message *m = message__list;
-
-	while (m != NULL) {
-		message__print_gettext_msgid_msgstr(m);
-		m = m->next;
-	}
-}
-
-int main(int ac, char **av)
-{
-	conf_parse(av[1]);
-
-	menu_build_message_list(menu_get_root_menu(NULL));
-	menu__xgettext();
-	return 0;
-}
diff --git a/scripts/kconfig/lex.zconf.c_shipped \
b/scripts/kconfig/lex.zconf.c_shipped deleted file mode 100644
index 51f15e175..000000000
--- a/scripts/kconfig/lex.zconf.c_shipped
+++ /dev/null
@@ -1,2325 +0,0 @@
-
-#line 3 "scripts/kconfig/lex.zconf.c"
-
-#define  YY_INT_ALIGNED short int
-
-/* A lexical scanner generated by flex */
-
-#define FLEX_SCANNER
-#define YY_FLEX_MAJOR_VERSION 2
-#define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 31
-#if YY_FLEX_SUBMINOR_VERSION > 0
-#define FLEX_BETA
-#endif
-
-/* First, we deal with  platform-specific or compiler-specific issues. */
-
-/* begin standard C headers. */
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-
-/* end standard C headers. */
-
-/* flex integer type definitions */
-
-#ifndef FLEXINT_H
-#define FLEXINT_H
-
-/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
-
-#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
-#include <inttypes.h>
-typedef int8_t flex_int8_t;
-typedef uint8_t flex_uint8_t;
-typedef int16_t flex_int16_t;
-typedef uint16_t flex_uint16_t;
-typedef int32_t flex_int32_t;
-typedef uint32_t flex_uint32_t;
-#else
-typedef signed char flex_int8_t;
-typedef short int flex_int16_t;
-typedef int flex_int32_t;
-typedef unsigned char flex_uint8_t;
-typedef unsigned short int flex_uint16_t;
-typedef unsigned int flex_uint32_t;
-#endif /* ! C99 */
-
-/* Limits of integral types. */
-#ifndef INT8_MIN
-#define INT8_MIN               (-128)
-#endif
-#ifndef INT16_MIN
-#define INT16_MIN              (-32767-1)
-#endif
-#ifndef INT32_MIN
-#define INT32_MIN              (-2147483647-1)
-#endif
-#ifndef INT8_MAX
-#define INT8_MAX               (127)
-#endif
-#ifndef INT16_MAX
-#define INT16_MAX              (32767)
-#endif
-#ifndef INT32_MAX
-#define INT32_MAX              (2147483647)
-#endif
-#ifndef UINT8_MAX
-#define UINT8_MAX              (255U)
-#endif
-#ifndef UINT16_MAX
-#define UINT16_MAX             (65535U)
-#endif
-#ifndef UINT32_MAX
-#define UINT32_MAX             (4294967295U)
-#endif
-
-#endif /* ! FLEXINT_H */
-
-#ifdef __cplusplus
-
-/* The "const" storage-class-modifier is valid. */
-#define YY_USE_CONST
-
-#else	/* ! __cplusplus */
-
-#if __STDC__
-
-#define YY_USE_CONST
-
-#endif	/* __STDC__ */
-#endif	/* ! __cplusplus */
-
-#ifdef YY_USE_CONST
-#define yyconst const
-#else
-#define yyconst
-#endif
-
-/* Returned upon end-of-file. */
-#define YY_NULL 0
-
-/* Promotes a possibly negative, possibly signed char to an unsigned
- * integer for use as an array index.  If the signed char is negative,
- * we want to instead treat it as an 8-bit unsigned char, hence the
- * double cast.
- */
-#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
-
-/* Enter a start condition.  This macro really ought to take a parameter,
- * but we do it the disgusting crufty way forced on us by the ()-less
- * definition of BEGIN.
- */
-#define BEGIN (yy_start) = 1 + 2 *
-
-/* Translate the current start state into a value that can be later handed
- * to BEGIN to return to the state.  The YYSTATE alias is for lex
- * compatibility.
- */
-#define YY_START (((yy_start) - 1) / 2)
-#define YYSTATE YY_START
-
-/* Action number for EOF rule of a given start state. */
-#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
-
-/* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE zconfrestart(zconfin  )
-
-#define YY_END_OF_BUFFER_CHAR 0
-
-/* Size of default input buffer. */
-#ifndef YY_BUF_SIZE
-#define YY_BUF_SIZE 16384
-#endif
-
-#ifndef YY_TYPEDEF_YY_BUFFER_STATE
-#define YY_TYPEDEF_YY_BUFFER_STATE
-typedef struct yy_buffer_state *YY_BUFFER_STATE;
-#endif
-
-extern int zconfleng;
-
-extern FILE *zconfin, *zconfout;
-
-#define EOB_ACT_CONTINUE_SCAN 0
-#define EOB_ACT_END_OF_FILE 1
-#define EOB_ACT_LAST_MATCH 2
-
-    #define YY_LESS_LINENO(n)
-
-/* Return all but the first "n" matched characters back to the input stream. */
-#define yyless(n) \
-	do \
-		{ \
-		/* Undo effects of setting up zconftext. */ \
-        int yyless_macro_arg = (n); \
-        YY_LESS_LINENO(yyless_macro_arg);\
-		*yy_cp = (yy_hold_char); \
-		YY_RESTORE_YY_MORE_OFFSET \
-		(yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
-		YY_DO_BEFORE_ACTION; /* set up zconftext again */ \
-		} \
-	while ( 0 )
-
-#define unput(c) yyunput( c, (yytext_ptr)  )
-
-/* The following is because we cannot portably get our hands on size_t
- * (without autoconf's help, which isn't available because we want
- * flex-generated scanners to compile on their own).
- */
-
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef unsigned int yy_size_t;
-#endif
-
-#ifndef YY_STRUCT_YY_BUFFER_STATE
-#define YY_STRUCT_YY_BUFFER_STATE
-struct yy_buffer_state
-	{
-	FILE *yy_input_file;
-
-	char *yy_ch_buf;		/* input buffer */
-	char *yy_buf_pos;		/* current position in input buffer */
-
-	/* Size of input buffer in bytes, not including room for EOB
-	 * characters.
-	 */
-	yy_size_t yy_buf_size;
-
-	/* Number of characters read into yy_ch_buf, not including EOB
-	 * characters.
-	 */
-	int yy_n_chars;
-
-	/* Whether we "own" the buffer - i.e., we know we created it,
-	 * and can realloc() it to grow it, and should free() it to
-	 * delete it.
-	 */
-	int yy_is_our_buffer;
-
-	/* Whether this is an "interactive" input source; if so, and
-	 * if we're using stdio for input, then we want to use getc()
-	 * instead of fread(), to make sure we stop fetching input after
-	 * each newline.
-	 */
-	int yy_is_interactive;
-
-	/* Whether we're considered to be at the beginning of a line.
-	 * If so, '^' rules will be active on the next match, otherwise
-	 * not.
-	 */
-	int yy_at_bol;
-
-    int yy_bs_lineno; /**< The line count. */
-    int yy_bs_column; /**< The column count. */
-
-	/* Whether to try to fill the input buffer when we reach the
-	 * end of it.
-	 */
-	int yy_fill_buffer;
-
-	int yy_buffer_status;
-
-#define YY_BUFFER_NEW 0
-#define YY_BUFFER_NORMAL 1
-	/* When an EOF's been seen but there's still some text to process
-	 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
-	 * shouldn't try reading from the input source any more.  We might
-	 * still have a bunch of tokens to match, though, because of
-	 * possible backing-up.
-	 *
-	 * When we actually see the EOF, we change the status to "new"
-	 * (via zconfrestart()), so that the user can continue scanning by
-	 * just pointing zconfin at a new input file.
-	 */
-#define YY_BUFFER_EOF_PENDING 2
-
-	};
-#endif /* !YY_STRUCT_YY_BUFFER_STATE */
-
-/* Stack of input buffers. */
-static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
-static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
-static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
-
-/* We provide macros for accessing buffer states in case in the
- * future we want to put the buffer states in a more general
- * "scanner state".
- *
- * Returns the top of the stack, or NULL.
- */
-#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
-                          ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
-                          : NULL)
-
-/* Same as previous macro, but useful when we know that the buffer stack is not
- * NULL or when we need an lvalue. For internal use only.
- */
-#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
-
-/* yy_hold_char holds the character lost when zconftext is formed. */
-static char yy_hold_char;
-static int yy_n_chars;		/* number of characters read into yy_ch_buf */
-int zconfleng;
-
-/* Points to current character in buffer. */
-static char *yy_c_buf_p = (char *) 0;
-static int yy_init = 1;		/* whether we need to initialize */
-static int yy_start = 0;	/* start state number */
-
-/* Flag which is used to allow zconfwrap()'s to do buffer switches
- * instead of setting up a fresh zconfin.  A bit of a hack ...
- */
-static int yy_did_buffer_switch_on_eof;
-
-void zconfrestart (FILE *input_file  );
-void zconf_switch_to_buffer (YY_BUFFER_STATE new_buffer  );
-YY_BUFFER_STATE zconf_create_buffer (FILE *file,int size  );
-void zconf_delete_buffer (YY_BUFFER_STATE b  );
-void zconf_flush_buffer (YY_BUFFER_STATE b  );
-void zconfpush_buffer_state (YY_BUFFER_STATE new_buffer  );
-void zconfpop_buffer_state (void );
-
-static void zconfensure_buffer_stack (void );
-static void zconf_load_buffer_state (void );
-static void zconf_init_buffer (YY_BUFFER_STATE b,FILE *file  );
-
-#define YY_FLUSH_BUFFER zconf_flush_buffer(YY_CURRENT_BUFFER )
-
-YY_BUFFER_STATE zconf_scan_buffer (char *base,yy_size_t size  );
-YY_BUFFER_STATE zconf_scan_string (yyconst char *yy_str  );
-YY_BUFFER_STATE zconf_scan_bytes (yyconst char *bytes,int len  );
-
-void *zconfalloc (yy_size_t  );
-void *zconfrealloc (void *,yy_size_t  );
-void zconffree (void *  );
-
-#define yy_new_buffer zconf_create_buffer
-
-#define yy_set_interactive(is_interactive) \
-	{ \
-	if ( ! YY_CURRENT_BUFFER ){ \
-        zconfensure_buffer_stack (); \
-		YY_CURRENT_BUFFER_LVALUE =    \
-            zconf_create_buffer(zconfin,YY_BUF_SIZE ); \
-	} \
-	YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
-	}
-
-#define yy_set_bol(at_bol) \
-	{ \
-	if ( ! YY_CURRENT_BUFFER ){\
-        zconfensure_buffer_stack (); \
-		YY_CURRENT_BUFFER_LVALUE =    \
-            zconf_create_buffer(zconfin,YY_BUF_SIZE ); \
-	} \
-	YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
-	}
-
-#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
-
-/* Begin user sect3 */
-
-#define zconfwrap() 1
-#define YY_SKIP_YYWRAP
-
-typedef unsigned char YY_CHAR;
-
-FILE *zconfin = (FILE *) 0, *zconfout = (FILE *) 0;
-
-typedef int yy_state_type;
-
-extern int zconflineno;
-
-int zconflineno = 1;
-
-extern char *zconftext;
-#define yytext_ptr zconftext
-static yyconst flex_int16_t yy_nxt[][17] =
-    {
-    {
-        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,    0,    0
-    },
-
-    {
-       11,   12,   13,   14,   12,   12,   15,   12,   12,   12,
-       12,   12,   12,   12,   12,   12,   12
-    },
-
-    {
-       11,   12,   13,   14,   12,   12,   15,   12,   12,   12,
-       12,   12,   12,   12,   12,   12,   12
-    },
-
-    {
-       11,   16,   16,   17,   16,   16,   16,   16,   16,   16,
-       16,   16,   16,   18,   16,   16,   16
-    },
-
-    {
-       11,   16,   16,   17,   16,   16,   16,   16,   16,   16,
-       16,   16,   16,   18,   16,   16,   16
-
-    },
-
-    {
-       11,   19,   20,   21,   19,   19,   19,   19,   19,   19,
-       19,   19,   19,   19,   19,   19,   19
-    },
-
-    {
-       11,   19,   20,   21,   19,   19,   19,   19,   19,   19,
-       19,   19,   19,   19,   19,   19,   19
-    },
-
-    {
-       11,   22,   22,   23,   22,   24,   22,   22,   24,   22,
-       22,   22,   22,   22,   22,   25,   22
-    },
-
-    {
-       11,   22,   22,   23,   22,   24,   22,   22,   24,   22,
-       22,   22,   22,   22,   22,   25,   22
-    },
-
-    {
-       11,   26,   26,   27,   28,   29,   30,   31,   29,   32,
-       33,   34,   35,   35,   36,   37,   38
-
-    },
-
-    {
-       11,   26,   26,   27,   28,   29,   30,   31,   29,   32,
-       33,   34,   35,   35,   36,   37,   38
-    },
-
-    {
-      -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,
-      -11,  -11,  -11,  -11,  -11,  -11,  -11
-    },
-
-    {
-       11,  -12,  -12,  -12,  -12,  -12,  -12,  -12,  -12,  -12,
-      -12,  -12,  -12,  -12,  -12,  -12,  -12
-    },
-
-    {
-       11,  -13,   39,   40,  -13,  -13,   41,  -13,  -13,  -13,
-      -13,  -13,  -13,  -13,  -13,  -13,  -13
-    },
-
-    {
-       11,  -14,  -14,  -14,  -14,  -14,  -14,  -14,  -14,  -14,
-      -14,  -14,  -14,  -14,  -14,  -14,  -14
-
-    },
-
-    {
-       11,   42,   42,   43,   42,   42,   42,   42,   42,   42,
-       42,   42,   42,   42,   42,   42,   42
-    },
-
-    {
-       11,  -16,  -16,  -16,  -16,  -16,  -16,  -16,  -16,  -16,
-      -16,  -16,  -16,  -16,  -16,  -16,  -16
-    },
-
-    {
-       11,  -17,  -17,  -17,  -17,  -17,  -17,  -17,  -17,  -17,
-      -17,  -17,  -17,  -17,  -17,  -17,  -17
-    },
-
-    {
-       11,  -18,  -18,  -18,  -18,  -18,  -18,  -18,  -18,  -18,
-      -18,  -18,  -18,   44,  -18,  -18,  -18
-    },
-
-    {
-       11,   45,   45,  -19,   45,   45,   45,   45,   45,   45,
-       45,   45,   45,   45,   45,   45,   45
-
-    },
-
-    {
-       11,  -20,   46,   47,  -20,  -20,  -20,  -20,  -20,  -20,
-      -20,  -20,  -20,  -20,  -20,  -20,  -20
-    },
-
-    {
-       11,   48,  -21,  -21,   48,   48,   48,   48,   48,   48,
-       48,   48,   48,   48,   48,   48,   48
-    },
-
-    {
-       11,   49,   49,   50,   49,  -22,   49,   49,  -22,   49,
-       49,   49,   49,   49,   49,  -22,   49
-    },
-
-    {
-       11,  -23,  -23,  -23,  -23,  -23,  -23,  -23,  -23,  -23,
-      -23,  -23,  -23,  -23,  -23,  -23,  -23
-    },
-
-    {
-       11,  -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,
-      -24,  -24,  -24,  -24,  -24,  -24,  -24
-
-    },
-
-    {
-       11,   51,   51,   52,   51,   51,   51,   51,   51,   51,
-       51,   51,   51,   51,   51,   51,   51
-    },
-
-    {
-       11,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,
-      -26,  -26,  -26,  -26,  -26,  -26,  -26
-    },
-
-    {
-       11,  -27,  -27,  -27,  -27,  -27,  -27,  -27,  -27,  -27,
-      -27,  -27,  -27,  -27,  -27,  -27,  -27
-    },
-
-    {
-       11,  -28,  -28,  -28,  -28,  -28,  -28,  -28,  -28,  -28,
-      -28,  -28,  -28,  -28,   53,  -28,  -28
-    },
-
-    {
-       11,  -29,  -29,  -29,  -29,  -29,  -29,  -29,  -29,  -29,
-      -29,  -29,  -29,  -29,  -29,  -29,  -29
-
-    },
-
-    {
-       11,   54,   54,  -30,   54,   54,   54,   54,   54,   54,
-       54,   54,   54,   54,   54,   54,   54
-    },
-
-    {
-       11,  -31,  -31,  -31,  -31,  -31,  -31,   55,  -31,  -31,
-      -31,  -31,  -31,  -31,  -31,  -31,  -31
-    },
-
-    {
-       11,  -32,  -32,  -32,  -32,  -32,  -32,  -32,  -32,  -32,
-      -32,  -32,  -32,  -32,  -32,  -32,  -32
-    },
-
-    {
-       11,  -33,  -33,  -33,  -33,  -33,  -33,  -33,  -33,  -33,
-      -33,  -33,  -33,  -33,  -33,  -33,  -33
-    },
-
-    {
-       11,  -34,  -34,  -34,  -34,  -34,  -34,  -34,  -34,  -34,
-      -34,   56,   57,   57,  -34,  -34,  -34
-
-    },
-
-    {
-       11,  -35,  -35,  -35,  -35,  -35,  -35,  -35,  -35,  -35,
-      -35,   57,   57,   57,  -35,  -35,  -35
-    },
-
-    {
-       11,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,
-      -36,  -36,  -36,  -36,  -36,  -36,  -36
-    },
-
-    {
-       11,  -37,  -37,   58,  -37,  -37,  -37,  -37,  -37,  -37,
-      -37,  -37,  -37,  -37,  -37,  -37,  -37
-    },
-
-    {
-       11,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,
-      -38,  -38,  -38,  -38,  -38,  -38,   59
-    },
-
-    {
-       11,  -39,   39,   40,  -39,  -39,   41,  -39,  -39,  -39,
-      -39,  -39,  -39,  -39,  -39,  -39,  -39
-
-    },
-
-    {
-       11,  -40,  -40,  -40,  -40,  -40,  -40,  -40,  -40,  -40,
-      -40,  -40,  -40,  -40,  -40,  -40,  -40
-    },
-
-    {
-       11,   42,   42,   43,   42,   42,   42,   42,   42,   42,
-       42,   42,   42,   42,   42,   42,   42
-    },
-
-    {
-       11,   42,   42,   43,   42,   42,   42,   42,   42,   42,
-       42,   42,   42,   42,   42,   42,   42
-    },
-
-    {
-       11,  -43,  -43,  -43,  -43,  -43,  -43,  -43,  -43,  -43,
-      -43,  -43,  -43,  -43,  -43,  -43,  -43
-    },
-
-    {
-       11,  -44,  -44,  -44,  -44,  -44,  -44,  -44,  -44,  -44,
-      -44,  -44,  -44,   44,  -44,  -44,  -44
-
-    },
-
-    {
-       11,   45,   45,  -45,   45,   45,   45,   45,   45,   45,
-       45,   45,   45,   45,   45,   45,   45
-    },
-
-    {
-       11,  -46,   46,   47,  -46,  -46,  -46,  -46,  -46,  -46,
-      -46,  -46,  -46,  -46,  -46,  -46,  -46
-    },
-
-    {
-       11,   48,  -47,  -47,   48,   48,   48,   48,   48,   48,
-       48,   48,   48,   48,   48,   48,   48
-    },
-
-    {
-       11,  -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,
-      -48,  -48,  -48,  -48,  -48,  -48,  -48
-    },
-
-    {
-       11,   49,   49,   50,   49,  -49,   49,   49,  -49,   49,
-       49,   49,   49,   49,   49,  -49,   49
-
-    },
-
-    {
-       11,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,
-      -50,  -50,  -50,  -50,  -50,  -50,  -50
-    },
-
-    {
-       11,  -51,  -51,   52,  -51,  -51,  -51,  -51,  -51,  -51,
-      -51,  -51,  -51,  -51,  -51,  -51,  -51
-    },
-
-    {
-       11,  -52,  -52,  -52,  -52,  -52,  -52,  -52,  -52,  -52,
-      -52,  -52,  -52,  -52,  -52,  -52,  -52
-    },
-
-    {
-       11,  -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,
-      -53,  -53,  -53,  -53,  -53,  -53,  -53
-    },
-
-    {
-       11,   54,   54,  -54,   54,   54,   54,   54,   54,   54,
-       54,   54,   54,   54,   54,   54,   54
-
-    },
-
-    {
-       11,  -55,  -55,  -55,  -55,  -55,  -55,  -55,  -55,  -55,
-      -55,  -55,  -55,  -55,  -55,  -55,  -55
-    },
-
-    {
-       11,  -56,  -56,  -56,  -56,  -56,  -56,  -56,  -56,  -56,
-      -56,   60,   57,   57,  -56,  -56,  -56
-    },
-
-    {
-       11,  -57,  -57,  -57,  -57,  -57,  -57,  -57,  -57,  -57,
-      -57,   57,   57,   57,  -57,  -57,  -57
-    },
-
-    {
-       11,  -58,  -58,  -58,  -58,  -58,  -58,  -58,  -58,  -58,
-      -58,  -58,  -58,  -58,  -58,  -58,  -58
-    },
-
-    {
-       11,  -59,  -59,  -59,  -59,  -59,  -59,  -59,  -59,  -59,
-      -59,  -59,  -59,  -59,  -59,  -59,  -59
-
-    },
-
-    {
-       11,  -60,  -60,  -60,  -60,  -60,  -60,  -60,  -60,  -60,
-      -60,   57,   57,   57,  -60,  -60,  -60
-    },
-
-    } ;
-
-static yy_state_type yy_get_previous_state (void );
-static yy_state_type yy_try_NUL_trans (yy_state_type current_state  );
-static int yy_get_next_buffer (void );
-static void yy_fatal_error (yyconst char msg[]  );
-
-/* Done after the current pattern has been matched and before the
- * corresponding action - sets up zconftext.
- */
-#define YY_DO_BEFORE_ACTION \
-	(yytext_ptr) = yy_bp; \
-	zconfleng = (size_t) (yy_cp - yy_bp); \
-	(yy_hold_char) = *yy_cp; \
-	*yy_cp = '\0'; \
-	(yy_c_buf_p) = yy_cp;
-
-#define YY_NUM_RULES 33
-#define YY_END_OF_BUFFER 34
-/* This struct is not used in this scanner,
-   but its presence is necessary. */
-struct yy_trans_info
-	{
-	flex_int32_t yy_verify;
-	flex_int32_t yy_nxt;
-	};
-static yyconst flex_int16_t yy_accept[61] =
-    {   0,
-        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-       34,    5,    4,    2,    3,    7,    8,    6,   32,   29,
-       31,   24,   28,   27,   26,   22,   17,   13,   16,   20,
-       22,   11,   12,   19,   19,   14,   22,   22,    4,    2,
-        3,    3,    1,    6,   32,   29,   31,   30,   24,   23,
-       26,   25,   15,   20,    9,   19,   19,   21,   10,   18
-    } ;
-
-static yyconst flex_int32_t yy_ec[256] =
-    {   0,
-        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    2,    4,    5,    6,    1,    1,    7,    8,    9,
-       10,    1,    1,    1,   11,   12,   12,   13,   13,   13,
-       13,   13,   13,   13,   13,   13,   13,    1,    1,    1,
-       14,    1,    1,    1,   13,   13,   13,   13,   13,   13,
-       13,   13,   13,   13,   13,   13,   13,   13,   13,   13,
-       13,   13,   13,   13,   13,   13,   13,   13,   13,   13,
-        1,   15,    1,    1,   13,    1,   13,   13,   13,   13,
-
-       13,   13,   13,   13,   13,   13,   13,   13,   13,   13,
-       13,   13,   13,   13,   13,   13,   13,   13,   13,   13,
-       13,   13,    1,   16,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1
-    } ;
-
-extern int zconf_flex_debug;
-int zconf_flex_debug = 0;
-
-/* The intent behind this definition is that it'll catch
- * any uses of REJECT which flex missed.
- */
-#define REJECT reject_used_but_not_detected
-#define yymore() yymore_used_but_not_detected
-#define YY_MORE_ADJ 0
-#define YY_RESTORE_YY_MORE_OFFSET
-char *zconftext;
-
-/*
- * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
- * Released under the terms of the GNU GPL v2.0.
- */
-
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#define LKC_DIRECT_LINK
-#include "lkc.h"
-
-#define START_STRSIZE	16
-
-static struct {
-	struct file *file;
-	int lineno;
-} current_pos;
-
-static char *text;
-static int text_size, text_asize;
-
-struct buffer {
-        struct buffer *parent;
-        YY_BUFFER_STATE state;
-};
-
-struct buffer *current_buf;
-
-static int last_ts, first_ts;
-
-static void zconf_endhelp(void);
-static void zconf_endfile(void);
-
-void new_string(void)
-{
-	text = malloc(START_STRSIZE);
-	text_asize = START_STRSIZE;
-	text_size = 0;
-	*text = 0;
-}
-
-void append_string(const char *str, int size)
-{
-	int new_size = text_size + size + 1;
-	if (size > 70) {
-		fprintf (stderr, "%s:%d error: Overlong line\n",
-		current_file->name, current_file->lineno);
-	}
-
-	if (new_size > text_asize) {
-		new_size += START_STRSIZE - 1;
-		new_size &= -START_STRSIZE;
-		text = realloc(text, new_size);
-		text_asize = new_size;
-	}
-	memcpy(text + text_size, str, size);
-	text_size += size;
-	text[text_size] = 0;
-}
-
-void alloc_string(const char *str, int size)
-{
-	text = malloc(size + 1);
-	memcpy(text, str, size);
-	text[size] = 0;
-}
-
-#define INITIAL 0
-#define COMMAND 1
-#define HELP 2
-#define STRING 3
-#define PARAM 4
-
-#ifndef YY_NO_UNISTD_H
-/* Special case for "unistd.h", since it is non-ANSI. We include it way
- * down here because we want the user's section 1 to have been scanned first.
- * The user has a chance to override it with an option.
- */
-#include <unistd.h>
-#endif
-
-#ifndef YY_EXTRA_TYPE
-#define YY_EXTRA_TYPE void *
-#endif
-
-/* Macros after this point can all be overridden by user definitions in
- * section 1.
- */
-
-#ifndef YY_SKIP_YYWRAP
-#ifdef __cplusplus
-extern "C" int zconfwrap (void );
-#else
-extern int zconfwrap (void );
-#endif
-#endif
-
-    static void yyunput (int c,char *buf_ptr  );
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy (char *,yyconst char *,int );
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * );
-#endif
-
-//bbox: suppressing "defined but not used" warning
-#define YY_NO_INPUT 1
-
-#ifndef YY_NO_INPUT
-
-#ifdef __cplusplus
-static int yyinput (void );
-#else
-static int input (void );
-#endif
-
-#endif
-
-/* Amount of stuff to slurp up with each read. */
-#ifndef YY_READ_BUF_SIZE
-#define YY_READ_BUF_SIZE 8192
-#endif
-
-/* Copy whatever the last rule matched to the standard output. */
-#ifndef ECHO
-/* This used to be an fputs(), but since the string might contain NUL's,
- * we now use fwrite().
- */
-#define ECHO (void) fwrite( zconftext, zconfleng, 1, zconfout )
-#endif
-
-/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
- * is returned in "result".
- */
-#ifndef YY_INPUT
-#define YY_INPUT(buf,result,max_size) \
-	errno=0; \
-	while ( (result = read( fileno(zconfin), (char *) buf, max_size )) < 0 ) \
-	{ \
-		if( errno != EINTR) \
-		{ \
-			YY_FATAL_ERROR( "input in flex scanner failed" ); \
-			break; \
-		} \
-		errno=0; \
-		clearerr(zconfin); \
-	}\
-\
-
-#endif
-
-/* No semi-colon after return; correct usage is to write "yyterminate();" -
- * we don't want an extra ';' after the "return" because that will cause
- * some compilers to complain about unreachable statements.
- */
-#ifndef yyterminate
-#define yyterminate() return YY_NULL
-#endif
-
-/* Number of entries by which start-condition stack grows. */
-#ifndef YY_START_STACK_INCR
-#define YY_START_STACK_INCR 25
-#endif
-
-/* Report a fatal error. */
-#ifndef YY_FATAL_ERROR
-#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
-#endif
-
-/* end tables serialization structures and prototypes */
-
-/* Default declaration of generated scanner - a define so the user can
- * easily add parameters.
- */
-#ifndef YY_DECL
-#define YY_DECL_IS_OURS 1
-
-extern int zconflex (void);
-
-#define YY_DECL int zconflex (void)
-#endif /* !YY_DECL */
-
-/* Code executed at the beginning of each rule, after zconftext and zconfleng
- * have been set up.
- */
-#ifndef YY_USER_ACTION
-#define YY_USER_ACTION
-#endif
-
-/* Code executed at the end of each rule. */
-#ifndef YY_BREAK
-#define YY_BREAK break;
-#endif
-
-#define YY_RULE_SETUP \
-	YY_USER_ACTION
-
-/** The main scanner function which does all the work.
- */
-YY_DECL
-{
-	register yy_state_type yy_current_state;
-	register char *yy_cp, *yy_bp;
-	register int yy_act;
-
-	int str = 0;
-	int ts, i;
-
-	if ( (yy_init) )
-		{
-		(yy_init) = 0;
-
-#ifdef YY_USER_INIT
-		YY_USER_INIT;
-#endif
-
-		if ( ! (yy_start) )
-			(yy_start) = 1;	/* first start state */
-
-		if ( ! zconfin )
-			zconfin = stdin;
-
-		if ( ! zconfout )
-			zconfout = stdout;
-
-		if ( ! YY_CURRENT_BUFFER ) {
-			zconfensure_buffer_stack ();
-			YY_CURRENT_BUFFER_LVALUE =
-				zconf_create_buffer(zconfin,YY_BUF_SIZE );
-		}
-
-		zconf_load_buffer_state( );
-		}
-
-	while ( 1 )		/* loops until end-of-file is reached */
-		{
-		yy_cp = (yy_c_buf_p);
-
-		/* Support of zconftext. */
-		*yy_cp = (yy_hold_char);
-
-		/* yy_bp points to the position in yy_ch_buf of the start of
-		 * the current run.
-		 */
-		yy_bp = yy_cp;
-
-		yy_current_state = (yy_start);
-yy_match:
-		while ( (yy_current_state = yy_nxt[yy_current_state][ yy_ec[YY_SC_TO_UI(*yy_cp)]  \
                ]) > 0 )
-			++yy_cp;
-
-		yy_current_state = -yy_current_state;
-
-yy_find_action:
-		yy_act = yy_accept[yy_current_state];
-
-		YY_DO_BEFORE_ACTION;
-
-do_action:	/* This label is used only to access EOF actions. */
-
-		switch ( yy_act )
-	{ /* beginning of action switch */
-case 1:
-/* rule 1 can match eol */
-case 2:
-/* rule 2 can match eol */
-YY_RULE_SETUP
-{
-	current_file->lineno++;
-	return T_EOL;
-}
-	YY_BREAK
-case 3:
-YY_RULE_SETUP
-
-	YY_BREAK
-case 4:
-YY_RULE_SETUP
-{
-	BEGIN(COMMAND);
-}
-	YY_BREAK
-case 5:
-YY_RULE_SETUP
-{
-	unput(zconftext[0]);
-	BEGIN(COMMAND);
-}
-	YY_BREAK
-
-case 6:
-YY_RULE_SETUP
-{
-		struct kconf_id *id = kconf_id_lookup(zconftext, zconfleng);
-		BEGIN(PARAM);
-		current_pos.file = current_file;
-		current_pos.lineno = current_file->lineno;
-		if (id && id->flags & TF_COMMAND) {
-			zconflval.id = id;
-			return id->token;
-		}
-		alloc_string(zconftext, zconfleng);
-		zconflval.string = text;
-		return T_WORD;
-	}
-	YY_BREAK
-case 7:
-YY_RULE_SETUP
-
-	YY_BREAK
-case 8:
-/* rule 8 can match eol */
-YY_RULE_SETUP
-{
-		BEGIN(INITIAL);
-		current_file->lineno++;
-		return T_EOL;
-	}
-	YY_BREAK
-
-case 9:
-YY_RULE_SETUP
-return T_AND;
-	YY_BREAK
-case 10:
-YY_RULE_SETUP
-return T_OR;
-	YY_BREAK
-case 11:
-YY_RULE_SETUP
-return T_OPEN_PAREN;
-	YY_BREAK
-case 12:
-YY_RULE_SETUP
-return T_CLOSE_PAREN;
-	YY_BREAK
-case 13:
-YY_RULE_SETUP
-return T_NOT;
-	YY_BREAK
-case 14:
-YY_RULE_SETUP
-return T_EQUAL;
-	YY_BREAK
-case 15:
-YY_RULE_SETUP
-return T_UNEQUAL;
-	YY_BREAK
-case 16:
-YY_RULE_SETUP
-{
-		str = zconftext[0];
-		new_string();
-		BEGIN(STRING);
-	}
-	YY_BREAK
-case 17:
-/* rule 17 can match eol */
-YY_RULE_SETUP
-BEGIN(INITIAL); current_file->lineno++; return T_EOL;
-	YY_BREAK
-case 18:
-YY_RULE_SETUP
-/* ignore */
-	YY_BREAK
-case 19:
-YY_RULE_SETUP
-{
-		struct kconf_id *id = kconf_id_lookup(zconftext, zconfleng);
-		if (id && id->flags & TF_PARAM) {
-			zconflval.id = id;
-			return id->token;
-		}
-		alloc_string(zconftext, zconfleng);
-		zconflval.string = text;
-		return T_WORD;
-	}
-	YY_BREAK
-case 20:
-YY_RULE_SETUP
-/* comment */
-	YY_BREAK
-case 21:
-/* rule 21 can match eol */
-YY_RULE_SETUP
-current_file->lineno++;
-	YY_BREAK
-case 22:
-YY_RULE_SETUP
-
-	YY_BREAK
-case YY_STATE_EOF(PARAM):
-{
-		BEGIN(INITIAL);
-	}
-	YY_BREAK
-
-case 23:
-/* rule 23 can match eol */
-*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */
-(yy_c_buf_p) = yy_cp -= 1;
-YY_DO_BEFORE_ACTION; /* set up zconftext again */
-YY_RULE_SETUP
-{
-		append_string(zconftext, zconfleng);
-		zconflval.string = text;
-		return T_WORD_QUOTE;
-	}
-	YY_BREAK
-case 24:
-YY_RULE_SETUP
-{
-		append_string(zconftext, zconfleng);
-	}
-	YY_BREAK
-case 25:
-/* rule 25 can match eol */
-*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */
-(yy_c_buf_p) = yy_cp -= 1;
-YY_DO_BEFORE_ACTION; /* set up zconftext again */
-YY_RULE_SETUP
-{
-		append_string(zconftext + 1, zconfleng - 1);
-		zconflval.string = text;
-		return T_WORD_QUOTE;
-	}
-	YY_BREAK
-case 26:
-YY_RULE_SETUP
-{
-		append_string(zconftext + 1, zconfleng - 1);
-	}
-	YY_BREAK
-case 27:
-YY_RULE_SETUP
-{
-		if (str == zconftext[0]) {
-			BEGIN(PARAM);
-			zconflval.string = text;
-			return T_WORD_QUOTE;
-		} else
-			append_string(zconftext, 1);
-	}
-	YY_BREAK
-case 28:
-/* rule 28 can match eol */
-YY_RULE_SETUP
-{
-		printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), \
                zconf_lineno());
-		current_file->lineno++;
-		BEGIN(INITIAL);
-		return T_EOL;
-	}
-	YY_BREAK
-case YY_STATE_EOF(STRING):
-{
-		BEGIN(INITIAL);
-	}
-	YY_BREAK
-
-case 29:
-YY_RULE_SETUP
-{
-		ts = 0;
-		for (i = 0; i < zconfleng; i++) {
-			if (zconftext[i] == '\t')
-				ts = (ts & ~7) + 8;
-			else
-				ts++;
-		}
-		last_ts = ts;
-		if (first_ts) {
-			if (ts < first_ts) {
-				zconf_endhelp();
-				return T_HELPTEXT;
-			}
-			ts -= first_ts;
-			while (ts > 8) {
-				append_string("        ", 8);
-				ts -= 8;
-			}
-			append_string("        ", ts);
-		}
-	}
-	YY_BREAK
-case 30:
-/* rule 30 can match eol */
-*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */
-(yy_c_buf_p) = yy_cp -= 1;
-YY_DO_BEFORE_ACTION; /* set up zconftext again */
-YY_RULE_SETUP
-{
-		current_file->lineno++;
-		zconf_endhelp();
-		return T_HELPTEXT;
-	}
-	YY_BREAK
-case 31:
-/* rule 31 can match eol */
-YY_RULE_SETUP
-{
-		current_file->lineno++;
-		append_string("\n", 1);
-	}
-	YY_BREAK
-case 32:
-YY_RULE_SETUP
-{
-		append_string(zconftext, zconfleng);
-		if (!first_ts)
-			first_ts = last_ts;
-	}
-	YY_BREAK
-case YY_STATE_EOF(HELP):
-{
-		zconf_endhelp();
-		return T_HELPTEXT;
-	}
-	YY_BREAK
-
-case YY_STATE_EOF(INITIAL):
-case YY_STATE_EOF(COMMAND):
-{
-	if (current_file) {
-		zconf_endfile();
-		return T_EOL;
-	}
-	fclose(zconfin);
-	yyterminate();
-}
-	YY_BREAK
-case 33:
-YY_RULE_SETUP
-YY_FATAL_ERROR( "flex scanner jammed" );
-	YY_BREAK
-
-	case YY_END_OF_BUFFER:
-		{
-		/* Amount of text matched not including the EOB char. */
-		int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
-
-		/* Undo the effects of YY_DO_BEFORE_ACTION. */
-		*yy_cp = (yy_hold_char);
-		YY_RESTORE_YY_MORE_OFFSET
-
-		if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
-			{
-			/* We're scanning a new file or input source.  It's
-			 * possible that this happened because the user
-			 * just pointed zconfin at a new source and called
-			 * zconflex().  If so, then we have to assure
-			 * consistency between YY_CURRENT_BUFFER and our
-			 * globals.  Here is the right place to do so, because
-			 * this is the first action (other than possibly a
-			 * back-up) that will match for the new input source.
-			 */
-			(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
-			YY_CURRENT_BUFFER_LVALUE->yy_input_file = zconfin;
-			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
-			}
-
-		/* Note that here we test for yy_c_buf_p "<=" to the position
-		 * of the first EOB in the buffer, since yy_c_buf_p will
-		 * already have been incremented past the NUL character
-		 * (since all states make transitions on EOB to the
-		 * end-of-buffer state).  Contrast this with the test
-		 * in input().
-		 */
-		if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
-			{ /* This was really a NUL. */
-			yy_state_type yy_next_state;
-
-			(yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
-
-			yy_current_state = yy_get_previous_state(  );
-
-			/* Okay, we're now positioned to make the NUL
-			 * transition.  We couldn't have
-			 * yy_get_previous_state() go ahead and do it
-			 * for us because it doesn't know how to deal
-			 * with the possibility of jamming (and we don't
-			 * want to build jamming into it because then it
-			 * will run more slowly).
-			 */
-
-			yy_next_state = yy_try_NUL_trans( yy_current_state );
-
-			yy_bp = (yytext_ptr) + YY_MORE_ADJ;
-
-			if ( yy_next_state )
-				{
-				/* Consume the NUL. */
-				yy_cp = ++(yy_c_buf_p);
-				yy_current_state = yy_next_state;
-				goto yy_match;
-				}
-
-			else
-				{
-				yy_cp = (yy_c_buf_p);
-				goto yy_find_action;
-				}
-			}
-
-		else switch ( yy_get_next_buffer(  ) )
-			{
-			case EOB_ACT_END_OF_FILE:
-				{
-				(yy_did_buffer_switch_on_eof) = 0;
-
-				if ( zconfwrap( ) )
-					{
-					/* Note: because we've taken care in
-					 * yy_get_next_buffer() to have set up
-					 * zconftext, we can now set up
-					 * yy_c_buf_p so that if some total
-					 * hoser (like flex itself) wants to
-					 * call the scanner after we return the
-					 * YY_NULL, it'll still work - another
-					 * YY_NULL will get returned.
-					 */
-					(yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
-
-					yy_act = YY_STATE_EOF(YY_START);
-					goto do_action;
-					}
-
-				else
-					{
-					if ( ! (yy_did_buffer_switch_on_eof) )
-						YY_NEW_FILE;
-					}
-				break;
-				}
-
-			case EOB_ACT_CONTINUE_SCAN:
-				(yy_c_buf_p) =
-					(yytext_ptr) + yy_amount_of_matched_text;
-
-				yy_current_state = yy_get_previous_state(  );
-
-				yy_cp = (yy_c_buf_p);
-				yy_bp = (yytext_ptr) + YY_MORE_ADJ;
-				goto yy_match;
-
-			case EOB_ACT_LAST_MATCH:
-				(yy_c_buf_p) =
-				&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
-
-				yy_current_state = yy_get_previous_state(  );
-
-				yy_cp = (yy_c_buf_p);
-				yy_bp = (yytext_ptr) + YY_MORE_ADJ;
-				goto yy_find_action;
-			}
-		break;
-		}
-
-	default:
-		YY_FATAL_ERROR(
-			"fatal flex scanner internal error--no action found" );
-	} /* end of action switch */
-		} /* end of scanning one token */
-} /* end of zconflex */
-
-/* yy_get_next_buffer - try to read in a new buffer
- *
- * Returns a code representing an action:
- *	EOB_ACT_LAST_MATCH -
- *	EOB_ACT_CONTINUE_SCAN - continue scanning from current position
- *	EOB_ACT_END_OF_FILE - end of file
- */
-static int yy_get_next_buffer (void)
-{
-    	register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
-	register char *source = (yytext_ptr);
-	register int number_to_move, i;
-	int ret_val;
-
-	if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
-		YY_FATAL_ERROR(
-		"fatal flex scanner internal error--end of buffer missed" );
-
-	if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
-		{ /* Don't try to fill the buffer, so this is an EOF. */
-		if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
-			{
-			/* We matched a single character, the EOB, so
-			 * treat this as a final EOF.
-			 */
-			return EOB_ACT_END_OF_FILE;
-			}
-
-		else
-			{
-			/* We matched some text prior to the EOB, first
-			 * process it.
-			 */
-			return EOB_ACT_LAST_MATCH;
-			}
-		}
-
-	/* Try to read more data. */
-
-	/* First move last chars to start of buffer. */
-	number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
-
-	for ( i = 0; i < number_to_move; ++i )
-		*(dest++) = *(source++);
-
-	if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
-		/* don't do the read, it's not guaranteed to return an EOF,
-		 * just force an EOF
-		 */
-		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
-
-	else
-		{
-			size_t num_to_read =
-			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
-
-		while ( num_to_read <= 0 )
-			{ /* Not enough room in the buffer - grow it. */
-
-			/* just a shorter name for the current buffer */
-			YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
-
-			int yy_c_buf_p_offset =
-				(int) ((yy_c_buf_p) - b->yy_ch_buf);
-
-			if ( b->yy_is_our_buffer )
-				{
-				int new_size = b->yy_buf_size * 2;
-
-				if ( new_size <= 0 )
-					b->yy_buf_size += b->yy_buf_size / 8;
-				else
-					b->yy_buf_size *= 2;
-
-				b->yy_ch_buf = (char *)
-					/* Include room in for 2 EOB chars. */
-					zconfrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2  );
-				}
-			else
-				/* Can't grow it, we don't own it. */
-				b->yy_ch_buf = 0;
-
-			if ( ! b->yy_ch_buf )
-				YY_FATAL_ERROR(
-				"fatal error - scanner input buffer overflow" );
-
-			(yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
-
-			num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
-						number_to_move - 1;
-
-			}
-
-		if ( num_to_read > YY_READ_BUF_SIZE )
-			num_to_read = YY_READ_BUF_SIZE;
-
-		/* Read in more data. */
-		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
-			(yy_n_chars), num_to_read );
-
-		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
-		}
-
-	if ( (yy_n_chars) == 0 )
-		{
-		if ( number_to_move == YY_MORE_ADJ )
-			{
-			ret_val = EOB_ACT_END_OF_FILE;
-			zconfrestart(zconfin  );
-			}
-
-		else
-			{
-			ret_val = EOB_ACT_LAST_MATCH;
-			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
-				YY_BUFFER_EOF_PENDING;
-			}
-		}
-
-	else
-		ret_val = EOB_ACT_CONTINUE_SCAN;
-
-	(yy_n_chars) += number_to_move;
-	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
-	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
-
-	(yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
-
-	return ret_val;
-}
-
-/* yy_get_previous_state - get the state just before the EOB char was reached */
-
-    static yy_state_type yy_get_previous_state (void)
-{
-	register yy_state_type yy_current_state;
-	register char *yy_cp;
-
-	yy_current_state = (yy_start);
-
-	for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
-		{
-		yy_current_state = yy_nxt[yy_current_state][(*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : \
                1)];
-		}
-
-	return yy_current_state;
-}
-
-/* yy_try_NUL_trans - try to make a transition on the NUL character
- *
- * synopsis
- *	next_state = yy_try_NUL_trans( current_state );
- */
-    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state )
-{
-	register int yy_is_jam;
-
-	yy_current_state = yy_nxt[yy_current_state][1];
-	yy_is_jam = (yy_current_state <= 0);
-
-	return yy_is_jam ? 0 : yy_current_state;
-}
-
-    static void yyunput (int c, register char * yy_bp )
-{
-	register char *yy_cp;
-
-    yy_cp = (yy_c_buf_p);
-
-	/* undo effects of setting up zconftext */
-	*yy_cp = (yy_hold_char);
-
-	if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
-		{ /* need to shift things up to make room */
-		/* +2 for EOB chars. */
-		register int number_to_move = (yy_n_chars) + 2;
-		register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
-					YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
-		register char *source =
-				&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
-
-		while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
-			*--dest = *--source;
-
-		yy_cp += (int) (dest - source);
-		yy_bp += (int) (dest - source);
-		YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
-			(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
-
-		if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
-			YY_FATAL_ERROR( "flex scanner push-back overflow" );
-		}
-
-	*--yy_cp = (char) c;
-
-	(yytext_ptr) = yy_bp;
-	(yy_hold_char) = *yy_cp;
-	(yy_c_buf_p) = yy_cp;
-}
-
-#ifndef YY_NO_INPUT
-#ifdef __cplusplus
-    static int yyinput (void)
-#else
-    static int input  (void)
-#endif
-
-{
-	int c;
-
-	*(yy_c_buf_p) = (yy_hold_char);
-
-	if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
-		{
-		/* yy_c_buf_p now points to the character we want to return.
-		 * If this occurs *before* the EOB characters, then it's a
-		 * valid NUL; if not, then we've hit the end of the buffer.
-		 */
-		if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
-			/* This was really a NUL. */
-			*(yy_c_buf_p) = '\0';
-
-		else
-			{ /* need more input */
-			int offset = (yy_c_buf_p) - (yytext_ptr);
-			++(yy_c_buf_p);
-
-			switch ( yy_get_next_buffer(  ) )
-				{
-				case EOB_ACT_LAST_MATCH:
-					/* This happens because yy_g_n_b()
-					 * sees that we've accumulated a
-					 * token and flags that we need to
-					 * try matching the token before
-					 * proceeding.  But for input(),
-					 * there's no matching to consider.
-					 * So convert the EOB_ACT_LAST_MATCH
-					 * to EOB_ACT_END_OF_FILE.
-					 */
-
-					/* Reset buffer status. */
-					zconfrestart(zconfin );
-
-					/*FALLTHROUGH*/
-
-				case EOB_ACT_END_OF_FILE:
-					{
-					if ( zconfwrap( ) )
-						return EOF;
-
-					if ( ! (yy_did_buffer_switch_on_eof) )
-						YY_NEW_FILE;
-#ifdef __cplusplus
-					return yyinput();
-#else
-					return input();
-#endif
-					}
-
-				case EOB_ACT_CONTINUE_SCAN:
-					(yy_c_buf_p) = (yytext_ptr) + offset;
-					break;
-				}
-			}
-		}
-
-	c = *(unsigned char *) (yy_c_buf_p);	/* cast for 8-bit char's */
-	*(yy_c_buf_p) = '\0';	/* preserve zconftext */
-	(yy_hold_char) = *++(yy_c_buf_p);
-
-	return c;
-}
-#endif	/* ifndef YY_NO_INPUT */
-
-/** Immediately switch to a different input stream.
- * @param input_file A readable stream.
- *
- * @note This function does not reset the start condition to @c INITIAL .
- */
-    void zconfrestart  (FILE * input_file )
-{
-
-	if ( ! YY_CURRENT_BUFFER ){
-        zconfensure_buffer_stack ();
-		YY_CURRENT_BUFFER_LVALUE =
-            zconf_create_buffer(zconfin,YY_BUF_SIZE );
-	}
-
-	zconf_init_buffer(YY_CURRENT_BUFFER,input_file );
-	zconf_load_buffer_state( );
-}
-
-/** Switch to a different input buffer.
- * @param new_buffer The new input buffer.
- *
- */
-    void zconf_switch_to_buffer  (YY_BUFFER_STATE  new_buffer )
-{
-
-	/* TODO. We should be able to replace this entire function body
-	 * with
-	 *		zconfpop_buffer_state();
-	 *		zconfpush_buffer_state(new_buffer);
-     */
-	zconfensure_buffer_stack ();
-	if ( YY_CURRENT_BUFFER == new_buffer )
-		return;
-
-	if ( YY_CURRENT_BUFFER )
-		{
-		/* Flush out information for old buffer. */
-		*(yy_c_buf_p) = (yy_hold_char);
-		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
-		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
-		}
-
-	YY_CURRENT_BUFFER_LVALUE = new_buffer;
-	zconf_load_buffer_state( );
-
-	/* We don't actually know whether we did this switch during
-	 * EOF (zconfwrap()) processing, but the only time this flag
-	 * is looked at is after zconfwrap() is called, so it's safe
-	 * to go ahead and always set it.
-	 */
-	(yy_did_buffer_switch_on_eof) = 1;
-}
-
-static void zconf_load_buffer_state  (void)
-{
-    	(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
-	(yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
-	zconfin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
-	(yy_hold_char) = *(yy_c_buf_p);
-}
-
-/** Allocate and initialize an input buffer state.
- * @param file A readable stream.
- * @param size The character buffer size in bytes. When in doubt, use @c \
                YY_BUF_SIZE.
- *
- * @return the allocated buffer state.
- */
-    YY_BUFFER_STATE zconf_create_buffer  (FILE * file, int  size )
-{
-	YY_BUFFER_STATE b;
-
-	b = (YY_BUFFER_STATE) zconfalloc(sizeof( struct yy_buffer_state )  );
-	if ( ! b )
-		YY_FATAL_ERROR( "out of dynamic memory in zconf_create_buffer()" );
-
-	b->yy_buf_size = size;
-
-	/* yy_ch_buf has to be 2 characters longer than the size given because
-	 * we need to put in 2 end-of-buffer characters.
-	 */
-	b->yy_ch_buf = (char *) zconfalloc(b->yy_buf_size + 2  );
-	if ( ! b->yy_ch_buf )
-		YY_FATAL_ERROR( "out of dynamic memory in zconf_create_buffer()" );
-
-	b->yy_is_our_buffer = 1;
-
-	zconf_init_buffer(b,file );
-
-	return b;
-}
-
-/** Destroy the buffer.
- * @param b a buffer created with zconf_create_buffer()
- *
- */
-    void zconf_delete_buffer (YY_BUFFER_STATE  b )
-{
-
-	if ( ! b )
-		return;
-
-	if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
-		YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
-
-	if ( b->yy_is_our_buffer )
-		zconffree((void *) b->yy_ch_buf  );
-
-	zconffree((void *) b  );
-}
-
-/* Initializes or reinitializes a buffer.
- * This function is sometimes called more than once on the same buffer,
- * such as during a zconfrestart() or at EOF.
- */
-    static void zconf_init_buffer  (YY_BUFFER_STATE  b, FILE * file )
-
-{
-	int oerrno = errno;
-
-	zconf_flush_buffer(b );
-
-	b->yy_input_file = file;
-	b->yy_fill_buffer = 1;
-
-    /* If b is the current buffer, then zconf_init_buffer was _probably_
-     * called from zconfrestart() or through yy_get_next_buffer.
-     * In that case, we don't want to reset the lineno or column.
-     */
-    if (b != YY_CURRENT_BUFFER){
-        b->yy_bs_lineno = 1;
-        b->yy_bs_column = 0;
-    }
-
-        b->yy_is_interactive = 0;
-
-	errno = oerrno;
-}
-
-/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
- * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
- *
- */
-    void zconf_flush_buffer (YY_BUFFER_STATE  b )
-{
-    	if ( ! b )
-		return;
-
-	b->yy_n_chars = 0;
-
-	/* We always need two end-of-buffer characters.  The first causes
-	 * a transition to the end-of-buffer state.  The second causes
-	 * a jam in that state.
-	 */
-	b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
-	b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
-
-	b->yy_buf_pos = &b->yy_ch_buf[0];
-
-	b->yy_at_bol = 1;
-	b->yy_buffer_status = YY_BUFFER_NEW;
-
-	if ( b == YY_CURRENT_BUFFER )
-		zconf_load_buffer_state( );
-}
-
-/** Pushes the new state onto the stack. The new state becomes
- *  the current state. This function will allocate the stack
- *  if necessary.
- *  @param new_buffer The new state.
- *
- */
-void zconfpush_buffer_state (YY_BUFFER_STATE new_buffer )
-{
-    	if (new_buffer == NULL)
-		return;
-
-	zconfensure_buffer_stack();
-
-	/* This block is copied from zconf_switch_to_buffer. */
-	if ( YY_CURRENT_BUFFER )
-		{
-		/* Flush out information for old buffer. */
-		*(yy_c_buf_p) = (yy_hold_char);
-		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
-		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
-		}
-
-	/* Only push if top exists. Otherwise, replace top. */
-	if (YY_CURRENT_BUFFER)
-		(yy_buffer_stack_top)++;
-	YY_CURRENT_BUFFER_LVALUE = new_buffer;
-
-	/* copied from zconf_switch_to_buffer. */
-	zconf_load_buffer_state( );
-	(yy_did_buffer_switch_on_eof) = 1;
-}
-
-/** Removes and deletes the top of the stack, if present.
- *  The next element becomes the new top.
- *
- */
-void zconfpop_buffer_state (void)
-{
-    	if (!YY_CURRENT_BUFFER)
-		return;
-
-	zconf_delete_buffer(YY_CURRENT_BUFFER );
-	YY_CURRENT_BUFFER_LVALUE = NULL;
-	if ((yy_buffer_stack_top) > 0)
-		--(yy_buffer_stack_top);
-
-	if (YY_CURRENT_BUFFER) {
-		zconf_load_buffer_state( );
-		(yy_did_buffer_switch_on_eof) = 1;
-	}
-}
-
-/* Allocates the stack if it does not exist.
- *  Guarantees space for at least one push.
- */
-static void zconfensure_buffer_stack (void)
-{
-	int num_to_alloc;
-
-	if (!(yy_buffer_stack)) {
-
-		/* First allocation is just for 2 elements, since we don't know if this
-		 * scanner will even need a stack. We use 2 instead of 1 to avoid an
-		 * immediate realloc on the next call.
-         */
-		num_to_alloc = 1;
-		(yy_buffer_stack) = (struct yy_buffer_state**)zconfalloc
-								(num_to_alloc * sizeof(struct yy_buffer_state*)
-								);
-
-		memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
-
-		(yy_buffer_stack_max) = num_to_alloc;
-		(yy_buffer_stack_top) = 0;
-		return;
-	}
-
-	if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
-
-		/* Increase the buffer to prepare for a possible push. */
-		int grow_size = 8 /* arbitrary grow size */;
-
-		num_to_alloc = (yy_buffer_stack_max) + grow_size;
-		(yy_buffer_stack) = (struct yy_buffer_state**)zconfrealloc
-								((yy_buffer_stack),
-								num_to_alloc * sizeof(struct yy_buffer_state*)
-								);
-
-		/* zero only the new slots.*/
-		memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct \
                yy_buffer_state*));
-		(yy_buffer_stack_max) = num_to_alloc;
-	}
-}
-
-/** Setup the input buffer state to scan directly from a user-specified character \
                buffer.
- * @param base the character buffer
- * @param size the size in bytes of the character buffer
- *
- * @return the newly allocated buffer state object.
- */
-YY_BUFFER_STATE zconf_scan_buffer  (char * base, yy_size_t  size )
-{
-	YY_BUFFER_STATE b;
-
-	if ( size < 2 ||
-	     base[size-2] != YY_END_OF_BUFFER_CHAR ||
-	     base[size-1] != YY_END_OF_BUFFER_CHAR )
-		/* They forgot to leave room for the EOB's. */
-		return 0;
-
-	b = (YY_BUFFER_STATE) zconfalloc(sizeof( struct yy_buffer_state )  );
-	if ( ! b )
-		YY_FATAL_ERROR( "out of dynamic memory in zconf_scan_buffer()" );
-
-	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
-	b->yy_buf_pos = b->yy_ch_buf = base;
-	b->yy_is_our_buffer = 0;
-	b->yy_input_file = 0;
-	b->yy_n_chars = b->yy_buf_size;
-	b->yy_is_interactive = 0;
-	b->yy_at_bol = 1;
-	b->yy_fill_buffer = 0;
-	b->yy_buffer_status = YY_BUFFER_NEW;
-
-	zconf_switch_to_buffer(b  );
-
-	return b;
-}
-
-/** Setup the input buffer state to scan a string. The next call to zconflex() will
- * scan from a @e copy of @a str.
- * @param yy_str a NUL-terminated string to scan
- *
- * @return the newly allocated buffer state object.
- * @note If you want to scan bytes that may contain NUL values, then use
- *       zconf_scan_bytes() instead.
- */
-YY_BUFFER_STATE zconf_scan_string (yyconst char * yy_str )
-{
-
-	return zconf_scan_bytes(yy_str,strlen(yy_str) );
-}
-
-/** Setup the input buffer state to scan the given bytes. The next call to \
                zconflex() will
- * scan from a @e copy of @a bytes.
- * @param bytes the byte buffer to scan
- * @param len the number of bytes in the buffer pointed to by @a bytes.
- *
- * @return the newly allocated buffer state object.
- */
-YY_BUFFER_STATE zconf_scan_bytes  (yyconst char * bytes, int  len )
-{
-	YY_BUFFER_STATE b;
-	char *buf;
-	yy_size_t n;
-	int i;
-
-	/* Get memory for full buffer, including space for trailing EOB's. */
-	n = len + 2;
-	buf = (char *) zconfalloc(n  );
-	if ( ! buf )
-		YY_FATAL_ERROR( "out of dynamic memory in zconf_scan_bytes()" );
-
-	for ( i = 0; i < len; ++i )
-		buf[i] = bytes[i];
-
-	buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
-
-	b = zconf_scan_buffer(buf,n );
-	if ( ! b )
-		YY_FATAL_ERROR( "bad buffer in zconf_scan_bytes()" );
-
-	/* It's okay to grow etc. this buffer, and we should throw it
-	 * away when we're done.
-	 */
-	b->yy_is_our_buffer = 1;
-
-	return b;
-}
-
-#ifndef YY_EXIT_FAILURE
-#define YY_EXIT_FAILURE 2
-#endif
-
-static void yy_fatal_error (yyconst char* msg )
-{
-    	(void) fprintf( stderr, "%s\n", msg );
-	exit( YY_EXIT_FAILURE );
-}
-
-/* Redefine yyless() so it works in section 3 code. */
-
-#undef yyless
-#define yyless(n) \
-	do \
-		{ \
-		/* Undo effects of setting up zconftext. */ \
-        int yyless_macro_arg = (n); \
-        YY_LESS_LINENO(yyless_macro_arg);\
-		zconftext[zconfleng] = (yy_hold_char); \
-		(yy_c_buf_p) = zconftext + yyless_macro_arg; \
-		(yy_hold_char) = *(yy_c_buf_p); \
-		*(yy_c_buf_p) = '\0'; \
-		zconfleng = yyless_macro_arg; \
-		} \
-	while ( 0 )
-
-/* Accessor  methods (get/set functions) to struct members. */
-
-/** Get the current line number.
- *
- */
-int zconfget_lineno  (void)
-{
-
-    return zconflineno;
-}
-
-/** Get the input stream.
- *
- */
-FILE *zconfget_in  (void)
-{
-        return zconfin;
-}
-
-/** Get the output stream.
- *
- */
-FILE *zconfget_out  (void)
-{
-        return zconfout;
-}
-
-/** Get the length of the current token.
- *
- */
-int zconfget_leng  (void)
-{
-        return zconfleng;
-}
-
-/** Get the current token.
- *
- */
-
-char *zconfget_text  (void)
-{
-        return zconftext;
-}
-
-/** Set the current line number.
- * @param line_number
- *
- */
-void zconfset_lineno (int  line_number )
-{
-
-    zconflineno = line_number;
-}
-
-/** Set the input stream. This does not discard the current
- * input buffer.
- * @param in_str A readable stream.
- *
- * @see zconf_switch_to_buffer
- */
-void zconfset_in (FILE *  in_str )
-{
-        zconfin = in_str ;
-}
-
-void zconfset_out (FILE *  out_str )
-{
-        zconfout = out_str ;
-}
-
-int zconfget_debug  (void)
-{
-        return zconf_flex_debug;
-}
-
-void zconfset_debug (int  bdebug )
-{
-        zconf_flex_debug = bdebug ;
-}
-
-/* zconflex_destroy is for both reentrant and non-reentrant scanners. */
-int zconflex_destroy  (void)
-{
-
-    /* Pop the buffer stack, destroying each element. */
-	while(YY_CURRENT_BUFFER){
-		zconf_delete_buffer(YY_CURRENT_BUFFER  );
-		YY_CURRENT_BUFFER_LVALUE = NULL;
-		zconfpop_buffer_state();
-	}
-
-	/* Destroy the stack itself. */
-	zconffree((yy_buffer_stack) );
-	(yy_buffer_stack) = NULL;
-
-    return 0;
-}
-
-/*
- * Internal utility routines.
- */
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
-{
-	register int i;
-    	for ( i = 0; i < n; ++i )
-		s1[i] = s2[i];
-}
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * s )
-{
-	register int n;
-    	for ( n = 0; s[n]; ++n )
-		;
-
-	return n;
-}
-#endif
-
-void *zconfalloc (yy_size_t  size )
-{
-	return (void *) malloc( size );
-}
-
-void *zconfrealloc  (void * ptr, yy_size_t  size )
-{
-	/* The cast to (char *) in the following accommodates both
-	 * implementations that use char* generic pointers, and those
-	 * that use void* generic pointers.  It works with the latter
-	 * because both ANSI C and C++ allow castless assignment from
-	 * any pointer type to void*, and deal with argument conversions
-	 * as though doing an assignment.
-	 */
-	return (void *) realloc( (char *) ptr, size );
-}
-
-void zconffree (void * ptr )
-{
-	free( (char *) ptr );	/* see zconfrealloc() for (char *) cast */
-}
-
-#define YYTABLES_NAME "yytables"
-
-#undef YY_NEW_FILE
-#undef YY_FLUSH_BUFFER
-#undef yy_set_bol
-#undef yy_new_buffer
-#undef yy_set_interactive
-#undef yytext_ptr
-#undef YY_DO_BEFORE_ACTION
-
-#ifdef YY_DECL_IS_OURS
-#undef YY_DECL_IS_OURS
-#undef YY_DECL
-#endif
-
-void zconf_starthelp(void)
-{
-	new_string();
-	last_ts = first_ts = 0;
-	BEGIN(HELP);
-}
-
-static void zconf_endhelp(void)
-{
-	zconflval.string = text;
-	BEGIN(INITIAL);
-}
-
-/*
- * Try to open specified file with following names:
- * ./name
- * $(srctree)/name
- * The latter is used when srctree is separate from objtree
- * when compiling the kernel.
- * Return NULL if file is not found.
- */
-FILE *zconf_fopen(const char *name)
-{
-	char *env;
-	FILE *f;
-
-	f = fopen(name, "r");
-	if (!f && name[0] != '/') {
-		env = getenv(SRCTREE);
-		if (env) {
-			char *fullname = alloca(strlen(env) + strlen(name) + 2);
-			sprintf(fullname, "%s/%s", env, name);
-			f = fopen(fullname, "r");
-		}
-	}
-	return f;
-}
-
-void zconf_initscan(const char *name)
-{
-	zconfin = zconf_fopen(name);
-	if (!zconfin) {
-		printf("can't find file %s\n", name);
-		exit(1);
-	}
-
-	current_buf = malloc(sizeof(*current_buf));
-	memset(current_buf, 0, sizeof(*current_buf));
-
-	current_file = file_lookup(name);
-	current_file->lineno = 1;
-	current_file->flags = FILE_BUSY;
-}
-
-void zconf_nextfile(const char *name)
-{
-	struct file *file = file_lookup(name);
-	struct buffer *buf = malloc(sizeof(*buf));
-	memset(buf, 0, sizeof(*buf));
-
-	current_buf->state = YY_CURRENT_BUFFER;
-	zconfin = zconf_fopen(name);
-	if (!zconfin) {
-		printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name);
-		exit(1);
-	}
-	zconf_switch_to_buffer(zconf_create_buffer(zconfin,YY_BUF_SIZE));
-	buf->parent = current_buf;
-	current_buf = buf;
-
-	if (file->flags & FILE_BUSY) {
-		printf("recursive scan (%s)?\n", name);
-		exit(1);
-	}
-	if (file->flags & FILE_SCANNED) {
-		printf("file %s already scanned?\n", name);
-		exit(1);
-	}
-	file->flags |= FILE_BUSY;
-	file->lineno = 1;
-	file->parent = current_file;
-	current_file = file;
-}
-
-static void zconf_endfile(void)
-{
-	struct buffer *parent;
-
-	current_file->flags |= FILE_SCANNED;
-	current_file->flags &= ~FILE_BUSY;
-	current_file = current_file->parent;
-
-	parent = current_buf->parent;
-	if (parent) {
-		fclose(zconfin);
-		zconf_delete_buffer(YY_CURRENT_BUFFER);
-		zconf_switch_to_buffer(parent->state);
-	}
-	free(current_buf);
-	current_buf = parent;
-}
-
-int zconf_lineno(void)
-{
-	return current_pos.lineno;
-}
-
-char *zconf_curname(void)
-{
-	return current_pos.file ? current_pos.file->name : "<none>";
-}
diff --git a/scripts/kconfig/lexer.l b/scripts/kconfig/lexer.l
new file mode 100644
index 000000000..9c22cb554
--- /dev/null
+++ b/scripts/kconfig/lexer.l
@@ -0,0 +1,470 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ */
+%option nostdinit noyywrap never-interactive full ecs
+%option 8bit nodefault yylineno
+%x ASSIGN_VAL HELP STRING
+%{
+
+#include <assert.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "lkc.h"
+#include "parser.tab.h"
+
+#define YY_DECL		static int yylex1(void)
+
+#define START_STRSIZE	16
+
+static struct {
+	struct file *file;
+	int lineno;
+} current_pos;
+
+static int prev_prev_token = T_EOL;
+static int prev_token = T_EOL;
+static char *text;
+static int text_size, text_asize;
+
+struct buffer {
+	struct buffer *parent;
+	YY_BUFFER_STATE state;
+};
+
+static struct buffer *current_buf;
+
+static int last_ts, first_ts;
+
+static char *expand_token(const char *in, size_t n);
+static void append_expanded_string(const char *in);
+static void zconf_endhelp(void);
+static void zconf_endfile(void);
+
+static void new_string(void)
+{
+	text = xmalloc(START_STRSIZE);
+	text_asize = START_STRSIZE;
+	text_size = 0;
+	*text = 0;
+}
+
+static void append_string(const char *str, int size)
+{
+	int new_size = text_size + size + 1;
+	if (new_size > text_asize) {
+		new_size += START_STRSIZE - 1;
+		new_size &= -START_STRSIZE;
+		text = xrealloc(text, new_size);
+		text_asize = new_size;
+	}
+	memcpy(text + text_size, str, size);
+	text_size += size;
+	text[text_size] = 0;
+}
+
+static void alloc_string(const char *str, int size)
+{
+	text = xmalloc(size + 1);
+	memcpy(text, str, size);
+	text[size] = 0;
+}
+
+static void warn_ignored_character(char chr)
+{
+	fprintf(stderr,
+	        "%s:%d:warning: ignoring unsupported character '%c'\n",
+	        current_file->name, yylineno, chr);
+}
+%}
+
+n	[A-Za-z0-9_-]
+
+%%
+	int str = 0;
+	int ts, i;
+
+#.*			/* ignore comment */
+[ \t]*			/* whitespaces */
+\\\n			/* escaped new line */
+\n			return T_EOL;
+"allnoconfig_y"		return T_ALLNOCONFIG_Y;
+"bool"			return T_BOOL;
+"choice"		return T_CHOICE;
+"comment"		return T_COMMENT;
+"config"		return T_CONFIG;
+"def_bool"		return T_DEF_BOOL;
+"def_tristate"		return T_DEF_TRISTATE;
+"default"		return T_DEFAULT;
+"defconfig_list"	return T_DEFCONFIG_LIST;
+"depends"		return T_DEPENDS;
+"endchoice"		return T_ENDCHOICE;
+"endif"			return T_ENDIF;
+"endmenu"		return T_ENDMENU;
+"help"			return T_HELP;
+"hex"			return T_HEX;
+"if"			return T_IF;
+"imply"			return T_IMPLY;
+"int"			return T_INT;
+"mainmenu"		return T_MAINMENU;
+"menu"			return T_MENU;
+"menuconfig"		return T_MENUCONFIG;
+"modules"		return T_MODULES;
+"on"			return T_ON;
+"option"		return T_OPTION;
+"optional"		return T_OPTIONAL;
+"prompt"		return T_PROMPT;
+"range"			return T_RANGE;
+"select"		return T_SELECT;
+"source"		return T_SOURCE;
+"string"		return T_STRING;
+"tristate"		return T_TRISTATE;
+"visible"		return T_VISIBLE;
+"||"			return T_OR;
+"&&"			return T_AND;
+"="			return T_EQUAL;
+"!="			return T_UNEQUAL;
+"<"			return T_LESS;
+"<="			return T_LESS_EQUAL;
+">"			return T_GREATER;
+">="			return T_GREATER_EQUAL;
+"!"			return T_NOT;
+"("			return T_OPEN_PAREN;
+")"			return T_CLOSE_PAREN;
+":="			return T_COLON_EQUAL;
+"+="			return T_PLUS_EQUAL;
+\"|\'			{
+				str = yytext[0];
+				new_string();
+				BEGIN(STRING);
+			}
+{n}+			{
+				alloc_string(yytext, yyleng);
+				yylval.string = text;
+				return T_WORD;
+			}
+({n}|$)+		{
+				/* this token includes at least one '$' */
+				yylval.string = expand_token(yytext, yyleng);
+				if (strlen(yylval.string))
+					return T_WORD;
+				free(yylval.string);
+			}
+.			warn_ignored_character(*yytext);
+
+<ASSIGN_VAL>{
+	[^[:blank:]\n]+.*	{
+		alloc_string(yytext, yyleng);
+		yylval.string = text;
+		return T_ASSIGN_VAL;
+	}
+	\n	{ BEGIN(INITIAL); return T_EOL; }
+	.
+}
+
+<STRING>{
+	"$".*	append_expanded_string(yytext);
+	[^$'"\\\n]+	{
+		append_string(yytext, yyleng);
+	}
+	\\.?	{
+		append_string(yytext + 1, yyleng - 1);
+	}
+	\'|\"	{
+		if (str == yytext[0]) {
+			BEGIN(INITIAL);
+			yylval.string = text;
+			return T_WORD_QUOTE;
+		} else
+			append_string(yytext, 1);
+	}
+	\n	{
+		fprintf(stderr,
+			"%s:%d:warning: multi-line strings not supported\n",
+			zconf_curname(), zconf_lineno());
+		unput('\n');
+		BEGIN(INITIAL);
+		yylval.string = text;
+		return T_WORD_QUOTE;
+	}
+	<<EOF>>	{
+		BEGIN(INITIAL);
+		yylval.string = text;
+		return T_WORD_QUOTE;
+	}
+}
+
+<HELP>{
+	[ \t]+	{
+		ts = 0;
+		for (i = 0; i < yyleng; i++) {
+			if (yytext[i] == '\t')
+				ts = (ts & ~7) + 8;
+			else
+				ts++;
+		}
+		last_ts = ts;
+		if (first_ts) {
+			if (ts < first_ts) {
+				zconf_endhelp();
+				return T_HELPTEXT;
+			}
+			ts -= first_ts;
+			while (ts > 8) {
+				append_string("        ", 8);
+				ts -= 8;
+			}
+			append_string("        ", ts);
+		}
+	}
+	[ \t]*\n/[^ \t\n] {
+		zconf_endhelp();
+		return T_HELPTEXT;
+	}
+	[ \t]*\n	{
+		append_string("\n", 1);
+	}
+	[^ \t\n].* {
+		while (yyleng) {
+			if ((yytext[yyleng-1] != ' ') && (yytext[yyleng-1] != '\t'))
+				break;
+			yyleng--;
+		}
+		append_string(yytext, yyleng);
+		if (!first_ts)
+			first_ts = last_ts;
+	}
+	<<EOF>>	{
+		zconf_endhelp();
+		return T_HELPTEXT;
+	}
+}
+
+<<EOF>>	{
+	BEGIN(INITIAL);
+
+	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);
+
+	if (current_file) {
+		zconf_endfile();
+		return T_EOL;
+	}
+	fclose(yyin);
+	yyterminate();
+}
+
+%%
+
+/* second stage lexer */
+int yylex(void)
+{
+	int token;
+
+repeat:
+	token = yylex1();
+
+	if (prev_token == T_EOL || prev_token == T_HELPTEXT) {
+		if (token == T_EOL) {
+			/* Do not pass unneeded T_EOL to the parser. */
+			goto repeat;
+		} else {
+			/*
+			 * For the parser, update file/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.
+			 */
+			current_pos.file = current_file;
+			current_pos.lineno = yylineno;
+		}
+	}
+
+	if (prev_prev_token == T_EOL && prev_token == T_WORD &&
+	    (token == T_EQUAL || token == T_COLON_EQUAL || token == T_PLUS_EQUAL))
+		BEGIN(ASSIGN_VAL);
+
+	prev_prev_token = prev_token;
+	prev_token = token;
+
+	return token;
+}
+
+static char *expand_token(const char *in, size_t n)
+{
+	char *out;
+	int c;
+	char c2;
+	const char *rest, *end;
+
+	new_string();
+	append_string(in, n);
+
+	/* get the whole line because we do not know the end of token. */
+	while ((c = input()) != EOF) {
+		if (c == '\n') {
+			unput(c);
+			break;
+		}
+		c2 = c;
+		append_string(&c2, 1);
+	}
+
+	rest = text;
+	out = expand_one_token(&rest);
+
+	/* push back unused characters to the input stream */
+	end = rest + strlen(rest);
+	while (end > rest)
+		unput(*--end);
+
+	free(text);
+
+	return out;
+}
+
+static void append_expanded_string(const char *str)
+{
+	const char *end;
+	char *res;
+
+	str++;
+
+	res = expand_dollar(&str);
+
+	/* push back unused characters to the input stream */
+	end = str + strlen(str);
+	while (end > str)
+		unput(*--end);
+
+	append_string(res, strlen(res));
+
+	free(res);
+}
+
+void zconf_starthelp(void)
+{
+	new_string();
+	last_ts = first_ts = 0;
+	BEGIN(HELP);
+}
+
+static void zconf_endhelp(void)
+{
+	yylval.string = text;
+	BEGIN(INITIAL);
+}
+
+
+/*
+ * Try to open specified file with following names:
+ * ./name
+ * $(srctree)/name
+ * The latter is used when srctree is separate from objtree
+ * when compiling the kernel.
+ * Return NULL if file is not found.
+ */
+FILE *zconf_fopen(const char *name)
+{
+	char *env, fullname[PATH_MAX+1];
+	FILE *f;
+
+	f = fopen(name, "r");
+	if (!f && name != NULL && name[0] != '/') {
+		env = getenv(SRCTREE);
+		if (env) {
+			snprintf(fullname, sizeof(fullname),
+				 "%s/%s", env, name);
+			f = fopen(fullname, "r");
+		}
+	}
+	return f;
+}
+
+void zconf_initscan(const char *name)
+{
+	yyin = zconf_fopen(name);
+	if (!yyin) {
+		fprintf(stderr, "can't find file %s\n", name);
+		exit(1);
+	}
+
+	current_buf = xmalloc(sizeof(*current_buf));
+	memset(current_buf, 0, sizeof(*current_buf));
+
+	current_file = file_lookup(name);
+	yylineno = 1;
+}
+
+void zconf_nextfile(const char *name)
+{
+	struct file *iter;
+	struct file *file = file_lookup(name);
+	struct buffer *buf = xmalloc(sizeof(*buf));
+	memset(buf, 0, sizeof(*buf));
+
+	current_buf->state = YY_CURRENT_BUFFER;
+	yyin = zconf_fopen(file->name);
+	if (!yyin) {
+		fprintf(stderr, "%s:%d: can't open file \"%s\"\n",
+			zconf_curname(), zconf_lineno(), file->name);
+		exit(1);
+	}
+	yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
+	buf->parent = current_buf;
+	current_buf = buf;
+
+	current_file->lineno = yylineno;
+	file->parent = current_file;
+
+	for (iter = current_file; iter; iter = iter->parent) {
+		if (!strcmp(iter->name, file->name)) {
+			fprintf(stderr,
+				"Recursive inclusion detected.\n"
+				"Inclusion path:\n"
+				"  current file : %s\n", file->name);
+			iter = file;
+			do {
+				iter = iter->parent;
+				fprintf(stderr, "  included from: %s:%d\n",
+					iter->name, iter->lineno - 1);
+			} while (strcmp(iter->name, file->name));
+			exit(1);
+		}
+	}
+
+	yylineno = 1;
+	current_file = file;
+}
+
+static void zconf_endfile(void)
+{
+	struct buffer *parent;
+
+	current_file = current_file->parent;
+	if (current_file)
+		yylineno = current_file->lineno;
+
+	parent = current_buf->parent;
+	if (parent) {
+		fclose(yyin);
+		yy_delete_buffer(YY_CURRENT_BUFFER);
+		yy_switch_to_buffer(parent->state);
+	}
+	free(current_buf);
+	current_buf = parent;
+}
+
+int zconf_lineno(void)
+{
+	return current_pos.lineno;
+}
+
+const char *zconf_curname(void)
+{
+	return current_pos.file ? current_pos.file->name : "<none>";
+}
diff --git a/scripts/kconfig/list.h b/scripts/kconfig/list.h
new file mode 100644
index 000000000..45cb237ab
--- /dev/null
+++ b/scripts/kconfig/list.h
@@ -0,0 +1,132 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef LIST_H
+#define LIST_H
+
+/*
+ * Copied from include/linux/...
+ */
+
+#undef offsetof
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+
+/**
+ * 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.
+ *
+ */
+#define container_of(ptr, type, member) ({                      \
+	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) \
+	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.
+ */
+#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)
+{
+	return head->next == head;
+}
+
+/*
+ * Insert a new entry between two known consecutive entries.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+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;
+}
+
+/**
+ * list_add_tail - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it before
+ *
+ * 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)
+{
+	__list_add(_new, head->prev, head);
+}
+
+/*
+ * Delete a list entry by making the prev/next entries
+ * point to each other.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __list_del(struct list_head *prev, struct list_head *next)
+{
+	next->prev = prev;
+	prev->next = next;
+}
+
+#define LIST_POISON1  ((void *) 0x00100100)
+#define LIST_POISON2  ((void *) 0x00200200)
+/**
+ * list_del - deletes entry from list.
+ * @entry: the element to delete from the list.
+ * Note: list_empty() on entry does not return true after this, the entry is
+ * in an undefined state.
+ */
+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;
+}
+#endif
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index 527f60c99..bee2413bd 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -1,107 +1,137 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
- * Released under the terms of the GNU GPL v2.0.
  */
 
 #ifndef LKC_H
 #define LKC_H
 
-#include "expr.h"
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
 
-#ifndef KBUILD_NO_NLS
-# include <libintl.h>
-#else
-# define gettext(Msgid) ((const char *) (Msgid))
-# define textdomain(Domainname) ((const char *) (Domainname))
-# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname))
-#endif
+#include "expr.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-#ifdef LKC_DIRECT_LINK
-#define P(name,type,arg)	extern type name arg
-#else
-#include "lkc_defs.h"
-#define P(name,type,arg)	extern type (*name ## _p) arg
-#endif
 #include "lkc_proto.h"
-#undef P
 
 #define SRCTREE "srctree"
 
+#ifndef PACKAGE
 #define PACKAGE "linux"
-#define LOCALEDIR "/usr/share/locale"
-
-#define _(text) gettext(text)
-#define N_(text) (text)
-
-
-#define TF_COMMAND	0x0001
-#define TF_PARAM	0x0002
+#endif
 
-struct kconf_id {
-	int name;
-	int token;
-	unsigned int flags;
-	enum symbol_type stype;
+#ifndef CONFIG_
+#define CONFIG_ "CONFIG_"
+#endif
+static inline const char *CONFIG_prefix(void)
+{
+	return getenv( "CONFIG_" ) ?: CONFIG_;
+}
+#undef CONFIG_
+#define CONFIG_ CONFIG_prefix()
+
+enum conf_def_mode {
+	def_default,
+	def_yes,
+	def_mod,
+	def_y2m,
+	def_m2y,
+	def_no,
+	def_random
 };
 
-int zconfparse(void);
+extern int yylineno;
 void zconfdump(FILE *out);
-
-extern int zconfdebug;
 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);
-char *zconf_curname(void);
+const char *zconf_curname(void);
 
 /* confdata.c */
-extern const char conf_def_filename[];
+const char *conf_get_configname(void);
+void sym_set_change_count(int count);
+void sym_add_change_count(int count);
+bool conf_set_all_new_symbols(enum conf_def_mode mode);
+void conf_rewrite_mod_or_yes(enum conf_def_mode mode);
+void set_all_choice_values(struct symbol *csym);
+
+/* confdata.c and expr.c */
+static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out)
+{
+	assert(len != 0);
 
-char *conf_get_default_confname(void);
+	if (fwrite(str, len, count, out) != count)
+		fprintf(stderr, "Error in writing or end of file.\n");
+}
 
-/* kconfig_load.c */
-void kconfig_load(void);
+/* util.c */
+struct file *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);
+char *xstrdup(const char *s);
+char *xstrndup(const char *s, size_t n);
+
+/* lexer.l */
+int yylex(void);
+
+struct gstr {
+	size_t len;
+	char  *s;
+	/*
+	* when max_width is not zero long lines in string s (if any) get
+	* wrapped not to exceed the max_width value
+	*/
+	int max_width;
+};
+struct gstr str_new(void);
+void str_free(struct gstr *gs);
+void str_append(struct gstr *gs, const char *s);
+void str_printf(struct gstr *gs, const char *fmt, ...);
+const char *str_get(struct gstr *gs);
 
 /* menu.c */
-void menu_init(void);
+void _menu_init(void);
+void menu_warn(struct menu *menu, const char *fmt, ...);
 struct menu *menu_add_menu(void);
 void menu_end_menu(void);
 void menu_add_entry(struct symbol *sym);
-void menu_end_entry(void);
 void menu_add_dep(struct expr *dep);
-struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, \
struct expr *dep); +void menu_add_visibility(struct expr *dep);
 struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr \
*dep);  void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep);
 void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep);
+void menu_add_option_modules(void);
+void menu_add_option_defconfig_list(void);
+void menu_add_option_allnoconfig_y(void);
 void menu_finalize(struct menu *parent);
 void menu_set_type(int type);
 
-/* util.c */
-struct file *file_lookup(const char *name);
-int file_write_dep(const char *name);
+extern struct menu rootmenu;
 
-struct gstr {
-	size_t len;
-	char  *s;
-};
-struct gstr str_new(void);
-struct gstr str_assign(const char *s);
-void str_free(struct gstr *gs);
-void str_append(struct gstr *gs, const char *s);
-void str_printf(struct gstr *gs, const char *fmt, ...);
-const char *str_get(struct gstr *gs);
+bool menu_is_empty(struct menu *menu);
+bool menu_is_visible(struct menu *menu);
+bool menu_has_prompt(struct menu *menu);
+const char *menu_get_prompt(struct menu *menu);
+struct menu *menu_get_root_menu(struct menu *menu);
+struct menu *menu_get_parent_menu(struct menu *menu);
+bool menu_has_help(struct menu *menu);
+const char *menu_get_help(struct menu *menu);
+struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head);
+void menu_get_ext_help(struct menu *menu, struct gstr *help);
 
 /* symbol.c */
-void sym_init(void);
 void sym_clear_all_valid(void);
-void sym_set_changed(struct symbol *sym);
+struct symbol *sym_choice_default(struct symbol *sym);
+struct property *sym_get_range_prop(struct symbol *sym);
+const char *sym_get_string_default(struct symbol *sym);
 struct symbol *sym_check_deps(struct symbol *sym);
-struct property *prop_alloc(enum prop_type type, struct symbol *sym);
 struct symbol *prop_get_symbol(struct property *prop);
 
 static inline tristate sym_get_tristate_value(struct symbol *sym)
@@ -137,7 +167,7 @@ static inline bool sym_is_optional(struct symbol *sym)
 
 static inline bool sym_has_value(struct symbol *sym)
 {
-	return sym->flags & SYMBOL_NEW ? false : true;
+	return sym->flags & SYMBOL_DEF_USER ? true : false;
 }
 
 #ifdef __cplusplus
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h
index b6a389c5f..9e81be33c 100644
--- a/scripts/kconfig/lkc_proto.h
+++ b/scripts/kconfig/lkc_proto.h
@@ -1,41 +1,51 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <stdarg.h>
 
 /* confdata.c */
-P(conf_parse,void,(const char *name));
-P(conf_read,int,(const char *name));
-P(conf_read_simple,int,(const char *name));
-P(conf_write,int,(const char *name));
-
-/* menu.c */
-P(rootmenu,struct menu,);
-
-P(menu_is_visible,bool,(struct menu *menu));
-P(menu_get_prompt,const char *,(struct menu *menu));
-P(menu_get_root_menu,struct menu *,(struct menu *menu));
-P(menu_get_parent_menu,struct menu *,(struct menu *menu));
+void conf_parse(const char *name);
+int conf_read(const char *name);
+int conf_read_simple(const char *name, int);
+int conf_write_defconfig(const char *name);
+int conf_write(const char *name);
+int conf_write_autoconf(int overwrite);
+bool conf_get_changed(void);
+void conf_set_changed_callback(void (*fn)(void));
+void conf_set_message_callback(void (*fn)(const char *s));
 
 /* symbol.c */
-P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]);
-P(sym_change_count,int,);
+extern struct symbol * symbol_hash[SYMBOL_HASHSIZE];
+
+struct symbol * sym_lookup(const char *name, int flags);
+struct symbol * sym_find(const char *name);
+const char * sym_escape_string_value(const char *in);
+struct symbol ** sym_re_search(const char *pattern);
+const char * sym_type_name(enum symbol_type type);
+void sym_calc_value(struct symbol *sym);
+enum symbol_type sym_get_type(struct symbol *sym);
+bool sym_tristate_within_range(struct symbol *sym,tristate tri);
+bool sym_set_tristate_value(struct symbol *sym,tristate tri);
+tristate sym_toggle_tristate_value(struct symbol *sym);
+bool sym_string_valid(struct symbol *sym, const char *newval);
+bool sym_string_within_range(struct symbol *sym, const char *str);
+bool sym_set_string_value(struct symbol *sym, const char *newval);
+bool sym_is_changeable(struct symbol *sym);
+struct property * sym_get_choice_prop(struct symbol *sym);
+const char * sym_get_string_value(struct symbol *sym);
 
-P(sym_lookup,struct symbol *,(const char *name, int isconst));
-P(sym_find,struct symbol *,(const char *name));
-P(sym_re_search,struct symbol **,(const char *pattern));
-P(sym_type_name,const char *,(enum symbol_type type));
-P(sym_calc_value,void,(struct symbol *sym));
-P(sym_get_type,enum symbol_type,(struct symbol *sym));
-P(sym_tristate_within_range,bool,(struct symbol *sym,tristate tri));
-P(sym_set_tristate_value,bool,(struct symbol *sym,tristate tri));
-P(sym_toggle_tristate_value,tristate,(struct symbol *sym));
-P(sym_string_valid,bool,(struct symbol *sym, const char *newval));
-P(sym_string_within_range,bool,(struct symbol *sym, const char *str));
-P(sym_set_string_value,bool,(struct symbol *sym, const char *newval));
-P(sym_is_changable,bool,(struct symbol *sym));
-P(sym_get_choice_prop,struct property *,(struct symbol *sym));
-P(sym_get_default_prop,struct property *,(struct symbol *sym));
-P(sym_get_string_value,const char *,(struct symbol *sym));
+const char * prop_get_type_name(enum prop_type type);
 
-P(prop_get_type_name,const char *,(enum prop_type type));
+/* preprocess.c */
+enum variable_flavor {
+	VAR_SIMPLE,
+	VAR_RECURSIVE,
+	VAR_APPEND,
+};
+void env_write_dep(FILE *f, const char *auto_conf_name);
+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 */
-P(expr_compare_type,int,(enum expr_type t1, enum expr_type t2));
-P(expr_print,void,(struct expr *e, void (*fn)(void *, const char *), void *data, int \
prevtoken)); +void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, \
                const char *), void *data, int prevtoken);
diff --git a/scripts/kconfig/lxdialog/.gitignore \
b/scripts/kconfig/lxdialog/.gitignore deleted file mode 100644
index 90b08ff02..000000000
--- a/scripts/kconfig/lxdialog/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-#
-# Generated files
-#
-lxdialog
diff --git a/scripts/kconfig/lxdialog/BIG.FAT.WARNING \
b/scripts/kconfig/lxdialog/BIG.FAT.WARNING index 4cadb80d3..7cb5a7ec9 100644
--- a/scripts/kconfig/lxdialog/BIG.FAT.WARNING
+++ b/scripts/kconfig/lxdialog/BIG.FAT.WARNING
@@ -1,4 +1,4 @@
 This is NOT the official version of dialog.  This version has been
-significantly modified from the original.  It was used by the Linux
-kernel configuration script, and subsequently adapted for busybox.
-Please do not bother Savio Lam with questions about this program.
+significantly modified from the original.  It is for use by the Linux
+kernel configuration script.  Please do not bother Savio Lam with
+questions about this program.
diff --git a/scripts/kconfig/lxdialog/Makefile b/scripts/kconfig/lxdialog/Makefile
deleted file mode 100644
index 2c9dc48f8..000000000
--- a/scripts/kconfig/lxdialog/Makefile
+++ /dev/null
@@ -1,21 +0,0 @@
-# Makefile to build lxdialog package
-#
-
-check-lxdialog  := $(srctree)/$(src)/check-lxdialog.sh
-
-# Use reursively expanded variables so we do not call gcc unless
-# we really need to do so. (Do not call gcc as part of make mrproper)
-HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags)
-HOST_LOADLIBES   = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC))
-
-HOST_EXTRACFLAGS += -DLOCALE
-
-PHONY += dochecklxdialog
-$(obj)/dochecklxdialog:
-	$(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_EXTRACFLAGS) \
                $(HOST_LOADLIBES)
-
-hostprogs-y	:= lxdialog
-always		:= $(hostprogs-y) dochecklxdialog
-
-lxdialog-objs := checklist.o menubox.o textbox.o yesno.o inputbox.o \
-		 util.o lxdialog.o msgbox.o
diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh \
b/scripts/kconfig/lxdialog/check-lxdialog.sh deleted file mode 100755
index 5075ebf2d..000000000
--- a/scripts/kconfig/lxdialog/check-lxdialog.sh
+++ /dev/null
@@ -1,91 +0,0 @@
-#!/bin/sh
-# Check ncurses compatibility
-
-# What library to link
-ldflags()
-{
-	pkg-config --libs ncursesw 2>/dev/null && exit
-	pkg-config --libs ncurses 2>/dev/null && exit
-	for ext in so a dll.a dylib ; do
-		for lib in ncursesw ncurses curses ; do
-			$cc -print-file-name=lib${lib}.${ext} | grep -q /
-			if [ $? -eq 0 ]; then
-				echo "-l${lib}"
-				exit
-			fi
-		done
-	done
-	exit 1
-}
-
-# Where is ncurses.h?
-ccflags()
-{
-	if pkg-config --cflags ncursesw 2>/dev/null; then
-		echo '-DCURSES_LOC="<ncurses.h>" -DNCURSES_WIDECHAR=1'
-	elif pkg-config --cflags ncurses 2>/dev/null; then
-		echo '-DCURSES_LOC="<ncurses.h>"'
-	elif [ -f /usr/include/ncursesw/curses.h ]; then
-		echo '-I/usr/include/ncursesw -DCURSES_LOC="<curses.h>"'
-		echo ' -DNCURSES_WIDECHAR=1'
-	elif [ -f /usr/include/ncurses/ncurses.h ]; then
-		echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"'
-	elif [ -f /usr/include/ncurses/curses.h ]; then
-		echo '-I/usr/include/ncurses -DCURSES_LOC="<curses.h>"'
-	elif [ -f /usr/include/ncurses.h ]; then
-		echo '-DCURSES_LOC="<ncurses.h>"'
-	else
-		echo '-DCURSES_LOC="<curses.h>"'
-	fi
-}
-
-# Temp file, try to clean up after us
-tmp=.lxdialog.tmp
-trap "rm -f $tmp" 0 1 2 3 15
-
-# Check if we can link to ncurses
-check() {
-        $cc -x c - -o $tmp 2>/dev/null <<'EOF'
-#include CURSES_LOC
-main() {}
-EOF
-	if [ $? != 0 ]; then
-	    echo " *** Unable to find the ncurses libraries or the"       1>&2
-	    echo " *** required header files."                            1>&2
-	    echo " *** 'make menuconfig' requires the ncurses libraries." 1>&2
-	    echo " *** "                                                  1>&2
-	    echo " *** Install ncurses (ncurses-devel) and try again."    1>&2
-	    echo " *** "                                                  1>&2
-	    exit 1
-	fi
-}
-
-usage() {
-	printf "Usage: $0 [-check compiler options|-ccflags|-ldflags compiler options]\n"
-}
-
-if [ $# -eq 0 ]; then
-	usage
-	exit 1
-fi
-
-cc=""
-case "$1" in
-	"-check")
-		shift
-		cc="$@"
-		check
-		;;
-	"-ccflags")
-		ccflags
-		;;
-	"-ldflags")
-		shift
-		cc="$@"
-		ldflags
-		;;
-	"*")
-		usage
-		exit 1
-		;;
-esac
diff --git a/scripts/kconfig/lxdialog/checklist.c \
b/scripts/kconfig/lxdialog/checklist.c index be0200e9c..fd161cfff 100644
--- a/scripts/kconfig/lxdialog/checklist.c
+++ b/scripts/kconfig/lxdialog/checklist.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  *  checklist.c -- implements the checklist box
  *
@@ -5,20 +6,6 @@
  *     Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension
  *     Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two
  *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "dialog.h"
@@ -28,29 +15,35 @@ static int list_width, check_x, item_x;
 /*
  * Print list item
  */
-static void print_item(WINDOW * win, const char *item, int status, int choice,
-		       int selected)
+static void print_item(WINDOW * win, int choice, int selected)
 {
 	int i;
+	char *list_item = malloc(list_width + 1);
+
+	strncpy(list_item, item_str(), list_width - item_x);
+	list_item[list_width - item_x] = '\0';
 
 	/* Clear 'residue' of last item */
-	wattrset(win, menubox_attr);
+	wattrset(win, dlg.menubox.atr);
 	wmove(win, choice, 0);
 	for (i = 0; i < list_width; i++)
 		waddch(win, ' ');
 
 	wmove(win, choice, check_x);
-	wattrset(win, selected ? check_selected_attr : check_attr);
-	wprintw(win, "(%c)", status ? 'X' : ' ');
-
-	wattrset(win, selected ? tag_selected_attr : tag_attr);
-	mvwaddch(win, choice, item_x, item[0]);
-	wattrset(win, selected ? item_selected_attr : item_attr);
-	waddstr(win, (char *)item + 1);
+	wattrset(win, selected ? dlg.check_selected.atr
+		 : dlg.check.atr);
+	if (!item_is_tag(':'))
+		wprintw(win, "(%c)", item_is_tag('X') ? 'X' : ' ');
+
+	wattrset(win, selected ? dlg.tag_selected.atr : dlg.tag.atr);
+	mvwaddch(win, choice, item_x, list_item[0]);
+	wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr);
+	waddstr(win, list_item + 1);
 	if (selected) {
 		wmove(win, choice, check_x + 1);
 		wrefresh(win);
 	}
+	free(list_item);
 }
 
 /*
@@ -62,11 +55,11 @@ static void print_arrows(WINDOW * win, int choice, int item_no, \
int scroll,  wmove(win, y, x);
 
 	if (scroll > 0) {
-		wattrset(win, uarrow_attr);
+		wattrset(win, dlg.uarrow.atr);
 		waddch(win, ACS_UARROW);
 		waddstr(win, "(-)");
 	} else {
-		wattrset(win, menubox_attr);
+		wattrset(win, dlg.menubox.atr);
 		waddch(win, ACS_HLINE);
 		waddch(win, ACS_HLINE);
 		waddch(win, ACS_HLINE);
@@ -77,11 +70,11 @@ static void print_arrows(WINDOW * win, int choice, int item_no, \
int scroll,  wmove(win, y, x);
 
 	if ((height < item_no) && (scroll + choice < item_no - 1)) {
-		wattrset(win, darrow_attr);
+		wattrset(win, dlg.darrow.atr);
 		waddch(win, ACS_DARROW);
 		waddstr(win, "(+)");
 	} else {
-		wattrset(win, menubox_border_attr);
+		wattrset(win, dlg.menubox_border.atr);
 		waddch(win, ACS_HLINE);
 		waddch(win, ACS_HLINE);
 		waddch(win, ACS_HLINE);
@@ -109,53 +102,51 @@ static void print_buttons(WINDOW * dialog, int height, int \
                width, int selected)
  * in the style of radiolist (only one option turned on at a time).
  */
 int dialog_checklist(const char *title, const char *prompt, int height,
-		     int width, int list_height, int item_no,
-		     const char *const *items)
+		     int width, int list_height)
 {
 	int i, x, y, box_x, box_y;
-	int key = 0, button = 0, choice = 0, scroll = 0, max_choice, *status;
+	int key = 0, button = 0, choice = 0, scroll = 0, max_choice;
 	WINDOW *dialog, *list;
 
-	/* Allocate space for storing item on/off status */
-	if ((status = malloc(sizeof(int) * item_no)) == NULL) {
-		endwin();
-		fprintf(stderr,
-			"\nCan't allocate memory in dialog_checklist().\n");
-		exit(-1);
+	/* which item to highlight */
+	item_foreach() {
+		if (item_is_tag('X'))
+			choice = item_n();
+		if (item_is_selected()) {
+			choice = item_n();
+			break;
+		}
 	}
 
-	/* Initializes status */
-	for (i = 0; i < item_no; i++) {
-		status[i] = !strcasecmp(items[i * 3 + 2], "on");
-		if ((!choice && status[i])
-		    || !strcasecmp(items[i * 3 + 2], "selected"))
-			choice = i + 1;
-	}
-	if (choice)
-		choice--;
+do_resize:
+	if (getmaxy(stdscr) < (height + CHECKLIST_HEIGTH_MIN))
+		return -ERRDISPLAYTOOSMALL;
+	if (getmaxx(stdscr) < (width + CHECKLIST_WIDTH_MIN))
+		return -ERRDISPLAYTOOSMALL;
 
-	max_choice = MIN(list_height, item_no);
+	max_choice = MIN(list_height, item_count());
 
 	/* center dialog box on screen */
-	x = (COLS - width) / 2;
-	y = (LINES - height) / 2;
+	x = (getmaxx(stdscr) - width) / 2;
+	y = (getmaxy(stdscr) - height) / 2;
 
 	draw_shadow(stdscr, y, x, height, width);
 
 	dialog = newwin(height, width, y, x);
 	keypad(dialog, TRUE);
 
-	draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
-	wattrset(dialog, border_attr);
+	draw_box(dialog, 0, 0, height, width,
+		 dlg.dialog.atr, dlg.border.atr);
+	wattrset(dialog, dlg.border.atr);
 	mvwaddch(dialog, height - 3, 0, ACS_LTEE);
 	for (i = 0; i < width - 2; i++)
 		waddch(dialog, ACS_HLINE);
-	wattrset(dialog, dialog_attr);
+	wattrset(dialog, dlg.dialog.atr);
 	waddch(dialog, ACS_RTEE);
 
 	print_title(dialog, title, width);
 
-	wattrset(dialog, dialog_attr);
+	wattrset(dialog, dlg.dialog.atr);
 	print_autowrap(dialog, prompt, width - 2, 1, 3);
 
 	list_width = width - 6;
@@ -164,18 +155,19 @@ int dialog_checklist(const char *title, const char *prompt, int \
height,  
 	/* create new window for the list */
 	list = subwin(dialog, list_height, list_width, y + box_y + 1,
-	              x + box_x + 1);
+		      x + box_x + 1);
 
 	keypad(list, TRUE);
 
 	/* draw a box around the list items */
 	draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2,
-	         menubox_border_attr, menubox_attr);
+		 dlg.menubox_border.atr, dlg.menubox.atr);
 
 	/* Find length of longest item in order to center checklist */
 	check_x = 0;
-	for (i = 0; i < item_no; i++)
-		check_x = MAX(check_x, +strlen(items[i * 3 + 1]) + 4);
+	item_foreach()
+		check_x = MAX(check_x, strlen(item_str()) + 4);
+	check_x = MIN(check_x, list_width);
 
 	check_x = (list_width - check_x) / 2;
 	item_x = check_x + 4;
@@ -187,11 +179,11 @@ int dialog_checklist(const char *title, const char *prompt, int \
height,  
 	/* Print the list */
 	for (i = 0; i < max_choice; i++) {
-		print_item(list, items[(scroll + i) * 3 + 1],
-			   status[i + scroll], i, i == choice);
+		item_set(scroll + i);
+		print_item(list, i, i == choice);
 	}
 
-	print_arrows(dialog, choice, item_no, scroll,
+	print_arrows(dialog, choice, item_count(), scroll,
 		     box_y, box_x + check_x + 5, list_height);
 
 	print_buttons(dialog, height, width, 0);
@@ -200,13 +192,14 @@ int dialog_checklist(const char *title, const char *prompt, int \
height,  wnoutrefresh(list);
 	doupdate();
 
-	while (key != ESC) {
+	while (key != KEY_ESC) {
 		key = wgetch(dialog);
 
-		for (i = 0; i < max_choice; i++)
-			if (toupper(key) ==
-			    toupper(items[(scroll + i) * 3 + 1][0]))
+		for (i = 0; i < max_choice; i++) {
+			item_set(i + scroll);
+			if (toupper(key) == toupper(item_str()[0]))
 				break;
+		}
 
 		if (i < max_choice || key == KEY_UP || key == KEY_DOWN ||
 		    key == '+' || key == '-') {
@@ -217,15 +210,16 @@ int dialog_checklist(const char *title, const char *prompt, int \
height,  /* Scroll list down */
 					if (list_height > 1) {
 						/* De-highlight current first item */
-						print_item(list, items[scroll * 3 + 1],
-							   status[scroll], 0, FALSE);
+						item_set(scroll);
+						print_item(list, 0, FALSE);
 						scrollok(list, TRUE);
 						wscrl(list, -1);
 						scrollok(list, FALSE);
 					}
 					scroll--;
-					print_item(list, items[scroll * 3 + 1], status[scroll], 0, TRUE);
-					print_arrows(dialog, choice, item_no,
+					item_set(scroll);
+					print_item(list, 0, TRUE);
+					print_arrows(dialog, choice, item_count(),
 						     scroll, box_y, box_x + check_x + 5, list_height);
 
 					wnoutrefresh(dialog);
@@ -236,23 +230,24 @@ int dialog_checklist(const char *title, const char *prompt, int \
height,  i = choice - 1;
 			} else if (key == KEY_DOWN || key == '+') {
 				if (choice == max_choice - 1) {
-					if (scroll + choice >= item_no - 1)
+					if (scroll + choice >= item_count() - 1)
 						continue;
 					/* Scroll list up */
 					if (list_height > 1) {
 						/* De-highlight current last item before scrolling up */
-						print_item(list, items[(scroll + max_choice - 1) * 3 + 1],
-							   status[scroll + max_choice - 1],
-							   max_choice - 1, FALSE);
+						item_set(scroll + max_choice - 1);
+						print_item(list,
+							    max_choice - 1,
+							    FALSE);
 						scrollok(list, TRUE);
 						wscrl(list, 1);
 						scrollok(list, FALSE);
 					}
 					scroll++;
-					print_item(list, items[(scroll + max_choice - 1) * 3 + 1],
-						   status[scroll + max_choice - 1], max_choice - 1, TRUE);
+					item_set(scroll + max_choice - 1);
+					print_item(list, max_choice - 1, TRUE);
 
-					print_arrows(dialog, choice, item_no,
+					print_arrows(dialog, choice, item_count(),
 						     scroll, box_y, box_x + check_x + 5, list_height);
 
 					wnoutrefresh(dialog);
@@ -264,12 +259,12 @@ int dialog_checklist(const char *title, const char *prompt, int \
height,  }
 			if (i != choice) {
 				/* De-highlight current item */
-				print_item(list, items[(scroll + choice) * 3 + 1],
-					   status[scroll + choice], choice, FALSE);
+				item_set(scroll + choice);
+				print_item(list, choice, FALSE);
 				/* Highlight new item */
 				choice = i;
-				print_item(list, items[(scroll + choice) * 3 + 1],
-					   status[scroll + choice], choice, TRUE);
+				item_set(scroll + choice);
+				print_item(list, choice, TRUE);
 				wnoutrefresh(dialog);
 				wrefresh(list);
 			}
@@ -279,10 +274,19 @@ int dialog_checklist(const char *title, const char *prompt, int \
height,  case 'H':
 		case 'h':
 		case '?':
-			fprintf(stderr, "%s", items[(scroll + choice) * 3]);
+			button = 1;
+			/* fall-through */
+		case 'S':
+		case 's':
+		case ' ':
+		case '\n':
+			item_foreach()
+				item_set_selected(0);
+			item_set(scroll + choice);
+			item_set_selected(1);
+			delwin(list);
 			delwin(dialog);
-			free(status);
-			return 1;
+			return button;
 		case TAB:
 		case KEY_LEFT:
 		case KEY_RIGHT:
@@ -292,42 +296,24 @@ int dialog_checklist(const char *title, const char *prompt, int \
height,  print_buttons(dialog, height, width, button);
 			wrefresh(dialog);
 			break;
-		case 'S':
-		case 's':
-		case ' ':
-		case '\n':
-			if (!button) {
-				if (!status[scroll + choice]) {
-					for (i = 0; i < item_no; i++)
-						status[i] = 0;
-					status[scroll + choice] = 1;
-					for (i = 0; i < max_choice; i++)
-						print_item(list, items[(scroll + i) * 3 + 1],
-							   status[scroll + i], i, i == choice);
-				}
-				wnoutrefresh(dialog);
-				wrefresh(list);
-
-				for (i = 0; i < item_no; i++)
-					if (status[i])
-						fprintf(stderr, "%s", items[i * 3]);
-			} else
-				fprintf(stderr, "%s", items[(scroll + choice) * 3]);
-			delwin(dialog);
-			free(status);
-			return button;
 		case 'X':
 		case 'x':
-			key = ESC;
-		case ESC:
+			key = KEY_ESC;
 			break;
+		case KEY_ESC:
+			key = on_key_esc(dialog);
+			break;
+		case KEY_RESIZE:
+			delwin(list);
+			delwin(dialog);
+			on_key_resize();
+			goto do_resize;
 		}
 
 		/* Now, update everything... */
 		doupdate();
 	}
-
+	delwin(list);
 	delwin(dialog);
-	free(status);
-	return -1;		/* ESC pressed */
+	return key;		/* ESC pressed */
 }
diff --git a/scripts/kconfig/lxdialog/colors.h b/scripts/kconfig/lxdialog/colors.h
deleted file mode 100644
index db071df12..000000000
--- a/scripts/kconfig/lxdialog/colors.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- *  colors.h -- color attribute definitions
- *
- *  AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- *   Default color definitions
- *
- *   *_FG = foreground
- *   *_BG = background
- *   *_HL = highlight?
- */
-#define SCREEN_FG                    COLOR_CYAN
-#define SCREEN_BG                    COLOR_BLUE
-#define SCREEN_HL                    TRUE
-
-#define SHADOW_FG                    COLOR_BLACK
-#define SHADOW_BG                    COLOR_BLACK
-#define SHADOW_HL                    TRUE
-
-#define DIALOG_FG                    COLOR_BLACK
-#define DIALOG_BG                    COLOR_WHITE
-#define DIALOG_HL                    FALSE
-
-#define TITLE_FG                     COLOR_YELLOW
-#define TITLE_BG                     COLOR_WHITE
-#define TITLE_HL                     TRUE
-
-#define BORDER_FG                    COLOR_WHITE
-#define BORDER_BG                    COLOR_WHITE
-#define BORDER_HL                    TRUE
-
-#define BUTTON_ACTIVE_FG             COLOR_WHITE
-#define BUTTON_ACTIVE_BG             COLOR_BLUE
-#define BUTTON_ACTIVE_HL             TRUE
-
-#define BUTTON_INACTIVE_FG           COLOR_BLACK
-#define BUTTON_INACTIVE_BG           COLOR_WHITE
-#define BUTTON_INACTIVE_HL           FALSE
-
-#define BUTTON_KEY_ACTIVE_FG         COLOR_WHITE
-#define BUTTON_KEY_ACTIVE_BG         COLOR_BLUE
-#define BUTTON_KEY_ACTIVE_HL         TRUE
-
-#define BUTTON_KEY_INACTIVE_FG       COLOR_RED
-#define BUTTON_KEY_INACTIVE_BG       COLOR_WHITE
-#define BUTTON_KEY_INACTIVE_HL       FALSE
-
-#define BUTTON_LABEL_ACTIVE_FG       COLOR_YELLOW
-#define BUTTON_LABEL_ACTIVE_BG       COLOR_BLUE
-#define BUTTON_LABEL_ACTIVE_HL       TRUE
-
-#define BUTTON_LABEL_INACTIVE_FG     COLOR_BLACK
-#define BUTTON_LABEL_INACTIVE_BG     COLOR_WHITE
-#define BUTTON_LABEL_INACTIVE_HL     TRUE
-
-#define INPUTBOX_FG                  COLOR_BLACK
-#define INPUTBOX_BG                  COLOR_WHITE
-#define INPUTBOX_HL                  FALSE
-
-#define INPUTBOX_BORDER_FG           COLOR_BLACK
-#define INPUTBOX_BORDER_BG           COLOR_WHITE
-#define INPUTBOX_BORDER_HL           FALSE
-
-#define SEARCHBOX_FG                 COLOR_BLACK
-#define SEARCHBOX_BG                 COLOR_WHITE
-#define SEARCHBOX_HL                 FALSE
-
-#define SEARCHBOX_TITLE_FG           COLOR_YELLOW
-#define SEARCHBOX_TITLE_BG           COLOR_WHITE
-#define SEARCHBOX_TITLE_HL           TRUE
-
-#define SEARCHBOX_BORDER_FG          COLOR_WHITE
-#define SEARCHBOX_BORDER_BG          COLOR_WHITE
-#define SEARCHBOX_BORDER_HL          TRUE
-
-#define POSITION_INDICATOR_FG        COLOR_YELLOW
-#define POSITION_INDICATOR_BG        COLOR_WHITE
-#define POSITION_INDICATOR_HL        TRUE
-
-#define MENUBOX_FG                   COLOR_BLACK
-#define MENUBOX_BG                   COLOR_WHITE
-#define MENUBOX_HL                   FALSE
-
-#define MENUBOX_BORDER_FG            COLOR_WHITE
-#define MENUBOX_BORDER_BG            COLOR_WHITE
-#define MENUBOX_BORDER_HL            TRUE
-
-#define ITEM_FG                      COLOR_BLACK
-#define ITEM_BG                      COLOR_WHITE
-#define ITEM_HL                      FALSE
-
-#define ITEM_SELECTED_FG             COLOR_WHITE
-#define ITEM_SELECTED_BG             COLOR_BLUE
-#define ITEM_SELECTED_HL             TRUE
-
-#define TAG_FG                       COLOR_YELLOW
-#define TAG_BG                       COLOR_WHITE
-#define TAG_HL                       TRUE
-
-#define TAG_SELECTED_FG              COLOR_YELLOW
-#define TAG_SELECTED_BG              COLOR_BLUE
-#define TAG_SELECTED_HL              TRUE
-
-#define TAG_KEY_FG                   COLOR_YELLOW
-#define TAG_KEY_BG                   COLOR_WHITE
-#define TAG_KEY_HL                   TRUE
-
-#define TAG_KEY_SELECTED_FG          COLOR_YELLOW
-#define TAG_KEY_SELECTED_BG          COLOR_BLUE
-#define TAG_KEY_SELECTED_HL          TRUE
-
-#define CHECK_FG                     COLOR_BLACK
-#define CHECK_BG                     COLOR_WHITE
-#define CHECK_HL                     FALSE
-
-#define CHECK_SELECTED_FG            COLOR_WHITE
-#define CHECK_SELECTED_BG            COLOR_BLUE
-#define CHECK_SELECTED_HL            TRUE
-
-#define UARROW_FG                    COLOR_GREEN
-#define UARROW_BG                    COLOR_WHITE
-#define UARROW_HL                    TRUE
-
-#define DARROW_FG                    COLOR_GREEN
-#define DARROW_BG                    COLOR_WHITE
-#define DARROW_HL                    TRUE
-
-/* End of default color definitions */
-
-#define C_ATTR(x,y)                  ((x ? A_BOLD : 0) | COLOR_PAIR((y)))
-#define COLOR_NAME_LEN               10
-#define COLOR_COUNT                  8
-
-/*
- * Global variables
- */
-
-extern int color_table[][3];
diff --git a/scripts/kconfig/lxdialog/dialog.h b/scripts/kconfig/lxdialog/dialog.h
index af3cf716e..68b565e3c 100644
--- a/scripts/kconfig/lxdialog/dialog.h
+++ b/scripts/kconfig/lxdialog/dialog.h
@@ -1,21 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  *  dialog.h -- common declarations for all dialog modules
  *
  *  AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <sys/types.h>
@@ -24,11 +11,12 @@
 #include <ctype.h>
 #include <stdlib.h>
 #include <string.h>
+#include <stdbool.h>
 
 #ifdef __sun__
 #define CURS_MACROS
 #endif
-#include CURSES_LOC
+#include <ncurses.h>
 
 /*
  * Colors in ncurses 1.9.9e do not work properly since foreground and
@@ -48,7 +36,7 @@
 
 #define TR(params) _tracef params
 
-#define ESC 27
+#define KEY_ESC 27
 #define TAB 9
 #define MAX_LEN 2048
 #define BUF_SIZE (10*1024)
@@ -86,63 +74,133 @@
 #define ACS_DARROW 'v'
 #endif
 
+/* error return codes */
+#define ERRDISPLAYTOOSMALL (KEY_MAX + 1)
+
 /*
- * Attribute names
+ *   Color definitions
  */
-#define screen_attr                   attributes[0]
-#define shadow_attr                   attributes[1]
-#define dialog_attr                   attributes[2]
-#define title_attr                    attributes[3]
-#define border_attr                   attributes[4]
-#define button_active_attr            attributes[5]
-#define button_inactive_attr          attributes[6]
-#define button_key_active_attr        attributes[7]
-#define button_key_inactive_attr      attributes[8]
-#define button_label_active_attr      attributes[9]
-#define button_label_inactive_attr    attributes[10]
-#define inputbox_attr                 attributes[11]
-#define inputbox_border_attr          attributes[12]
-#define searchbox_attr                attributes[13]
-#define searchbox_title_attr          attributes[14]
-#define searchbox_border_attr         attributes[15]
-#define position_indicator_attr       attributes[16]
-#define menubox_attr                  attributes[17]
-#define menubox_border_attr           attributes[18]
-#define item_attr                     attributes[19]
-#define item_selected_attr            attributes[20]
-#define tag_attr                      attributes[21]
-#define tag_selected_attr             attributes[22]
-#define tag_key_attr                  attributes[23]
-#define tag_key_selected_attr         attributes[24]
-#define check_attr                    attributes[25]
-#define check_selected_attr           attributes[26]
-#define uarrow_attr                   attributes[27]
-#define darrow_attr                   attributes[28]
-
-/* number of attributes */
-#define ATTRIBUTE_COUNT               29
+struct dialog_color {
+	chtype atr;	/* Color attribute */
+	int fg;		/* foreground */
+	int bg;		/* background */
+	int hl;		/* highlight this item */
+};
+
+struct subtitle_list {
+	struct subtitle_list *next;
+	const char *text;
+};
+
+struct dialog_info {
+	const char *backtitle;
+	struct subtitle_list *subtitles;
+	struct dialog_color screen;
+	struct dialog_color shadow;
+	struct dialog_color dialog;
+	struct dialog_color title;
+	struct dialog_color border;
+	struct dialog_color button_active;
+	struct dialog_color button_inactive;
+	struct dialog_color button_key_active;
+	struct dialog_color button_key_inactive;
+	struct dialog_color button_label_active;
+	struct dialog_color button_label_inactive;
+	struct dialog_color inputbox;
+	struct dialog_color inputbox_border;
+	struct dialog_color searchbox;
+	struct dialog_color searchbox_title;
+	struct dialog_color searchbox_border;
+	struct dialog_color position_indicator;
+	struct dialog_color menubox;
+	struct dialog_color menubox_border;
+	struct dialog_color item;
+	struct dialog_color item_selected;
+	struct dialog_color tag;
+	struct dialog_color tag_selected;
+	struct dialog_color tag_key;
+	struct dialog_color tag_key_selected;
+	struct dialog_color check;
+	struct dialog_color check_selected;
+	struct dialog_color uarrow;
+	struct dialog_color darrow;
+};
 
 /*
  * Global variables
  */
-extern bool use_colors;
-extern bool use_shadow;
-
-extern chtype attributes[];
-
-extern const char *backtitle;
+extern struct dialog_info dlg;
+extern char dialog_input_result[];
+extern int saved_x, saved_y;		/* Needed in signal handler in mconf.c */
 
 /*
  * Function prototypes
  */
-extern void create_rc(const char *filename);
-extern int parse_rc(void);
 
-void init_dialog(void);
-void end_dialog(void);
+/* item list as used by checklist and menubox */
+void item_reset(void);
+void item_make(const char *fmt, ...);
+void item_add_str(const char *fmt, ...);
+void item_set_tag(char tag);
+void item_set_data(void *p);
+void item_set_selected(int val);
+int item_activate_selected(void);
+void *item_data(void);
+char item_tag(void);
+
+/* item list manipulation for lxdialog use */
+#define MAXITEMSTR 200
+struct dialog_item {
+	char str[MAXITEMSTR];	/* prompt displayed */
+	char tag;
+	void *data;	/* pointer to menu item - used by menubox+checklist */
+	int selected;	/* Set to 1 by dialog_*() function if selected. */
+};
+
+/* list of lialog_items */
+struct dialog_list {
+	struct dialog_item node;
+	struct dialog_list *next;
+};
+
+extern struct dialog_list *item_cur;
+extern struct dialog_list item_nil;
+extern struct dialog_list *item_head;
+
+int item_count(void);
+void item_set(int n);
+int item_n(void);
+const char *item_str(void);
+int item_is_selected(void);
+int item_is_tag(char tag);
+#define item_foreach() \
+	for (item_cur = item_head ? item_head: item_cur; \
+	     item_cur && (item_cur != &item_nil); item_cur = item_cur->next)
+
+/* generic key handlers */
+int on_key_esc(WINDOW *win);
+int on_key_resize(void);
+
+/* minimum (re)size values */
+#define CHECKLIST_HEIGTH_MIN 6	/* For dialog_checklist() */
+#define CHECKLIST_WIDTH_MIN 6
+#define INPUTBOX_HEIGTH_MIN 2	/* For dialog_inputbox() */
+#define INPUTBOX_WIDTH_MIN 2
+#define MENUBOX_HEIGTH_MIN 15	/* For dialog_menu() */
+#define MENUBOX_WIDTH_MIN 65
+#define TEXTBOX_HEIGTH_MIN 8	/* For dialog_textbox() */
+#define TEXTBOX_WIDTH_MIN 8
+#define YESNO_HEIGTH_MIN 4	/* For dialog_yesno() */
+#define YESNO_WIDTH_MIN 4
+#define WINDOW_HEIGTH_MIN 19	/* For init_dialog() */
+#define WINDOW_WIDTH_MIN 80
+
+int init_dialog(const char *backtitle);
+void set_dialog_backtitle(const char *backtitle);
+void set_dialog_subtitles(struct subtitle_list *subtitles);
+void end_dialog(int x, int y);
 void attr_clear(WINDOW * win, int height, int width, chtype attr);
 void dialog_clear(void);
-void color_setup(void);
 void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x);
 void print_button(WINDOW * win, const char *label, int y, int x, int selected);
 void print_title(WINDOW *dialog, const char *title, int width);
@@ -154,14 +212,17 @@ int first_alpha(const char *string, const char *exempt);
 int dialog_yesno(const char *title, const char *prompt, int height, int width);
 int dialog_msgbox(const char *title, const char *prompt, int height,
 		  int width, int pause);
-int dialog_textbox(const char *title, const char *file, int height, int width);
-int dialog_menu(const char *title, const char *prompt, int height, int width,
-		int menu_height, const char *choice, int item_no,
-		const char *const *items);
+
+
+typedef void (*update_text_fn)(char *buf, size_t start, size_t end, void
+			       *_data);
+int dialog_textbox(const char *title, char *tbuf, int initial_height,
+		   int initial_width, int *keys, int *_vscroll, int *_hscroll,
+		   update_text_fn update_text, void *data);
+int dialog_menu(const char *title, const char *prompt,
+		const void *selected, int *s_scroll);
 int dialog_checklist(const char *title, const char *prompt, int height,
-		     int width, int list_height, int item_no,
-		     const char *const *items);
-extern char dialog_input_result[];
+		     int width, int list_height);
 int dialog_inputbox(const char *title, const char *prompt, int height,
 		    int width, const char *init);
 
diff --git a/scripts/kconfig/lxdialog/inputbox.c \
b/scripts/kconfig/lxdialog/inputbox.c index 779503726..1dcfb288e 100644
--- a/scripts/kconfig/lxdialog/inputbox.c
+++ b/scripts/kconfig/lxdialog/inputbox.c
@@ -1,22 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  *  inputbox.c -- implements the input box
  *
  *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
  *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "dialog.h"
@@ -42,33 +29,46 @@ static void print_buttons(WINDOW * dialog, int height, int width, \
                int selected)
  * Display a dialog box for inputing a string
  */
 int dialog_inputbox(const char *title, const char *prompt, int height, int width,
-                    const char *init)
+		    const char *init)
 {
 	int i, x, y, box_y, box_x, box_width;
-	int input_x = 0, scroll = 0, key = 0, button = -1;
+	int input_x = 0, key = 0, button = -1;
+	int show_x, len, pos;
 	char *instr = dialog_input_result;
 	WINDOW *dialog;
 
+	if (!init)
+		instr[0] = '\0';
+	else
+		strcpy(instr, init);
+
+do_resize:
+	if (getmaxy(stdscr) <= (height - INPUTBOX_HEIGTH_MIN))
+		return -ERRDISPLAYTOOSMALL;
+	if (getmaxx(stdscr) <= (width - INPUTBOX_WIDTH_MIN))
+		return -ERRDISPLAYTOOSMALL;
+
 	/* center dialog box on screen */
-	x = (COLS - width) / 2;
-	y = (LINES - height) / 2;
+	x = (getmaxx(stdscr) - width) / 2;
+	y = (getmaxy(stdscr) - height) / 2;
 
 	draw_shadow(stdscr, y, x, height, width);
 
 	dialog = newwin(height, width, y, x);
 	keypad(dialog, TRUE);
 
-	draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
-	wattrset(dialog, border_attr);
+	draw_box(dialog, 0, 0, height, width,
+		 dlg.dialog.atr, dlg.border.atr);
+	wattrset(dialog, dlg.border.atr);
 	mvwaddch(dialog, height - 3, 0, ACS_LTEE);
 	for (i = 0; i < width - 2; i++)
 		waddch(dialog, ACS_HLINE);
-	wattrset(dialog, dialog_attr);
+	wattrset(dialog, dlg.dialog.atr);
 	waddch(dialog, ACS_RTEE);
 
 	print_title(dialog, title, width);
 
-	wattrset(dialog, dialog_attr);
+	wattrset(dialog, dlg.dialog.atr);
 	print_autowrap(dialog, prompt, width - 2, 1, 3);
 
 	/* Draw the input field box */
@@ -76,27 +76,26 @@ int dialog_inputbox(const char *title, const char *prompt, int \
height, int width  getyx(dialog, y, x);
 	box_y = y + 2;
 	box_x = (width - box_width) / 2;
-	draw_box(dialog, y + 1, box_x - 1, 3, box_width + 2, border_attr, dialog_attr);
+	draw_box(dialog, y + 1, box_x - 1, 3, box_width + 2,
+		 dlg.dialog.atr, dlg.border.atr);
 
 	print_buttons(dialog, height, width, 0);
 
 	/* Set up the initial value */
 	wmove(dialog, box_y, box_x);
-	wattrset(dialog, inputbox_attr);
+	wattrset(dialog, dlg.inputbox.atr);
 
-	if (!init)
-		instr[0] = '\0';
-	else
-		strcpy(instr, init);
-
-	input_x = strlen(instr);
+	len = strlen(instr);
+	pos = len;
 
-	if (input_x >= box_width) {
-		scroll = input_x - box_width + 1;
+	if (len >= box_width) {
+		show_x = len - box_width + 1;
 		input_x = box_width - 1;
 		for (i = 0; i < box_width - 1; i++)
-			waddch(dialog, instr[scroll + i]);
+			waddch(dialog, instr[show_x + i]);
 	} else {
+		show_x = 0;
+		input_x = len;
 		waddstr(dialog, instr);
 	}
 
@@ -104,7 +103,7 @@ int dialog_inputbox(const char *title, const char *prompt, int \
height, int width  
 	wrefresh(dialog);
 
-	while (key != ESC) {
+	while (key != KEY_ESC) {
 		key = wgetch(dialog);
 
 		if (button == -1) {	/* Input box selected */
@@ -113,45 +112,105 @@ int dialog_inputbox(const char *title, const char *prompt, int \
height, int width  case KEY_UP:
 			case KEY_DOWN:
 				break;
-			case KEY_LEFT:
-				continue;
-			case KEY_RIGHT:
-				continue;
 			case KEY_BACKSPACE:
-			case 127:
-				if (input_x || scroll) {
-					wattrset(dialog, inputbox_attr);
-					if (!input_x) {
-						scroll = scroll < box_width - 1 ? 0 : scroll - (box_width - 1);
-						wmove(dialog, box_y, box_x);
-						for (i = 0; i < box_width; i++)
-							waddch(dialog,
-							       instr[scroll + input_x + i] ?
-							       instr[scroll + input_x + i] : ' ');
-						input_x = strlen(instr) - scroll;
+			case 8:   /* ^H */
+			case 127: /* ^? */
+				if (pos) {
+					wattrset(dialog, dlg.inputbox.atr);
+					if (input_x == 0) {
+						show_x--;
 					} else
 						input_x--;
-					instr[scroll + input_x] = '\0';
-					mvwaddch(dialog, box_y, input_x + box_x, ' ');
+
+					if (pos < len) {
+						for (i = pos - 1; i < len; i++) {
+							instr[i] = instr[i+1];
+						}
+					}
+
+					pos--;
+					len--;
+					instr[len] = '\0';
+					wmove(dialog, box_y, box_x);
+					for (i = 0; i < box_width; i++) {
+						if (!instr[show_x + i]) {
+							waddch(dialog, ' ');
+							break;
+						}
+						waddch(dialog, instr[show_x + i]);
+					}
 					wmove(dialog, box_y, input_x + box_x);
 					wrefresh(dialog);
 				}
 				continue;
+			case KEY_LEFT:
+				if (pos > 0) {
+					if (input_x > 0) {
+						wmove(dialog, box_y, --input_x + box_x);
+					} else if (input_x == 0) {
+						show_x--;
+						wmove(dialog, box_y, box_x);
+						for (i = 0; i < box_width; i++) {
+							if (!instr[show_x + i]) {
+								waddch(dialog, ' ');
+								break;
+							}
+							waddch(dialog, instr[show_x + i]);
+						}
+						wmove(dialog, box_y, box_x);
+					}
+					pos--;
+				}
+				continue;
+			case KEY_RIGHT:
+				if (pos < len) {
+					if (input_x < box_width - 1) {
+						wmove(dialog, box_y, ++input_x + box_x);
+					} else if (input_x == box_width - 1) {
+						show_x++;
+						wmove(dialog, box_y, box_x);
+						for (i = 0; i < box_width; i++) {
+							if (!instr[show_x + i]) {
+								waddch(dialog, ' ');
+								break;
+							}
+							waddch(dialog, instr[show_x + i]);
+						}
+						wmove(dialog, box_y, input_x + box_x);
+					}
+					pos++;
+				}
+				continue;
 			default:
 				if (key < 0x100 && isprint(key)) {
-					if (scroll + input_x < MAX_LEN) {
-						wattrset(dialog, inputbox_attr);
-						instr[scroll + input_x] = key;
-						instr[scroll + input_x + 1] = '\0';
+					if (len < MAX_LEN) {
+						wattrset(dialog, dlg.inputbox.atr);
+						if (pos < len) {
+							for (i = len; i > pos; i--)
+								instr[i] = instr[i-1];
+							instr[pos] = key;
+						} else {
+							instr[len] = key;
+						}
+						pos++;
+						len++;
+						instr[len] = '\0';
+
 						if (input_x == box_width - 1) {
-							scroll++;
-							wmove(dialog, box_y, box_x);
-							for (i = 0; i < box_width - 1; i++)
-								waddch(dialog, instr [scroll + i]);
+							show_x++;
 						} else {
-							wmove(dialog, box_y, input_x++ + box_x);
-							waddch(dialog, key);
+							input_x++;
 						}
+
+						wmove(dialog, box_y, box_x);
+						for (i = 0; i < box_width; i++) {
+							if (!instr[show_x + i]) {
+								waddch(dialog, ' ');
+								break;
+							}
+							waddch(dialog, instr[show_x + i]);
+						}
+						wmove(dialog, box_y, input_x + box_x);
 						wrefresh(dialog);
 					} else
 						flash();	/* Alarm user about overflow */
@@ -172,7 +231,7 @@ int dialog_inputbox(const char *title, const char *prompt, int \
height, int width  case KEY_LEFT:
 			switch (button) {
 			case -1:
-				button = 1;	/* Indicates "Cancel" button is selected */
+				button = 1;	/* Indicates "Help" button is selected */
 				print_buttons(dialog, height, width, 1);
 				break;
 			case 0:
@@ -196,7 +255,7 @@ int dialog_inputbox(const char *title, const char *prompt, int \
height, int width  print_buttons(dialog, height, width, 0);
 				break;
 			case 0:
-				button = 1;	/* Indicates "Cancel" button is selected */
+				button = 1;	/* Indicates "Help" button is selected */
 				print_buttons(dialog, height, width, 1);
 				break;
 			case 1:
@@ -213,12 +272,18 @@ int dialog_inputbox(const char *title, const char *prompt, int \
height, int width  return (button == -1 ? 0 : button);
 		case 'X':
 		case 'x':
-			key = ESC;
-		case ESC:
+			key = KEY_ESC;
 			break;
+		case KEY_ESC:
+			key = on_key_esc(dialog);
+			break;
+		case KEY_RESIZE:
+			delwin(dialog);
+			on_key_resize();
+			goto do_resize;
 		}
 	}
 
 	delwin(dialog);
-	return -1;		/* ESC pressed */
+	return KEY_ESC;		/* ESC pressed */
 }
diff --git a/scripts/kconfig/lxdialog/lxdialog.c \
b/scripts/kconfig/lxdialog/lxdialog.c deleted file mode 100644
index 5b8e3e947..000000000
--- a/scripts/kconfig/lxdialog/lxdialog.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- *  dialog - Display simple dialog boxes from shell scripts
- *
- *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "dialog.h"
-
-static void Usage(const char *name);
-
-typedef int (jumperFn) (const char *title, int argc, const char *const *argv);
-
-struct Mode {
-	char *name;
-	int argmin, argmax, argmod;
-	jumperFn *jumper;
-};
-
-jumperFn j_menu, j_radiolist, j_yesno, j_textbox, j_inputbox;
-jumperFn j_msgbox, j_infobox;
-
-static struct Mode modes[] = {
-	{"--menu", 9, 0, 3, j_menu},
-	{"--radiolist", 9, 0, 3, j_radiolist},
-	{"--yesno", 5, 5, 1, j_yesno},
-	{"--textbox", 5, 5, 1, j_textbox},
-	{"--inputbox", 5, 6, 1, j_inputbox},
-	{"--msgbox", 5, 5, 1, j_msgbox},
-	{"--infobox", 5, 5, 1, j_infobox},
-	{NULL, 0, 0, 0, NULL}
-};
-
-static struct Mode *modePtr;
-
-#ifdef LOCALE
-#include <locale.h>
-#endif
-
-int main(int argc, const char *const *argv)
-{
-	int offset = 0, opt_clear = 0, end_common_opts = 0, retval;
-	const char *title = NULL;
-
-#ifdef LOCALE
-	(void)setlocale(LC_ALL, "");
-#endif
-
-#ifdef TRACE
-	trace(TRACE_CALLS | TRACE_UPDATE);
-#endif
-	if (argc < 2) {
-		Usage(argv[0]);
-		exit(-1);
-	}
-
-	while (offset < argc - 1 && !end_common_opts) {	/* Common options */
-		if (!strcmp(argv[offset + 1], "--title")) {
-			if (argc - offset < 3 || title != NULL) {
-				Usage(argv[0]);
-				exit(-1);
-			} else {
-				title = argv[offset + 2];
-				offset += 2;
-			}
-		} else if (!strcmp(argv[offset + 1], "--backtitle")) {
-			if (backtitle != NULL) {
-				Usage(argv[0]);
-				exit(-1);
-			} else {
-				backtitle = argv[offset + 2];
-				offset += 2;
-			}
-		} else if (!strcmp(argv[offset + 1], "--clear")) {
-			if (opt_clear) {	/* Hey, "--clear" can't appear twice! */
-				Usage(argv[0]);
-				exit(-1);
-			} else if (argc == 2) {	/* we only want to clear the screen */
-				init_dialog();
-				refresh();	/* init_dialog() will clear the screen for us */
-				end_dialog();
-				return 0;
-			} else {
-				opt_clear = 1;
-				offset++;
-			}
-		} else		/* no more common options */
-			end_common_opts = 1;
-	}
-
-	if (argc - 1 == offset) {	/* no more options */
-		Usage(argv[0]);
-		exit(-1);
-	}
-	/* use a table to look for the requested mode, to avoid code duplication */
-
-	for (modePtr = modes; modePtr->name; modePtr++)	/* look for the mode */
-		if (!strcmp(argv[offset + 1], modePtr->name))
-			break;
-
-	if (!modePtr->name)
-		Usage(argv[0]);
-	if (argc - offset < modePtr->argmin)
-		Usage(argv[0]);
-	if (modePtr->argmax && argc - offset > modePtr->argmax)
-		Usage(argv[0]);
-
-	init_dialog();
-	retval = (*(modePtr->jumper)) (title, argc - offset, argv + offset);
-
-	if (opt_clear) {	/* clear screen before exit */
-		attr_clear(stdscr, LINES, COLS, screen_attr);
-		refresh();
-	}
-	end_dialog();
-
-	exit(retval);
-}
-
-/*
- * Print program usage
- */
-static void Usage(const char *name)
-{
-	fprintf(stderr, "\
-\ndialog, by Savio Lam (lam836@cs.cuhk.hk).\
-\n  patched by Stuart Herbert (S.Herbert@shef.ac.uk)\
-\n  modified/gutted for use as a Linux kernel config tool by \
-\n  William Roadcap (roadcapw@cfw.com)\
-\n\
-\n* Display dialog boxes from shell scripts *\
-\n\
-\nUsage: %s --clear\
-\n       %s [--title <title>] [--backtitle <backtitle>] --clear <Box options>\
-\n\
-\nBox options:\
-\n\
-\n  --menu      <text> <height> <width> <menu height> <tag1> <item1>...\
-\n  --radiolist <text> <height> <width> <list height> <tag1> <item1> <status1>...\
-\n  --textbox   <file> <height> <width>\
-\n  --inputbox  <text> <height> <width> [<init>]\
-\n  --yesno     <text> <height> <width>\
-\n", name, name);
-	exit(-1);
-}
-
-/*
- * These are the program jumpers
- */
-
-int j_menu(const char *t, int ac, const char *const *av)
-{
-	return dialog_menu(t, av[2], atoi(av[3]), atoi(av[4]),
-			   atoi(av[5]), av[6], (ac - 6) / 2, av + 7);
-}
-
-int j_radiolist(const char *t, int ac, const char *const *av)
-{
-	return dialog_checklist(t, av[2], atoi(av[3]), atoi(av[4]),
-				atoi(av[5]), (ac - 6) / 3, av + 6);
-}
-
-int j_textbox(const char *t, int ac, const char *const *av)
-{
-	return dialog_textbox(t, av[2], atoi(av[3]), atoi(av[4]));
-}
-
-int j_yesno(const char *t, int ac, const char *const *av)
-{
-	return dialog_yesno(t, av[2], atoi(av[3]), atoi(av[4]));
-}
-
-int j_inputbox(const char *t, int ac, const char *const *av)
-{
-	int ret = dialog_inputbox(t, av[2], atoi(av[3]), atoi(av[4]),
-				  ac == 6 ? av[5] : (char *)NULL);
-	if (ret == 0)
-		fprintf(stderr, "%s", dialog_input_result);
-	return ret;
-}
-
-int j_msgbox(const char *t, int ac, const char *const *av)
-{
-	return dialog_msgbox(t, av[2], atoi(av[3]), atoi(av[4]), 1);
-}
-
-int j_infobox(const char *t, int ac, const char *const *av)
-{
-	return dialog_msgbox(t, av[2], atoi(av[3]), atoi(av[4]), 0);
-}
diff --git a/scripts/kconfig/lxdialog/menubox.c b/scripts/kconfig/lxdialog/menubox.c
index 1fd501b39..58c2f8afe 100644
--- a/scripts/kconfig/lxdialog/menubox.c
+++ b/scripts/kconfig/lxdialog/menubox.c
@@ -1,22 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  *  menubox.c -- implements the menu box
  *
  *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
  *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 /*
@@ -63,19 +50,19 @@ static int menu_width, item_x;
 /*
  * Print menu item
  */
-static void do_print_item(WINDOW * win, const char *item, int choice,
-                          int selected, int hotkey)
+static void do_print_item(WINDOW * win, const char *item, int line_y,
+			  int selected, int hotkey)
 {
 	int j;
 	char *menu_item = malloc(menu_width + 1);
 
 	strncpy(menu_item, item, menu_width - item_x);
-	menu_item[menu_width] = 0;
+	menu_item[menu_width - item_x] = '\0';
 	j = first_alpha(menu_item, "YyNnMmHh");
 
 	/* Clear 'residue' of last item */
-	wattrset(win, menubox_attr);
-	wmove(win, choice, 0);
+	wattrset(win, dlg.menubox.atr);
+	wmove(win, line_y, 0);
 #if OLD_NCURSES
 	{
 		int i;
@@ -85,23 +72,24 @@ static void do_print_item(WINDOW * win, const char *item, int \
choice,  #else
 	wclrtoeol(win);
 #endif
-	wattrset(win, selected ? item_selected_attr : item_attr);
-	mvwaddstr(win, choice, item_x, menu_item);
+	wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr);
+	mvwaddstr(win, line_y, item_x, menu_item);
 	if (hotkey) {
-		wattrset(win, selected ? tag_key_selected_attr : tag_key_attr);
-		mvwaddch(win, choice, item_x + j, menu_item[j]);
+		wattrset(win, selected ? dlg.tag_key_selected.atr
+			 : dlg.tag_key.atr);
+		mvwaddch(win, line_y, item_x + j, menu_item[j]);
 	}
 	if (selected) {
-		wmove(win, choice, item_x + 1);
+		wmove(win, line_y, item_x + 1);
 	}
 	free(menu_item);
 	wrefresh(win);
 }
 
-#define print_item(index, choice, selected) \
-do {\
-	int hotkey = (items[(index) * 2][0] != ':'); \
-	do_print_item(menu, items[(index) * 2 + 1], choice, selected, hotkey); \
+#define print_item(index, choice, selected)				\
+do {									\
+	item_set(index);						\
+	do_print_item(menu, item_str(), choice, selected, !item_is_tag(':')); \
 } while (0)
 
 /*
@@ -117,11 +105,11 @@ static void print_arrows(WINDOW * win, int item_no, int scroll, \
int y, int x,  wmove(win, y, x);
 
 	if (scroll > 0) {
-		wattrset(win, uarrow_attr);
+		wattrset(win, dlg.uarrow.atr);
 		waddch(win, ACS_UARROW);
 		waddstr(win, "(-)");
 	} else {
-		wattrset(win, menubox_attr);
+		wattrset(win, dlg.menubox.atr);
 		waddch(win, ACS_HLINE);
 		waddch(win, ACS_HLINE);
 		waddch(win, ACS_HLINE);
@@ -133,11 +121,11 @@ static void print_arrows(WINDOW * win, int item_no, int scroll, \
int y, int x,  wrefresh(win);
 
 	if ((height < item_no) && (scroll + height < item_no)) {
-		wattrset(win, darrow_attr);
+		wattrset(win, dlg.darrow.atr);
 		waddch(win, ACS_DARROW);
 		waddstr(win, "(+)");
 	} else {
-		wattrset(win, menubox_border_attr);
+		wattrset(win, dlg.menubox_border.atr);
 		waddch(win, ACS_HLINE);
 		waddch(win, ACS_HLINE);
 		waddch(win, ACS_HLINE);
@@ -153,12 +141,14 @@ static void print_arrows(WINDOW * win, int item_no, int scroll, \
                int y, int x,
  */
 static void print_buttons(WINDOW * win, int height, int width, int selected)
 {
-	int x = width / 2 - 16;
+	int x = width / 2 - 28;
 	int y = height - 2;
 
 	print_button(win, "Select", y, x, selected == 0);
 	print_button(win, " Exit ", y, x + 12, selected == 1);
 	print_button(win, " Help ", y, x + 24, selected == 2);
+	print_button(win, " Save ", y, x + 36, selected == 3);
+	print_button(win, " Load ", y, x + 48, selected == 4);
 
 	wmove(win, y, x + 1 + 12 * selected);
 	wrefresh(win);
@@ -178,39 +168,49 @@ static void do_scroll(WINDOW *win, int *scroll, int n)
 /*
  * Display a menu for choosing among a number of options
  */
-int dialog_menu(const char *title, const char *prompt, int height, int width,
-		int menu_height, const char *current, int item_no,
-		const char *const *items)
+int dialog_menu(const char *title, const char *prompt,
+		const void *selected, int *s_scroll)
 {
 	int i, j, x, y, box_x, box_y;
+	int height, width, menu_height;
 	int key = 0, button = 0, scroll = 0, choice = 0;
 	int first_item =  0, max_choice;
 	WINDOW *dialog, *menu;
-	FILE *f;
 
-	max_choice = MIN(menu_height, item_no);
+do_resize:
+	height = getmaxy(stdscr);
+	width = getmaxx(stdscr);
+	if (height < MENUBOX_HEIGTH_MIN || width < MENUBOX_WIDTH_MIN)
+		return -ERRDISPLAYTOOSMALL;
+
+	height -= 4;
+	width  -= 5;
+	menu_height = height - 10;
+
+	max_choice = MIN(menu_height, item_count());
 
 	/* center dialog box on screen */
-	x = (COLS - width) / 2;
-	y = (LINES - height) / 2;
+	x = (getmaxx(stdscr) - width) / 2;
+	y = (getmaxy(stdscr) - height) / 2;
 
 	draw_shadow(stdscr, y, x, height, width);
 
 	dialog = newwin(height, width, y, x);
 	keypad(dialog, TRUE);
 
-	draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
-	wattrset(dialog, border_attr);
+	draw_box(dialog, 0, 0, height, width,
+		 dlg.dialog.atr, dlg.border.atr);
+	wattrset(dialog, dlg.border.atr);
 	mvwaddch(dialog, height - 3, 0, ACS_LTEE);
 	for (i = 0; i < width - 2; i++)
 		waddch(dialog, ACS_HLINE);
-	wattrset(dialog, dialog_attr);
-	wbkgdset(dialog, dialog_attr & A_COLOR);
+	wattrset(dialog, dlg.dialog.atr);
+	wbkgdset(dialog, dlg.dialog.atr & A_COLOR);
 	waddch(dialog, ACS_RTEE);
 
 	print_title(dialog, title, width);
 
-	wattrset(dialog, dialog_attr);
+	wattrset(dialog, dlg.dialog.atr);
 	print_autowrap(dialog, prompt, width - 2, 1, 3);
 
 	menu_width = width - 6;
@@ -224,33 +224,29 @@ int dialog_menu(const char *title, const char *prompt, int \
height, int width,  
 	/* draw a box around the menu items */
 	draw_box(dialog, box_y, box_x, menu_height + 2, menu_width + 2,
-		 menubox_border_attr, menubox_attr);
+		 dlg.menubox_border.atr, dlg.menubox.atr);
 
-	item_x = (menu_width - 70) / 2;
+	if (menu_width >= 80)
+		item_x = (menu_width - 70) / 2;
+	else
+		item_x = 4;
 
 	/* Set choice to default item */
-	for (i = 0; i < item_no; i++)
-		if (strcmp(current, items[i * 2]) == 0)
-			choice = i;
-
-	/* get the scroll info from the temp file */
-	if ((f = fopen("lxdialog.scrltmp", "r")) != NULL) {
-		if ((fscanf(f, "%d\n", &scroll) == 1) && (scroll <= choice) &&
-		    (scroll + max_choice > choice) && (scroll >= 0) &&
-		    (scroll + max_choice <= item_no)) {
-			first_item = scroll;
-			choice = choice - scroll;
-			fclose(f);
-		} else {
-			scroll = 0;
-			remove("lxdialog.scrltmp");
-			fclose(f);
-			f = NULL;
-		}
+	item_foreach()
+		if (selected && (selected == item_data()))
+			choice = item_n();
+	/* get the saved scroll info */
+	scroll = *s_scroll;
+	if ((scroll <= choice) && (scroll + max_choice > choice) &&
+	   (scroll >= 0) && (scroll + max_choice <= item_count())) {
+		first_item = scroll;
+		choice = choice - scroll;
+	} else {
+		scroll = 0;
 	}
-	if ((choice >= max_choice) || (f == NULL && choice >= max_choice / 2)) {
-		if (choice >= item_no - max_choice / 2)
-			scroll = first_item = item_no - max_choice;
+	if ((choice >= max_choice)) {
+		if (choice >= item_count() - max_choice / 2)
+			scroll = first_item = item_count() - max_choice;
 		else
 			scroll = first_item = choice - max_choice / 2;
 		choice = choice - scroll;
@@ -263,14 +259,14 @@ int dialog_menu(const char *title, const char *prompt, int \
height, int width,  
 	wnoutrefresh(menu);
 
-	print_arrows(dialog, item_no, scroll,
+	print_arrows(dialog, item_count(), scroll,
 		     box_y, box_x + item_x + 1, menu_height);
 
 	print_buttons(dialog, height, width, 0);
 	wmove(menu, choice, item_x + 1);
 	wrefresh(menu);
 
-	while (key != ESC) {
+	while (key != KEY_ESC) {
 		key = wgetch(menu);
 
 		if (key < 256 && isalpha(key))
@@ -280,22 +276,25 @@ int dialog_menu(const char *title, const char *prompt, int \
height, int width,  i = max_choice;
 		else {
 			for (i = choice + 1; i < max_choice; i++) {
-				j = first_alpha(items[(scroll + i) * 2 + 1], "YyNnMmHh");
-				if (key == tolower(items[(scroll + i) * 2 + 1][j]))
+				item_set(scroll + i);
+				j = first_alpha(item_str(), "YyNnMmHh");
+				if (key == tolower(item_str()[j]))
 					break;
 			}
 			if (i == max_choice)
 				for (i = 0; i < max_choice; i++) {
-					j = first_alpha(items [(scroll + i) * 2 + 1], "YyNnMmHh");
-					if (key == tolower(items[(scroll + i) * 2 + 1][j]))
+					item_set(scroll + i);
+					j = first_alpha(item_str(), "YyNnMmHh");
+					if (key == tolower(item_str()[j]))
 						break;
 				}
 		}
 
-		if (i < max_choice ||
-		    key == KEY_UP || key == KEY_DOWN ||
-		    key == '-' || key == '+' ||
-		    key == KEY_PPAGE || key == KEY_NPAGE) {
+		if (item_count() != 0 &&
+		    (i < max_choice ||
+		     key == KEY_UP || key == KEY_DOWN ||
+		     key == '-' || key == '+' ||
+		     key == KEY_PPAGE || key == KEY_NPAGE)) {
 			/* Remove highligt of current item */
 			print_item(scroll + choice, choice, FALSE);
 
@@ -312,7 +311,7 @@ int dialog_menu(const char *title, const char *prompt, int \
height, int width,  print_item(scroll+choice, choice, FALSE);
 
 				if ((choice > max_choice - 3) &&
-				    (scroll + max_choice < item_no)) {
+				    (scroll + max_choice < item_count())) {
 					/* Scroll menu up */
 					do_scroll(menu, &scroll, 1);
 
@@ -335,7 +334,7 @@ int dialog_menu(const char *title, const char *prompt, int \
height, int width,  
 			} else if (key == KEY_NPAGE) {
 				for (i = 0; (i < max_choice); i++) {
-					if (scroll + max_choice < item_no) {
+					if (scroll + max_choice < item_count()) {
 						do_scroll(menu, &scroll, 1);
 						print_item(scroll+max_choice-1,
 							   max_choice - 1, FALSE);
@@ -349,7 +348,7 @@ int dialog_menu(const char *title, const char *prompt, int \
height, int width,  
 			print_item(scroll + choice, choice, TRUE);
 
-			print_arrows(dialog, item_no, scroll,
+			print_arrows(dialog, item_count(), scroll,
 				     box_y, box_x + item_x + 1, menu_height);
 
 			wnoutrefresh(dialog);
@@ -363,7 +362,7 @@ int dialog_menu(const char *title, const char *prompt, int \
height, int width,  case TAB:
 		case KEY_RIGHT:
 			button = ((key == KEY_LEFT ? --button : ++button) < 0)
-			    ? 2 : (button > 2 ? 0 : button);
+			    ? 4 : (button > 4 ? 0 : button);
 
 			print_buttons(dialog, height, width, button);
 			wrefresh(menu);
@@ -374,53 +373,52 @@ int dialog_menu(const char *title, const char *prompt, int \
height, int width,  case 'n':
 		case 'm':
 		case '/':
+		case 'h':
+		case '?':
+		case 'z':
+		case '\n':
 			/* save scroll info */
-			if ((f = fopen("lxdialog.scrltmp", "w")) != NULL) {
-				fprintf(f, "%d\n", scroll);
-				fclose(f);
-			}
+			*s_scroll = scroll;
+			delwin(menu);
 			delwin(dialog);
-			fprintf(stderr, "%s\n", items[(scroll + choice) * 2]);
+			item_set(scroll + choice);
+			item_set_selected(1);
 			switch (key) {
+			case 'h':
+			case '?':
+				return 2;
 			case 's':
-				return 3;
 			case 'y':
-				return 3;
+				return 5;
 			case 'n':
-				return 4;
+				return 6;
 			case 'm':
-				return 5;
+				return 7;
 			case ' ':
-				return 6;
+				return 8;
 			case '/':
-				return 7;
+				return 9;
+			case 'z':
+				return 10;
+			case '\n':
+				return button;
 			}
 			return 0;
-		case 'h':
-		case '?':
-			button = 2;
-		case '\n':
-			delwin(dialog);
-			if (button == 2)
-				fprintf(stderr, "%s \"%s\"\n",
-					items[(scroll + choice) * 2],
-					items[(scroll + choice) * 2 + 1] +
-					first_alpha(items [(scroll + choice) * 2 + 1], ""));
-			else
-				fprintf(stderr, "%s\n",
-					items[(scroll + choice) * 2]);
-
-			remove("lxdialog.scrltmp");
-			return button;
 		case 'e':
 		case 'x':
-			key = ESC;
-		case ESC:
+			key = KEY_ESC;
 			break;
+		case KEY_ESC:
+			key = on_key_esc(menu);
+			break;
+		case KEY_RESIZE:
+			on_key_resize();
+			delwin(menu);
+			delwin(dialog);
+			goto do_resize;
 		}
 	}
-
+	delwin(menu);
 	delwin(dialog);
-	remove("lxdialog.scrltmp");
-	return -1;		/* ESC pressed */
+	return key;		/* ESC pressed */
 }
diff --git a/scripts/kconfig/lxdialog/msgbox.c b/scripts/kconfig/lxdialog/msgbox.c
deleted file mode 100644
index 7323f5471..000000000
--- a/scripts/kconfig/lxdialog/msgbox.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- *  msgbox.c -- implements the message box and info box
- *
- *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "dialog.h"
-
-/*
- * Display a message box. Program will pause and display an "OK" button
- * if the parameter 'pause' is non-zero.
- */
-int dialog_msgbox(const char *title, const char *prompt, int height, int width,
-                  int pause)
-{
-	int i, x, y, key = 0;
-	WINDOW *dialog;
-
-	/* center dialog box on screen */
-	x = (COLS - width) / 2;
-	y = (LINES - height) / 2;
-
-	draw_shadow(stdscr, y, x, height, width);
-
-	dialog = newwin(height, width, y, x);
-	keypad(dialog, TRUE);
-
-	draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
-
-	print_title(dialog, title, width);
-
-	wattrset(dialog, dialog_attr);
-	print_autowrap(dialog, prompt, width - 2, 1, 2);
-
-	if (pause) {
-		wattrset(dialog, border_attr);
-		mvwaddch(dialog, height - 3, 0, ACS_LTEE);
-		for (i = 0; i < width - 2; i++)
-			waddch(dialog, ACS_HLINE);
-		wattrset(dialog, dialog_attr);
-		waddch(dialog, ACS_RTEE);
-
-		print_button(dialog, "  Ok  ", height - 2, width / 2 - 4, TRUE);
-
-		wrefresh(dialog);
-		while (key != ESC && key != '\n' && key != ' ' &&
-		       key != 'O' && key != 'o' && key != 'X' && key != 'x')
-			key = wgetch(dialog);
-	} else {
-		key = '\n';
-		wrefresh(dialog);
-	}
-
-	delwin(dialog);
-	return key == ESC ? -1 : 0;
-}
diff --git a/scripts/kconfig/lxdialog/textbox.c b/scripts/kconfig/lxdialog/textbox.c
index de4ae41d7..4e339b126 100644
--- a/scripts/kconfig/lxdialog/textbox.c
+++ b/scripts/kconfig/lxdialog/textbox.c
@@ -1,103 +1,117 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  *  textbox.c -- implements the text box
  *
  *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
  *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "dialog.h"
 
 static void back_lines(int n);
-static void print_page(WINDOW * win, int height, int width);
-static void print_line(WINDOW * win, int row, int width);
+static void print_page(WINDOW *win, int height, int width, update_text_fn
+		       update_text, void *data);
+static void print_line(WINDOW *win, int row, int width);
 static char *get_line(void);
-static void print_position(WINDOW * win, int height, int width);
+static void print_position(WINDOW * win);
+
+static int hscroll;
+static int begin_reached, end_reached, page_length;
+static char *buf;
+static char *page;
+
+/*
+ * refresh window content
+ */
+static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw,
+			     int cur_y, int cur_x, update_text_fn update_text,
+			     void *data)
+{
+	print_page(box, boxh, boxw, update_text, data);
+	print_position(dialog);
+	wmove(dialog, cur_y, cur_x);	/* Restore cursor position */
+	wrefresh(dialog);
+}
 
-static int hscroll, fd, file_size, bytes_read;
-static int begin_reached = 1, end_reached, page_length;
-static char *buf, *page;
 
 /*
  * Display text from a file in a dialog box.
+ *
+ * keys is a null-terminated array
+ * update_text() may not add or remove any '\n' or '\0' in tbuf
  */
-int dialog_textbox(const char *title, const char *file, int height, int width)
+int dialog_textbox(const char *title, char *tbuf, int initial_height,
+		   int initial_width, int *keys, int *_vscroll, int *_hscroll,
+		   update_text_fn update_text, void *data)
 {
-	int i, x, y, cur_x, cur_y, fpos, key = 0;
-	int passed_end;
-	WINDOW *dialog, *text;
-
-	/* Open input file for reading */
-	if ((fd = open(file, O_RDONLY)) == -1) {
-		endwin();
-		fprintf(stderr, "\nCan't open input file in dialog_textbox().\n");
-		exit(-1);
-	}
-	/* Get file size. Actually, 'file_size' is the real file size - 1,
-	   since it's only the last byte offset from the beginning */
-	if ((file_size = lseek(fd, 0, SEEK_END)) == -1) {
-		endwin();
-		fprintf(stderr, "\nError getting file size in dialog_textbox().\n");
-		exit(-1);
-	}
-	/* Restore file pointer to beginning of file after getting file size */
-	if (lseek(fd, 0, SEEK_SET) == -1) {
-		endwin();
-		fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
-		exit(-1);
-	}
-	/* Allocate space for read buffer */
-	if ((buf = malloc(BUF_SIZE + 1)) == NULL) {
-		endwin();
-		fprintf(stderr, "\nCan't allocate memory in dialog_textbox().\n");
-		exit(-1);
-	}
-	if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
-		endwin();
-		fprintf(stderr, "\nError reading file in dialog_textbox().\n");
-		exit(-1);
+	int i, x, y, cur_x, cur_y, key = 0;
+	int height, width, boxh, boxw;
+	WINDOW *dialog, *box;
+	bool done = false;
+
+	begin_reached = 1;
+	end_reached = 0;
+	page_length = 0;
+	hscroll = 0;
+	buf = tbuf;
+	page = buf;	/* page is pointer to start of page to be displayed */
+
+	if (_vscroll && *_vscroll) {
+		begin_reached = 0;
+
+		for (i = 0; i < *_vscroll; i++)
+			get_line();
 	}
-	buf[bytes_read] = '\0';	/* mark end of valid data */
-	page = buf;		/* page is pointer to start of page to be displayed */
+	if (_hscroll)
+		hscroll = *_hscroll;
+
+do_resize:
+	getmaxyx(stdscr, height, width);
+	if (height < TEXTBOX_HEIGTH_MIN || width < TEXTBOX_WIDTH_MIN)
+		return -ERRDISPLAYTOOSMALL;
+	if (initial_height != 0)
+		height = initial_height;
+	else
+		if (height > 4)
+			height -= 4;
+		else
+			height = 0;
+	if (initial_width != 0)
+		width = initial_width;
+	else
+		if (width > 5)
+			width -= 5;
+		else
+			width = 0;
 
 	/* center dialog box on screen */
-	x = (COLS - width) / 2;
-	y = (LINES - height) / 2;
+	x = (getmaxx(stdscr) - width) / 2;
+	y = (getmaxy(stdscr) - height) / 2;
 
 	draw_shadow(stdscr, y, x, height, width);
 
 	dialog = newwin(height, width, y, x);
 	keypad(dialog, TRUE);
 
-	/* Create window for text region, used for scrolling text */
-	text = subwin(dialog, height - 4, width - 2, y + 1, x + 1);
-	wattrset(text, dialog_attr);
-	wbkgdset(text, dialog_attr & A_COLOR);
+	/* Create window for box region, used for scrolling text */
+	boxh = height - 4;
+	boxw = width - 2;
+	box = subwin(dialog, boxh, boxw, y + 1, x + 1);
+	wattrset(box, dlg.dialog.atr);
+	wbkgdset(box, dlg.dialog.atr & A_COLOR);
 
-	keypad(text, TRUE);
+	keypad(box, TRUE);
 
 	/* register the new window, along with its borders */
-	draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
+	draw_box(dialog, 0, 0, height, width,
+		 dlg.dialog.atr, dlg.border.atr);
 
-	wattrset(dialog, border_attr);
+	wattrset(dialog, dlg.border.atr);
 	mvwaddch(dialog, height - 3, 0, ACS_LTEE);
 	for (i = 0; i < width - 2; i++)
 		waddch(dialog, ACS_HLINE);
-	wattrset(dialog, dialog_attr);
-	wbkgdset(dialog, dialog_attr & A_COLOR);
+	wattrset(dialog, dlg.dialog.atr);
+	wbkgdset(dialog, dlg.dialog.atr & A_COLOR);
 	waddch(dialog, ACS_RTEE);
 
 	print_title(dialog, title, width);
@@ -107,157 +121,80 @@ int dialog_textbox(const char *title, const char *file, int \
height, int width)  getyx(dialog, cur_y, cur_x);	/* Save cursor position */
 
 	/* Print first page of text */
-	attr_clear(text, height - 4, width - 2, dialog_attr);
-	print_page(text, height - 4, width - 2);
-	print_position(dialog, height, width);
-	wmove(dialog, cur_y, cur_x);	/* Restore cursor position */
-	wrefresh(dialog);
+	attr_clear(box, boxh, boxw, dlg.dialog.atr);
+	refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x, update_text,
+			 data);
 
-	while ((key != ESC) && (key != '\n')) {
+	while (!done) {
 		key = wgetch(dialog);
 		switch (key) {
 		case 'E':	/* Exit */
 		case 'e':
 		case 'X':
 		case 'x':
-			delwin(dialog);
-			free(buf);
-			close(fd);
-			return 0;
+		case 'q':
+		case '\n':
+			done = true;
+			break;
 		case 'g':	/* First page */
 		case KEY_HOME:
 			if (!begin_reached) {
 				begin_reached = 1;
-				/* First page not in buffer? */
-				if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
-					endwin();
-					fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
-					exit(-1);
-				}
-				if (fpos > bytes_read) {	/* Yes, we have to read it in */
-					if (lseek(fd, 0, SEEK_SET) == -1) {
-						endwin();
-						fprintf(stderr, "\nError moving file pointer in "
-							        "dialog_textbox().\n");
-						exit(-1);
-					}
-					if ((bytes_read =
-					     read(fd, buf, BUF_SIZE)) == -1) {
-						endwin();
-						fprintf(stderr, "\nError reading file in dialog_textbox().\n");
-						exit(-1);
-					}
-					buf[bytes_read] = '\0';
-				}
 				page = buf;
-				print_page(text, height - 4, width - 2);
-				print_position(dialog, height, width);
-				wmove(dialog, cur_y, cur_x);	/* Restore cursor position */
-				wrefresh(dialog);
+				refresh_text_box(dialog, box, boxh, boxw,
+						 cur_y, cur_x, update_text,
+						 data);
 			}
 			break;
 		case 'G':	/* Last page */
 		case KEY_END:
 
 			end_reached = 1;
-			/* Last page not in buffer? */
-			if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
-				endwin();
-				fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
-				exit(-1);
-			}
-			if (fpos < file_size) {	/* Yes, we have to read it in */
-				if (lseek(fd, -BUF_SIZE, SEEK_END) == -1) {
-					endwin();
-					fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
-					exit(-1);
-				}
-				if ((bytes_read =
-				     read(fd, buf, BUF_SIZE)) == -1) {
-					endwin();
-					fprintf(stderr, "\nError reading file in dialog_textbox().\n");
-					exit(-1);
-				}
-				buf[bytes_read] = '\0';
-			}
-			page = buf + bytes_read;
-			back_lines(height - 4);
-			print_page(text, height - 4, width - 2);
-			print_position(dialog, height, width);
-			wmove(dialog, cur_y, cur_x);	/* Restore cursor position */
-			wrefresh(dialog);
+			/* point to last char in buf */
+			page = buf + strlen(buf);
+			back_lines(boxh);
+			refresh_text_box(dialog, box, boxh, boxw, cur_y,
+					 cur_x, update_text, data);
 			break;
 		case 'K':	/* Previous line */
 		case 'k':
 		case KEY_UP:
-			if (!begin_reached) {
-				back_lines(page_length + 1);
-
-				/* We don't call print_page() here but use scrolling to ensure
-				   faster screen update. However, 'end_reached' and
-				   'page_length' should still be updated, and 'page' should
-				   point to start of next page. This is done by calling
-				   get_line() in the following 'for' loop. */
-				scrollok(text, TRUE);
-				wscrl(text, -1);	/* Scroll text region down one line */
-				scrollok(text, FALSE);
-				page_length = 0;
-				passed_end = 0;
-				for (i = 0; i < height - 4; i++) {
-					if (!i) {
-						/* print first line of page */
-						print_line(text, 0, width - 2);
-						wnoutrefresh(text);
-					} else
-						/* Called to update 'end_reached' and 'page' */
-						get_line();
-					if (!passed_end)
-						page_length++;
-					if (end_reached && !passed_end)
-						passed_end = 1;
-				}
+			if (begin_reached)
+				break;
 
-				print_position(dialog, height, width);
-				wmove(dialog, cur_y, cur_x);	/* Restore cursor position */
-				wrefresh(dialog);
-			}
+			back_lines(page_length + 1);
+			refresh_text_box(dialog, box, boxh, boxw, cur_y,
+					 cur_x, update_text, data);
 			break;
 		case 'B':	/* Previous page */
 		case 'b':
+		case 'u':
 		case KEY_PPAGE:
 			if (begin_reached)
 				break;
-			back_lines(page_length + height - 4);
-			print_page(text, height - 4, width - 2);
-			print_position(dialog, height, width);
-			wmove(dialog, cur_y, cur_x);
-			wrefresh(dialog);
+			back_lines(page_length + boxh);
+			refresh_text_box(dialog, box, boxh, boxw, cur_y,
+					 cur_x, update_text, data);
 			break;
 		case 'J':	/* Next line */
 		case 'j':
 		case KEY_DOWN:
-			if (!end_reached) {
-				begin_reached = 0;
-				scrollok(text, TRUE);
-				scroll(text);	/* Scroll text region up one line */
-				scrollok(text, FALSE);
-				print_line(text, height - 5, width - 2);
-				wnoutrefresh(text);
-				print_position(dialog, height, width);
-				wmove(dialog, cur_y, cur_x);	/* Restore cursor position */
-				wrefresh(dialog);
-			}
+			if (end_reached)
+				break;
+
+			back_lines(page_length - 1);
+			refresh_text_box(dialog, box, boxh, boxw, cur_y,
+					 cur_x, update_text, data);
 			break;
 		case KEY_NPAGE:	/* Next page */
 		case ' ':
+		case 'd':
 			if (end_reached)
 				break;
 
 			begin_reached = 0;
-			print_page(text, height - 4, width - 2);
-			print_position(dialog, height, width);
-			wmove(dialog, cur_y, cur_x);
-			wrefresh(dialog);
+			refresh_text_box(dialog, box, boxh, boxw, cur_y,
+					 cur_x, update_text, data);
 			break;
 		case '0':	/* Beginning of line */
 		case 'H':	/* Scroll left */
@@ -272,9 +209,8 @@ int dialog_textbox(const char *title, const char *file, int \
height, int width)  hscroll--;
 			/* Reprint current page to scroll horizontally */
 			back_lines(page_length);
-			print_page(text, height - 4, width - 2);
-			wmove(dialog, cur_y, cur_x);
-			wrefresh(dialog);
+			refresh_text_box(dialog, box, boxh, boxw, cur_y,
+					 cur_x, update_text, data);
 			break;
 		case 'L':	/* Scroll right */
 		case 'l':
@@ -284,140 +220,97 @@ int dialog_textbox(const char *title, const char *file, int \
height, int width)  hscroll++;
 			/* Reprint current page to scroll horizontally */
 			back_lines(page_length);
-			print_page(text, height - 4, width - 2);
-			wmove(dialog, cur_y, cur_x);
-			wrefresh(dialog);
+			refresh_text_box(dialog, box, boxh, boxw, cur_y,
+					 cur_x, update_text, data);
 			break;
-		case ESC:
+		case KEY_ESC:
+			if (on_key_esc(dialog) == KEY_ESC)
+				done = true;
 			break;
+		case KEY_RESIZE:
+			back_lines(height);
+			delwin(box);
+			delwin(dialog);
+			on_key_resize();
+			goto do_resize;
+		default:
+			for (i = 0; keys[i]; i++) {
+				if (key == keys[i]) {
+					done = true;
+					break;
+				}
+			}
 		}
 	}
-
+	delwin(box);
 	delwin(dialog);
-	free(buf);
-	close(fd);
-	return -1;		/* ESC pressed */
+	if (_vscroll) {
+		const char *s;
+
+		s = buf;
+		*_vscroll = 0;
+		back_lines(page_length);
+		while (s < page && (s = strchr(s, '\n'))) {
+			(*_vscroll)++;
+			s++;
+		}
+	}
+	if (_hscroll)
+		*_hscroll = hscroll;
+	return key;
 }
 
 /*
- * Go back 'n' lines in text file. Called by dialog_textbox().
+ * Go back 'n' lines in text. Called by dialog_textbox().
  * 'page' will be updated to point to the desired line in 'buf'.
  */
 static void back_lines(int n)
 {
-	int i, fpos;
+	int i;
 
 	begin_reached = 0;
-	/* We have to distinguish between end_reached and !end_reached
-	   since at end of file, the line is not ended by a '\n'.
-	   The code inside 'if' basically does a '--page' to move one
-	   character backward so as to skip '\n' of the previous line */
-	if (!end_reached) {
-		/* Either beginning of buffer or beginning of file reached? */
-		if (page == buf) {
-			if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
-				endwin();
-				fprintf(stderr, "\nError moving file pointer in "
-					        "back_lines().\n");
-				exit(-1);
-			}
-			if (fpos > bytes_read) {	/* Not beginning of file yet */
-				/* We've reached beginning of buffer, but not beginning of
-				   file yet, so read previous part of file into buffer.
-				   Note that we only move backward for BUF_SIZE/2 bytes,
-				   but not BUF_SIZE bytes to avoid re-reading again in
-				   print_page() later */
-				/* Really possible to move backward BUF_SIZE/2 bytes? */
-				if (fpos < BUF_SIZE / 2 + bytes_read) {
-					/* No, move less then */
-					if (lseek(fd, 0, SEEK_SET) == -1) {
-						endwin();
-						fprintf(stderr, "\nError moving file pointer in "
-						                "back_lines().\n");
-						exit(-1);
-					}
-					page = buf + fpos - bytes_read;
-				} else {	/* Move backward BUF_SIZE/2 bytes */
-					if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR) == -1) {
-						endwin();
-						fprintf(stderr, "\nError moving file pointer "
-						                "in back_lines().\n");
-						exit(-1);
-					}
-					page = buf + BUF_SIZE / 2;
-				}
-				if ((bytes_read =
-				     read(fd, buf, BUF_SIZE)) == -1) {
-					endwin();
-					fprintf(stderr, "\nError reading file in back_lines().\n");
-					exit(-1);
-				}
-				buf[bytes_read] = '\0';
-			} else {	/* Beginning of file reached */
-				begin_reached = 1;
-				return;
+	/* Go back 'n' lines */
+	for (i = 0; i < n; i++) {
+		if (*page == '\0') {
+			if (end_reached) {
+				end_reached = 0;
+				continue;
 			}
 		}
-		if (*(--page) != '\n') {	/* '--page' here */
-			/* Something's wrong... */
-			endwin();
-			fprintf(stderr, "\nInternal error in back_lines().\n");
-			exit(-1);
+		if (page == buf) {
+			begin_reached = 1;
+			return;
 		}
-	}
-	/* Go back 'n' lines */
-	for (i = 0; i < n; i++)
+		page--;
 		do {
 			if (page == buf) {
-				if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
-					endwin();
-					fprintf(stderr, "\nError moving file pointer in back_lines().\n");
-					exit(-1);
-				}
-				if (fpos > bytes_read) {
-					/* Really possible to move backward BUF_SIZE/2 bytes? */
-					if (fpos < BUF_SIZE / 2 + bytes_read) {
-						/* No, move less then */
-						if (lseek(fd, 0, SEEK_SET) == -1) {
-							endwin();
-							fprintf(stderr, "\nError moving file pointer "
-							                "in back_lines().\n");
-							exit(-1);
-						}
-						page = buf + fpos - bytes_read;
-					} else {	/* Move backward BUF_SIZE/2 bytes */
-						if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR) == -1) {
-							endwin();
-							fprintf(stderr, "\nError moving file pointer"
-							                " in back_lines().\n");
-							exit(-1);
-						}
-						page = buf + BUF_SIZE / 2;
-					}
-					if ((bytes_read =
-					     read(fd, buf, BUF_SIZE)) == -1) {
-						endwin();
-						fprintf(stderr, "\nError reading file in "
-						                "back_lines().\n");
-						exit(-1);
-					}
-					buf[bytes_read] = '\0';
-				} else {	/* Beginning of file reached */
-					begin_reached = 1;
-					return;
-				}
+				begin_reached = 1;
+				return;
 			}
-		} while (*(--page) != '\n');
-	page++;
+			page--;
+		} while (*page != '\n');
+		page++;
+	}
 }
 
 /*
- * Print a new page of text. Called by dialog_textbox().
+ * Print a new page of text.
  */
-static void print_page(WINDOW * win, int height, int width)
+static void print_page(WINDOW *win, int height, int width, update_text_fn
+		       update_text, void *data)
 {
 	int i, passed_end = 0;
 
+	if (update_text) {
+		char *end;
+
+		for (i = 0; i < height; i++)
+			get_line();
+		end = page;
+		back_lines(height);
+		update_text(buf, page - buf, end - buf, data);
+	}
+
 	page_length = 0;
 	for (i = 0; i < height; i++) {
 		print_line(win, i, width);
@@ -430,7 +323,7 @@ static void print_page(WINDOW * win, int height, int width)
 }
 
 /*
- * Print a new line of text. Called by dialog_textbox() and print_page().
+ * Print a new line of text.
  */
 static void print_line(WINDOW * win, int row, int width)
 {
@@ -445,10 +338,8 @@ static void print_line(WINDOW * win, int row, int width)
 	/* Clear 'residue' of previous line */
 #if OLD_NCURSES
 	{
+		int x = getcurx(win);
 		int i;
-		int y, x;
-
-		getyx(win, y, x);
 		for (i = 0; i < width - x; i++)
 			waddch(win, ' ');
 	}
@@ -464,35 +355,14 @@ static void print_line(WINDOW * win, int row, int width)
  */
 static char *get_line(void)
 {
-	int i = 0, fpos;
+	int i = 0;
 	static char line[MAX_LEN + 1];
 
 	end_reached = 0;
 	while (*page != '\n') {
 		if (*page == '\0') {
-			/* Either end of file or end of buffer reached */
-			if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
-				endwin();
-				fprintf(stderr, "\nError moving file pointer in "
-				                "get_line().\n");
-				exit(-1);
-			}
-			if (fpos < file_size) {	/* Not end of file yet */
-				/* We've reached end of buffer, but not end of file yet,
-				   so read next part of file into buffer */
-				if ((bytes_read =
-				     read(fd, buf, BUF_SIZE)) == -1) {
-					endwin();
-					fprintf(stderr, "\nError reading file in get_line().\n");
-					exit(-1);
-				}
-				buf[bytes_read] = '\0';
-				page = buf;
-			} else {
-				if (!end_reached)
-					end_reached = 1;
-				break;
-			}
+			end_reached = 1;
+			break;
 		} else if (i < MAX_LEN)
 			line[i++] = *(page++);
 		else {
@@ -505,7 +375,7 @@ static char *get_line(void)
 	if (i <= MAX_LEN)
 		line[i] = '\0';
 	if (!end_reached)
-		page++;		/* move pass '\n' */
+		page++;		/* move past '\n' */
 
 	return line;
 }
@@ -513,19 +383,13 @@ static char *get_line(void)
 /*
  * Print current position
  */
-static void print_position(WINDOW * win, int height, int width)
+static void print_position(WINDOW * win)
 {
-	int fpos, percent;
+	int percent;
 
-	if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
-		endwin();
-		fprintf(stderr, "\nError moving file pointer in print_position().\n");
-		exit(-1);
-	}
-	wattrset(win, position_indicator_attr);
-	wbkgdset(win, position_indicator_attr & A_COLOR);
-	percent = !file_size ?
-	    100 : ((fpos - bytes_read + page - buf) * 100) / file_size;
-	wmove(win, height - 3, width - 9);
+	wattrset(win, dlg.position_indicator.atr);
+	wbkgdset(win, dlg.position_indicator.atr & A_COLOR);
+	percent = (page - buf) * 100 / strlen(buf);
+	wmove(win, getmaxy(win) - 3, getmaxx(win) - 9);
 	wprintw(win, "(%3d%%)", percent);
 }
diff --git a/scripts/kconfig/lxdialog/util.c b/scripts/kconfig/lxdialog/util.c
index 072d3eecc..1b490d4af 100644
--- a/scripts/kconfig/lxdialog/util.c
+++ b/scripts/kconfig/lxdialog/util.c
@@ -1,105 +1,227 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  *  util.c
  *
  *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
  *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <stdarg.h>
+
 #include "dialog.h"
 
-/* use colors by default? */
-bool use_colors = 1;
+/* Needed in signal handler in mconf.c */
+int saved_x, saved_y;
+
+struct dialog_info dlg;
+
+static void set_mono_theme(void)
+{
+	dlg.screen.atr = A_NORMAL;
+	dlg.shadow.atr = A_NORMAL;
+	dlg.dialog.atr = A_NORMAL;
+	dlg.title.atr = A_BOLD;
+	dlg.border.atr = A_NORMAL;
+	dlg.button_active.atr = A_REVERSE;
+	dlg.button_inactive.atr = A_DIM;
+	dlg.button_key_active.atr = A_REVERSE;
+	dlg.button_key_inactive.atr = A_BOLD;
+	dlg.button_label_active.atr = A_REVERSE;
+	dlg.button_label_inactive.atr = A_NORMAL;
+	dlg.inputbox.atr = A_NORMAL;
+	dlg.inputbox_border.atr = A_NORMAL;
+	dlg.searchbox.atr = A_NORMAL;
+	dlg.searchbox_title.atr = A_BOLD;
+	dlg.searchbox_border.atr = A_NORMAL;
+	dlg.position_indicator.atr = A_BOLD;
+	dlg.menubox.atr = A_NORM



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic