From 532b561288f6a9628073e68aaa51b87d9c20e838 Mon Sep 17 00:00:00 2001 From: Ulf Magnusson Date: Mon, 22 Jan 2018 19:20:13 +0100 Subject: Simplify escape() The fancy regex isn't really justified. Much faster with replace() too, though this is an unlikely hotspot. Could have used a \g<0> backreference to refer to the entire match instead of using a capturing group too. Hadn't discovered that. Add some selftests for escape() and unescape() too. --- kconfiglib.py | 10 +++++----- testsuite.py | 23 ++++++++++++++++++++++- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/kconfiglib.py b/kconfiglib.py index f1a254d..550c347 100644 --- a/kconfiglib.py +++ b/kconfiglib.py @@ -3671,17 +3671,17 @@ def expr_str(expr): _REL_TO_STR[expr[0]], expr_str(expr[2])) -# escape()/unescape() helpers -_escape_re_sub = re.compile(r'(["\\])').sub -_unescape_re_sub = re.compile(r"\\(.)").sub - 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. """ - return _escape_re_sub(r"\\\1", s) + # \ must be escaped before " to avoid double escaping + return s.replace("\\", r"\\").replace('"', r'\"') + +# unescape() helper +_unescape_re_sub = re.compile(r"\\(.)").sub def unescape(s): r""" diff --git a/testsuite.py b/testsuite.py index 0d892ed..9d7dda2 100644 --- a/testsuite.py +++ b/testsuite.py @@ -41,7 +41,7 @@ from kconfiglib import Kconfig, Symbol, Choice, COMMENT, MENU, \ BOOL, TRISTATE, HEX, STRING, \ TRI_TO_STR, \ - KconfigSyntaxError, expr_value + KconfigSyntaxError, expr_value, escape, unescape import difflib import errno import os @@ -241,6 +241,27 @@ def run_selftests(): verify_string_bad(r""" 'foo """) + print("Testing escape() and unescape()") + + def verify_escape_unescape(s, sesc): + # Verify that 's' escapes to 'sesc' and that 'sesc' unescapes to 's' + verify_equal(escape(s), sesc) + verify_equal(unescape(sesc), s) + + verify_escape_unescape(r'' , r'' ) + verify_escape_unescape(r'foo' , r'foo' ) + verify_escape_unescape(r'"' , r'\"' ) + verify_escape_unescape(r'""' , r'\"\"' ) + verify_escape_unescape('\\' , r'\\' ) + verify_escape_unescape(r'\\' , r'\\\\' ) + verify_escape_unescape(r'\"' , r'\\\"' ) + verify_escape_unescape(r'"ab\cd"ef"', r'\"ab\\cd\"ef\"') + + # Backslashes before any character should be unescaped, not just before " + # and \ + verify_equal(unescape(r"\afoo\b\c\\d\\\e\\\\f"), r"afoobc\d\e\\f") + + print("Testing expression evaluation") c = Kconfig("Kconfiglib/tests/Keval") -- cgit v1.2.3