diff --git a/externals/simplecpp/simplecpp.cpp b/externals/simplecpp/simplecpp.cpp index 47bb78f8cf17..3cce780efcad 100755 --- a/externals/simplecpp/simplecpp.cpp +++ b/externals/simplecpp/simplecpp.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -377,6 +378,42 @@ class StdIStream : public simplecpp::TokenList::Stream { std::istream &istr; }; +class StdCharBufStream : public simplecpp::TokenList::Stream { +public: + // cppcheck-suppress uninitDerivedMemberVar - we call Stream::init() to initialize the private members + StdCharBufStream(const unsigned char* str, std::size_t size) + : str(str) + , size(size) + , pos(0) + , lastStatus(0) + { + init(); + } + + virtual int get() OVERRIDE { + if (pos >= size) + return lastStatus = EOF; + return str[pos++]; + } + virtual int peek() OVERRIDE { + if (pos >= size) + return lastStatus = EOF; + return str[pos]; + } + virtual void unget() OVERRIDE { + --pos; + } + virtual bool good() OVERRIDE { + return lastStatus != EOF; + } + +private: + const unsigned char *str; + const std::size_t size; + std::size_t pos; + int lastStatus; +}; + class FileStream : public simplecpp::TokenList::Stream { public: // cppcheck-suppress uninitDerivedMemberVar - we call Stream::init() to initialize the private members @@ -442,6 +479,20 @@ simplecpp::TokenList::TokenList(std::istream &istr, std::vector &fi readfile(stream,filename,outputList); } +simplecpp::TokenList::TokenList(const unsigned char* data, std::size_t size, std::vector &filenames, const std::string &filename, OutputList *outputList) + : frontToken(nullptr), backToken(nullptr), files(filenames) +{ + StdCharBufStream stream(data, size); + readfile(stream,filename,outputList); +} + +simplecpp::TokenList::TokenList(const char* data, std::size_t size, std::vector &filenames, const std::string &filename, OutputList *outputList) + : frontToken(nullptr), backToken(nullptr), files(filenames) +{ + StdCharBufStream stream(reinterpret_cast(data), size); + readfile(stream,filename,outputList); +} + simplecpp::TokenList::TokenList(const std::string &filename, std::vector &filenames, OutputList *outputList) : frontToken(nullptr), backToken(nullptr), files(filenames) { @@ -1447,8 +1498,7 @@ namespace simplecpp { Macro(const std::string &name, const std::string &value, std::vector &f) : nameTokDef(nullptr), files(f), tokenListDefine(f), valueDefinedInCode_(false) { const std::string def(name + ' ' + value); - std::istringstream istr(def); - StdIStream stream(istr); + StdCharBufStream stream(reinterpret_cast(def.data()), def.size()); tokenListDefine.readfile(stream); if (!parseDefine(tokenListDefine.cfront())) throw std::runtime_error("bad macro syntax. macroname=" + name + " value=" + value); @@ -3315,8 +3365,17 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL macros.insert(std::make_pair("__STDC_VERSION__", Macro("__STDC_VERSION__", std_def, dummy))); } else { std_def = simplecpp::getCppStdString(dui.std); - if (!std_def.empty()) - macros.insert(std::make_pair("__cplusplus", Macro("__cplusplus", std_def, dummy))); + if (std_def.empty()) { + if (outputList) { + simplecpp::Output err(files); + err.type = Output::DUI_ERROR; + err.msg = "unknown standard specified: '" + dui.std + "'"; + outputList->push_back(err); + } + output.clear(); + return; + } + macros.insert(std::make_pair("__cplusplus", Macro("__cplusplus", std_def, dummy))); } } @@ -3463,7 +3522,8 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL std::ifstream f; header2 = openHeader(f, dui, rawtok->location.file(), header, systemheader); if (f.is_open()) { - TokenList * const tokens = new TokenList(f, files, header2, outputList); + f.close(); + TokenList * const tokens = new TokenList(header2, files, outputList); if (dui.removeComments) tokens->removeComments(); filedata[header2] = tokens; diff --git a/externals/simplecpp/simplecpp.h b/externals/simplecpp/simplecpp.h index c72e4c655cf5..88a140145677 100755 --- a/externals/simplecpp/simplecpp.h +++ b/externals/simplecpp/simplecpp.h @@ -1,4 +1,4 @@ -/* +/* -*- C++ -*- * simplecpp - A simple and high-fidelity C/C++ preprocessor library * Copyright (C) 2016-2023 simplecpp team */ @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include #include @@ -181,7 +181,8 @@ namespace simplecpp { PORTABILITY_BACKSLASH, UNHANDLED_CHAR_ERROR, EXPLICIT_INCLUDE_NOT_FOUND, - FILE_NOT_FOUND + FILE_NOT_FOUND, + DUI_ERROR } type; explicit Output(const std::vector& files, Type type, const std::string& msg) : type(type), location(files), msg(msg) {} Location location; @@ -198,6 +199,10 @@ namespace simplecpp { explicit TokenList(std::vector &filenames); /** generates a token list from the given std::istream parameter */ TokenList(std::istream &istr, std::vector &filenames, const std::string &filename=std::string(), OutputList *outputList = nullptr); + /** generates a token list from the given buffer */ + TokenList(const unsigned char* data, std::size_t size, std::vector &filenames, const std::string &filename=std::string(), OutputList *outputList = nullptr); + /** generates a token list from the given buffer */ + TokenList(const char* data, std::size_t size, std::vector &filenames, const std::string &filename=std::string(), OutputList *outputList = nullptr); /** generates a token list from the given filename parameter */ TokenList(const std::string &filename, std::vector &filenames, OutputList *outputList = nullptr); TokenList(const TokenList &other);