Skip to content

Commit 20bed39

Browse files
authored
pass a char buffer to simplecpp instead of a stream (#6379)
1 parent 9257dd6 commit 20bed39

31 files changed

+257
-221
lines changed

democlient/democlient.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ class CppcheckExecutor : public ErrorLogger {
6666
, cppcheck(settings, supprs, *this, false, nullptr)
6767
{}
6868

69-
void run(const char code[]) {
70-
cppcheck.check(FileWithDetails("test.cpp", Standards::Language::CPP, 0), code);
69+
void run(const char* code) {
70+
cppcheck.checkBuffer(FileWithDetails("test.cpp", Standards::Language::CPP, 0), reinterpret_cast<const uint8_t*>(code), strlen(code));
7171
}
7272

7373
void reportOut(const std::string & /*outmsg*/, Color /*c*/) override {}

gui/mainwindow.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -729,8 +729,11 @@ void MainWindow::analyzeCode(const QString& code, const QString& filename)
729729
checkLockDownUI();
730730
clearResults();
731731
mUI->mResults->checkingStarted(1);
732-
// TODO: apply enforcedLanguage?
733-
cppcheck.check(FileWithDetails(filename.toStdString(), Path::identify(filename.toStdString(), false), 0), code.toStdString());
732+
{
733+
const std::string code_s = code.toStdString();
734+
// TODO: apply enforcedLanguage?
735+
cppcheck.checkBuffer(FileWithDetails(filename.toStdString(), Path::identify(filename.toStdString(), false), 0), reinterpret_cast<const std::uint8_t*>(code_s.data()), code_s.size());
736+
}
734737
analysisDone();
735738

736739
// Expand results

lib/cppcheck.cpp

Lines changed: 27 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -799,10 +799,9 @@ unsigned int CppCheck::check(const FileWithDetails &file)
799799
return returnValue;
800800
}
801801

802-
unsigned int CppCheck::check(const FileWithDetails &file, const std::string &content)
802+
unsigned int CppCheck::checkBuffer(const FileWithDetails &file, const uint8_t* data, std::size_t size)
803803
{
804-
std::istringstream iss(content);
805-
return checkFile(file, "", 0, &iss);
804+
return checkBuffer(file, "", 0, data, size);
806805
}
807806

808807
unsigned int CppCheck::check(const FileSettings &fs)
@@ -851,14 +850,6 @@ unsigned int CppCheck::check(const FileSettings &fs)
851850
return returnValue;
852851
}
853852

854-
static simplecpp::TokenList createTokenList(const std::string& filename, std::vector<std::string>& files, simplecpp::OutputList* outputList, std::istream* fileStream)
855-
{
856-
if (fileStream)
857-
return {*fileStream, files, filename, outputList};
858-
859-
return {filename, files, outputList};
860-
}
861-
862853
std::size_t CppCheck::calculateHash(const Preprocessor& preprocessor, const simplecpp::TokenList& tokens, const std::string& filePath) const
863854
{
864855
std::ostringstream toolinfo;
@@ -880,7 +871,23 @@ std::size_t CppCheck::calculateHash(const Preprocessor& preprocessor, const simp
880871
return preprocessor.calculateHash(tokens, toolinfo.str());
881872
}
882873

883-
unsigned int CppCheck::checkFile(const FileWithDetails& file, const std::string &cfgname, int fileIndex, std::istream* fileStream)
874+
unsigned int CppCheck::checkBuffer(const FileWithDetails &file, const std::string &cfgname, int fileIndex, const uint8_t* data, std::size_t size)
875+
{
876+
const auto f = [&file, data, size](std::vector<std::string>& files, simplecpp::OutputList* outputList) {
877+
return simplecpp::TokenList{data, size, files, file.spath(), outputList};
878+
};
879+
return checkInternal(file, cfgname, fileIndex, f);
880+
}
881+
882+
unsigned int CppCheck::checkFile(const FileWithDetails& file, const std::string &cfgname, int fileIndex)
883+
{
884+
const auto f = [&file](std::vector<std::string>& files, simplecpp::OutputList* outputList) {
885+
return simplecpp::TokenList{file.spath(), files, outputList};
886+
};
887+
return checkInternal(file, cfgname, fileIndex, f);
888+
}
889+
890+
unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::string &cfgname, int fileIndex, const CreateTokenListFn& createTokenList)
884891
{
885892
// TODO: move to constructor when CppCheck no longer owns the settings
886893
if (mSettings.checks.isEnabled(Checks::unusedFunction) && !mUnusedFunctionsCheck)
@@ -931,24 +938,13 @@ unsigned int CppCheck::checkFile(const FileWithDetails& file, const std::string
931938
std::size_t hash = 0;
932939
// markup files are special and do not adhere to the enforced language
933940
TokenList tokenlist{mSettings, Standards::Language::C};
934-
if (fileStream) {
935-
std::vector<std::string> files;
936-
simplecpp::TokenList tokens(*fileStream, files, file.spath());
937-
if (analyzerInformation) {
938-
const Preprocessor preprocessor(mSettings, mErrorLogger, Standards::Language::C);
939-
hash = calculateHash(preprocessor, tokens);
940-
}
941-
tokenlist.createTokens(std::move(tokens));
942-
}
943-
else {
944-
std::vector<std::string> files;
945-
simplecpp::TokenList tokens(file.spath(), files);
946-
if (analyzerInformation) {
947-
const Preprocessor preprocessor(mSettings, mErrorLogger, file.lang());
948-
hash = calculateHash(preprocessor, tokens);
949-
}
950-
tokenlist.createTokens(std::move(tokens));
941+
std::vector<std::string> files;
942+
simplecpp::TokenList tokens = createTokenList(files, nullptr);
943+
if (analyzerInformation) {
944+
const Preprocessor preprocessor(mSettings, mErrorLogger, file.lang());
945+
hash = calculateHash(preprocessor, tokens);
951946
}
947+
tokenlist.createTokens(std::move(tokens));
952948
// this is not a real source file - we just want to tokenize it. treat it as C anyways as the language needs to be determined.
953949
Tokenizer tokenizer(std::move(tokenlist), mErrorLogger);
954950
mUnusedFunctionsCheck->parseTokens(tokenizer, mSettings);
@@ -967,7 +963,7 @@ unsigned int CppCheck::checkFile(const FileWithDetails& file, const std::string
967963

968964
simplecpp::OutputList outputList;
969965
std::vector<std::string> files;
970-
simplecpp::TokenList tokens1 = createTokenList(file.spath(), files, &outputList, fileStream);
966+
simplecpp::TokenList tokens1 = createTokenList(files, &outputList);
971967

972968
// If there is a syntax error, report it and stop
973969
const auto output_it = std::find_if(outputList.cbegin(), outputList.cend(), [](const simplecpp::Output &output){
@@ -1075,8 +1071,7 @@ unsigned int CppCheck::checkFile(const FileWithDetails& file, const std::string
10751071
code += "#line " + std::to_string(dir.linenr) + " \"" + dir.file + "\"\n" + dir.str + '\n';
10761072
}
10771073
TokenList tokenlist(mSettings, file.lang());
1078-
std::istringstream istr2(code);
1079-
tokenlist.createTokens(istr2); // TODO: check result?
1074+
tokenlist.createTokensFromBuffer(code.data(), code.size()); // TODO: check result?
10801075
executeRules("define", tokenlist);
10811076
}
10821077
#endif

lib/cppcheck.h

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,10 @@ class Settings;
4545
struct Suppressions;
4646
class Preprocessor;
4747

48-
namespace simplecpp { class TokenList; }
48+
namespace simplecpp {
49+
class TokenList;
50+
struct Output;
51+
}
4952

5053
/// @addtogroup Core
5154
/// @{
@@ -100,12 +103,13 @@ class CPPCHECKLIB CppCheck {
100103
* the disk but the content is given in @p content. In errors the @p path
101104
* is used as a filename.
102105
* @param file The file to check.
103-
* @param content File content as a string.
106+
* @param data File content as a buffer.
107+
* @param size Size of buffer.
104108
* @return amount of errors found or 0 if none were found.
105109
* @note You must set settings before calling this function (by calling
106110
* settings()).
107111
*/
108-
unsigned int check(const FileWithDetails &file, const std::string &content);
112+
unsigned int checkBuffer(const FileWithDetails &file, const uint8_t* data, std::size_t size);
109113

110114
/**
111115
* @brief Returns current version number as a string.
@@ -174,14 +178,35 @@ class CPPCHECKLIB CppCheck {
174178
*/
175179
std::size_t calculateHash(const Preprocessor &preprocessor, const simplecpp::TokenList &tokens, const std::string& filePath = {}) const;
176180

181+
/**
182+
* @brief Check a file
183+
* @param file the file
184+
* @param cfgname cfg name
185+
* @return number of errors found
186+
*/
187+
unsigned int checkFile(const FileWithDetails& file, const std::string &cfgname, int fileIndex);
188+
189+
/**
190+
* @brief Check a file using buffer
191+
* @param file the file
192+
* @param cfgname cfg name
193+
* @param data the data to be read
194+
* @param size the size of the data to be read
195+
* @return number of errors found
196+
*/
197+
unsigned int checkBuffer(const FileWithDetails& file, const std::string &cfgname, int fileIndex, const uint8_t* data, std::size_t size);
198+
199+
// TODO: should use simplecpp::OutputList
200+
using CreateTokenListFn = std::function<simplecpp::TokenList (std::vector<std::string>&, std::list<simplecpp::Output>*)>;
201+
177202
/**
178203
* @brief Check a file using stream
179204
* @param file the file
180205
* @param cfgname cfg name
181-
* @param fileStream stream the file content can be read from
206+
* @param createTokenList a function to create the simplecpp::TokenList with
182207
* @return number of errors found
183208
*/
184-
unsigned int checkFile(const FileWithDetails& file, const std::string &cfgname, int fileIndex, std::istream* fileStream = nullptr);
209+
unsigned int checkInternal(const FileWithDetails& file, const std::string &cfgname, int fileIndex, const CreateTokenListFn& createTokenList);
185210

186211
/**
187212
* @brief Check normal tokens

lib/importproject.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -533,8 +533,7 @@ namespace {
533533
// TODO: improve evaluation
534534
const Settings s;
535535
TokenList tokenlist(s, Standards::Language::C);
536-
std::istringstream istr(c);
537-
tokenlist.createTokens(istr); // TODO: check result
536+
tokenlist.createTokensFromBuffer(c.data(), c.size()); // TODO: check result
538537
// TODO: put in a helper
539538
// generate links
540539
{

lib/library.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
#include <iostream>
3636
#include <list>
3737
#include <memory>
38-
#include <sstream>
3938
#include <stdexcept>
4039
#include <string>
4140
#include <unordered_set>
@@ -178,8 +177,8 @@ static std::vector<std::string> getnames(const char *names)
178177

179178
static void gettokenlistfromvalid(const std::string& valid, TokenList& tokenList)
180179
{
181-
std::istringstream istr(valid + ',');
182-
tokenList.createTokens(istr); // TODO: check result?
180+
const std::string str(valid + ',');
181+
tokenList.createTokensFromBuffer(str.data(), str.size()); // TODO: check result?
183182
for (Token *tok = tokenList.front(); tok; tok = tok->next()) {
184183
if (Token::Match(tok,"- %num%")) {
185184
tok->str("-" + tok->strAt(1));

lib/programmemory.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1839,8 +1839,7 @@ static std::shared_ptr<Token> createTokenFromExpression(const std::string& retur
18391839
std::shared_ptr<TokenList> tokenList = std::make_shared<TokenList>(settings, cpp ? Standards::Language::CPP : Standards::Language::C);
18401840
{
18411841
const std::string code = "return " + returnValue + ";";
1842-
std::istringstream istr(code);
1843-
if (!tokenList->createTokens(istr))
1842+
if (!tokenList->createTokensFromBuffer(code.data(), code.size()))
18441843
return nullptr;
18451844
}
18461845

lib/symboldatabase.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7758,8 +7758,8 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to
77587758
if (!typestr.empty()) {
77597759
ValueType valuetype;
77607760
TokenList tokenList(mSettings, tok->isCpp() ? Standards::Language::CPP : Standards::Language::C);
7761-
std::istringstream istr(typestr+";");
7762-
tokenList.createTokens(istr); // TODO: check result?
7761+
const std::string str(typestr+";");
7762+
tokenList.createTokensFromBuffer(str.data(), str.size()); // TODO: check result?
77637763
tokenList.simplifyStdType();
77647764
if (parsedecl(tokenList.front(), &valuetype, mDefaultSignedness, mSettings)) {
77657765
valuetype.originalTypeName = typestr;
@@ -7848,8 +7848,8 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to
78487848
continue;
78497849
}
78507850
TokenList tokenList(mSettings, tok->isCpp() ? Standards::Language::CPP : Standards::Language::C);
7851-
std::istringstream istr(typestr+";");
7852-
if (tokenList.createTokens(istr)) {
7851+
const std::string str(typestr+";");
7852+
if (tokenList.createTokensFromBuffer(str.data(), str.size())) {
78537853
ValueType vt;
78547854
tokenList.simplifyPlatformTypes();
78557855
tokenList.simplifyStdType();

lib/tokenlist.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -321,17 +321,17 @@ void TokenList::insertTokens(Token *dest, const Token *src, nonneg int n)
321321

322322
//---------------------------------------------------------------------------
323323

324-
bool TokenList::createTokens(std::istream &code)
324+
bool TokenList::createTokensFromBuffer(const uint8_t* data, size_t size)
325325
{
326-
return createTokensInternal(code, mFiles.empty() ? "" : *mFiles.cbegin());
326+
return createTokensFromBufferInternal(data, size, mFiles.empty() ? "" : *mFiles.cbegin());
327327
}
328328

329329
//---------------------------------------------------------------------------
330330

331-
bool TokenList::createTokensInternal(std::istream &code, const std::string& file0)
331+
bool TokenList::createTokensFromBufferInternal(const uint8_t* data, size_t size, const std::string& file0)
332332
{
333333
simplecpp::OutputList outputList;
334-
simplecpp::TokenList tokens(code, mFiles, file0, &outputList);
334+
simplecpp::TokenList tokens(data, size, mFiles, file0, &outputList);
335335

336336
createTokens(std::move(tokens));
337337

lib/tokenlist.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,16 @@ class CPPCHECKLIB TokenList {
9898
* - multiline strings are not handled.
9999
* - UTF in the code are not handled.
100100
* - comments are not handled.
101-
* @param code input stream for code
102101
*/
103-
bool createTokens(std::istream &code);
102+
bool createTokensFromBuffer(const uint8_t* data, size_t size);
103+
bool createTokensFromBuffer(const char* data, size_t size) {
104+
return createTokensFromBuffer(reinterpret_cast<const uint8_t*>(data), size);
105+
}
106+
template<size_t size>
107+
// cppcheck-suppress unusedFunction - used in tests only
108+
bool createTokensFromString(const char (&data)[size]) {
109+
return createTokensFromBuffer(reinterpret_cast<const uint8_t*>(data), size-1);
110+
}
104111

105112
void createTokens(simplecpp::TokenList&& tokenList);
106113

@@ -208,7 +215,7 @@ class CPPCHECKLIB TokenList {
208215
}
209216

210217
private:
211-
bool createTokensInternal(std::istream &code, const std::string& file0);
218+
bool createTokensFromBufferInternal(const uint8_t* data, std::size_t size, const std::string& file0);
212219

213220
/** Token list */
214221
std::shared_ptr<TokensFrontBack> mTokensFrontBack;

0 commit comments

Comments
 (0)