[PATCH 05/23] tools: docs: parse_data_structs: make process_exceptions two stages

Mauro Carvalho Chehab posted 23 patches 5 hours ago
[PATCH 05/23] tools: docs: parse_data_structs: make process_exceptions two stages
Posted by Mauro Carvalho Chehab 5 hours ago
Split the logic which parses exceptions on two stages, preparing
the exceptions file to have rules that will affect xref generation.

For now, preserve the original API.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 tools/docs/lib/parse_data_structs.py | 125 +++++++++++++++------------
 1 file changed, 71 insertions(+), 54 deletions(-)

diff --git a/tools/docs/lib/parse_data_structs.py b/tools/docs/lib/parse_data_structs.py
index 9ad621712103..46535a05ea4a 100755
--- a/tools/docs/lib/parse_data_structs.py
+++ b/tools/docs/lib/parse_data_structs.py
@@ -140,9 +140,41 @@ class ParseDataStructs:
 
         self.symbols = {}
 
+        self.ignore = []
+        self.replace = []
+
         for symbol_type in self.DEF_SYMBOL_TYPES:
             self.symbols[symbol_type] = {}
 
+    def read_exceptions(self, fname: str):
+        if not fname:
+            return
+
+        name = os.path.basename(fname)
+
+        with open(fname, "r", encoding="utf-8", errors="backslashreplace") as f:
+            for ln, line in enumerate(f):
+                ln += 1
+                line = line.strip()
+                if not line or line.startswith("#"):
+                    continue
+
+                # ignore rules
+                match = re.match(r"^ignore\s+(\w+)\s+(\S+)", line)
+
+                if match:
+                    self.ignore.append((ln, match.group(1), match.group(2)))
+                    continue
+
+                # replace rules
+                match = re.match(r"^replace\s+(\S+)\s+(\S+)\s+(\S+)", line)
+                if match:
+                    self.replace.append((ln, match.group(1), match.group(2),
+                                         match.group(3)))
+                    continue
+
+                sys.exit(f"{name}:{ln}: invalid line: {line}")
+
     def store_type(self, ln, symbol_type: str, symbol: str,
                    ref_name: str = None, replace_underscores: bool = True):
         """
@@ -277,75 +309,60 @@ class ParseDataStructs:
                         self.store_type(line_no, "struct", match.group(1))
                         break
 
-    def process_exceptions(self, fname: str):
+    def apply_exceptions(self):
         """
         Process exceptions file with rules to ignore or replace references.
         """
-        if not fname:
-            return
 
-        name = os.path.basename(fname)
+        # Handle ignore rules
+        for ln, c_type, symbol in self.ignore:
+            if c_type not in self.DEF_SYMBOL_TYPES:
+                sys.exit(f"{name}:{ln}: {c_type} is invalid")
 
-        with open(fname, "r", encoding="utf-8", errors="backslashreplace") as f:
-            for ln, line in enumerate(f):
-                ln += 1
-                line = line.strip()
-                if not line or line.startswith("#"):
-                    continue
+            d = self.symbols[c_type]
+            if symbol in d:
+                del d[symbol]
 
-                # Handle ignore rules
-                match = re.match(r"^ignore\s+(\w+)\s+(\S+)", line)
-                if match:
-                    c_type = match.group(1)
-                    symbol = match.group(2)
-
-                    if c_type not in self.DEF_SYMBOL_TYPES:
-                        sys.exit(f"{name}:{ln}: {c_type} is invalid")
-
-                    d = self.symbols[c_type]
-                    if symbol in d:
-                        del d[symbol]
-
-                    continue
-
-                # Handle replace rules
-                match = re.match(r"^replace\s+(\S+)\s+(\S+)\s+(\S+)", line)
-                if not match:
-                    sys.exit(f"{name}:{ln}: invalid line: {line}")
-
-                c_type, old, new = match.groups()
-
-                if c_type not in self.DEF_SYMBOL_TYPES:
-                    sys.exit(f"{name}:{ln}: {c_type} is invalid")
+        # Handle replace rules
+        for ln, c_type, old, new in self.replace:
+            if c_type not in self.DEF_SYMBOL_TYPES:
+                sys.exit(f"{name}:{ln}: {c_type} is invalid")
 
-                reftype = None
+            reftype = None
 
-                # Parse reference type when the type is specified
+            # Parse reference type when the type is specified
 
-                match = re.match(r"^\:c\:(data|func|macro|type)\:\`(.+)\`", new)
+            match = re.match(r"^\:c\:(data|func|macro|type)\:\`(.+)\`", new)
+            if match:
+                reftype = f":c:{match.group(1)}"
+                new = match.group(2)
+            else:
+                match = re.search(r"(\:ref)\:\`(.+)\`", new)
                 if match:
-                    reftype = f":c:{match.group(1)}"
+                    reftype = match.group(1)
                     new = match.group(2)
-                else:
-                    match = re.search(r"(\:ref)\:\`(.+)\`", new)
-                    if match:
-                        reftype = match.group(1)
-                        new = match.group(2)
 
-                # If the replacement rule doesn't have a type, get default
+            # If the replacement rule doesn't have a type, get default
+            if not reftype:
+                reftype = self.DEF_SYMBOL_TYPES[c_type].get("ref_type")
                 if not reftype:
-                    reftype = self.DEF_SYMBOL_TYPES[c_type].get("ref_type")
-                    if not reftype:
-                        reftype = self.DEF_SYMBOL_TYPES[c_type].get("real_type")
+                    reftype = self.DEF_SYMBOL_TYPES[c_type].get("real_type")
 
-                new_ref = f"{reftype}:`{old} <{new}>`"
+            new_ref = f"{reftype}:`{old} <{new}>`"
 
-                # Change self.symbols to use the replacement rule
-                if old in self.symbols[c_type]:
-                    (_, ln) = self.symbols[c_type][old]
-                    self.symbols[c_type][old] = (new_ref, ln)
-                else:
-                    print(f"{name}:{ln}: Warning: can't find {old} {c_type}")
+            # Change self.symbols to use the replacement rule
+            if old in self.symbols[c_type]:
+                (_, ln) = self.symbols[c_type][old]
+                self.symbols[c_type][old] = (new_ref, ln)
+            else:
+                print(f"{name}:{ln}: Warning: can't find {old} {c_type}")
+
+    def process_exceptions(self, fname: str):
+        """
+        Process exceptions file with rules to ignore or replace references.
+        """
+        self.read_exceptions(fname)
+        self.apply_exceptions()
 
     def debug_print(self):
         """
-- 
2.51.0