Skip to content

Commit ccbbeed

Browse files
committed
Add integration test for using CPPLINT.cfg file
1 parent 2cba6ce commit ccbbeed

4 files changed

Lines changed: 294 additions & 0 deletions

File tree

‎cpplint_clitest.py‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,9 @@ def testVlcSample(self):
166166
def testSillySample(self):
167167
self.checkAllInFolder('./samples/silly-sample', 4)
168168

169+
def testCfgFileSample(self):
170+
self.checkAllInFolder('./samples/cfg-file', 1)
171+
169172
def testBoostSample(self):
170173
self.checkAllInFolder('./samples/boost-sample', 4)
171174

‎samples/cfg-file/CPPLINT.cfg‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
set noparent
2+
filter=-whitespace,-build/include_what_you_use
3+
linelength=80

‎samples/cfg-file/simple.def‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
src/*.cpp
2+
1
3+
3
4+
Done processing src/sillycode.cpp
5+
Total errors found: 19
6+
7+
src/sillycode.cpp:0: No copyright message found. You should have a line: "Copyright [year] <Copyright Owner>" [legal/copyright] [5]
8+
src/sillycode.cpp:3: Found C system header after C++ system header. Should be: sillycode.h, c system, c++ system, other. [build/include_order] [4]
9+
src/sillycode.cpp:14: Is this a non-const reference? If so, make const or use a pointer: vector<string>& v [runtime/references] [2]
10+
src/sillycode.cpp:40: If/else bodies with multiple statements require braces [readability/braces] [4]
11+
src/sillycode.cpp:66: Single-parameter constructors should be marked explicit. [runtime/explicit] [5]
12+
src/sillycode.cpp:76: Single-parameter constructors should be marked explicit. [runtime/explicit] [5]
13+
src/sillycode.cpp:85: Constructors callable with one argument should be marked explicit. [runtime/explicit] [5]
14+
src/sillycode.cpp:118: Is this a non-const reference? If so, make const or use a pointer: N::X& a [runtime/references] [2]
15+
src/sillycode.cpp:118: Is this a non-const reference? If so, make const or use a pointer: N::X& b [runtime/references] [2]
16+
src/sillycode.cpp:123: Is this a non-const reference? If so, make const or use a pointer: N::X& a [runtime/references] [2]
17+
src/sillycode.cpp:123: Is this a non-const reference? If so, make const or use a pointer: N::X& b [runtime/references] [2]
18+
src/sillycode.cpp:171: Do not use variable-length arrays. Use an appropriately named ('k' followed by CamelCase) compile-time constant for the size. [runtime/arrays] [1]
19+
src/sillycode.cpp:178: Static/global string variables are not permitted. [runtime/string] [4]
20+
src/sillycode.cpp:199: If an else has a brace on one side, it should have it on both [readability/braces] [5]
21+
src/sillycode.cpp:202: If an else has a brace on one side, it should have it on both [readability/braces] [5]
22+
src/sillycode.cpp:208: Static/global string variables are not permitted. [runtime/string] [4]
23+
src/sillycode.cpp:227: Static/global string variables are not permitted. [runtime/string] [4]
24+
src/sillycode.cpp:228: Using C-style cast. Use reinterpret_cast<double*>(...) instead [readability/casting] [4]
25+
src/sillycode.cpp:243: Using C-style cast. Use reinterpret_cast<derived2*>(...) instead [readability/casting] [4]
26+

‎samples/cfg-file/src/sillycode.cpp‎

Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
#include <vector>
2+
3+
#include <gtest/test.h>
4+
5+
#include <something.hh>
6+
class Date {
7+
// ...
8+
public:
9+
Month month() const; // do
10+
int month(); // don't
11+
// ...
12+
};
13+
14+
void do_something(vector<string>& v)
15+
{
16+
string val;
17+
cin >> val;
18+
// ...
19+
int index = 0; // bad
20+
for (int i = 0; i < v.size(); ++i)
21+
if (v[i] == val) {
22+
index = i;
23+
break;
24+
}
25+
// ...
26+
}
27+
28+
struct X {
29+
char ch;
30+
int i;
31+
string s;
32+
char ch2;
33+
34+
X& operator=(const X& a);
35+
X(const X&);
36+
};
37+
38+
X waste(const char* p)
39+
{
40+
if (p == nullptr) throw Nullptr_error{};
41+
int n = strlen(p);
42+
auto buf = new char[n];
43+
if (buf == nullptr) throw Allocation_error{};
44+
for (int i = 0; i < n; ++i) buf[i] = p[i];
45+
// ... manipulate buffer ...
46+
X x;
47+
x.ch = 'a';
48+
x.s = string(n); // give x.s space for *ps
49+
for (int i = 0; i < x.s.size(); ++i) x.s[i] = buf[i]; // copy buf into x.s
50+
delete buf;
51+
return x;
52+
}
53+
54+
void driver()
55+
{
56+
X x = waste("Typical argument");
57+
// ...
58+
}
59+
60+
class X { // BAD
61+
int i;
62+
string s;
63+
int j;
64+
public:
65+
X() :i{666}, s{"qqq"} { } // j is uninitialized
66+
X(int ii) :i{ii} {} // s is "" and j is uninitialized
67+
// ...
68+
};
69+
70+
class X2 {
71+
int i {666};
72+
string s {"qqq"};
73+
int j {0};
74+
public:
75+
X2() = default; // all members are initialized to their defaults
76+
X2(int ii) :i{ii} {} // s and j initialized to their defaults
77+
// ...
78+
};
79+
80+
class X3 { // BAD: inexplicit, argument passing overhead
81+
int i;
82+
string s;
83+
int j;
84+
public:
85+
X3(int ii = 666, const string& ss = "qqq", int jj = 0)
86+
:i{ii}, s{ss}, j{jj} { } // all members are initialized to their defaults
87+
// ...
88+
};
89+
90+
91+
class Foo {
92+
string s;
93+
int i;
94+
public:
95+
Foo& operator=(Foo&& a);
96+
// ...
97+
};
98+
99+
Foo& Foo::operator=(Foo&& a) // OK, but there is a cost
100+
{
101+
if (this == &a) return *this; // this line is redundant
102+
s = std::move(a.s);
103+
i = a.i;
104+
return *this;
105+
}
106+
107+
template<typename T>
108+
class Vector2 {
109+
// ...
110+
Vector2(Vector2&& a) { *this = a; } // just use the copy
111+
Vector2& operator=(Vector2&& a) { *this = a; } // just use the copy
112+
//...
113+
public:
114+
T* elem;
115+
int sz;
116+
};
117+
118+
void f2(N::X& a, N::X& b)
119+
{
120+
swap(a,b); // calls N::swap
121+
}
122+
123+
void f3(N::X& a, N::X& b)
124+
{
125+
using std::swap; // make std::swap available
126+
swap(a,b); // calls N::swap if it exists, otherwise std::swap
127+
}
128+
129+
130+
// webcolors.h (third party header)
131+
#define RED 0xFF0000
132+
#define GREEN 0x00FF00
133+
#define BLUE 0x0000FF
134+
135+
// productinfo.h
136+
// The following define product subtypes based on color
137+
#define RED 0
138+
#define PURPLE 1
139+
#define BLUE 2
140+
141+
int webby = BLUE; // webby==2; probably not what was desired
142+
143+
enum class Webcolor { red=0xFF0000, green=0x00FF00, blue=0x0000FF };
144+
enum class Productinfo { red=0, purple=1, blue=2 };
145+
146+
int webby = blue; // error: be specific
147+
Webcolor webby = Webcolor::blue;
148+
149+
enum Webcolor { red=0xFF0000, green=0x00FF00, blue=0x0000FF };
150+
enum Productinfo { red=0, purple=1, blue=2 };
151+
152+
int webby = blue; // error, ambiguous: be specific
153+
Webcolor webby = Webcolor::blue;
154+
155+
enum class Webcolor { red=0xFF0000, green=0x00FF00, blue=0x0000FF };
156+
enum class Productinfo { red=0, purple=1, blue=2 };
157+
158+
int webby = blue; // error: blue undefined in this scope
159+
Webcolor webby = Webcolor::blue;
160+
161+
162+
void sink(unique_ptr<widget>); // consumes the widget
163+
164+
void sink(widget*); // just uses the widget
165+
166+
void thinko(const unique_ptr<widget>&); // usually not what you want
167+
168+
void reseat(unique_ptr<widget>&); // "will" or "might" reseat pointer
169+
170+
constexpr int max = 8*1024;
171+
int buf[max]; // OK, but suspicious: uninitialized
172+
f.read(buf, max);
173+
174+
constexpr int max = 8*1024;
175+
int buf[max] = {0}; // better in some situations
176+
f.read(buf, max);
177+
178+
string s; // s is default initialized to ""
179+
cin >> s; // s expands to hold the string
180+
181+
182+
error_code ec;
183+
Value v = [&] {
184+
auto p = get_value(); // get_value() returns a pair<error_code, Value>
185+
ec = p.first;
186+
return p.second;
187+
}();
188+
189+
Value v = [] {
190+
auto p = get_value(); // get_value() returns a pair<error_code, Value>
191+
if (p.first) throw Bad_value{p.first};
192+
return p.second;
193+
}();
194+
195+
SomeLargeType var; // ugly CaMeLcAsEvArIaBlE
196+
197+
if (cond) // some non-trivial condition
198+
Set(&var);
199+
else if (cond2 || !cond3) {
200+
var = Set2(3.14);
201+
}
202+
else {
203+
var = 0;
204+
for (auto& e : something)
205+
var += e;
206+
}
207+
208+
string var = [&]{
209+
if (!in) return ""; // default
210+
string s;
211+
for (char c : in >> c)
212+
s += toupper(c);
213+
return s;
214+
}(); // note ()
215+
216+
void use(int n)
217+
{
218+
switch (n) { // good
219+
case 0: // ...
220+
case 7: // ...
221+
}
222+
}
223+
224+
int n = numeric_limits<int>::max();
225+
int m = n + 1; // bad
226+
227+
std::string s = "hello world";
228+
double* p = (double*)(&s); // BAD
229+
230+
class base { public: virtual ~base() = 0; };
231+
232+
class derived1 : public base { };
233+
234+
class derived2 : public base {
235+
std::string s;
236+
public:
237+
std::string get_s() { return s; }
238+
};
239+
240+
derived1 d1;
241+
base* p = &d1; // ok, implicit conversion to pointer to base is fine
242+
243+
derived2* p2 = (derived2*)(p); // BAD, tries to treat d1 as a derived2, which it is not
244+
cout << p2.get_s(); // tries to access d1's nonexistent string member, instead sees arbitrary bytes near d1
245+
246+
void f(const int& i) {
247+
(int&)(i) = 42; // BAD
248+
}
249+
250+
static int i = 0;
251+
static const int j = 0;
252+
253+
f(i); // silent side effect
254+
f(j); // undefined behavior
255+
256+
257+
auto x = m*v1 + vv; // multiply m with v1 and add the result to vv
258+
259+
int i;
260+
for (i = 0; i < max; ++i); // bug waiting to happen
261+
if (i == j)
262+
return i;

0 commit comments

Comments
 (0)