Skip to content

Commit

Permalink
Fixed #12504 (dumpfile: usage of relative paths is inconsistent)
Browse files Browse the repository at this point in the history
  • Loading branch information
danmar committed Apr 11, 2024
1 parent d0de1fe commit 33fa1bd
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 37 deletions.
66 changes: 36 additions & 30 deletions lib/cppcheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -716,36 +716,7 @@ unsigned int CppCheck::checkFile(const std::string& filename, const std::string

std::string dumpProlog;
if (mSettings.dump || !mSettings.addons.empty()) {
dumpProlog += " <rawtokens>\n";
for (unsigned int i = 0; i < files.size(); ++i) {
dumpProlog += " <file index=\"";
dumpProlog += std::to_string(i);
dumpProlog += "\" name=\"";
dumpProlog += ErrorLogger::toxml(files[i]);
dumpProlog += "\"/>\n";
}
for (const simplecpp::Token *tok = tokens1.cfront(); tok; tok = tok->next) {
dumpProlog += " <tok ";

dumpProlog += "fileIndex=\"";
dumpProlog += std::to_string(tok->location.fileIndex);
dumpProlog += "\" ";

dumpProlog += "linenr=\"";
dumpProlog += std::to_string(tok->location.line);
dumpProlog += "\" ";

dumpProlog +="column=\"";
dumpProlog += std::to_string(tok->location.col);
dumpProlog += "\" ";

dumpProlog += "str=\"";
dumpProlog += ErrorLogger::toxml(tok->str());
dumpProlog += "\"";

dumpProlog += "/>\n";
}
dumpProlog += " </rawtokens>\n";
dumpProlog += getDumpFileContentsRawTokens(files, tokens1);
}

// Parse comments and then remove them
Expand Down Expand Up @@ -1905,3 +1876,38 @@ bool CppCheck::isPremiumCodingStandardId(const std::string& id) const {
return true;
return false;
}

std::string CppCheck::getDumpFileContentsRawTokens(const std::vector<std::string>& files, const simplecpp::TokenList& tokens1) const {
std::string dumpProlog;
dumpProlog += " <rawtokens>\n";
for (unsigned int i = 0; i < files.size(); ++i) {
dumpProlog += " <file index=\"";
dumpProlog += std::to_string(i);
dumpProlog += "\" name=\"";
dumpProlog += ErrorLogger::toxml(Path::getRelativePath(files[i], mSettings.basePaths));
dumpProlog += "\"/>\n";
}
for (const simplecpp::Token *tok = tokens1.cfront(); tok; tok = tok->next) {
dumpProlog += " <tok ";

dumpProlog += "fileIndex=\"";
dumpProlog += std::to_string(tok->location.fileIndex);
dumpProlog += "\" ";

dumpProlog += "linenr=\"";
dumpProlog += std::to_string(tok->location.line);
dumpProlog += "\" ";

dumpProlog +="column=\"";
dumpProlog += std::to_string(tok->location.col);
dumpProlog += "\" ";

dumpProlog += "str=\"";
dumpProlog += ErrorLogger::toxml(tok->str());
dumpProlog += "\"";

dumpProlog += "/>\n";
}
dumpProlog += " </rawtokens>\n";
return dumpProlog;
}
7 changes: 7 additions & 0 deletions lib/cppcheck.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ enum class SHOWTIME_MODES;
struct FileSettings;
class CheckUnusedFunctions;

namespace simplecpp { class TokenList; }

/// @addtogroup Core
/// @{

Expand Down Expand Up @@ -151,6 +153,11 @@ class CPPCHECKLIB CppCheck : ErrorLogger {

std::string getAddonMessage(const std::string& id, const std::string& text) const;

/**
* @brief Get dumpfile <rawtokens> contents, this is only public for testing purposes
*/
std::string getDumpFileContentsRawTokens(const std::vector<std::string>& files, const simplecpp::TokenList& tokens1) const;

private:
#ifdef HAVE_RULES
/** Are there "simple" rules */
Expand Down
3 changes: 2 additions & 1 deletion lib/tokenize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "errortypes.h"
#include "library.h"
#include "mathlib.h"
#include "path.h"
#include "platform.h"
#include "preprocessor.h"
#include "settings.h"
Expand Down Expand Up @@ -5916,7 +5917,7 @@ void Tokenizer::dump(std::ostream &out) const
for (const Directive &dir : mDirectives) {
outs += " <directive ";
outs += "file=\"";
outs += ErrorLogger::toxml(dir.file);
outs += ErrorLogger::toxml(Path::getRelativePath(dir.file, mSettings.basePaths));
outs += "\" ";
outs += "linenr=\"";
outs += std::to_string(dir.linenr);
Expand Down
17 changes: 17 additions & 0 deletions test/testcppcheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#include "helpers.h"
#include "settings.h"

#include "simplecpp.h"

#include <algorithm>
#include <list>
#include <string>
Expand Down Expand Up @@ -56,6 +58,7 @@ class TestCppcheck : public TestFixture {
TEST_CASE(suppress_error_library);
TEST_CASE(unique_errors);
TEST_CASE(isPremiumCodingStandardId);
TEST_CASE(getDumpFileContentsRawTokens);
}

void getErrorMessages() const {
Expand Down Expand Up @@ -206,6 +209,20 @@ class TestCppcheck : public TestFixture {
ASSERT_EQUALS(true, cppcheck.isPremiumCodingStandardId("premium-autosar-0-0-0"));
}

void getDumpFileContentsRawTokens() const {
ErrorLogger2 errorLogger;
CppCheck cppcheck(errorLogger, false, {});
cppcheck.settings() = settingsBuilder().build();
cppcheck.settings().relativePaths = true;
cppcheck.settings().basePaths.emplace_back("/some/path");
std::vector<std::string> files{"/some/path/test.cpp"};
simplecpp::TokenList tokens1(files);
const std::string expected = " <rawtokens>\n"
" <file index=\"0\" name=\"test.cpp\"/>\n"
" </rawtokens>\n";
ASSERT_EQUALS(expected, cppcheck.getDumpFileContentsRawTokens(files, tokens1));
}

// TODO: test suppressions
// TODO: test all with FS
};
Expand Down
30 changes: 24 additions & 6 deletions test/testtokenize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,7 @@ class TestTokenizer : public TestFixture {
TEST_CASE(testDirectiveIncludeTypes);
TEST_CASE(testDirectiveIncludeLocations);
TEST_CASE(testDirectiveIncludeComments);
TEST_CASE(testDirectiveRelativePath);
}

#define tokenizeAndStringify(...) tokenizeAndStringify_(__FILE__, __LINE__, __VA_ARGS__)
Expand Down Expand Up @@ -502,15 +503,18 @@ class TestTokenizer : public TestFixture {
}

void directiveDump(const char filedata[], std::ostream& ostr) {
Preprocessor preprocessor(settingsDefault, *this);
directiveDump(filedata, "test.c", settingsDefault, ostr);
}

void directiveDump(const char filedata[], const char filename[], const Settings& settings, std::ostream& ostr) {
Preprocessor preprocessor(settings, *this);
std::istringstream istr(filedata);
simplecpp::OutputList outputList;
std::vector<std::string> files;
simplecpp::TokenList tokens1(istr, files, "test.c", &outputList);
std::vector<std::string> files{filename};
const simplecpp::TokenList tokens1(istr, files, filename, &outputList);
std::list<Directive> directives = preprocessor.createDirectives(tokens1);

const Settings s = settingsBuilder().severity(Severity::information).build();
Tokenizer tokenizer(s, *this);
Tokenizer tokenizer(settings, *this);
tokenizer.setDirectives(std::move(directives));

tokenizer.dump(ostr);
Expand Down Expand Up @@ -7954,7 +7958,6 @@ class TestTokenizer : public TestFixture {
"#warning some warning message\n"
"#error some error message\n";
const char dumpdata[] = " <directivelist>\n"

" <directive file=\"test.c\" linenr=\"1\" str=\"#define macro some definition\"/>\n"
" <directive file=\"test.c\" linenr=\"2\" str=\"#undef macro\"/>\n"
" <directive file=\"test.c\" linenr=\"3\" str=\"#ifdef macro\"/>\n"
Expand Down Expand Up @@ -8020,6 +8023,21 @@ class TestTokenizer : public TestFixture {
directiveDump(filedata, ostr);
ASSERT_EQUALS(dumpdata, ostr.str());
}

void testDirectiveRelativePath() {
const char filedata[] = "#define macro 1\n";
const char dumpdata[] = " <directivelist>\n"
" <directive file=\"test.c\" linenr=\"1\" str=\"#define macro 1\"/>\n"
" </directivelist>\n"
" <tokenlist>\n"
" </tokenlist>\n";
std::ostringstream ostr;
Settings s(settingsDefault);
s.relativePaths = true;
s.basePaths.emplace_back("/some/path");
directiveDump(filedata, "/some/path/test.c", s, ostr);
ASSERT_EQUALS(dumpdata, ostr.str());
}
};

REGISTER_TEST(TestTokenizer)

0 comments on commit 33fa1bd

Please sign in to comment.