diff --git a/luprex/cpp/core/enginewrapper.hpp b/luprex/cpp/core/enginewrapper.hpp index 8cd482e2..fee34661 100644 --- a/luprex/cpp/core/enginewrapper.hpp +++ b/luprex/cpp/core/enginewrapper.hpp @@ -248,7 +248,7 @@ struct EngineWrapper { // void (*hook_dprint)(void (*func)(const char *oneline, size_t size)); - // Restore the wrapper to its initial blank state. + // Release: delete the engine object and close log files. // // Note that the wrapper must have already been initialized using // init_engine_wrapper. Otherwise, the 'release' function pointer would not diff --git a/luprex/cpp/drv/drvutil.cpp b/luprex/cpp/drv/drvutil.cpp index c4bbf273..7ab53739 100644 --- a/luprex/cpp/drv/drvutil.cpp +++ b/luprex/cpp/drv/drvutil.cpp @@ -194,6 +194,30 @@ std::u32string from_utf8(std::string_view s, int *consumed) { return result.substr(0, len); } +std::u16string utf8_to_ucs2(std::string_view s, int *consumed) { + std::string_view rest = s; + std::u16string result(s.size(), 0); + int len = 0; + while (true) { + int32_t c = read_codepoint_utf8(rest); + if (c == -1) { + break; // EOF reached; + } else if (c < 0) { + rest.remove_prefix(1); + } else if ((c >= 0xD800) && (c <= 0xDFFF)) { + result[len++] = 0x2610; + } else if (c > 0xFFFF) { + result[len++] = 0x2610; + } else { + result[len++] = (char16_t)c; + } + } + if (consumed != nullptr) { + *consumed = s.size() - rest.size(); + } + return result.substr(0, len); +} + static std::vector parse_control_lst(std::string_view ctrl) { std::vector result; while (!ctrl.empty()) { diff --git a/luprex/cpp/drv/drvutil.hpp b/luprex/cpp/drv/drvutil.hpp index 364db007..5ef8484b 100644 --- a/luprex/cpp/drv/drvutil.hpp +++ b/luprex/cpp/drv/drvutil.hpp @@ -63,6 +63,10 @@ std::string to_utf8(const std::u32string &cps); // std::u32string from_utf8(std::string_view source, int *consumed); +// Convert a UTF8 string to a UCS-2 string. +// +std::u16string utf8_to_ucs2(std::string_view source, int *consumed); + // Get a system error message, in an OS-independent manner. // // These versions of strerror is thread-safe, and it never fails