]> git.puffer.fish Git - matthieu/frr.git/commitdiff
python: improve clippy/clidef macro processing
authorDavid Lamparter <equinox@opensourcerouting.org>
Sun, 16 Jan 2022 20:43:55 +0000 (21:43 +0100)
committerDavid Lamparter <equinox@opensourcerouting.org>
Mon, 28 Feb 2022 12:28:43 +0000 (13:28 +0100)
Process macros from the current file, and warn if something is
redefined (to a different value).

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
python/clidef.py

index b57a00fc892638e5dd6024c82bccd553685a2e9f..101c9a5ae376d0aea64c3ad196f7e19ff1de417e 100644 (file)
@@ -241,24 +241,51 @@ def get_always_args(token, always_args, args=[], stack=[]):
 
 
 class Macros(dict):
+    def __init__(self):
+        super().__init__()
+        self._loc = {}
+
     def load(self, filename):
         filedata = clippy.parse(filename)
         for entry in filedata["data"]:
             if entry["type"] != "PREPROC":
                 continue
-            ppdir = entry["line"].lstrip().split(None, 1)
-            if ppdir[0] != "define" or len(ppdir) != 2:
-                continue
-            ppdef = ppdir[1].split(None, 1)
-            name = ppdef[0]
-            if "(" in name:
-                continue
-            val = ppdef[1] if len(ppdef) == 2 else ""
-
-            val = val.strip(" \t\n\\")
-            if name in self:
-                sys.stderr.write("warning: macro %s redefined!\n" % (name))
+            self.load_preproc(filename, entry)
+
+    def setup(self, key, val, where="built-in"):
+        self[key] = val
+        self._loc[key] = (where, 0)
+
+    def load_preproc(self, filename, entry):
+        ppdir = entry["line"].lstrip().split(None, 1)
+        if ppdir[0] != "define" or len(ppdir) != 2:
+            return
+        ppdef = ppdir[1].split(None, 1)
+        name = ppdef[0]
+        if "(" in name:
+            return
+        val = ppdef[1] if len(ppdef) == 2 else ""
+
+        val = val.strip(" \t\n\\")
+        if self.get(name, val) != val:
+            sys.stderr.write(
+                "%s:%d: warning: macro %s redefined!\n"
+                % (
+                    filename,
+                    entry["lineno"],
+                    name,
+                )
+            )
+            sys.stderr.write(
+                "%s:%d: note: previously defined here\n"
+                % (
+                    self._loc[name][0],
+                    self._loc[name][1],
+                )
+            )
+        else:
             self[name] = val
+            self._loc[name] = (filename, entry["lineno"])
 
 
 def process_file(fn, ofd, dumpfd, all_defun, macros):
@@ -283,6 +310,11 @@ def process_file(fn, ofd, dumpfd, all_defun, macros):
                 cond_stack.append(prev_line + line)
             elif tokens[0] in ["endif"]:
                 cond_stack.pop(-1)
+            elif tokens[0] in ["define"]:
+                if not cond_stack:
+                    macros.load_preproc(fn, entry)
+                elif len(cond_stack) == 1 and cond_stack[0] == "#ifdef CLIPPY\n":
+                    macros.load_preproc(fn, entry)
             continue
         if entry["type"].startswith("DEFPY") or (
             all_defun and entry["type"].startswith("DEFUN")
@@ -454,9 +486,9 @@ if __name__ == "__main__":
     macros.load(os.path.join(basepath, "lib/command.h"))
     macros.load(os.path.join(basepath, "bgpd/bgp_vty.h"))
     # sigh :(
-    macros["PROTO_REDIST_STR"] = "FRR_REDIST_STR_ISISD"
-    macros["PROTO_IP_REDIST_STR"] = "FRR_IP_REDIST_STR_ISISD"
-    macros["PROTO_IP6_REDIST_STR"] = "FRR_IP6_REDIST_STR_ISISD"
+    macros.setup("PROTO_REDIST_STR", "FRR_REDIST_STR_ISISD")
+    macros.setup("PROTO_IP_REDIST_STR", "FRR_IP_REDIST_STR_ISISD")
+    macros.setup("PROTO_IP6_REDIST_STR", "FRR_IP6_REDIST_STR_ISISD")
 
     errors = process_file(args.cfile, ofd, dumpfd, args.all_defun, macros)
     if errors != 0: