From patchwork Sun Mar 29 11:10:29 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 2067 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774782711; bh=lmyStjvQxb92Tn5LYP664frfQcRdYEQJH5EaXThukGI=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=pnTAr+EC52YbTW2O6phx2HC92szs38g5IjSfhEX08eVR3frJSS0q6Cxpc4QrjloyN 3ZuMWIywiMhEvnRKc9ZXhzcnb3+7uoFQ4uqHv5oWK5shNA0UNIlAQgBAfy/PSwSxnK gU0hHN8AQ7NP+FII3RmbbuBmwLs6hIcW5rZQnq8Sdf8zgxi4H7NJeMe0tJ/TZCfry0 uzGf+hgYlwgvIn5EYesNtiVsU47yHkxYudPfDMHWrU7L+lPjwijqgaAYLfMaM0TB77 IB+qgiXqutHn3KPu3vb/JE4dO0LSkOQMkIT2cC/6I358IYOLE2nG/10NeNz8Z1211/ N/NB+n/bL4+4g== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 813766A2BE for ; Sun, 29 Mar 2026 05:11:51 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id 3_C-5lIzt3sM for ; Sun, 29 Mar 2026 05:11:51 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774782711; bh=lmyStjvQxb92Tn5LYP664frfQcRdYEQJH5EaXThukGI=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=pnTAr+EC52YbTW2O6phx2HC92szs38g5IjSfhEX08eVR3frJSS0q6Cxpc4QrjloyN 3ZuMWIywiMhEvnRKc9ZXhzcnb3+7uoFQ4uqHv5oWK5shNA0UNIlAQgBAfy/PSwSxnK gU0hHN8AQ7NP+FII3RmbbuBmwLs6hIcW5rZQnq8Sdf8zgxi4H7NJeMe0tJ/TZCfry0 uzGf+hgYlwgvIn5EYesNtiVsU47yHkxYudPfDMHWrU7L+lPjwijqgaAYLfMaM0TB77 IB+qgiXqutHn3KPu3vb/JE4dO0LSkOQMkIT2cC/6I358IYOLE2nG/10NeNz8Z1211/ N/NB+n/bL4+4g== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 6891A67C16 for ; Sun, 29 Mar 2026 05:11:51 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774782708; bh=YBc0jF/NNVd+KPq6Gxg0U3QywpLWlFbyT0M2i/rK97c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gloXJtYaNEQO0KdJY2rrpmIivZ4X3aNnDe+fjzXennXi3bCmO4LhOBmJPXxGXU9NB Y7oHKMaoCYSvRHXH4TYmGNerBASL5YPOmfugaI0yhaZ8AaKkstQgdYGZIX+UaGYHFz Oc4AfYfiNtpb/O95H5zi36q2bn18jETdTNYcqHyv3LA60fW7oDRopbK6vnc8/VuRw0 K2ky9SmYfoRlkVN0GyHlBYln+G4cwTnrHZrU6Fznfr48w66tLjcaSKUIap1jMzCUUG rBLJTHZ4EtUTPJVN3UulH9QgXa2l314WEf9U+0in1c5CrMKxkRdCA8nnl8OroWJZNk w1s8x4EwBfhTA== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 49DD46A2BE; Sun, 29 Mar 2026 05:11:48 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id u_V1mQjMdyk7; Sun, 29 Mar 2026 05:11:48 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774782703; bh=vwNxRJpWHyaz1vQTzgW3o4FPUiYIPaPJ0wrl9uO5J2s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=sg77Hk1w7Rd66Glg/q8zshml5PgqtN6L7sqwMo8SEYfpZGcqOTA0HDZgqk3dZSpwU n4yV/9zkezq/asZj9TgXSSKnRLWrby5rfEMIXXjxQME3lzWdMbIsUVXMbyh84/Wkj7 cy81mW7XFnAwCE953U3E11HUXstZrwED7Cw0mH/ptC0A00a1RSNkvyG1/s9DzILvGQ ji/hee1TUGuWPd7ZpIbei/Y++1s+5yS2Mnj1tf7ILWnLRcO7cGTq7C/6Dt+FOfY6dg HNoxG31S9vwXXlr/F47VZW1xiQKtrum2FIlMstsaPYHwOCuJS40/8jf31V0Z4gAwwE JDluWlp1ggqQg== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id E46E76A2BF; Sun, 29 Mar 2026 05:11:42 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Sun, 29 Mar 2026 05:10:29 -0600 Message-ID: <20260329111037.1352652-5-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260329111037.1352652-1-sjg@u-boot.org> References: <20260329111037.1352652-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: WTY4QOCWYJX67SNNDMNNILKEXOCEY2QW X-Message-ID-Hash: WTY4QOCWYJX67SNNDMNNILKEXOCEY2QW X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Simon Glass X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 4/7] buildman: Fix kconfiglib string-value escaping List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass The C Kconfig implementation (scripts/kconfig/confdata.c) stores string values from .config files verbatim -- no unescaping on read, no escaping on write. But kconfiglib's unescape() strips backslashes before ANY character (\n -> n, \x -> x), and escape() only re-adds them for \ and ". This means \n in a .config string silently becomes n after a round-trip. Fix unescape() to only handle \" (the only escape that matters for .config parsing), and escape() to only handle " -> \". This makes string values pass through unchanged, matching the C behaviour. Also fix _expand_str() (the Kconfig file string parser) to only consume \\, \", \', and \$ (meaningful Kconfig escapes), leaving \n and similar sequences as-is. Signed-off-by: Simon Glass --- doc/develop/qconfig.rst | 17 +++++------------ tools/buildman/kconfiglib.py | 32 ++++++++++++++++++++------------ 2 files changed, 25 insertions(+), 24 deletions(-) -- 2.43.0 diff --git a/doc/develop/qconfig.rst b/doc/develop/qconfig.rst index 423fb9118d8..431de08cff3 100644 --- a/doc/develop/qconfig.rst +++ b/doc/develop/qconfig.rst @@ -41,18 +41,11 @@ since no ``make`` subprocesses or cross-compiler toolchains are needed. Defconfig files containing ``#include`` directives are preprocessed with the C preprocessor before loading, matching the behaviour of the build system. -There are two known cosmetic differences compared with the old make-based -approach: - -- ``CONFIG_GCC_VERSION`` reflects the host compiler rather than each board's - cross-compiler, since no cross-compiler is invoked. - -- Backslash escape sequences in string values (e.g. ``\n``, ``\x1b``) may - differ slightly due to kconfiglib's unescape/escape round-trip. This affects - a handful of string CONFIGs such as ``CONFIG_AUTOBOOT_PROMPT``. - -Neither difference affects the usefulness of the database for finding CONFIG -combinations or computing imply relationships. +There is one known cosmetic difference compared with the old make-based +approach: ``CONFIG_GCC_VERSION`` reflects the host compiler rather than each +board's cross-compiler, since no cross-compiler is invoked. This does not +affect the usefulness of the database for finding CONFIG combinations or +computing imply relationships. Resyncing defconfigs ~~~~~~~~~~~~~~~~~~~~ diff --git a/tools/buildman/kconfiglib.py b/tools/buildman/kconfiglib.py index 27abbf9a7a1..cdaacf471d8 100644 --- a/tools/buildman/kconfiglib.py +++ b/tools/buildman/kconfiglib.py @@ -2727,10 +2727,16 @@ class Kconfig(object): return (s, match.end()) elif match.group() == "\\": - # Replace '\x' with 'x'. 'i' ends up pointing to the character - # after 'x', which allows macros to be canceled with '\$(foo)'. + # Replace '\x' with 'x' for characters that are meaningful + # escapes in Kconfig string literals: \\, \", \', and \$ + # (to cancel macro expansion). Other \ sequences + # like \n are left as-is, so that the stored value + # round-trips correctly through escape(). i = match.end() - s = s[:match.start()] + s[i:] + if i < len(s) and s[i] in "\\\"'$": + s = s[:match.start()] + s[i:] + else: + i = match.end() elif match.group() == "$(": # A macro call within the string @@ -6176,23 +6182,25 @@ def split_expr(expr, op): def escape(s): r""" - Escapes the string 's' in the same fashion as is done for display in - Kconfig format and when writing strings to a .config file. " and \ are - replaced by \" and \\, respectively. + Escapes the string 's' for writing to a .config file. Only " is escaped + (to \"), matching the symmetric unescape() behaviour. Backslash sequences + like \\ and \n are left as-is, since unescape() preserves them and the C + Kconfig implementation does not process them. """ - # \ must be escaped before " to avoid double escaping - return s.replace("\\", r"\\").replace('"', r'\"') + return s.replace('"', r'\"') def unescape(s): r""" - Unescapes the string 's'. \ followed by any character is replaced with just - that character. Used internally when reading .config files. + Unescapes the string 's'. \" is replaced with ". Other \ sequences, + including \\, are left as-is so that escape() can round-trip them + correctly. This matches the C Kconfig implementation which does not + unescape string values read from .config files. """ return _unescape_sub(r"\1", s) -# unescape() helper -_unescape_sub = re.compile(r"\\(.)").sub +# unescape() helper — only unescape \" +_unescape_sub = re.compile(r'\\(")').sub def standard_kconfig(description=None):