Handle quotes in wxTranslateFromUnicodeFormat.

When parsing Unicode date formats text inside single quotes should not be
escaped and instead treated as literal text. In addition two single quotes
(either inside or outside quoted text) should be interpreted as a single
quote.

Fixes #16118.
This commit is contained in:
Dimitri Schoolwerth
2015-04-09 04:39:35 +04:00
parent e44df8e12f
commit adbc9863b2
2 changed files with 103 additions and 9 deletions

View File

@@ -1135,6 +1135,22 @@ wxString wxLocale::GetHeaderValue(const wxString& header,
namespace
{
bool IsAtTwoSingleQuotes(const wxString& fmt, wxString::const_iterator p)
{
if ( p != fmt.end() && *p == '\'')
{
++p;
if ( p != fmt.end() && *p == '\'')
{
return true;
}
}
return false;
}
} // anonymous namespace
// This function translates from Unicode date formats described at
//
// http://unicode.org/reports/tr35/tr35-6.html#Date_Format_Patterns
@@ -1142,7 +1158,7 @@ namespace
// to strftime()-like syntax. This translation is not lossless but we try to do
// our best.
static wxString TranslateFromUnicodeFormat(const wxString& fmt)
wxString wxTranslateFromUnicodeFormat(const wxString& fmt)
{
wxString fmtWX;
fmtWX.reserve(fmt.length());
@@ -1385,6 +1401,49 @@ static wxString TranslateFromUnicodeFormat(const wxString& fmt)
if ( p == fmt.end() )
break;
/*
Handle single quotes:
"Two single quotes represents [sic] a literal single quote, either
inside or outside single quotes. Text within single quotes is not
interpreted in any way (except for two adjacent single quotes)."
*/
if ( IsAtTwoSingleQuotes(fmt, p) )
{
fmtWX += '\'';
++p; // the 2nd single quote is skipped by the for loop's increment
continue;
}
bool isEndQuote = false;
if ( *p == '\'' )
{
++p;
while ( p != fmt.end() )
{
if ( IsAtTwoSingleQuotes(fmt, p) )
{
fmtWX += '\'';
p += 2;
continue;
}
if ( *p == '\'' )
{
isEndQuote = true;
break;
}
fmtWX += *p;
++p;
}
}
if ( p == fmt.end() )
break;
if ( !isEndQuote )
{
// not a special character so must be just a separator, treat as is
if ( *p == wxT('%') )
{
@@ -1394,11 +1453,11 @@ static wxString TranslateFromUnicodeFormat(const wxString& fmt)
fmtWX += *p;
}
}
return fmtWX;
}
} // anonymous namespace
#endif // __WINDOWS__ || __WXOSX__
@@ -1476,7 +1535,7 @@ GetInfoFromLCID(LCID lcid,
if ( ::GetLocaleInfo(lcid, GetLCTYPEFormatFromLocalInfo(index),
buf, WXSIZEOF(buf)) )
{
return TranslateFromUnicodeFormat(buf);
return wxTranslateFromUnicodeFormat(buf);
}
break;
@@ -1630,7 +1689,7 @@ wxString wxLocale::GetInfo(wxLocaleInfo index, wxLocaleCategory WXUNUSED(cat))
wxCFRef<CFDateFormatterRef> dateFormatter( CFDateFormatterCreate
(NULL, userLocaleRef, dateStyle, timeStyle));
wxCFStringRef cfs = wxCFRetain( CFDateFormatterGetFormat(dateFormatter ));
wxString format = TranslateFromUnicodeFormat(cfs.AsString());
wxString format = wxTranslateFromUnicodeFormat(cfs.AsString());
// we always want full years
format.Replace("%y","%Y");
return format;

View File

@@ -232,6 +232,7 @@ private:
CPPUNIT_TEST( TestTimeArithmetics );
CPPUNIT_TEST( TestDSTBug );
CPPUNIT_TEST( TestDateOnly );
CPPUNIT_TEST( TestTranslateFromUnicodeFormat );
CPPUNIT_TEST_SUITE_END();
void TestLeapYears();
@@ -252,6 +253,7 @@ private:
void TestTimeArithmetics();
void TestDSTBug();
void TestDateOnly();
void TestTranslateFromUnicodeFormat();
DECLARE_NO_COPY_CLASS(DateTimeTestCase)
};
@@ -1447,4 +1449,37 @@ void DateTimeTestCase::TestDateOnly()
CPPUNIT_ASSERT_EQUAL( wxDateTime::Today(), wxDateTime::Now().GetDateOnly() );
}
// Forward declaration
wxString wxTranslateFromUnicodeFormat(const wxString& fmt);
void DateTimeTestCase::TestTranslateFromUnicodeFormat()
{
// Test single quote handling...
CPPUNIT_ASSERT_EQUAL("", wxTranslateFromUnicodeFormat("'"));
CPPUNIT_ASSERT_EQUAL("%H", wxTranslateFromUnicodeFormat("H'"));
CPPUNIT_ASSERT_EQUAL("H", wxTranslateFromUnicodeFormat("'H"));
CPPUNIT_ASSERT_EQUAL("'", wxTranslateFromUnicodeFormat("''"));
CPPUNIT_ASSERT_EQUAL("%H'", wxTranslateFromUnicodeFormat("H''"));
CPPUNIT_ASSERT_EQUAL("H", wxTranslateFromUnicodeFormat("'H'"));
CPPUNIT_ASSERT_EQUAL("'%H", wxTranslateFromUnicodeFormat("''H"));
CPPUNIT_ASSERT_EQUAL("'", wxTranslateFromUnicodeFormat("'''"));
CPPUNIT_ASSERT_EQUAL("%H'", wxTranslateFromUnicodeFormat("H'''"));
CPPUNIT_ASSERT_EQUAL("H'", wxTranslateFromUnicodeFormat("'H''"));
CPPUNIT_ASSERT_EQUAL("'%H", wxTranslateFromUnicodeFormat("''H'"));
CPPUNIT_ASSERT_EQUAL("'H", wxTranslateFromUnicodeFormat("'''H"));
CPPUNIT_ASSERT_EQUAL("''", wxTranslateFromUnicodeFormat("''''"));
CPPUNIT_ASSERT_EQUAL("%H''", wxTranslateFromUnicodeFormat("H''''"));
CPPUNIT_ASSERT_EQUAL("H'", wxTranslateFromUnicodeFormat("'H'''"));
CPPUNIT_ASSERT_EQUAL("'%H'", wxTranslateFromUnicodeFormat("''H''"));
CPPUNIT_ASSERT_EQUAL("'H", wxTranslateFromUnicodeFormat("'''H'"));
CPPUNIT_ASSERT_EQUAL("''%H", wxTranslateFromUnicodeFormat("''''H"));
CPPUNIT_ASSERT_EQUAL("'%H o'clock: It's about time'",
wxTranslateFromUnicodeFormat("''H 'o''clock: It''s about time'''"));
}
#endif // wxUSE_DATETIME