From e78f508997f9384518c2dd1a005c5306ccd24783 Mon Sep 17 00:00:00 2001 From: Winfried Donkers Date: Tue, 21 Nov 2017 16:08:32 +0100 Subject: tdf#97198 Make calc function MID work with Unicode non-BMP characters. Change-Id: Ic86344495490d6ca942f9fd2752874da22ef531f Reviewed-on: https://gerrit.libreoffice.org/45040 Reviewed-by: Eike Rathke Tested-by: Eike Rathke --- sc/qa/unit/data/functions/text/fods/mid.fods | 175 ++++++++++++++++++++++----- sc/source/core/tool/interpr1.cxx | 28 +++-- 2 files changed, 166 insertions(+), 37 deletions(-) diff --git a/sc/qa/unit/data/functions/text/fods/mid.fods b/sc/qa/unit/data/functions/text/fods/mid.fods index 56fcd55d3f27..68c7feb10299 100644 --- a/sc/qa/unit/data/functions/text/fods/mid.fods +++ b/sc/qa/unit/data/functions/text/fods/mid.fods @@ -1054,41 +1054,158 @@ - - - - - - + + + + + + + + + TRUE + + + =MID(I2;12;8) + + - - - - + + Err:502 + + + Err:502 + + + TRUE + + + =MID(I2;0;3) + + - - - - + + bπŸ˜‚ + + + bπŸ˜‚ + + + TRUE + + + =MID(I8;J8;K8) + + + result Excel 2016 is bπŸ˜‚ + + + abπŸ˜‚de𝔖ghπ•¬π–ˆπ–π–™π–šπ–“π–Œ! + + + 2 + - - - - - - + + + b + + + b + + + TRUE + + + =MID(I9;J9;K9) + + + result Excel 2016 is b + + + + abπŸ˜‚ + + + 2 + + + 1 + - - - - - - - + + + π§Œ’π§€¬ + + + π§Œ’π§€¬ + + + TRUE + + + =MID(I10;J10;K10) + + + result Excel 2016 is π§Œ’ + + + "π§Œ’π§€¬" + + + 2 + + + + + ü + + + ü + + + TRUE + + + =MID(I11;J11;K11) + + + result Excel 2016 is identical + + + + "üë" + + + 2 + + + + + π–π–™π–š + + + π–π–™π–š + + + TRUE + + + =MID(I12;J12;K12) + + + result Excel 2016 is π–ˆ + + + + π•¬π–ˆπ–π–™π–šπ–“π–Œ! + + + 3 + - + @@ -1130,4 +1247,4 @@ - \ No newline at end of file + diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx index 5bb02e6e363d..d53c00f9fcd7 100644 --- a/sc/source/core/tool/interpr1.cxx +++ b/sc/source/core/tool/interpr1.cxx @@ -8914,18 +8914,30 @@ void ScInterpreter::ScMid() { if ( MustHaveParamCount( GetByte(), 3 ) ) { - double fCnt = GetStringPositionArgument(); - double fAnfang = GetStringPositionArgument(); + sal_Int32 nSubLen = ( sal_Int32 )GetStringPositionArgument(); + sal_Int32 nStart = ( sal_Int32 )GetStringPositionArgument(); OUString aStr = GetString().getString(); - if (fAnfang < 1.0 || fCnt < 0.0) + if ( nStart < 1 || nSubLen < 0 ) PushIllegalArgument(); else { - sal_Int32 nCharacters = std::min(static_cast(fCnt), aStr.getLength() - fAnfang + 1); - OUString sRes; - if (nCharacters > 0) - sRes = aStr.copy(static_cast(fAnfang-1), nCharacters); - PushString(sRes); + sal_Int32 nLen = aStr.getLength(); + sal_Int32 nIdx = 0; + sal_Int32 nCnt = 0; + while ( nIdx < nLen && nStart - 1 > nCnt ) + { + aStr.iterateCodePoints( &nIdx ); + ++nCnt; + } + sal_Int32 nIdx0 = nIdx; //start position + + while ( nIdx < nLen && nStart + nSubLen - 1 > nCnt ) + { + aStr.iterateCodePoints( &nIdx ); + ++nCnt; + } + aStr = aStr.copy( nIdx0, nIdx - nIdx0 ); + PushString( aStr ); } } } -- cgit v1.2.3