summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@opensourcerouting.org>2022-01-16 21:43:55 +0100
committerDavid Lamparter <equinox@opensourcerouting.org>2022-02-28 13:28:43 +0100
commite960eedd98b622bb1745012796a78bb654a889ed (patch)
tree9e4faac9f00be98840eebe84d3cef917b5b2b29c
parentlib: implement `terminal monitor` for vtysh (diff)
downloadfrr-e960eedd98b622bb1745012796a78bb654a889ed.tar.xz
frr-e960eedd98b622bb1745012796a78bb654a889ed.zip
python: improve clippy/clidef macro processing
Process macros from the current file, and warn if something is redefined (to a different value). Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
-rw-r--r--python/clidef.py62
1 files changed, 47 insertions, 15 deletions
diff --git a/python/clidef.py b/python/clidef.py
index b57a00fc8..101c9a5ae 100644
--- a/python/clidef.py
+++ b/python/clidef.py
@@ -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: