Skip to content

Commit 423cb76

Browse files
committed
14113
1 parent 92fffee commit 423cb76

12 files changed

Lines changed: 189 additions & 143 deletions

externals/simplecpp/simplecpp.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3072,6 +3072,9 @@ std::pair<simplecpp::FileData *, bool> simplecpp::FileDataCache::tryload(FileDat
30723072
mIdMap.emplace(fileId, data);
30733073
mData.emplace_back(data);
30743074

3075+
if (mCallback)
3076+
mCallback(*data);
3077+
30753078
return {data, true};
30763079
}
30773080

externals/simplecpp/simplecpp.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <cctype>
1010
#include <cstdint>
1111
#include <cstring>
12+
#include <functional>
1213
#include <iosfwd>
1314
#include <list>
1415
#include <map>
@@ -465,6 +466,12 @@ namespace simplecpp {
465466
return mData.cend();
466467
}
467468

469+
using callback_type = std::function<void (FileData &)>;
470+
471+
void set_callback(callback_type cb) {
472+
mCallback = cb;
473+
}
474+
468475
private:
469476
struct FileID {
470477
#ifdef _WIN32
@@ -511,6 +518,7 @@ namespace simplecpp {
511518
container_type mData;
512519
name_map_type mNameMap;
513520
id_map_type mIdMap;
521+
callback_type mCallback;
514522
};
515523

516524
SIMPLECPP_LIB long long characterLiteralToLL(const std::string& str);

lib/cppcheck.cpp

Lines changed: 79 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,9 @@ class CppCheck::CppCheckLogger : public ErrorLogger
9999
closePlist();
100100
}
101101

102-
void setRemarkComments(std::vector<RemarkComment> remarkComments)
102+
std::vector<RemarkComment>& remarkComments()
103103
{
104-
mRemarkComments = std::move(remarkComments);
104+
return mRemarkComments;
105105
}
106106

107107
void setLocationMacros(const Token* startTok, const std::vector<std::string>& files)
@@ -123,17 +123,25 @@ class CppCheck::CppCheckLogger : public ErrorLogger
123123
mErrorList.clear();
124124
}
125125

126-
void openPlist(const std::string& filename, const std::vector<std::string>& files)
126+
void openPlist(const std::string& filename)
127127
{
128128
mPlistFile.open(filename);
129-
mPlistFile << ErrorLogger::plistHeader(version(), files);
129+
mPlistFile << ErrorLogger::plistHeader(version());
130+
}
131+
132+
void setPlistFilenames(std::vector<std::string> files)
133+
{
134+
if (mPlistFile.is_open()) {
135+
mPlistFilenames = std::move(files);
136+
}
130137
}
131138

132139
void closePlist()
133140
{
134141
if (mPlistFile.is_open()) {
135-
mPlistFile << ErrorLogger::plistFooter();
142+
mPlistFile << ErrorLogger::plistFooter(mPlistFilenames);
136143
mPlistFile.close();
144+
mPlistFilenames.clear();
137145
}
138146
}
139147

@@ -276,6 +284,7 @@ class CppCheck::CppCheckLogger : public ErrorLogger
276284
std::map<Location, std::set<std::string>> mLocationMacros; // What macros are used on a location?
277285

278286
std::ofstream mPlistFile;
287+
std::vector<std::string> mPlistFilenames;
279288

280289
unsigned int mExitCode{};
281290

@@ -986,9 +995,6 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str
986995

987996
Preprocessor preprocessor(mSettings, mErrorLogger, file.lang());
988997

989-
if (!preprocessor.loadFiles(tokens1, files))
990-
return mLogger->exitcode();
991-
992998
if (!mSettings.plistOutput.empty()) {
993999
std::string filename2;
9941000
if (file.spath().find('/') != std::string::npos)
@@ -997,23 +1003,18 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str
9971003
filename2 = file.spath();
9981004
const std::size_t fileNameHash = std::hash<std::string> {}(file.spath());
9991005
filename2 = mSettings.plistOutput + filename2.substr(0, filename2.find('.')) + "_" + std::to_string(fileNameHash) + ".plist";
1000-
mLogger->openPlist(filename2, files);
1006+
mLogger->openPlist(filename2);
10011007
}
10021008

1003-
std::string dumpProlog;
1009+
std::string dumpFooter;
10041010
if (mSettings.dump || !mSettings.addons.empty()) {
1005-
dumpProlog += getDumpFileContentsRawTokens(files, tokens1);
1011+
dumpFooter += getDumpFileContentsRawTokensFooter(tokens1);
10061012
}
10071013

10081014
// Parse comments and then remove them
1009-
mLogger->setRemarkComments(preprocessor.getRemarkComments(tokens1));
1015+
preprocessor.addRemarkComments(tokens1, mLogger->remarkComments());
10101016
preprocessor.inlineSuppressions(tokens1, mSuppressions.nomsg);
1011-
if (mSettings.dump || !mSettings.addons.empty()) {
1012-
std::ostringstream oss;
1013-
mSuppressions.nomsg.dump(oss);
1014-
dumpProlog += oss.str();
1015-
}
1016-
preprocessor.removeComments(tokens1);
1017+
Preprocessor::removeComments(tokens1);
10171018

10181019
if (!mSettings.buildDir.empty()) {
10191020
analyzerInformation.reset(new AnalyzerInformation);
@@ -1035,19 +1036,39 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str
10351036
}
10361037

10371038
// Get directives
1038-
std::list<Directive> directives = preprocessor.createDirectives(tokens1);
1039-
preprocessor.simplifyPragmaAsm(tokens1);
1039+
std::list<Directive> directives;
1040+
Preprocessor::createDirectives(tokens1, directives);
1041+
Preprocessor::simplifyPragmaAsm(tokens1);
1042+
1043+
// This needs to be a linked list to allow new configurations to be discovered
1044+
// and added while iterating and checking existing configurations
1045+
std::list<std::string> configurations;
1046+
std::set<std::string> configDefines = { "__cplusplus" };
1047+
1048+
preprocessor.setLoadCallback([&](simplecpp::FileData& data) {
1049+
// Do preprocessing on included file
1050+
preprocessor.addRemarkComments(data.tokens, mLogger->remarkComments());
1051+
preprocessor.inlineSuppressions(data.tokens, mSuppressions.nomsg);
1052+
Preprocessor::removeComments(data.tokens);
1053+
Preprocessor::createDirectives(data.tokens, directives);
1054+
Preprocessor::simplifyPragmaAsm(data.tokens);
1055+
// Discover new configurations from included file
1056+
if ((mSettings.checkAllConfigurations && mSettings.userDefines.empty()) || mSettings.force)
1057+
preprocessor.getConfigs(data.filename, data.tokens, configDefines, configurations);
1058+
});
10401059

10411060
Preprocessor::setPlatformInfo(tokens1, mSettings);
10421061

10431062
// Get configurations..
1044-
std::set<std::string> configurations;
10451063
if ((mSettings.checkAllConfigurations && mSettings.userDefines.empty()) || mSettings.force) {
10461064
Timer::run("Preprocessor::getConfigs", mSettings.showtime, &s_timerResults, [&]() {
1047-
configurations = preprocessor.getConfigs(tokens1);
1065+
configurations = { "" };
1066+
preprocessor.getConfigs(file.spath(), tokens1, configDefines, configurations);
1067+
preprocessor.loadFiles(tokens1, files);
1068+
configurations.sort();
10481069
});
10491070
} else {
1050-
configurations.insert(mSettings.userDefines);
1071+
configurations = { mSettings.userDefines };
10511072
}
10521073

10531074
if (mSettings.checkConfiguration) {
@@ -1089,7 +1110,6 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str
10891110
createDumpFile(mSettings, file, fileIndex, fdump, dumpFile);
10901111
if (fdump.is_open()) {
10911112
fdump << getLibraryDumpData();
1092-
fdump << dumpProlog;
10931113
if (!mSettings.dump)
10941114
filesDeleter.addFile(dumpFile);
10951115
}
@@ -1272,12 +1292,20 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str
12721292
}
12731293

12741294
// TODO: will not be closed if we encountered an exception
1275-
// dumped all configs, close root </dumps> element now
12761295
if (fdump.is_open()) {
1296+
// dump all filenames, raw tokens, suppressions
1297+
std::string dumpHeader = getDumpFileContentsRawTokensHeader(files);
1298+
fdump << getDumpFileContentsRawTokens(dumpHeader, dumpFooter);
1299+
mSuppressions.nomsg.dump(fdump);
1300+
// dumped all configs, close root </dumps> element now
12771301
fdump << "</dumps>" << std::endl;
12781302
fdump.close();
12791303
}
12801304

1305+
if (!mSettings.plistOutput.empty()) {
1306+
mLogger->setPlistFilenames(std::move(files));
1307+
}
1308+
12811309
executeAddons(dumpFile, file);
12821310
} catch (const TerminateException &) {
12831311
// Analysis is terminated
@@ -1949,17 +1977,40 @@ bool CppCheck::isPremiumCodingStandardId(const std::string& id) const {
19491977
return false;
19501978
}
19511979

1952-
std::string CppCheck::getDumpFileContentsRawTokens(const std::vector<std::string>& files, const simplecpp::TokenList& tokens1) const {
1980+
std::string CppCheck::getDumpFileContentsRawTokens(const std::vector<std::string>& files, const simplecpp::TokenList& tokens1) const
1981+
{
1982+
std::string header = getDumpFileContentsRawTokensHeader(files);
1983+
std::string footer = getDumpFileContentsRawTokensFooter(tokens1);
1984+
return getDumpFileContentsRawTokens(header, footer);
1985+
}
1986+
1987+
std::string CppCheck::getDumpFileContentsRawTokens(const std::string& header, const std::string& footer)
1988+
{
19531989
std::string dumpProlog;
19541990
dumpProlog += " <rawtokens>\n";
1991+
dumpProlog += header;
1992+
dumpProlog += footer;
1993+
dumpProlog += " </rawtokens>\n";
1994+
return dumpProlog;
1995+
}
1996+
1997+
std::string CppCheck::getDumpFileContentsRawTokensHeader(const std::vector<std::string>& files) const
1998+
{
1999+
std::string dumpProlog;
19552000
for (unsigned int i = 0; i < files.size(); ++i) {
19562001
dumpProlog += " <file index=\"";
19572002
dumpProlog += std::to_string(i);
19582003
dumpProlog += "\" name=\"";
19592004
dumpProlog += ErrorLogger::toxml(Path::getRelativePath(files[i], mSettings.basePaths));
19602005
dumpProlog += "\"/>\n";
19612006
}
1962-
for (const simplecpp::Token *tok = tokens1.cfront(); tok; tok = tok->next) {
2007+
return dumpProlog;
2008+
}
2009+
2010+
std::string CppCheck::getDumpFileContentsRawTokensFooter(const simplecpp::TokenList& tokens1)
2011+
{
2012+
std::string dumpProlog;
2013+
for (const simplecpp::Token* tok = tokens1.cfront(); tok; tok = tok->next) {
19632014
dumpProlog += " <tok ";
19642015

19652016
dumpProlog += "fileIndex=\"";
@@ -1970,7 +2021,7 @@ std::string CppCheck::getDumpFileContentsRawTokens(const std::vector<std::string
19702021
dumpProlog += std::to_string(tok->location.line);
19712022
dumpProlog += "\" ";
19722023

1973-
dumpProlog +="column=\"";
2024+
dumpProlog += "column=\"";
19742025
dumpProlog += std::to_string(tok->location.col);
19752026
dumpProlog += "\" ";
19762027

@@ -1980,6 +2031,5 @@ std::string CppCheck::getDumpFileContentsRawTokens(const std::vector<std::string
19802031

19812032
dumpProlog += "/>\n";
19822033
}
1983-
dumpProlog += " </rawtokens>\n";
19842034
return dumpProlog;
19852035
}

lib/cppcheck.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,9 @@ class CPPCHECKLIB CppCheck {
154154
* @brief Get dumpfile <rawtokens> contents, this is only public for testing purposes
155155
*/
156156
std::string getDumpFileContentsRawTokens(const std::vector<std::string>& files, const simplecpp::TokenList& tokens1) const;
157+
static std::string getDumpFileContentsRawTokens(const std::string& header, const std::string& footer);
158+
std::string getDumpFileContentsRawTokensHeader(const std::vector<std::string>& files) const;
159+
static std::string getDumpFileContentsRawTokensFooter(const simplecpp::TokenList& tokens1);
157160

158161
std::string getLibraryDumpData() const;
159162

lib/cppcheck.vcxproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -200,25 +200,25 @@
200200
<ConfigurationType>DynamicLibrary</ConfigurationType>
201201
<CharacterSet>Unicode</CharacterSet>
202202
<WholeProgramOptimization>false</WholeProgramOptimization>
203-
<PlatformToolset>v142</PlatformToolset>
203+
<PlatformToolset>v143</PlatformToolset>
204204
</PropertyGroup>
205205
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-PCRE|x64'" Label="Configuration">
206206
<ConfigurationType>DynamicLibrary</ConfigurationType>
207207
<CharacterSet>Unicode</CharacterSet>
208208
<WholeProgramOptimization>false</WholeProgramOptimization>
209-
<PlatformToolset>v142</PlatformToolset>
209+
<PlatformToolset>v143</PlatformToolset>
210210
</PropertyGroup>
211211
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
212212
<ConfigurationType>DynamicLibrary</ConfigurationType>
213213
<CharacterSet>Unicode</CharacterSet>
214214
<WholeProgramOptimization>false</WholeProgramOptimization>
215-
<PlatformToolset>v142</PlatformToolset>
215+
<PlatformToolset>v143</PlatformToolset>
216216
</PropertyGroup>
217217
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-PCRE|x64'" Label="Configuration">
218218
<ConfigurationType>DynamicLibrary</ConfigurationType>
219219
<CharacterSet>Unicode</CharacterSet>
220220
<WholeProgramOptimization>false</WholeProgramOptimization>
221-
<PlatformToolset>v142</PlatformToolset>
221+
<PlatformToolset>v143</PlatformToolset>
222222
</PropertyGroup>
223223
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
224224
<ImportGroup Label="ExtensionSettings" />

lib/errorlogger.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -818,20 +818,15 @@ std::string ErrorLogger::toxml(const std::string &str)
818818
return xml;
819819
}
820820

821-
std::string ErrorLogger::plistHeader(const std::string &version, const std::vector<std::string> &files)
821+
std::string ErrorLogger::plistHeader(const std::string &version)
822822
{
823823
std::ostringstream ostr;
824824
ostr << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
825825
<< "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\r\n"
826826
<< "<plist version=\"1.0\">\r\n"
827827
<< "<dict>\r\n"
828828
<< " <key>clang_version</key>\r\n"
829-
<< "<string>cppcheck version " << version << "</string>\r\n"
830-
<< " <key>files</key>\r\n"
831-
<< " <array>\r\n";
832-
for (const std::string & file : files)
833-
ostr << " <string>" << ErrorLogger::toxml(file) << "</string>\r\n";
834-
ostr << " </array>\r\n"
829+
<< " <string>cppcheck version " << version << "</string>\r\n"
835830
<< " <key>diagnostics</key>\r\n"
836831
<< " <array>\r\n";
837832
return ostr.str();

lib/errorlogger.h

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <cstdint>
2929
#include <list>
3030
#include <set>
31+
#include <sstream>
3132
#include <string>
3233
#include <vector>
3334
#include <map>
@@ -268,12 +269,19 @@ class CPPCHECKLIB ErrorLogger {
268269
*/
269270
static std::string toxml(const std::string &str);
270271

271-
static std::string plistHeader(const std::string &version, const std::vector<std::string> &files);
272+
static std::string plistHeader(const std::string &version);
272273
static std::string plistData(const ErrorMessage &msg);
273-
static const char *plistFooter() {
274-
return " </array>\r\n"
275-
"</dict>\r\n"
276-
"</plist>";
274+
static std::string plistFooter(const std::vector<std::string>& files) {
275+
std::ostringstream ostr;
276+
ostr << " </array>\r\n"
277+
<< " <key>files</key>\r\n"
278+
<< " <array>\r\n";
279+
for (const std::string& file : files)
280+
ostr << " <string>" << ErrorLogger::toxml(file) << "</string>\r\n";
281+
ostr << " </array>\r\n"
282+
<< "</dict>\r\n"
283+
<< "</plist>";
284+
return ostr.str();
277285
}
278286

279287
static bool isCriticalErrorId(const std::string& id) {

0 commit comments

Comments
 (0)