129 lines
4.6 KiB
Ruby
129 lines
4.6 KiB
Ruby
class Cppcheck < Formula
|
|
desc "Static analysis of C and C++ code"
|
|
homepage "https://sourceforge.net/projects/cppcheck/"
|
|
url "https://github.com/danmar/cppcheck/archive/2.9.3.tar.gz"
|
|
sha256 "46319ca73e33e4b2bd91981a76a0d4f184cd3f86b62dc18e8938eabacd3ad2e3"
|
|
license "GPL-3.0-or-later"
|
|
head "https://github.com/danmar/cppcheck.git", branch: "main"
|
|
|
|
bottle do
|
|
sha256 arm64_ventura: "5d30c0dccdd1f66892f23d0207220a75618ebc81412f697298ad93384af8d787"
|
|
sha256 arm64_monterey: "ca5489c7d52a768992ee41a8b3f6491f08cb98957920aa49553a6de3a3b6cc8a"
|
|
sha256 arm64_big_sur: "7881dd73f227727e83e7bffb81a3e80bbc3f811732f140e2230e2c98c373f95d"
|
|
sha256 ventura: "d7a1b4d676ebf53f51ea61ab753381c0e08822f5320d30efdb6efd1115c4321a"
|
|
sha256 monterey: "5d63ca53bb4d817d2cc41204d84cfb0e8dc95b0f5c4b1256d266f9ad156799d6"
|
|
sha256 big_sur: "9a7b69603b4f40e0a82ac6ed542a534ef286c9331f4e8abb5bf9cb2d8958ef83"
|
|
sha256 catalina: "dce3803732af06c30cfbfcde968344590a78c60cdaae78a17722a97f87736470"
|
|
sha256 x86_64_linux: "f7893b050c0ad9983c5c76a82c581e54f27bda149c63b8ed31bc1b32b506b034"
|
|
end
|
|
|
|
depends_on "cmake" => :build
|
|
depends_on "python@3.11" => [:build, :test]
|
|
depends_on "pcre"
|
|
depends_on "tinyxml2"
|
|
|
|
uses_from_macos "libxml2"
|
|
|
|
def python3
|
|
which("python3.11")
|
|
end
|
|
|
|
def install
|
|
args = std_cmake_args + %W[
|
|
-DHAVE_RULES=ON
|
|
-DUSE_MATCHCOMPILER=ON
|
|
-DUSE_BUNDLED_TINYXML2=OFF
|
|
-DENABLE_OSS_FUZZ=OFF
|
|
-DPYTHON_EXECUTABLE=#{python3}
|
|
]
|
|
system "cmake", "-S", ".", "-B", "build", *args
|
|
system "cmake", "--build", "build"
|
|
system "cmake", "--install", "build"
|
|
|
|
# Move the python addons to the cppcheck pkgshare folder
|
|
(pkgshare/"addons").install Dir.glob("addons/*.py")
|
|
end
|
|
|
|
test do
|
|
# Execution test with an input .cpp file
|
|
test_cpp_file = testpath/"test.cpp"
|
|
test_cpp_file.write <<~EOS
|
|
#include <iostream>
|
|
using namespace std;
|
|
|
|
int main()
|
|
{
|
|
cout << "Hello World!" << endl;
|
|
return 0;
|
|
}
|
|
|
|
class Example
|
|
{
|
|
public:
|
|
int GetNumber() const;
|
|
explicit Example(int initialNumber);
|
|
private:
|
|
int number;
|
|
};
|
|
|
|
Example::Example(int initialNumber)
|
|
{
|
|
number = initialNumber;
|
|
}
|
|
EOS
|
|
system "#{bin}/cppcheck", test_cpp_file
|
|
|
|
# Test the "out of bounds" check
|
|
test_cpp_file_check = testpath/"testcheck.cpp"
|
|
test_cpp_file_check.write <<~EOS
|
|
int main()
|
|
{
|
|
char a[10];
|
|
a[10] = 0;
|
|
return 0;
|
|
}
|
|
EOS
|
|
output = shell_output("#{bin}/cppcheck #{test_cpp_file_check} 2>&1")
|
|
assert_match "out of bounds", output
|
|
|
|
# Test the addon functionality: sampleaddon.py imports the cppcheckdata python
|
|
# module and uses it to parse a cppcheck dump into an OOP structure. We then
|
|
# check the correct number of detected tokens and function names.
|
|
addons_dir = pkgshare/"addons"
|
|
cppcheck_module = "#{name}data"
|
|
expect_token_count = 55
|
|
expect_function_names = "main,GetNumber,Example"
|
|
assert_parse_message = "Error: sampleaddon.py: failed: can't parse the #{name} dump."
|
|
|
|
sample_addon_file = testpath/"sampleaddon.py"
|
|
sample_addon_file.write <<~EOS
|
|
#!/usr/bin/env #{python3}
|
|
"""A simple test addon for #{name}, prints function names and token count"""
|
|
import sys
|
|
from importlib import machinery, util
|
|
# Manually import the '#{cppcheck_module}' module
|
|
spec = machinery.PathFinder().find_spec("#{cppcheck_module}", ["#{addons_dir}"])
|
|
cpp_check_data = util.module_from_spec(spec)
|
|
spec.loader.exec_module(cpp_check_data)
|
|
|
|
for arg in sys.argv[1:]:
|
|
# Parse the dump file generated by #{name}
|
|
configKlass = cpp_check_data.parsedump(arg)
|
|
if len(configKlass.configurations) == 0:
|
|
sys.exit("#{assert_parse_message}") # Parse failure
|
|
fConfig = configKlass.configurations[0]
|
|
# Pick and join the function names in a string, separated by ','
|
|
detected_functions = ','.join(fn.name for fn in fConfig.functions)
|
|
detected_token_count = len(fConfig.tokenlist)
|
|
# Print the function names on the first line and the token count on the second
|
|
print("%s\\n%s" %(detected_functions, detected_token_count))
|
|
EOS
|
|
|
|
system "#{bin}/cppcheck", "--dump", test_cpp_file
|
|
test_cpp_file_dump = "#{test_cpp_file}.dump"
|
|
assert_predicate testpath/test_cpp_file_dump, :exist?
|
|
output = shell_output("#{python3} #{sample_addon_file} #{test_cpp_file_dump}")
|
|
assert_match "#{expect_function_names}\n#{expect_token_count}", output
|
|
end
|
|
end
|