summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2015-04-09 18:03:09 +0200
committerEike Rathke <erack@redhat.com>2015-04-09 18:19:02 +0200
commitd6398719abecfca60db37637490e602222992dc2 (patch)
tree5ec533cc8830086b7e6b7eb3a696523691049688 /sc
parent3335b46d123053b1228b94207a32bab08cf9d4e3 (diff)
TableRef: correct GetToken() logic
Ensure that only desired tokens are obtained and the resulting new token is actually the current one upon return. Change-Id: I624c324b861d8658accf3285cad2cfc5a598b450
Diffstat (limited to 'sc')
-rw-r--r--sc/inc/compiler.hxx3
-rw-r--r--sc/source/core/tool/compiler.cxx79
2 files changed, 45 insertions, 37 deletions
diff --git a/sc/inc/compiler.hxx b/sc/inc/compiler.hxx
index 3154d57e6386..03baa2983504 100644
--- a/sc/inc/compiler.hxx
+++ b/sc/inc/compiler.hxx
@@ -386,6 +386,9 @@ public:
bool IsTableRefItem( const OUString& ) const;
bool IsTableRefColumn( const OUString& ) const;
+ /** Calls GetToken() if PeekNextNoSpaces() is of given OpCode. */
+ bool GetTokenIfOpCode( OpCode eOp );
+
/**
* When auto correction is set, the jump command reorder must be enabled.
*/
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index 4cf6f245535a..a988209312f3 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -4820,6 +4820,14 @@ bool ScCompiler::HandleDbData()
return true;
}
+bool ScCompiler::GetTokenIfOpCode( OpCode eOp )
+{
+ const formula::FormulaToken* p = pArr->PeekNextNoSpaces();
+ if (p && p->GetOpCode() == eOp)
+ return GetToken();
+ return false;
+}
+
/* Documentation on MS-Excel Table structured references:
* https://support.office.com/en-us/article/Use-structured-references-in-Excel-table-formulas-75fb07d3-826a-449c-b76f-363057e3d16f
@@ -4847,7 +4855,6 @@ bool ScCompiler::HandleTableRef()
aDBRange.aEnd.SetTab(aDBRange.aStart.Tab());
ScRange aRange( aDBRange);
ScTokenArray* pNew = new ScTokenArray();
- bool bGotToken = false;
bool bAddRange = true;
bool bForwardToClose = false;
ScTableRefToken::Item eItem = pTR->GetItem();
@@ -4927,22 +4934,27 @@ bool ScCompiler::HandleTableRef()
break;
}
bool bColumnRange = false;
- if (bForwardToClose && (bGotToken = GetToken()) && mpToken->GetOpCode() == ocTableRefOpen)
+ int nLevel = 0;
+ if (bForwardToClose && GetTokenIfOpCode( ocTableRefOpen))
{
- int nLevel = 1;
+ ++nLevel;
enum
{
sOpen,
sItem,
sClose,
sSep,
+ sLast,
sStop
} eState = sOpen;
do
{
- if ((bGotToken = GetToken()))
+ const formula::FormulaToken* p = pArr->PeekNextNoSpaces();
+ if (!p)
+ eState = sStop;
+ else
{
- switch (mpToken->GetOpCode())
+ switch (p->GetOpCode())
{
case ocTableRefOpen:
eState = ((eState == sOpen || eState == sSep) ? sOpen : sStop);
@@ -4961,35 +4973,37 @@ bool ScCompiler::HandleTableRef()
break;
case ocTableRefClose:
eState = ((eState == sItem || eState == sClose) ? sClose : sStop);
- if (--nLevel <= 0)
- {
- if (nLevel < 0)
- SetError( errPair);
- eState = sStop;
- }
+ if (eState != sStop && --nLevel == 0)
+ eState = sLast;
break;
case ocSep:
eState = ((eState == sClose) ? sSep : sStop);
break;
case ocPush:
- if (eState == sOpen &&
- (mpToken->GetType() == svSingleRef || mpToken->GetType() == svDoubleRef))
+ if (eState == sOpen && (p->GetType() == svSingleRef || p->GetType() == svDoubleRef))
+ {
bColumnRange = true;
- eState = sStop;
+ eState = sLast;
+ }
+ else
+ {
+ eState = sStop;
+ }
break;
default:
eState = sStop;
}
+ if (eState != sStop)
+ GetToken();
+ if (eState == sLast)
+ eState = sStop;
}
- } while (bGotToken && eState != sStop);
- if (bGotToken && mpToken->GetOpCode() == ocTableRefClose)
- bGotToken = false; // get next token below in return
+ } while (eState != sStop);
}
if (bAddRange)
{
if (bColumnRange)
{
- bGotToken = false; // obtain at least a close hereafter
// Limit range to specified columns.
ScRange aColRange( ScAddress::INITIALIZE_INVALID );
switch (mpToken->GetType())
@@ -4997,16 +5011,15 @@ bool ScCompiler::HandleTableRef()
case svSingleRef:
{
aColRange.aStart = aColRange.aEnd = mpToken->GetSingleRef()->toAbs( aPos);
- if ( (bGotToken = GetToken()) && mpToken->GetOpCode() == ocTableRefClose &&
- (bGotToken = GetToken()) && mpToken->GetOpCode() == ocRange &&
- (bGotToken = GetToken()) && mpToken->GetOpCode() == ocTableRefOpen &&
- (bGotToken = GetToken()) && mpToken->GetOpCode() == ocPush)
+ if ( GetTokenIfOpCode( ocTableRefClose) && (nLevel--) &&
+ GetTokenIfOpCode( ocRange) &&
+ GetTokenIfOpCode( ocTableRefOpen) && (++nLevel) &&
+ GetTokenIfOpCode( ocPush))
{
if (mpToken->GetType() != svSingleRef)
aColRange = ScRange( ScAddress::INITIALIZE_INVALID);
else
{
- bGotToken = false; // obtain at least a close hereafter
aColRange.aEnd = mpToken->GetSingleRef()->toAbs( aPos);
aColRange.Justify();
}
@@ -5040,27 +5053,19 @@ bool ScCompiler::HandleTableRef()
{
SetError( errNoRef);
}
- if (bColumnRange && !bGotToken)
- {
- if ((bGotToken = GetToken()) && mpToken->GetOpCode() == ocTableRefClose)
- {
- if ((bGotToken = GetToken()) && mpToken->GetOpCode() == ocTableRefClose)
- bGotToken = false; // get next token below in return
- }
- else
- {
- SetError( errPair);
- bGotToken = false; // get next token below in return
- }
- }
}
else
{
SetError( errNoRef);
}
+ while (nLevel-- > 0)
+ {
+ if (!GetTokenIfOpCode( ocTableRefClose))
+ SetError( errPair);
+ }
PushTokenArray( pNew, true );
pNew->Reset();
- return bGotToken ? true : GetToken();
+ return GetToken();
}
return true;
}