Skip to content

Commit 4056cd5

Browse files
authored
added TokenList constructors with modern buffer wrappers and hide "unsafe" ones - if available (danmar#496)
1 parent 3911fdd commit 4056cd5

File tree

4 files changed

+111
-10
lines changed

4 files changed

+111
-10
lines changed

.github/workflows/CI-unixish.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,16 @@ jobs:
6262
run: |
6363
make -j$(nproc) selfcheck
6464
65+
- name: make testrunner (c++17)
66+
run: |
67+
make clean
68+
make -j$(nproc) testrunner CXXOPTS="-std=c++17"
69+
70+
- name: make testrunner (c++20)
71+
run: |
72+
make clean
73+
make -j$(nproc) testrunner CXXOPTS="-std=c++20"
74+
6575
- name: Run CMake
6676
run: |
6777
cmake -S . -B cmake.output -DCMAKE_COMPILE_WARNING_AS_ERROR=On

simplecpp.cpp

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -466,20 +466,13 @@ simplecpp::TokenList::TokenList(std::istream &istr, std::vector<std::string> &fi
466466
readfile(stream,filename,outputList);
467467
}
468468

469-
simplecpp::TokenList::TokenList(const unsigned char* data, std::size_t size, std::vector<std::string> &filenames, const std::string &filename, OutputList *outputList)
469+
simplecpp::TokenList::TokenList(const unsigned char* data, std::size_t size, std::vector<std::string> &filenames, const std::string &filename, OutputList *outputList, int /*unused*/)
470470
: frontToken(nullptr), backToken(nullptr), files(filenames)
471471
{
472472
StdCharBufStream stream(data, size);
473473
readfile(stream,filename,outputList);
474474
}
475475

476-
simplecpp::TokenList::TokenList(const char* data, std::size_t size, std::vector<std::string> &filenames, const std::string &filename, OutputList *outputList)
477-
: frontToken(nullptr), backToken(nullptr), files(filenames)
478-
{
479-
StdCharBufStream stream(reinterpret_cast<const unsigned char*>(data), size);
480-
readfile(stream,filename,outputList);
481-
}
482-
483476
simplecpp::TokenList::TokenList(const std::string &filename, std::vector<std::string> &filenames, OutputList *outputList)
484477
: frontToken(nullptr), backToken(nullptr), files(filenames)
485478
{

simplecpp.h

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,16 @@
2020
#include <string>
2121
#include <unordered_map>
2222
#include <vector>
23+
#if __cplusplus >= 202002L
24+
# include <version>
25+
#endif
26+
27+
#if defined(__cpp_lib_string_view) && !defined(__cpp_lib_span)
28+
#include <string_view>
29+
#endif
30+
#ifdef __cpp_lib_span
31+
#include <span>
32+
#endif
2333

2434
#ifdef _WIN32
2535
# ifdef SIMPLECPP_EXPORT
@@ -46,6 +56,15 @@
4656
# pragma warning(disable : 4244)
4757
#endif
4858

59+
// provide legacy (i.e. raw pointer) API for TokenList
60+
// note: std::istream has an overhead compared to raw pointers
61+
#ifndef SIMPLECPP_TOKENLIST_ALLOW_PTR
62+
// still provide the legacy API in case we lack the performant wrappers
63+
# if !defined(__cpp_lib_string_view) && !defined(__cpp_lib_span)
64+
# define SIMPLECPP_TOKENLIST_ALLOW_PTR
65+
# endif
66+
#endif
67+
4968
namespace simplecpp {
5069
/** C code standard */
5170
enum cstd_t { CUnknown=-1, C89, C99, C11, C17, C23 };
@@ -216,10 +235,45 @@ namespace simplecpp {
216235
explicit TokenList(std::vector<std::string> &filenames);
217236
/** generates a token list from the given std::istream parameter */
218237
TokenList(std::istream &istr, std::vector<std::string> &filenames, const std::string &filename=std::string(), OutputList *outputList = nullptr);
238+
#ifdef SIMPLECPP_TOKENLIST_ALLOW_PTR
239+
/** generates a token list from the given buffer */
240+
template<size_t size>
241+
TokenList(const char (&data)[size], std::vector<std::string> &filenames, const std::string &filename=std::string(), OutputList *outputList = nullptr)
242+
: TokenList(reinterpret_cast<const unsigned char*>(data), size-1, filenames, filename, outputList, 0)
243+
{}
244+
/** generates a token list from the given buffer */
245+
template<size_t size>
246+
TokenList(const unsigned char (&data)[size], std::vector<std::string> &filenames, const std::string &filename=std::string(), OutputList *outputList = nullptr)
247+
: TokenList(data, size-1, filenames, filename, outputList, 0)
248+
{}
249+
219250
/** generates a token list from the given buffer */
220-
TokenList(const unsigned char* data, std::size_t size, std::vector<std::string> &filenames, const std::string &filename=std::string(), OutputList *outputList = nullptr);
251+
TokenList(const unsigned char* data, std::size_t size, std::vector<std::string> &filenames, const std::string &filename=std::string(), OutputList *outputList = nullptr)
252+
: TokenList(data, size, filenames, filename, outputList, 0)
253+
{}
221254
/** generates a token list from the given buffer */
222-
TokenList(const char* data, std::size_t size, std::vector<std::string> &filenames, const std::string &filename=std::string(), OutputList *outputList = nullptr);
255+
TokenList(const char* data, std::size_t size, std::vector<std::string> &filenames, const std::string &filename=std::string(), OutputList *outputList = nullptr)
256+
: TokenList(reinterpret_cast<const unsigned char*>(data), size, filenames, filename, outputList, 0)
257+
{}
258+
#endif
259+
#if defined(__cpp_lib_string_view) && !defined(__cpp_lib_span)
260+
/** generates a token list from the given buffer */
261+
TokenList(std::string_view data, std::vector<std::string> &filenames, const std::string &filename=std::string(), OutputList *outputList = nullptr)
262+
: TokenList(reinterpret_cast<const unsigned char*>(data.data()), data.size(), filenames, filename, outputList, 0)
263+
{}
264+
#endif
265+
#ifdef __cpp_lib_span
266+
/** generates a token list from the given buffer */
267+
TokenList(std::span<const char> data, std::vector<std::string> &filenames, const std::string &filename=std::string(), OutputList *outputList = nullptr)
268+
: TokenList(reinterpret_cast<const unsigned char*>(data.data()), data.size(), filenames, filename, outputList, 0)
269+
{}
270+
271+
/** generates a token list from the given buffer */
272+
TokenList(std::span<const unsigned char> data, std::vector<std::string> &filenames, const std::string &filename=std::string(), OutputList *outputList = nullptr)
273+
: TokenList(data.data(), data.size(), filenames, filename, outputList, 0)
274+
{}
275+
#endif
276+
223277
/** generates a token list from the given filename parameter */
224278
TokenList(const std::string &filename, std::vector<std::string> &filenames, OutputList *outputList = nullptr);
225279
TokenList(const TokenList &other);
@@ -295,6 +349,8 @@ namespace simplecpp {
295349
}
296350

297351
private:
352+
TokenList(const unsigned char* data, std::size_t size, std::vector<std::string> &filenames, const std::string &filename, OutputList *outputList, int unused);
353+
298354
void combineOperators();
299355

300356
void constFoldUnaryNotPosNeg(Token *tok);
@@ -505,6 +561,8 @@ namespace simplecpp {
505561
SIMPLECPP_LIB std::string getCppStdString(cppstd_t std);
506562
}
507563

564+
#undef SIMPLECPP_TOKENLIST_ALLOW_PTR
565+
508566
#if defined(_MSC_VER)
509567
# pragma warning(pop)
510568
#endif

test.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3179,6 +3179,44 @@ static void preprocess_files()
31793179
}
31803180
}
31813181

3182+
static void safe_api()
3183+
{
3184+
// this test is to make sure the safe APIs are compiling
3185+
#if defined(__cpp_lib_string_view) || defined(__cpp_lib_span)
3186+
std::vector<std::string> filenames;
3187+
# if defined(__cpp_lib_string_view)
3188+
{
3189+
const char input[] = "code";
3190+
const std::string_view sv = input;
3191+
// std::string_view can be implicitly converted into a std::span
3192+
simplecpp::TokenList(sv,filenames,"");
3193+
}
3194+
# endif
3195+
# ifdef __cpp_lib_span
3196+
{
3197+
char input[] = "code";
3198+
const std::span sp = input;
3199+
simplecpp::TokenList(sp,filenames,"");
3200+
}
3201+
{
3202+
const char input[] = "code";
3203+
const std::span sp = input;
3204+
simplecpp::TokenList(sp,filenames,"");
3205+
}
3206+
{
3207+
unsigned char input[] = "code";
3208+
const std::span sp = input;
3209+
simplecpp::TokenList(sp,filenames,"");
3210+
}
3211+
{
3212+
const unsigned char input[] = "code";
3213+
const std::span sp = input;
3214+
simplecpp::TokenList(sp,filenames,"");
3215+
}
3216+
# endif
3217+
#endif
3218+
}
3219+
31823220
static void fuzz_crash()
31833221
{
31843222
{
@@ -3445,6 +3483,8 @@ int main(int argc, char **argv)
34453483

34463484
TEST_CASE(preprocess_files);
34473485

3486+
TEST_CASE(safe_api);
3487+
34483488
TEST_CASE(fuzz_crash);
34493489

34503490
return numberOfFailedAssertions > 0 ? EXIT_FAILURE : EXIT_SUCCESS;

0 commit comments

Comments
 (0)