| 437 | |
| 438 | |
| 439 | def scan_package(cppcheck_path, source_path, libraries, capture_callstack=True, enable='style,information', debug_warnings=True, check_level=None, extra_args=None): |
| 440 | print('Analyze..') |
| 441 | libs = '' |
| 442 | for library in libraries: |
| 443 | if os.path.exists(os.path.join(cppcheck_path, 'cfg', library + '.cfg')): |
| 444 | libs += '--library=' + library + ' ' |
| 445 | |
| 446 | dir_to_scan = source_path |
| 447 | |
| 448 | # TODO: temporarily disabled timing information - use --showtime=top5_summary when next version is released |
| 449 | # Reference for GNU C: https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html |
| 450 | options = '{} --inconclusive --enable={} --inline-suppr --template=daca2'.format(libs, enable) |
| 451 | if 'information' in enable: |
| 452 | # TODO: remove missingInclude disabling after 2.16 has been released |
| 453 | options += ' --disable=missingInclude --suppress=unmatchedSuppression' |
| 454 | if check_level: |
| 455 | options += ' --check-level=' + check_level |
| 456 | if extra_args: |
| 457 | options += ' ' + extra_args |
| 458 | if debug_warnings: |
| 459 | options += ' --check-library --debug-warnings --suppress=autoNoType --suppress=valueFlowBailout' \ |
| 460 | ' --suppress=bailoutUninitVar --suppress=symbolDatabaseWarning --suppress=normalCheckLevelConditionExpressions' |
| 461 | options += ' -D__GNUC__ --platform=unix64' |
| 462 | options_rp = options + ' -rp={}'.format(dir_to_scan) |
| 463 | if __make_cmd == 'msbuild.exe': |
| 464 | cppcheck_cmd = os.path.join(cppcheck_path, 'bin', 'cppcheck.exe') + ' ' + options_rp |
| 465 | cmd = cppcheck_cmd + ' ' + __jobs + ' ' + dir_to_scan |
| 466 | else: |
| 467 | nice_cmd = 'nice' |
| 468 | if __make_cmd == 'mingw32-make': |
| 469 | nice_cmd = '' |
| 470 | cppcheck_cmd = os.path.join(cppcheck_path, 'cppcheck') + ' ' + options_rp |
| 471 | cmd = nice_cmd + ' ' + cppcheck_cmd + ' ' + __jobs + ' ' + dir_to_scan |
| 472 | returncode, stdout, stderr, elapsed_time = __run_command(cmd) |
| 473 | |
| 474 | # collect messages |
| 475 | information_messages_list = [] |
| 476 | issue_messages_list = [] |
| 477 | internal_error_messages_list = [] |
| 478 | count = 0 |
| 479 | re_obj = None |
| 480 | for line in stderr.split('\n'): |
| 481 | if ': information: ' in line: |
| 482 | information_messages_list.append(line + '\n') |
| 483 | elif line: |
| 484 | issue_messages_list.append(line + '\n') |
| 485 | if re_obj is None: |
| 486 | re_obj = re.compile(r'.*:[0-9]+:.*\]$') |
| 487 | if re_obj.match(line): |
| 488 | count += 1 |
| 489 | if ': error: Internal error: ' in line: |
| 490 | internal_error_messages_list.append(line + '\n') |
| 491 | print('Number of issues: ' + str(count)) |
| 492 | # Collect timing information |
| 493 | stdout_lines = stdout.split('\n') |
| 494 | timing_info_list = [] |
| 495 | overall_time_found = False |
| 496 | max_timing_lines = 6 |