#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 件のコメント:
コメントを投稿