Skip to content

Commit 40b8f3d

Browse files
committed
686
1 parent f6947eb commit 40b8f3d

4 files changed

Lines changed: 271 additions & 124 deletions

File tree

main.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ int main(int argc, char **argv)
224224
{
225225
simplecpp::TokenList *rawtokens;
226226
if (toklist_inf == Fstream) {
227-
rawtokens = new simplecpp::TokenList(f,files,filename,&outputList);
227+
rawtokens = new simplecpp::TokenList(f,files,filename,dui,&outputList);
228228
}
229229
else if (toklist_inf == Sstream || toklist_inf == CharBuffer) {
230230
std::ostringstream oss;
@@ -233,14 +233,14 @@ int main(int argc, char **argv)
233233
const std::string s = oss.str();
234234
if (toklist_inf == Sstream) {
235235
std::istringstream iss(s);
236-
rawtokens = new simplecpp::TokenList(iss,files,filename,&outputList);
236+
rawtokens = new simplecpp::TokenList(iss,files,filename,dui,&outputList);
237237
}
238238
else {
239-
rawtokens = new simplecpp::TokenList({s.data(),s.size()},files,filename,&outputList);
239+
rawtokens = new simplecpp::TokenList({s.data(),s.size()},files,filename,dui,&outputList);
240240
}
241241
} else {
242242
f.close();
243-
rawtokens = new simplecpp::TokenList(filename,files,&outputList);
243+
rawtokens = new simplecpp::TokenList(filename,files,dui,&outputList);
244244
}
245245
rawtokens->removeComments();
246246
simplecpp::FileDataCache filedata;
@@ -276,6 +276,7 @@ int main(int argc, char **argv)
276276
std::cerr << "directive as macro parameter: ";
277277
break;
278278
case simplecpp::Output::PORTABILITY_BACKSLASH:
279+
case simplecpp::Output::PORTABILITY_LINE_DIRECTIVE:
279280
std::cerr << "portability: ";
280281
break;
281282
case simplecpp::Output::PORTABILITY_NO_EOF_NEWLINE:

simplecpp.cpp

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -475,26 +475,26 @@ namespace {
475475

476476
simplecpp::TokenList::TokenList(std::vector<std::string> &filenames) : frontToken(nullptr), backToken(nullptr), files(filenames) {}
477477

478-
simplecpp::TokenList::TokenList(std::istream &istr, std::vector<std::string> &filenames, const std::string &filename, OutputList *outputList)
478+
simplecpp::TokenList::TokenList(std::istream &istr, std::vector<std::string> &filenames, const std::string &filename, const DUI &dui, OutputList *outputList)
479479
: frontToken(nullptr), backToken(nullptr), files(filenames)
480480
{
481481
StdIStream stream(istr);
482-
readfile(stream,filename,outputList);
482+
readfile(stream,filename,dui,outputList);
483483
}
484484

485-
simplecpp::TokenList::TokenList(const unsigned char* data, std::size_t size, std::vector<std::string> &filenames, const std::string &filename, OutputList *outputList, int /*unused*/)
485+
simplecpp::TokenList::TokenList(const unsigned char* data, std::size_t size, std::vector<std::string> &filenames, const std::string &filename, const DUI &dui, OutputList *outputList, int /*unused*/)
486486
: frontToken(nullptr), backToken(nullptr), files(filenames)
487487
{
488488
StdCharBufStream stream(data, size);
489-
readfile(stream,filename,outputList);
489+
readfile(stream,filename,dui,outputList);
490490
}
491491

492-
simplecpp::TokenList::TokenList(const std::string &filename, std::vector<std::string> &filenames, OutputList *outputList)
492+
simplecpp::TokenList::TokenList(const std::string &filename, std::vector<std::string> &filenames, const DUI &dui, OutputList *outputList)
493493
: frontToken(nullptr), backToken(nullptr), files(filenames)
494494
{
495495
try {
496496
FileStream stream(filename, filenames);
497-
readfile(stream,filename,outputList);
497+
readfile(stream,filename,dui,outputList);
498498
} catch (const simplecpp::Output & e) {
499499
outputList->emplace_back(e);
500500
}
@@ -659,13 +659,23 @@ void simplecpp::TokenList::lineDirective(unsigned int fileIndex_, unsigned int l
659659

660660
static const std::string COMMENT_END("*/");
661661

662-
void simplecpp::TokenList::readfile(Stream &stream, const std::string &filename, OutputList *outputList)
662+
void simplecpp::TokenList::readfile(Stream &stream, const std::string &filename, const DUI &dui, OutputList *outputList)
663663
{
664664
unsigned int multiline = 0U;
665665
bool trailing_nl = true;
666666

667667
const Token *oldLastToken = nullptr;
668668

669+
unsigned long maxline;
670+
{
671+
cstd_t cstd = getCStd(dui.std);
672+
cppstd_t cppstd = getCppStd(dui.std);
673+
if ((cstd != CUnknown && cstd < C99) || (cppstd != CPPUnknown && cppstd < CPP11))
674+
maxline = 32767;
675+
else
676+
maxline = 2147483647;
677+
}
678+
669679
Location location(fileIndex(filename), 1, 1);
670680
while (stream.good()) {
671681
unsigned char ch = stream.readChar();
@@ -730,7 +740,22 @@ void simplecpp::TokenList::readfile(Stream &stream, const std::string &filename,
730740
if (!ppTok || !ppTok->number)
731741
continue;
732742

733-
const unsigned int line = std::atol(ppTok->str().c_str());
743+
unsigned long line = 0;
744+
try {
745+
line = std::stoul(ppTok->str());
746+
} catch (...) {}
747+
748+
if (line == 0 || line > maxline) {
749+
if (outputList) {
750+
simplecpp::Output err{
751+
simplecpp::Output::PORTABILITY_LINE_DIRECTIVE,
752+
location,
753+
"Line number out of range: " + ppTok->str() + "."
754+
};
755+
outputList->emplace_back(std::move(err));
756+
}
757+
}
758+
734759
ppTok = advanceAndSkipComments(ppTok);
735760

736761
unsigned int fileindex;
@@ -3163,7 +3188,7 @@ std::pair<simplecpp::FileData *, bool> simplecpp::FileDataCache::tryload(FileDat
31633188
return {id_it->second, false};
31643189
}
31653190

3166-
auto *const data = new FileData {path, TokenList(path, filenames, outputList)};
3191+
auto *const data = new FileData {path, TokenList(path, filenames, {}, outputList)};
31673192

31683193
if (dui.removeComments)
31693194
data->tokens.removeComments();

simplecpp.h

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ namespace simplecpp {
249249
SYNTAX_ERROR,
250250
DIRECTIVE_AS_MACRO_PARAMETER,
251251
PORTABILITY_BACKSLASH,
252+
PORTABILITY_LINE_DIRECTIVE,
252253
PORTABILITY_NO_EOF_NEWLINE,
253254
UNHANDLED_CHAR_ERROR,
254255
EXPLICIT_INCLUDE_NOT_FOUND,
@@ -262,52 +263,67 @@ namespace simplecpp {
262263

263264
using OutputList = std::list<Output>;
264265

266+
/**
267+
* Command line preprocessor settings.
268+
* On the command line these are configured by -D, -U, -I, --include, -std
269+
*/
270+
struct SIMPLECPP_LIB DUI {
271+
DUI() = default;
272+
std::list<std::string> defines;
273+
std::set<std::string> undefined;
274+
std::list<std::string> includePaths;
275+
std::list<std::string> includes;
276+
std::string std;
277+
bool clearIncludeCache{};
278+
bool removeComments{}; /** remove comment tokens from included files */
279+
};
280+
265281
/** List of tokens. */
266282
class SIMPLECPP_LIB TokenList {
267283
public:
268284
class Stream;
269285

270286
explicit TokenList(std::vector<std::string> &filenames);
271287
/** generates a token list from the given std::istream parameter */
272-
TokenList(std::istream &istr, std::vector<std::string> &filenames, const std::string &filename=std::string(), OutputList *outputList = nullptr);
288+
TokenList(std::istream &istr, std::vector<std::string> &filenames, const std::string &filename=std::string(), const DUI &dui = {}, OutputList *outputList = nullptr);
273289
/** generates a token list from the given buffer */
274290
template<size_t size>
275-
TokenList(const char (&data)[size], std::vector<std::string> &filenames, const std::string &filename=std::string(), OutputList *outputList = nullptr)
276-
: TokenList(reinterpret_cast<const unsigned char*>(data), size-1, filenames, filename, outputList, 0)
291+
TokenList(const char (&data)[size], std::vector<std::string> &filenames, const std::string &filename=std::string(), const DUI &dui = {}, OutputList *outputList = nullptr)
292+
: TokenList(reinterpret_cast<const unsigned char*>(data), size-1, filenames, filename, dui, outputList, 0)
277293
{}
278294
/** generates a token list from the given buffer */
279295
template<size_t size>
280-
TokenList(const unsigned char (&data)[size], std::vector<std::string> &filenames, const std::string &filename=std::string(), OutputList *outputList = nullptr)
281-
: TokenList(data, size-1, filenames, filename, outputList, 0)
296+
TokenList(const unsigned char (&data)[size], std::vector<std::string> &filenames, const std::string &filename=std::string(), const DUI &dui = {}, OutputList *outputList = nullptr)
297+
: TokenList(data, size-1, filenames, filename, dui, outputList, 0)
282298
{}
283299
#if SIMPLECPP_TOKENLIST_ALLOW_PTR
284300
/** generates a token list from the given buffer */
285-
TokenList(const unsigned char* data, std::size_t size, std::vector<std::string> &filenames, const std::string &filename=std::string(), OutputList *outputList = nullptr)
286-
: TokenList(data, size, filenames, filename, outputList, 0)
301+
TokenList(const unsigned char* data, std::size_t size, std::vector<std::string> &filenames, const std::string &filename=std::string(), const DUI &dui = {}, OutputList *outputList = nullptr)
302+
: TokenList(data, size, filenames, filename, dui, outputList, 0)
287303
{}
288304
/** generates a token list from the given buffer */
289-
TokenList(const char* data, std::size_t size, std::vector<std::string> &filenames, const std::string &filename=std::string(), OutputList *outputList = nullptr)
290-
: TokenList(reinterpret_cast<const unsigned char*>(data), size, filenames, filename, outputList, 0)
305+
TokenList(const char* data, std::size_t size, std::vector<std::string> &filenames, const std::string &filename=std::string(), const DUI &dui = {}, OutputList *outputList = nullptr)
306+
: TokenList(reinterpret_cast<const unsigned char*>(data), size, filenames, filename, dui, outputList, 0)
291307
{}
292308
#endif // SIMPLECPP_TOKENLIST_ALLOW_PTR
293309
/** generates a token list from the given buffer */
294-
TokenList(View data, std::vector<std::string> &filenames, const std::string &filename=std::string(), OutputList *outputList = nullptr)
295-
: TokenList(reinterpret_cast<const unsigned char*>(data.data()), data.size(), filenames, filename, outputList, 0)
310+
TokenList(View data, std::vector<std::string> &filenames, const std::string &filename=std::string(), const DUI &dui = {}, OutputList *outputList = nullptr)
311+
: TokenList(reinterpret_cast<const unsigned char*>(data.data()), data.size(), filenames, filename, dui, outputList, 0)
296312
{}
297313
#ifdef __cpp_lib_span
298314
/** generates a token list from the given buffer */
299-
TokenList(std::span<const char> data, std::vector<std::string> &filenames, const std::string &filename=std::string(), OutputList *outputList = nullptr)
300-
: TokenList(reinterpret_cast<const unsigned char*>(data.data()), data.size(), filenames, filename, outputList, 0)
315+
TokenList(std::span<const char> data, std::vector<std::string> &filenames, const std::string &filename=std::string(), const DUI &dui = {}, OutputList *outputList = nullptr)
316+
: TokenList(reinterpret_cast<const unsigned char*>(data.data()), data.size(), filenames, filename, dui, outputList, 0)
301317
{}
302318

303319
/** generates a token list from the given buffer */
304-
TokenList(std::span<const unsigned char> data, std::vector<std::string> &filenames, const std::string &filename=std::string(), OutputList *outputList = nullptr)
305-
: TokenList(data.data(), data.size(), filenames, filename, outputList, 0)
320+
TokenList(std::span<const unsigned char> data, std::vector<std::string> &filenames, const std::string &filename=std::string(), const DUI &dui = {}, OutputList *outputList = nullptr)
321+
: TokenList(data.data(), data.size(), filenames, filename, dui, outputList, 0)
306322
{}
307323
#endif // __cpp_lib_span
308324

309325
/** generates a token list from the given filename parameter */
310-
TokenList(const std::string &filename, std::vector<std::string> &filenames, OutputList *outputList = nullptr);
326+
TokenList(const std::string &filename, std::vector<std::string> &filenames, const DUI &dui = {}, OutputList *outputList = nullptr);
311327
TokenList(const TokenList &other);
312328
TokenList(TokenList &&other);
313329
~TokenList();
@@ -323,7 +339,7 @@ namespace simplecpp {
323339
void dump(bool linenrs = false) const;
324340
std::string stringify(bool linenrs = false) const;
325341

326-
void readfile(Stream &stream, const std::string &filename=std::string(), OutputList *outputList = nullptr);
342+
void readfile(Stream &stream, const std::string &filename=std::string(), const DUI &dui = {}, OutputList *outputList = nullptr);
327343
/**
328344
* @throws std::overflow_error thrown on overflow or division by zero
329345
* @throws std::runtime_error thrown on invalid expressions
@@ -387,7 +403,7 @@ namespace simplecpp {
387403
const std::string& file(const Location& loc) const;
388404

389405
private:
390-
TokenList(const unsigned char* data, std::size_t size, std::vector<std::string> &filenames, const std::string &filename, OutputList *outputList, int /*unused*/);
406+
TokenList(const unsigned char* data, std::size_t size, std::vector<std::string> &filenames, const std::string &filename, const DUI &dui, OutputList *outputList, int /*unused*/);
391407

392408
void combineOperators();
393409

@@ -436,21 +452,6 @@ namespace simplecpp {
436452
long long result; // condition result
437453
};
438454

439-
/**
440-
* Command line preprocessor settings.
441-
* On the command line these are configured by -D, -U, -I, --include, -std
442-
*/
443-
struct SIMPLECPP_LIB DUI {
444-
DUI() = default;
445-
std::list<std::string> defines;
446-
std::set<std::string> undefined;
447-
std::list<std::string> includePaths;
448-
std::list<std::string> includes;
449-
std::string std;
450-
bool clearIncludeCache{};
451-
bool removeComments{}; /** remove comment tokens from included files */
452-
};
453-
454455
struct SIMPLECPP_LIB FileData {
455456
/** The canonical filename associated with this data */
456457
std::string filename;

0 commit comments

Comments
 (0)