140 lines
4.8 KiB
Ruby
140 lines
4.8 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/1.75.tar.gz"
|
|
sha256 "d3732dba3fb4dee075009e2422cd9b48bbd095249994ec60550aee43026030e5"
|
|
head "https://github.com/danmar/cppcheck.git"
|
|
|
|
bottle do
|
|
sha256 "cd54368b63ca1ab7e6c47064373001b3c560b1cf2d2ffd1caf63ac31d49334d5" => :sierra
|
|
sha256 "754138e7816ebfcd2cffed7b345eb21c030073713376c21fef68e1aa58edd78a" => :el_capitan
|
|
sha256 "920c43b65dfd11d6c9f829cff3b6dfbd561bd8b07ee983128d4f31ab374bd5c7" => :yosemite
|
|
sha256 "1d5a015ee5d0c85aced3691a6d7cd38c43d51eb286ed125bd71e88b0626e067d" => :mavericks
|
|
end
|
|
|
|
option "without-rules", "Build without rules (no pcre dependency)"
|
|
option "with-qt5", "Build the cppcheck GUI (requires Qt)"
|
|
|
|
deprecated_option "no-rules" => "without-rules"
|
|
deprecated_option "with-gui" => "with-qt5"
|
|
|
|
depends_on "pcre" if build.with? "rules"
|
|
depends_on "qt5" => :optional
|
|
|
|
needs :cxx11
|
|
|
|
def install
|
|
ENV.cxx11
|
|
|
|
# Man pages aren't installed as they require docbook schemas.
|
|
|
|
# Pass to make variables.
|
|
if build.with? "rules"
|
|
system "make", "HAVE_RULES=yes", "CFGDIR=#{prefix}/cfg"
|
|
else
|
|
system "make", "HAVE_RULES=no", "CFGDIR=#{prefix}/cfg"
|
|
end
|
|
|
|
# CFGDIR is relative to the prefix for install, don't add #{prefix}.
|
|
system "make", "DESTDIR=#{prefix}", "BIN=#{bin}", "CFGDIR=/cfg", "install"
|
|
|
|
# Move the python addons to the cppcheck pkgshare folder
|
|
(pkgshare/"addons").install Dir.glob(bin/"*.py")
|
|
|
|
if build.with? "qt5"
|
|
cd "gui" do
|
|
if build.with? "rules"
|
|
system "qmake", "HAVE_RULES=yes",
|
|
"INCLUDEPATH+=#{Formula["pcre"].opt_include}",
|
|
"LIBS+=-L#{Formula["pcre"].opt_lib}"
|
|
else
|
|
system "qmake", "HAVE_RULES=no"
|
|
end
|
|
|
|
system "make"
|
|
prefix.install "cppcheck-gui.app"
|
|
end
|
|
end
|
|
end
|
|
|
|
test do
|
|
# Execution test with an input .cpp file
|
|
test_cpp_file = testpath/"test.cpp"
|
|
test_cpp_file.write <<-EOS.undent
|
|
#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.undent
|
|
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.undent
|
|
#!/usr/bin/env python
|
|
"""A simple test addon for #{name}, prints function names and token count"""
|
|
import sys
|
|
import imp
|
|
# Manually import the '#{cppcheck_module}' module
|
|
CFILE, FNAME, CDATA = imp.find_module("#{cppcheck_module}", ["#{addons_dir}"])
|
|
CPPCHECKDATA = imp.load_module("#{cppcheck_module}", CFILE, FNAME, CDATA)
|
|
|
|
for arg in sys.argv[1:]:
|
|
# Parse the dump file generated by #{name}
|
|
configKlass = CPPCHECKDATA.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 File.exist? test_cpp_file_dump
|
|
python_addon_output = shell_output "python #{sample_addon_file} #{test_cpp_file_dump}"
|
|
assert_match "#{expect_function_names}\n#{expect_token_count}", python_addon_output
|
|
end
|
|
end
|