diff options
Diffstat (limited to 'doc/doxygen/warningfilter.py')
-rwxr-xr-x | doc/doxygen/warningfilter.py | 55 |
1 files changed, 46 insertions, 9 deletions
diff --git a/doc/doxygen/warningfilter.py b/doc/doxygen/warningfilter.py index 396260006..ab25bb893 100755 --- a/doc/doxygen/warningfilter.py +++ b/doc/doxygen/warningfilter.py | |||
@@ -2,29 +2,66 @@ | |||
2 | 2 | ||
3 | import argparse as ap | 3 | import argparse as ap |
4 | import re | 4 | import re |
5 | import sys | ||
5 | 6 | ||
6 | filename = r"(/\w+)+\.\w" | 7 | def sep_re(field, separator): |
7 | main_match = rf"(?P<filename>{filename}):(?P<linenumber>\d+): warning:" | 8 | return rf"{field}(?:{separator}{field})*" |
8 | var_def = rf"(?:const)? \w+ \*?\w+" | 9 | |
9 | func_params = rf"\({var_def}(?:, {var_def})*\)" | 10 | fileclass = r"[\w-]" |
10 | func_name = r"\w+" | 11 | filename = rf"{fileclass}+" |
12 | # filename = rf"(/{fileclass}+)+\.\w" | ||
13 | filepath = rf"{sep_re(filename, '/')}\.(?:\w+)" | ||
14 | main_match = rf"(?P<path>/{filepath}|\[generated\]):(?P<linenumber>\d+): warning:" | ||
15 | type_name = rf"(?:const )?(?:unsigned (?:long )?|struct |enum )?(?:\w+)(?: \*?const)? \*{{0,3}}" | ||
16 | var_def = rf"{type_name}\w+(?:\[(?:\(\d+/\d+\))?\])?" | ||
17 | func_params = rf"\({sep_re(var_def, ', ')}(?:,\.\.\.)?\)" | ||
18 | simple_name = r"\w+" | ||
19 | func_name = simple_name | ||
20 | verbose_name = rf"{sep_re(simple_name, ' ')}" | ||
21 | command_re = "(?:</[^>]+>|\\\w+)" | ||
22 | macro_params = rf"\({sep_re(simple_name, ', ')}(?:,\.\.\.)?\)" | ||
11 | 23 | ||
12 | matches = { | 24 | matches = { |
13 | "not an input @file": re.compile(rf"{main_match} the name '{filename}' supplied as the argument in the \file statement is not an input file"), | 25 | "not an input @file": re.compile(rf"{main_match} the name '{filepath}' supplied as the argument in the \\file statement is not an input file"), |
14 | "multiple @param docs": re.compile(rf"{main_match} {filename} argument '\w+' from the argument list of \w+ has multiple @param documentation sections"), | 26 | "multiple @param docs": re.compile(rf"{main_match} argument '\w+' from the argument list of \w+ has multiple @param documentation sections"), |
15 | "undocumented param": re.compile(rf"{main_match} {filename} The following parameter of {func_name}{func_params} is not documented:"), | 27 | "undocumented param (message)": re.compile(rf"{main_match} The following parameters? of {func_name}(?:{func_params}|{macro_params}) (?:is|are) not documented:"), |
28 | "undocumented param (name)": re.compile(r" parameter '[\w.]+'"), | ||
29 | "explicit link not resolved": re.compile(rf"{main_match} explicit link request to '\w+(?:\(\))?' could not be resolved"), | ||
30 | "unknown command": re.compile(rf"{main_match} Found unknown command '\\\w+'"), | ||
31 | "missing argument": re.compile(rf"{main_match} argument '\w+' of command @param is not found in the argument list of {func_name}(?:{func_params}|{macro_params})"), | ||
32 | "eof inside group": re.compile(rf"{main_match} end of file while inside a group"), | ||
33 | "eof inside comment": re.compile(rf"{main_match} Reached end of file while still inside a \(nested\) comment. Nesting level \d+ \(probable line reference: \d+\)"), | ||
34 | "blank": re.compile(rf"^\s*$"), | ||
35 | "eof inside code block (line 1)": re.compile(rf"{main_match} reached end of file while inside a 'code' block!"), | ||
36 | "eof inside code block (line 2)": re.compile(rf"The command that should end the block seems to be missing!"), | ||
37 | "title mismatch": re.compile(rf"{main_match} group (?P<group_id>\w+): ignoring title \"(?P<new_title>{verbose_name})\" that does not match old title \"(?P<old_title>{verbose_name})\""), | ||
38 | "end of comment expecting command": re.compile(rf"{main_match} end of comment block while expecting command {command_re}"), | ||
39 | "no matching tag": re.compile(rf"{main_match} found </(?P<tag>[^>]+)> tag without matching <(?P=tag)>"), | ||
40 | "documented empty return type": re.compile(rf"{main_match} documented empty return type of {func_name}"), | ||
41 | "unsupported tag": re.compile(rf"{main_match} Unsupported xml/html tag <(?P<tag>[^>]+)> found"), | ||
42 | "expected whitespace after command": re.compile(rf"{main_match} expected whitespace after \\(?P<command>\w+) command"), | ||
43 | "illegal command": re.compile(rf"{main_match} Illegal command (?P<illegal_cmd>(?:@|\\)\w+) as part of a (?P<command>\\\w+) command"), | ||
44 | "undeclared symbol": re.compile(rf"{main_match} documented symbol '\w+' was not declared or defined\."), | ||
45 | "nameless member": re.compile(rf"{main_match} member with no name found."), | ||
46 | "end of empty list": re.compile(rf"{main_match} End of list marker found without any preceding list items"), | ||
47 | # "": re.compile(rf"{main_match} "), | ||
16 | } | 48 | } |
17 | 49 | ||
18 | parser = ap.ArgumentParser() | 50 | parser = ap.ArgumentParser() |
19 | parser.add_argument("filename") | 51 | parser.add_argument("filename") |
20 | args = parser.parse_args() | 52 | args = parser.parse_args() |
21 | 53 | ||
22 | counts = {k: 0 for k in matches.keys()} | 54 | counts = {**{k: 0 for k in matches.keys()}, |
55 | **{"unsorted":0}} | ||
23 | 56 | ||
24 | with open(args.filename, "r") as file: | 57 | with open(args.filename, "r") as file: |
25 | for line in file.readlines(): | 58 | for line in file.readlines(): |
26 | for key, regex in matches.items(): | 59 | for key, regex in matches.items(): |
27 | if regex.match(line): | 60 | if regex.match(line): |
28 | counts[key] += 1 | 61 | counts[key] += 1 |
62 | break | ||
63 | else: | ||
64 | print(line.strip("\n"), file=sys.stderr) | ||
65 | counts["unsorted"] += 1 | ||
29 | 66 | ||
30 | print(counts) | 67 | print(counts) |