diff --git a/VERSION b/VERSION index 9084fa2..26aaba0 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.1.0 +1.2.0 diff --git a/dconv/include/dconv/probe.hpp b/dconv/include/dconv/probe.hpp index c5da8fd..b9090dc 100644 --- a/dconv/include/dconv/probe.hpp +++ b/dconv/include/dconv/probe.hpp @@ -26,9 +26,7 @@ #define __DCONV_PROBE_HPP__ // C++. -#include #include -#include #include // C. @@ -41,43 +39,6 @@ namespace dconv { - namespace details - { - struct alignas (64) EscapedTable - { - uint8_t data[256]; - - constexpr EscapedTable () - : data{} - { - for (unsigned i = 0; i < 0x20; ++i) - { - data[i] = 1; - } - data[static_cast ('"')] = 1; - data[static_cast ('\\')] = 1; - } - }; - - constexpr EscapedTable escapedLookup{}; - - struct alignas (64) WhitespaceTable - { - uint8_t data[256]; - - constexpr WhitespaceTable () - : data{} - { - data[static_cast ('\t')] = 1; - data[static_cast ('\n')] = 1; - data[static_cast ('\r')] = 1; - data[static_cast (' ')] = 1; - } - }; - - constexpr WhitespaceTable whitespaceLookup{}; - } - /** * @brief string probe. */ @@ -262,145 +223,21 @@ namespace dconv } /** - * @brief read characters until escaped, without copying them. - * @return characters read. - */ - inline std::string_view readUntilEscaped () noexcept - { - const char* beg = _cur; - const char* cur = _cur; - const char* end = _end; - - while (end - cur >= 8) - { - uint64_t word, quote, backslash; - std::memcpy (&word, cur, 8); - quote = word ^ 0x2222222222222222ULL; - backslash = word ^ 0x5C5C5C5C5C5C5C5CULL; - uint64_t mask = - (((quote - 0x0101010101010101ULL) & ~quote) | ((backslash - 0x0101010101010101ULL) & ~backslash) | - ((word - 0x2020202020202020ULL) & ~word)) & - 0x8080808080808080ULL; - if (mask) - { - cur += __builtin_ctzll (mask) >> 3; - break; - } - cur += 8; - } - - while (cur < end && !details::escapedLookup.data[static_cast (*cur)]) - { - ++cur; - } - - _cur = cur; - return std::string_view (beg, static_cast (cur - beg)); - } - - /** - * @brief read characters until escaped. - * @param out output buffer. - */ - inline void readUntilEscaped (std::string& out) noexcept - { - out.append (readUntilEscaped ()); - } - - /** - * @brief skip whitespaces. - * @return 0 on success, -1 otherwise. - */ - inline int skipWhitespaces () noexcept - { - const char* cur = _cur; - const char* end = _end; - - while (cur < end && details::whitespaceLookup.data[static_cast (*cur)]) - { - ++cur; - - uint64_t word; - while ((end - cur >= 8) && (std::memcpy (&word, cur, 8), word == 0x2020202020202020ULL)) - { - cur += 8; - } - } - - _cur = cur; - - return 0; - } - - /** - * @brief skip whitespaces and comments. - * @return 0 on success, -1 otherwise. + * @brief get input position indicator. + * @return current position. */ - inline int skipWhitespacesAndComments () noexcept + inline ProbePos tell () const noexcept { - const char* cur = _cur; - const char* end = _end; - - while (cur < end) - { - while (cur < end && details::whitespaceLookup.data[static_cast (*cur)]) - { - ++cur; - } - - if (cur >= end || *cur != '/') - { - break; - } - - if (++cur >= end) - { - return -1; - } - - if (*cur == '*') - { - ++cur; - bool closed = false; - while (cur < end) - { - if (*cur == '*' && (cur + 1 < end) && *(cur + 1) == '/') - { - cur += 2; - closed = true; - break; - } - ++cur; - } - if (!closed) - { - return -1; - } - } - else if (*cur == '/') - { - ++cur; - const char* p = static_cast (memchr (cur, '\n', end - cur)); - cur = p ? p : end; - } - else - { - return -1; - } - } - - _cur = cur; - - return 0; + return _cur; } /** - * @brief get input position indicator. - * @return current position. + * @brief get end position indicator. + * @return end position. */ - inline ProbePos tell () const noexcept + inline ProbePos end () const noexcept { - return _cur; + return _end; } /** @@ -560,103 +397,6 @@ namespace dconv return _in->sgetn (buf, count); } - /** - * @brief read characters until escaped. - * @param out output buffer. - */ - inline void readUntilEscaped (std::string& out) noexcept - { - int c; - while ((c = _in->sgetc ()) != std::char_traits::eof () && - !details::escapedLookup.data[static_cast (c)]) - { - out.push_back (static_cast (c)); - _in->sbumpc (); - } - } - - /** - * @brief skip whitespaces. - * @return 0 on success, -1 otherwise. - */ - inline int skipWhitespaces () noexcept - { - int c; - while ((c = _in->sgetc ()) != std::char_traits::eof () && - details::whitespaceLookup.data[static_cast (c)]) - { - _in->sbumpc (); - } - - return 0; - } - - /** - * @brief skip whitespaces and comments. - * @return 0 on success, -1 otherwise. - */ - inline int skipWhitespacesAndComments () noexcept - { - int c; - - while ((c = _in->sgetc ()) != std::char_traits::eof ()) - { - while ((c = _in->sgetc ()) != std::char_traits::eof () && - details::whitespaceLookup.data[static_cast (c)]) - { - _in->sbumpc (); - } - - if (c != '/') - { - break; - } - - _in->sbumpc (); - c = _in->sgetc (); - - if (c == std::char_traits::eof ()) - { - return -1; - } - - if (c == '*') - { - _in->sbumpc (); - bool closed = false; - - while ((c = _in->sbumpc ()) != std::char_traits::eof ()) - { - if (c == '*' && _in->sgetc () == '/') - { - _in->sbumpc (); - closed = true; - break; - } - } - - if (!closed) - { - return -1; - } - } - else if (c == '/') - { - _in->sbumpc (); - - while ((c = _in->sbumpc ()) != std::char_traits::eof () && c != '\n') - { - } - } - else - { - return -1; - } - } - - return 0; - } - private: /// input stream buffer. std::streambuf* _in; diff --git a/dconv/tests/stream_probe_test.cpp b/dconv/tests/stream_probe_test.cpp index bf6825f..2cd223a 100644 --- a/dconv/tests/stream_probe_test.cpp +++ b/dconv/tests/stream_probe_test.cpp @@ -167,77 +167,6 @@ TEST (StreamProbe, read) ASSERT_EQ (probe.read (buf, 8), 0); } -/** - * @brief readUntilEscaped test. - */ -TEST (StreamProbe, readUntilEscaped) -{ - std::stringstream msg ("hello\"world"); - StreamProbe probe (msg); - std::string out; - - probe.readUntilEscaped (out); - ASSERT_EQ (out, "hello"); - ASSERT_EQ (probe.peek (), '"'); -} - -/** - * @brief skipWhitespaces test. - */ -TEST (StreamProbe, skipWhitespaces) -{ - std::stringstream msg (" hello"); - StreamProbe probe (msg); - std::string out; - - probe.skipWhitespaces (); - ASSERT_EQ (probe.peek (), 'h'); -} - -/** - * @brief skipWhitespacesAndComments test. - */ -TEST (StreamProbe, skipWhitespacesAndComments) -{ - std::stringstream msg (" // comment\nhello"); - StreamProbe probe1 (msg); - ASSERT_EQ (probe1.skipWhitespacesAndComments (), 0); - ASSERT_EQ (probe1.peek (), 'h'); - - msg.str (" /* comment */hello"); - msg.clear (); - StreamProbe probe2 (msg); - ASSERT_EQ (probe2.skipWhitespacesAndComments (), 0); - ASSERT_EQ (probe2.peek (), 'h'); - - msg.str ("// comment"); - msg.clear (); - StreamProbe probe3 (msg); - ASSERT_EQ (probe3.skipWhitespacesAndComments (), 0); - ASSERT_EQ (probe3.peek (), std::char_traits::eof ()); - - msg.str ("/* comment */"); - msg.clear (); - StreamProbe probe4 (msg); - ASSERT_EQ (probe4.skipWhitespacesAndComments (), 0); - ASSERT_EQ (probe4.peek (), std::char_traits::eof ()); - - msg.str ("/"); - msg.clear (); - StreamProbe probe5 (msg); - ASSERT_EQ (probe5.skipWhitespacesAndComments (), -1); - - msg.str ("/*"); - msg.clear (); - StreamProbe probe6 (msg); - ASSERT_EQ (probe6.skipWhitespacesAndComments (), -1); - - msg.str ("/!"); - msg.clear (); - StreamProbe probe7 (msg); - ASSERT_EQ (probe7.skipWhitespacesAndComments (), -1); -} - /** * @brief main function. */ diff --git a/dconv/tests/string_probe_test.cpp b/dconv/tests/string_probe_test.cpp index 169cce8..27f9c3c 100644 --- a/dconv/tests/string_probe_test.cpp +++ b/dconv/tests/string_probe_test.cpp @@ -189,74 +189,16 @@ TEST (StringProbe, read) } /** - * @brief readUntilEscaped test. + * @brief end test. */ -TEST (StringProbe, readUntilEscaped) +TEST (StringProbe, end) { - StringProbe probe ("hello\"world"); - std::string out; - - probe.readUntilEscaped (out); - ASSERT_EQ (out, "hello"); - ASSERT_EQ (probe.peek (), '"'); - - probe = StringProbe ("hello wonderful world\\"); - out.clear (); - probe.readUntilEscaped (out); - ASSERT_EQ (out, "hello wonderful world"); - ASSERT_EQ (probe.peek (), '\\'); - - probe = StringProbe ("abc"); - out.clear (); - probe.readUntilEscaped (out); - ASSERT_EQ (out, "abc"); - ASSERT_EQ (probe.peek (), std::char_traits::eof ()); -} + const char* text = "hello"; + StringProbe probe (text); -/** - * @brief skipWhitespaces test. - */ -TEST (StringProbe, skipWhitespaces) -{ - StringProbe probe (" hello"); - - probe.skipWhitespaces (); - ASSERT_EQ (probe.peek (), 'h'); - - probe = StringProbe ("\t hello"); - probe.skipWhitespaces (); - ASSERT_EQ (probe.peek (), 'h'); -} - -/** - * @brief skipWhitespacesAndComments test. - */ -TEST (StringProbe, skipWhitespacesAndComments) -{ - StringProbe probe (" // comment\nhello"); - ASSERT_EQ (probe.skipWhitespacesAndComments (), 0); - ASSERT_EQ (probe.peek (), 'h'); - - probe = StringProbe (" /* comment */hello"); - ASSERT_EQ (probe.skipWhitespacesAndComments (), 0); - ASSERT_EQ (probe.peek (), 'h'); - - probe = StringProbe ("// comment"); - ASSERT_EQ (probe.skipWhitespacesAndComments (), 0); - ASSERT_EQ (probe.peek (), std::char_traits::eof ()); - - probe = StringProbe ("/* comment */"); - ASSERT_EQ (probe.skipWhitespacesAndComments (), 0); - ASSERT_EQ (probe.peek (), std::char_traits::eof ()); - - probe = StringProbe ("/"); - ASSERT_EQ (probe.skipWhitespacesAndComments (), -1); - - probe = StringProbe ("/*"); - ASSERT_EQ (probe.skipWhitespacesAndComments (), -1); - - probe = StringProbe ("/!"); - ASSERT_EQ (probe.skipWhitespacesAndComments (), -1); + ASSERT_EQ (probe.end (), text + 5); + probe.get (); + ASSERT_EQ (probe.end (), text + 5); } /** diff --git a/doxyfile b/doxyfile index 403e9d3..6939ab0 100644 --- a/doxyfile +++ b/doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = "dconv" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.1 +PROJECT_NUMBER = 1.2 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/eisellemirepowgen/CMakeLists.txt b/tools/eisellemirepowgen/CMakeLists.txt index 007c6bc..d9e01be 100644 --- a/tools/eisellemirepowgen/CMakeLists.txt +++ b/tools/eisellemirepowgen/CMakeLists.txt @@ -32,4 +32,4 @@ set_target_properties(eisellemirepowgen PROPERTIES PUBLIC_HEADER "${PUBLIC_HEADE target_include_directories(eisellemirepowgen PUBLIC ${PUBLIC_HEADER_DIRS}) target_include_directories(eisellemirepowgen PRIVATE ${PRIVATE_HEADER_DIRS}) -install(TARGETS eisellemirepowgen DESTINATION /bin) +install(TARGETS eisellemirepowgen DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/tools/grisupowgen/CMakeLists.txt b/tools/grisupowgen/CMakeLists.txt index 0c0bd79..3531bbf 100644 --- a/tools/grisupowgen/CMakeLists.txt +++ b/tools/grisupowgen/CMakeLists.txt @@ -32,4 +32,4 @@ set_target_properties(grisupowgen PROPERTIES PUBLIC_HEADER "${PUBLIC_HEADERS}") target_include_directories(grisupowgen PUBLIC ${PUBLIC_HEADER_DIRS}) target_include_directories(grisupowgen PRIVATE ${PRIVATE_HEADER_DIRS}) -install(TARGETS grisupowgen DESTINATION /bin) +install(TARGETS grisupowgen DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/tools/schubfachpowgen/CMakeLists.txt b/tools/schubfachpowgen/CMakeLists.txt index cbc4ab4..e43658a 100644 --- a/tools/schubfachpowgen/CMakeLists.txt +++ b/tools/schubfachpowgen/CMakeLists.txt @@ -32,4 +32,4 @@ set_target_properties(schubfachpowgen PROPERTIES PUBLIC_HEADER "${PUBLIC_HEADERS target_include_directories(schubfachpowgen PUBLIC ${PUBLIC_HEADER_DIRS}) target_include_directories(schubfachpowgen PRIVATE ${PRIVATE_HEADER_DIRS}) -install(TARGETS schubfachpowgen DESTINATION /bin) +install(TARGETS schubfachpowgen DESTINATION ${CMAKE_INSTALL_BINDIR})