@@ -280,3 +280,88 @@ std::string CheckersReport::getReport(const std::string& criticalErrors) const
280
280
281
281
return fout.str ();
282
282
}
283
+
284
+ std::string CheckersReport::getXmlReport (const std::string& criticalErrors) const
285
+ {
286
+ std::string ret;
287
+
288
+ if (!criticalErrors.empty ()) {
289
+ ret += " <critical-errors>" + criticalErrors + " \n </critical-errors>\n " ;
290
+ } else
291
+ ret += " <critical-errors/>\n " ;
292
+ ret += " <checkers-report>\n " ;
293
+
294
+ const bool cppcheckPremium = isCppcheckPremium (mSettings );
295
+
296
+ auto reportSection = [&ret, cppcheckPremium]
297
+ (const std::string& title,
298
+ const Settings& settings,
299
+ const std::set<std::string>& activeCheckers,
300
+ const std::map<std::string, std::string>& premiumCheckers,
301
+ const std::string& substring) {
302
+ if (!cppcheckPremium) {
303
+ ret += " <" + title + " />\n " ;
304
+ return ;
305
+ }
306
+ ret += " <" + title + " >\n " ;
307
+ for (const auto & checkReq: premiumCheckers) {
308
+ const std::string& checker = checkReq.first ;
309
+ if (checker.find (substring) == std::string::npos)
310
+ continue ;
311
+ bool active = cppcheckPremium && activeCheckers.count (checker) > 0 ;
312
+ if (substring == " ::" ) {
313
+ if (checkReq.second == " warning" )
314
+ active &= settings.severity .isEnabled (Severity::warning);
315
+ else if (checkReq.second == " style" )
316
+ active &= settings.severity .isEnabled (Severity::style);
317
+ else if (checkReq.second == " portability" )
318
+ active &= settings.severity .isEnabled (Severity::portability);
319
+ else if (!checkReq.second .empty ())
320
+ active = false ; // FIXME: handle req
321
+ }
322
+ ret += " <checker active=\" " + std::string (active ? " Yes" : " No" ) + " \" id=\" " + checker + " \" " ;
323
+ ret += " />\n " ;
324
+ }
325
+ ret += " </" + title + " >\n " ;
326
+ };
327
+
328
+ reportSection (" premium-checkers" , mSettings , mActiveCheckers , checkers::premiumCheckers, " ::" );
329
+ reportSection (" autosar" , mSettings , mActiveCheckers , checkers::premiumCheckers, " Autosar: " );
330
+ reportSection (" cert-c" , mSettings , mActiveCheckers , checkers::premiumCheckers, " Cert C: " );
331
+ reportSection (" cert-cpp" , mSettings , mActiveCheckers , checkers::premiumCheckers, " Cert C++: " );
332
+
333
+ int misra = 0 ;
334
+ if (mSettings .premiumArgs .find (" misra-c-2012" ) != std::string::npos)
335
+ misra = 2012 ;
336
+ else if (mSettings .premiumArgs .find (" misra-c-2023" ) != std::string::npos)
337
+ misra = 2023 ;
338
+ else if (mSettings .addons .count (" misra" ))
339
+ misra = 2012 ;
340
+
341
+ if (misra == 0 ) {
342
+ ret += " <misra-c/>\n " ;
343
+ } else {
344
+ ret += " <misra-c-" + std::to_string (misra) + " >\n " ;
345
+ for (const checkers::MisraInfo& info: checkers::misraC2012Directives) {
346
+ const std::string directive = " Dir " + std::to_string (info.a ) + " ." + std::to_string (info.b );
347
+ const bool active = isMisraRuleActive (mActiveCheckers , directive);
348
+ ret += " <checker active=\" " ;
349
+ ret += std::string (active ? " Yes" : " No" ) + " \" id=\" Misra C " + std::to_string (misra) + " : " + directive + " \" " ;
350
+ ret += " />\n " ;
351
+ }
352
+ for (const checkers::MisraInfo& info: checkers::misraC2012Rules) {
353
+ const std::string rule = std::to_string (info.a ) + " ." + std::to_string (info.b );
354
+ const bool active = isMisraRuleActive (mActiveCheckers , rule);
355
+ ret += " <checker active=\" " ;
356
+ ret += std::string (active ? " Yes" : " No" ) + " \" id=\" Misra C " + std::to_string (misra) + " : " + rule + " \" " ;
357
+ ret += " />\n " ;
358
+ }
359
+ ret += " </misra-c-" + std::to_string (misra) + " >\n " ;
360
+ }
361
+
362
+ reportSection (" misra-cpp-2008" , mSettings , mActiveCheckers , checkers::premiumCheckers, " Misra C++ 2008: " );
363
+ reportSection (" misra-cpp-2023" , mSettings , mActiveCheckers , checkers::premiumCheckers, " Misra C++ 2023: " );
364
+
365
+ ret += " </checkers-report>" ;
366
+ return ret;
367
+ }
0 commit comments