formula/source/core/api/FormulaCompiler.cxx | 143 ++++++++++++++-------------- 1 file changed, 75 insertions(+), 68 deletions(-)
New commits: commit e0875f8e348a3aca036bc0cc629fb038fabc8062 Author: Eike Rathke <[email protected]> Date: Sat Apr 23 20:40:38 2016 +0200 narrow down where a space could be an intersection, tdf#96426 follow-up Change-Id: Ic53a4a0d19a11298895efb28e2786e48a071e72b diff --git a/formula/source/core/api/FormulaCompiler.cxx b/formula/source/core/api/FormulaCompiler.cxx index 535dc41..6a11fc0 100644 --- a/formula/source/core/api/FormulaCompiler.cxx +++ b/formula/source/core/api/FormulaCompiler.cxx @@ -266,6 +266,75 @@ struct OpCodeMapData }; +bool isRangeResultFunction( OpCode eOp ) +{ + switch (eOp) + { + case ocIndirect: + case ocOffset: + return true; + default: + return false; + } +} + +bool isRangeResultOpCode( OpCode eOp ) +{ + switch (eOp) + { + case ocRange: + case ocUnion: + case ocIntersect: + case ocIndirect: + case ocOffset: + return true; + default: + return false; + } +} + +bool isPotentialRangeType( FormulaToken* pToken, bool bRPN ) +{ + switch (pToken->GetType()) + { + case svByte: // could be range result, but only a few + if (bRPN) + return isRangeResultOpCode( pToken->GetOpCode()); + else + return isRangeResultFunction( pToken->GetOpCode()); + case svSingleRef: + case svDoubleRef: + case svIndex: // could be range + //case svRefList: // um..what? + case svExternalSingleRef: + case svExternalDoubleRef: + case svExternalName: // could be range + return true; + default: + return false; + } +} + +bool isIntersectable( FormulaToken** pCode1, FormulaToken** pCode2 ) +{ + FormulaToken* pToken1 = *pCode1; + FormulaToken* pToken2 = *pCode2; + if (pToken1 && pToken2) + return isPotentialRangeType( pToken1, true) && isPotentialRangeType( pToken2, true); + return false; +} + +bool isAdjacentRpnEnd( sal_uInt16 nPC, + FormulaToken const * const * const pCode, + FormulaToken const * const * const pCode1, + FormulaToken const * const * const pCode2 ) +{ + return nPC >= 2 && pCode1 && pCode2 && + (pCode2 - pCode1 == 1) && (pCode - pCode2 == 1) && + (*pCode1 != nullptr) && (*pCode2 != nullptr); +} + + } // namespace @@ -1061,6 +1130,7 @@ bool FormulaCompiler::GetToken() bStop = true; else { + FormulaTokenRef pCurrToken = mpToken; FormulaTokenRef pSpacesToken; short nWasColRowName; if ( pArr->nIndex > 0 && pArr->pCode[ pArr->nIndex-1 ]->GetOpCode() == ocColRowName ) @@ -1098,7 +1168,8 @@ bool FormulaCompiler::GetToken() mpToken = new FormulaByteToken( ocIntersect ); pArr->nIndex--; // we advanced to the second ocColRowName, step back } - else if (pSpacesToken && FormulaGrammar::isExcelSyntax( meGrammar)) + else if (pSpacesToken && FormulaGrammar::isExcelSyntax( meGrammar) && + isPotentialRangeType( pCurrToken.get(), false) && isPotentialRangeType( mpToken.get(), false)) { // Let IntersectionLine() <- Factor() decide how to treat this, // once the actual arguments are determined in RPN. @@ -1574,78 +1645,6 @@ void FormulaCompiler::RangeLine() } } -namespace { - -bool isRangeResultFunction( OpCode eOp ) -{ - switch (eOp) - { - case ocIndirect: - case ocOffset: - return true; - default: - return false; - } -} - -bool isRangeResultOpCode( OpCode eOp ) -{ - switch (eOp) - { - case ocRange: - case ocUnion: - case ocIntersect: - case ocIndirect: - case ocOffset: - return true; - default: - return false; - } -} - -bool isPotentialRangeType( FormulaToken* pToken, bool bRPN ) -{ - switch (pToken->GetType()) - { - case svByte: // could be range result, but only a few - if (bRPN) - return isRangeResultOpCode( pToken->GetOpCode()); - else - return isRangeResultFunction( pToken->GetOpCode()); - case svSingleRef: - case svDoubleRef: - case svIndex: // could be range - //case svRefList: // um..what? - case svExternalSingleRef: - case svExternalDoubleRef: - case svExternalName: // could be range - return true; - default: - return false; - } -} - -bool isIntersectable( FormulaToken** pCode1, FormulaToken** pCode2 ) -{ - FormulaToken* pToken1 = *pCode1; - FormulaToken* pToken2 = *pCode2; - if (pToken1 && pToken2) - return isPotentialRangeType( pToken1, true) && isPotentialRangeType( pToken2, true); - return false; -} - -bool isAdjacentRpnEnd( sal_uInt16 nPC, - FormulaToken const * const * const pCode, - FormulaToken const * const * const pCode1, - FormulaToken const * const * const pCode2 ) -{ - return nPC >= 2 && pCode1 && pCode2 && - (pCode2 - pCode1 == 1) && (pCode - pCode2 == 1) && - (*pCode1 != nullptr) && (*pCode2 != nullptr); -} - -} - void FormulaCompiler::IntersectionLine() { RangeLine(); commit b0992e11905e36a64edeb92a13acfde5837c1878 Author: Eike Rathke <[email protected]> Date: Sat Apr 23 20:23:23 2016 +0200 fully check for adjacent RPN end, tdf#96426 follow-up Change-Id: I886e559c6f6041bf4889fdd6d89c12a10be70e5f diff --git a/formula/source/core/api/FormulaCompiler.cxx b/formula/source/core/api/FormulaCompiler.cxx index 303e00e..535dc41 100644 --- a/formula/source/core/api/FormulaCompiler.cxx +++ b/formula/source/core/api/FormulaCompiler.cxx @@ -1634,6 +1634,16 @@ bool isIntersectable( FormulaToken** pCode1, FormulaToken** pCode2 ) return false; } +bool isAdjacentRpnEnd( sal_uInt16 nPC, + FormulaToken const * const * const pCode, + FormulaToken const * const * const pCode1, + FormulaToken const * const * const pCode2 ) +{ + return nPC >= 2 && pCode1 && pCode2 && + (pCode2 - pCode1 == 1) && (pCode - pCode2 == 1) && + (*pCode1 != nullptr) && (*pCode2 != nullptr); +} + } void FormulaCompiler::IntersectionLine() @@ -1653,7 +1663,7 @@ void FormulaCompiler::IntersectionLine() // functions (potentially returning references, if not then a space // or no space would be a syntax error anyway), not other operators // or operands. Else discard. - if (isIntersectable( pCode1, pCode2)) + if (isAdjacentRpnEnd( pc, pCode, pCode1, pCode2) && isIntersectable( pCode1, pCode2)) { FormulaTokenRef pIntersect( new FormulaByteToken( ocIntersect)); // Replace ocSpaces with ocIntersect so that when switching @@ -1812,12 +1822,10 @@ FormulaTokenRef FormulaCompiler::ExtendRangeReference( FormulaToken & /*rTok1*/, bool FormulaCompiler::MergeRangeReference( FormulaToken * * const pCode1, FormulaToken * const * const pCode2 ) { - FormulaToken *p1, *p2; - if (pc < 2 || !pCode1 || !pCode2 || - (pCode2 - pCode1 != 1) || (pCode - pCode2 != 1) || - ((p1 = *pCode1) == nullptr) || ((p2 = *pCode2) == nullptr) ) + if (!isAdjacentRpnEnd( pc, pCode, pCode1, pCode2)) return false; + FormulaToken *p1 = *pCode1, *p2 = *pCode2; FormulaTokenRef p = ExtendRangeReference( *p1, *p2); if (!p) return false; _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
