tdf#163680: fix fixed-length strings assignment

Change-Id: I4aa8144df5dfb836ad0689c7855301b8b04da485
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/175878
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Tested-by: Jenkins
This commit is contained in:
Mike Kaganski 2024-10-30 15:31:33 +05:00
parent 9a07b6c34c
commit de4ef35350
3 changed files with 68 additions and 5 deletions

View file

@ -0,0 +1,54 @@
' 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 VBASupport 0
Option Explicit
Function doUnitTest() As String
TestUtil.TestInit
verify_stringFixedLen
doUnitTest = TestUtil.GetResult()
End Function
Sub verify_stringFixedLen()
On Error GoTo errorHandler
' tdf#163680 - fixed-length strings support
Dim s As String * 10
TestUtil.AssertEqual(Len(s), 10, "Len(s) - default")
' The default value is 10 null characters
TestUtil.AssertEqual(s, String(10, 0), "s - default")
s = "abc"
TestUtil.AssertEqual(Len(s), 10, "Len(s) - abc")
TestUtil.AssertEqual("""" & s & """", """abc """, """s"" - abc")
s = "defghijklmno"
TestUtil.AssertEqual(Len(s), 10, "Len(s) - defghijklmno")
TestUtil.AssertEqual("""" & s & """", """defghijklm""", """s"" - defghijklmno")
Let s = "xyz" ' Test also Let keyword - uses a different code path
TestUtil.AssertEqual(Len(s), 10, "Len(s) - xyz")
TestUtil.AssertEqual("""" & s & """", """xyz """, """s"" - xyz")
Let s = "opqrstuvwxyz"
TestUtil.AssertEqual(Len(s), 10, "Len(s) - opqrstuvwxyz")
TestUtil.AssertEqual("""" & s & """", """opqrstuvwx""", """s"" - opqrstuvwxyz")
Dim s1 As String * 0 ' Unlike VBA, LibreOffice Basic allows this for unrestricted strings
TestUtil.AssertEqual(Len(s1), 0, "Len(s1) - default")
TestUtil.AssertEqual("""" & s1 & """", """""", """s1"" - default")
s1 = "klm"
TestUtil.AssertEqual(Len(s1), 3, "Len(s1) - klm")
TestUtil.AssertEqual("""" & s1 & """", """klm""", """s1"" - klm")
s = s1
TestUtil.AssertEqual(Len(s), 10, "Len(s) - klm")
TestUtil.AssertEqual("""" & s & """", """klm """, """s"" - klm")
' Also test s1 - it must not be affected
TestUtil.AssertEqual(Len(s1), 3, "Len(s1) - klm")
TestUtil.AssertEqual("""" & s1 & """", """klm""", """s1"" - klm")
Exit Sub
errorHandler:
TestUtil.ReportErrorHandler("verify_stringFixedLen", Err, Error$, Erl)
End Sub

View file

@ -551,6 +551,10 @@ void SbiParser::Symbol( const KeywordSymbolInfo* pKeywordSymbolInfo )
return;
}
}
else if (auto nLen = pDef->GetLen()) // Dim s As String * 123 ' 123 -> nLen
{
aGen.Gen(SbiOpcode::PAD_, nLen);
}
}
aGen.Gen( eOp );
}
@ -564,15 +568,15 @@ void SbiParser::Assign()
SbiExpression aExpr( this );
aLvalue.Gen();
aExpr.Gen();
sal_uInt16 nLen = 0;
SbiSymDef* pDef = aLvalue.GetRealVar();
if (SbiSymDef* pDef = aLvalue.GetRealVar())
{
if( pDef->GetConstDef() )
Error( ERRCODE_BASIC_DUPLICATE_DEF, pDef->GetName() );
nLen = aLvalue.GetRealVar()->GetLen();
if (auto nLen = pDef->GetLen()) // Dim s As String * 123 ' 123 -> nLen
{
aGen.Gen( SbiOpcode::PAD_, nLen );
}
}
if( nLen )
aGen.Gen( SbiOpcode::PAD_, nLen );
aGen.Gen( SbiOpcode::PUT_ );
}

View file

@ -2975,6 +2975,11 @@ void SbiRuntime::StepPAD( sal_uInt32 nOp1 )
comphelper::string::padToLength(aBuf, nLen, ' ');
}
s = aBuf.makeStringAndClear();
// Do not modify the original variable inadvertently
PopVar();
p = new SbxVariable;
p->PutString(s);
PushVar(p);
}
// jump (+target)