verilator/test_regress/t/t_dist_docs_warnings.py

110 lines
3.3 KiB
Python
Executable File

#!/usr/bin/env python3
# DESCRIPTION: Verilator: Primitive C++ style checker
#
# Copyright 2025 by Wilson Snyder. This program is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('dist')
Waivers = [
'Internal',
'Unsupported',
'DIDNOTCONVERGE', # Runtime
]
src_filename = "src/V3Error.h"
doc_filename = "docs/guide/warnings.rst"
def get_src_warns():
args = {}
for filename in test.glob_some(test.root + "/" + src_filename):
with open(filename, "r", encoding="latin-1") as fh:
state = 0
lineno = 0
for line in fh:
lineno += 1
line = line.rstrip()
line = re.sub(r'\s*//.*', '', line)
# print("S: %s" % line)
if state == 0 and re.search(r'class V3ErrorCode', line):
state = 1
elif state == 1 and re.search(r'const names', line):
state = 2
elif state == 2 and re.search(r' return ', line):
state = 3
elif state == 2:
for opt in re.findall(r'"([A-Z0-9]+)"', line):
opt = opt_clean(opt)
if test.verbose:
print("S '" + opt + "' " + line)
args[opt] = filename + ":" + str(lineno)
return args
def get_docs_warns():
args = {}
for filename in test.glob_some(test.root + "/" + doc_filename):
with open(filename, "r", encoding="latin-1") as fh:
lineno = 0
last_opt = None
for line in fh:
lineno += 1
line = line.rstrip()
m = re.search(r' option:: ([A-Za-z0-9]+)', line)
if m:
opt = opt_clean(m.group(1))
if test.verbose:
print("D '" + opt + "' " + line)
args[opt] = filename + ":" + str(lineno)
last_opt = opt
if last_opt and re.search(r'Historical', line):
Waivers.append(last_opt)
return args
def opt_clean(opt):
return opt
if not os.path.exists(test.root + "/.git"):
test.skip("Not in a git repository")
srcs = get_src_warns()
docs = get_docs_warns()
if len(srcs) < 10:
test.error(src_filename + ": Too few warnings found; parse error?")
if len(docs) < 10:
test.error(doc_filename + ": Too few warnings found; parse error?")
both = {}
both.update(srcs)
both.update(docs)
waiver = {k: 1 for k in Waivers}
for opt in sorted(both.keys()):
if opt in waiver:
continue
src_ok = opt in srcs
docs_ok = opt in docs
if not src_ok:
test.error_keep_going(docs[opt] + ": Warn code documented in " + doc_filename + " '" +
opt + "' not found in " + src_filename + " sources")
elif not docs_ok:
test.error_keep_going(srcs[opt] + ": Warn code documented in " + src_filename + " '" +
opt + "' not found in " + doc_filename + " documentation")
elif test.verbose:
print(": ok '" + opt)
test.passes()