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:
committed by
Andreas Heinisch
parent
ba431d2bcb
commit
a400c865a6
@@ -114,4 +114,57 @@ CPPUNIT_TEST_FIXTURE(CppUnit::TestFixture, testTdf149402_vba)
|
|||||||
CPPUNIT_ASSERT(!aMacro.HasError());
|
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: */
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|
||||||
|
@@ -29,6 +29,7 @@
|
|||||||
#include <rtl/character.hxx>
|
#include <rtl/character.hxx>
|
||||||
#include <o3tl/string_view.hxx>
|
#include <o3tl/string_view.hxx>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
SbiScanner::SbiScanner(OUString _aBuf, StarBASIC* p)
|
SbiScanner::SbiScanner(OUString _aBuf, StarBASIC* p)
|
||||||
: aBuf(std::move(_aBuf))
|
: aBuf(std::move(_aBuf))
|
||||||
@@ -209,6 +210,17 @@ bool SbiScanner::readLine()
|
|||||||
return true;
|
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()
|
bool SbiScanner::NextSym()
|
||||||
{
|
{
|
||||||
// memorize for the EOLN-case
|
// memorize for the EOLN-case
|
||||||
@@ -220,7 +232,6 @@ bool SbiScanner::NextSym()
|
|||||||
eScanType = SbxVARIANT;
|
eScanType = SbxVARIANT;
|
||||||
aSym.clear();
|
aSym.clear();
|
||||||
bHash = bSymbol = bNumber = bSpaces = false;
|
bHash = bSymbol = bNumber = bSpaces = false;
|
||||||
bool bCompilerDirective = false;
|
|
||||||
|
|
||||||
// read in line?
|
// read in line?
|
||||||
if (nLineIdx == -1)
|
if (nLineIdx == -1)
|
||||||
@@ -256,6 +267,8 @@ bool SbiScanner::NextSym()
|
|||||||
if(nCol < aLine.getLength() && aLine[nCol] == '#')
|
if(nCol < aLine.getLength() && aLine[nCol] == '#')
|
||||||
{
|
{
|
||||||
sal_Int32 nLineTempIdx = nLineIdx;
|
sal_Int32 nLineTempIdx = nLineIdx;
|
||||||
|
std::u16string_view candidate(aLine.subView(nCol + 1));
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
nLineTempIdx++;
|
nLineTempIdx++;
|
||||||
@@ -266,9 +279,20 @@ bool SbiScanner::NextSym()
|
|||||||
{
|
{
|
||||||
++nLineIdx;
|
++nLineIdx;
|
||||||
++nCol;
|
++nCol;
|
||||||
//ignore compiler directives (# is first non-space character)
|
//handle compiler directives (# is first non-space character)
|
||||||
if (nOldCol2 == 0)
|
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
|
else
|
||||||
bHash = true;
|
bHash = true;
|
||||||
}
|
}
|
||||||
@@ -660,10 +684,9 @@ bool SbiScanner::NextSym()
|
|||||||
|
|
||||||
PrevLineCommentLbl:
|
PrevLineCommentLbl:
|
||||||
|
|
||||||
if( bPrevLineExtentsComment || (eScanType != SbxSTRING &&
|
if (bPrevLineExtentsComment ||
|
||||||
( bCompilerDirective ||
|
(eScanType != SbxSTRING &&
|
||||||
aSym.startsWith("'") ||
|
(aSym.startsWith("'") || aSym.equalsIgnoreAsciiCase("REM") || aSym.startsWith("#"))))
|
||||||
aSym.equalsIgnoreAsciiCase( "REM" ) ) ) )
|
|
||||||
{
|
{
|
||||||
bPrevLineExtentsComment = false;
|
bPrevLineExtentsComment = false;
|
||||||
aSym = "REM";
|
aSym = "REM";
|
||||||
|
Reference in New Issue
Block a user