scripts: dts: properly escape string properties
Fixed escaping of double quotes, backslashes, and new line characters
so they can be used in string properties.
Previously, double quotes and backslashes were escaped in gen_defines.py
but not in gen_dts_cmake.py, and new lines were not escaped in either,
so using any of these characters would break the build.
Signed-off-by: Joel Spadin <joelspadin@gmail.com>
diff --git a/scripts/dts/gen_defines.py b/scripts/dts/gen_defines.py
index fda6152..fb97faf 100755
--- a/scripts/dts/gen_defines.py
+++ b/scripts/dts/gen_defines.py
@@ -583,7 +583,7 @@
if prop.spec.type == 'string':
# DT_N_<node-id>_P_<prop-id>_IDX_<i>_STRING_UNQUOTED
- macro2val[macro + "_STRING_UNQUOTED"] = prop.val
+ macro2val[macro + "_STRING_UNQUOTED"] = escape_unquoted(prop.val)
# DT_N_<node-id>_P_<prop-id>_IDX_<i>_STRING_TOKEN
macro2val[macro + "_STRING_TOKEN"] = prop.val_as_token
# DT_N_<node-id>_P_<prop-id>_IDX_<i>_STRING_UPPER_TOKEN
@@ -626,7 +626,7 @@
macro2val[macro + f"_IDX_{i}"] = quote_str(subval)
subval_as_token = edtlib.str_as_token(subval)
# DT_N_<node-id>_P_<prop-id>_IDX_<i>_STRING_UNQUOTED
- macro2val[macro + f"_IDX_{i}_STRING_UNQUOTED"] = subval
+ macro2val[macro + f"_IDX_{i}_STRING_UNQUOTED"] = escape_unquoted(subval)
# DT_N_<node-id>_P_<prop-id>_IDX_<i>_STRING_TOKEN
macro2val[macro + f"_IDX_{i}_STRING_TOKEN"] = subval_as_token
# DT_N_<node-id>_P_<prop-id>_IDX_<i>_STRING_UPPER_TOKEN
@@ -1020,11 +1020,20 @@
print("/* " + s + " */", file=header_file)
-def escape(s: str) -> str:
- # Backslash-escapes any double quotes and backslashes in 's'
+ESCAPE_TABLE = str.maketrans(
+ {
+ "\n": "\\n",
+ "\r": "\\r",
+ "\\": "\\\\",
+ '"': '\\"',
+ }
+)
- # \ must be escaped before " to avoid double escaping
- return s.replace("\\", "\\\\").replace('"', '\\"')
+
+def escape(s: str) -> str:
+ # Backslash-escapes any double quotes, backslashes, and new lines in 's'
+
+ return s.translate(ESCAPE_TABLE)
def quote_str(s: str) -> str:
@@ -1034,6 +1043,15 @@
return f'"{escape(s)}"'
+def escape_unquoted(s: str) -> str:
+ # C macros cannot contain line breaks, so replace them with spaces.
+ # Whitespace is used to separate preprocessor tokens, but it does not matter
+ # which whitespace characters are used, so a line break and a space are
+ # equivalent with regards to unquoted strings being used as C code.
+
+ return s.replace("\r", " ").replace("\n", " ")
+
+
def err(s: str) -> NoReturn:
raise Exception(s)