basic/qa/basic_coverage/test_format_function.bas | 5 ++ basic/qa/basic_coverage/test_str_method.bas | 41 +++++++++++++++++++++++ basic/source/runtime/methods.cxx | 19 ++++++++-- basic/source/sbx/sbxscan.cxx | 10 +++++ 4 files changed, 70 insertions(+), 5 deletions(-)
New commits: commit f846899e0b6fc2ec9ab2b4a4f65d06549e3f0763 Author: Mike Kaganski <[email protected]> AuthorDate: Fri Sep 26 21:14:33 2025 +0500 Commit: Xisco Fauli <[email protected]> CommitDate: Mon Sep 29 10:25:20 2025 +0200 tdf#168561: fix Str function implementation 1. If a string is passed as argument, it is returned without any changes. For that, SbRtl_Str checks argument type, skipping processing for string. 2. Non-negative numbers are preceded by a blank space. That already was implemented. 3. Negative numbers are preceded by a minus sign. That was done incorrectly - a space was added for any number. 4. Dates are converted into locale-dependent strings. That wasn't done at all - dates were converted to strings representing the serial date. A check is implemented SbxValue::Format, to handle this. Additionally, Format function was improved to handle such input without format string (taking into account that it handles strings that can be converted to numbers differently). Change-Id: I5ac0429950e4ea8bf69b0091502b4e6dc1f4957d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/191549 Reviewed-by: Mike Kaganski <[email protected]> Tested-by: Jenkins (cherry picked from commit 92878d3216aeaf0e5131c0c3fa1f8dc9ce67b5b4) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/191582 Reviewed-by: Xisco Fauli <[email protected]> diff --git a/basic/qa/basic_coverage/test_format_function.bas b/basic/qa/basic_coverage/test_format_function.bas index f72e504a2379..0492a51b8840 100644 --- a/basic/qa/basic_coverage/test_format_function.bas +++ b/basic/qa/basic_coverage/test_format_function.bas @@ -39,6 +39,11 @@ Sub verify_testFormat TestUtil.AssertEqual(Format("abc", "1�5"), "abc", "Format(""abc"", ""1�5"")") TestUtil.AssertEqual(Format("abc", "@ &"), "abc &", "Format(""abc"", ""@ &"")") + TestUtil.AssertEqual(Format(""), "", "Format("""")") + TestUtil.AssertEqual(Format(" "), " ", "Format("" "")") + TestUtil.AssertEqual(Format(" 00 "), "0", "Format("" 00 "")") + TestUtil.AssertEqual(Format(CDate("2025-09-26")), "09/26/2025", "Format(CDate(""2025-09-26""))") + Exit Sub errorHandler: TestUtil.ReportErrorHandler("verify_testFormat", Err, Error$, Erl) diff --git a/basic/qa/basic_coverage/test_str_method.bas b/basic/qa/basic_coverage/test_str_method.bas new file mode 100644 index 000000000000..2ce10952ee04 --- /dev/null +++ b/basic/qa/basic_coverage/test_str_method.bas @@ -0,0 +1,41 @@ +' This file is part of the LibreOffice project. +' +' This Source Code Form is subject to the terms of the Mozilla Public +' License, v. 2.0. If a copy of the MPL was not distributed with this +' file, You can obtain one at http://mozilla.org/MPL/2.0/. +' + +Option Explicit + +Function doUnitTest as String + TestUtil.TestInit + verify_testStr + doUnitTest = TestUtil.GetResult() +End Function + +Dim failedAssertion As Boolean, messages As String + +Sub verify_testStr + On Error GoTo errorHandler + + ' If a string is passed as argument, it is returned without any changes + TestUtil.AssertEqualStrict(Str(""), "", "Str("""")") + TestUtil.AssertEqualStrict(Str(" "), " ", "Str("" "")") + TestUtil.AssertEqualStrict(Str(" 00 "), " 00 ", "Str("" 00 "")") + + ' Non-negative numbers are preceded by a blank space + TestUtil.AssertEqualStrict(Str(0), " 0", "Str(0)") + TestUtil.AssertEqualStrict(Str(1 / 10), " 0.1", "Str(1 / 10)") + + ' Negative numbers are preceded by a minus sign + TestUtil.AssertEqualStrict(Str(-1 / 10), "-0.1", "Str(-1 / 10)") + + ' Dates are converted into locale-dependent strings (test uses en-US) + TestUtil.AssertEqualStrict(Str(CDate("2025-09-26")), "09/26/2025", "Str(CDate(""2025-09-26""))") + + TestUtil.AssertEqualStrict(Str(true), "True", "Str(true)") + + Exit Sub +errorHandler: + TestUtil.ReportErrorHandler("verify_testStr", Err, Error$, Erl) +End Sub diff --git a/basic/source/runtime/methods.cxx b/basic/source/runtime/methods.cxx index 679414e10a14..8598a9a522cf 100644 --- a/basic/source/runtime/methods.cxx +++ b/basic/source/runtime/methods.cxx @@ -1330,12 +1330,21 @@ void SbRtl_Str(StarBASIC *, SbxArray & rPar, bool) } OUString aStr; - OUString aStrNew(u""_ustr); + OUString aStrNew; SbxVariableRef pArg = rPar.Get(1); - pArg->Format( aStr ); + const SbxDataType argType = pArg->GetType(); + if (argType == SbxSTRING) + { + // From Help: "If a string is passed as argument, it is returned without any changes" + aStr = pArg->GetOUString(); + } + else + { + pArg->Format(aStr); + } // Numbers start with a space - if (pArg->GetType() != SbxBOOL && pArg->IsNumericRTL()) + if (argType != SbxBOOL && argType != SbxSTRING && pArg->IsNumericRTL()) { // replace commas by points so that it's symmetric to Val! aStr = aStr.replaceFirst( ",", "." ); @@ -1371,7 +1380,9 @@ void SbRtl_Str(StarBASIC *, SbxArray & rPar, bool) } else { - aStrNew = " " + aStr; + if (!aStr.startsWith("-")) + aStrNew = " "; + aStrNew += aStr; } } else diff --git a/basic/source/sbx/sbxscan.cxx b/basic/source/sbx/sbxscan.cxx index df6e704299b8..ed332d6ff645 100644 --- a/basic/source/sbx/sbxscan.cxx +++ b/basic/source/sbx/sbxscan.cxx @@ -443,7 +443,10 @@ std::optional<double> StrToNumberIntl(const OUString& s, std::shared_ptr<SvNumberFormatter>& rpFormatter) { double ret; - if (SbxValue::ScanNumIntnl(s, ret) == ERRCODE_NONE) + sal_Int32 nLen = 0; + bool bHasNumber = false; + if (ImpScan(s, ret, o3tl::temporary(SbxDataType()), &nLen, &bHasNumber, true) == ERRCODE_NONE + && bHasNumber && nLen == s.getLength()) return ret; // We couldn't detect a Basic-formatted number (including type characters & specific exponents). @@ -552,6 +555,11 @@ void SbxValue::Format( OUString& rRes, const OUString* pFmt ) const rRes = SbxBasicFormater::BasicFormatNull(pFmt ? *pFmt : std::u16string_view{}); return; } + if (eType == SbxDATE && !pFmt) + { + rRes = GetOUString(); + return; + } std::shared_ptr<SvNumberFormatter> pFormatter; std::optional<double> number = GetNumberIntl(*this, rRes, pFormatter, pFmt != nullptr);
