diff options
author | Eike Rathke <erack@redhat.com> | 2013-01-11 16:50:48 +0100 |
---|---|---|
committer | Eike Rathke <erack@redhat.com> | 2013-01-11 17:01:44 +0100 |
commit | 3914d00c32c4226d3a73ffdd8985c887016887e0 (patch) | |
tree | 214d06dd8f9a28e8196ba7d26275d4bd16179ae2 /formula | |
parent | 5fd9feafa5d73121636af9397d42e046cc394719 (diff) |
fdo#56124 changes to "add functions IFERROR and IFNA"
* reimplemented actual ScIfError() function for matrix cases and simpler
pop/push of non-error values
* various smaller adaptions, see also inline comments of
https://gerrit.libreoffice.org/1522
Change-Id: I80a8235a2cbb548c0ef993862e76741af46e30d2
Diffstat (limited to 'formula')
-rw-r--r-- | formula/inc/formula/errorcodes.hxx | 3 | ||||
-rw-r--r-- | formula/source/core/api/FormulaCompiler.cxx | 69 |
2 files changed, 57 insertions, 15 deletions
diff --git a/formula/inc/formula/errorcodes.hxx b/formula/inc/formula/errorcodes.hxx index a99dc7b9d4e0..1e145e04132b 100644 --- a/formula/inc/formula/errorcodes.hxx +++ b/formula/inc/formula/errorcodes.hxx @@ -72,6 +72,9 @@ const sal_uInt16 errNestedArray = 533; // be used to distinguish that condition from all other (inherited) errors. Do // not use for anything else! Never push or inherit the error otherwise! const sal_uInt16 errNotNumericString = 534; +// ScInterpreter internal: jump matrix already has a result at this position, +// do not overwrite in case of empty code path. +const sal_uInt16 errJumpMatHasResult = 535; // Interpreter: NA() not available condition, not a real error const sal_uInt16 NOTAVAILABLE = 0x7fff; diff --git a/formula/source/core/api/FormulaCompiler.cxx b/formula/source/core/api/FormulaCompiler.cxx index e91912368a5c..d4d69ddbd84b 100644 --- a/formula/source/core/api/FormulaCompiler.cxx +++ b/formula/source/core/api/FormulaCompiler.cxx @@ -1179,12 +1179,21 @@ void FormulaCompiler::Factor() { // the PC counters are -1 pFacToken = mpToken; - if ( eOp == ocIf ) - pFacToken->GetJump()[ 0 ] = 3; // if, else, behind - else if ( eOp == ocChose ) - pFacToken->GetJump()[ 0 ] = MAXJUMPCOUNT+1; - else - pFacToken->GetJump()[ 0 ] = 2; // if, else + switch (eOp) + { + case ocIf: + pFacToken->GetJump()[ 0 ] = 3; // if, else, behind + break; + case ocChose: + pFacToken->GetJump()[ 0 ] = MAXJUMPCOUNT+1; + break; + case ocIfError: + case ocIfNA: + pFacToken->GetJump()[ 0 ] = 2; // if, behind + break; + default: + SAL_WARN( "formula.core", "FormulaCompiler::Factor: forgot to add a jump count case?"); + } eOp = NextToken(); if (eOp == ocOpen) { @@ -1193,15 +1202,30 @@ void FormulaCompiler::Factor() } else SetError(errPairExpected); - short nJumpCount = 0; PutCode( pFacToken ); - // during AutoCorrect (since pArr->GetCodeError() is + // During AutoCorrect (since pArr->GetCodeError() is // ignored) an unlimited ocIf would crash because // ScRawToken::Clone() allocates the JumpBuffer according to // nJump[0]*2+2, which is 3*2+2 on ocIf and 2*2+2 ocIfError and ocIfNA. + short nJumpMax; OpCode eFacOpCode = pFacToken->GetOpCode(); - const short nJumpMax = ( eFacOpCode == ocIf ? 3 : - ( eFacOpCode == ocChose ? MAXJUMPCOUNT : 2 ) ); + switch (eFacOpCode) + { + case ocIf: + nJumpMax = 3; + break; + case ocChose: + nJumpMax = MAXJUMPCOUNT; + break; + case ocIfError: + case ocIfNA: + nJumpMax = 2; + break; + default: + nJumpMax = 0; + SAL_WARN( "formula.core", "FormulaCompiler::Factor: forgot to add a jump max case?"); + } + short nJumpCount = 0; while ( (nJumpCount < (MAXJUMPCOUNT - 1)) && (eOp == ocSep) && (!pArr->GetCodeError() || bIgnoreErrors) ) { @@ -1221,12 +1245,27 @@ void FormulaCompiler::Factor() if ( ++nJumpCount <= nJumpMax ) pFacToken->GetJump()[ nJumpCount ] = pc-1; eFacOpCode = pFacToken->GetOpCode(); - if ( ( eFacOpCode == ocIf && nJumpCount > 3) || - ( ( eFacOpCode == ocIfError || eFacOpCode == ocIfNA ) && nJumpCount > 2 ) || - ( nJumpCount >= MAXJUMPCOUNT ) ) - SetError(errIllegalParameter); - else + bool bLimitOk; + switch (eFacOpCode) + { + case ocIf: + bLimitOk = (nJumpCount <= 3); + break; + case ocChose: + bLimitOk = (nJumpCount < MAXJUMPCOUNT); /* TODO: check, really <, not <=? */ + break; + case ocIfError: + case ocIfNA: + bLimitOk = (nJumpCount <= 2); + break; + default: + bLimitOk = false; + SAL_WARN( "formula.core", "FormulaCompiler::Factor: forgot to add a jump limit case?"); + } + if (bLimitOk) pFacToken->GetJump()[ 0 ] = nJumpCount; + else + SetError(errIllegalParameter); } } else if ( eOp == ocMissing ) |