From 888be88c7795d19dd9c7809c66edc98ebfbdf600 Mon Sep 17 00:00:00 2001 From: AfonsoSantos96 Date: Tue, 10 Oct 2023 10:19:40 +0100 Subject: [PATCH] feat(HIS): add function calls metric check to script Signed-off-by: Afonso Santos --- docker/Dockerfile | 1 + his_checker.py | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/docker/Dockerfile b/docker/Dockerfile index 5c1b94e..d01e3ac 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -28,6 +28,7 @@ RUN apt-get update && apt-get install -y \ nodejs \ npm \ pmccabe \ + cflow \ enchant-2 && \ pip3 install gitlint && \ pip3 install license-expression && \ diff --git a/his_checker.py b/his_checker.py index 74adb12..3aaf3d8 100755 --- a/his_checker.py +++ b/his_checker.py @@ -10,8 +10,10 @@ import sys import argparse import os +import re CYCLOMATIC_THRESHOLD = 10 +CALL_THRESHOLD = 7 def process_complexity(files): @@ -31,6 +33,44 @@ def process_complexity(files): print("== Check done with " + str(metric_fail) + " error(s) ==\n") return metric_fail +def process_calls(files): + + """Process the number of calls inside a function.""" + + metric_fail = 0 + cflow = "cflow -l --depth=2" + print("== Checking the number of called functions ==") + for file in files.files: + if file.endswith(".c"): + lines = os.popen(f"{cflow} {file}").read().split('\n') + call_counter = 0 + for line in lines: + if not line: + continue + depth = int(line.split('}')[0].strip('{ ').strip()) + if depth == 0: + if call_counter > CALL_THRESHOLD: + print(f"{function_info} calls {call_counter} functions." + f"The maximum are {CALL_THRESHOLD} calls") + metric_fail += 1 + match = re.match( + r'\{\s*(\d+)\}\s+(.*?)\(\) <.*?at (.*?):(\d+)>', line) + if match: + depth, function_name, file_path, line_number = \ + match.groups() + function_info = ( + f"At {file_path.split('src', 1)[1]} ({line_number})" + f": {function_name}") + call_counter = 0 + elif depth >= 1: + call_counter += 1 + if call_counter > CALL_THRESHOLD: + print(f"{function_info} calls {call_counter} functions. " + f"The maximum are {CALL_THRESHOLD} calls") + metric_fail += 1 + print(f"== Check done with {metric_fail} error(s) ==\n") + return metric_fail + if __name__ == "__main__": CHECK_FAIL = 0 PARSER = argparse.ArgumentParser() @@ -38,6 +78,7 @@ def process_complexity(files): ARGS = PARSER.parse_args() CHECK_FAIL += process_complexity(ARGS) + CHECK_FAIL += process_calls(ARGS) if CHECK_FAIL: sys.exit(-1)