From 919744e25f546f94c69c7ee9112edc878594052e Mon Sep 17 00:00:00 2001 From: Nora Zinaeddin Date: Tue, 29 Oct 2024 16:29:04 +0100 Subject: [PATCH 1/2] Handle ambigous profile/prefix group parameters Introduce the -e prefix: option, to improve handling of ambigous parameters (such as "security" etc.) --- .../analyzers/config_handler.py | 52 ++++++++---- analyzer/codechecker_analyzer/checkers.py | 3 +- analyzer/codechecker_analyzer/cmd/analyze.py | 56 +++++++++---- analyzer/codechecker_analyzer/cmd/check.py | 24 ++++++ analyzer/tests/unit/test_checker_handling.py | 81 +++++++++++++++++-- docs/analyzer/user_guide.md | 24 ++++++ 6 files changed, 204 insertions(+), 36 deletions(-) diff --git a/analyzer/codechecker_analyzer/analyzers/config_handler.py b/analyzer/codechecker_analyzer/analyzers/config_handler.py index bfc8be40fa..e701bd96af 100644 --- a/analyzer/codechecker_analyzer/analyzers/config_handler.py +++ b/analyzer/codechecker_analyzer/analyzers/config_handler.py @@ -12,8 +12,10 @@ from abc import ABCMeta from enum import Enum +from string import Template import collections import platform +import sys import re from codechecker_analyzer import analyzer_context @@ -149,10 +151,12 @@ def initialize_checkers(self, and "debug" checker groups. "osx" checker group is also not included unless the target platform is Darwin. - Command line "--enable/--disable" flags. - - Their arguments may start with "profile:" or "guideline:" prefix - which makes the choice explicit. - - Without prefix it means a profile name, a guideline name or a - checker group/name in this priority order. + - Their arguments may start with "prefix:", "profile:" or + "guideline:" label which makes the choice explicit. + - Without a label, it means either a profile name, a guideline name + or a checker prefix group/name, unless there is a clash + between these names, in which case an error is emitted. + If there is a name clash, using a label is mandatory. checkers -- [(checker name, description), ...] Checkers to add with their description. @@ -210,23 +214,41 @@ def initialize_checkers(self, profiles = checker_labels.get_description('profile') guidelines = checker_labels.occurring_values('guideline') + templ = Template("The ${entity} name '${identifier}' conflicts with a " + "checker name prefix '${identifier}'. Please use -e " + "${entity}:${identifier} to enable checkers of the " + "${identifier} ${entity} or use -e " + "prefix:${identifier} to select checkers which have " + "a name starting with '${identifier}'.") + for identifier, enabled in cmdline_enable: - if ':' in identifier: + if "prefix:" in identifier: + identifier = identifier.replace("prefix:", "") + self.set_checker_enabled(identifier, enabled) + + elif ':' in identifier: for checker in checker_labels.checkers_by_labels([identifier]): self.set_checker_enabled(checker, enabled) + elif identifier in profiles: if identifier in reserved_names: - LOG.warning("Profile name '%s' conflicts with a " - "checker(-group) name.", identifier) - for checker in checker_labels.checkers_by_labels( - [f'profile:{identifier}']): - self.set_checker_enabled(checker, enabled) + LOG.error(templ.substitute(entity="profile", + identifier=identifier)) + sys.exit(1) + else: + for checker in checker_labels.checkers_by_labels( + [f'profile:{identifier}']): + self.set_checker_enabled(checker, enabled) + elif identifier in guidelines: if identifier in reserved_names: - LOG.warning("Guideline name '%s' conflicts with a " - "checker(-group) name.", identifier) - for checker in checker_labels.checkers_by_labels( - [f'guideline:{identifier}']): - self.set_checker_enabled(checker, enabled) + LOG.error(templ.substitute(entity="guideline", + identifier=identifier)) + sys.exit(1) + else: + for checker in checker_labels.checkers_by_labels( + [f'guideline:{identifier}']): + self.set_checker_enabled(checker, enabled) + else: self.set_checker_enabled(identifier, enabled) diff --git a/analyzer/codechecker_analyzer/checkers.py b/analyzer/codechecker_analyzer/checkers.py index 1e9b6f7461..23f0c401c3 100644 --- a/analyzer/codechecker_analyzer/checkers.py +++ b/analyzer/codechecker_analyzer/checkers.py @@ -23,7 +23,8 @@ def available(ordered_checkers, available_checkers): if checker_name.startswith('profile:') or \ checker_name.startswith('guideline:') or \ checker_name.startswith('severity:') or \ - checker_name.startswith('sei-cert:'): + checker_name.startswith('sei-cert:') or \ + checker_name.startswith('prefix:'): continue name_match = False diff --git a/analyzer/codechecker_analyzer/cmd/analyze.py b/analyzer/codechecker_analyzer/cmd/analyze.py index 42e9336ad4..440018e243 100644 --- a/analyzer/codechecker_analyzer/cmd/analyze.py +++ b/analyzer/codechecker_analyzer/cmd/analyze.py @@ -699,6 +699,22 @@ def add_arguments_to_parser(parser): Note that compiler errors and warnings are captured by CodeChecker only if it was emitted by clang-tidy. +Checker prefix groups +------------------------------------------------ +Checker prefix groups allow you to enable checkers that share a common +prefix in their names. Checkers within a prefix group will have names that +start with the same identifier, making it easier to manage and reference +related checkers. + +You can enable/disable checkers belonging to a checker prefix group: +'-e