1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2015 - Scilab Enterprises - Calixte DENIZET
4 *
5 * This file must be used under the terms of the CeCILL.
6 * This source file is licensed as described in the file COPYING, which
7 * you should have received as part of this distribution. The terms
8 * are also available at
9 * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
10 *
11 */
12
13 #include <unordered_map>
14
15 #include "config/cnes/CNESConfig.hxx"
16 #include "SLintOptions.hxx"
17
18 #define SLINT_INSERT_IN_MAP(name) callbacks.emplace(#name, &create<name##Checker>)
19
20 namespace slint
21 {
22 namespace CNES
23 {
24
25 std::unordered_map<std::string, CNESConfig::CBType> CNESConfig::callbacks = initCallbacks();
26
getOptions(const ToolConfigurationType & tct,const AnalysisConfigurationType & act,SLintOptions & options)27 void CNESConfig::getOptions(const ToolConfigurationType & tct, const AnalysisConfigurationType & act, SLintOptions & options)
28 {
29 for (const auto & art : act.getAnalysisRuleType())
30 {
31 auto i = callbacks.find(art.getId());
32 if (i != callbacks.end())
33 {
34 if (SLintChecker * checker = i->second(tct, art))
35 {
36 options.addDefault(checker);
37 }
38 }
39 }
40 }
41
getWString(const AnalysisRuleType & art,const std::string & name,std::wstring & value)42 void CNESConfig::getWString(const AnalysisRuleType & art, const std::string & name, std::wstring & value)
43 {
44 auto i = art.getAnalysisRuleParameter().find(name);
45 if (i != art.getAnalysisRuleParameter().end())
46 {
47 value = scilab::UTF8::toWide(i->second.getTextValue());
48 }
49 }
50
getString(const AnalysisRuleType & art,const std::string & name,std::string & value)51 void CNESConfig::getString(const AnalysisRuleType & art, const std::string & name, std::string & value)
52 {
53 auto i = art.getAnalysisRuleParameter().find(name);
54 if (i != art.getAnalysisRuleParameter().end())
55 {
56 value = i->second.getTextValue();
57 }
58 }
59
getDouble(const AnalysisRuleType & art,const std::string & name,double & value)60 void CNESConfig::getDouble(const AnalysisRuleType & art, const std::string & name, double & value)
61 {
62 auto i = art.getAnalysisRuleParameter().find(name);
63 if (i != art.getAnalysisRuleParameter().end())
64 {
65 value = i->second.getNumericalValue();
66 }
67 }
68
getInt(const AnalysisRuleType & art,const std::string & name,int & value)69 void CNESConfig::getInt(const AnalysisRuleType & art, const std::string & name, int & value)
70 {
71 auto i = art.getAnalysisRuleParameter().find(name);
72 if (i != art.getAnalysisRuleParameter().end())
73 {
74 value = (int)i->second.getNumericalValue();
75 }
76 }
77
getInt(const AnalysisRuleType & art,const std::string & name,int & min,int & max)78 void CNESConfig::getInt(const AnalysisRuleType & art, const std::string & name, int & min, int & max)
79 {
80 auto i = art.getAnalysisRuleParameter().find(name);
81 if (i != art.getAnalysisRuleParameter().end())
82 {
83 min = (int)i->second.getValueMin();
84 max = (int)i->second.getValueMax();
85 }
86 }
87
getUInt(const AnalysisRuleType & art,const std::string & name,unsigned int & value)88 void CNESConfig::getUInt(const AnalysisRuleType & art, const std::string & name, unsigned int & value)
89 {
90 auto i = art.getAnalysisRuleParameter().find(name);
91 if (i != art.getAnalysisRuleParameter().end())
92 {
93 value = (unsigned int)i->second.getNumericalValue();
94 }
95 }
96
getBool(const AnalysisRuleType & art,const std::string & name,bool & value)97 void CNESConfig::getBool(const AnalysisRuleType & art, const std::string & name, bool & value)
98 {
99 auto i = art.getAnalysisRuleParameter().find(name);
100 if (i != art.getAnalysisRuleParameter().end())
101 {
102 value = i->second.getNumericalValue() != 0.;
103 }
104 }
105
getId(const ToolConfigurationType & tct,const AnalysisRuleType & art)106 const std::wstring CNESConfig::getId(const ToolConfigurationType & tct, const AnalysisRuleType & art)
107 {
108 /*auto i = tct.getRuleLink().find(art.getId());
109 if (i == tct.getRuleLink().end())
110 {
111 return scilab::UTF8::toWide(art.getId());
112 }
113 else
114 {
115 return scilab::UTF8::toWide(i->second.getStandardRuleId());
116 }*/
117 return scilab::UTF8::toWide(art.getId());
118 }
119
120 template<>
create(const ToolConfigurationType & tct,const AnalysisRuleType & art)121 SLintChecker * CNESConfig::create<FunctionNameChecker>(const ToolConfigurationType & tct, const AnalysisRuleType & art)
122 {
123 if (art.getActivation())
124 {
125 std::wstring pattern;
126 int min = -1;
127 int max = -1;
128
129 CNESConfig::getWString(art, "namePattern", pattern);
130 CNESConfig::getInt(art, "length", min, max);
131
132 return new FunctionNameChecker(CNESConfig::getId(tct, art), pattern, min, max);
133 }
134
135 return nullptr;
136 }
137
138 template<>
create(const ToolConfigurationType & tct,const AnalysisRuleType & art)139 SLintChecker * CNESConfig::create<VariableNameChecker>(const ToolConfigurationType & tct, const AnalysisRuleType & art)
140 {
141 if (art.getActivation())
142 {
143 std::wstring pattern;
144 int min = -1;
145 int max = -1;
146
147 CNESConfig::getWString(art, "namePattern", pattern);
148 CNESConfig::getInt(art, "length", min, max);
149
150 return new VariableNameChecker(CNESConfig::getId(tct, art), pattern, min, max);
151 }
152
153 return nullptr;
154 }
155
156 template<>
create(const ToolConfigurationType & tct,const AnalysisRuleType & art)157 SLintChecker * CNESConfig::create<McCabeChecker>(const ToolConfigurationType & tct, const AnalysisRuleType & art)
158 {
159 if (art.getActivation())
160 {
161 int max = -1;
162 CNESConfig::getInt(art, "max", max);
163
164 return new McCabeChecker(CNESConfig::getId(tct, art), max);
165 }
166
167 return nullptr;
168 }
169
170 template<>
create(const ToolConfigurationType & tct,const AnalysisRuleType & art)171 SLintChecker * CNESConfig::create<DecimalChecker>(const ToolConfigurationType & tct, const AnalysisRuleType & art)
172 {
173 if (art.getActivation())
174 {
175 std::wstring character;
176 bool checkDot = false;
177
178 CNESConfig::getWString(art, "character", character);
179 CNESConfig::getBool(art, "checkDot", checkDot);
180
181 return new DecimalChecker(CNESConfig::getId(tct, art), character, checkDot);
182 }
183
184 return nullptr;
185 }
186
187 template<>
create(const ToolConfigurationType & tct,const AnalysisRuleType & art)188 SLintChecker * CNESConfig::create<LineLengthChecker>(const ToolConfigurationType & tct, const AnalysisRuleType & art)
189 {
190 if (art.getActivation())
191 {
192 int max = -1;
193 CNESConfig::getInt(art, "max", max);
194
195 return new LineLengthChecker(CNESConfig::getId(tct, art), max);
196 }
197
198 return nullptr;
199 }
200
201 template<>
create(const ToolConfigurationType & tct,const AnalysisRuleType & art)202 SLintChecker * CNESConfig::create<LinesCountChecker>(const ToolConfigurationType & tct, const AnalysisRuleType & art)
203 {
204 if (art.getActivation())
205 {
206 int max = -1;
207 CNESConfig::getInt(art, "max", max);
208
209 return new LinesCountChecker(CNESConfig::getId(tct, art), max);
210 }
211
212 return nullptr;
213 }
214
215 template<>
create(const ToolConfigurationType & tct,const AnalysisRuleType & art)216 SLintChecker * CNESConfig::create<StructChecker>(const ToolConfigurationType & tct, const AnalysisRuleType & art)
217 {
218 if (art.getActivation())
219 {
220 std::wstring pattern;
221 int min = -1;
222 int max = -1;
223
224 CNESConfig::getWString(art, "fieldPattern", pattern);
225 CNESConfig::getInt(art, "length", min, max);
226
227 return new StructChecker(CNESConfig::getId(tct, art), pattern, min, max);
228 }
229
230 return nullptr;
231 }
232
233 template<>
create(const ToolConfigurationType & tct,const AnalysisRuleType & art)234 SLintChecker * CNESConfig::create<BreaksInLoopChecker>(const ToolConfigurationType & tct, const AnalysisRuleType & art)
235 {
236 if (art.getActivation())
237 {
238 int maxBreaks = -1;
239 int maxContinues = -1;
240
241 CNESConfig::getInt(art, "maxBreaks", maxBreaks);
242 CNESConfig::getInt(art, "maxContinues", maxContinues);
243
244 return new BreaksInLoopChecker(CNESConfig::getId(tct, art), maxBreaks, maxContinues);
245 }
246
247 return nullptr;
248 }
249
250 template<>
create(const ToolConfigurationType & tct,const AnalysisRuleType & art)251 SLintChecker * CNESConfig::create<NestedBlocksChecker>(const ToolConfigurationType & tct, const AnalysisRuleType & art)
252 {
253 if (art.getActivation())
254 {
255 int max = -1;
256 CNESConfig::getInt(art, "max", max);
257
258 return new NestedBlocksChecker(CNESConfig::getId(tct, art), max);
259 }
260
261 return nullptr;
262 }
263
264 template<>
create(const ToolConfigurationType & tct,const AnalysisRuleType & art)265 SLintChecker * CNESConfig::create<ReturnsCountChecker>(const ToolConfigurationType & tct, const AnalysisRuleType & art)
266 {
267 if (art.getActivation())
268 {
269 int max = -1;
270 CNESConfig::getInt(art, "max", max);
271
272 return new ReturnsCountChecker(CNESConfig::getId(tct, art), max);
273 }
274
275 return nullptr;
276 }
277
278 template<>
create(const ToolConfigurationType & tct,const AnalysisRuleType & art)279 SLintChecker * CNESConfig::create<ExpInCondChecker>(const ToolConfigurationType & tct, const AnalysisRuleType & art)
280 {
281 if (art.getActivation())
282 {
283 int max = -1;
284 CNESConfig::getInt(art, "max", max);
285
286 return new ExpInCondChecker(CNESConfig::getId(tct, art), max);
287 }
288
289 return nullptr;
290 }
291
292 template<>
create(const ToolConfigurationType & tct,const AnalysisRuleType & art)293 SLintChecker * CNESConfig::create<IllegalCallsChecker>(const ToolConfigurationType & tct, const AnalysisRuleType & art)
294 {
295 if (art.getActivation())
296 {
297 std::vector<std::wstring> names;
298 const auto & p = art.getAnalysisRuleParameter().equal_range("keyword");
299 for (auto i = p.first; i != p.second; ++i)
300 {
301 const AnalysisRuleParameterType & arpt = i->second;
302 names.emplace_back(scilab::UTF8::toWide(arpt.getTextValue()));
303 }
304
305 return new IllegalCallsChecker(CNESConfig::getId(tct, art), names);
306 }
307
308 return nullptr;
309 }
310
311 template<>
create(const ToolConfigurationType & tct,const AnalysisRuleType & art)312 SLintChecker * CNESConfig::create<FunctionTestReturnChecker>(const ToolConfigurationType & tct, const AnalysisRuleType & art)
313 {
314 if (art.getActivation())
315 {
316 std::unordered_map<std::wstring, std::vector<unsigned int>> namesArgs;
317 const auto & p = art.getAnalysisRuleParameter().equal_range("keyword");
318 for (auto i = p.first; i != p.second; ++i)
319 {
320 const AnalysisRuleParameterType & arpt = i->second;
321 const std::wstring name = scilab::UTF8::toWide(arpt.getTextValue());
322 const double x = arpt.getNumericalValue();
323 if (x > 0 && !name.empty())
324 {
325 const std::vector<unsigned int> arg = { (unsigned int)x };
326 namesArgs.emplace(name, arg);
327 }
328 }
329
330 return new FunctionTestReturnChecker(CNESConfig::getId(tct, art), namesArgs);
331 }
332
333 return nullptr;
334 }
335
336 template<>
create(const ToolConfigurationType & tct,const AnalysisRuleType & art)337 SLintChecker * CNESConfig::create<SelectChecker>(const ToolConfigurationType & tct, const AnalysisRuleType & art)
338 {
339 if (art.getActivation())
340 {
341 bool checkDefault = false;
342 bool checkHomogeneity = false;
343 bool checkEmpty = false;
344 bool checkOneCase = false;
345
346 CNESConfig::getBool(art, "default", checkDefault);
347 CNESConfig::getBool(art, "homogeneity", checkHomogeneity);
348 CNESConfig::getBool(art, "empty", checkEmpty);
349 CNESConfig::getBool(art, "oneCase", checkOneCase);
350
351 return new SelectChecker(CNESConfig::getId(tct, art), checkDefault, checkHomogeneity, checkEmpty, checkOneCase);
352 }
353
354 return nullptr;
355 }
356
357 template<>
create(const ToolConfigurationType & tct,const AnalysisRuleType & art)358 SLintChecker * CNESConfig::create<CommentRatioChecker>(const ToolConfigurationType & tct, const AnalysisRuleType & art)
359 {
360 if (art.getActivation())
361 {
362 double ratio = 0;
363
364 CNESConfig::getDouble(art, "ratioMin", ratio);
365 if (ratio < 0)
366 {
367 ratio = 0;
368 }
369 else if (ratio > 1)
370 {
371 ratio = 1;
372 }
373
374 return new CommentRatioChecker(CNESConfig::getId(tct, art), ratio);
375 }
376
377 return nullptr;
378 }
379
initCallbacks()380 std::unordered_map<std::string, CNESConfig::CBType> CNESConfig::initCallbacks()
381 {
382 std::unordered_map<std::string, CBType> callbacks;
383
384 SLINT_INSERT_IN_MAP(GlobalKeyword);
385 SLINT_INSERT_IN_MAP(Redefinition);
386 SLINT_INSERT_IN_MAP(Variables);
387 SLINT_INSERT_IN_MAP(FunctionName);
388 SLINT_INSERT_IN_MAP(FunctionArgs);
389 SLINT_INSERT_IN_MAP(UselessArg);
390 SLINT_INSERT_IN_MAP(UselessRet);
391 SLINT_INSERT_IN_MAP(VariableName);
392 SLINT_INSERT_IN_MAP(SingleInstr);
393 SLINT_INSERT_IN_MAP(EmptyBlock);
394 SLINT_INSERT_IN_MAP(SemicolonAtEOL);
395 SLINT_INSERT_IN_MAP(MopenMclose);
396 SLINT_INSERT_IN_MAP(McCabe);
397 SLINT_INSERT_IN_MAP(Decimal);
398 SLINT_INSERT_IN_MAP(Printf);
399 SLINT_INSERT_IN_MAP(LineLength);
400 SLINT_INSERT_IN_MAP(LinesCount);
401 SLINT_INSERT_IN_MAP(Todo);
402 SLINT_INSERT_IN_MAP(NaN);
403 SLINT_INSERT_IN_MAP(EqEq);
404 SLINT_INSERT_IN_MAP(UselessOp);
405 SLINT_INSERT_IN_MAP(UnreachableCode);
406 SLINT_INSERT_IN_MAP(Deprecated);
407 SLINT_INSERT_IN_MAP(Select);
408 SLINT_INSERT_IN_MAP(ImplicitList);
409 SLINT_INSERT_IN_MAP(Struct);
410 SLINT_INSERT_IN_MAP(LoadSave);
411 SLINT_INSERT_IN_MAP(OldNot);
412 SLINT_INSERT_IN_MAP(SpacesAroundOp);
413 SLINT_INSERT_IN_MAP(SpacesInArgs);
414 SLINT_INSERT_IN_MAP(BreaksInLoop);
415 SLINT_INSERT_IN_MAP(NestedBlocks);
416 SLINT_INSERT_IN_MAP(BracketedExp);
417 SLINT_INSERT_IN_MAP(NotNot);
418 SLINT_INSERT_IN_MAP(IllegalCalls);
419 SLINT_INSERT_IN_MAP(ExpInCond);
420 SLINT_INSERT_IN_MAP(CommentRatio);
421 SLINT_INSERT_IN_MAP(FunctionArgsOrder);
422 SLINT_INSERT_IN_MAP(FunctionTestReturn);
423 SLINT_INSERT_IN_MAP(ReturnsCount);
424
425 return callbacks;
426 }
427
428 } // namspace CNES
429 } // namespace slint
430
431 #undef SLINT_INSERT_IN_MAP
432