#!/usr/bin/env python3
# Convert output from Google's cpplint to the cppcheck XML format
# Reads from stdin and writes to stderr (to mimic cppcheck)
# https://stackoverflow.com/questions/14172232/how-to-make-cpplint-work-with-jenkins-warnings-plugin
import re
import sys
import xml.sax.saxutils
OUTPUT_FILE_XML_HEADER = """
"""
OUTPUT_FILE_XML_FOOTER = """
"""
CPPLINT_ERR_REGEX = "([^:]*):([0-9]*): ([^\[]*)\[([^\]]*)\] \[([0-9]*)\].*"
CPPLINT_ERR_REGEX_NB_INFO = 5
def cpplint_score_to_cppcheck_severity(err_score: int) -> str:
if err_score in {1, 2}:
return "style"
if err_score in {3, 4}:
return "warning"
return "error" if err_score == 5 else ""
def write_if_relevant_error(
file_name: str, err_severity: str, err_label: str, err_msg: str, err_line: str
) -> None:
if err_severity in {"warning", "error"}:
sys.stderr.write(
f"""\n"""
)
sys.stderr.write(
f"""\n"""
)
sys.stderr.write("""\n""")
def fmt_report_from_cpplint_to_cppcheck() -> None:
sys.stderr.write(OUTPUT_FILE_XML_HEADER)
compiled_regex = re.compile(CPPLINT_ERR_REGEX)
for line in sys.stdin.readlines():
matched_regex = compiled_regex.match(line.strip())
if not matched_regex:
continue
matched_subgroups = matched_regex.groups()
if len(matched_subgroups) != CPPLINT_ERR_REGEX_NB_INFO:
continue
file_name, err_line, raw_err_msg, err_label, err_score = matched_subgroups
# Prepare the data to be used as attribute values
err_msg = xml.sax.saxutils.escape(raw_err_msg)
err_msg = xml.sax.saxutils.quoteattr(err_msg)
err_severity = cpplint_score_to_cppcheck_severity(int(err_score))
write_if_relevant_error(file_name, err_severity, err_label, err_msg, err_line)
sys.stderr.write(OUTPUT_FILE_XML_FOOTER)
if __name__ == "__main__":
fmt_report_from_cpplint_to_cppcheck()