[Bf-blender-cvs] [978a7459f12] master: CMake: support multi-line strings for the help_features target

Campbell Barton noreply at git.blender.org
Thu Jan 19 07:31:49 CET 2023


Commit: 978a7459f121c2a1491687ccc83b0caddc7d6d1f
Author: Campbell Barton
Date:   Thu Jan 19 17:07:20 2023 +1100
Branches: master
https://developer.blender.org/rB978a7459f121c2a1491687ccc83b0caddc7d6d1f

CMake: support multi-line strings for the help_features target

===================================================================

M	build_files/cmake/cmake_print_build_options.py

===================================================================

diff --git a/build_files/cmake/cmake_print_build_options.py b/build_files/cmake/cmake_print_build_options.py
index 3dc2951680a..7a30bb5da2b 100644
--- a/build_files/cmake/cmake_print_build_options.py
+++ b/build_files/cmake/cmake_print_build_options.py
@@ -6,18 +6,80 @@
 import re
 import sys
 
+from typing import Optional
+
 cmakelists_file = sys.argv[-1]
 
 
-def main():
+def count_backslashes_before_pos(file_data: str, pos: int) -> int:
+    slash_count = 0
+    pos -= 1
+    while pos >= 0:
+        if file_data[pos] != '\\':
+            break
+        pos -= 1
+        slash_count += 1
+    return slash_count
+
+
+def extract_cmake_string_at_pos(file_data: str, pos_beg: int) -> Optional[str]:
+    assert file_data[pos_beg - 1] == '"'
+
+    pos = pos_beg
+    # Dummy assignment.
+    pos_end = pos_beg
+    while True:
+        pos_next = file_data.find('"', pos)
+        if pos_next == -1:
+            raise Exception("Un-terminated string (parse error?)")
+
+        count_slashes = count_backslashes_before_pos(file_data, pos_next)
+        if (count_slashes % 2) == 0:
+            pos_end = pos_next
+            # Found the closing quote.
+            break
+
+        # The quote was back-slash escaped, step over it.
+        pos = pos_next + 1
+        file_data[pos_next]
+
+    assert file_data[pos_end] == '"'
+
+    if pos_beg == pos_end:
+        return None
+
+    # See: https://cmake.org/cmake/help/latest/manual/cmake-language.7.html#escape-sequences
+    text = file_data[pos_beg: pos_end].replace(
+        # Handle back-slash literals.
+        "\\\\", "\\",
+    ).replace(
+        # Handle tabs.
+        "\\t", "\t",
+    ).replace(
+        # Handle escaped quotes.
+        "\\\"", "\"",
+    ).replace(
+        # Handle tabs.
+        "\\;", ";",
+    ).replace(
+        # Handle trailing newlines.
+        "\\\n", "",
+    )
+
+    return text
+
+
+def main() -> None:
     options = []
-    for l in open(cmakelists_file, 'r').readlines():
-        if not l.lstrip().startswith('#'):
-            l_option = re.sub(r'.*\boption\s*\(\s*(WITH_[a-zA-Z0-9_]+)\s+\"(.*)\"\s*.*', r'\g<1> - \g<2>', l)
-            if l_option != l:
-                l_option = l_option.strip()
-                if l_option.startswith('WITH_'):
-                    options.append(l_option)
+    with open(cmakelists_file, 'r', encoding="utf-8") as fh:
+        file_data = fh.read()
+        for m in re.finditer(r"^\s*option\s*\(\s*(WITH_[a-zA-Z0-9_]+)\s+(\")", file_data, re.MULTILINE):
+            option_name = m.group(1)
+            option_descr = extract_cmake_string_at_pos(file_data, m.span(2)[1])
+            if option_descr is None:
+                # Possibly a parsing error, at least show something.
+                option_descr = "(UNDOCUMENTED)"
+            options.append("{:s}: {:s}".format(option_name, option_descr))
 
     print('\n'.join(options))



More information about the Bf-blender-cvs mailing list