diff options
author | Eike Rathke <erack@redhat.com> | 2013-03-09 18:41:01 +0100 |
---|---|---|
committer | Eike Rathke <erack@redhat.com> | 2013-03-09 18:50:33 +0100 |
commit | 3bc5cb3c485d67f1ce0541d349d11637f52ebda5 (patch) | |
tree | 5fc844a3b32641839aba29f0ebb2a4563bf29654 | |
parent | c00601dab0f5533b152cd63cec0a89bfec1ba95f (diff) |
regex: handle zero-length matches, fdo#60259 related
Also in backward search ignore all zero-length matches except the text
end single $ anchor search. The anchor search is a valid match, treat it
as such in Writer.
This still doesn't solve the backward $ backward search, the convoluted
Writer code in that place apparently never worked, someone more familiar
with those internals should straighten out the mess.
Change-Id: I2bc83cdcfe6425f9bebf06e23e879bc79b82daa9
-rw-r--r-- | i18npool/source/search/textsearch.cxx | 20 | ||||
-rw-r--r-- | sw/source/core/crsr/findtxt.cxx | 13 |
2 files changed, 28 insertions, 5 deletions
diff --git a/i18npool/source/search/textsearch.cxx b/i18npool/source/search/textsearch.cxx index 72e1d60d4507..14ecdcc1059d 100644 --- a/i18npool/source/search/textsearch.cxx +++ b/i18npool/source/search/textsearch.cxx @@ -797,17 +797,35 @@ SearchResult TextSearch::RESrchBkwrd( const OUString& searchStr, // find the last match int nLastPos = 0; int nFoundEnd = 0; + int nGoodPos = 0, nGoodEnd = 0; + bool bFirst = true; do { nLastPos = pRegexMatcher->start( nIcuErr); nFoundEnd = pRegexMatcher->end( nIcuErr); + if (nLastPos < nFoundEnd) + { + // remember last non-zero-length match + nGoodPos = nLastPos; + nGoodEnd = nFoundEnd; + } if( nFoundEnd >= startPos) break; + bFirst = false; if( nFoundEnd == nLastPos) ++nFoundEnd; } while( pRegexMatcher->find( nFoundEnd, nIcuErr)); + // Ignore all zero-length matches except "$" anchor on first match. + if (nGoodPos == nGoodEnd) + { + if (bFirst && nLastPos == startPos) + nGoodPos = nLastPos; + else + return aRet; + } + // find last match again to get its details - pRegexMatcher->find( nLastPos, nIcuErr); + pRegexMatcher->find( nGoodPos, nIcuErr); // fill in the details of the last match const int nGroupCount = pRegexMatcher->groupCount(); diff --git a/sw/source/core/crsr/findtxt.cxx b/sw/source/core/crsr/findtxt.cxx index b2fbea85104b..e1c9358c0741 100644 --- a/sw/source/core/crsr/findtxt.cxx +++ b/sw/source/core/crsr/findtxt.cxx @@ -450,8 +450,9 @@ bool SwPaM::DoSearch( const SearchOptions& rSearchOpt, utl::TextSearch& rSTxt, } xub_StrLen nStringEnd = nEnd; - while ( (bSrchForward && nStart < nStringEnd) || - (! bSrchForward && nStart > nStringEnd) ) + bool bZeroMatch = false; // zero-length match, i.e. only $ anchor as regex + while ( ((bSrchForward && nStart < nStringEnd) || + (! bSrchForward && nStart > nStringEnd)) && !bZeroMatch ) { // SearchAlgorithms_APPROXIMATE works on a per word base so we have to // provide the text searcher with the correct locale, because it uses @@ -479,7 +480,8 @@ bool SwPaM::DoSearch( const SearchOptions& rSearchOpt, utl::TextSearch& rSTxt, } if( nSearchScript == nCurrScript && - (rSTxt.*fnMove->fnSearch)( sCleanStr, &nStart, &nEnd, 0 )) + (rSTxt.*fnMove->fnSearch)( sCleanStr, &nStart, &nEnd, 0 ) && + !(bZeroMatch = (nStart == nEnd))) { // set section correctly *GetPoint() = *pPam->GetPoint(); @@ -522,11 +524,14 @@ bool SwPaM::DoSearch( const SearchOptions& rSearchOpt, utl::TextSearch& rSTxt, if ( bFound ) return true; - else if( ( bChkEmptyPara && !nStart && !nTxtLen ) || bChkParaEnd ) + else if( ( bChkEmptyPara && !nStart && !nTxtLen ) || (bChkParaEnd && bZeroMatch && nEnd == nTxtLen)) { *GetPoint() = *pPam->GetPoint(); GetPoint()->nContent = bChkParaEnd ? nTxtLen : 0; SetMark(); + /* FIXME: this condition does not work for !bSrchForward backward + * search, it probably never did. (pSttNd != &rNdIdx.GetNode()) + * is never true in this case. */ if( (bSrchForward || pSttNd != &rNdIdx.GetNode()) && Move( fnMoveForward, fnGoCntnt ) && (!bSrchForward || pSttNd != &GetPoint()->nNode.GetNode()) && |