#!/usr/bin/env python3 """Run the production conversion function with a controlled Windows API stub. This host check compiles only Utf8FromUtf16 from utils.cpp. It checks API arguments, counts, and failure handling using 16-bit wchar_t and known UTF-16/UTF-8 data. It does not build the Windows runner or validate Windows' Unicode implementation. """ import argparse from pathlib import Path import subprocess PREFIX = r""" #include #include #include static_assert(sizeof(wchar_t) == 2, "test requires UTF-16 code units"); constexpr unsigned CP_UTF8 = 65001; constexpr unsigned WC_ERR_INVALID_CHARS = 0x80; static const wchar_t* expected_source; static std::string expected_utf8; static int query_result; static int conversion_result; static int calls; int WideCharToMultiByte(unsigned code_page, unsigned flags, const wchar_t* source, int input_length, char* target, int capacity, const char* default_char, int* used_default_char) { ++calls; assert(code_page == CP_UTF8 && flags == WC_ERR_INVALID_CHARS); assert(source == expected_source && input_length == -1); assert(default_char == nullptr && used_default_char == nullptr); if (target == nullptr) { assert(calls == 1 && capacity == 0); return query_result; } assert(calls == 2 && capacity == query_result); assert(capacity == static_cast(expected_utf8.size()) + 1); std::memcpy(target, expected_utf8.c_str(), expected_utf8.size() + 1); return conversion_result; } """ SUFFIX = r""" void configure(const wchar_t* source, const std::string& expected, int query, int converted) { expected_source = source; expected_utf8 = expected; query_result = query; conversion_result = converted; calls = 0; } int main() { assert(Utf8FromUtf16(nullptr).empty()); assert(calls == 0); const wchar_t empty[] = {0}; configure(empty, "", 1, 1); assert(Utf8FromUtf16(empty).empty()); assert(calls == 2); // Independent known encoding: A, U+00E9, U+1F642 (a surrogate pair). const wchar_t text[] = {0x0041, 0x00e9, 0xd83d, 0xde42, 0}; const std::string utf8 = "A\xc3\xa9\xf0\x9f\x99\x82"; configure(text, utf8, 8, 8); assert(Utf8FromUtf16(text) == utf8); assert(calls == 2); // WC_ERR_INVALID_CHARS reports an isolated surrogate as a zero query result. const wchar_t invalid[] = {0xd800, 0}; for (int failed : {0, -1}) { configure(invalid, "", failed, 0); assert(Utf8FromUtf16(invalid).empty()); assert(calls == 1); } for (int failed_or_mismatched : {0, -1, 7, 9}) { configure(text, utf8, 8, failed_or_mismatched); assert(Utf8FromUtf16(text).empty()); assert(calls == 2); } } """ def main(): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--work-dir", type=Path, required=True) parser.add_argument("--cxx", default="c++") args = parser.parse_args() work = args.work_dir.resolve() work.mkdir(parents=True, exist_ok=True) source = Path(__file__).with_name("utils.cpp").read_text() start = source.index("std::string Utf8FromUtf16(") end = source.index("\n}", start) + 2 fixture = work / "utf8_from_utf16.cpp" fixture.write_text(PREFIX + source[start:end] + SUFFIX) binary = work / "utf8_from_utf16_test" subprocess.run( [ args.cxx, "-std=c++17", "-fshort-wchar", "-Wall", "-Wextra", "-Werror", "-pedantic", str(fixture), "-o", str(binary), ], check=True, ) subprocess.run([str(binary)], check=True) print("Utf8FromUtf16 host stub checks passed (9 cases, 16-bit wchar_t)") if __name__ == "__main__": main()