diff --git a/examples/main/main.cpp b/examples/main/main.cpp index c8ea6eb..7be8944 100644 --- a/examples/main/main.cpp +++ b/examples/main/main.cpp @@ -26,6 +26,43 @@ static void sigint_handler(int signo) { } #endif +static bool readline_utf8(std::string & line, bool multiline_input) { +#if defined(_WIN32) + std::wstring wline; + if (!std::getline(std::wcin, wline)) { + // Input stream is bad or EOF received + line.clear(); + GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0); + return false; + } + + int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wline[0], (int)wline.size(), NULL, 0, NULL, NULL); + line.resize(size_needed); + WideCharToMultiByte(CP_UTF8, 0, &wline[0], (int)wline.size(), &line[0], size_needed, NULL, NULL); +#else + if (!std::getline(std::cin, line)) { + // Input stream is bad or EOF received + line.clear(); + return false; + } +#endif + if (!line.empty()) { + char last = line.back(); + if (last == '/') { // Always return control on '/' symbol + line.pop_back(); + return false; + } + if (last == '\\') { // '\\' changes the default action + line.pop_back(); + multiline_input = !multiline_input; + } + } + line += '\n'; + + // By default, continue input if multiline_input is set + return multiline_input; +} + int main() { // ctrl+C handling @@ -41,6 +78,9 @@ int main() { return (ctrl_type == CTRL_C_EVENT) ? (sigint_handler(SIGINT), true) : false; }; SetConsoleCtrlHandler(reinterpret_cast(console_ctrl_handler), true); + SetConsoleCP(CP_UTF8); + SetConsoleOutputCP(CP_UTF8); + _setmode(_fileno(stdin), _O_WTEXT); // wide character input mode #endif } @@ -54,8 +94,8 @@ int main() { std::cout << "Enter your prompt (or 'exit' to quit): "; } std::string prompt; - std::getline(std::cin, prompt); - if (prompt == "exit") { + readline_utf8(prompt, false); + if (prompt == "exit" || prompt == "exit\n") { logger->info("Goodbye!"); break; } diff --git a/examples/plan/humanus_plan.cpp b/examples/plan/humanus_plan.cpp index 3091259..0e8f61a 100644 --- a/examples/plan/humanus_plan.cpp +++ b/examples/plan/humanus_plan.cpp @@ -26,6 +26,43 @@ static void sigint_handler(int signo) { } #endif +static bool readline_utf8(std::string & line, bool multiline_input) { +#if defined(_WIN32) + std::wstring wline; + if (!std::getline(std::wcin, wline)) { + // Input stream is bad or EOF received + line.clear(); + GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0); + return false; + } + + int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wline[0], (int)wline.size(), NULL, 0, NULL, NULL); + line.resize(size_needed); + WideCharToMultiByte(CP_UTF8, 0, &wline[0], (int)wline.size(), &line[0], size_needed, NULL, NULL); +#else + if (!std::getline(std::cin, line)) { + // Input stream is bad or EOF received + line.clear(); + return false; + } +#endif + if (!line.empty()) { + char last = line.back(); + if (last == '/') { // Always return control on '/' symbol + line.pop_back(); + return false; + } + if (last == '\\') { // '\\' changes the default action + line.pop_back(); + multiline_input = !multiline_input; + } + } + line += '\n'; + + // By default, continue input if multiline_input is set + return multiline_input; +} + int main() { // ctrl+C handling @@ -41,6 +78,9 @@ int main() { return (ctrl_type == CTRL_C_EVENT) ? (sigint_handler(SIGINT), true) : false; }; SetConsoleCtrlHandler(reinterpret_cast(console_ctrl_handler), true); + SetConsoleCP(CP_UTF8); + SetConsoleOutputCP(CP_UTF8); + _setmode(_fileno(stdin), _O_WTEXT); // wide character input mode #endif } @@ -73,8 +113,8 @@ int main() { } std::string prompt; - std::getline(std::cin, prompt); - if (prompt == "exit") { + readline_utf8(prompt, false); + if (prompt == "exit" || prompt == "exit\n") { logger->info("Goodbye!"); break; }