| 157 | } |
| 158 | |
| 159 | std::string CheckersReport::getReport(const std::string& criticalErrors) const |
| 160 | { |
| 161 | std::ostringstream fout; |
| 162 | |
| 163 | fout << "Critical errors" << std::endl; |
| 164 | fout << "---------------" << std::endl; |
| 165 | if (!criticalErrors.empty()) { |
| 166 | fout << "There were critical errors (" << criticalErrors << ")." << std::endl; |
| 167 | fout << "These cause the analysis of the file to end prematurely." << std::endl; |
| 168 | } else { |
| 169 | fout << "No critical errors encountered." << std::endl; |
| 170 | // TODO: mention "information" and "debug" as source for indications of bailouts |
| 171 | // TODO: still rephrase this - this message does not provides confidence in the results |
| 172 | // TODO: document what a bailout is and why it is done - mention it in the upcoming security/tuning guide |
| 173 | // TODO: make bailouts a separate group - need to differentiate between user bailouts (missing data like configuration/includes) and internal bailouts (e.g. limitations of ValueFlow) |
| 174 | fout << "Note: There might still have been non-critical bailouts which might lead to false negatives." << std::endl; |
| 175 | } |
| 176 | |
| 177 | fout << std::endl << std::endl; |
| 178 | fout << "Open source checkers" << std::endl; |
| 179 | fout << "--------------------" << std::endl; |
| 180 | |
| 181 | std::size_t maxCheckerSize = 0; |
| 182 | for (const auto& checkReq: checkers::allCheckers) { |
| 183 | const std::string& checker = checkReq.first; |
| 184 | maxCheckerSize = std::max(checker.size(), maxCheckerSize); |
| 185 | } |
| 186 | for (const auto& checkReq: checkers::allCheckers) { |
| 187 | const std::string& checker = checkReq.first; |
| 188 | const bool active = mActiveCheckers.count(checkReq.first) > 0; |
| 189 | const std::string& req = checkReq.second; |
| 190 | fout << (active ? "Yes " : "No ") << checker; |
| 191 | if (!active && !req.empty()) |
| 192 | fout << std::string(maxCheckerSize + 4 - checker.size(), ' ') << "require:" + req; |
| 193 | fout << std::endl; |
| 194 | } |
| 195 | |
| 196 | for (const auto& addonInfo: mSettings.addonInfos) { |
| 197 | if (addonInfo.checkers.empty()) |
| 198 | continue; |
| 199 | fout << std::endl << std::endl; |
| 200 | std::string title; |
| 201 | if (mSettings.premium && addonInfo.name == "premiumaddon.json") |
| 202 | title = "Cppcheck Premium"; |
| 203 | else { |
| 204 | title = addonInfo.name; |
| 205 | if (endsWith(title, ".json")) |
| 206 | title.erase(title.rfind('.')); |
| 207 | } |
| 208 | title += " checkers"; |
| 209 | fout << title << std::endl; |
| 210 | fout << std::string(title.size(), '-') << std::endl; |
| 211 | |
| 212 | maxCheckerSize = 0; |
| 213 | for (const auto& checkReq: addonInfo.checkers) { |
| 214 | const std::string& checker = checkReq.first; |
| 215 | maxCheckerSize = std::max(checker.size(), maxCheckerSize); |
| 216 | } |