tdf#93727 Syntax Error on # in basic

Change-Id: I400a4061de580a5c91b0e4763cad40ae88a9f738
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162639
Tested-by: Jenkins
Tested-by: Andreas Heinisch <andreas.heinisch@yahoo.de>
Reviewed-by: Andreas Heinisch <andreas.heinisch@yahoo.de>
This commit is contained in:
Luv Sharma 2024-01-27 14:54:49 +05:30 committed by Andreas Heinisch
parent ba431d2bcb
commit a400c865a6
2 changed files with 83 additions and 7 deletions

View file

@ -114,4 +114,57 @@ CPPUNIT_TEST_FIXTURE(CppUnit::TestFixture, testTdf149402_vba)
CPPUNIT_ASSERT(!aMacro.HasError());
}
CPPUNIT_TEST_FIXTURE(CppUnit::TestFixture, testTdf93727_if)
{
// #If and #End directive
MacroSnippet aMacro("Sub doUnitTest\n"
" #If 1 = 1 Then\n"
" Const a = 10\n"
" #End If\n"
"End Sub\n");
aMacro.Compile();
CPPUNIT_ASSERT_MESSAGE("#If directive causes compile error", !aMacro.HasError());
}
CPPUNIT_TEST_FIXTURE(CppUnit::TestFixture, testTdf93727_else)
{
// #Else directive
MacroSnippet aMacro("Sub doUnitTest\n"
"a = 0\n"
"#If 1 = 0 Then\n"
" a = 10\n"
"#Else\n"
" a = 20\n"
"#End If\n"
"End Sub\n");
aMacro.Compile();
CPPUNIT_ASSERT_MESSAGE("#Else directive causes compile error", !aMacro.HasError());
}
CPPUNIT_TEST_FIXTURE(CppUnit::TestFixture, testTdf93727_elseif)
{
// #ElseIf directive
MacroSnippet aMacro("Sub doUnitTest\n"
"a = 0\n"
" #If 1 = 0 Then\n"
" a = 10\n"
" #ElseIf 2 = 2 Then\n"
" a = 20\n"
" #End If\n"
"End Sub\n");
aMacro.Compile();
CPPUNIT_ASSERT_MESSAGE("#ElseIf directive causes compile error", !aMacro.HasError());
}
CPPUNIT_TEST_FIXTURE(CppUnit::TestFixture, testTdf93727_const)
{
// #Const directive
MacroSnippet aMacro("#Const MaxValue = 1000\n"
"Sub doUnitTest\n"
" Dim value As Integer\n"
" value = MaxValue\n"
"End Sub\n");
aMacro.Compile();
CPPUNIT_ASSERT_MESSAGE("#Const directive causes compile error", !aMacro.HasError());
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */

View file

@ -29,6 +29,7 @@
#include <rtl/character.hxx>
#include <o3tl/string_view.hxx>
#include <utility>
#include <vector>
SbiScanner::SbiScanner(OUString _aBuf, StarBASIC* p)
: aBuf(std::move(_aBuf))
@ -209,6 +210,17 @@ bool SbiScanner::readLine()
return true;
}
// Function to check if a string is a valid compiler directive
static bool isValidCompilerDirective(std::u16string_view directive) {
static const std::vector<std::u16string_view> validDirectives = {
u"if", u"elseif", u"else", u"end", u"const"
};
return std::any_of(validDirectives.begin(), validDirectives.end(), [&](const auto& valid) {
return o3tl::matchIgnoreAsciiCase(directive, valid);
});
}
bool SbiScanner::NextSym()
{
// memorize for the EOLN-case
@ -220,7 +232,6 @@ bool SbiScanner::NextSym()
eScanType = SbxVARIANT;
aSym.clear();
bHash = bSymbol = bNumber = bSpaces = false;
bool bCompilerDirective = false;
// read in line?
if (nLineIdx == -1)
@ -256,6 +267,8 @@ bool SbiScanner::NextSym()
if(nCol < aLine.getLength() && aLine[nCol] == '#')
{
sal_Int32 nLineTempIdx = nLineIdx;
std::u16string_view candidate(aLine.subView(nCol + 1));
do
{
nLineTempIdx++;
@ -266,9 +279,20 @@ bool SbiScanner::NextSym()
{
++nLineIdx;
++nCol;
//ignore compiler directives (# is first non-space character)
//handle compiler directives (# is first non-space character)
if (nOldCol2 == 0)
bCompilerDirective = true;
{
if (isValidCompilerDirective(candidate))
{
// Skip the whole line if starts with a hash and is a valid compiler directive
nCol = 0;
goto eoln;
}
else
{
GenError(ERRCODE_BASIC_SYNTAX);
}
}
else
bHash = true;
}
@ -660,10 +684,9 @@ bool SbiScanner::NextSym()
PrevLineCommentLbl:
if( bPrevLineExtentsComment || (eScanType != SbxSTRING &&
( bCompilerDirective ||
aSym.startsWith("'") ||
aSym.equalsIgnoreAsciiCase( "REM" ) ) ) )
if (bPrevLineExtentsComment ||
(eScanType != SbxSTRING &&
(aSym.startsWith("'") || aSym.equalsIgnoreAsciiCase("REM") || aSym.startsWith("#"))))
{
bPrevLineExtentsComment = false;
aSym = "REM";