unleashed-firmware/scripts/fbt_tools/pvsstudio.py
あく 0469ef0e55
FuriHal, drivers: rework gauge initialization routine (#3912)
* FuriHal, drivers: rework gauge initialization, ensure that we can recover from any kind of internal/external issue
* Make PVS happy
* Format sources
* bq27220: add gaps injection into write operations
* Drivers: bq27220 cleanup and various fixes
* Drivers: bq27220 verbose logging and full access routine fix
* Drivers: better cfg mode exit handling in bq27220 driver
* Drivers: rewrite bq27220 based on bqstudio+ev2400, experiments and guessing. Fixes all known issues.
* PVS: hello license check
* Drivers: minimize reset count in bq27220 init sequence
* Drivers: bq27220 hide debug logging, reorganize routine to ensure predictable result and minimum amount of interaction with gauge, add documentation and notes.
* Drivers: more reliable bq27220_full_access routine
* Drivers: replace some warning with error in bq27220
* Drivers: move static asserts to headers in bq27220
* Fix PVS warnings
* Drivers: simplify logic in bq27220

---------

Co-authored-by: hedger <hedger@users.noreply.github.com>
2024-10-06 22:36:05 +04:00

129 lines
3.6 KiB
Python

import atexit
import multiprocessing
import subprocess
import sys
import webbrowser
from SCons.Action import Action
from SCons.Builder import Builder
from SCons.Script import Delete, Flatten, GetBuildFailures, Mkdir
__no_browser = False
def _set_browser_action(target, source, env):
if env["PVSNOBROWSER"]:
global __no_browser
__no_browser = True
def _emit_pvsreport(target, source, env):
target_dir = env["REPORT_DIR"]
if env["PLATFORM"] == "win32":
# Report generator on Windows emits to a subfolder of given output folder
target_dir = target_dir.Dir("fullhtml")
return [target_dir.File("index.html")], source
def atexist_handler():
global __no_browser
if __no_browser:
return
for bf in GetBuildFailures():
for node in Flatten(bf.node):
if node.exists and "pvs" in node.path and node.name.endswith(".html"):
# macOS
if sys.platform == "darwin":
subprocess.run(["open", node.abspath])
else:
webbrowser.open(node.abspath)
break
def generate(env):
env.SetDefault(
PVSNCORES=multiprocessing.cpu_count(),
PVSOPTIONS=[
"@.pvsoptions",
"-j${PVSNCORES}",
# "--disableLicenseExpirationCheck",
# "--incremental", # kinda broken on PVS side
],
PVSCONVOPTIONS=[
"-a",
"GA:1,2,3",
"-t",
"fullhtml",
"--indicate-warnings",
],
)
if env["PLATFORM"] == "win32":
env.SetDefault(
PVSCHECKBIN="CompilerCommandsAnalyzer.exe",
PVSCONVBIN="PlogConverter.exe",
)
else:
env.SetDefault(
PVSCHECKBIN="pvs-studio-analyzer",
PVSCONVBIN="plog-converter",
)
if not env["VERBOSE"]:
env.SetDefault(
PVSCHECKCOMSTR="\tPVS\t${TARGET}",
PVSCONVCOMSTR="\tPVSREP\t${TARGET}",
)
env.Append(
BUILDERS={
"PVSCheck": Builder(
action=Action(
[
[
"${PVSCHECKBIN}",
"analyze",
"${PVSOPTIONS}",
"-f",
"${SOURCE}",
"-o",
"${TARGET}",
]
],
"${PVSCHECKCOMSTR}",
),
suffix=".log",
src_suffix=".json",
),
"PVSReport": Builder(
action=Action(
[
Delete("${TARGET.dir}"),
# PlogConverter.exe and plog-converter have different behavior
Mkdir("${TARGET.dir}") if env["PLATFORM"] == "win32" else None,
Action(_set_browser_action, None),
Action(
[
[
"${PVSCONVBIN}",
"${PVSCONVOPTIONS}",
"${SOURCE}",
"-o",
"${REPORT_DIR}",
]
]
),
],
"${PVSCONVCOMSTR}",
),
emitter=_emit_pvsreport,
src_suffix=".log",
),
}
)
atexit.register(atexist_handler)
def exists(env):
return True