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