Replaced the usage of ReadConsoleInputW and fgetwc with standard C++ input functions to make getchar32() work consistently in all environments, including cases when stdin is redirected.
The previous implementation of getchar32() relied on low-level console functions, which caused issues when running the code in subprocesses with redirected stdin. The ReadConsoleInputW function is designed to read from the console input buffer and may not function correctly with input redirection. Additionally, using fgetwc in a Windows environment could lead to potential issues in certain scenarios. I encountered unexpected results when redirecting stdin, even without passing any argument. To replicate the issue, try the following command in your C# code: ``` ProcessStartInfo startInfo = new() { FileName = ".\\main.exe", Arguments = "-m .\\7b-q4.bin -n 256 --repeat_penalty 1.0 --interactive-first -r \"User:\" -f .\\chat-with-bob.txt", RedirectStandardOutput = true, RedirectStandardInput = true, UseShellExecute = false, CreateNoWindow = true }; ``` To address this problem and enable people to stream the program directly to a UI without worrying about the C++ part, I made the following changes: - Replaced ReadConsoleInputW with std::getwchar(), a standard C++ input function that reads wide characters from std::wcin. This change allows getchar32() to handle both console and redirected stdin scenarios consistently. With these modifications, getchar32() now functions as intended in various environments and ensures that console interactions work correctly, even when stdin is redirected.
This commit is contained in:
parent
86aeb27734
commit
5b61ec41e0
1 changed files with 12 additions and 20 deletions
|
@ -778,34 +778,26 @@ void console_set_color(console_state & con_st, console_color_t color) {
|
|||
|
||||
char32_t getchar32() {
|
||||
#if defined(_WIN32)
|
||||
HANDLE hConsole = GetStdHandle(STD_INPUT_HANDLE);
|
||||
wchar_t high_surrogate = 0;
|
||||
|
||||
while (true) {
|
||||
INPUT_RECORD record;
|
||||
DWORD count;
|
||||
if (!ReadConsoleInputW(hConsole, &record, 1, &count) || count == 0) {
|
||||
wint_t wc = std::getwchar(); // Use std::getwchar() to read a wide character from std::wcin
|
||||
|
||||
if (wc == WEOF) {
|
||||
return WEOF;
|
||||
}
|
||||
|
||||
if (record.EventType == KEY_EVENT && record.Event.KeyEvent.bKeyDown) {
|
||||
wchar_t wc = record.Event.KeyEvent.uChar.UnicodeChar;
|
||||
if (wc == 0) {
|
||||
continue;
|
||||
if ((wc >= 0xD800) && (wc <= 0xDBFF)) { // Check if wc is a high surrogate
|
||||
high_surrogate = wc;
|
||||
continue;
|
||||
} else if ((wc >= 0xDC00) && (wc <= 0xDFFF)) { // Check if wc is a low surrogate
|
||||
if (high_surrogate != 0) { // Check if we have a high surrogate
|
||||
return ((high_surrogate - 0xD800) << 10) + (wc - 0xDC00) + 0x10000;
|
||||
}
|
||||
|
||||
if ((wc >= 0xD800) && (wc <= 0xDBFF)) { // Check if wc is a high surrogate
|
||||
high_surrogate = wc;
|
||||
continue;
|
||||
} else if ((wc >= 0xDC00) && (wc <= 0xDFFF)) { // Check if wc is a low surrogate
|
||||
if (high_surrogate != 0) { // Check if we have a high surrogate
|
||||
return ((high_surrogate - 0xD800) << 10) + (wc - 0xDC00) + 0x10000;
|
||||
}
|
||||
}
|
||||
|
||||
high_surrogate = 0; // Reset the high surrogate
|
||||
return static_cast<char32_t>(wc);
|
||||
}
|
||||
|
||||
high_surrogate = 0; // Reset the high surrogate
|
||||
return static_cast<char32_t>(wc);
|
||||
}
|
||||
#else
|
||||
wchar_t wc = getwchar();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue