forked from Homebrew/homebrew-core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcppcheck.rb
141 lines (120 loc) · 4.72 KB
/
cppcheck.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
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.78.tar.gz"
sha256 "31048901dd8744d12b3e6ac1bc904c08a72cad8118bd6a1f56ce489701ffd1b6"
head "https://github.com/danmar/cppcheck.git"
bottle do
rebuild 1
sha256 "ed03ed3ef038cc7da0e4aa83d520f6c9e34e92d9a7b4f4efae0bd7b54ace775b" => :sierra
sha256 "10bf6ee8d192ae51cade858efe9575b8c1112e06e955e5d0406d78978a20271b" => :el_capitan
sha256 "3e64f1ee49d495cad0fdec7ed6af73ab9c7e0da4c9461b09c786fd5c08174afc" => :yosemite
end
option "without-rules", "Build without rules (no pcre dependency)"
option "with-qt", "Build the cppcheck GUI (requires Qt)"
deprecated_option "no-rules" => "without-rules"
deprecated_option "with-gui" => "with-qt"
deprecated_option "with-qt5" => "with-qt"
depends_on "pcre" if build.with? "rules"
depends_on "qt" => :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? "qt"
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