From 1fde16fb2dd10e363a7ab70c6c33cbee2ad1ad43 Mon Sep 17 00:00:00 2001 From: Adam Wardynski <award@.(win7-laptop)> Date: Thu, 16 Dec 2010 20:59:32 +0100 Subject: [PATCH] Unicode support reading from Win Console in wcclparser tool. --- wcclparser/main.cpp | 106 ++++++++++++++++++++++++++++++++------------ 1 file changed, 78 insertions(+), 28 deletions(-) diff --git a/wcclparser/main.cpp b/wcclparser/main.cpp index cd00f57..6eea080 100644 --- a/wcclparser/main.cpp +++ b/wcclparser/main.cpp @@ -19,42 +19,26 @@ #include <histedit.h> #endif +#ifdef _WINDOWS +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#endif + /** * @desc A simple command line tester for testing operators */ - namespace { const char* _prompt = "Enter any operator expression: "; } -void std_read_loop(boost::function<bool (const std::string&)>& line_cb) -{ - while (std::cin.good()) { - std::cout << _prompt << std::flush; - std::string s; - getline(std::cin, s); - if (line_cb(s)) { - return; - } - } -} +#if defined(HAVE_LIBEDIT) && !defined(_WINDOWS) //non-Windows libedit read loop -int clear_screen() -{ -#ifdef _WINDOWS - return std::system("cls"); -#else - return std::system("clear"); -#endif -} - -#ifdef HAVE_LIBEDIT const char* query_prompt(EditLine*) { return _prompt; } -void libedit_read_loop(boost::function<bool (const std::string&)>& line_cb) +void read_loop(boost::function<bool (const std::string&)>& line_cb) { EditLine *el = el_init("wccl-parser", stdin, stdout, stderr); el_set(el, EL_PROMPT, &query_prompt); @@ -89,7 +73,77 @@ void libedit_read_loop(boost::function<bool (const std::string&)>& line_cb) history_end(myhistory); el_end(el); } + +#elif defined(_WINDOWS) // windows console read loop, doing UNICODE + +struct ConsoleCPSetter +{ + UINT original_CP; + ConsoleCPSetter(UINT cp) { + original_CP = GetConsoleCP(); + SetConsoleCP(cp); + } + ~ConsoleCPSetter() { + SetConsoleCP(original_CP); + } +}; + +void read_loop(boost::function<bool (const std::string&)>& line_cb) +{ + HANDLE stdinhandle = GetStdHandle(STD_INPUT_HANDLE); + WCHAR buffer[1024]; + const int max = sizeof(buffer)/sizeof(WCHAR) - 1; + ConsoleCPSetter cp(CP_UTF8); + bool more = true; + while(more) { + std::cout << _prompt << std::flush; + std::wstring s; + while(more) { + DWORD read; + if (ReadConsoleW(stdinhandle, buffer, max, &read, NULL)) { + buffer[read] = NULL; + while(buffer[read - 1] == L'\n' || buffer[read - 1] == L'\r') { + buffer[--read] = 0; + } + more = (read == max); + s += buffer; + } else { + if (GetLastError() == ERROR_INVALID_HANDLE) { + // assume stdin redirect, fallback to standard getline + getline(std::wcin, s); + } + more = false; + } + } + UnicodeString us(s.c_str()); + more = !line_cb(PwrNlp::to_utf8(us)); + } +} + +#else // standard io read loop + +void read_loop(boost::function<bool (const std::string&)>& line_cb) +{ + while (std::cin.good()) { + std::cout << _prompt << std::flush; + std::string s; + getline(std::cin, s); + if (line_cb(s)) { + return; + } + } +} + +#endif + +int clear_screen() +{ +#ifdef _WINDOWS + return std::system("cls"); +#else + return std::system("clear"); #endif +} bool process_line(const std::string& line, Wccl::Parser& parser, Wccl::SentenceContext& sc, bool all_positions, bool dump_variables) @@ -247,11 +301,7 @@ int main(int argc, char** argv) boost::function<bool (const std::string&)> f; f = boost::bind(&process_line, _1, boost::ref(parser), boost::ref(sc), position == "all", dump_variables); -#ifdef HAVE_LIBEDIT - libedit_read_loop(f); -#else - std_read_loop(f); -#endif + read_loop(f); } catch (PwrNlp::PwrNlpError& e) { std::cerr << e.info() << std::endl; return 2; -- GitLab