adlint 1.10.0 → 1.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/ChangeLog +197 -4
  2. data/MANIFEST +17 -0
  3. data/NEWS +23 -4
  4. data/etc/mesg.d/en_US/messages.yml +14 -1
  5. data/etc/mesg.d/ja_JP/messages.yml +14 -1
  6. data/features/message_detection/W0093.feature +87 -0
  7. data/features/message_detection/W0687.feature +25 -0
  8. data/features/message_detection/W0688.feature +63 -0
  9. data/features/message_detection/W0689.feature +46 -0
  10. data/features/message_detection/W0690.feature +35 -0
  11. data/features/message_detection/W0698.feature +3 -2
  12. data/features/message_detection/W0703.feature +1 -0
  13. data/features/message_detection/W0723.feature +34 -0
  14. data/features/message_detection/W0732.feature +158 -0
  15. data/features/message_detection/W0733.feature +158 -0
  16. data/features/message_detection/W0734.feature +322 -0
  17. data/features/message_detection/W0735.feature +322 -0
  18. data/features/message_detection/W1052.feature +66 -0
  19. data/features/message_detection/W9001.feature +33 -0
  20. data/features/message_detection/W9003.feature +131 -0
  21. data/lib/adlint/c/ctrlexpr.rb +51 -50
  22. data/lib/adlint/c/domain.rb +237 -223
  23. data/lib/adlint/c/expr.rb +6 -8
  24. data/lib/adlint/c/interp.rb +8 -11
  25. data/lib/adlint/c/message.rb +20 -0
  26. data/lib/adlint/c/message_shima.rb +63 -0
  27. data/lib/adlint/c/object.rb +5 -4
  28. data/lib/adlint/c/operator.rb +99 -0
  29. data/lib/adlint/c/parser.rb +2 -2
  30. data/lib/adlint/c/parser.y +2 -2
  31. data/lib/adlint/c/phase.rb +6 -1
  32. data/lib/adlint/c/syntax.rb +442 -30
  33. data/lib/adlint/c/type.rb +449 -363
  34. data/lib/adlint/c/value.rb +96 -25
  35. data/lib/adlint/c.rb +1 -0
  36. data/lib/adlint/prelude.rb +16 -18
  37. data/lib/adlint/version.rb +2 -2
  38. data/share/doc/developers_guide_ja.html +11 -5
  39. data/share/doc/developers_guide_ja.texi +9 -3
  40. data/share/doc/users_guide_en.html +697 -131
  41. data/share/doc/users_guide_en.texi +491 -41
  42. data/share/doc/users_guide_ja.html +709 -139
  43. data/share/doc/users_guide_ja.texi +499 -45
  44. data/spec/adlint/c/ctrlexpr_spec.rb +168 -0
  45. data/spec/adlint/c/domain_spec.rb +835 -0
  46. data/spec/adlint/c/operator_spec.rb +406 -0
  47. data/spec/adlint/c/syntax_spec.rb +717 -0
  48. data/spec/adlint/c/type_spec.rb +55 -30
  49. metadata +19 -2
@@ -0,0 +1,322 @@
1
+ Feature: W0735
2
+
3
+ W0735 detects that right side of logical expression is bitwise expression or
4
+ arithmetic expression.
5
+
6
+ Scenario: right side of `&&' operator is an arithmetic expression
7
+ Given a target source named "W0735.c" with:
8
+ """
9
+ static void func(int a, int b, int c)
10
+ {
11
+ int r;
12
+
13
+ r = a && (b + c); /* W0735 */
14
+ r = a && (b - c); /* W0735 */
15
+ r = a && (b * c); /* W0735 */
16
+ r = a && (b / c); /* W0735 */
17
+ r = a && (b % c); /* W0735 */
18
+ }
19
+ """
20
+ When I successfully run `adlint W0735.c` on noarch
21
+ Then the output should exactly match with:
22
+ | mesg | line | column |
23
+ | W0723 | 5 | 17 |
24
+ | W0723 | 6 | 17 |
25
+ | W0723 | 7 | 17 |
26
+ | W0093 | 8 | 17 |
27
+ | W0093 | 9 | 17 |
28
+ | W0104 | 1 | 22 |
29
+ | W0104 | 1 | 29 |
30
+ | W0104 | 1 | 36 |
31
+ | W0629 | 1 | 13 |
32
+ | W0088 | 5 | 11 |
33
+ | W0735 | 5 | 14 |
34
+ | W0088 | 6 | 11 |
35
+ | W0735 | 6 | 14 |
36
+ | W0088 | 7 | 11 |
37
+ | W0735 | 7 | 14 |
38
+ | W0088 | 8 | 11 |
39
+ | W0735 | 8 | 14 |
40
+ | W0088 | 9 | 11 |
41
+ | W0735 | 9 | 14 |
42
+ | W0628 | 1 | 13 |
43
+
44
+ Scenario: right side of `&&' operator is an arithmetic expression
45
+ Given a target source named "W0735.c" with:
46
+ """
47
+ static void func(int a, int b, int c, int d)
48
+ {
49
+ int r;
50
+
51
+ r = (a == b) && (c + d); /* W0735 */
52
+ r = (a = b) && (c - d); /* W0735 */
53
+ r = (a && b) && (c * d); /* W0735 */
54
+ r = (a < b) && (c / d); /* W0735 */
55
+ r = (a != b) && (c % d); /* W0735 */
56
+ }
57
+ """
58
+ When I successfully run `adlint W0735.c` on noarch
59
+ Then the output should exactly match with:
60
+ | mesg | line | column |
61
+ | W0723 | 5 | 24 |
62
+ | W0723 | 6 | 23 |
63
+ | W0723 | 7 | 24 |
64
+ | W0093 | 8 | 23 |
65
+ | W0093 | 9 | 24 |
66
+ | W0104 | 1 | 29 |
67
+ | W0104 | 1 | 36 |
68
+ | W0104 | 1 | 43 |
69
+ | W0629 | 1 | 13 |
70
+ | W0088 | 5 | 18 |
71
+ | W0735 | 5 | 21 |
72
+ | W0088 | 6 | 17 |
73
+ | W0735 | 6 | 20 |
74
+ | W0088 | 7 | 18 |
75
+ | W0735 | 7 | 21 |
76
+ | W0088 | 8 | 17 |
77
+ | W0735 | 8 | 20 |
78
+ | W0088 | 9 | 18 |
79
+ | W0735 | 9 | 21 |
80
+ | W0108 | 6 | 12 |
81
+ | W0628 | 1 | 13 |
82
+
83
+ Scenario: right side of `||' operator is an arithmetic expression
84
+ Given a target source named "W0735.c" with:
85
+ """
86
+ static void func(int a, int b, int c)
87
+ {
88
+ int r;
89
+
90
+ r = a || (b + c); /* W0735 */
91
+ r = a || (b - c); /* W0735 */
92
+ r = a || (b * c); /* W0735 */
93
+ r = a || (b / c); /* W0735 */
94
+ r = a || (b % c); /* W0735 */
95
+ }
96
+ """
97
+ When I successfully run `adlint W0735.c` on noarch
98
+ Then the output should exactly match with:
99
+ | mesg | line | column |
100
+ | W0723 | 5 | 17 |
101
+ | W0723 | 6 | 17 |
102
+ | W0723 | 7 | 17 |
103
+ | W0093 | 8 | 17 |
104
+ | W0093 | 9 | 17 |
105
+ | W0104 | 1 | 22 |
106
+ | W0104 | 1 | 29 |
107
+ | W0104 | 1 | 36 |
108
+ | W0629 | 1 | 13 |
109
+ | W0088 | 5 | 11 |
110
+ | W0735 | 5 | 14 |
111
+ | W0088 | 6 | 11 |
112
+ | W0735 | 6 | 14 |
113
+ | W0088 | 7 | 11 |
114
+ | W0735 | 7 | 14 |
115
+ | W0088 | 8 | 11 |
116
+ | W0735 | 8 | 14 |
117
+ | W0088 | 9 | 11 |
118
+ | W0735 | 9 | 14 |
119
+ | W0628 | 1 | 13 |
120
+
121
+ Scenario: right side of `||' operator is an arithmetic expression
122
+ Given a target source named "W0735.c" with:
123
+ """
124
+ static void func(int a, int b, int c, int d)
125
+ {
126
+ int r;
127
+
128
+ r = (a == b) || (c + d); /* W0735 */
129
+ r = (a = b) || (c - d); /* W0735 */
130
+ r = (a || b) || (c * d); /* W0735 */
131
+ r = (a < b) || (c / d); /* W0735 */
132
+ r = (a != b) || (c % d); /* W0735 */
133
+ }
134
+ """
135
+ When I successfully run `adlint W0735.c` on noarch
136
+ Then the output should exactly match with:
137
+ | mesg | line | column |
138
+ | W0723 | 5 | 24 |
139
+ | W0723 | 6 | 23 |
140
+ | W0723 | 7 | 24 |
141
+ | W0093 | 8 | 23 |
142
+ | W0093 | 9 | 24 |
143
+ | W0104 | 1 | 29 |
144
+ | W0104 | 1 | 36 |
145
+ | W0104 | 1 | 43 |
146
+ | W0629 | 1 | 13 |
147
+ | W0088 | 5 | 18 |
148
+ | W0735 | 5 | 21 |
149
+ | W0088 | 6 | 17 |
150
+ | W0735 | 6 | 20 |
151
+ | W0088 | 7 | 18 |
152
+ | W0735 | 7 | 21 |
153
+ | W0088 | 8 | 17 |
154
+ | W0735 | 8 | 20 |
155
+ | W0088 | 9 | 18 |
156
+ | W0735 | 9 | 21 |
157
+ | W0108 | 6 | 12 |
158
+ | W0628 | 1 | 13 |
159
+
160
+ Scenario: right side of `&&' operator is a bitwise expression
161
+ Given a target source named "W0735.c" with:
162
+ """
163
+ static void func(int a, int b, int c)
164
+ {
165
+ int r;
166
+
167
+ r = a && (b << c); /* W0735 */
168
+ r = a && (b >> c); /* W0735 */
169
+ r = a && (b & c); /* W0735 */
170
+ r = a && (b ^ c); /* W0735 */
171
+ r = a && (b | c); /* W0735 */
172
+ }
173
+ """
174
+ When I successfully run `adlint W0735.c` on noarch
175
+ Then the output should exactly match with:
176
+ | mesg | line | column |
177
+ | W0570 | 5 | 17 |
178
+ | W0572 | 5 | 17 |
179
+ | W0571 | 6 | 17 |
180
+ | W0572 | 6 | 17 |
181
+ | W0572 | 7 | 17 |
182
+ | W0572 | 8 | 17 |
183
+ | W0572 | 9 | 17 |
184
+ | W0104 | 1 | 22 |
185
+ | W0104 | 1 | 29 |
186
+ | W0104 | 1 | 36 |
187
+ | W0629 | 1 | 13 |
188
+ | W0088 | 5 | 11 |
189
+ | W0735 | 5 | 14 |
190
+ | W0088 | 6 | 11 |
191
+ | W0735 | 6 | 14 |
192
+ | W0088 | 7 | 11 |
193
+ | W0735 | 7 | 14 |
194
+ | W0088 | 8 | 11 |
195
+ | W0735 | 8 | 14 |
196
+ | W0088 | 9 | 11 |
197
+ | W0735 | 9 | 14 |
198
+ | W0628 | 1 | 13 |
199
+
200
+ Scenario: right side of `||' operator is a bitwise expression
201
+ Given a target source named "W0735.c" with:
202
+ """
203
+ static void func(int a, int b, int c)
204
+ {
205
+ int r;
206
+
207
+ r = a || (b << c); /* W0735 */
208
+ r = a || (b >> c); /* W0735 */
209
+ r = a || (b & c); /* W0735 */
210
+ r = a || (b ^ c); /* W0735 */
211
+ r = a || (b | c); /* W0735 */
212
+ }
213
+ """
214
+ When I successfully run `adlint W0735.c` on noarch
215
+ Then the output should exactly match with:
216
+ | mesg | line | column |
217
+ | W0570 | 5 | 17 |
218
+ | W0572 | 5 | 17 |
219
+ | W0571 | 6 | 17 |
220
+ | W0572 | 6 | 17 |
221
+ | W0572 | 7 | 17 |
222
+ | W0572 | 8 | 17 |
223
+ | W0572 | 9 | 17 |
224
+ | W0104 | 1 | 22 |
225
+ | W0104 | 1 | 29 |
226
+ | W0104 | 1 | 36 |
227
+ | W0629 | 1 | 13 |
228
+ | W0088 | 5 | 11 |
229
+ | W0735 | 5 | 14 |
230
+ | W0088 | 6 | 11 |
231
+ | W0735 | 6 | 14 |
232
+ | W0088 | 7 | 11 |
233
+ | W0735 | 7 | 14 |
234
+ | W0088 | 8 | 11 |
235
+ | W0735 | 8 | 14 |
236
+ | W0088 | 9 | 11 |
237
+ | W0735 | 9 | 14 |
238
+ | W0628 | 1 | 13 |
239
+
240
+ Scenario: right side of `&&' operator is a bitwise expression
241
+ Given a target source named "W0735.c" with:
242
+ """
243
+ static void func(int a, int b, int c, int d)
244
+ {
245
+ int r;
246
+
247
+ r = (a == b) && (c << d); /* W0735 */
248
+ r = (a = b) && (c >> d); /* W0735 */
249
+ r = (a && b) && (c & d); /* W0735 */
250
+ r = (a < b) && (c ^ d); /* W0735 */
251
+ r = (a != b) && (c | d); /* W0735 */
252
+ }
253
+ """
254
+ When I successfully run `adlint W0735.c` on noarch
255
+ Then the output should exactly match with:
256
+ | mesg | line | column |
257
+ | W0570 | 5 | 24 |
258
+ | W0572 | 5 | 24 |
259
+ | W0571 | 6 | 23 |
260
+ | W0572 | 6 | 23 |
261
+ | W0572 | 7 | 24 |
262
+ | W0572 | 8 | 23 |
263
+ | W0572 | 9 | 24 |
264
+ | W0104 | 1 | 29 |
265
+ | W0104 | 1 | 36 |
266
+ | W0104 | 1 | 43 |
267
+ | W0629 | 1 | 13 |
268
+ | W0088 | 5 | 18 |
269
+ | W0735 | 5 | 21 |
270
+ | W0088 | 6 | 17 |
271
+ | W0735 | 6 | 20 |
272
+ | W0088 | 7 | 18 |
273
+ | W0735 | 7 | 21 |
274
+ | W0088 | 8 | 17 |
275
+ | W0735 | 8 | 20 |
276
+ | W0088 | 9 | 18 |
277
+ | W0735 | 9 | 21 |
278
+ | W0108 | 6 | 12 |
279
+ | W0628 | 1 | 13 |
280
+
281
+ Scenario: right side of `||' operator is a bitwise expression
282
+ Given a target source named "W0735.c" with:
283
+ """
284
+ static void func(int a, int b, int c, int d)
285
+ {
286
+ int r;
287
+
288
+ r = (a == b) || (c << d); /* W0735 */
289
+ r = (a = b) || (c >> d); /* W0735 */
290
+ r = (a && b) || (c & d); /* W0735 */
291
+ r = (a < b) || (c ^ d); /* W0735 */
292
+ r = (a != b) || (c | d); /* W0735 */
293
+ }
294
+ """
295
+ When I successfully run `adlint W0735.c` on noarch
296
+ Then the output should exactly match with:
297
+ | mesg | line | column |
298
+ | W0570 | 5 | 24 |
299
+ | W0572 | 5 | 24 |
300
+ | W0571 | 6 | 23 |
301
+ | W0572 | 6 | 23 |
302
+ | W0572 | 7 | 24 |
303
+ | W0572 | 8 | 23 |
304
+ | W0572 | 9 | 24 |
305
+ | W0104 | 1 | 29 |
306
+ | W0104 | 1 | 36 |
307
+ | W0104 | 1 | 43 |
308
+ | W0629 | 1 | 13 |
309
+ | W0088 | 5 | 18 |
310
+ | W0735 | 5 | 21 |
311
+ | W0088 | 6 | 17 |
312
+ | W0735 | 6 | 20 |
313
+ | W0088 | 7 | 18 |
314
+ | W0735 | 7 | 21 |
315
+ | W0088 | 8 | 17 |
316
+ | W0735 | 8 | 20 |
317
+ | W0088 | 9 | 18 |
318
+ | W0735 | 9 | 21 |
319
+ | W0108 | 6 | 12 |
320
+ | W0628 | 1 | 13 |
321
+
322
+ # vim:ts=2:sw=2:sts=2:et:
@@ -0,0 +1,66 @@
1
+ Feature: W1052
2
+
3
+ W1052 detects that an arithmetic operation of unsigned values may be
4
+ overflow.
5
+
6
+ Scenario: multiplication of two arbitrary `unsigned char' values
7
+ Given a target source named "W1052.c" with:
8
+ """
9
+ static unsigned int foo(unsigned char a, unsigned char b)
10
+ {
11
+ return a * b; /* W1052 should not be output */
12
+ }
13
+ """
14
+ When I successfully run `adlint W1052.c` on noarch
15
+ Then the output should exactly match with:
16
+ | mesg | line | column |
17
+ | W0123 | 3 | 12 |
18
+ | W0246 | 3 | 12 |
19
+ | W0123 | 3 | 16 |
20
+ | W0246 | 3 | 16 |
21
+ | W0167 | 3 | 14 |
22
+ | W0303 | 3 | 5 |
23
+ | W0104 | 1 | 39 |
24
+ | W0104 | 1 | 56 |
25
+ | W0629 | 1 | 21 |
26
+ | W0628 | 1 | 21 |
27
+
28
+ Scenario: multiplication of two arbitrary `unsigned short' values
29
+ Given a target source named "W1052.c" with:
30
+ """
31
+ static unsigned int foo(unsigned short a, unsigned short b)
32
+ {
33
+ return a * b; /* W1052 */
34
+ }
35
+ """
36
+ When I successfully run `adlint W1052.c` on noarch
37
+ Then the output should exactly match with:
38
+ | mesg | line | column |
39
+ | W0248 | 3 | 12 |
40
+ | W0248 | 3 | 16 |
41
+ | W1052 | 3 | 14 |
42
+ | W0167 | 3 | 14 |
43
+ | W0303 | 3 | 5 |
44
+ | W0104 | 1 | 40 |
45
+ | W0104 | 1 | 58 |
46
+ | W0629 | 1 | 21 |
47
+ | W0628 | 1 | 21 |
48
+
49
+ Scenario: multiplication of two arbitrary `unsigned int' values
50
+ Given a target source named "W1052.c" with:
51
+ """
52
+ static unsigned int foo(unsigned int a, unsigned int b)
53
+ {
54
+ return a * b; /* W1052 */
55
+ }
56
+ """
57
+ When I successfully run `adlint W1052.c` on noarch
58
+ Then the output should exactly match with:
59
+ | mesg | line | column |
60
+ | W1052 | 3 | 14 |
61
+ | W0104 | 1 | 38 |
62
+ | W0104 | 1 | 54 |
63
+ | W0629 | 1 | 21 |
64
+ | W0628 | 1 | 21 |
65
+
66
+ # vim:ts=2:sw=2:sts=2:et:
@@ -0,0 +1,33 @@
1
+ Feature: W9001
2
+
3
+ W9001 detects that the control never reach to a statement.
4
+
5
+ Scenario: indefinitive controlling variable narrowing
6
+ Given a target source named "W9001.c" with:
7
+ """
8
+ static void bar(int);
9
+
10
+ int main(void)
11
+ {
12
+ int i;
13
+ int j;
14
+
15
+ for (i = 0; i < 10; i++) {
16
+ for (j = 0; j < 10; j++) {
17
+ if (i == j) {
18
+ bar(1);
19
+ }
20
+ else {
21
+ bar(2); /* W9001 should not be output */
22
+ }
23
+ }
24
+ }
25
+
26
+ return 0;
27
+ }
28
+ """
29
+ When I successfully run `adlint W9001.c` on noarch
30
+ Then the output should exactly match with:
31
+ | mesg | line | column |
32
+
33
+ # vim:ts=2:sw=2:sts=2:et:
@@ -0,0 +1,131 @@
1
+ Feature: W9003
2
+
3
+ W9003 detects that an object is implicitly converted into a new object of
4
+ the different type.
5
+
6
+ Scenario: passing an enum variable whose type differs from one of the
7
+ corresponding enum parameter
8
+ Given a target source named "W9003.c" with:
9
+ """
10
+ enum Color { RED, BLUE, GREEN };
11
+ enum Fruit { APPLE, BANANA, ORANGE };
12
+
13
+ extern void foo(enum Color);
14
+
15
+ static void bar(void)
16
+ {
17
+ foo(ORANGE); /* W9003 */
18
+ }
19
+ """
20
+ When I successfully run `adlint W9003.c` on noarch
21
+ Then the output should match with /8:.*:W9003/
22
+ And the output should exactly match with:
23
+ | mesg | line | column |
24
+ | W0118 | 4 | 13 |
25
+ | W9003 | 8 | 9 |
26
+ | W0728 | 8 | 9 |
27
+ | W0629 | 6 | 13 |
28
+ | W0628 | 6 | 13 |
29
+
30
+ Scenario: passing an enum argument as an `int' parameter
31
+ Given a target source named "W9003.c" with:
32
+ """
33
+ enum Color { RED, BLUE, GREEN };
34
+
35
+ extern void foo(int);
36
+
37
+ static void bar(void)
38
+ {
39
+ foo(RED); /* W9003 */
40
+ }
41
+ """
42
+ When I successfully run `adlint W9003.c` on noarch
43
+ Then the output should match with /7:.*:W9003/
44
+ And the output should exactly match with:
45
+ | mesg | line | column |
46
+ | W0118 | 3 | 13 |
47
+ | W9003 | 7 | 9 |
48
+ | W1059 | 7 | 9 |
49
+ | W0629 | 5 | 13 |
50
+ | W0628 | 5 | 13 |
51
+
52
+ Scenario: passing an `int' argument as an enum parameter
53
+ Given a target source named "W9003.c" with:
54
+ """
55
+ enum Color { RED, BLUE, GREEN };
56
+
57
+ extern void foo(enum Color);
58
+
59
+ static void bar(void)
60
+ {
61
+ foo(0); /* W9003 */
62
+ }
63
+ """
64
+ When I successfully run `adlint W9003.c` on noarch
65
+ Then the output should match with /7:.*:W9003/
66
+ And the output should exactly match with:
67
+ | mesg | line | column |
68
+ | W0118 | 3 | 13 |
69
+ | W9003 | 7 | 9 |
70
+ | W1053 | 7 | 9 |
71
+ | W0629 | 5 | 13 |
72
+ | W0628 | 5 | 13 |
73
+
74
+ Scenario: initializing an `int' variable with an enumerator
75
+ Given a target source named "W9003.c" with:
76
+ """
77
+ enum Color { RED, BLUE, GREEN };
78
+ int i = RED; /* W9003 */
79
+ """
80
+ When I successfully run `adlint W9003.c` on noarch
81
+ Then the output should match with /2:.*:W9003/
82
+ And the output should exactly match with:
83
+ | mesg | line | column |
84
+ | W9003 | 2 | 9 |
85
+ | W0117 | 2 | 5 |
86
+
87
+ Scenario: initializing an enum variable with an `int' value
88
+ Given a target source named "W9003.c" with:
89
+ """
90
+ enum Color { RED, BLUE, GREEN };
91
+ enum Color c = 1; /* W9003 */
92
+ """
93
+ When I successfully run `adlint W9003.c` on noarch
94
+ Then the output should match with /2:.*:W9003/
95
+ And the output should exactly match with:
96
+ | mesg | line | column |
97
+ | W9003 | 2 | 16 |
98
+ | W0117 | 2 | 12 |
99
+
100
+ Scenario: arithmetic expression with an `int' variable and an enum variable
101
+ Given a target source named "W9003.c" with:
102
+ """
103
+ enum Color { RED, BLUE, GREEN };
104
+
105
+ static int foo(enum Color c)
106
+ {
107
+ if (c == RED || c == BLUE || c == GREEN) {
108
+ return c + 10; /* W9003 */
109
+ }
110
+ else {
111
+ return 0;
112
+ }
113
+ }
114
+ """
115
+ When I successfully run `adlint W9003.c` on noarch
116
+ Then the output should match with /6:.*:W9003/
117
+ And the output should exactly match with:
118
+ | mesg | line | column |
119
+ | W0727 | 6 | 20 |
120
+ | W9003 | 6 | 20 |
121
+ | W9003 | 6 | 18 |
122
+ | W1060 | 6 | 18 |
123
+ | W0104 | 3 | 27 |
124
+ | W0629 | 3 | 12 |
125
+ | W0490 | 5 | 9 |
126
+ | W0497 | 5 | 9 |
127
+ | W0497 | 5 | 9 |
128
+ | W0502 | 5 | 9 |
129
+ | W0628 | 3 | 12 |
130
+
131
+ # vim:ts=2:sw=2:sts=2:et: