Skip to content

Replace POSIX getline with std::getline#184

Open
etorth wants to merge 4 commits into
libpinyin:mainfrom
etorth:main
Open

Replace POSIX getline with std::getline#184
etorth wants to merge 4 commits into
libpinyin:mainfrom
etorth:main

Conversation

@etorth

@etorth etorth commented Jun 17, 2026

Copy link
Copy Markdown

Use C++ standard stream-based line reading in tests and utilities so the code does not depend on POSIX getline availability on MinGW UCRT64.

Refs #183.

Use C++ standard stream-based line reading in tests and utilities so the code does not depend on POSIX getline availability on MinGW UCRT64.

Refs libpinyin#183.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@etorth etorth closed this Jun 19, 2026
@etorth etorth reopened this Jun 19, 2026
etorth and others added 3 commits June 19, 2026 02:14
The libpinyin model tables are UTF-8 text files with ASCII field separators. Parsing them with fscanf("%s") is not safe after gen_binary_files calls setlocale(LC_ALL, ""), because the C runtime decides what counts as whitespace according to the active locale.

On MinGW/UCRT this can split a UTF-8 Chinese character in the middle. One failing case is the valid source row:

    lao    唠    16782070    477

where 唠 is encoded as E5 94 A0. In the MinGW build log, ChewingLargeTable2::load_text reported the phrase as truncated bytes:

    ChewingLargeTable2::load_text:lao    E5 94    16782070    477

That shows UCRT treated the 0xA0 byte inside the UTF-8 sequence as whitespace. The phrase then becomes invalid UTF-8, so g_utf8_strlen() and the parsed pinyin key count no longer match. The result is not only noisy diagnostics: the generated indexes can miss or corrupt entries. Native Linux does not show this because glibc's UTF-8 locale does not classify those high UTF-8 bytes as whitespace.

Use line-based table parsing so field boundaries are determined by the model file format rather than CRT locale behavior. This also avoids the old %ld conversion into size_t, which is incorrect on Windows LLP64.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
MemoryChunk::load("gb_char.bin") fails with "load gb_char.bin failed!" after gen_binary_files writes gb_char.bin and import_interpolation reads it back.

On MinGW, open() defaults to text mode. MemoryChunk::save() wrote binary table data without O_BINARY, so LF bytes in the payload were expanded to CRLF. MemoryChunk::load() then saw a payload whose actual size/checksum no longer matched the stored header and rejected it as corrupted.

The generated file showed file_size=2979848, header_len=2972089, actual_data_len=2979840, difference=7751, and crlf_pairs_in_payload=7751. The exact match between the size difference and CRLF pairs proves text-mode newline expansion caused the corruption.

Use O_BINARY for MemoryChunk load and save paths, defining it as 0 when unavailable. This fixes MinGW while leaving Linux and macOS behavior unchanged.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@epico

epico commented Jun 22, 2026

Copy link
Copy Markdown
Member

Could you make the second and third commit message shorter?

I understand the issues now, maybe you can put the details of the commit messages into this pull request or the previous issue.

For the O_BINARY macro, how about to use the following code snippet?

int flags = O_RDONLY;

#ifdef _WIN32
flags |= O_BINARY;
#endif

int fd = open(filename, flags);

@etorth

etorth commented Jun 22, 2026

Copy link
Copy Markdown
Author

Could you make the second and third commit message shorter?

I understand the issues now, maybe you can put the details of the commit messages into this pull request or the previous issue.

For the O_BINARY macro, how about to use the following code snippet?

int flags = O_RDONLY;

#ifdef _WIN32
flags |= O_BINARY;
#endif

int fd = open(filename, flags);

Let me make sure the main project build passes before focusing on this libpinyin PR.
It's still a work in progress, I'll batch this with any other issues that pop up later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants