|
12 | 12 | import os
|
13 | 13 | import plistlib
|
14 | 14 | import re
|
15 |
| -import shlex |
16 | 15 | import subprocess
|
| 16 | +import sys |
| 17 | +from typing import List, Tuple |
17 | 18 |
|
18 |
| -from typing import List |
19 |
| - |
| 19 | +from codechecker_common import util |
20 | 20 | from codechecker_common.logger import get_logger
|
21 | 21 |
|
22 | 22 | from codechecker_analyzer import analyzer_context, env
|
|
42 | 42 | def parse_clang_help_page(
|
43 | 43 | command: List[str],
|
44 | 44 | start_label: str
|
45 |
| -) -> List[str]: |
| 45 | +) -> List[Tuple[str, str]]: |
46 | 46 | """
|
47 | 47 | Parse the clang help page starting from a specific label.
|
48 | 48 | Returns a list of (flag, description) tuples.
|
@@ -121,6 +121,12 @@ class ClangSA(analyzer_base.SourceAnalyzer):
|
121 | 121 |
|
122 | 122 | __ctu_autodetection = None
|
123 | 123 |
|
| 124 | + __additional_analyzer_config = { |
| 125 | + 'cc-verbatim-args-file': |
| 126 | + 'A file path containing flags that are forwarded verbatim to the ' |
| 127 | + 'analyzer tool. E.g.: cc-verbatim-args-file=<filepath>' |
| 128 | + } |
| 129 | + |
124 | 130 | def __init__(self, cfg_handler, buildaction):
|
125 | 131 | super().__init__(cfg_handler, buildaction)
|
126 | 132 | self.__disable_ctu = False
|
@@ -308,15 +314,17 @@ def get_checker_config(cls) -> List[str]:
|
308 | 314 | return parse_clang_help_page(command, 'OPTIONS:')
|
309 | 315 |
|
310 | 316 | @classmethod
|
311 |
| - def get_analyzer_config(cls) -> List[str]: |
| 317 | + def get_analyzer_config(cls) -> List[Tuple[str, str]]: |
312 | 318 | """Return the list of analyzer config options."""
|
313 | 319 | command = [cls.analyzer_binary(), "-cc1"]
|
314 | 320 |
|
315 | 321 | cls.__add_plugin_load_flags(command)
|
316 | 322 |
|
317 | 323 | command.append("-analyzer-config-help")
|
318 | 324 |
|
319 |
| - return parse_clang_help_page(command, 'OPTIONS:') |
| 325 | + native_config = parse_clang_help_page(command, 'OPTIONS:') |
| 326 | + |
| 327 | + return native_config + list(cls.__additional_analyzer_config.items()) |
320 | 328 |
|
321 | 329 | def post_analyze(self, result_handler):
|
322 | 330 | """
|
@@ -636,28 +644,13 @@ def construct_config_handler(cls, args):
|
636 | 644 | 'ctu_ast_mode' in args and \
|
637 | 645 | args.ctu_ast_mode == 'parse-on-demand'
|
638 | 646 |
|
639 |
| - try: |
640 |
| - with open(args.clangsa_args_cfg_file, 'r', encoding='utf8', |
641 |
| - errors='ignore') as sa_cfg: |
642 |
| - handler.analyzer_extra_arguments = \ |
643 |
| - re.sub(r'\$\((.*?)\)', |
644 |
| - env.replace_env_var(args.clangsa_args_cfg_file), |
645 |
| - sa_cfg.read().strip()) |
646 |
| - handler.analyzer_extra_arguments = \ |
647 |
| - shlex.split(handler.analyzer_extra_arguments) |
648 |
| - except IOError as ioerr: |
649 |
| - LOG.debug_analyzer(ioerr) |
650 |
| - except AttributeError as aerr: |
651 |
| - # No clangsa arguments file was given in the command line. |
652 |
| - LOG.debug_analyzer(aerr) |
653 |
| - |
654 | 647 | checkers = ClangSA.get_analyzer_checkers()
|
655 | 648 |
|
656 | 649 | try:
|
657 | 650 | cmdline_checkers = args.ordered_checkers
|
658 | 651 | except AttributeError:
|
659 |
| - LOG.debug_analyzer('No checkers were defined in ' |
660 |
| - 'the command line for %s', cls.ANALYZER_NAME) |
| 652 | + LOG.debug('No checkers were defined in the command line for %s', |
| 653 | + cls.ANALYZER_NAME) |
661 | 654 | cmdline_checkers = []
|
662 | 655 |
|
663 | 656 | handler.initialize_checkers(
|
@@ -716,7 +709,19 @@ def construct_config_handler(cls, args):
|
716 | 709 | if 'analyzer_config' in args and \
|
717 | 710 | isinstance(args.analyzer_config, list):
|
718 | 711 | for cfg in args.analyzer_config:
|
719 |
| - if cfg.analyzer == cls.ANALYZER_NAME: |
| 712 | + # TODO: The analyzer plugin should get only its own analyzer |
| 713 | + # config options from outside. |
| 714 | + if cfg.analyzer != cls.ANALYZER_NAME: |
| 715 | + continue |
| 716 | + |
| 717 | + if cfg.option == 'cc-verbatim-args-file': |
| 718 | + try: |
| 719 | + handler.analyzer_extra_arguments = \ |
| 720 | + util.load_args_from_file(cfg.value) |
| 721 | + except FileNotFoundError: |
| 722 | + LOG.error(f"File not found: {cfg.value}") |
| 723 | + sys.exit(1) |
| 724 | + else: |
720 | 725 | handler.checker_config.append(f"{cfg.option}={cfg.value}")
|
721 | 726 |
|
722 | 727 | return handler
|
0 commit comments