#ifdef _MSC_VER TEST(Japanese, テスト) { FAIL() << "テスト"; } #endif
出力されたXML
<testsuite name="Japanese" tests="1" failures="1" disabled="0" errors="0" time="0.001"> <testcase name="eXg" status="run" time="0" classname="Japanese"> <failure message="Failed" type=""><![CDATA[samples.cpp:16 Failed]]></failure> </testcase> </testsuite>
FAIL() で出力した「テスト」メッセージも無き者にされてしまっています。
今回は日本語出力ができるようにソースコードを変更します。
改変
文字コード変換
まずは、MBS を UTF-8 に変換します。(XML が UTF-8 で出力しているので)幸い、ワイド文字列から UTF-8 への変換関数はあるのでそちらを利用します。
gtest.cc
--- src.orig/gtest.cc 2011-04-15 12:49:12.000000000 +0900 +++ src/gtest.cc 2012-09-18 21:50:15.185407700 +0900 @@ -1525,6 +1525,27 @@ return StringStreamToString(&stream); } +String MultiByteStringToUtf8(const char* str, int num_chars) { + if (num_chars == -1) + num_chars = static_cast<int>(strlen(str)); + + ::std::stringstream stream; + for (int i = 0; i < num_chars; ++i) { + wchar_t wc=0; + int len = mbtowc(&wc, str+i, MB_CUR_MAX); + if( len > 1 ) + { + stream << WideStringToUtf8(&wc, 1); + i += len-1; + } + else + { + stream << str[i]; + } + } + return StringStreamToString(&stream); +} + // Converts a wide C string to a String using the UTF-8 encoding. // NULL will be converted to "(null)". String String::ShowWideCString(const wchar_t * wide_c_str) {
--- src.orig/gtest-internal-inl.h 2011-04-15 12:49:12.000000000 +0900 +++ src/gtest-internal-inl.h 2012-09-18 21:48:43.489163000 +0900 @@ -221,6 +221,7 @@ // (i.e. outside of Unicode range U+0 to U+10FFFF) it will be output // as '(Invalid Unicode 0xXXXXXXXX)'. GTEST_API_ char* CodePointToUtf8(UInt32 code_point, char* str); +GTEST_API_ String MultiByteStringToUtf8(const char* str, int num_chars); // Converts a wide string to a narrow string in UTF-8 encoding. // The wide string is assumed to have the following encoding:
XML の処理を修正
XML に出力するか判断する前に UTF-8 に変換しておきます。@@ -3124,6 +3145,9 @@ String XmlUnitTestResultPrinter::EscapeXml(const char* str, bool is_attribute) { Message m; + String tmp = MultiByteStringToUtf8(str, -1); + str = tmp.c_str(); + if (str != NULL) { for (const char* src = str; *src; ++src) { switch (*src) {
@@ -3255,7 +3279,8 @@ << "\" type=\"\">"; const string location = internal::FormatCompilerIndependentFileLocation( part.file_name(), part.line_number()); - const string message = location + "\n" + part.message(); + const string message_raw = location + "\n" + part.message(); + const string message = MultiByteStringToUtf8(message_raw.c_str(), -1); OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(message).c_str()); *stream << "</failure>\n";
先行バイトを許可する
最後に先行バイトを許可します。(厳密にやるなら本当に先行バイトかどうか、後続バイトも調べるべきかも)
@@ -3022,7 +3043,7 @@ // May c appear in a well-formed XML document? static bool IsValidXmlCharacter(char c) { - return IsNormalizableWhitespace(c) || c >= 0x20; + return IsNormalizableWhitespace(c) || c >= 0x20 || c < 0x00; } // Returns an XML-escaped copy of the input string str. If
テスト側の修正
テストを実行する前に、setlocale( LC_ALL, "" ); をしてください。Visual Studio だと、起動時に setlocale( LC_ALL, "C" ); を実行するので、
mbtowc が期待どおりに動作しません。
以上で、日本語も XML に出力できるようになるはずです。
ソース/パッチ
github で公開してます。
0 件のコメント:
コメントを投稿