From b845aa636a85da9d147e6e1fbda6a331486c2cdf Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 15 Oct 2013 13:04:23 +0000 Subject: [PATCH] Fix reading of files with Mac EOLs in wxTextFile. The last CR-terminated line wasn't handled correctly. Fix this now and add unit tests to ensure that it stays fixed. Closes #15583. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@75009 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 1 + src/common/textfile.cpp | 20 ++++++++++++++-- tests/textfile/textfiletest.cpp | 42 +++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 2 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index e17b388f19..d38cd3a562 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -567,6 +567,7 @@ All: - Add possibility to validate the input files against a schema to wxrc. - Fix recently broken compilation with Intel compiler. +- Fix reading of files with Mac EOLs in wxTextFile. All (GUI): diff --git a/src/common/textfile.cpp b/src/common/textfile.cpp index 4c7d4c330c..4607fc207b 100644 --- a/src/common/textfile.cpp +++ b/src/common/textfile.cpp @@ -275,8 +275,24 @@ bool wxTextFile::OnRead(const wxMBConv& conv) // anything in the last line? if ( lineStart != end ) { - // add unterminated last line - AddLine(wxString(lineStart, end), wxTextFileType_None); + // add the last line, notice that it may have been terminated with CR + // as we don't end the line immediately when we see a CR, as it could + // be followed by a LF. + wxString lastLine(lineStart, end); + wxTextFileType lastType; + if ( chLast == '\r' ) + { + // last line had Mac EOL, exclude it from the string + lastLine.RemoveLast(); + lastType = wxTextFileType_Mac; + } + else + { + // last line wasn't terminated at all + lastType = wxTextFileType_None; + } + + AddLine(lastLine, lastType); } return true; diff --git a/tests/textfile/textfiletest.cpp b/tests/textfile/textfiletest.cpp index c0415717d7..d523e6371b 100644 --- a/tests/textfile/textfiletest.cpp +++ b/tests/textfile/textfiletest.cpp @@ -43,8 +43,11 @@ private: CPPUNIT_TEST_SUITE( TextFileTestCase ); CPPUNIT_TEST( ReadEmpty ); CPPUNIT_TEST( ReadDOS ); + CPPUNIT_TEST( ReadDOSLast ); CPPUNIT_TEST( ReadUnix ); + CPPUNIT_TEST( ReadUnixLast ); CPPUNIT_TEST( ReadMac ); + CPPUNIT_TEST( ReadMacLast ); CPPUNIT_TEST( ReadMixed ); #if wxUSE_UNICODE CPPUNIT_TEST( ReadUTF8 ); @@ -55,8 +58,11 @@ private: void ReadEmpty(); void ReadDOS(); + void ReadDOSLast(); void ReadUnix(); + void ReadUnixLast(); void ReadMac(); + void ReadMacLast(); void ReadMixed(); #if wxUSE_UNICODE void ReadUTF8(); @@ -120,6 +126,18 @@ void TextFileTestCase::ReadDOS() CPPUNIT_ASSERT_EQUAL( wxString(wxT("baz")), f.GetLastLine() ); } +void TextFileTestCase::ReadDOSLast() +{ + CreateTestFile("foo\r\n"); + + wxTextFile f; + CPPUNIT_ASSERT( f.Open(GetTestFileName()) ); + + CPPUNIT_ASSERT_EQUAL( 1, f.GetLineCount() ); + CPPUNIT_ASSERT_EQUAL( wxTextFileType_Dos, f.GetLineType(0) ); + CPPUNIT_ASSERT_EQUAL( "foo", f.GetFirstLine() ); +} + void TextFileTestCase::ReadUnix() { CreateTestFile("foo\nbar\nbaz"); @@ -134,6 +152,18 @@ void TextFileTestCase::ReadUnix() CPPUNIT_ASSERT_EQUAL( wxString(wxT("baz")), f.GetLastLine() ); } +void TextFileTestCase::ReadUnixLast() +{ + CreateTestFile("foo\n"); + + wxTextFile f; + CPPUNIT_ASSERT( f.Open(GetTestFileName()) ); + + CPPUNIT_ASSERT_EQUAL( 1, f.GetLineCount() ); + CPPUNIT_ASSERT_EQUAL( wxTextFileType_Unix, f.GetLineType(0) ); + CPPUNIT_ASSERT_EQUAL( "foo", f.GetFirstLine() ); +} + void TextFileTestCase::ReadMac() { CreateTestFile("foo\rbar\rbaz"); @@ -148,6 +178,18 @@ void TextFileTestCase::ReadMac() CPPUNIT_ASSERT_EQUAL( wxString(wxT("baz")), f.GetLastLine() ); } +void TextFileTestCase::ReadMacLast() +{ + CreateTestFile("foo\r"); + + wxTextFile f; + CPPUNIT_ASSERT( f.Open(GetTestFileName()) ); + + CPPUNIT_ASSERT_EQUAL( 1, f.GetLineCount() ); + CPPUNIT_ASSERT_EQUAL( wxTextFileType_Mac, f.GetLineType(0) ); + CPPUNIT_ASSERT_EQUAL( "foo", f.GetFirstLine() ); +} + void TextFileTestCase::ReadMixed() { CreateTestFile("foo\rbar\r\nbaz\n");