diff options
30 files changed, 6431 insertions, 6426 deletions
diff --git a/sc/source/core/tool/addincol.cxx b/sc/source/core/tool/addincol.cxx index 48f5d4c03846..fbc9ac23592f 100644 --- a/sc/source/core/tool/addincol.cxx +++ b/sc/source/core/tool/addincol.cxx @@ -537,23 +537,23 @@ void ScUnoAddInCollection::LoadComponent( const ScUnoAddInFuncData& rFuncData ) { const OUString& aFullName = rFuncData.GetOriginalName(); sal_Int32 nPos = aFullName.lastIndexOf( '.' ); - if ( nPos > 0 ) - { - OUString aServiceName = aFullName.copy( 0, nPos ); + if ( nPos <= 0 ) + return; - try - { - uno::Reference<lang::XMultiServiceFactory> xServiceFactory = comphelper::getProcessServiceFactory(); - uno::Reference<uno::XInterface> xInterface( xServiceFactory->createInstance( aServiceName ) ); + OUString aServiceName = aFullName.copy( 0, nPos ); - if (xInterface.is()) - UpdateFromAddIn( xInterface, aServiceName ); - } - catch (const uno::Exception &) - { - SAL_WARN ("sc", "Failed to create addin component '" - << aServiceName << "'"); - } + try + { + uno::Reference<lang::XMultiServiceFactory> xServiceFactory = comphelper::getProcessServiceFactory(); + uno::Reference<uno::XInterface> xInterface( xServiceFactory->createInstance( aServiceName ) ); + + if (xInterface.is()) + UpdateFromAddIn( xInterface, aServiceName ); + } + catch (const uno::Exception &) + { + SAL_WARN ("sc", "Failed to create addin component '" + << aServiceName << "'"); } } @@ -698,216 +698,216 @@ void ScUnoAddInCollection::ReadFromAddIn( const uno::Reference<uno::XInterface>& { uno::Reference<sheet::XAddIn> xAddIn( xInterface, uno::UNO_QUERY ); uno::Reference<lang::XServiceName> xName( xInterface, uno::UNO_QUERY ); - if ( xAddIn.is() && xName.is() ) - { - // fdo50118 when GetUseEnglishFunctionName() returns true, set the - // locale to en-US to get English function names - if ( SC_MOD()->GetFormulaOptions().GetUseEnglishFuncName() ) - xAddIn->setLocale( lang::Locale( "en", "US", "")); - else - xAddIn->setLocale( Application::GetSettings().GetUILanguageTag().getLocale()); + if ( !(xAddIn.is() && xName.is()) ) + return; - OUString aServiceName( xName->getServiceName() ); - ScUnoAddInHelpIdGenerator aHelpIdGenerator( aServiceName ); + // fdo50118 when GetUseEnglishFunctionName() returns true, set the + // locale to en-US to get English function names + if ( SC_MOD()->GetFormulaOptions().GetUseEnglishFuncName() ) + xAddIn->setLocale( lang::Locale( "en", "US", "")); + else + xAddIn->setLocale( Application::GetSettings().GetUILanguageTag().getLocale()); - //TODO: pass XIntrospection to ReadFromAddIn + OUString aServiceName( xName->getServiceName() ); + ScUnoAddInHelpIdGenerator aHelpIdGenerator( aServiceName ); - uno::Reference<uno::XComponentContext> xContext = comphelper::getProcessComponentContext(); + //TODO: pass XIntrospection to ReadFromAddIn - uno::Reference<beans::XIntrospection> xIntro = beans::theIntrospection::get( xContext ); - uno::Any aObject; - aObject <<= xAddIn; - uno::Reference<beans::XIntrospectionAccess> xAcc = xIntro->inspect(aObject); - if (xAcc.is()) + uno::Reference<uno::XComponentContext> xContext = comphelper::getProcessComponentContext(); + + uno::Reference<beans::XIntrospection> xIntro = beans::theIntrospection::get( xContext ); + uno::Any aObject; + aObject <<= xAddIn; + uno::Reference<beans::XIntrospectionAccess> xAcc = xIntro->inspect(aObject); + if (!xAcc.is()) + return; + + uno::Sequence< uno::Reference<reflection::XIdlMethod> > aMethods = + xAcc->getMethods( beans::MethodConcept::ALL ); + long nNewCount = aMethods.getLength(); + if ( !nNewCount ) + return; + + long nOld = nFuncCount; + nFuncCount = nNewCount+nOld; + if ( nOld ) + { + std::unique_ptr<std::unique_ptr<ScUnoAddInFuncData>[]> ppNew(new std::unique_ptr<ScUnoAddInFuncData>[nFuncCount]); + for (long i=0; i<nOld; i++) + ppNew[i] = std::move(ppFuncData[i]); + ppFuncData = std::move(ppNew); + } + else + ppFuncData.reset(new std::unique_ptr<ScUnoAddInFuncData>[nFuncCount]); + + //TODO: adjust bucket count? + if ( !pExactHashMap ) + pExactHashMap.reset( new ScAddInHashMap ); + if ( !pNameHashMap ) + pNameHashMap.reset( new ScAddInHashMap ); + if ( !pLocalHashMap ) + pLocalHashMap.reset( new ScAddInHashMap ); + + const uno::Reference<reflection::XIdlMethod>* pArray = aMethods.getConstArray(); + for (long nFuncPos=0; nFuncPos<nNewCount; nFuncPos++) + { + ppFuncData[nFuncPos+nOld] = nullptr; + + uno::Reference<reflection::XIdlMethod> xFunc = pArray[nFuncPos]; + if (xFunc.is()) { - uno::Sequence< uno::Reference<reflection::XIdlMethod> > aMethods = - xAcc->getMethods( beans::MethodConcept::ALL ); - long nNewCount = aMethods.getLength(); - if ( nNewCount ) + // leave out internal functions + uno::Reference<reflection::XIdlClass> xClass = + xFunc->getDeclaringClass(); + bool bSkip = true; + if ( xClass.is() ) { - long nOld = nFuncCount; - nFuncCount = nNewCount+nOld; - if ( nOld ) + //TODO: XIdlClass needs getType() method! + OUString sName = xClass->getName(); + bSkip = ( + IsTypeName( sName, + cppu::UnoType<uno::XInterface>::get()) || + IsTypeName( sName, + cppu::UnoType<lang::XServiceName>::get()) || + IsTypeName( sName, + cppu::UnoType<lang::XServiceInfo>::get()) || + IsTypeName( sName, + cppu::UnoType<sheet::XAddIn>::get()) ); + } + if (!bSkip) + { + uno::Reference<reflection::XIdlClass> xReturn = + xFunc->getReturnType(); + if ( !lcl_ValidReturnType( xReturn ) ) + bSkip = true; + } + if (!bSkip) + { + OUString aFuncU = xFunc->getName(); + + // stored function name: (service name).(function) + OUString aFuncName = aServiceName + "." + aFuncU; + + bool bValid = true; + long nVisibleCount = 0; + long nCallerPos = SC_CALLERPOS_NONE; + + uno::Sequence<reflection::ParamInfo> aParams = + xFunc->getParameterInfos(); + long nParamCount = aParams.getLength(); + const reflection::ParamInfo* pParArr = aParams.getConstArray(); + long nParamPos; + for (nParamPos=0; nParamPos<nParamCount; nParamPos++) { - std::unique_ptr<std::unique_ptr<ScUnoAddInFuncData>[]> ppNew(new std::unique_ptr<ScUnoAddInFuncData>[nFuncCount]); - for (long i=0; i<nOld; i++) - ppNew[i] = std::move(ppFuncData[i]); - ppFuncData = std::move(ppNew); + if ( pParArr[nParamPos].aMode != reflection::ParamMode_IN ) + bValid = false; + uno::Reference<reflection::XIdlClass> xParClass = + pParArr[nParamPos].aType; + ScAddInArgumentType eArgType = lcl_GetArgType( xParClass ); + if ( eArgType == SC_ADDINARG_NONE ) + bValid = false; + else if ( eArgType == SC_ADDINARG_CALLER ) + nCallerPos = nParamPos; + else + ++nVisibleCount; } - else - ppFuncData.reset(new std::unique_ptr<ScUnoAddInFuncData>[nFuncCount]); - - //TODO: adjust bucket count? - if ( !pExactHashMap ) - pExactHashMap.reset( new ScAddInHashMap ); - if ( !pNameHashMap ) - pNameHashMap.reset( new ScAddInHashMap ); - if ( !pLocalHashMap ) - pLocalHashMap.reset( new ScAddInHashMap ); - - const uno::Reference<reflection::XIdlMethod>* pArray = aMethods.getConstArray(); - for (long nFuncPos=0; nFuncPos<nNewCount; nFuncPos++) + if (bValid) { - ppFuncData[nFuncPos+nOld] = nullptr; + sal_uInt16 nCategory = lcl_GetCategory( + xAddIn->getProgrammaticCategoryName( aFuncU ) ); - uno::Reference<reflection::XIdlMethod> xFunc = pArray[nFuncPos]; - if (xFunc.is()) - { - // leave out internal functions - uno::Reference<reflection::XIdlClass> xClass = - xFunc->getDeclaringClass(); - bool bSkip = true; - if ( xClass.is() ) - { - //TODO: XIdlClass needs getType() method! - OUString sName = xClass->getName(); - bSkip = ( - IsTypeName( sName, - cppu::UnoType<uno::XInterface>::get()) || - IsTypeName( sName, - cppu::UnoType<lang::XServiceName>::get()) || - IsTypeName( sName, - cppu::UnoType<lang::XServiceInfo>::get()) || - IsTypeName( sName, - cppu::UnoType<sheet::XAddIn>::get()) ); - } - if (!bSkip) - { - uno::Reference<reflection::XIdlClass> xReturn = - xFunc->getReturnType(); - if ( !lcl_ValidReturnType( xReturn ) ) - bSkip = true; - } - if (!bSkip) - { - OUString aFuncU = xFunc->getName(); + OString sHelpId = aHelpIdGenerator.GetHelpId( aFuncU ); - // stored function name: (service name).(function) - OUString aFuncName = aServiceName + "." + aFuncU; + OUString aLocalName; + try + { + aLocalName = xAddIn-> + getDisplayFunctionName( aFuncU ); + } + catch(uno::Exception&) + { + aLocalName = "###"; + } - bool bValid = true; - long nVisibleCount = 0; - long nCallerPos = SC_CALLERPOS_NONE; + OUString aDescription; + try + { + aDescription = xAddIn-> + getFunctionDescription( aFuncU ); + } + catch(uno::Exception&) + { + aDescription = "###"; + } - uno::Sequence<reflection::ParamInfo> aParams = - xFunc->getParameterInfos(); - long nParamCount = aParams.getLength(); - const reflection::ParamInfo* pParArr = aParams.getConstArray(); - long nParamPos; - for (nParamPos=0; nParamPos<nParamCount; nParamPos++) - { - if ( pParArr[nParamPos].aMode != reflection::ParamMode_IN ) - bValid = false; - uno::Reference<reflection::XIdlClass> xParClass = - pParArr[nParamPos].aType; - ScAddInArgumentType eArgType = lcl_GetArgType( xParClass ); - if ( eArgType == SC_ADDINARG_NONE ) - bValid = false; - else if ( eArgType == SC_ADDINARG_CALLER ) - nCallerPos = nParamPos; - else - ++nVisibleCount; - } - if (bValid) + std::unique_ptr<ScAddInArgDesc[]> pVisibleArgs; + if ( nVisibleCount > 0 ) + { + ScAddInArgDesc aDesc; + pVisibleArgs.reset(new ScAddInArgDesc[nVisibleCount]); + long nDestPos = 0; + for (nParamPos=0; nParamPos<nParamCount; nParamPos++) + { + uno::Reference<reflection::XIdlClass> xParClass = + pParArr[nParamPos].aType; + ScAddInArgumentType eArgType = lcl_GetArgType( xParClass ); + if ( eArgType != SC_ADDINARG_CALLER ) { - sal_uInt16 nCategory = lcl_GetCategory( - xAddIn->getProgrammaticCategoryName( aFuncU ) ); - - OString sHelpId = aHelpIdGenerator.GetHelpId( aFuncU ); - - OUString aLocalName; + OUString aArgName; try { - aLocalName = xAddIn-> - getDisplayFunctionName( aFuncU ); + aArgName = xAddIn-> + getDisplayArgumentName( aFuncU, nParamPos ); } catch(uno::Exception&) { - aLocalName = "###"; + aArgName = "###"; } - - OUString aDescription; + OUString aArgDesc; try { - aDescription = xAddIn-> - getFunctionDescription( aFuncU ); + aArgDesc = xAddIn-> + getArgumentDescription( aFuncU, nParamPos ); } catch(uno::Exception&) { - aDescription = "###"; + aArgDesc = "###"; } - std::unique_ptr<ScAddInArgDesc[]> pVisibleArgs; - if ( nVisibleCount > 0 ) - { - ScAddInArgDesc aDesc; - pVisibleArgs.reset(new ScAddInArgDesc[nVisibleCount]); - long nDestPos = 0; - for (nParamPos=0; nParamPos<nParamCount; nParamPos++) - { - uno::Reference<reflection::XIdlClass> xParClass = - pParArr[nParamPos].aType; - ScAddInArgumentType eArgType = lcl_GetArgType( xParClass ); - if ( eArgType != SC_ADDINARG_CALLER ) - { - OUString aArgName; - try - { - aArgName = xAddIn-> - getDisplayArgumentName( aFuncU, nParamPos ); - } - catch(uno::Exception&) - { - aArgName = "###"; - } - OUString aArgDesc; - try - { - aArgDesc = xAddIn-> - getArgumentDescription( aFuncU, nParamPos ); - } - catch(uno::Exception&) - { - aArgDesc = "###"; - } - - bool bOptional = - ( eArgType == SC_ADDINARG_VALUE_OR_ARRAY || - eArgType == SC_ADDINARG_VARARGS ); - - aDesc.eType = eArgType; - aDesc.aName = aArgName; - aDesc.aDescription = aArgDesc; - aDesc.bOptional = bOptional; - //TODO: initialize aInternalName only from config? - aDesc.aInternalName = pParArr[nParamPos].aName; - - pVisibleArgs[nDestPos++] = aDesc; - } - } - OSL_ENSURE( nDestPos==nVisibleCount, "wrong count" ); - } + bool bOptional = + ( eArgType == SC_ADDINARG_VALUE_OR_ARRAY || + eArgType == SC_ADDINARG_VARARGS ); + + aDesc.eType = eArgType; + aDesc.aName = aArgName; + aDesc.aDescription = aArgDesc; + aDesc.bOptional = bOptional; + //TODO: initialize aInternalName only from config? + aDesc.aInternalName = pParArr[nParamPos].aName; - ppFuncData[nFuncPos+nOld].reset( new ScUnoAddInFuncData( - aFuncName, aLocalName, aDescription, - nCategory, sHelpId, - xFunc, aObject, - nVisibleCount, pVisibleArgs.get(), nCallerPos ) ); - - const ScUnoAddInFuncData* pData = - ppFuncData[nFuncPos+nOld].get(); - pExactHashMap->emplace( - pData->GetOriginalName(), - pData ); - pNameHashMap->emplace( - pData->GetUpperName(), - pData ); - pLocalHashMap->emplace( - pData->GetUpperLocal(), - pData ); + pVisibleArgs[nDestPos++] = aDesc; } } + OSL_ENSURE( nDestPos==nVisibleCount, "wrong count" ); } + + ppFuncData[nFuncPos+nOld].reset( new ScUnoAddInFuncData( + aFuncName, aLocalName, aDescription, + nCategory, sHelpId, + xFunc, aObject, + nVisibleCount, pVisibleArgs.get(), nCallerPos ) ); + + const ScUnoAddInFuncData* pData = + ppFuncData[nFuncPos+nOld].get(); + pExactHashMap->emplace( + pData->GetOriginalName(), + pData ); + pNameHashMap->emplace( + pData->GetUpperName(), + pData ); + pLocalHashMap->emplace( + pData->GetUpperLocal(), + pData ); } } } @@ -970,97 +970,97 @@ void ScUnoAddInCollection::UpdateFromAddIn( const uno::Reference<uno::XInterface uno::Any aObject; aObject <<= xInterface; uno::Reference<beans::XIntrospectionAccess> xAcc = xIntro->inspect(aObject); - if (xAcc.is()) + if (!xAcc.is()) + return; + + const uno::Sequence< uno::Reference<reflection::XIdlMethod> > aMethods = + xAcc->getMethods( beans::MethodConcept::ALL ); + for (const uno::Reference<reflection::XIdlMethod>& xFunc : aMethods) { - const uno::Sequence< uno::Reference<reflection::XIdlMethod> > aMethods = - xAcc->getMethods( beans::MethodConcept::ALL ); - for (const uno::Reference<reflection::XIdlMethod>& xFunc : aMethods) + if (xFunc.is()) { - if (xFunc.is()) + OUString aFuncU = xFunc->getName(); + + // stored function name: (service name).(function) + OUString aFuncName = rServiceName + "." + aFuncU; + + // internal names are skipped because no FuncData exists + ScUnoAddInFuncData* pOldData = const_cast<ScUnoAddInFuncData*>( GetFuncData( aFuncName ) ); + if ( pOldData ) { - OUString aFuncU = xFunc->getName(); + // Create new (complete) argument info. + // As in ReadFromAddIn, the reflection information is authoritative. + // Local names and descriptions from pOldData are looked up using the + // internal argument name. - // stored function name: (service name).(function) - OUString aFuncName = rServiceName + "." + aFuncU; + bool bValid = true; + long nVisibleCount = 0; + long nCallerPos = SC_CALLERPOS_NONE; - // internal names are skipped because no FuncData exists - ScUnoAddInFuncData* pOldData = const_cast<ScUnoAddInFuncData*>( GetFuncData( aFuncName ) ); - if ( pOldData ) + const uno::Sequence<reflection::ParamInfo> aParams = + xFunc->getParameterInfos(); + long nParamCount = aParams.getLength(); + const reflection::ParamInfo* pParArr = aParams.getConstArray(); + for (long nParamPos=0; nParamPos<nParamCount; nParamPos++) { - // Create new (complete) argument info. - // As in ReadFromAddIn, the reflection information is authoritative. - // Local names and descriptions from pOldData are looked up using the - // internal argument name. - - bool bValid = true; - long nVisibleCount = 0; - long nCallerPos = SC_CALLERPOS_NONE; - - const uno::Sequence<reflection::ParamInfo> aParams = - xFunc->getParameterInfos(); - long nParamCount = aParams.getLength(); - const reflection::ParamInfo* pParArr = aParams.getConstArray(); - for (long nParamPos=0; nParamPos<nParamCount; nParamPos++) - { - if ( pParArr[nParamPos].aMode != reflection::ParamMode_IN ) - bValid = false; - uno::Reference<reflection::XIdlClass> xParClass = - pParArr[nParamPos].aType; - ScAddInArgumentType eArgType = lcl_GetArgType( xParClass ); - if ( eArgType == SC_ADDINARG_NONE ) - bValid = false; - else if ( eArgType == SC_ADDINARG_CALLER ) - nCallerPos = nParamPos; - else - ++nVisibleCount; - } - if (bValid) + if ( pParArr[nParamPos].aMode != reflection::ParamMode_IN ) + bValid = false; + uno::Reference<reflection::XIdlClass> xParClass = + pParArr[nParamPos].aType; + ScAddInArgumentType eArgType = lcl_GetArgType( xParClass ); + if ( eArgType == SC_ADDINARG_NONE ) + bValid = false; + else if ( eArgType == SC_ADDINARG_CALLER ) + nCallerPos = nParamPos; + else + ++nVisibleCount; + } + if (bValid) + { + std::unique_ptr<ScAddInArgDesc[]> pVisibleArgs; + if ( nVisibleCount > 0 ) { - std::unique_ptr<ScAddInArgDesc[]> pVisibleArgs; - if ( nVisibleCount > 0 ) + ScAddInArgDesc aDesc; + pVisibleArgs.reset(new ScAddInArgDesc[nVisibleCount]); + long nDestPos = 0; + for (const auto& rParam : aParams) { - ScAddInArgDesc aDesc; - pVisibleArgs.reset(new ScAddInArgDesc[nVisibleCount]); - long nDestPos = 0; - for (const auto& rParam : aParams) + uno::Reference<reflection::XIdlClass> xParClass = + rParam.aType; + ScAddInArgumentType eArgType = lcl_GetArgType( xParClass ); + if ( eArgType != SC_ADDINARG_CALLER ) { - uno::Reference<reflection::XIdlClass> xParClass = - rParam.aType; - ScAddInArgumentType eArgType = lcl_GetArgType( xParClass ); - if ( eArgType != SC_ADDINARG_CALLER ) + const ScAddInArgDesc* pOldArgDesc = + lcl_FindArgDesc( *pOldData, rParam.aName ); + if ( pOldArgDesc ) { - const ScAddInArgDesc* pOldArgDesc = - lcl_FindArgDesc( *pOldData, rParam.aName ); - if ( pOldArgDesc ) - { - aDesc.aName = pOldArgDesc->aName; - aDesc.aDescription = pOldArgDesc->aDescription; - } - else - aDesc.aName = aDesc.aDescription = "###"; - - bool bOptional = - ( eArgType == SC_ADDINARG_VALUE_OR_ARRAY || - eArgType == SC_ADDINARG_VARARGS ); - - aDesc.eType = eArgType; - aDesc.bOptional = bOptional; - //TODO: initialize aInternalName only from config? - aDesc.aInternalName = rParam.aName; - - pVisibleArgs[nDestPos++] = aDesc; + aDesc.aName = pOldArgDesc->aName; + aDesc.aDescription = pOldArgDesc->aDescription; } + else + aDesc.aName = aDesc.aDescription = "###"; + + bool bOptional = + ( eArgType == SC_ADDINARG_VALUE_OR_ARRAY || + eArgType == SC_ADDINARG_VARARGS ); + + aDesc.eType = eArgType; + aDesc.bOptional = bOptional; + //TODO: initialize aInternalName only from config? + aDesc.aInternalName = rParam.aName; + + pVisibleArgs[nDestPos++] = aDesc; } - OSL_ENSURE( nDestPos==nVisibleCount, "wrong count" ); } + OSL_ENSURE( nDestPos==nVisibleCount, "wrong count" ); + } - pOldData->SetFunction( xFunc, aObject ); - pOldData->SetArguments( nVisibleCount, pVisibleArgs.get() ); - pOldData->SetCallerPos( nCallerPos ); + pOldData->SetFunction( xFunc, aObject ); + pOldData->SetArguments( nVisibleCount, pVisibleArgs.get() ); + pOldData->SetCallerPos( nCallerPos ); - if ( pFunctionList ) - lcl_UpdateFunctionList( *pFunctionList, *pOldData ); - } + if ( pFunctionList ) + lcl_UpdateFunctionList( *pFunctionList, *pOldData ); } } } @@ -1240,32 +1240,32 @@ ScUnoAddInCall::ScUnoAddInCall( ScUnoAddInCollection& rColl, const OUString& rNa { pFuncData = rColl.GetFuncData( rName, true ); // need fully initialized data OSL_ENSURE( pFuncData, "Function Data missing" ); - if ( pFuncData ) - { - long nDescCount = pFuncData->GetArgumentCount(); - const ScAddInArgDesc* pArgs = pFuncData->GetArguments(); + if ( !pFuncData ) + return; - // is aVarArg sequence needed? - if ( nParamCount >= nDescCount && nDescCount > 0 && - pArgs[nDescCount-1].eType == SC_ADDINARG_VARARGS ) - { - long nVarCount = nParamCount - ( nDescCount - 1 ); // size of last argument - aVarArg.realloc( nVarCount ); - bValidCount = true; - } - else if ( nParamCount <= nDescCount ) - { - // all args behind nParamCount must be optional - bValidCount = true; - for (long i=nParamCount; i<nDescCount; i++) - if ( !pArgs[i].bOptional ) - bValidCount = false; - } - // else invalid (too many arguments) + long nDescCount = pFuncData->GetArgumentCount(); + const ScAddInArgDesc* pArgs = pFuncData->GetArguments(); - if ( bValidCount ) - aArgs.realloc( nDescCount ); // sequence must always match function signature + // is aVarArg sequence needed? + if ( nParamCount >= nDescCount && nDescCount > 0 && + pArgs[nDescCount-1].eType == SC_ADDINARG_VARARGS ) + { + long nVarCount = nParamCount - ( nDescCount - 1 ); // size of last argument + aVarArg.realloc( nVarCount ); + bValidCount = true; + } + else if ( nParamCount <= nDescCount ) + { + // all args behind nParamCount must be optional + bValidCount = true; + for (long i=nParamCount; i<nDescCount; i++) + if ( !pArgs[i].bOptional ) + bValidCount = false; } + // else invalid (too many arguments) + + if ( bValidCount ) + aArgs.realloc( nDescCount ); // sequence must always match function signature } ScUnoAddInCall::~ScUnoAddInCall() @@ -1311,27 +1311,27 @@ void ScUnoAddInCall::SetCallerFromObjectShell( const SfxObjectShell* pObjSh ) void ScUnoAddInCall::SetParam( long nPos, const uno::Any& rValue ) { - if ( pFuncData ) + if ( !pFuncData ) + return; + + long nCount = pFuncData->GetArgumentCount(); + const ScAddInArgDesc* pArgs = pFuncData->GetArguments(); + if ( nCount > 0 && nPos >= nCount-1 && pArgs[nCount-1].eType == SC_ADDINARG_VARARGS ) { - long nCount = pFuncData->GetArgumentCount(); - const ScAddInArgDesc* pArgs = pFuncData->GetArguments(); - if ( nCount > 0 && nPos >= nCount-1 && pArgs[nCount-1].eType == SC_ADDINARG_VARARGS ) - { - long nVarPos = nPos-(nCount-1); - if ( nVarPos < aVarArg.getLength() ) - aVarArg.getArray()[nVarPos] = rValue; - else - { - OSL_FAIL("wrong argument number"); - } - } - else if ( nPos < aArgs.getLength() ) - aArgs.getArray()[nPos] = rValue; + long nVarPos = nPos-(nCount-1); + if ( nVarPos < aVarArg.getLength() ) + aVarArg.getArray()[nVarPos] = rValue; else { OSL_FAIL("wrong argument number"); } } + else if ( nPos < aArgs.getLength() ) + aArgs.getArray()[nPos] = rValue; + else + { + OSL_FAIL("wrong argument number"); + } } void ScUnoAddInCall::ExecuteCall() @@ -1389,38 +1389,38 @@ void ScUnoAddInCall::ExecuteCallWithArgs(uno::Sequence<uno::Any>& rCallArgs) aObject = pFuncData->GetObject(); } - if ( xFunction.is() ) - { - uno::Any aAny; - nErrCode = FormulaError::NONE; + if ( !xFunction.is() ) + return; - try - { - aAny = xFunction->invoke( aObject, rCallArgs ); - } - catch(lang::IllegalArgumentException&) - { + uno::Any aAny; + nErrCode = FormulaError::NONE; + + try + { + aAny = xFunction->invoke( aObject, rCallArgs ); + } + catch(lang::IllegalArgumentException&) + { + nErrCode = FormulaError::IllegalArgument; + } + catch(const reflection::InvocationTargetException& rWrapped) + { + if ( rWrapped.TargetException.getValueType().equals( + cppu::UnoType<lang::IllegalArgumentException>::get()) ) nErrCode = FormulaError::IllegalArgument; - } - catch(const reflection::InvocationTargetException& rWrapped) - { - if ( rWrapped.TargetException.getValueType().equals( - cppu::UnoType<lang::IllegalArgumentException>::get()) ) - nErrCode = FormulaError::IllegalArgument; - else if ( rWrapped.TargetException.getValueType().equals( - cppu::UnoType<sheet::NoConvergenceException>::get()) ) - nErrCode = FormulaError::NoConvergence; - else - nErrCode = FormulaError::NoValue; - } - catch(uno::Exception&) - { + else if ( rWrapped.TargetException.getValueType().equals( + cppu::UnoType<sheet::NoConvergenceException>::get()) ) + nErrCode = FormulaError::NoConvergence; + else nErrCode = FormulaError::NoValue; - } - - if (nErrCode == FormulaError::NONE) - SetResult( aAny ); // convert result to Calc types } + catch(uno::Exception&) + { + nErrCode = FormulaError::NoValue; + } + + if (nErrCode == FormulaError::NONE) + SetResult( aAny ); // convert result to Calc types } template <typename T> diff --git a/sc/source/core/tool/address.cxx b/sc/source/core/tool/address.cxx index 0d75dfe4a816..be7beec97d83 100644 --- a/sc/source/core/tool/address.cxx +++ b/sc/source/core/tool/address.cxx @@ -2156,42 +2156,42 @@ static void lcl_ScRange_Format_XL_Header( OUStringBuffer& rString, const ScRange ScRefFlags nFlags, const ScDocument& rDoc, const ScAddress::Details& rDetails ) { - if( nFlags & ScRefFlags::TAB_3D ) + if( !(nFlags & ScRefFlags::TAB_3D) ) + return; + + OUString aTabName, aDocName; + lcl_Split_DocTab( rDoc, rRange.aStart.Tab(), rDetails, nFlags, aTabName, aDocName ); + switch (rDetails.eConv) { - OUString aTabName, aDocName; - lcl_Split_DocTab( rDoc, rRange.aStart.Tab(), rDetails, nFlags, aTabName, aDocName ); - switch (rDetails.eConv) - { - case formula::FormulaGrammar::CONV_XL_OOX: - if (!aTabName.isEmpty() && aTabName[0] == '\'') + case formula::FormulaGrammar::CONV_XL_OOX: + if (!aTabName.isEmpty() && aTabName[0] == '\'') + { + if (!aDocName.isEmpty()) { - if (!aDocName.isEmpty()) - { - rString.append("'[").append(aDocName).append("]").append(std::u16string_view(aTabName).substr(1)); - } - else - { - rString.append(aTabName); - } - break; + rString.append("'[").append(aDocName).append("]").append(std::u16string_view(aTabName).substr(1)); } - [[fallthrough]]; - default: - if (!aDocName.isEmpty()) + else { - rString.append("[").append(aDocName).append("]"); + rString.append(aTabName); } - rString.append(aTabName); - break; - } - if( nFlags & ScRefFlags::TAB2_3D ) - { - lcl_Split_DocTab( rDoc, rRange.aEnd.Tab(), rDetails, nFlags, aTabName, aDocName ); - rString.append(":"); + break; + } + [[fallthrough]]; + default: + if (!aDocName.isEmpty()) + { + rString.append("[").append(aDocName).append("]"); + } rString.append(aTabName); - } - rString.append("!"); + break; + } + if( nFlags & ScRefFlags::TAB2_3D ) + { + lcl_Split_DocTab( rDoc, rRange.aEnd.Tab(), rDetails, nFlags, aTabName, aDocName ); + rString.append(":"); + rString.append(aTabName); } + rString.append("!"); } // helpers used in ScRange::Format diff --git a/sc/source/core/tool/appoptio.cxx b/sc/source/core/tool/appoptio.cxx index 530a8d9438cb..f66134c0d1c2 100644 --- a/sc/source/core/tool/appoptio.cxx +++ b/sc/source/core/tool/appoptio.cxx @@ -128,18 +128,18 @@ void ScAppOptions::SetLRUFuncList( const sal_uInt16* pList, const sal_uInt16 nCo static void lcl_SetLastFunctions( ScAppOptions& rOpt, const Any& rValue ) { Sequence<sal_Int32> aSeq; - if ( rValue >>= aSeq ) + if ( !(rValue >>= aSeq) ) + return; + + sal_Int32 nCount = aSeq.getLength(); + if ( nCount < SAL_MAX_UINT16 ) { - sal_Int32 nCount = aSeq.getLength(); - if ( nCount < SAL_MAX_UINT16 ) - { - const sal_Int32* pArray = aSeq.getConstArray(); - std::unique_ptr<sal_uInt16[]> pUShorts(new sal_uInt16[nCount]); - for (sal_Int32 i=0; i<nCount; i++) - pUShorts[i] = static_cast<sal_uInt16>(pArray[i]); + const sal_Int32* pArray = aSeq.getConstArray(); + std::unique_ptr<sal_uInt16[]> pUShorts(new sal_uInt16[nCount]); + for (sal_Int32 i=0; i<nCount; i++) + pUShorts[i] = static_cast<sal_uInt16>(pArray[i]); - rOpt.SetLRUFuncList( pUShorts.get(), sal::static_int_cast<sal_uInt16>(nCount) ); - } + rOpt.SetLRUFuncList( pUShorts.get(), sal::static_int_cast<sal_uInt16>(nCount) ); } } @@ -162,29 +162,29 @@ static void lcl_GetLastFunctions( Any& rDest, const ScAppOptions& rOpt ) static void lcl_SetSortList( const Any& rValue ) { Sequence<OUString> aSeq; - if ( rValue >>= aSeq ) - { - long nCount = aSeq.getLength(); - const OUString* pArray = aSeq.getConstArray(); - ScUserList aList; + if ( !(rValue >>= aSeq) ) + return; - // if setting is "default", keep default values from ScUserList ctor - //TODO: mark "default" in a safe way - bool bDefault = ( nCount == 1 && pArray[0] == "NULL" ); + long nCount = aSeq.getLength(); + const OUString* pArray = aSeq.getConstArray(); + ScUserList aList; - if (!bDefault) - { - aList.clear(); + // if setting is "default", keep default values from ScUserList ctor + //TODO: mark "default" in a safe way + bool bDefault = ( nCount == 1 && pArray[0] == "NULL" ); - for (const auto& rStr : std::as_const(aSeq)) - { - ScUserListData* pNew = new ScUserListData( rStr ); - aList.push_back(pNew); - } - } + if (!bDefault) + { + aList.clear(); - ScGlobal::SetUserList( &aList ); + for (const auto& rStr : std::as_const(aSeq)) + { + ScUserListData* pNew = new ScUserListData( rStr ); + aList.push_back(pNew); + } } + + ScGlobal::SetUserList( &aList ); } static void lcl_GetSortList( Any& rDest ) diff --git a/sc/source/core/tool/callform.cxx b/sc/source/core/tool/callform.cxx index 3f5930925724..cbf8ae73a69f 100644 --- a/sc/source/core/tool/callform.cxx +++ b/sc/source/core/tool/callform.cxx @@ -249,74 +249,74 @@ void LegacyFuncData::Call(void** ppParam) const #else osl::Module* pLib = pModuleData->GetInstance(); oslGenericFunction fProc = pLib->getFunctionSymbol(aFuncName); - if (fProc != nullptr) + if (fProc == nullptr) + return; + + switch (nParamCount) { - switch (nParamCount) - { - case 1 : - (*reinterpret_cast<ExFuncPtr1>(fProc))(ppParam[0]); - break; - case 2 : - (*reinterpret_cast<ExFuncPtr2>(fProc))(ppParam[0], ppParam[1]); - break; - case 3 : - (*reinterpret_cast<ExFuncPtr3>(fProc))(ppParam[0], ppParam[1], ppParam[2]); - break; - case 4 : - (*reinterpret_cast<ExFuncPtr4>(fProc))(ppParam[0], ppParam[1], ppParam[2], ppParam[3]); - break; - case 5 : - (*reinterpret_cast<ExFuncPtr5>(fProc))(ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4]); - break; - case 6 : - (*reinterpret_cast<ExFuncPtr6>(fProc))(ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5]); - break; - case 7 : - (*reinterpret_cast<ExFuncPtr7>(fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], - ppParam[6]); - break; - case 8 : - (*reinterpret_cast<ExFuncPtr8>(fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], - ppParam[6], ppParam[7]); - break; - case 9 : - (*reinterpret_cast<ExFuncPtr9>(fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], - ppParam[6], ppParam[7], ppParam[8]); - break; - case 10 : - (*reinterpret_cast<ExFuncPtr10>(fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], - ppParam[6], ppParam[7], ppParam[8], ppParam[9]); - break; - case 11 : - (*reinterpret_cast<ExFuncPtr11>(fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], - ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10]); - break; - case 12: - (*reinterpret_cast<ExFuncPtr12>(fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], - ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11]); - break; - case 13: - (*reinterpret_cast<ExFuncPtr13>(fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], - ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11], - ppParam[12]); - break; - case 14 : - (*reinterpret_cast<ExFuncPtr14>(fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], - ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11], - ppParam[12], ppParam[13]); - break; - case 15 : - (*reinterpret_cast<ExFuncPtr15>(fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], - ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11], - ppParam[12], ppParam[13], ppParam[14]); - break; - case 16 : - (*reinterpret_cast<ExFuncPtr16>(fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], - ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11], - ppParam[12], ppParam[13], ppParam[14], ppParam[15]); - break; - default : break; - } + case 1 : + (*reinterpret_cast<ExFuncPtr1>(fProc))(ppParam[0]); + break; + case 2 : + (*reinterpret_cast<ExFuncPtr2>(fProc))(ppParam[0], ppParam[1]); + break; + case 3 : + (*reinterpret_cast<ExFuncPtr3>(fProc))(ppParam[0], ppParam[1], ppParam[2]); + break; + case 4 : + (*reinterpret_cast<ExFuncPtr4>(fProc))(ppParam[0], ppParam[1], ppParam[2], ppParam[3]); + break; + case 5 : + (*reinterpret_cast<ExFuncPtr5>(fProc))(ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4]); + break; + case 6 : + (*reinterpret_cast<ExFuncPtr6>(fProc))(ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5]); + break; + case 7 : + (*reinterpret_cast<ExFuncPtr7>(fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], + ppParam[6]); + break; + case 8 : + (*reinterpret_cast<ExFuncPtr8>(fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], + ppParam[6], ppParam[7]); + break; + case 9 : + (*reinterpret_cast<ExFuncPtr9>(fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], + ppParam[6], ppParam[7], ppParam[8]); + break; + case 10 : + (*reinterpret_cast<ExFuncPtr10>(fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], + ppParam[6], ppParam[7], ppParam[8], ppParam[9]); + break; + case 11 : + (*reinterpret_cast<ExFuncPtr11>(fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], + ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10]); + break; + case 12: + (*reinterpret_cast<ExFuncPtr12>(fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], + ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11]); + break; + case 13: + (*reinterpret_cast<ExFuncPtr13>(fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], + ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11], + ppParam[12]); + break; + case 14 : + (*reinterpret_cast<ExFuncPtr14>(fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], + ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11], + ppParam[12], ppParam[13]); + break; + case 15 : + (*reinterpret_cast<ExFuncPtr15>(fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], + ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11], + ppParam[12], ppParam[13], ppParam[14]); + break; + case 16 : + (*reinterpret_cast<ExFuncPtr16>(fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], + ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11], + ppParam[12], ppParam[13], ppParam[14], ppParam[15]); + break; + default : break; } #endif } diff --git a/sc/source/core/tool/charthelper.cxx b/sc/source/core/tool/charthelper.cxx index 6acca9ce3666..cb31f2c7468f 100644 --- a/sc/source/core/tool/charthelper.cxx +++ b/sc/source/core/tool/charthelper.cxx @@ -118,32 +118,32 @@ void ScChartHelper::AdjustRangesOfChartsOnDestinationPage( const ScDocument* pSr return; SdrPage* pDestPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nDestTab)); - if( pDestPage ) + if( !pDestPage ) + return; + + SdrObjListIter aIter( pDestPage, SdrIterMode::Flat ); + SdrObject* pObject = aIter.Next(); + while( pObject ) { - SdrObjListIter aIter( pDestPage, SdrIterMode::Flat ); - SdrObject* pObject = aIter.Next(); - while( pObject ) + if( pObject->GetObjIdentifier() == OBJ_OLE2 && static_cast<SdrOle2Obj*>(pObject)->IsChart() ) { - if( pObject->GetObjIdentifier() == OBJ_OLE2 && static_cast<SdrOle2Obj*>(pObject)->IsChart() ) + OUString aChartName = static_cast<SdrOle2Obj*>(pObject)->GetPersistName(); + + Reference< chart2::XChartDocument > xChartDoc( pDestDoc->GetChartByName( aChartName ) ); + Reference< chart2::data::XDataReceiver > xReceiver( xChartDoc, uno::UNO_QUERY ); + if( xChartDoc.is() && xReceiver.is() && !xChartDoc->hasInternalDataProvider() ) { - OUString aChartName = static_cast<SdrOle2Obj*>(pObject)->GetPersistName(); + ::std::vector< ScRangeList > aRangesVector; + pDestDoc->GetChartRanges( aChartName, aRangesVector, pSrcDoc ); - Reference< chart2::XChartDocument > xChartDoc( pDestDoc->GetChartByName( aChartName ) ); - Reference< chart2::data::XDataReceiver > xReceiver( xChartDoc, uno::UNO_QUERY ); - if( xChartDoc.is() && xReceiver.is() && !xChartDoc->hasInternalDataProvider() ) + for( ScRangeList& rScRangeList : aRangesVector ) { - ::std::vector< ScRangeList > aRangesVector; - pDestDoc->GetChartRanges( aChartName, aRangesVector, pSrcDoc ); - - for( ScRangeList& rScRangeList : aRangesVector ) - { - lcl_AdjustRanges( rScRangeList, nSrcTab, nDestTab, pDestDoc->GetTableCount() ); - } - pDestDoc->SetChartRanges( aChartName, aRangesVector ); + lcl_AdjustRanges( rScRangeList, nSrcTab, nDestTab, pDestDoc->GetTableCount() ); } + pDestDoc->SetChartRanges( aChartName, aRangesVector ); } - pObject = aIter.Next(); } + pObject = aIter.Next(); } } @@ -156,21 +156,21 @@ void ScChartHelper::UpdateChartsOnDestinationPage( ScDocument* pDestDoc, const S return; SdrPage* pDestPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nDestTab)); - if( pDestPage ) + if( !pDestPage ) + return; + + SdrObjListIter aIter( pDestPage, SdrIterMode::Flat ); + SdrObject* pObject = aIter.Next(); + while( pObject ) { - SdrObjListIter aIter( pDestPage, SdrIterMode::Flat ); - SdrObject* pObject = aIter.Next(); - while( pObject ) + if( pObject->GetObjIdentifier() == OBJ_OLE2 && static_cast<SdrOle2Obj*>(pObject)->IsChart() ) { - if( pObject->GetObjIdentifier() == OBJ_OLE2 && static_cast<SdrOle2Obj*>(pObject)->IsChart() ) - { - OUString aChartName = static_cast<SdrOle2Obj*>(pObject)->GetPersistName(); - Reference< chart2::XChartDocument > xChartDoc( pDestDoc->GetChartByName( aChartName ) ); - Reference< util::XModifiable > xModif(xChartDoc, uno::UNO_QUERY_THROW); - xModif->setModified( true); - } - pObject = aIter.Next(); + OUString aChartName = static_cast<SdrOle2Obj*>(pObject)->GetPersistName(); + Reference< chart2::XChartDocument > xChartDoc( pDestDoc->GetChartByName( aChartName ) ); + Reference< util::XModifiable > xModif(xChartDoc, uno::UNO_QUERY_THROW); + xModif->setModified( true); } + pObject = aIter.Next(); } } @@ -283,44 +283,44 @@ void ScChartHelper::SetChartRanges( const uno::Reference< chart2::XChartDocument void ScChartHelper::AddRangesIfProtectedChart( ScRangeListVector& rRangesVector, const ScDocument* pDocument, SdrObject* pObject ) { - if ( pDocument && pObject && ( pObject->GetObjIdentifier() == OBJ_OLE2 ) ) + if ( !(pDocument && pObject && ( pObject->GetObjIdentifier() == OBJ_OLE2 )) ) + return; + + SdrOle2Obj* pSdrOle2Obj = dynamic_cast< SdrOle2Obj* >( pObject ); + if ( !(pSdrOle2Obj && pSdrOle2Obj->IsChart()) ) + return; + + const uno::Reference< embed::XEmbeddedObject >& xEmbeddedObj = pSdrOle2Obj->GetObjRef(); + if ( !xEmbeddedObj.is() ) + return; + + bool bDisableDataTableDialog = false; + sal_Int32 nOldState = xEmbeddedObj->getCurrentState(); + svt::EmbeddedObjectRef::TryRunningState( xEmbeddedObj ); + uno::Reference< beans::XPropertySet > xProps( xEmbeddedObj->getComponent(), uno::UNO_QUERY ); + if ( xProps.is() && + ( xProps->getPropertyValue("DisableDataTableDialog") >>= bDisableDataTableDialog ) && + bDisableDataTableDialog ) { - SdrOle2Obj* pSdrOle2Obj = dynamic_cast< SdrOle2Obj* >( pObject ); - if ( pSdrOle2Obj && pSdrOle2Obj->IsChart() ) + ScChartListenerCollection* pCollection = pDocument->GetChartListenerCollection(); + if (pCollection) { - const uno::Reference< embed::XEmbeddedObject >& xEmbeddedObj = pSdrOle2Obj->GetObjRef(); - if ( xEmbeddedObj.is() ) + const OUString& aChartName = pSdrOle2Obj->GetPersistName(); + const ScChartListener* pListener = pCollection->findByName(aChartName); + if (pListener) { - bool bDisableDataTableDialog = false; - sal_Int32 nOldState = xEmbeddedObj->getCurrentState(); - svt::EmbeddedObjectRef::TryRunningState( xEmbeddedObj ); - uno::Reference< beans::XPropertySet > xProps( xEmbeddedObj->getComponent(), uno::UNO_QUERY ); - if ( xProps.is() && - ( xProps->getPropertyValue("DisableDataTableDialog") >>= bDisableDataTableDialog ) && - bDisableDataTableDialog ) - { - ScChartListenerCollection* pCollection = pDocument->GetChartListenerCollection(); - if (pCollection) - { - const OUString& aChartName = pSdrOle2Obj->GetPersistName(); - const ScChartListener* pListener = pCollection->findByName(aChartName); - if (pListener) - { - const ScRangeListRef& rRangeList = pListener->GetRangeList(); - if ( rRangeList.is() ) - { - rRangesVector.push_back( *rRangeList ); - } - } - } - } - if ( xEmbeddedObj->getCurrentState() != nOldState ) + const ScRangeListRef& rRangeList = pListener->GetRangeList(); + if ( rRangeList.is() ) { - xEmbeddedObj->changeState( nOldState ); + rRangesVector.push_back( *rRangeList ); } } } } + if ( xEmbeddedObj->getCurrentState() != nOldState ) + { + xEmbeddedObj->changeState( nOldState ); + } } void ScChartHelper::FillProtectedChartRangesVector( ScRangeListVector& rRangesVector, const ScDocument* pDocument, const SdrPage* pPage ) @@ -339,95 +339,95 @@ void ScChartHelper::FillProtectedChartRangesVector( ScRangeListVector& rRangesVe void ScChartHelper::GetChartNames( ::std::vector< OUString >& rChartNames, const SdrPage* pPage ) { - if ( pPage ) + if ( !pPage ) + return; + + SdrObjListIter aIter( pPage, SdrIterMode::DeepNoGroups ); + SdrObject* pObject = aIter.Next(); + while ( pObject ) { - SdrObjListIter aIter( pPage, SdrIterMode::DeepNoGroups ); - SdrObject* pObject = aIter.Next(); - while ( pObject ) + if ( pObject->GetObjIdentifier() == OBJ_OLE2 ) { - if ( pObject->GetObjIdentifier() == OBJ_OLE2 ) + SdrOle2Obj* pSdrOle2Obj = dynamic_cast< SdrOle2Obj* >( pObject ); + if ( pSdrOle2Obj && pSdrOle2Obj->IsChart() ) { - SdrOle2Obj* pSdrOle2Obj = dynamic_cast< SdrOle2Obj* >( pObject ); - if ( pSdrOle2Obj && pSdrOle2Obj->IsChart() ) - { - rChartNames.push_back( pSdrOle2Obj->GetPersistName() ); - } + rChartNames.push_back( pSdrOle2Obj->GetPersistName() ); } - pObject = aIter.Next(); } + pObject = aIter.Next(); } } void ScChartHelper::CreateProtectedChartListenersAndNotify( ScDocument* pDoc, const SdrPage* pPage, ScModelObj* pModelObj, SCTAB nTab, const ScRangeListVector& rRangesVector, const ::std::vector< OUString >& rExcludedChartNames, bool bSameDoc ) { - if ( pDoc && pPage && pModelObj ) + if ( !(pDoc && pPage && pModelObj) ) + return; + + size_t nRangeListCount = rRangesVector.size(); + size_t nRangeList = 0; + SdrObjListIter aIter( pPage, SdrIterMode::DeepNoGroups ); + SdrObject* pObject = aIter.Next(); + while ( pObject ) { - size_t nRangeListCount = rRangesVector.size(); - size_t nRangeList = 0; - SdrObjListIter aIter( pPage, SdrIterMode::DeepNoGroups ); - SdrObject* pObject = aIter.Next(); - while ( pObject ) + if ( pObject->GetObjIdentifier() == OBJ_OLE2 ) { - if ( pObject->GetObjIdentifier() == OBJ_OLE2 ) + SdrOle2Obj* pSdrOle2Obj = dynamic_cast< SdrOle2Obj* >( pObject ); + if ( pSdrOle2Obj && pSdrOle2Obj->IsChart() ) { - SdrOle2Obj* pSdrOle2Obj = dynamic_cast< SdrOle2Obj* >( pObject ); - if ( pSdrOle2Obj && pSdrOle2Obj->IsChart() ) + const OUString& aChartName = pSdrOle2Obj->GetPersistName(); + ::std::vector< OUString >::const_iterator aEnd = rExcludedChartNames.end(); + ::std::vector< OUString >::const_iterator aFound = ::std::find( rExcludedChartNames.begin(), aEnd, aChartName ); + if ( aFound == aEnd ) { - const OUString& aChartName = pSdrOle2Obj->GetPersistName(); - ::std::vector< OUString >::const_iterator aEnd = rExcludedChartNames.end(); - ::std::vector< OUString >::const_iterator aFound = ::std::find( rExcludedChartNames.begin(), aEnd, aChartName ); - if ( aFound == aEnd ) + const uno::Reference< embed::XEmbeddedObject >& xEmbeddedObj = pSdrOle2Obj->GetObjRef(); + if ( xEmbeddedObj.is() && ( nRangeList < nRangeListCount ) ) { - const uno::Reference< embed::XEmbeddedObject >& xEmbeddedObj = pSdrOle2Obj->GetObjRef(); - if ( xEmbeddedObj.is() && ( nRangeList < nRangeListCount ) ) + bool bDisableDataTableDialog = false; + svt::EmbeddedObjectRef::TryRunningState( xEmbeddedObj ); + uno::Reference< beans::XPropertySet > xProps( xEmbeddedObj->getComponent(), uno::UNO_QUERY ); + if ( xProps.is() && + ( xProps->getPropertyValue("DisableDataTableDialog") >>= bDisableDataTableDialog ) && + bDisableDataTableDialog ) { - bool bDisableDataTableDialog = false; - svt::EmbeddedObjectRef::TryRunningState( xEmbeddedObj ); - uno::Reference< beans::XPropertySet > xProps( xEmbeddedObj->getComponent(), uno::UNO_QUERY ); - if ( xProps.is() && - ( xProps->getPropertyValue("DisableDataTableDialog") >>= bDisableDataTableDialog ) && - bDisableDataTableDialog ) + if ( bSameDoc ) { - if ( bSameDoc ) + ScChartListenerCollection* pCollection = pDoc->GetChartListenerCollection(); + if (pCollection && !pCollection->findByName(aChartName)) { - ScChartListenerCollection* pCollection = pDoc->GetChartListenerCollection(); - if (pCollection && !pCollection->findByName(aChartName)) - { - ScRangeList aRangeList( rRangesVector[ nRangeList++ ] ); - ScRangeListRef rRangeList( new ScRangeList( aRangeList ) ); - ScChartListener* pChartListener = new ScChartListener( aChartName, pDoc, rRangeList ); - pCollection->insert( pChartListener ); - pChartListener->StartListeningTo(); - } - } - else - { - xProps->setPropertyValue("DisableDataTableDialog", - uno::makeAny( false ) ); - xProps->setPropertyValue("DisableComplexChartTypes", - uno::makeAny( false ) ); + ScRangeList aRangeList( rRangesVector[ nRangeList++ ] ); + ScRangeListRef rRangeList( new ScRangeList( aRangeList ) ); + ScChartListener* pChartListener = new ScChartListener( aChartName, pDoc, rRangeList ); + pCollection->insert( pChartListener ); + pChartListener->StartListeningTo(); } } + else + { + xProps->setPropertyValue("DisableDataTableDialog", + uno::makeAny( false ) ); + xProps->setPropertyValue("DisableComplexChartTypes", + uno::makeAny( false ) ); + } } + } - if (pModelObj->HasChangesListeners()) - { - tools::Rectangle aRectangle = pSdrOle2Obj->GetSnapRect(); - ScRange aRange( pDoc->GetRange( nTab, aRectangle ) ); - ScRangeList aChangeRanges( aRange ); + if (pModelObj->HasChangesListeners()) + { + tools::Rectangle aRectangle = pSdrOle2Obj->GetSnapRect(); + ScRange aRange( pDoc->GetRange( nTab, aRectangle ) ); + ScRangeList aChangeRanges( aRange ); - uno::Sequence< beans::PropertyValue > aProperties( 1 ); - aProperties[ 0 ].Name = "Name"; - aProperties[ 0 ].Value <<= aChartName; + uno::Sequence< beans::PropertyValue > aProperties( 1 ); + aProperties[ 0 ].Name = "Name"; + aProperties[ 0 ].Value <<= aChartName; - pModelObj->NotifyChanges( "insert-chart", aChangeRanges, aProperties ); - } + pModelObj->NotifyChanges( "insert-chart", aChangeRanges, aProperties ); } } } - pObject = aIter.Next(); } + pObject = aIter.Next(); } } diff --git a/sc/source/core/tool/chgtrack.cxx b/sc/source/core/tool/chgtrack.cxx index ab1714d3683e..4f12df13ec42 100644 --- a/sc/source/core/tool/chgtrack.cxx +++ b/sc/source/core/tool/chgtrack.cxx @@ -478,27 +478,27 @@ void ScChangeAction::GetDescription( return; } - if (pReject->HasDependent()) - { - ScChangeActionMap aMap; - pCT->GetDependents( pReject, aMap, false, true ); - ScChangeActionMap::iterator itChangeAction = std::find_if(aMap.begin(), aMap.end(), - [&pReject](const ScChangeActionMap::value_type& rEntry) { - return rEntry.second->GetType() == SC_CAT_MOVE || pReject->IsDeleteType(); }); - if (itChangeAction != aMap.end()) - { - if( itChangeAction->second->GetType() == SC_CAT_MOVE) - aBuf.append( - ScResId(STR_CHANGED_MOVE_REJECTION_WARNING)); - else - aBuf.append( - ScResId(STR_CHANGED_DELETE_REJECTION_WARNING)); + if (!pReject->HasDependent()) + return; - aBuf.append(' '); - rStr = aBuf.makeStringAndClear(); - return; - } - } + ScChangeActionMap aMap; + pCT->GetDependents( pReject, aMap, false, true ); + ScChangeActionMap::iterator itChangeAction = std::find_if(aMap.begin(), aMap.end(), + [&pReject](const ScChangeActionMap::value_type& rEntry) { + return rEntry.second->GetType() == SC_CAT_MOVE || pReject->IsDeleteType(); }); + if (itChangeAction == aMap.end()) + return; + + if( itChangeAction->second->GetType() == SC_CAT_MOVE) + aBuf.append( + ScResId(STR_CHANGED_MOVE_REJECTION_WARNING)); + else + aBuf.append( + ScResId(STR_CHANGED_DELETE_REJECTION_WARNING)); + + aBuf.append(' '); + rStr = aBuf.makeStringAndClear(); + return; } OUString ScChangeAction::GetRefString( @@ -711,19 +711,19 @@ void ScChangeActionIns::GetDescription( OUString aRsc = ScResId(STR_CHANGED_INSERT); sal_Int32 nPos = aRsc.indexOf("#1"); - if (nPos >= 0) - { - // Construct a range string to replace '#1' first. - OUStringBuffer aBuf(ScResId(pWhatId)); - aBuf.append(' '); - aBuf.append(GetRefString(GetBigRange(), pDoc)); - OUString aRangeStr = aBuf.makeStringAndClear(); + if (nPos < 0) + return; - aRsc = aRsc.replaceAt(nPos, 2, aRangeStr); // replace '#1' with the range string. + // Construct a range string to replace '#1' first. + OUStringBuffer aBuf(ScResId(pWhatId)); + aBuf.append(' '); + aBuf.append(GetRefString(GetBigRange(), pDoc)); + OUString aRangeStr = aBuf.makeStringAndClear(); - aBuf.append(rStr).append(aRsc); - rStr = aBuf.makeStringAndClear(); - } + aRsc = aRsc.replaceAt(nPos, 2, aRangeStr); // replace '#1' with the range string. + + aBuf.append(rStr).append(aRsc); + rStr = aBuf.makeStringAndClear(); } bool ScChangeActionIns::IsEndOfList() const @@ -959,19 +959,19 @@ void ScChangeActionDel::GetDescription( OUString aRsc = ScResId(STR_CHANGED_DELETE); sal_Int32 nPos = aRsc.indexOf("#1"); - if (nPos >= 0) - { - // Build a string to replace with. - OUStringBuffer aBuf; - aBuf.append(ScResId(pWhatId)); - aBuf.append(' '); - aBuf.append(GetRefString(aTmpRange, pDoc)); - OUString aRangeStr = aBuf.makeStringAndClear(); - aRsc = aRsc.replaceAt(nPos, 2, aRangeStr); // replace '#1' with the string. + if (nPos < 0) + return; - aBuf.append(rStr).append(aRsc); - rStr = aBuf.makeStringAndClear(); // append to the original. - } + // Build a string to replace with. + OUStringBuffer aBuf; + aBuf.append(ScResId(pWhatId)); + aBuf.append(' '); + aBuf.append(GetRefString(aTmpRange, pDoc)); + OUString aRangeStr = aBuf.makeStringAndClear(); + aRsc = aRsc.replaceAt(nPos, 2, aRangeStr); // replace '#1' with the string. + + aBuf.append(rStr).append(aRsc); + rStr = aBuf.makeStringAndClear(); // append to the original. } bool ScChangeActionDel::Reject( ScDocument* pDoc ) @@ -1095,35 +1095,35 @@ void ScChangeActionDel::UndoCutOffMoves() void ScChangeActionDel::UndoCutOffInsert() { //Restore cut off Insert - if ( pCutOff ) + if ( !pCutOff ) + return; + + switch ( pCutOff->GetType() ) { - switch ( pCutOff->GetType() ) + case SC_CAT_INSERT_COLS : + if ( nCutOff < 0 ) + pCutOff->GetBigRange().aEnd.IncCol( -nCutOff ); + else + pCutOff->GetBigRange().aStart.IncCol( -nCutOff ); + break; + case SC_CAT_INSERT_ROWS : + if ( nCutOff < 0 ) + pCutOff->GetBigRange().aEnd.IncRow( -nCutOff ); + else + pCutOff->GetBigRange().aStart.IncRow( -nCutOff ); + break; + case SC_CAT_INSERT_TABS : + if ( nCutOff < 0 ) + pCutOff->GetBigRange().aEnd.IncTab( -nCutOff ); + else + pCutOff->GetBigRange().aStart.IncTab( -nCutOff ); + break; + default: { - case SC_CAT_INSERT_COLS : - if ( nCutOff < 0 ) - pCutOff->GetBigRange().aEnd.IncCol( -nCutOff ); - else - pCutOff->GetBigRange().aStart.IncCol( -nCutOff ); - break; - case SC_CAT_INSERT_ROWS : - if ( nCutOff < 0 ) - pCutOff->GetBigRange().aEnd.IncRow( -nCutOff ); - else - pCutOff->GetBigRange().aStart.IncRow( -nCutOff ); - break; - case SC_CAT_INSERT_TABS : - if ( nCutOff < 0 ) - pCutOff->GetBigRange().aEnd.IncTab( -nCutOff ); - else - pCutOff->GetBigRange().aStart.IncTab( -nCutOff ); - break; - default: - { - // added to avoid warnings - } + // added to avoid warnings } - SetCutOffInsert( nullptr, 0 ); } + SetCutOffInsert( nullptr, 0 ); } // ScChangeActionMove @@ -1866,21 +1866,21 @@ static void lcl_InvalidateReference( const ScDocument* pDoc, formula::FormulaTok { rRef1.SetTabDeleted( true ); } - if ( rTok.GetType() == formula::svDoubleRef ) + if ( rTok.GetType() != formula::svDoubleRef ) + return; + + ScSingleRefData& rRef2 = rTok.GetDoubleRef()->Ref2; + if ( rPos.Col() < 0 || pDoc->MaxCol() < rPos.Col() ) { - ScSingleRefData& rRef2 = rTok.GetDoubleRef()->Ref2; - if ( rPos.Col() < 0 || pDoc->MaxCol() < rPos.Col() ) - { - rRef2.SetColDeleted( true ); - } - if ( rPos.Row() < 0 || pDoc->MaxRow() < rPos.Row() ) - { - rRef2.SetRowDeleted( true ); - } - if ( rPos.Tab() < 0 || MAXTAB < rPos.Tab() ) - { - rRef2.SetTabDeleted( true ); - } + rRef2.SetColDeleted( true ); + } + if ( rPos.Row() < 0 || pDoc->MaxRow() < rPos.Row() ) + { + rRef2.SetRowDeleted( true ); + } + if ( rPos.Tab() < 0 || MAXTAB < rPos.Tab() ) + { + rRef2.SetTabDeleted( true ); } } @@ -1902,111 +1902,113 @@ void ScChangeActionContent::UpdateReference( const ScChangeTrack* pTrack, bool bOldFormula = maOldCell.meType == CELLTYPE_FORMULA; bool bNewFormula = maNewCell.meType == CELLTYPE_FORMULA; - if ( bOldFormula || bNewFormula ) - { // Adjust UpdateReference via ScFormulaCell (there) - if ( pTrack->IsInDelete() ) - { - const ScRange& rDelRange = pTrack->GetInDeleteRange(); - if ( nDx > 0 ) - nDx = rDelRange.aEnd.Col() - rDelRange.aStart.Col() + 1; - else if ( nDx < 0 ) - nDx = -(rDelRange.aEnd.Col() - rDelRange.aStart.Col() + 1); - if ( nDy > 0 ) - nDy = rDelRange.aEnd.Row() - rDelRange.aStart.Row() + 1; - else if ( nDy < 0 ) - nDy = -(rDelRange.aEnd.Row() - rDelRange.aStart.Row() + 1); - if ( nDz > 0 ) - nDz = rDelRange.aEnd.Tab() - rDelRange.aStart.Tab() + 1; - else if ( nDz < 0 ) - nDz = -(rDelRange.aEnd.Tab() - rDelRange.aStart.Tab() + 1); - } - ScBigRange aTmpRange( rRange ); - switch ( eMode ) - { - case URM_INSDEL : - if ( nDx < 0 || nDy < 0 || nDz < 0 ) - { // Delete starts there after removed range - // Position is changed there - if ( nDx ) - aTmpRange.aStart.IncCol( -nDx ); - if ( nDy ) - aTmpRange.aStart.IncRow( -nDy ); - if ( nDz ) - aTmpRange.aStart.IncTab( -nDz ); - } - break; - case URM_MOVE : - // Move is Source here and Target there - // Position needs to be adjusted before that - if ( bOldFormula ) - maOldCell.mpFormula->aPos = aBigRange.aStart.MakeAddress(); - if ( bNewFormula ) - maNewCell.mpFormula->aPos = aBigRange.aStart.MakeAddress(); + if ( !(bOldFormula || bNewFormula) ) + return; + +// Adjust UpdateReference via ScFormulaCell (there) + if ( pTrack->IsInDelete() ) + { + const ScRange& rDelRange = pTrack->GetInDeleteRange(); + if ( nDx > 0 ) + nDx = rDelRange.aEnd.Col() - rDelRange.aStart.Col() + 1; + else if ( nDx < 0 ) + nDx = -(rDelRange.aEnd.Col() - rDelRange.aStart.Col() + 1); + if ( nDy > 0 ) + nDy = rDelRange.aEnd.Row() - rDelRange.aStart.Row() + 1; + else if ( nDy < 0 ) + nDy = -(rDelRange.aEnd.Row() - rDelRange.aStart.Row() + 1); + if ( nDz > 0 ) + nDz = rDelRange.aEnd.Tab() - rDelRange.aStart.Tab() + 1; + else if ( nDz < 0 ) + nDz = -(rDelRange.aEnd.Tab() - rDelRange.aStart.Tab() + 1); + } + ScBigRange aTmpRange( rRange ); + switch ( eMode ) + { + case URM_INSDEL : + if ( nDx < 0 || nDy < 0 || nDz < 0 ) + { // Delete starts there after removed range + // Position is changed there if ( nDx ) - { - aTmpRange.aStart.IncCol( nDx ); - aTmpRange.aEnd.IncCol( nDx ); - } + aTmpRange.aStart.IncCol( -nDx ); if ( nDy ) - { - aTmpRange.aStart.IncRow( nDy ); - aTmpRange.aEnd.IncRow( nDy ); - } + aTmpRange.aStart.IncRow( -nDy ); if ( nDz ) - { - aTmpRange.aStart.IncTab( nDz ); - aTmpRange.aEnd.IncTab( nDz ); - } - break; - default: - { - // added to avoid warnings + aTmpRange.aStart.IncTab( -nDz ); } - } - ScRange aRange( aTmpRange.MakeRange() ); - - sc::RefUpdateContext aRefCxt(*pTrack->GetDocument()); - aRefCxt.meMode = eMode; - aRefCxt.maRange = aRange; - aRefCxt.mnColDelta = nDx; - aRefCxt.mnRowDelta = nDy; - aRefCxt.mnTabDelta = nDz; - - if ( bOldFormula ) - maOldCell.mpFormula->UpdateReference(aRefCxt); - if ( bNewFormula ) - maNewCell.mpFormula->UpdateReference(aRefCxt); - - if ( !aBigRange.aStart.IsValid( pTrack->GetDocument() ) ) - { //FIXME: - // UpdateReference cannot handle positions outside of the Document. - // Therefore set everything to #REF! - //TODO: Remove the need for this hack! This means big changes to ScAddress etc.! - const ScBigAddress& rPos = aBigRange.aStart; + break; + case URM_MOVE : + // Move is Source here and Target there + // Position needs to be adjusted before that if ( bOldFormula ) + maOldCell.mpFormula->aPos = aBigRange.aStart.MakeAddress(); + if ( bNewFormula ) + maNewCell.mpFormula->aPos = aBigRange.aStart.MakeAddress(); + if ( nDx ) { - formula::FormulaToken* t; - ScTokenArray* pArr = maOldCell.mpFormula->GetCode(); - formula::FormulaTokenArrayPlainIterator aIter(*pArr); - while ( ( t = aIter.GetNextReference() ) != nullptr ) - lcl_InvalidateReference( pTrack->GetDocument(), *t, rPos ); - aIter.Reset(); - while ( ( t = aIter.GetNextReferenceRPN() ) != nullptr ) - lcl_InvalidateReference( pTrack->GetDocument(), *t, rPos ); + aTmpRange.aStart.IncCol( nDx ); + aTmpRange.aEnd.IncCol( nDx ); } - if ( bNewFormula ) + if ( nDy ) + { + aTmpRange.aStart.IncRow( nDy ); + aTmpRange.aEnd.IncRow( nDy ); + } + if ( nDz ) { - formula::FormulaToken* t; - ScTokenArray* pArr = maNewCell.mpFormula->GetCode(); - formula::FormulaTokenArrayPlainIterator aIter(*pArr); - while ( ( t = aIter.GetNextReference() ) != nullptr ) - lcl_InvalidateReference( pTrack->GetDocument(), *t, rPos ); - aIter.Reset(); - while ( ( t = aIter.GetNextReferenceRPN() ) != nullptr ) - lcl_InvalidateReference( pTrack->GetDocument(), *t, rPos ); + aTmpRange.aStart.IncTab( nDz ); + aTmpRange.aEnd.IncTab( nDz ); } + break; + default: + { + // added to avoid warnings } } + ScRange aRange( aTmpRange.MakeRange() ); + + sc::RefUpdateContext aRefCxt(*pTrack->GetDocument()); + aRefCxt.meMode = eMode; + aRefCxt.maRange = aRange; + aRefCxt.mnColDelta = nDx; + aRefCxt.mnRowDelta = nDy; + aRefCxt.mnTabDelta = nDz; + + if ( bOldFormula ) + maOldCell.mpFormula->UpdateReference(aRefCxt); + if ( bNewFormula ) + maNewCell.mpFormula->UpdateReference(aRefCxt); + + if ( aBigRange.aStart.IsValid( pTrack->GetDocument() ) ) + return; + +//FIXME: + // UpdateReference cannot handle positions outside of the Document. + // Therefore set everything to #REF! + //TODO: Remove the need for this hack! This means big changes to ScAddress etc.! + const ScBigAddress& rPos = aBigRange.aStart; + if ( bOldFormula ) + { + formula::FormulaToken* t; + ScTokenArray* pArr = maOldCell.mpFormula->GetCode(); + formula::FormulaTokenArrayPlainIterator aIter(*pArr); + while ( ( t = aIter.GetNextReference() ) != nullptr ) + lcl_InvalidateReference( pTrack->GetDocument(), *t, rPos ); + aIter.Reset(); + while ( ( t = aIter.GetNextReferenceRPN() ) != nullptr ) + lcl_InvalidateReference( pTrack->GetDocument(), *t, rPos ); + } + if ( bNewFormula ) + { + formula::FormulaToken* t; + ScTokenArray* pArr = maNewCell.mpFormula->GetCode(); + formula::FormulaTokenArrayPlainIterator aIter(*pArr); + while ( ( t = aIter.GetNextReference() ) != nullptr ) + lcl_InvalidateReference( pTrack->GetDocument(), *t, rPos ); + aIter.Reset(); + while ( ( t = aIter.GetNextReferenceRPN() ) != nullptr ) + lcl_InvalidateReference( pTrack->GetDocument(), *t, rPos ); + } } bool ScChangeActionContent::IsMatrixOrigin() const @@ -2200,28 +2202,28 @@ ScChangeAction* ScChangeTrack::GetLastSaved() const void ScChangeTrack::ConfigurationChanged( utl::ConfigurationBroadcaster*, ConfigurationHints ) { - if ( !pDoc->IsInDtorClear() ) - { - const SvtUserOptions& rUserOptions = SC_MOD()->GetUserOptions(); - size_t nOldCount = maUserCollection.size(); + if ( pDoc->IsInDtorClear() ) + return; - OUStringBuffer aBuf; - aBuf.append(rUserOptions.GetFirstName()); - aBuf.append(' '); - aBuf.append(rUserOptions.GetLastName()); - SetUser(aBuf.makeStringAndClear()); + const SvtUserOptions& rUserOptions = SC_MOD()->GetUserOptions(); + size_t nOldCount = maUserCollection.size(); - if ( maUserCollection.size() != nOldCount ) - { - // New user in collection -> have to repaint because - // colors may be different now (#106697#). - // (Has to be done in the Notify handler, to be sure - // the user collection has already been updated) - - SfxObjectShell* pDocSh = pDoc->GetDocumentShell(); - if (pDocSh) - pDocSh->Broadcast( ScPaintHint( ScRange(0,0,0,pDoc->MaxCol(),pDoc->MaxRow(),MAXTAB), PaintPartFlags::Grid ) ); - } + OUStringBuffer aBuf; + aBuf.append(rUserOptions.GetFirstName()); + aBuf.append(' '); + aBuf.append(rUserOptions.GetLastName()); + SetUser(aBuf.makeStringAndClear()); + + if ( maUserCollection.size() != nOldCount ) + { + // New user in collection -> have to repaint because + // colors may be different now (#106697#). + // (Has to be done in the Notify handler, to be sure + // the user collection has already been updated) + + SfxObjectShell* pDocSh = pDoc->GetDocumentShell(); + if (pDocSh) + pDocSh->Broadcast( ScPaintHint( ScRange(0,0,0,pDoc->MaxCol(),pDoc->MaxRow(),MAXTAB), PaintPartFlags::Grid ) ); } } @@ -2247,36 +2249,36 @@ void ScChangeTrack::StartBlockModify( ScChangeTrackMsgType eMsgType, void ScChangeTrack::EndBlockModify( sal_uLong nEndAction ) { - if ( aModifiedLink.IsSet() ) + if ( !aModifiedLink.IsSet() ) + return; + + if ( xBlockModifyMsg ) { - if ( xBlockModifyMsg ) + if ( xBlockModifyMsg->nStartAction <= nEndAction ) { - if ( xBlockModifyMsg->nStartAction <= nEndAction ) - { - xBlockModifyMsg->nEndAction = nEndAction; - // Blocks dissolved in Blocks - aMsgStackFinal.push_back( *xBlockModifyMsg ); - } - else - xBlockModifyMsg.reset(); - if (aMsgStackTmp.empty()) - xBlockModifyMsg.reset(); - else - { - xBlockModifyMsg = aMsgStackTmp.back(); // Maybe Block in Block - aMsgStackTmp.pop_back(); - } + xBlockModifyMsg->nEndAction = nEndAction; + // Blocks dissolved in Blocks + aMsgStackFinal.push_back( *xBlockModifyMsg ); } - if ( !xBlockModifyMsg ) + else + xBlockModifyMsg.reset(); + if (aMsgStackTmp.empty()) + xBlockModifyMsg.reset(); + else { - bool bNew = !aMsgStackFinal.empty(); - aMsgQueue.reserve(aMsgQueue.size() + aMsgStackFinal.size()); - aMsgQueue.insert(aMsgQueue.end(), aMsgStackFinal.rbegin(), aMsgStackFinal.rend()); - aMsgStackFinal.clear(); - if ( bNew ) - aModifiedLink.Call( *this ); + xBlockModifyMsg = aMsgStackTmp.back(); // Maybe Block in Block + aMsgStackTmp.pop_back(); } } + if ( !xBlockModifyMsg ) + { + bool bNew = !aMsgStackFinal.empty(); + aMsgQueue.reserve(aMsgQueue.size() + aMsgStackFinal.size()); + aMsgQueue.insert(aMsgQueue.end(), aMsgStackFinal.rbegin(), aMsgStackFinal.rend()); + aMsgStackFinal.clear(); + if ( bNew ) + aModifiedLink.Call( *this ); + } } ScChangeTrackMsgQueue& ScChangeTrack::GetMsgQueue() @@ -2402,22 +2404,22 @@ void ScChangeTrack::Append( ScChangeAction* pAppend, sal_uLong nAction ) UpdateReference( pAppend, false ); MasterLinks( pAppend ); - if ( aModifiedLink.IsSet() ) + if ( !aModifiedLink.IsSet() ) + return; + + NotifyModified( ScChangeTrackMsgType::Append, nAction, nAction ); + if ( pAppend->GetType() == SC_CAT_CONTENT ) { - NotifyModified( ScChangeTrackMsgType::Append, nAction, nAction ); - if ( pAppend->GetType() == SC_CAT_CONTENT ) + ScChangeActionContent* pContent = static_cast<ScChangeActionContent*>(pAppend); + if ( ( pContent = pContent->GetPrevContent() ) != nullptr ) { - ScChangeActionContent* pContent = static_cast<ScChangeActionContent*>(pAppend); - if ( ( pContent = pContent->GetPrevContent() ) != nullptr ) - { - sal_uLong nMod = pContent->GetActionNumber(); - NotifyModified( ScChangeTrackMsgType::Change, nMod, nMod ); - } + sal_uLong nMod = pContent->GetActionNumber(); + NotifyModified( ScChangeTrackMsgType::Change, nMod, nMod ); } - else - NotifyModified( ScChangeTrackMsgType::Change, pFirst->GetActionNumber(), - pLast->GetActionNumber() ); } + else + NotifyModified( ScChangeTrackMsgType::Change, pFirst->GetActionNumber(), + pLast->GetActionNumber() ); } void ScChangeTrack::Append( ScChangeAction* pAppend ) @@ -2652,21 +2654,21 @@ void ScChangeTrack::AppendContent( const ScAddress& rPos, const ScCellValue& rOl void ScChangeTrack::SetLastCutMoveRange( const ScRange& rRange, ScDocument* pRefDoc ) { - if ( pLastCutMove ) - { - // Do not link ToRange with Deletes and don't change its size - // This is actually unnecessary, as a delete triggers a ResetLastCut - // in ScViewFunc::PasteFromClip before that - ScBigRange& r = pLastCutMove->GetBigRange(); - r.aEnd.SetCol( -1 ); - r.aEnd.SetRow( -1 ); - r.aEnd.SetTab( -1 ); - r.aStart.SetCol( -1 - (rRange.aEnd.Col() - rRange.aStart.Col()) ); - r.aStart.SetRow( -1 - (rRange.aEnd.Row() - rRange.aStart.Row()) ); - r.aStart.SetTab( -1 - (rRange.aEnd.Tab() - rRange.aStart.Tab()) ); - // Contents in FromRange we should overwrite - LookUpContents( rRange, pRefDoc, 0, 0, 0 ); - } + if ( !pLastCutMove ) + return; + + // Do not link ToRange with Deletes and don't change its size + // This is actually unnecessary, as a delete triggers a ResetLastCut + // in ScViewFunc::PasteFromClip before that + ScBigRange& r = pLastCutMove->GetBigRange(); + r.aEnd.SetCol( -1 ); + r.aEnd.SetRow( -1 ); + r.aEnd.SetTab( -1 ); + r.aStart.SetCol( -1 - (rRange.aEnd.Col() - rRange.aStart.Col()) ); + r.aStart.SetRow( -1 - (rRange.aEnd.Row() - rRange.aStart.Row()) ); + r.aStart.SetTab( -1 - (rRange.aEnd.Tab() - rRange.aStart.Tab()) ); + // Contents in FromRange we should overwrite + LookUpContents( rRange, pRefDoc, 0, 0, 0 ); } void ScChangeTrack::AppendContentRange( const ScRange& rRange, @@ -2982,46 +2984,46 @@ void ScChangeTrack::Dependencies( ScChangeAction* pAct ) } } - if ( pLinkMove ) - { - if ( eActType == SC_CAT_CONTENT ) - { // Content is depending on FromRange - const ScBigAddress& rPos = rRange.aStart; - for ( ScChangeActionLinkEntry* pL = pLinkMove; pL; pL = pL->GetNext() ) + if ( !pLinkMove ) + return; + + if ( eActType == SC_CAT_CONTENT ) + { // Content is depending on FromRange + const ScBigAddress& rPos = rRange.aStart; + for ( ScChangeActionLinkEntry* pL = pLinkMove; pL; pL = pL->GetNext() ) + { + ScChangeActionMove* pTest = static_cast<ScChangeActionMove*>(pL->GetAction()); + if ( !pTest->IsRejected() && + pTest->GetFromRange().In( rPos ) ) { - ScChangeActionMove* pTest = static_cast<ScChangeActionMove*>(pL->GetAction()); - if ( !pTest->IsRejected() && - pTest->GetFromRange().In( rPos ) ) - { - AddDependentWithNotify( pTest, pAct ); - } + AddDependentWithNotify( pTest, pAct ); } } - else if ( eActType == SC_CAT_MOVE ) - { // Move FromRange is depending on ToRange - const ScBigRange& rFromRange = static_cast<ScChangeActionMove*>(pAct)->GetFromRange(); - for ( ScChangeActionLinkEntry* pL = pLinkMove; pL; pL = pL->GetNext() ) + } + else if ( eActType == SC_CAT_MOVE ) + { // Move FromRange is depending on ToRange + const ScBigRange& rFromRange = static_cast<ScChangeActionMove*>(pAct)->GetFromRange(); + for ( ScChangeActionLinkEntry* pL = pLinkMove; pL; pL = pL->GetNext() ) + { + ScChangeActionMove* pTest = static_cast<ScChangeActionMove*>(pL->GetAction()); + if ( !pTest->IsRejected() && + pTest->GetBigRange().Intersects( rFromRange ) ) { - ScChangeActionMove* pTest = static_cast<ScChangeActionMove*>(pL->GetAction()); - if ( !pTest->IsRejected() && - pTest->GetBigRange().Intersects( rFromRange ) ) - { - AddDependentWithNotify( pTest, pAct ); - } + AddDependentWithNotify( pTest, pAct ); } } - else - { // Inserts and Deletes are depending as soon as they cross FromRange or - // ToRange - for ( ScChangeActionLinkEntry* pL = pLinkMove; pL; pL = pL->GetNext() ) + } + else + { // Inserts and Deletes are depending as soon as they cross FromRange or + // ToRange + for ( ScChangeActionLinkEntry* pL = pLinkMove; pL; pL = pL->GetNext() ) + { + ScChangeActionMove* pTest = static_cast<ScChangeActionMove*>(pL->GetAction()); + if ( !pTest->IsRejected() && + (pTest->GetFromRange().Intersects( rRange ) || + pTest->GetBigRange().Intersects( rRange )) ) { - ScChangeActionMove* pTest = static_cast<ScChangeActionMove*>(pL->GetAction()); - if ( !pTest->IsRejected() && - (pTest->GetFromRange().Intersects( rRange ) || - pTest->GetBigRange().Intersects( rRange )) ) - { - AddDependentWithNotify( pTest, pAct ); - } + AddDependentWithNotify( pTest, pAct ); } } } @@ -3215,22 +3217,22 @@ void ScChangeTrack::MergePrepare( const ScChangeAction* pFirstMerge, bool bShare void ScChangeTrack::MergeOwn( ScChangeAction* pAct, sal_uLong nFirstMerge, bool bShared ) { // #i94841# [Collaboration] When deleting rows is rejected, the content is sometimes wrong - if ( bShared || !ScChangeTrack::MergeIgnore( *pAct, nFirstMerge ) ) + if ( !(bShared || !ScChangeTrack::MergeIgnore( *pAct, nFirstMerge )) ) + return; + + SetMergeState( SC_CTMS_OWN ); + if ( pAct->IsDeleteType() ) { - SetMergeState( SC_CTMS_OWN ); - if ( pAct->IsDeleteType() ) + if ( static_cast<ScChangeActionDel*>(pAct)->IsTopDelete() ) { - if ( static_cast<ScChangeActionDel*>(pAct)->IsTopDelete() ) - { - SetInDeleteTop( true ); - SetInDeleteRange( static_cast<ScChangeActionDel*>(pAct)-> - GetOverAllRange().MakeRange() ); - } + SetInDeleteTop( true ); + SetInDeleteRange( static_cast<ScChangeActionDel*>(pAct)-> + GetOverAllRange().MakeRange() ); } - UpdateReference( pAct, false ); - SetInDeleteTop( false ); - SetMergeState( SC_CTMS_OTHER ); // Preceding by default MergeOther! } + UpdateReference( pAct, false ); + SetInDeleteTop( false ); + SetMergeState( SC_CTMS_OTHER ); // Preceding by default MergeOther! } void ScChangeTrack::UpdateReference( ScChangeAction* pAct, bool bUndo ) @@ -4659,44 +4661,44 @@ ScChangeTrack* ScChangeTrack::Clone( ScDocument* pDocument ) const void ScChangeTrack::MergeActionState( ScChangeAction* pAct, const ScChangeAction* pOtherAct ) { - if ( pAct->IsVirgin() ) + if ( !pAct->IsVirgin() ) + return; + + if ( pOtherAct->IsAccepted() ) { - if ( pOtherAct->IsAccepted() ) - { - pAct->Accept(); - if ( pOtherAct->IsRejecting() ) - { - pAct->SetRejectAction( pOtherAct->GetRejectAction() ); - } - } - else if ( pOtherAct->IsRejected() ) + pAct->Accept(); + if ( pOtherAct->IsRejecting() ) { - pAct->SetRejected(); + pAct->SetRejectAction( pOtherAct->GetRejectAction() ); } } + else if ( pOtherAct->IsRejected() ) + { + pAct->SetRejected(); + } } /// Get info about a single ScChangeAction element. static void lcl_getTrackedChange(ScDocument* pDoc, int nIndex, const ScChangeAction* pAction, tools::JsonWriter& rRedlines) { - if (pAction->GetType() == SC_CAT_CONTENT) - { - auto redlinesNode = rRedlines.startNode(""); - rRedlines.put("index", static_cast<sal_Int64>(nIndex)); + if (pAction->GetType() != SC_CAT_CONTENT) + return; - rRedlines.put("author", pAction->GetUser()); + auto redlinesNode = rRedlines.startNode(""); + rRedlines.put("index", static_cast<sal_Int64>(nIndex)); - rRedlines.put("type", "Modify"); + rRedlines.put("author", pAction->GetUser()); - rRedlines.put("comment", pAction->GetComment()); + rRedlines.put("type", "Modify"); - OUString aDescription; - pAction->GetDescription(aDescription, pDoc, true); - rRedlines.put("description", aDescription); + rRedlines.put("comment", pAction->GetComment()); - OUString sDateTime = utl::toISO8601(pAction->GetDateTimeUTC().GetUNODateTime()); - rRedlines.put("dateTime", sDateTime); - } + OUString aDescription; + pAction->GetDescription(aDescription, pDoc, true); + rRedlines.put("description", aDescription); + + OUString sDateTime = utl::toISO8601(pAction->GetDateTimeUTC().GetUNODateTime()); + rRedlines.put("dateTime", sDateTime); } void ScChangeTrack::GetChangeTrackInfo(tools::JsonWriter& aRedlines) diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx index 3dc18b0fe5dc..4eb3012b04ad 100644 --- a/sc/source/core/tool/compiler.cxx +++ b/sc/source/core/tool/compiler.cxx @@ -262,19 +262,19 @@ void ScCompiler::SetNumberFormatter( SvNumberFormatter* pFormatter ) void ScCompiler::SetFormulaLanguage( const ScCompiler::OpCodeMapPtr & xMap ) { - if (xMap) + if (!xMap) + return; + + mxSymbols = xMap; + if (mxSymbols->isEnglish()) { - mxSymbols = xMap; - if (mxSymbols->isEnglish()) - { - if (!pCharClassEnglish) - InitCharClassEnglish(); - pCharClass = pCharClassEnglish; - } - else - pCharClass = ScGlobal::getCharClassPtr(); - SetGrammarAndRefConvention( mxSymbols->getGrammar(), GetGrammar()); + if (!pCharClassEnglish) + InitCharClassEnglish(); + pCharClass = pCharClassEnglish; } + else + pCharClass = ScGlobal::getCharClassPtr(); + SetGrammarAndRefConvention( mxSymbols->getGrammar(), GetGrammar()); } void ScCompiler::SetGrammarAndRefConvention( @@ -409,8 +409,9 @@ ScCompiler::Convention::Convention( FormulaGrammar::AddressConvention eConv ) /* ~ */ t[126] = ScCharFlags::Char; // OOo specific /* 127 */ // FREE - if( FormulaGrammar::CONV_XL_A1 == meConv || FormulaGrammar::CONV_XL_R1C1 == meConv || FormulaGrammar::CONV_XL_OOX == meConv ) - { + if( !(FormulaGrammar::CONV_XL_A1 == meConv || FormulaGrammar::CONV_XL_R1C1 == meConv || FormulaGrammar::CONV_XL_OOX == meConv) ) +return; + /* */ t[32] |= ScCharFlags::Word; /* ! */ t[33] |= ScCharFlags::Ident | ScCharFlags::Word; /* " */ t[34] |= ScCharFlags::Word; @@ -445,7 +446,6 @@ ScCompiler::Convention::Convention( FormulaGrammar::AddressConvention eConv ) /* | */ t[124]|= ScCharFlags::Word; /* } */ t[125]|= ScCharFlags::Word; /* ~ */ t[126]|= ScCharFlags::Word; - } } static bool lcl_isValidQuotedText( const OUString& rFormula, sal_Int32 nSrcPos, ParseResult& rRes ) @@ -1117,26 +1117,26 @@ struct ConventionXL const ScComplexRefData& rRef, bool bSingleRef ) { - if( rRef.Ref1.IsFlag3D() ) - { - OUString aStartTabName, aEndTabName; + if( !rRef.Ref1.IsFlag3D() ) + return; - GetTab(rLimits, rPos, rTabNames, rRef.Ref1, aStartTabName); + OUString aStartTabName, aEndTabName; - if( !bSingleRef && rRef.Ref2.IsFlag3D() ) - { - GetTab(rLimits, rPos, rTabNames, rRef.Ref2, aEndTabName); - } + GetTab(rLimits, rPos, rTabNames, rRef.Ref1, aStartTabName); - rBuf.append( aStartTabName ); - if( !bSingleRef && rRef.Ref2.IsFlag3D() && aStartTabName != aEndTabName ) - { - rBuf.append( ':' ); - rBuf.append( aEndTabName ); - } + if( !bSingleRef && rRef.Ref2.IsFlag3D() ) + { + GetTab(rLimits, rPos, rTabNames, rRef.Ref2, aEndTabName); + } - rBuf.append( '!' ); + rBuf.append( aStartTabName ); + if( !bSingleRef && rRef.Ref2.IsFlag3D() && aStartTabName != aEndTabName ) + { + rBuf.append( ':' ); + rBuf.append( aEndTabName ); } + + rBuf.append( '!' ); } static sal_Unicode getSpecialSymbol( ScCompiler::Convention::SpecialSymbolType eSymType ) @@ -3975,183 +3975,183 @@ void ScCompiler::SetAutoCorrection( bool bVal ) void ScCompiler::AutoCorrectParsedSymbol() { sal_Int32 nPos = aCorrectedSymbol.getLength(); - if ( nPos ) - { - nPos--; - const sal_Unicode cQuote = '\"'; - const sal_Unicode cx = 'x'; - const sal_Unicode cX = 'X'; - sal_Unicode c1 = aCorrectedSymbol[0]; - sal_Unicode c2 = aCorrectedSymbol[nPos]; - sal_Unicode c2p = nPos > 0 ? aCorrectedSymbol[nPos-1] : 0; - if ( c1 == cQuote && c2 != cQuote ) - { // "... - // What's not a word doesn't belong to it. - // Don't be pedantic: c < 128 should be sufficient here. - while ( nPos && ((aCorrectedSymbol[nPos] < 128) && - ((GetCharTableFlags(aCorrectedSymbol[nPos], aCorrectedSymbol[nPos-1]) & - (ScCharFlags::Word | ScCharFlags::CharDontCare)) == ScCharFlags::NONE)) ) - nPos--; - if ( nPos == MAXSTRLEN - 1 ) - aCorrectedSymbol = aCorrectedSymbol.replaceAt( nPos, 1, OUString(cQuote) ); // '"' the MAXSTRLENth character - else - aCorrectedSymbol = aCorrectedSymbol.replaceAt( nPos + 1, 0, OUString(cQuote) ); - bCorrected = true; - } - else if ( c1 != cQuote && c2 == cQuote ) - { // ..." - aCorrectedSymbol = OUStringChar(cQuote) + aCorrectedSymbol; + if ( !nPos ) + return; + + nPos--; + const sal_Unicode cQuote = '\"'; + const sal_Unicode cx = 'x'; + const sal_Unicode cX = 'X'; + sal_Unicode c1 = aCorrectedSymbol[0]; + sal_Unicode c2 = aCorrectedSymbol[nPos]; + sal_Unicode c2p = nPos > 0 ? aCorrectedSymbol[nPos-1] : 0; + if ( c1 == cQuote && c2 != cQuote ) + { // "... + // What's not a word doesn't belong to it. + // Don't be pedantic: c < 128 should be sufficient here. + while ( nPos && ((aCorrectedSymbol[nPos] < 128) && + ((GetCharTableFlags(aCorrectedSymbol[nPos], aCorrectedSymbol[nPos-1]) & + (ScCharFlags::Word | ScCharFlags::CharDontCare)) == ScCharFlags::NONE)) ) + nPos--; + if ( nPos == MAXSTRLEN - 1 ) + aCorrectedSymbol = aCorrectedSymbol.replaceAt( nPos, 1, OUString(cQuote) ); // '"' the MAXSTRLENth character + else + aCorrectedSymbol = aCorrectedSymbol.replaceAt( nPos + 1, 0, OUString(cQuote) ); + bCorrected = true; + } + else if ( c1 != cQuote && c2 == cQuote ) + { // ..." + aCorrectedSymbol = OUStringChar(cQuote) + aCorrectedSymbol; + bCorrected = true; + } + else if ( nPos == 0 && (c1 == cx || c1 == cX) ) + { // x => * + aCorrectedSymbol = mxSymbols->getSymbol(ocMul); + bCorrected = true; + } + else if ( (GetCharTableFlags( c1, 0 ) & ScCharFlags::CharValue) + && (GetCharTableFlags( c2, c2p ) & ScCharFlags::CharValue) ) + { + if ( aCorrectedSymbol.indexOf(cx) >= 0 ) // At least two tokens separated by cx + { // x => * + sal_Unicode c = mxSymbols->getSymbolChar(ocMul); + aCorrectedSymbol = aCorrectedSymbol.replaceAll(OUStringChar(cx), OUStringChar(c)); bCorrected = true; } - else if ( nPos == 0 && (c1 == cx || c1 == cX) ) - { // x => * - aCorrectedSymbol = mxSymbols->getSymbol(ocMul); + if ( aCorrectedSymbol.indexOf(cX) >= 0 ) // At least two tokens separated by cX + { // X => * + sal_Unicode c = mxSymbols->getSymbolChar(ocMul); + aCorrectedSymbol = aCorrectedSymbol.replaceAll(OUStringChar(cX), OUStringChar(c)); bCorrected = true; } - else if ( (GetCharTableFlags( c1, 0 ) & ScCharFlags::CharValue) - && (GetCharTableFlags( c2, c2p ) & ScCharFlags::CharValue) ) + } + else + { + OUString aSymbol( aCorrectedSymbol ); + OUString aDoc; + if ( aSymbol[0] == '\'' ) { - if ( aCorrectedSymbol.indexOf(cx) >= 0 ) // At least two tokens separated by cx - { // x => * - sal_Unicode c = mxSymbols->getSymbolChar(ocMul); - aCorrectedSymbol = aCorrectedSymbol.replaceAll(OUStringChar(cx), OUStringChar(c)); - bCorrected = true; - } - if ( aCorrectedSymbol.indexOf(cX) >= 0 ) // At least two tokens separated by cX - { // X => * - sal_Unicode c = mxSymbols->getSymbolChar(ocMul); - aCorrectedSymbol = aCorrectedSymbol.replaceAll(OUStringChar(cX), OUStringChar(c)); - bCorrected = true; + sal_Int32 nPosition = aSymbol.indexOf( "'#" ); + if (nPosition != -1) + { // Split off 'Doc'#, may be d:\... or whatever + aDoc = aSymbol.copy(0, nPosition + 2); + aSymbol = aSymbol.copy(nPosition + 2); } } - else - { - OUString aSymbol( aCorrectedSymbol ); - OUString aDoc; - if ( aSymbol[0] == '\'' ) + sal_Int32 nRefs = comphelper::string::getTokenCount(aSymbol, ':'); + bool bColons; + if ( nRefs > 2 ) + { // duplicated or too many ':'? B:2::C10 => B2:C10 + bColons = true; + sal_Int32 nIndex = 0; + OUString aTmp1( aSymbol.getToken( 0, ':', nIndex ) ); + sal_Int32 nLen1 = aTmp1.getLength(); + OUStringBuffer aSym; + OUString aTmp2; + bool bLastAlp = true; + sal_Int32 nStrip = 0; + sal_Int32 nCount = nRefs; + for ( sal_Int32 j=1; j<nCount; j++ ) { - sal_Int32 nPosition = aSymbol.indexOf( "'#" ); - if (nPosition != -1) - { // Split off 'Doc'#, may be d:\... or whatever - aDoc = aSymbol.copy(0, nPosition + 2); - aSymbol = aSymbol.copy(nPosition + 2); - } - } - sal_Int32 nRefs = comphelper::string::getTokenCount(aSymbol, ':'); - bool bColons; - if ( nRefs > 2 ) - { // duplicated or too many ':'? B:2::C10 => B2:C10 - bColons = true; - sal_Int32 nIndex = 0; - OUString aTmp1( aSymbol.getToken( 0, ':', nIndex ) ); - sal_Int32 nLen1 = aTmp1.getLength(); - OUStringBuffer aSym; - OUString aTmp2; - bool bLastAlp = true; - sal_Int32 nStrip = 0; - sal_Int32 nCount = nRefs; - for ( sal_Int32 j=1; j<nCount; j++ ) + aTmp2 = aSymbol.getToken( 0, ':', nIndex ); + sal_Int32 nLen2 = aTmp2.getLength(); + if ( nLen1 || nLen2 ) { - aTmp2 = aSymbol.getToken( 0, ':', nIndex ); - sal_Int32 nLen2 = aTmp2.getLength(); - if ( nLen1 || nLen2 ) + if ( nLen1 ) { - if ( nLen1 ) - { - aSym.append(aTmp1); - bLastAlp = CharClass::isAsciiAlpha( aTmp1 ); - } - if ( nLen2 ) + aSym.append(aTmp1); + bLastAlp = CharClass::isAsciiAlpha( aTmp1 ); + } + if ( nLen2 ) + { + bool bNextNum = CharClass::isAsciiNumeric( aTmp2 ); + if ( bLastAlp == bNextNum && nStrip < 1 ) { - bool bNextNum = CharClass::isAsciiNumeric( aTmp2 ); - if ( bLastAlp == bNextNum && nStrip < 1 ) - { - // Must be alternating number/string, only - // strip within a reference. - nRefs--; - nStrip++; - } - else - { - if ( !aSym.isEmpty() && aSym[aSym.getLength()-1] != ':') - aSym.append(":"); - nStrip = 0; - } - bLastAlp = !bNextNum; + // Must be alternating number/string, only + // strip within a reference. + nRefs--; + nStrip++; } else - { // :: - nRefs--; - if ( nLen1 ) - { // B10::C10 ? append ':' on next round - if ( !bLastAlp && !CharClass::isAsciiNumeric( aTmp1 ) ) - nStrip++; - } + { + if ( !aSym.isEmpty() && aSym[aSym.getLength()-1] != ':') + aSym.append(":"); + nStrip = 0; } - aTmp1 = aTmp2; - nLen1 = nLen2; + bLastAlp = !bNextNum; } else + { // :: nRefs--; + if ( nLen1 ) + { // B10::C10 ? append ':' on next round + if ( !bLastAlp && !CharClass::isAsciiNumeric( aTmp1 ) ) + nStrip++; + } + } + aTmp1 = aTmp2; + nLen1 = nLen2; } - aSymbol = aSym.makeStringAndClear() + aTmp1; + else + nRefs--; + } + aSymbol = aSym.makeStringAndClear() + aTmp1; + } + else + bColons = false; + if ( nRefs && nRefs <= 2 ) + { // reference twisted? 4A => A4 etc. + OUString aTab[2], aRef[2]; + const ScAddress::Details aDetails( pConv->meConv, aPos ); + if ( nRefs == 2 ) + { + sal_Int32 nIdx{ 0 }; + aRef[0] = aSymbol.getToken( 0, ':', nIdx ); + aRef[1] = aSymbol.getToken( 0, ':', nIdx ); } else - bColons = false; - if ( nRefs && nRefs <= 2 ) - { // reference twisted? 4A => A4 etc. - OUString aTab[2], aRef[2]; - const ScAddress::Details aDetails( pConv->meConv, aPos ); - if ( nRefs == 2 ) + aRef[0] = aSymbol; + + bool bChanged = false; + bool bOk = true; + ScRefFlags nMask = ScRefFlags::VALID | ScRefFlags::COL_VALID | ScRefFlags::ROW_VALID; + for ( int j=0; j<nRefs; j++ ) + { + sal_Int32 nTmp = 0; + sal_Int32 nDotPos = -1; + while ( (nTmp = aRef[j].indexOf( '.', nTmp )) != -1 ) + nDotPos = nTmp++; // the last one counts + if ( nDotPos != -1 ) { - sal_Int32 nIdx{ 0 }; - aRef[0] = aSymbol.getToken( 0, ':', nIdx ); - aRef[1] = aSymbol.getToken( 0, ':', nIdx ); + aTab[j] = aRef[j].copy( 0, nDotPos + 1 ); // with '.' + aRef[j] = aRef[j].copy( nDotPos + 1 ); } - else - aRef[0] = aSymbol; - - bool bChanged = false; - bool bOk = true; - ScRefFlags nMask = ScRefFlags::VALID | ScRefFlags::COL_VALID | ScRefFlags::ROW_VALID; - for ( int j=0; j<nRefs; j++ ) + OUString aOld( aRef[j] ); + OUStringBuffer aStr2; + const sal_Unicode* p = aRef[j].getStr(); + while ( *p && rtl::isAsciiDigit( *p ) ) + aStr2.append(*p++); + aRef[j] = OUString( p ); + aRef[j] += aStr2.makeStringAndClear(); + if ( bColons || aRef[j] != aOld ) { - sal_Int32 nTmp = 0; - sal_Int32 nDotPos = -1; - while ( (nTmp = aRef[j].indexOf( '.', nTmp )) != -1 ) - nDotPos = nTmp++; // the last one counts - if ( nDotPos != -1 ) - { - aTab[j] = aRef[j].copy( 0, nDotPos + 1 ); // with '.' - aRef[j] = aRef[j].copy( nDotPos + 1 ); - } - OUString aOld( aRef[j] ); - OUStringBuffer aStr2; - const sal_Unicode* p = aRef[j].getStr(); - while ( *p && rtl::isAsciiDigit( *p ) ) - aStr2.append(*p++); - aRef[j] = OUString( p ); - aRef[j] += aStr2.makeStringAndClear(); - if ( bColons || aRef[j] != aOld ) - { - bChanged = true; - ScAddress aAdr; - bOk &= ((aAdr.Parse( aRef[j], pDoc, aDetails ) & nMask) == nMask); - } + bChanged = true; + ScAddress aAdr; + bOk &= ((aAdr.Parse( aRef[j], pDoc, aDetails ) & nMask) == nMask); } - if ( bChanged && bOk ) + } + if ( bChanged && bOk ) + { + aCorrectedSymbol = aDoc; + aCorrectedSymbol += aTab[0]; + aCorrectedSymbol += aRef[0]; + if ( nRefs == 2 ) { - aCorrectedSymbol = aDoc; - aCorrectedSymbol += aTab[0]; - aCorrectedSymbol += aRef[0]; - if ( nRefs == 2 ) - { - aCorrectedSymbol += ":"; - aCorrectedSymbol += aTab[1]; - aCorrectedSymbol += aRef[1]; - } - bCorrected = true; + aCorrectedSymbol += ":"; + aCorrectedSymbol += aTab[1]; + aCorrectedSymbol += aRef[1]; } + bCorrected = true; } } } diff --git a/sc/source/core/tool/consoli.cxx b/sc/source/core/tool/consoli.cxx index dd202bd525bc..725baa1ca802 100644 --- a/sc/source/core/tool/consoli.cxx +++ b/sc/source/core/tool/consoli.cxx @@ -186,20 +186,20 @@ void ScConsData::AddFields( const ScDocument* pSrcDoc, SCTAB nTab, } } - if (bRowByName) + if (!bRowByName) + return; + + for (SCROW nRow=nStartRow; nRow<=nRow2; nRow++) { - for (SCROW nRow=nStartRow; nRow<=nRow2; nRow++) + aTitle = pSrcDoc->GetString(nCol1, nRow, nTab); + if (!aTitle.isEmpty()) { - aTitle = pSrcDoc->GetString(nCol1, nRow, nTab); - if (!aTitle.isEmpty()) - { - bool bFound = false; - for (SCSIZE i=0; i<nRowCount && !bFound; i++) - if ( maRowHeaders[i] == aTitle ) - bFound = true; - if (!bFound) - lcl_AddString( maRowHeaders, nRowCount, aTitle ); - } + bool bFound = false; + for (SCSIZE i=0; i<nRowCount && !bFound; i++) + if ( maRowHeaders[i] == aTitle ) + bFound = true; + if (!bFound) + lcl_AddString( maRowHeaders, nRowCount, aTitle ); } } } @@ -209,31 +209,31 @@ void ScConsData::AddName( const OUString& rName ) SCSIZE nArrX; SCSIZE nArrY; - if (bReference) - { - maTitles.push_back( rName); - size_t nTitleCount = maTitles.size(); + if (!bReference) + return; - for (nArrY=0; nArrY<nRowCount; nArrY++) - { - // set all data to same length - - SCSIZE nMax = 0; - for (nArrX=0; nArrX<nColCount; nArrX++) - nMax = std::max( nMax, ppRefs[nArrX][nArrY].size() ); + maTitles.push_back( rName); + size_t nTitleCount = maTitles.size(); - for (nArrX=0; nArrX<nColCount; nArrX++) - { - ppUsed[nArrX][nArrY] = true; - ppRefs[nArrX][nArrY].resize( nMax, { SC_CONS_NOTFOUND, SC_CONS_NOTFOUND, SC_CONS_NOTFOUND }); - } + for (nArrY=0; nArrY<nRowCount; nArrY++) + { + // set all data to same length - // store positions + SCSIZE nMax = 0; + for (nArrX=0; nArrX<nColCount; nArrX++) + nMax = std::max( nMax, ppRefs[nArrX][nArrY].size() ); - if (ppTitlePos) - if (nTitleCount < nDataCount) - ppTitlePos[nArrY][nTitleCount] = nMax; + for (nArrX=0; nArrX<nColCount; nArrX++) + { + ppUsed[nArrX][nArrY] = true; + ppRefs[nArrX][nArrY].resize( nMax, { SC_CONS_NOTFOUND, SC_CONS_NOTFOUND, SC_CONS_NOTFOUND }); } + + // store positions + + if (ppTitlePos) + if (nTitleCount < nDataCount) + ppTitlePos[nArrY][nTitleCount] = nMax; } } @@ -437,108 +437,108 @@ void ScConsData::OutputToDocument( ScDocument* pDestDoc, SCCOL nCol, SCROW nRow, } } - if ( ppRefs && ppUsed ) // insert Reference - { - //TODO: differentiate, if split into categories - OUString aString; + if ( !(ppRefs && ppUsed) ) // insert Reference + return; - ScSingleRefData aSRef; // data for Reference formula cells - aSRef.InitFlags(); // this reference is absolute at all times - aSRef.SetFlag3D(true); + //TODO: differentiate, if split into categories + OUString aString; - ScComplexRefData aCRef; // data for Sum cells - aCRef.InitFlags(); - aCRef.Ref1.SetColRel(true); aCRef.Ref1.SetRowRel(true); aCRef.Ref1.SetTabRel(true); - aCRef.Ref2.SetColRel(true); aCRef.Ref2.SetRowRel(true); aCRef.Ref2.SetTabRel(true); + ScSingleRefData aSRef; // data for Reference formula cells + aSRef.InitFlags(); // this reference is absolute at all times + aSRef.SetFlag3D(true); - for (nArrY=0; nArrY<nRowCount; nArrY++) - { - SCSIZE nNeeded = 0; - for (nArrX=0; nArrX<nColCount; nArrX++) - nNeeded = std::max( nNeeded, ppRefs[nArrX][nArrY].size() ); + ScComplexRefData aCRef; // data for Sum cells + aCRef.InitFlags(); + aCRef.Ref1.SetColRel(true); aCRef.Ref1.SetRowRel(true); aCRef.Ref1.SetTabRel(true); + aCRef.Ref2.SetColRel(true); aCRef.Ref2.SetRowRel(true); aCRef.Ref2.SetTabRel(true); - if (nNeeded) - { - pDestDoc->InsertRow( 0,nTab, pDestDoc->MaxCol(),nTab, nRow+nArrY, nNeeded ); + for (nArrY=0; nArrY<nRowCount; nArrY++) + { + SCSIZE nNeeded = 0; + for (nArrX=0; nArrX<nColCount; nArrX++) + nNeeded = std::max( nNeeded, ppRefs[nArrX][nArrY].size() ); - for (nArrX=0; nArrX<nColCount; nArrX++) - if (ppUsed[nArrX][nArrY]) + if (nNeeded) + { + pDestDoc->InsertRow( 0,nTab, pDestDoc->MaxCol(),nTab, nRow+nArrY, nNeeded ); + + for (nArrX=0; nArrX<nColCount; nArrX++) + if (ppUsed[nArrX][nArrY]) + { + SCSIZE nCount = ppRefs[nArrX][nArrY].size(); + if (nCount) { - SCSIZE nCount = ppRefs[nArrX][nArrY].size(); - if (nCount) + for (SCSIZE nPos=0; nPos<nCount; nPos++) { - for (SCSIZE nPos=0; nPos<nCount; nPos++) + ScReferenceEntry aRef = ppRefs[nArrX][nArrY][nPos]; + if (aRef.nTab != SC_CONS_NOTFOUND) { - ScReferenceEntry aRef = ppRefs[nArrX][nArrY][nPos]; - if (aRef.nTab != SC_CONS_NOTFOUND) - { - // insert reference (absolute, 3d) - - aSRef.SetAddress(pDestDoc->GetSheetLimits(), ScAddress(aRef.nCol,aRef.nRow,aRef.nTab), ScAddress()); - - ScTokenArray aRefArr(pDestDoc); - aRefArr.AddSingleReference(aSRef); - aRefArr.AddOpCode(ocStop); - ScAddress aDest( sal::static_int_cast<SCCOL>(nCol+nArrX), - sal::static_int_cast<SCROW>(nRow+nArrY+nPos), nTab ); - ScFormulaCell* pCell = new ScFormulaCell(pDestDoc, aDest, aRefArr); - pDestDoc->SetFormulaCell(aDest, pCell); - } + // insert reference (absolute, 3d) + + aSRef.SetAddress(pDestDoc->GetSheetLimits(), ScAddress(aRef.nCol,aRef.nRow,aRef.nTab), ScAddress()); + + ScTokenArray aRefArr(pDestDoc); + aRefArr.AddSingleReference(aSRef); + aRefArr.AddOpCode(ocStop); + ScAddress aDest( sal::static_int_cast<SCCOL>(nCol+nArrX), + sal::static_int_cast<SCROW>(nRow+nArrY+nPos), nTab ); + ScFormulaCell* pCell = new ScFormulaCell(pDestDoc, aDest, aRefArr); + pDestDoc->SetFormulaCell(aDest, pCell); } + } - // insert sum (relative, not 3d) + // insert sum (relative, not 3d) - ScAddress aDest( sal::static_int_cast<SCCOL>(nCol+nArrX), - sal::static_int_cast<SCROW>(nRow+nArrY+nNeeded), nTab ); + ScAddress aDest( sal::static_int_cast<SCCOL>(nCol+nArrX), + sal::static_int_cast<SCROW>(nRow+nArrY+nNeeded), nTab ); - ScRange aRange(sal::static_int_cast<SCCOL>(nCol+nArrX), nRow+nArrY, nTab); - aRange.aEnd.SetRow(nRow+nArrY+nNeeded-1); - aCRef.SetRange(pDestDoc->GetSheetLimits(), aRange, aDest); + ScRange aRange(sal::static_int_cast<SCCOL>(nCol+nArrX), nRow+nArrY, nTab); + aRange.aEnd.SetRow(nRow+nArrY+nNeeded-1); + aCRef.SetRange(pDestDoc->GetSheetLimits(), aRange, aDest); - ScTokenArray aArr(pDestDoc); - aArr.AddOpCode(eOpCode); // selected function - aArr.AddOpCode(ocOpen); - aArr.AddDoubleReference(aCRef); - aArr.AddOpCode(ocClose); - aArr.AddOpCode(ocStop); - ScFormulaCell* pCell = new ScFormulaCell(pDestDoc, aDest, aArr); - pDestDoc->SetFormulaCell(aDest, pCell); - } + ScTokenArray aArr(pDestDoc); + aArr.AddOpCode(eOpCode); // selected function + aArr.AddOpCode(ocOpen); + aArr.AddDoubleReference(aCRef); + aArr.AddOpCode(ocClose); + aArr.AddOpCode(ocStop); + ScFormulaCell* pCell = new ScFormulaCell(pDestDoc, aDest, aArr); + pDestDoc->SetFormulaCell(aDest, pCell); } + } - // insert outline + // insert outline - ScOutlineArray& rOutArr = pDestDoc->GetOutlineTable( nTab, true )->GetRowArray(); - SCROW nOutStart = nRow+nArrY; - SCROW nOutEnd = nRow+nArrY+nNeeded-1; - bool bSize = false; - rOutArr.Insert( nOutStart, nOutEnd, bSize ); - for (SCROW nOutRow=nOutStart; nOutRow<=nOutEnd; nOutRow++) - pDestDoc->ShowRow( nOutRow, nTab, false ); - pDestDoc->SetDrawPageSize(nTab); - pDestDoc->UpdateOutlineRow( nOutStart, nOutEnd, nTab, false ); + ScOutlineArray& rOutArr = pDestDoc->GetOutlineTable( nTab, true )->GetRowArray(); + SCROW nOutStart = nRow+nArrY; + SCROW nOutEnd = nRow+nArrY+nNeeded-1; + bool bSize = false; + rOutArr.Insert( nOutStart, nOutEnd, bSize ); + for (SCROW nOutRow=nOutStart; nOutRow<=nOutEnd; nOutRow++) + pDestDoc->ShowRow( nOutRow, nTab, false ); + pDestDoc->SetDrawPageSize(nTab); + pDestDoc->UpdateOutlineRow( nOutStart, nOutEnd, nTab, false ); - // sub title + // sub title - if (ppTitlePos && !maTitles.empty() && !maRowHeaders.empty()) + if (ppTitlePos && !maTitles.empty() && !maRowHeaders.empty()) + { + for (SCSIZE nPos=0; nPos<nDataCount; nPos++) { - for (SCSIZE nPos=0; nPos<nDataCount; nPos++) + SCSIZE nTPos = ppTitlePos[nArrY][nPos]; + bool bDo = true; + if (nPos+1<nDataCount) + if (ppTitlePos[nArrY][nPos+1] == nTPos) + bDo = false; // empty + if ( bDo && nTPos < nNeeded ) { - SCSIZE nTPos = ppTitlePos[nArrY][nPos]; - bool bDo = true; - if (nPos+1<nDataCount) - if (ppTitlePos[nArrY][nPos+1] == nTPos) - bDo = false; // empty - if ( bDo && nTPos < nNeeded ) - { - aString = maRowHeaders[nArrY] + " / " + maTitles[nPos]; - pDestDoc->SetString( nCol-1, nRow+nArrY+nTPos, nTab, aString ); - } + aString = maRowHeaders[nArrY] + " / " + maTitles[nPos]; + pDestDoc->SetString( nCol-1, nRow+nArrY+nTPos, nTab, aString ); } } - - nRow += nNeeded; } + + nRow += nNeeded; } } } diff --git a/sc/source/core/tool/dbdata.cxx b/sc/source/core/tool/dbdata.cxx index 51b2ecc6be62..26e81d4d9406 100644 --- a/sc/source/core/tool/dbdata.cxx +++ b/sc/source/core/tool/dbdata.cxx @@ -897,27 +897,27 @@ void ScDBData::Notify( const SfxHint& rHint ) if (!pScHint) return; - if (pScHint->GetId() == SfxHintId::ScDataChanged) + if (pScHint->GetId() != SfxHintId::ScDataChanged) + return; + + mbTableColumnNamesDirty = true; + if (!mpContainer) + assert(!"ScDBData::Notify - how did we end up here without container?"); + else { - mbTableColumnNamesDirty = true; - if (!mpContainer) - assert(!"ScDBData::Notify - how did we end up here without container?"); - else + // Only one cell of a range is broadcasted per area listener if + // multiple cells are affected. Expand the range to what this is + // listening to. Broadcasted address outside should not happen, + // but... let it trigger a refresh if. + ScRange aHeaderRange( GetHeaderArea()); + if (aHeaderRange.IsValid()) { - // Only one cell of a range is broadcasted per area listener if - // multiple cells are affected. Expand the range to what this is - // listening to. Broadcasted address outside should not happen, - // but... let it trigger a refresh if. - ScRange aHeaderRange( GetHeaderArea()); - if (aHeaderRange.IsValid()) - { - mpContainer->GetDirtyTableColumnNames().Join( aHeaderRange); - if (!aHeaderRange.In( pScHint->GetAddress())) - mpContainer->GetDirtyTableColumnNames().Join( pScHint->GetAddress()); - } - else + mpContainer->GetDirtyTableColumnNames().Join( aHeaderRange); + if (!aHeaderRange.In( pScHint->GetAddress())) mpContainer->GetDirtyTableColumnNames().Join( pScHint->GetAddress()); } + else + mpContainer->GetDirtyTableColumnNames().Join( pScHint->GetAddress()); } // Do not refresh column names here, which might trigger unwanted @@ -1095,23 +1095,23 @@ ScDBCollection::NamedDBs::~NamedDBs() void ScDBCollection::NamedDBs::initInserted( ScDBData* p ) { p->SetContainer( this); - if (!mrDoc.IsClipOrUndo()) + if (mrDoc.IsClipOrUndo()) + return; + + p->StartTableColumnNamesListener(); // needs the container be set already + if (!p->AreTableColumnNamesDirty()) + return; + + if (p->HasHeader()) { - p->StartTableColumnNamesListener(); // needs the container be set already - if (p->AreTableColumnNamesDirty()) - { - if (p->HasHeader()) - { - // Refresh table column names in next round. - maDirtyTableColumnNames.Join( p->GetHeaderArea()); - } - else - { - // Header-less table can generate its column names - // already without accessing the document. - p->RefreshTableColumnNames( nullptr); - } - } + // Refresh table column names in next round. + maDirtyTableColumnNames.Join( p->GetHeaderArea()); + } + else + { + // Header-less table can generate its column names + // already without accessing the document. + p->RefreshTableColumnNames( nullptr); } } diff --git a/sc/source/core/tool/defaultsoptions.cxx b/sc/source/core/tool/defaultsoptions.cxx index e0221fcdda73..b82197471c4c 100644 --- a/sc/source/core/tool/defaultsoptions.cxx +++ b/sc/source/core/tool/defaultsoptions.cxx @@ -89,28 +89,28 @@ ScDefaultsCfg::ScDefaultsCfg() : Sequence<Any> aValues = GetProperties(aNames); const Any* pValues = aValues.getConstArray(); OSL_ENSURE(aValues.getLength() == aNames.getLength(), "GetProperties failed"); - if(aValues.getLength() == aNames.getLength()) + if(aValues.getLength() != aNames.getLength()) + return; + + sal_Int32 nIntVal = 0; + for(int nProp = 0; nProp < aNames.getLength(); nProp++) { - sal_Int32 nIntVal = 0; - for(int nProp = 0; nProp < aNames.getLength(); nProp++) + if(pValues[nProp].hasValue()) { - if(pValues[nProp].hasValue()) + switch (nProp) { - switch (nProp) - { - case SCDEFAULTSOPT_TAB_COUNT: - if (pValues[nProp] >>= nIntVal) - SetInitTabCount( static_cast<SCTAB>(nIntVal) ); - break; - case SCDEFAULTSOPT_TAB_PREFIX: - if (pValues[nProp] >>= aPrefix) - SetInitTabPrefix(aPrefix); - break; - case SCDEFAULTSOPT_JUMBO_SHEETS: - if (pValues[nProp] >>= bValue) - SetInitJumboSheets(bValue); - break; - } + case SCDEFAULTSOPT_TAB_COUNT: + if (pValues[nProp] >>= nIntVal) + SetInitTabCount( static_cast<SCTAB>(nIntVal) ); + break; + case SCDEFAULTSOPT_TAB_PREFIX: + if (pValues[nProp] >>= aPrefix) + SetInitTabPrefix(aPrefix); + break; + case SCDEFAULTSOPT_JUMBO_SHEETS: + if (pValues[nProp] >>= bValue) + SetInitJumboSheets(bValue); + break; } } } diff --git a/sc/source/core/tool/detfunc.cxx b/sc/source/core/tool/detfunc.cxx index 4923a2f68345..e77313830a17 100644 --- a/sc/source/core/tool/detfunc.cxx +++ b/sc/source/core/tool/detfunc.cxx @@ -675,45 +675,45 @@ void ScDetectiveFunc::DeleteArrowsAt( SCCOL nCol, SCROW nRow, bool bDestPnt ) pPage->RecalcObjOrdNums(); const size_t nObjCount = pPage->GetObjCount(); - if (nObjCount) - { - size_t nDelCount = 0; - std::unique_ptr<SdrObject*[]> ppObj(new SdrObject*[nObjCount]); + if (!nObjCount) + return; - SdrObjListIter aIter( pPage, SdrIterMode::Flat ); - SdrObject* pObject = aIter.Next(); - while (pObject) - { - if ( pObject->GetLayer()==SC_LAYER_INTERN && - pObject->IsPolyObj() && pObject->GetPointCount()==2 ) - { - if (aRect.IsInside(pObject->GetPoint(bDestPnt ? 1 : 0))) // start/destinationpoint - ppObj[nDelCount++] = pObject; - } + size_t nDelCount = 0; + std::unique_ptr<SdrObject*[]> ppObj(new SdrObject*[nObjCount]); - pObject = aIter.Next(); + SdrObjListIter aIter( pPage, SdrIterMode::Flat ); + SdrObject* pObject = aIter.Next(); + while (pObject) + { + if ( pObject->GetLayer()==SC_LAYER_INTERN && + pObject->IsPolyObj() && pObject->GetPointCount()==2 ) + { + if (aRect.IsInside(pObject->GetPoint(bDestPnt ? 1 : 0))) // start/destinationpoint + ppObj[nDelCount++] = pObject; } - const bool bRecording = pModel->IsRecording(); + pObject = aIter.Next(); + } - if (bRecording) - { - for (size_t i=1; i<=nDelCount; ++i) - pModel->AddCalcUndo(std::make_unique<SdrUndoDelObj>(*ppObj[nDelCount-i])); - } + const bool bRecording = pModel->IsRecording(); + if (bRecording) + { for (size_t i=1; i<=nDelCount; ++i) - { - // remove the object from the drawing page, delete if undo is disabled - SdrObject* pObj = pPage->RemoveObject(ppObj[nDelCount-i]->GetOrdNum()); - if( !bRecording ) - SdrObject::Free( pObj ); - } - - ppObj.reset(); + pModel->AddCalcUndo(std::make_unique<SdrUndoDelObj>(*ppObj[nDelCount-i])); + } - Modified(); + for (size_t i=1; i<=nDelCount; ++i) + { + // remove the object from the drawing page, delete if undo is disabled + SdrObject* pObj = pPage->RemoveObject(ppObj[nDelCount-i]->GetOrdNum()); + if( !bRecording ) + SdrObject::Free( pObj ); } + + ppObj.reset(); + + Modified(); } // delete box around reference @@ -748,37 +748,37 @@ void ScDetectiveFunc::DeleteBox( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nR pPage->RecalcObjOrdNums(); const size_t nObjCount = pPage->GetObjCount(); - if (nObjCount) - { - size_t nDelCount = 0; - std::unique_ptr<SdrObject*[]> ppObj(new SdrObject*[nObjCount]); + if (!nObjCount) + return; - SdrObjListIter aIter( pPage, SdrIterMode::Flat ); - SdrObject* pObject = aIter.Next(); - while (pObject) - { - if ( pObject->GetLayer() == SC_LAYER_INTERN && - dynamic_cast< const SdrRectObj* >(pObject) != nullptr ) - { - aObjRect = static_cast<SdrRectObj*>(pObject)->GetLogicRect(); - aObjRect.Justify(); - if ( RectIsPoints( aObjRect, aStartCorner, aEndCorner ) ) - ppObj[nDelCount++] = pObject; - } + size_t nDelCount = 0; + std::unique_ptr<SdrObject*[]> ppObj(new SdrObject*[nObjCount]); - pObject = aIter.Next(); + SdrObjListIter aIter( pPage, SdrIterMode::Flat ); + SdrObject* pObject = aIter.Next(); + while (pObject) + { + if ( pObject->GetLayer() == SC_LAYER_INTERN && + dynamic_cast< const SdrRectObj* >(pObject) != nullptr ) + { + aObjRect = static_cast<SdrRectObj*>(pObject)->GetLogicRect(); + aObjRect.Justify(); + if ( RectIsPoints( aObjRect, aStartCorner, aEndCorner ) ) + ppObj[nDelCount++] = pObject; } - for (size_t i=1; i<=nDelCount; ++i) - pModel->AddCalcUndo( std::make_unique<SdrUndoRemoveObj>( *ppObj[nDelCount-i] ) ); + pObject = aIter.Next(); + } - for (size_t i=1; i<=nDelCount; ++i) - pPage->RemoveObject( ppObj[nDelCount-i]->GetOrdNum() ); + for (size_t i=1; i<=nDelCount; ++i) + pModel->AddCalcUndo( std::make_unique<SdrUndoRemoveObj>( *ppObj[nDelCount-i] ) ); - ppObj.reset(); + for (size_t i=1; i<=nDelCount; ++i) + pPage->RemoveObject( ppObj[nDelCount-i]->GetOrdNum() ); - Modified(); - } + ppObj.reset(); + + Modified(); } sal_uInt16 ScDetectiveFunc::InsertPredLevelArea( const ScRange& rRef, @@ -1545,24 +1545,24 @@ void ScDetectiveFunc::FindFrameForObject( const SdrObject* pObject, ScRange& rRa if (!pPage) return; // test if the object is a direct page member - if( pObject && pObject->getSdrPageFromSdrObject() && (pObject->getSdrPageFromSdrObject() == pObject->getParentSdrObjListFromSdrObject()->getSdrPageFromSdrObjList()) ) - { - // Is there a previous object? - const size_t nOrdNum = pObject->GetOrdNum(); + if( !(pObject && pObject->getSdrPageFromSdrObject() && (pObject->getSdrPageFromSdrObject() == pObject->getParentSdrObjListFromSdrObject()->getSdrPageFromSdrObjList())) ) + return; - if(nOrdNum > 0) - { - SdrObject* pPrevObj = pPage->GetObj(nOrdNum - 1); + // Is there a previous object? + const size_t nOrdNum = pObject->GetOrdNum(); - if ( pPrevObj && pPrevObj->GetLayer() == SC_LAYER_INTERN && dynamic_cast<const SdrRectObj*>( pPrevObj) != nullptr ) - { - ScDrawObjData* pPrevData = ScDrawLayer::GetObjDataTab( pPrevObj, rRange.aStart.Tab() ); - if ( pPrevData && pPrevData->maStart.IsValid() && pPrevData->maEnd.IsValid() && (pPrevData->maStart == rRange.aStart) ) - { - rRange.aEnd = pPrevData->maEnd; - return; - } - } + if(nOrdNum <= 0) + return; + + SdrObject* pPrevObj = pPage->GetObj(nOrdNum - 1); + + if ( pPrevObj && pPrevObj->GetLayer() == SC_LAYER_INTERN && dynamic_cast<const SdrRectObj*>( pPrevObj) != nullptr ) + { + ScDrawObjData* pPrevData = ScDrawLayer::GetObjDataTab( pPrevObj, rRange.aStart.Tab() ); + if ( pPrevData && pPrevData->maStart.IsValid() && pPrevData->maEnd.IsValid() && (pPrevData->maStart == rRange.aStart) ) + { + rRange.aEnd = pPrevData->maEnd; + return; } } } diff --git a/sc/source/core/tool/filtopt.cxx b/sc/source/core/tool/filtopt.cxx index d12cdbeca43c..93ab7bac3302 100644 --- a/sc/source/core/tool/filtopt.cxx +++ b/sc/source/core/tool/filtopt.cxx @@ -41,19 +41,19 @@ ScFilterOptions::ScFilterOptions() : Sequence<Any> aValues = GetProperties(aNames); const Any* pValues = aValues.getConstArray(); OSL_ENSURE(aValues.getLength() == aNames.getLength(), "GetProperties failed"); - if(aValues.getLength() == aNames.getLength()) + if(aValues.getLength() != aNames.getLength()) + return; + + for(int nProp = 0; nProp < aNames.getLength(); nProp++) { - for(int nProp = 0; nProp < aNames.getLength(); nProp++) + OSL_ENSURE(pValues[nProp].hasValue(), "property value missing"); + if(pValues[nProp].hasValue()) { - OSL_ENSURE(pValues[nProp].hasValue(), "property value missing"); - if(pValues[nProp].hasValue()) + switch(nProp) { - switch(nProp) - { - case SCFILTOPT_WK3: - bWK3Flag = ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ); - break; - } + case SCFILTOPT_WK3: + bWK3Flag = ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ); + break; } } } diff --git a/sc/source/core/tool/formulaopt.cxx b/sc/source/core/tool/formulaopt.cxx index c93059f5f087..60b3bde9f176 100644 --- a/sc/source/core/tool/formulaopt.cxx +++ b/sc/source/core/tool/formulaopt.cxx @@ -225,235 +225,235 @@ void ScFormulaCfg::UpdateFromProperties( const Sequence<OUString>& aNames ) const Any* pValues = aValues.getConstArray(); OSL_ENSURE(aValues.getLength() == aNames.getLength(), "GetProperties failed"); PropsToIds aPropMap = GetPropNamesToId(); - if(aValues.getLength() == aNames.getLength()) + if(aValues.getLength() != aNames.getLength()) + return; + + sal_Int32 nIntVal = 0; + for(int nProp = 0; nProp < aNames.getLength(); nProp++) { - sal_Int32 nIntVal = 0; - for(int nProp = 0; nProp < aNames.getLength(); nProp++) + PropsToIds::iterator it_end = aPropMap.end(); + PropsToIds::iterator it = aPropMap.find( aNames[nProp] ); + if(pValues[nProp].hasValue() && it != it_end ) { - PropsToIds::iterator it_end = aPropMap.end(); - PropsToIds::iterator it = aPropMap.find( aNames[nProp] ); - if(pValues[nProp].hasValue() && it != it_end ) + switch(it->second) { - switch(it->second) - { - case SCFORMULAOPT_GRAMMAR: + case SCFORMULAOPT_GRAMMAR: + { + // Get default value in case this option is not set. + ::formula::FormulaGrammar::Grammar eGram = GetFormulaSyntax(); + + do { - // Get default value in case this option is not set. - ::formula::FormulaGrammar::Grammar eGram = GetFormulaSyntax(); + if (!(pValues[nProp] >>= nIntVal)) + // extracting failed. + break; - do + switch (nIntVal) { - if (!(pValues[nProp] >>= nIntVal)) - // extracting failed. - break; - - switch (nIntVal) - { - case 0: // Calc A1 - eGram = ::formula::FormulaGrammar::GRAM_NATIVE; - break; - case 1: // Excel A1 - eGram = ::formula::FormulaGrammar::GRAM_NATIVE_XL_A1; - break; - case 2: // Excel R1C1 - eGram = ::formula::FormulaGrammar::GRAM_NATIVE_XL_R1C1; - break; - default: - ; - } + case 0: // Calc A1 + eGram = ::formula::FormulaGrammar::GRAM_NATIVE; + break; + case 1: // Excel A1 + eGram = ::formula::FormulaGrammar::GRAM_NATIVE_XL_A1; + break; + case 2: // Excel R1C1 + eGram = ::formula::FormulaGrammar::GRAM_NATIVE_XL_R1C1; + break; + default: + ; } - while (false); - SetFormulaSyntax(eGram); - } - break; - case SCFORMULAOPT_ENGLISH_FUNCNAME: - { - bool bEnglish = false; - if (pValues[nProp] >>= bEnglish) - SetUseEnglishFuncName(bEnglish); - } - break; - case SCFORMULAOPT_SEP_ARG: - { - OUString aSep; - if ((pValues[nProp] >>= aSep) && !aSep.isEmpty()) - SetFormulaSepArg(aSep); - } - break; - case SCFORMULAOPT_SEP_ARRAY_ROW: - { - OUString aSep; - if ((pValues[nProp] >>= aSep) && !aSep.isEmpty()) - SetFormulaSepArrayRow(aSep); } - break; - case SCFORMULAOPT_SEP_ARRAY_COL: + while (false); + SetFormulaSyntax(eGram); + } + break; + case SCFORMULAOPT_ENGLISH_FUNCNAME: + { + bool bEnglish = false; + if (pValues[nProp] >>= bEnglish) + SetUseEnglishFuncName(bEnglish); + } + break; + case SCFORMULAOPT_SEP_ARG: + { + OUString aSep; + if ((pValues[nProp] >>= aSep) && !aSep.isEmpty()) + SetFormulaSepArg(aSep); + } + break; + case SCFORMULAOPT_SEP_ARRAY_ROW: + { + OUString aSep; + if ((pValues[nProp] >>= aSep) && !aSep.isEmpty()) + SetFormulaSepArrayRow(aSep); + } + break; + case SCFORMULAOPT_SEP_ARRAY_COL: + { + OUString aSep; + if ((pValues[nProp] >>= aSep) && !aSep.isEmpty()) + SetFormulaSepArrayCol(aSep); + } + break; + case SCFORMULAOPT_STRING_REF_SYNTAX: + { + // Get default value in case this option is not set. + ::formula::FormulaGrammar::AddressConvention eConv = GetCalcConfig().meStringRefAddressSyntax; + + do { - OUString aSep; - if ((pValues[nProp] >>= aSep) && !aSep.isEmpty()) - SetFormulaSepArrayCol(aSep); + if (!(pValues[nProp] >>= nIntVal)) + // extraction failed. + break; + + switch (nIntVal) + { + case -1: // Same as the formula grammar. + eConv = formula::FormulaGrammar::CONV_UNSPECIFIED; + break; + case 0: // Calc A1 + eConv = formula::FormulaGrammar::CONV_OOO; + break; + case 1: // Excel A1 + eConv = formula::FormulaGrammar::CONV_XL_A1; + break; + case 2: // Excel R1C1 + eConv = formula::FormulaGrammar::CONV_XL_R1C1; + break; + case 3: // Calc A1 | Excel A1 + eConv = formula::FormulaGrammar::CONV_A1_XL_A1; + break; + default: + ; + } } - break; - case SCFORMULAOPT_STRING_REF_SYNTAX: + while (false); + GetCalcConfig().meStringRefAddressSyntax = eConv; + } + break; + case SCFORMULAOPT_STRING_CONVERSION: + { + // Get default value in case this option is not set. + ScCalcConfig::StringConversion eConv = GetCalcConfig().meStringConversion; + + do { - // Get default value in case this option is not set. - ::formula::FormulaGrammar::AddressConvention eConv = GetCalcConfig().meStringRefAddressSyntax; + if (!(pValues[nProp] >>= nIntVal)) + // extraction failed. + break; - do + switch (nIntVal) { - if (!(pValues[nProp] >>= nIntVal)) - // extraction failed. - break; - - switch (nIntVal) - { - case -1: // Same as the formula grammar. - eConv = formula::FormulaGrammar::CONV_UNSPECIFIED; - break; - case 0: // Calc A1 - eConv = formula::FormulaGrammar::CONV_OOO; - break; - case 1: // Excel A1 - eConv = formula::FormulaGrammar::CONV_XL_A1; - break; - case 2: // Excel R1C1 - eConv = formula::FormulaGrammar::CONV_XL_R1C1; - break; - case 3: // Calc A1 | Excel A1 - eConv = formula::FormulaGrammar::CONV_A1_XL_A1; - break; - default: - ; - } + case 0: + eConv = ScCalcConfig::StringConversion::ILLEGAL; + break; + case 1: + eConv = ScCalcConfig::StringConversion::ZERO; + break; + case 2: + eConv = ScCalcConfig::StringConversion::UNAMBIGUOUS; + break; + case 3: + eConv = ScCalcConfig::StringConversion::LOCALE; + break; + default: + SAL_WARN("sc", "unknown string conversion option!"); } - while (false); - GetCalcConfig().meStringRefAddressSyntax = eConv; } - break; - case SCFORMULAOPT_STRING_CONVERSION: + while (false); + GetCalcConfig().meStringConversion = eConv; + } + break; + case SCFORMULAOPT_EMPTY_OUSTRING_AS_ZERO: + { + bool bVal = GetCalcConfig().mbEmptyStringAsZero; + pValues[nProp] >>= bVal; + GetCalcConfig().mbEmptyStringAsZero = bVal; + } + break; + case SCFORMULAOPT_OOXML_RECALC: + { + ScRecalcOptions eOpt = RECALC_ASK; + if (pValues[nProp] >>= nIntVal) { - // Get default value in case this option is not set. - ScCalcConfig::StringConversion eConv = GetCalcConfig().meStringConversion; - - do + switch (nIntVal) { - if (!(pValues[nProp] >>= nIntVal)) - // extraction failed. + case 0: + eOpt = RECALC_ALWAYS; break; - - switch (nIntVal) - { - case 0: - eConv = ScCalcConfig::StringConversion::ILLEGAL; - break; - case 1: - eConv = ScCalcConfig::StringConversion::ZERO; + case 1: + eOpt = RECALC_NEVER; break; - case 2: - eConv = ScCalcConfig::StringConversion::UNAMBIGUOUS; + case 2: + eOpt = RECALC_ASK; break; - case 3: - eConv = ScCalcConfig::StringConversion::LOCALE; - break; - default: - SAL_WARN("sc", "unknown string conversion option!"); - } + default: + SAL_WARN("sc", "unknown ooxml recalc option!"); } - while (false); - GetCalcConfig().meStringConversion = eConv; - } - break; - case SCFORMULAOPT_EMPTY_OUSTRING_AS_ZERO: - { - bool bVal = GetCalcConfig().mbEmptyStringAsZero; - pValues[nProp] >>= bVal; - GetCalcConfig().mbEmptyStringAsZero = bVal; } - break; - case SCFORMULAOPT_OOXML_RECALC: - { - ScRecalcOptions eOpt = RECALC_ASK; - if (pValues[nProp] >>= nIntVal) - { - switch (nIntVal) - { - case 0: - eOpt = RECALC_ALWAYS; - break; - case 1: - eOpt = RECALC_NEVER; - break; - case 2: - eOpt = RECALC_ASK; - break; - default: - SAL_WARN("sc", "unknown ooxml recalc option!"); - } - } - SetOOXMLRecalcOptions(eOpt); - } - break; - case SCFORMULAOPT_ODF_RECALC: + SetOOXMLRecalcOptions(eOpt); + } + break; + case SCFORMULAOPT_ODF_RECALC: + { + ScRecalcOptions eOpt = RECALC_ASK; + if (pValues[nProp] >>= nIntVal) { - ScRecalcOptions eOpt = RECALC_ASK; - if (pValues[nProp] >>= nIntVal) + switch (nIntVal) { - switch (nIntVal) - { - case 0: - eOpt = RECALC_ALWAYS; - break; - case 1: - eOpt = RECALC_NEVER; - break; - case 2: - eOpt = RECALC_ASK; - break; - default: - SAL_WARN("sc", "unknown odf recalc option!"); - } + case 0: + eOpt = RECALC_ALWAYS; + break; + case 1: + eOpt = RECALC_NEVER; + break; + case 2: + eOpt = RECALC_ASK; + break; + default: + SAL_WARN("sc", "unknown odf recalc option!"); } - - SetODFRecalcOptions(eOpt); - } - break; - case SCFORMULAOPT_OPENCL_AUTOSELECT: - { - bool bVal = GetCalcConfig().mbOpenCLAutoSelect; - pValues[nProp] >>= bVal; - GetCalcConfig().mbOpenCLAutoSelect = bVal; - } - break; - case SCFORMULAOPT_OPENCL_DEVICE: - { - OUString aOpenCLDevice = GetCalcConfig().maOpenCLDevice; - pValues[nProp] >>= aOpenCLDevice; - GetCalcConfig().maOpenCLDevice = aOpenCLDevice; - } - break; - case SCFORMULAOPT_OPENCL_SUBSET_ONLY: - { - bool bVal = GetCalcConfig().mbOpenCLSubsetOnly; - pValues[nProp] >>= bVal; - GetCalcConfig().mbOpenCLSubsetOnly = bVal; - } - break; - case SCFORMULAOPT_OPENCL_MIN_SIZE: - { - sal_Int32 nVal = GetCalcConfig().mnOpenCLMinimumFormulaGroupSize; - pValues[nProp] >>= nVal; - GetCalcConfig().mnOpenCLMinimumFormulaGroupSize = nVal; - } - break; - case SCFORMULAOPT_OPENCL_SUBSET_OPS: - { - OUString sVal = ScOpCodeSetToSymbolicString(GetCalcConfig().mpOpenCLSubsetOpCodes); - pValues[nProp] >>= sVal; - GetCalcConfig().mpOpenCLSubsetOpCodes = ScStringToOpCodeSet(sVal); - } - break; } + + SetODFRecalcOptions(eOpt); + } + break; + case SCFORMULAOPT_OPENCL_AUTOSELECT: + { + bool bVal = GetCalcConfig().mbOpenCLAutoSelect; + pValues[nProp] >>= bVal; + GetCalcConfig().mbOpenCLAutoSelect = bVal; + } + break; + case SCFORMULAOPT_OPENCL_DEVICE: + { + OUString aOpenCLDevice = GetCalcConfig().maOpenCLDevice; + pValues[nProp] >>= aOpenCLDevice; + GetCalcConfig().maOpenCLDevice = aOpenCLDevice; + } + break; + case SCFORMULAOPT_OPENCL_SUBSET_ONLY: + { + bool bVal = GetCalcConfig().mbOpenCLSubsetOnly; + pValues[nProp] >>= bVal; + GetCalcConfig().mbOpenCLSubsetOnly = bVal; + } + break; + case SCFORMULAOPT_OPENCL_MIN_SIZE: + { + sal_Int32 nVal = GetCalcConfig().mnOpenCLMinimumFormulaGroupSize; + pValues[nProp] >>= nVal; + GetCalcConfig().mnOpenCLMinimumFormulaGroupSize = nVal; + } + break; + case SCFORMULAOPT_OPENCL_SUBSET_OPS: + { + OUString sVal = ScOpCodeSetToSymbolicString(GetCalcConfig().mpOpenCLSubsetOpCodes); + pValues[nProp] >>= sVal; + GetCalcConfig().mpOpenCLSubsetOpCodes = ScStringToOpCodeSet(sVal); + } + break; } } } diff --git a/sc/source/core/tool/formulaparserpool.cxx b/sc/source/core/tool/formulaparserpool.cxx index 9a766cd4863c..5e50ea96ec4d 100644 --- a/sc/source/core/tool/formulaparserpool.cxx +++ b/sc/source/core/tool/formulaparserpool.cxx @@ -56,7 +56,10 @@ private: ScParserFactoryMap::ScParserFactoryMap() : mxContext( ::comphelper::getProcessComponentContext() ) { - if( mxContext.is() ) try + if( !mxContext.is() ) + return; + + try { // enumerate all implementations of the FormulaParser service Reference< XContentEnumerationAccess > xFactoryEA( mxContext->getServiceManager(), UNO_QUERY_THROW ); diff --git a/sc/source/core/tool/inputopt.cxx b/sc/source/core/tool/inputopt.cxx index f78d059cb864..0ceefd1fa9f1 100644 --- a/sc/source/core/tool/inputopt.cxx +++ b/sc/source/core/tool/inputopt.cxx @@ -94,54 +94,54 @@ ScInputCfg::ScInputCfg() : EnableNotification(aNames); const Any* pValues = aValues.getConstArray(); OSL_ENSURE(aValues.getLength() == aNames.getLength(), "GetProperties failed"); - if(aValues.getLength() == aNames.getLength()) + if(aValues.getLength() != aNames.getLength()) + return; + + for(int nProp = 0; nProp < aNames.getLength(); nProp++) { - for(int nProp = 0; nProp < aNames.getLength(); nProp++) + OSL_ENSURE(pValues[nProp].hasValue(), "property value missing"); + if(pValues[nProp].hasValue()) { - OSL_ENSURE(pValues[nProp].hasValue(), "property value missing"); - if(pValues[nProp].hasValue()) + sal_Int32 nIntVal = 0; + switch(nProp) { - sal_Int32 nIntVal = 0; - switch(nProp) - { - case SCINPUTOPT_MOVEDIR: - if ( pValues[nProp] >>= nIntVal ) - SetMoveDir( static_cast<sal_uInt16>(nIntVal) ); - break; - case SCINPUTOPT_MOVESEL: - SetMoveSelection( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); - break; - case SCINPUTOPT_EDTEREDIT: - SetEnterEdit( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); - break; - case SCINPUTOPT_EXTENDFMT: - SetExtendFormat( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); - break; - case SCINPUTOPT_RANGEFIND: - SetRangeFinder( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); - break; - case SCINPUTOPT_EXPANDREFS: - SetExpandRefs( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); - break; - case SCINPUTOPT_SORT_REF_UPDATE: - SetSortRefUpdate(ScUnoHelpFunctions::GetBoolFromAny(pValues[nProp])); - break; - case SCINPUTOPT_MARKHEADER: - SetMarkHeader( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); - break; - case SCINPUTOPT_USETABCOL: - SetUseTabCol( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); - break; - case SCINPUTOPT_TEXTWYSIWYG: - SetTextWysiwyg( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); - break; - case SCINPUTOPT_REPLCELLSWARN: - SetReplaceCellsWarn( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); - break; - case SCINPUTOPT_LEGACY_CELL_SELECTION: - SetLegacyCellSelection( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); - break; - } + case SCINPUTOPT_MOVEDIR: + if ( pValues[nProp] >>= nIntVal ) + SetMoveDir( static_cast<sal_uInt16>(nIntVal) ); + break; + case SCINPUTOPT_MOVESEL: + SetMoveSelection( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); + break; + case SCINPUTOPT_EDTEREDIT: + SetEnterEdit( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); + break; + case SCINPUTOPT_EXTENDFMT: + SetExtendFormat( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); + break; + case SCINPUTOPT_RANGEFIND: + SetRangeFinder( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); + break; + case SCINPUTOPT_EXPANDREFS: + SetExpandRefs( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); + break; + case SCINPUTOPT_SORT_REF_UPDATE: + SetSortRefUpdate(ScUnoHelpFunctions::GetBoolFromAny(pValues[nProp])); + break; + case SCINPUTOPT_MARKHEADER: + SetMarkHeader( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); + break; + case SCINPUTOPT_USETABCOL: + SetUseTabCol( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); + break; + case SCINPUTOPT_TEXTWYSIWYG: + SetTextWysiwyg( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); + break; + case SCINPUTOPT_REPLCELLSWARN: + SetReplaceCellsWarn( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); + break; + case SCINPUTOPT_LEGACY_CELL_SELECTION: + SetLegacyCellSelection( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); + break; } } } diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx index 50683114a242..783dfd2849bb 100644 --- a/sc/source/core/tool/interpr1.cxx +++ b/sc/source/core/tool/interpr1.cxx @@ -514,26 +514,26 @@ static void lcl_AdjustJumpMatrix( ScJumpMatrix* pJumpM, SCSIZE nParmCols, SCSIZE SCSIZE nAdjustCols, nAdjustRows; pJumpM->GetDimensions( nJumpCols, nJumpRows ); pJumpM->GetResMatDimensions( nResCols, nResRows ); - if (( nJumpCols == 1 && nParmCols > nResCols ) || - ( nJumpRows == 1 && nParmRows > nResRows )) + if (!(( nJumpCols == 1 && nParmCols > nResCols ) || + ( nJumpRows == 1 && nParmRows > nResRows ))) + return; + + if ( nJumpCols == 1 && nJumpRows == 1 ) { - if ( nJumpCols == 1 && nJumpRows == 1 ) - { - nAdjustCols = std::max(nParmCols, nResCols); - nAdjustRows = std::max(nParmRows, nResRows); - } - else if ( nJumpCols == 1 ) - { - nAdjustCols = nParmCols; - nAdjustRows = nResRows; - } - else - { - nAdjustCols = nResCols; - nAdjustRows = nParmRows; - } - pJumpM->SetNewResMat( nAdjustCols, nAdjustRows ); + nAdjustCols = std::max(nParmCols, nResCols); + nAdjustRows = std::max(nParmRows, nResRows); + } + else if ( nJumpCols == 1 ) + { + nAdjustCols = nParmCols; + nAdjustRows = nResRows; + } + else + { + nAdjustCols = nResCols; + nAdjustRows = nParmRows; } + pJumpM->SetNewResMat( nAdjustCols, nAdjustRows ); } bool ScInterpreter::JumpMatrix( short nStackLevel ) @@ -1269,197 +1269,197 @@ void ScInterpreter::ScAnd() { nFuncFmtType = SvNumFormatType::LOGICAL; short nParamCount = GetByte(); - if ( MustHaveParamCountMin( nParamCount, 1 ) ) + if ( !MustHaveParamCountMin( nParamCount, 1 ) ) + return; + + bool bHaveValue = false; + bool bRes = true; + size_t nRefInList = 0; + while( nParamCount-- > 0) { - bool bHaveValue = false; - bool bRes = true; - size_t nRefInList = 0; - while( nParamCount-- > 0) + if ( nGlobalError == FormulaError::NONE ) { - if ( nGlobalError == FormulaError::NONE ) + switch ( GetStackType() ) { - switch ( GetStackType() ) + case svDouble : + bHaveValue = true; + bRes &= ( PopDouble() != 0.0 ); + break; + case svString : + Pop(); + SetError( FormulaError::NoValue ); + break; + case svSingleRef : { - case svDouble : - bHaveValue = true; - bRes &= ( PopDouble() != 0.0 ); - break; - case svString : - Pop(); - SetError( FormulaError::NoValue ); - break; - case svSingleRef : + ScAddress aAdr; + PopSingleRef( aAdr ); + if ( nGlobalError == FormulaError::NONE ) { - ScAddress aAdr; - PopSingleRef( aAdr ); - if ( nGlobalError == FormulaError::NONE ) + ScRefCellValue aCell(*pDok, aAdr); + if (aCell.hasNumeric()) { - ScRefCellValue aCell(*pDok, aAdr); - if (aCell.hasNumeric()) - { - bHaveValue = true; - bRes &= ( GetCellValue(aAdr, aCell) != 0.0 ); - } - // else: Xcl raises no error here + bHaveValue = true; + bRes &= ( GetCellValue(aAdr, aCell) != 0.0 ); } + // else: Xcl raises no error here } - break; - case svDoubleRef: - case svRefList: + } + break; + case svDoubleRef: + case svRefList: + { + ScRange aRange; + PopDoubleRef( aRange, nParamCount, nRefInList); + if ( nGlobalError == FormulaError::NONE ) { - ScRange aRange; - PopDoubleRef( aRange, nParamCount, nRefInList); - if ( nGlobalError == FormulaError::NONE ) + double fVal; + FormulaError nErr = FormulaError::NONE; + ScValueIterator aValIter( pDok, aRange ); + if ( aValIter.GetFirst( fVal, nErr ) && nErr == FormulaError::NONE ) { - double fVal; - FormulaError nErr = FormulaError::NONE; - ScValueIterator aValIter( pDok, aRange ); - if ( aValIter.GetFirst( fVal, nErr ) && nErr == FormulaError::NONE ) + bHaveValue = true; + do { - bHaveValue = true; - do - { - bRes &= ( fVal != 0.0 ); - } while ( (nErr == FormulaError::NONE) && - aValIter.GetNext( fVal, nErr ) ); - } - SetError( nErr ); + bRes &= ( fVal != 0.0 ); + } while ( (nErr == FormulaError::NONE) && + aValIter.GetNext( fVal, nErr ) ); } + SetError( nErr ); } - break; - case svExternalSingleRef: - case svExternalDoubleRef: - case svMatrix: + } + break; + case svExternalSingleRef: + case svExternalDoubleRef: + case svMatrix: + { + ScMatrixRef pMat = GetMatrix(); + if ( pMat ) { - ScMatrixRef pMat = GetMatrix(); - if ( pMat ) + bHaveValue = true; + double fVal = pMat->And(); + FormulaError nErr = GetDoubleErrorValue( fVal ); + if ( nErr != FormulaError::NONE ) { - bHaveValue = true; - double fVal = pMat->And(); - FormulaError nErr = GetDoubleErrorValue( fVal ); - if ( nErr != FormulaError::NONE ) - { - SetError( nErr ); - bRes = false; - } - else - bRes &= (fVal != 0.0); + SetError( nErr ); + bRes = false; } - // else: GetMatrix did set FormulaError::IllegalParameter + else + bRes &= (fVal != 0.0); } - break; - default: - Pop(); - SetError( FormulaError::IllegalParameter); + // else: GetMatrix did set FormulaError::IllegalParameter } + break; + default: + Pop(); + SetError( FormulaError::IllegalParameter); } - else - Pop(); } - if ( bHaveValue ) - PushInt( int(bRes) ); else - PushNoValue(); + Pop(); } + if ( bHaveValue ) + PushInt( int(bRes) ); + else + PushNoValue(); } void ScInterpreter::ScOr() { nFuncFmtType = SvNumFormatType::LOGICAL; short nParamCount = GetByte(); - if ( MustHaveParamCountMin( nParamCount, 1 ) ) + if ( !MustHaveParamCountMin( nParamCount, 1 ) ) + return; + + bool bHaveValue = false; + bool bRes = false; + size_t nRefInList = 0; + while( nParamCount-- > 0) { - bool bHaveValue = false; - bool bRes = false; - size_t nRefInList = 0; - while( nParamCount-- > 0) + if ( nGlobalError == FormulaError::NONE ) { - if ( nGlobalError == FormulaError::NONE ) + switch ( GetStackType() ) { - switch ( GetStackType() ) + case svDouble : + bHaveValue = true; + bRes |= ( PopDouble() != 0.0 ); + break; + case svString : + Pop(); + SetError( FormulaError::NoValue ); + break; + case svSingleRef : { - case svDouble : - bHaveValue = true; - bRes |= ( PopDouble() != 0.0 ); - break; - case svString : - Pop(); - SetError( FormulaError::NoValue ); - break; - case svSingleRef : + ScAddress aAdr; + PopSingleRef( aAdr ); + if ( nGlobalError == FormulaError::NONE ) { - ScAddress aAdr; - PopSingleRef( aAdr ); - if ( nGlobalError == FormulaError::NONE ) + ScRefCellValue aCell(*pDok, aAdr); + if (aCell.hasNumeric()) { - ScRefCellValue aCell(*pDok, aAdr); - if (aCell.hasNumeric()) - { - bHaveValue = true; - bRes |= ( GetCellValue(aAdr, aCell) != 0.0 ); - } - // else: Xcl raises no error here + bHaveValue = true; + bRes |= ( GetCellValue(aAdr, aCell) != 0.0 ); } + // else: Xcl raises no error here } - break; - case svDoubleRef: - case svRefList: + } + break; + case svDoubleRef: + case svRefList: + { + ScRange aRange; + PopDoubleRef( aRange, nParamCount, nRefInList); + if ( nGlobalError == FormulaError::NONE ) { - ScRange aRange; - PopDoubleRef( aRange, nParamCount, nRefInList); - if ( nGlobalError == FormulaError::NONE ) + double fVal; + FormulaError nErr = FormulaError::NONE; + ScValueIterator aValIter( pDok, aRange ); + if ( aValIter.GetFirst( fVal, nErr ) ) { - double fVal; - FormulaError nErr = FormulaError::NONE; - ScValueIterator aValIter( pDok, aRange ); - if ( aValIter.GetFirst( fVal, nErr ) ) + bHaveValue = true; + do { - bHaveValue = true; - do - { - bRes |= ( fVal != 0.0 ); - } while ( (nErr == FormulaError::NONE) && - aValIter.GetNext( fVal, nErr ) ); - } - SetError( nErr ); + bRes |= ( fVal != 0.0 ); + } while ( (nErr == FormulaError::NONE) && + aValIter.GetNext( fVal, nErr ) ); } + SetError( nErr ); } - break; - case svExternalSingleRef: - case svExternalDoubleRef: - case svMatrix: + } + break; + case svExternalSingleRef: + case svExternalDoubleRef: + case svMatrix: + { + bHaveValue = true; + ScMatrixRef pMat = GetMatrix(); + if ( pMat ) { bHaveValue = true; - ScMatrixRef pMat = GetMatrix(); - if ( pMat ) + double fVal = pMat->Or(); + FormulaError nErr = GetDoubleErrorValue( fVal ); + if ( nErr != FormulaError::NONE ) { - bHaveValue = true; - double fVal = pMat->Or(); - FormulaError nErr = GetDoubleErrorValue( fVal ); - if ( nErr != FormulaError::NONE ) - { - SetError( nErr ); - bRes = false; - } - else - bRes |= (fVal != 0.0); + SetError( nErr ); + bRes = false; } - // else: GetMatrix did set FormulaError::IllegalParameter + else + bRes |= (fVal != 0.0); } - break; - default: - Pop(); - SetError( FormulaError::IllegalParameter); + // else: GetMatrix did set FormulaError::IllegalParameter } + break; + default: + Pop(); + SetError( FormulaError::IllegalParameter); } - else - Pop(); } - if ( bHaveValue ) - PushInt( int(bRes) ); else - PushNoValue(); + Pop(); } + if ( bHaveValue ) + PushInt( int(bRes) ); + else + PushNoValue(); } void ScInterpreter::ScXor() @@ -1467,101 +1467,101 @@ void ScInterpreter::ScXor() nFuncFmtType = SvNumFormatType::LOGICAL; short nParamCount = GetByte(); - if ( MustHaveParamCountMin( nParamCount, 1 ) ) + if ( !MustHaveParamCountMin( nParamCount, 1 ) ) + return; + + bool bHaveValue = false; + bool bRes = false; + size_t nRefInList = 0; + while( nParamCount-- > 0) { - bool bHaveValue = false; - bool bRes = false; - size_t nRefInList = 0; - while( nParamCount-- > 0) + if ( nGlobalError == FormulaError::NONE ) { - if ( nGlobalError == FormulaError::NONE ) + switch ( GetStackType() ) { - switch ( GetStackType() ) + case svDouble : + bHaveValue = true; + bRes ^= ( PopDouble() != 0.0 ); + break; + case svString : + Pop(); + SetError( FormulaError::NoValue ); + break; + case svSingleRef : { - case svDouble : - bHaveValue = true; - bRes ^= ( PopDouble() != 0.0 ); - break; - case svString : - Pop(); - SetError( FormulaError::NoValue ); - break; - case svSingleRef : + ScAddress aAdr; + PopSingleRef( aAdr ); + if ( nGlobalError == FormulaError::NONE ) { - ScAddress aAdr; - PopSingleRef( aAdr ); - if ( nGlobalError == FormulaError::NONE ) + ScRefCellValue aCell(*pDok, aAdr); + if (aCell.hasNumeric()) { - ScRefCellValue aCell(*pDok, aAdr); - if (aCell.hasNumeric()) - { - bHaveValue = true; - bRes ^= ( GetCellValue(aAdr, aCell) != 0.0 ); - } - /* TODO: set error? Excel doesn't have XOR, but - * doesn't set an error in this case for AND and - * OR. */ + bHaveValue = true; + bRes ^= ( GetCellValue(aAdr, aCell) != 0.0 ); } + /* TODO: set error? Excel doesn't have XOR, but + * doesn't set an error in this case for AND and + * OR. */ } - break; - case svDoubleRef: - case svRefList: + } + break; + case svDoubleRef: + case svRefList: + { + ScRange aRange; + PopDoubleRef( aRange, nParamCount, nRefInList); + if ( nGlobalError == FormulaError::NONE ) { - ScRange aRange; - PopDoubleRef( aRange, nParamCount, nRefInList); - if ( nGlobalError == FormulaError::NONE ) + double fVal; + FormulaError nErr = FormulaError::NONE; + ScValueIterator aValIter( pDok, aRange ); + if ( aValIter.GetFirst( fVal, nErr ) ) { - double fVal; - FormulaError nErr = FormulaError::NONE; - ScValueIterator aValIter( pDok, aRange ); - if ( aValIter.GetFirst( fVal, nErr ) ) + bHaveValue = true; + do { - bHaveValue = true; - do - { - bRes ^= ( fVal != 0.0 ); - } while ( (nErr == FormulaError::NONE) && - aValIter.GetNext( fVal, nErr ) ); - } - SetError( nErr ); + bRes ^= ( fVal != 0.0 ); + } while ( (nErr == FormulaError::NONE) && + aValIter.GetNext( fVal, nErr ) ); } + SetError( nErr ); } - break; - case svExternalSingleRef: - case svExternalDoubleRef: - case svMatrix: + } + break; + case svExternalSingleRef: + case svExternalDoubleRef: + case svMatrix: + { + bHaveValue = true; + ScMatrixRef pMat = GetMatrix(); + if ( pMat ) { bHaveValue = true; - ScMatrixRef pMat = GetMatrix(); - if ( pMat ) + double fVal = pMat->Xor(); + FormulaError nErr = GetDoubleErrorValue( fVal ); + if ( nErr != FormulaError::NONE ) { - bHaveValue = true; - double fVal = pMat->Xor(); - FormulaError nErr = GetDoubleErrorValue( fVal ); - if ( nErr != FormulaError::NONE ) - { - SetError( nErr ); - bRes = false; - } - else - bRes ^= ( fVal != 0.0 ); + SetError( nErr ); + bRes = false; } - // else: GetMatrix did set FormulaError::IllegalParameter + else + bRes ^= ( fVal != 0.0 ); } - break; - default: - Pop(); - SetError( FormulaError::IllegalParameter); + // else: GetMatrix did set FormulaError::IllegalParameter } + break; + default: + Pop(); + SetError( FormulaError::IllegalParameter); } - else - Pop(); } - if ( bHaveValue ) - PushInt( int(bRes) ); else - PushNoValue(); + Pop(); } + if ( bHaveValue ) + PushInt( int(bRes) ); + else + PushNoValue(); } void ScInterpreter::ScNeg() @@ -2242,177 +2242,177 @@ void getFormatString(SvNumberFormatter* pFormatter, sal_uLong nFormat, OUString& void ScInterpreter::ScCell() { // ATTRIBUTE ; [REF] sal_uInt8 nParamCount = GetByte(); - if( MustHaveParamCount( nParamCount, 1, 2 ) ) + if( !MustHaveParamCount( nParamCount, 1, 2 ) ) + return; + + ScAddress aCellPos( aPos ); + bool bError = false; + if( nParamCount == 2 ) { - ScAddress aCellPos( aPos ); - bool bError = false; - if( nParamCount == 2 ) + switch (GetStackType()) { - switch (GetStackType()) + case svExternalSingleRef: + case svExternalDoubleRef: { - case svExternalSingleRef: - case svExternalDoubleRef: - { - // Let's handle external reference separately... - ScCellExternal(); - return; - } - default: - ; + // Let's handle external reference separately... + ScCellExternal(); + return; } - bError = !PopDoubleRefOrSingleRef( aCellPos ); + default: + ; } - OUString aInfoType = GetString().getString(); - if( bError || nGlobalError != FormulaError::NONE ) - PushIllegalParameter(); - else - { - ScRefCellValue aCell(*pDok, aCellPos); + bError = !PopDoubleRefOrSingleRef( aCellPos ); + } + OUString aInfoType = GetString().getString(); + if( bError || nGlobalError != FormulaError::NONE ) + PushIllegalParameter(); + else + { + ScRefCellValue aCell(*pDok, aCellPos); - ScCellKeywordTranslator::transKeyword(aInfoType, ScGlobal::GetLocale(), ocCell); + ScCellKeywordTranslator::transKeyword(aInfoType, ScGlobal::GetLocale(), ocCell); // *** ADDRESS INFO *** - if( aInfoType == "COL" ) - { // column number (1-based) - PushInt( aCellPos.Col() + 1 ); - } - else if( aInfoType == "ROW" ) - { // row number (1-based) - PushInt( aCellPos.Row() + 1 ); - } - else if( aInfoType == "SHEET" ) - { // table number (1-based) - PushInt( aCellPos.Tab() + 1 ); - } - else if( aInfoType == "ADDRESS" ) - { // address formatted as [['FILENAME'#]$TABLE.]$COL$ROW - ScRefFlags nFlags = (aCellPos.Tab() == aPos.Tab()) ? ScRefFlags::ADDR_ABS : ScRefFlags::ADDR_ABS_3D; - OUString aStr(aCellPos.Format(nFlags, pDok, pDok->GetAddressConvention())); - PushString(aStr); - } - else if( aInfoType == "FILENAME" ) - { // file name and table name: 'FILENAME'#$TABLE - SCTAB nTab = aCellPos.Tab(); - OUString aFuncResult; - if( nTab < pDok->GetTableCount() ) + if( aInfoType == "COL" ) + { // column number (1-based) + PushInt( aCellPos.Col() + 1 ); + } + else if( aInfoType == "ROW" ) + { // row number (1-based) + PushInt( aCellPos.Row() + 1 ); + } + else if( aInfoType == "SHEET" ) + { // table number (1-based) + PushInt( aCellPos.Tab() + 1 ); + } + else if( aInfoType == "ADDRESS" ) + { // address formatted as [['FILENAME'#]$TABLE.]$COL$ROW + ScRefFlags nFlags = (aCellPos.Tab() == aPos.Tab()) ? ScRefFlags::ADDR_ABS : ScRefFlags::ADDR_ABS_3D; + OUString aStr(aCellPos.Format(nFlags, pDok, pDok->GetAddressConvention())); + PushString(aStr); + } + else if( aInfoType == "FILENAME" ) + { // file name and table name: 'FILENAME'#$TABLE + SCTAB nTab = aCellPos.Tab(); + OUString aFuncResult; + if( nTab < pDok->GetTableCount() ) + { + if( pDok->GetLinkMode( nTab ) == ScLinkMode::VALUE ) + pDok->GetName( nTab, aFuncResult ); + else { - if( pDok->GetLinkMode( nTab ) == ScLinkMode::VALUE ) - pDok->GetName( nTab, aFuncResult ); - else + SfxObjectShell* pShell = pDok->GetDocumentShell(); + if( pShell && pShell->GetMedium() ) { - SfxObjectShell* pShell = pDok->GetDocumentShell(); - if( pShell && pShell->GetMedium() ) - { - OUStringBuffer aBuf; - aBuf.append('\''); - const INetURLObject& rURLObj = pShell->GetMedium()->GetURLObject(); - aBuf.append(rURLObj.GetMainURL(INetURLObject::DecodeMechanism::Unambiguous)); - aBuf.append("'#$"); - OUString aTabName; - pDok->GetName( nTab, aTabName ); - aBuf.append(aTabName); - aFuncResult = aBuf.makeStringAndClear(); - } + OUStringBuffer aBuf; + aBuf.append('\''); + const INetURLObject& rURLObj = pShell->GetMedium()->GetURLObject(); + aBuf.append(rURLObj.GetMainURL(INetURLObject::DecodeMechanism::Unambiguous)); + aBuf.append("'#$"); + OUString aTabName; + pDok->GetName( nTab, aTabName ); + aBuf.append(aTabName); + aFuncResult = aBuf.makeStringAndClear(); } } - PushString( aFuncResult ); - } - else if( aInfoType == "COORD" ) - { // address, lotus 1-2-3 formatted: $TABLE:$COL$ROW - // Yes, passing tab as col is intentional! - OUString aCellStr1 = - ScAddress( static_cast<SCCOL>(aCellPos.Tab()), 0, 0 ).Format( - (ScRefFlags::COL_ABS|ScRefFlags::COL_VALID), nullptr, pDok->GetAddressConvention() ); - OUString aCellStr2 = - aCellPos.Format((ScRefFlags::COL_ABS|ScRefFlags::COL_VALID|ScRefFlags::ROW_ABS|ScRefFlags::ROW_VALID), - nullptr, pDok->GetAddressConvention()); - OUString aFuncResult = aCellStr1 + ":" + aCellStr2; - PushString( aFuncResult ); } + PushString( aFuncResult ); + } + else if( aInfoType == "COORD" ) + { // address, lotus 1-2-3 formatted: $TABLE:$COL$ROW + // Yes, passing tab as col is intentional! + OUString aCellStr1 = + ScAddress( static_cast<SCCOL>(aCellPos.Tab()), 0, 0 ).Format( + (ScRefFlags::COL_ABS|ScRefFlags::COL_VALID), nullptr, pDok->GetAddressConvention() ); + OUString aCellStr2 = + aCellPos.Format((ScRefFlags::COL_ABS|ScRefFlags::COL_VALID|ScRefFlags::ROW_ABS|ScRefFlags::ROW_VALID), + nullptr, pDok->GetAddressConvention()); + OUString aFuncResult = aCellStr1 + ":" + aCellStr2; + PushString( aFuncResult ); + } // *** CELL PROPERTIES *** - else if( aInfoType == "CONTENTS" ) - { // contents of the cell, no formatting - if (aCell.hasString()) - { - svl::SharedString aStr; - GetCellString(aStr, aCell); - PushString( aStr ); - } - else - PushDouble(GetCellValue(aCellPos, aCell)); + else if( aInfoType == "CONTENTS" ) + { // contents of the cell, no formatting + if (aCell.hasString()) + { + svl::SharedString aStr; + GetCellString(aStr, aCell); + PushString( aStr ); } - else if( aInfoType == "TYPE" ) - { // b = blank; l = string (label); v = otherwise (value) - sal_Unicode c; - if (aCell.hasString()) - c = 'l'; - else - c = aCell.hasNumeric() ? 'v' : 'b'; - PushString( OUString(c) ); - } - else if( aInfoType == "WIDTH" ) - { // column width (rounded off as count of zero characters in standard font and size) - Printer* pPrinter = pDok->GetPrinter(); - MapMode aOldMode( pPrinter->GetMapMode() ); - vcl::Font aOldFont( pPrinter->GetFont() ); - vcl::Font aDefFont; - - pPrinter->SetMapMode(MapMode(MapUnit::MapTwip)); - // font color doesn't matter here - pDok->GetDefPattern()->GetFont( aDefFont, SC_AUTOCOL_BLACK, pPrinter ); - pPrinter->SetFont( aDefFont ); - long nZeroWidth = pPrinter->GetTextWidth( OUString( '0' ) ); - pPrinter->SetFont( aOldFont ); - pPrinter->SetMapMode( aOldMode ); - int nZeroCount = static_cast<int>(pDok->GetColWidth( aCellPos.Col(), aCellPos.Tab() ) / nZeroWidth); - PushInt( nZeroCount ); - } - else if( aInfoType == "PREFIX" ) - { // ' = left; " = right; ^ = centered - sal_Unicode c = 0; - if (aCell.hasString()) - { - const SvxHorJustifyItem* pJustAttr = pDok->GetAttr( aCellPos, ATTR_HOR_JUSTIFY ); - switch( pJustAttr->GetValue() ) - { - case SvxCellHorJustify::Standard: - case SvxCellHorJustify::Left: - case SvxCellHorJustify::Block: c = '\''; break; - case SvxCellHorJustify::Center: c = '^'; break; - case SvxCellHorJustify::Right: c = '"'; break; - case SvxCellHorJustify::Repeat: c = '\\'; break; - } + else + PushDouble(GetCellValue(aCellPos, aCell)); + } + else if( aInfoType == "TYPE" ) + { // b = blank; l = string (label); v = otherwise (value) + sal_Unicode c; + if (aCell.hasString()) + c = 'l'; + else + c = aCell.hasNumeric() ? 'v' : 'b'; + PushString( OUString(c) ); + } + else if( aInfoType == "WIDTH" ) + { // column width (rounded off as count of zero characters in standard font and size) + Printer* pPrinter = pDok->GetPrinter(); + MapMode aOldMode( pPrinter->GetMapMode() ); + vcl::Font aOldFont( pPrinter->GetFont() ); + vcl::Font aDefFont; + + pPrinter->SetMapMode(MapMode(MapUnit::MapTwip)); + // font color doesn't matter here + pDok->GetDefPattern()->GetFont( aDefFont, SC_AUTOCOL_BLACK, pPrinter ); + pPrinter->SetFont( aDefFont ); + long nZeroWidth = pPrinter->GetTextWidth( OUString( '0' ) ); + pPrinter->SetFont( aOldFont ); + pPrinter->SetMapMode( aOldMode ); + int nZeroCount = static_cast<int>(pDok->GetColWidth( aCellPos.Col(), aCellPos.Tab() ) / nZeroWidth); + PushInt( nZeroCount ); + } + else if( aInfoType == "PREFIX" ) + { // ' = left; " = right; ^ = centered + sal_Unicode c = 0; + if (aCell.hasString()) + { + const SvxHorJustifyItem* pJustAttr = pDok->GetAttr( aCellPos, ATTR_HOR_JUSTIFY ); + switch( pJustAttr->GetValue() ) + { + case SvxCellHorJustify::Standard: + case SvxCellHorJustify::Left: + case SvxCellHorJustify::Block: c = '\''; break; + case SvxCellHorJustify::Center: c = '^'; break; + case SvxCellHorJustify::Right: c = '"'; break; + case SvxCellHorJustify::Repeat: c = '\\'; break; } - PushString( OUString(c) ); - } - else if( aInfoType == "PROTECT" ) - { // 1 = cell locked - const ScProtectionAttr* pProtAttr = pDok->GetAttr( aCellPos, ATTR_PROTECTION ); - PushInt( pProtAttr->GetProtection() ? 1 : 0 ); } + PushString( OUString(c) ); + } + else if( aInfoType == "PROTECT" ) + { // 1 = cell locked + const ScProtectionAttr* pProtAttr = pDok->GetAttr( aCellPos, ATTR_PROTECTION ); + PushInt( pProtAttr->GetProtection() ? 1 : 0 ); + } // *** FORMATTING *** - else if( aInfoType == "FORMAT" ) - { // specific format code for standard formats - OUString aFuncResult; - sal_uInt32 nFormat = pDok->GetNumberFormat( aCellPos ); - getFormatString(pFormatter, nFormat, aFuncResult); - PushString( aFuncResult ); - } - else if( aInfoType == "COLOR" ) - { // 1 = negative values are colored, otherwise 0 - const SvNumberformat* pFormat = pFormatter->GetEntry( pDok->GetNumberFormat( aCellPos ) ); - PushInt( lcl_FormatHasNegColor( pFormat ) ? 1 : 0 ); - } - else if( aInfoType == "PARENTHESES" ) - { // 1 = format string contains a '(' character, otherwise 0 - const SvNumberformat* pFormat = pFormatter->GetEntry( pDok->GetNumberFormat( aCellPos ) ); - PushInt( lcl_FormatHasOpenPar( pFormat ) ? 1 : 0 ); - } - else - PushIllegalArgument(); + else if( aInfoType == "FORMAT" ) + { // specific format code for standard formats + OUString aFuncResult; + sal_uInt32 nFormat = pDok->GetNumberFormat( aCellPos ); + getFormatString(pFormatter, nFormat, aFuncResult); + PushString( aFuncResult ); + } + else if( aInfoType == "COLOR" ) + { // 1 = negative values are colored, otherwise 0 + const SvNumberformat* pFormat = pFormatter->GetEntry( pDok->GetNumberFormat( aCellPos ) ); + PushInt( lcl_FormatHasNegColor( pFormat ) ? 1 : 0 ); + } + else if( aInfoType == "PARENTHESES" ) + { // 1 = format string contains a '(' character, otherwise 0 + const SvNumberformat* pFormat = pFormatter->GetEntry( pDok->GetNumberFormat( aCellPos ) ); + PushInt( lcl_FormatHasOpenPar( pFormat ) ? 1 : 0 ); } + else + PushIllegalArgument(); } } @@ -4367,260 +4367,260 @@ void ScInterpreter::ScSheets() void ScInterpreter::ScColumn() { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 0, 1 ) ) + if ( !MustHaveParamCount( nParamCount, 0, 1 ) ) + return; + + double nVal = 0.0; + if (nParamCount == 0) { - double nVal = 0.0; - if (nParamCount == 0) + nVal = aPos.Col() + 1; + if (bMatrixFormula) { - nVal = aPos.Col() + 1; - if (bMatrixFormula) + SCCOL nCols = 0; + SCROW nRows = 0; + if (pMyFormulaCell) + pMyFormulaCell->GetMatColsRows( nCols, nRows); + if (nCols == 0) { - SCCOL nCols = 0; - SCROW nRows = 0; - if (pMyFormulaCell) - pMyFormulaCell->GetMatColsRows( nCols, nRows); - if (nCols == 0) - { - // Happens if called via ScViewFunc::EnterMatrix() - // ScFormulaCell::GetResultDimensions() as of course a - // matrix result is not available yet. - nCols = 1; - } - ScMatrixRef pResMat = GetNewMat( static_cast<SCSIZE>(nCols), 1); - if (pResMat) - { - for (SCCOL i=0; i < nCols; ++i) - pResMat->PutDouble( nVal + i, static_cast<SCSIZE>(i), 0); - PushMatrix( pResMat); - return; - } + // Happens if called via ScViewFunc::EnterMatrix() + // ScFormulaCell::GetResultDimensions() as of course a + // matrix result is not available yet. + nCols = 1; + } + ScMatrixRef pResMat = GetNewMat( static_cast<SCSIZE>(nCols), 1); + if (pResMat) + { + for (SCCOL i=0; i < nCols; ++i) + pResMat->PutDouble( nVal + i, static_cast<SCSIZE>(i), 0); + PushMatrix( pResMat); + return; } } - else + } + else + { + switch ( GetStackType() ) { - switch ( GetStackType() ) + case svSingleRef : { - case svSingleRef : + SCCOL nCol1(0); + SCROW nRow1(0); + SCTAB nTab1(0); + PopSingleRef( nCol1, nRow1, nTab1 ); + nVal = static_cast<double>(nCol1 + 1); + } + break; + case svExternalSingleRef : + { + sal_uInt16 nFileId; + OUString aTabName; + ScSingleRefData aRef; + PopExternalSingleRef( nFileId, aTabName, aRef ); + ScAddress aAbsRef = aRef.toAbs(pDok, aPos); + nVal = static_cast<double>( aAbsRef.Col() + 1 ); + } + break; + + case svDoubleRef : + case svExternalDoubleRef : + { + SCCOL nCol1; + SCCOL nCol2; + if ( GetStackType() == svDoubleRef ) { - SCCOL nCol1(0); - SCROW nRow1(0); - SCTAB nTab1(0); - PopSingleRef( nCol1, nRow1, nTab1 ); - nVal = static_cast<double>(nCol1 + 1); + SCROW nRow1; + SCTAB nTab1; + SCROW nRow2; + SCTAB nTab2; + PopDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); } - break; - case svExternalSingleRef : + else { sal_uInt16 nFileId; OUString aTabName; - ScSingleRefData aRef; - PopExternalSingleRef( nFileId, aTabName, aRef ); - ScAddress aAbsRef = aRef.toAbs(pDok, aPos); - nVal = static_cast<double>( aAbsRef.Col() + 1 ); + ScComplexRefData aRef; + PopExternalDoubleRef( nFileId, aTabName, aRef ); + ScRange aAbs = aRef.toAbs(pDok, aPos); + nCol1 = aAbs.aStart.Col(); + nCol2 = aAbs.aEnd.Col(); } - break; - - case svDoubleRef : - case svExternalDoubleRef : + if (nCol2 > nCol1) { - SCCOL nCol1; - SCCOL nCol2; - if ( GetStackType() == svDoubleRef ) + ScMatrixRef pResMat = GetNewMat( + static_cast<SCSIZE>(nCol2-nCol1+1), 1); + if (pResMat) { - SCROW nRow1; - SCTAB nTab1; - SCROW nRow2; - SCTAB nTab2; - PopDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); - } - else - { - sal_uInt16 nFileId; - OUString aTabName; - ScComplexRefData aRef; - PopExternalDoubleRef( nFileId, aTabName, aRef ); - ScRange aAbs = aRef.toAbs(pDok, aPos); - nCol1 = aAbs.aStart.Col(); - nCol2 = aAbs.aEnd.Col(); - } - if (nCol2 > nCol1) - { - ScMatrixRef pResMat = GetNewMat( - static_cast<SCSIZE>(nCol2-nCol1+1), 1); - if (pResMat) - { - for (SCCOL i = nCol1; i <= nCol2; i++) - pResMat->PutDouble(static_cast<double>(i+1), - static_cast<SCSIZE>(i-nCol1), 0); - PushMatrix(pResMat); - return; - } + for (SCCOL i = nCol1; i <= nCol2; i++) + pResMat->PutDouble(static_cast<double>(i+1), + static_cast<SCSIZE>(i-nCol1), 0); + PushMatrix(pResMat); + return; } - else - nVal = static_cast<double>(nCol1 + 1); } - break; - default: - SetError( FormulaError::IllegalParameter ); + else + nVal = static_cast<double>(nCol1 + 1); } + break; + default: + SetError( FormulaError::IllegalParameter ); } - PushDouble( nVal ); } + PushDouble( nVal ); } void ScInterpreter::ScRow() { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 0, 1 ) ) + if ( !MustHaveParamCount( nParamCount, 0, 1 ) ) + return; + + double nVal = 0.0; + if (nParamCount == 0) { - double nVal = 0.0; - if (nParamCount == 0) + nVal = aPos.Row() + 1; + if (bMatrixFormula) { - nVal = aPos.Row() + 1; - if (bMatrixFormula) + SCCOL nCols = 0; + SCROW nRows = 0; + if (pMyFormulaCell) + pMyFormulaCell->GetMatColsRows( nCols, nRows); + if (nRows == 0) { - SCCOL nCols = 0; - SCROW nRows = 0; - if (pMyFormulaCell) - pMyFormulaCell->GetMatColsRows( nCols, nRows); - if (nRows == 0) - { - // Happens if called via ScViewFunc::EnterMatrix() - // ScFormulaCell::GetResultDimensions() as of course a - // matrix result is not available yet. - nRows = 1; - } - ScMatrixRef pResMat = GetNewMat( 1, static_cast<SCSIZE>(nRows)); - if (pResMat) - { - for (SCROW i=0; i < nRows; i++) - pResMat->PutDouble( nVal + i, 0, static_cast<SCSIZE>(i)); - PushMatrix( pResMat); - return; - } + // Happens if called via ScViewFunc::EnterMatrix() + // ScFormulaCell::GetResultDimensions() as of course a + // matrix result is not available yet. + nRows = 1; + } + ScMatrixRef pResMat = GetNewMat( 1, static_cast<SCSIZE>(nRows)); + if (pResMat) + { + for (SCROW i=0; i < nRows; i++) + pResMat->PutDouble( nVal + i, 0, static_cast<SCSIZE>(i)); + PushMatrix( pResMat); + return; } } - else + } + else + { + switch ( GetStackType() ) { - switch ( GetStackType() ) + case svSingleRef : { - case svSingleRef : + SCCOL nCol1(0); + SCROW nRow1(0); + SCTAB nTab1(0); + PopSingleRef( nCol1, nRow1, nTab1 ); + nVal = static_cast<double>(nRow1 + 1); + } + break; + case svExternalSingleRef : + { + sal_uInt16 nFileId; + OUString aTabName; + ScSingleRefData aRef; + PopExternalSingleRef( nFileId, aTabName, aRef ); + ScAddress aAbsRef = aRef.toAbs(pDok, aPos); + nVal = static_cast<double>( aAbsRef.Row() + 1 ); + } + break; + case svDoubleRef : + case svExternalDoubleRef : + { + SCROW nRow1; + SCROW nRow2; + if ( GetStackType() == svDoubleRef ) { - SCCOL nCol1(0); - SCROW nRow1(0); - SCTAB nTab1(0); - PopSingleRef( nCol1, nRow1, nTab1 ); - nVal = static_cast<double>(nRow1 + 1); + SCCOL nCol1; + SCTAB nTab1; + SCCOL nCol2; + SCTAB nTab2; + PopDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); } - break; - case svExternalSingleRef : + else { sal_uInt16 nFileId; OUString aTabName; - ScSingleRefData aRef; - PopExternalSingleRef( nFileId, aTabName, aRef ); - ScAddress aAbsRef = aRef.toAbs(pDok, aPos); - nVal = static_cast<double>( aAbsRef.Row() + 1 ); + ScComplexRefData aRef; + PopExternalDoubleRef( nFileId, aTabName, aRef ); + ScRange aAbs = aRef.toAbs(pDok, aPos); + nRow1 = aAbs.aStart.Row(); + nRow2 = aAbs.aEnd.Row(); } - break; - case svDoubleRef : - case svExternalDoubleRef : + if (nRow2 > nRow1) { - SCROW nRow1; - SCROW nRow2; - if ( GetStackType() == svDoubleRef ) + ScMatrixRef pResMat = GetNewMat( 1, + static_cast<SCSIZE>(nRow2-nRow1+1)); + if (pResMat) { - SCCOL nCol1; - SCTAB nTab1; - SCCOL nCol2; - SCTAB nTab2; - PopDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); - } - else - { - sal_uInt16 nFileId; - OUString aTabName; - ScComplexRefData aRef; - PopExternalDoubleRef( nFileId, aTabName, aRef ); - ScRange aAbs = aRef.toAbs(pDok, aPos); - nRow1 = aAbs.aStart.Row(); - nRow2 = aAbs.aEnd.Row(); - } - if (nRow2 > nRow1) - { - ScMatrixRef pResMat = GetNewMat( 1, - static_cast<SCSIZE>(nRow2-nRow1+1)); - if (pResMat) - { - for (SCROW i = nRow1; i <= nRow2; i++) - pResMat->PutDouble(static_cast<double>(i+1), 0, - static_cast<SCSIZE>(i-nRow1)); - PushMatrix(pResMat); - return; - } + for (SCROW i = nRow1; i <= nRow2; i++) + pResMat->PutDouble(static_cast<double>(i+1), 0, + static_cast<SCSIZE>(i-nRow1)); + PushMatrix(pResMat); + return; } - else - nVal = static_cast<double>(nRow1 + 1); } - break; - default: - SetError( FormulaError::IllegalParameter ); + else + nVal = static_cast<double>(nRow1 + 1); } + break; + default: + SetError( FormulaError::IllegalParameter ); } - PushDouble( nVal ); } + PushDouble( nVal ); } void ScInterpreter::ScSheet() { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 0, 1 ) ) + if ( !MustHaveParamCount( nParamCount, 0, 1 ) ) + return; + + SCTAB nVal = 0; + if ( nParamCount == 0 ) + nVal = aPos.Tab() + 1; + else { - SCTAB nVal = 0; - if ( nParamCount == 0 ) - nVal = aPos.Tab() + 1; - else + switch ( GetStackType() ) { - switch ( GetStackType() ) + case svString : { - case svString : - { - svl::SharedString aStr = PopString(); - if ( pDok->GetTable(aStr.getString(), nVal)) - ++nVal; - else - SetError( FormulaError::IllegalArgument ); - } - break; - case svSingleRef : - { - SCCOL nCol1(0); - SCROW nRow1(0); - SCTAB nTab1(0); - PopSingleRef(nCol1, nRow1, nTab1); - nVal = nTab1 + 1; - } - break; - case svDoubleRef : - { - SCCOL nCol1; - SCROW nRow1; - SCTAB nTab1; - SCCOL nCol2; - SCROW nRow2; - SCTAB nTab2; - PopDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); - nVal = nTab1 + 1; - } - break; - default: - SetError( FormulaError::IllegalParameter ); + svl::SharedString aStr = PopString(); + if ( pDok->GetTable(aStr.getString(), nVal)) + ++nVal; + else + SetError( FormulaError::IllegalArgument ); } - if ( nGlobalError != FormulaError::NONE ) - nVal = 0; + break; + case svSingleRef : + { + SCCOL nCol1(0); + SCROW nRow1(0); + SCTAB nTab1(0); + PopSingleRef(nCol1, nRow1, nTab1); + nVal = nTab1 + 1; + } + break; + case svDoubleRef : + { + SCCOL nCol1; + SCROW nRow1; + SCTAB nTab1; + SCCOL nCol2; + SCROW nRow2; + SCTAB nTab2; + PopDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); + nVal = nTab1 + 1; + } + break; + default: + SetError( FormulaError::IllegalParameter ); } - PushDouble( static_cast<double>(nVal) ); + if ( nGlobalError != FormulaError::NONE ) + nVal = 0; } + PushDouble( static_cast<double>(nVal) ); } namespace { @@ -4781,306 +4781,306 @@ void ScInterpreter::ScMatch() { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 2, 3 ) ) - { - double fTyp; - if (nParamCount == 3) - fTyp = GetDouble(); - else - fTyp = 1.0; - SCCOL nCol1 = 0; - SCROW nRow1 = 0; - SCTAB nTab1 = 0; - SCCOL nCol2 = 0; - SCROW nRow2 = 0; - ScMatrixRef pMatSrc = nullptr; + if ( !MustHaveParamCount( nParamCount, 2, 3 ) ) + return; - switch (GetStackType()) + double fTyp; + if (nParamCount == 3) + fTyp = GetDouble(); + else + fTyp = 1.0; + SCCOL nCol1 = 0; + SCROW nRow1 = 0; + SCTAB nTab1 = 0; + SCCOL nCol2 = 0; + SCROW nRow2 = 0; + ScMatrixRef pMatSrc = nullptr; + + switch (GetStackType()) + { + case svSingleRef: + PopSingleRef( nCol1, nRow1, nTab1); + nCol2 = nCol1; + nRow2 = nRow1; + break; + case svDoubleRef: { - case svSingleRef: - PopSingleRef( nCol1, nRow1, nTab1); - nCol2 = nCol1; - nRow2 = nRow1; - break; - case svDoubleRef: + SCTAB nTab2 = 0; + PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); + if (nTab1 != nTab2 || (nCol1 != nCol2 && nRow1 != nRow2)) { - SCTAB nTab2 = 0; - PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); - if (nTab1 != nTab2 || (nCol1 != nCol2 && nRow1 != nRow2)) - { - PushIllegalParameter(); - return; - } + PushIllegalParameter(); + return; } - break; - case svMatrix: - case svExternalDoubleRef: - { - if (GetStackType() == svMatrix) - pMatSrc = PopMatrix(); - else - PopExternalDoubleRef(pMatSrc); + } + break; + case svMatrix: + case svExternalDoubleRef: + { + if (GetStackType() == svMatrix) + pMatSrc = PopMatrix(); + else + PopExternalDoubleRef(pMatSrc); - if (!pMatSrc) - { - PushIllegalParameter(); - return; - } - } - break; - default: + if (!pMatSrc) + { PushIllegalParameter(); return; + } } + break; + default: + PushIllegalParameter(); + return; + } - if (nGlobalError == FormulaError::NONE) - { - double fVal; - ScQueryParam rParam; - rParam.nCol1 = nCol1; - rParam.nRow1 = nRow1; - rParam.nCol2 = nCol2; - rParam.nTab = nTab1; + if (nGlobalError == FormulaError::NONE) + { + double fVal; + ScQueryParam rParam; + rParam.nCol1 = nCol1; + rParam.nRow1 = nRow1; + rParam.nCol2 = nCol2; + rParam.nTab = nTab1; - ScQueryEntry& rEntry = rParam.GetEntry(0); - ScQueryEntry::Item& rItem = rEntry.GetQueryItem(); - rEntry.bDoQuery = true; - if (fTyp < 0.0) - rEntry.eOp = SC_GREATER_EQUAL; - else if (fTyp > 0.0) - rEntry.eOp = SC_LESS_EQUAL; - switch ( GetStackType() ) + ScQueryEntry& rEntry = rParam.GetEntry(0); + ScQueryEntry::Item& rItem = rEntry.GetQueryItem(); + rEntry.bDoQuery = true; + if (fTyp < 0.0) + rEntry.eOp = SC_GREATER_EQUAL; + else if (fTyp > 0.0) + rEntry.eOp = SC_LESS_EQUAL; + switch ( GetStackType() ) + { + case svDouble: { - case svDouble: + fVal = GetDouble(); + rItem.mfVal = fVal; + rItem.meType = ScQueryEntry::ByValue; + } + break; + case svString: + { + rItem.meType = ScQueryEntry::ByString; + rItem.maString = GetString(); + } + break; + case svDoubleRef : + case svSingleRef : + { + ScAddress aAdr; + if ( !PopDoubleRefOrSingleRef( aAdr ) ) { - fVal = GetDouble(); - rItem.mfVal = fVal; - rItem.meType = ScQueryEntry::ByValue; + PushInt(0); + return ; } - break; - case svString: + ScRefCellValue aCell(*pDok, aAdr); + if (aCell.hasNumeric()) { - rItem.meType = ScQueryEntry::ByString; - rItem.maString = GetString(); + fVal = GetCellValue(aAdr, aCell); + rItem.meType = ScQueryEntry::ByValue; + rItem.mfVal = fVal; } - break; - case svDoubleRef : - case svSingleRef : + else { - ScAddress aAdr; - if ( !PopDoubleRefOrSingleRef( aAdr ) ) - { - PushInt(0); - return ; - } - ScRefCellValue aCell(*pDok, aAdr); - if (aCell.hasNumeric()) - { - fVal = GetCellValue(aAdr, aCell); - rItem.meType = ScQueryEntry::ByValue; - rItem.mfVal = fVal; - } - else - { - GetCellString(rItem.maString, aCell); - rItem.meType = ScQueryEntry::ByString; - } + GetCellString(rItem.maString, aCell); + rItem.meType = ScQueryEntry::ByString; } - break; - case svExternalSingleRef: + } + break; + case svExternalSingleRef: + { + ScExternalRefCache::TokenRef pToken; + PopExternalSingleRef(pToken); + if (nGlobalError != FormulaError::NONE) { - ScExternalRefCache::TokenRef pToken; - PopExternalSingleRef(pToken); - if (nGlobalError != FormulaError::NONE) - { - PushError( nGlobalError); - return; - } - if (pToken->GetType() == svDouble) - { - rItem.meType = ScQueryEntry::ByValue; - rItem.mfVal = pToken->GetDouble(); - } - else - { - rItem.meType = ScQueryEntry::ByString; - rItem.maString = pToken->GetString(); - } + PushError( nGlobalError); + return; } - break; - case svExternalDoubleRef: - case svMatrix : + if (pToken->GetType() == svDouble) { - svl::SharedString aStr; - ScMatValType nType = GetDoubleOrStringFromMatrix( - rItem.mfVal, aStr); - rItem.maString = aStr; - rItem.meType = ScMatrix::IsNonValueType(nType) ? - ScQueryEntry::ByString : ScQueryEntry::ByValue; + rItem.meType = ScQueryEntry::ByValue; + rItem.mfVal = pToken->GetDouble(); } - break; - default: + else { - PushIllegalParameter(); - return; + rItem.meType = ScQueryEntry::ByString; + rItem.maString = pToken->GetString(); } } - if (rItem.meType == ScQueryEntry::ByString) + break; + case svExternalDoubleRef: + case svMatrix : { - bool bIsVBAMode = pDok->IsInVBAMode(); - - if ( bIsVBAMode ) - rParam.eSearchType = utl::SearchParam::SearchType::Wildcard; - else - rParam.eSearchType = DetectSearchType(rEntry.GetQueryItem().maString.getString(), pDok); + svl::SharedString aStr; + ScMatValType nType = GetDoubleOrStringFromMatrix( + rItem.mfVal, aStr); + rItem.maString = aStr; + rItem.meType = ScMatrix::IsNonValueType(nType) ? + ScQueryEntry::ByString : ScQueryEntry::ByValue; + } + break; + default: + { + PushIllegalParameter(); + return; } + } + if (rItem.meType == ScQueryEntry::ByString) + { + bool bIsVBAMode = pDok->IsInVBAMode(); - if (pMatSrc) // The source data is matrix array. + if ( bIsVBAMode ) + rParam.eSearchType = utl::SearchParam::SearchType::Wildcard; + else + rParam.eSearchType = DetectSearchType(rEntry.GetQueryItem().maString.getString(), pDok); + } + + if (pMatSrc) // The source data is matrix array. + { + SCSIZE nC, nR; + pMatSrc->GetDimensions( nC, nR); + if (nC > 1 && nR > 1) { - SCSIZE nC, nR; - pMatSrc->GetDimensions( nC, nR); - if (nC > 1 && nR > 1) - { - // The source matrix must be a vector. - PushIllegalParameter(); - return; - } + // The source matrix must be a vector. + PushIllegalParameter(); + return; + } - // Do not propagate errors from matrix while searching. - pMatSrc->SetErrorInterpreter( nullptr); + // Do not propagate errors from matrix while searching. + pMatSrc->SetErrorInterpreter( nullptr); - SCSIZE nMatCount = (nC == 1) ? nR : nC; - VectorMatrixAccessor aMatAcc(*pMatSrc, nC == 1); + SCSIZE nMatCount = (nC == 1) ? nR : nC; + VectorMatrixAccessor aMatAcc(*pMatSrc, nC == 1); - // simple serial search for equality mode (source data doesn't - // need to be sorted). + // simple serial search for equality mode (source data doesn't + // need to be sorted). - if (rEntry.eOp == SC_EQUAL) + if (rEntry.eOp == SC_EQUAL) + { + for (SCSIZE i = 0; i < nMatCount; ++i) { - for (SCSIZE i = 0; i < nMatCount; ++i) + if (lcl_CompareMatrix2Query( i, aMatAcc, rEntry) == 0) { - if (lcl_CompareMatrix2Query( i, aMatAcc, rEntry) == 0) - { - PushDouble(i+1); // found ! - return; - } + PushDouble(i+1); // found ! + return; } - PushNA(); // not found - return; } + PushNA(); // not found + return; + } - // binary search for non-equality mode (the source data is - // assumed to be sorted). + // binary search for non-equality mode (the source data is + // assumed to be sorted). - bool bAscOrder = (rEntry.eOp == SC_LESS_EQUAL); - SCSIZE nFirst = 0, nLast = nMatCount-1, nHitIndex = 0; - for (SCSIZE nLen = nLast-nFirst; nLen > 0; nLen = nLast-nFirst) + bool bAscOrder = (rEntry.eOp == SC_LESS_EQUAL); + SCSIZE nFirst = 0, nLast = nMatCount-1, nHitIndex = 0; + for (SCSIZE nLen = nLast-nFirst; nLen > 0; nLen = nLast-nFirst) + { + SCSIZE nMid = nFirst + nLen/2; + sal_Int32 nCmp = lcl_CompareMatrix2Query( nMid, aMatAcc, rEntry); + if (nCmp == 0) { - SCSIZE nMid = nFirst + nLen/2; - sal_Int32 nCmp = lcl_CompareMatrix2Query( nMid, aMatAcc, rEntry); - if (nCmp == 0) - { - // exact match. find the last item with the same value. - lcl_GetLastMatch( nMid, aMatAcc, nMatCount, !bAscOrder); - PushDouble( nMid+1); - return; - } - - if (nLen == 1) // first and last items are next to each other. - { - if (nCmp < 0) - nHitIndex = bAscOrder ? nLast : nFirst; - else - nHitIndex = bAscOrder ? nFirst : nLast; - break; - } + // exact match. find the last item with the same value. + lcl_GetLastMatch( nMid, aMatAcc, nMatCount, !bAscOrder); + PushDouble( nMid+1); + return; + } + if (nLen == 1) // first and last items are next to each other. + { if (nCmp < 0) - { - if (bAscOrder) - nFirst = nMid; - else - nLast = nMid; - } + nHitIndex = bAscOrder ? nLast : nFirst; else - { - if (bAscOrder) - nLast = nMid; - else - nFirst = nMid; - } + nHitIndex = bAscOrder ? nFirst : nLast; + break; } - if (nHitIndex == nMatCount-1) // last item + if (nCmp < 0) { - sal_Int32 nCmp = lcl_CompareMatrix2Query( nHitIndex, aMatAcc, rEntry); - if ((bAscOrder && nCmp <= 0) || (!bAscOrder && nCmp >= 0)) - { - // either the last item is an exact match or the real - // hit is beyond the last item. - PushDouble( nHitIndex+1); - return; - } + if (bAscOrder) + nFirst = nMid; + else + nLast = nMid; + } + else + { + if (bAscOrder) + nLast = nMid; + else + nFirst = nMid; } + } - if (nHitIndex > 0) // valid hit must be 2nd item or higher + if (nHitIndex == nMatCount-1) // last item + { + sal_Int32 nCmp = lcl_CompareMatrix2Query( nHitIndex, aMatAcc, rEntry); + if ((bAscOrder && nCmp <= 0) || (!bAscOrder && nCmp >= 0)) { - PushDouble( nHitIndex); // non-exact match + // either the last item is an exact match or the real + // hit is beyond the last item. + PushDouble( nHitIndex+1); return; } + } - PushNA(); + if (nHitIndex > 0) // valid hit must be 2nd item or higher + { + PushDouble( nHitIndex); // non-exact match return; } - SCCOLROW nDelta = 0; - if (nCol1 == nCol2) - { // search row in column - rParam.nRow2 = nRow2; - rEntry.nField = nCol1; - ScAddress aResultPos( nCol1, nRow1, nTab1); - if (!LookupQueryWithCache( aResultPos, rParam)) + PushNA(); + return; + } + + SCCOLROW nDelta = 0; + if (nCol1 == nCol2) + { // search row in column + rParam.nRow2 = nRow2; + rEntry.nField = nCol1; + ScAddress aResultPos( nCol1, nRow1, nTab1); + if (!LookupQueryWithCache( aResultPos, rParam)) + { + PushNA(); + return; + } + nDelta = aResultPos.Row() - nRow1; + } + else + { // search column in row + SCCOL nC; + rParam.bByRow = false; + rParam.nRow2 = nRow1; + rEntry.nField = nCol1; + ScQueryCellIterator aCellIter(pDok, mrContext, nTab1, rParam, false); + // Advance Entry.nField in Iterator if column changed + aCellIter.SetAdvanceQueryParamEntryField( true ); + if (fTyp == 0.0) + { // EQUAL + if ( aCellIter.GetFirst() ) + nC = aCellIter.GetCol(); + else { PushNA(); return; } - nDelta = aResultPos.Row() - nRow1; } else - { // search column in row - SCCOL nC; - rParam.bByRow = false; - rParam.nRow2 = nRow1; - rEntry.nField = nCol1; - ScQueryCellIterator aCellIter(pDok, mrContext, nTab1, rParam, false); - // Advance Entry.nField in Iterator if column changed - aCellIter.SetAdvanceQueryParamEntryField( true ); - if (fTyp == 0.0) - { // EQUAL - if ( aCellIter.GetFirst() ) - nC = aCellIter.GetCol(); - else - { - PushNA(); - return; - } - } - else - { // <= or >= - SCROW nR; - if ( !aCellIter.FindEqualOrSortedLastInRange( nC, nR ) ) - { - PushNA(); - return; - } + { // <= or >= + SCROW nR; + if ( !aCellIter.FindEqualOrSortedLastInRange( nC, nR ) ) + { + PushNA(); + return; } - nDelta = nC - nCol1; } - PushDouble(static_cast<double>(nDelta + 1)); + nDelta = nC - nCol1; } - else - PushIllegalParameter(); + PushDouble(static_cast<double>(nDelta + 1)); } + else + PushIllegalParameter(); } namespace { @@ -5121,62 +5121,62 @@ bool isCellContentEmpty( const ScRefCellValue& rCell ) void ScInterpreter::ScCountEmptyCells() { - if ( MustHaveParamCount( GetByte(), 1 ) ) + if ( !MustHaveParamCount( GetByte(), 1 ) ) + return; + + const SCSIZE nMatRows = GetRefListArrayMaxSize(1); + // There's either one RefList and nothing else, or none. + ScMatrixRef xResMat = (nMatRows ? GetNewMat( 1, nMatRows) : nullptr); + sal_uLong nMaxCount = 0, nCount = 0; + switch (GetStackType()) { - const SCSIZE nMatRows = GetRefListArrayMaxSize(1); - // There's either one RefList and nothing else, or none. - ScMatrixRef xResMat = (nMatRows ? GetNewMat( 1, nMatRows) : nullptr); - sal_uLong nMaxCount = 0, nCount = 0; - switch (GetStackType()) + case svSingleRef : { - case svSingleRef : - { - nMaxCount = 1; - ScAddress aAdr; - PopSingleRef( aAdr ); - ScRefCellValue aCell(*pDok, aAdr); - if (!isCellContentEmpty(aCell)) - nCount = 1; - } - break; - case svRefList : - case svDoubleRef : + nMaxCount = 1; + ScAddress aAdr; + PopSingleRef( aAdr ); + ScRefCellValue aCell(*pDok, aAdr); + if (!isCellContentEmpty(aCell)) + nCount = 1; + } + break; + case svRefList : + case svDoubleRef : + { + ScRange aRange; + short nParam = 1; + SCSIZE nRefListArrayPos = 0; + size_t nRefInList = 0; + while (nParam-- > 0) { - ScRange aRange; - short nParam = 1; - SCSIZE nRefListArrayPos = 0; - size_t nRefInList = 0; - while (nParam-- > 0) - { - nRefListArrayPos = nRefInList; - PopDoubleRef( aRange, nParam, nRefInList); - nMaxCount += - static_cast<sal_uLong>(aRange.aEnd.Row() - aRange.aStart.Row() + 1) * - static_cast<sal_uLong>(aRange.aEnd.Col() - aRange.aStart.Col() + 1) * - static_cast<sal_uLong>(aRange.aEnd.Tab() - aRange.aStart.Tab() + 1); + nRefListArrayPos = nRefInList; + PopDoubleRef( aRange, nParam, nRefInList); + nMaxCount += + static_cast<sal_uLong>(aRange.aEnd.Row() - aRange.aStart.Row() + 1) * + static_cast<sal_uLong>(aRange.aEnd.Col() - aRange.aStart.Col() + 1) * + static_cast<sal_uLong>(aRange.aEnd.Tab() - aRange.aStart.Tab() + 1); - ScCellIterator aIter( pDok, aRange, mnSubTotalFlags); - for (bool bHas = aIter.first(); bHas; bHas = aIter.next()) - { - const ScRefCellValue& rCell = aIter.getRefCellValue(); - if (!isCellContentEmpty(rCell)) - ++nCount; - } - if (xResMat) - { - xResMat->PutDouble( nMaxCount - nCount, 0, nRefListArrayPos); - nMaxCount = nCount = 0; - } + ScCellIterator aIter( pDok, aRange, mnSubTotalFlags); + for (bool bHas = aIter.first(); bHas; bHas = aIter.next()) + { + const ScRefCellValue& rCell = aIter.getRefCellValue(); + if (!isCellContentEmpty(rCell)) + ++nCount; + } + if (xResMat) + { + xResMat->PutDouble( nMaxCount - nCount, 0, nRefListArrayPos); + nMaxCount = nCount = 0; } } - break; - default : SetError(FormulaError::IllegalParameter); break; } - if (xResMat) - PushMatrix( xResMat); - else - PushDouble(nMaxCount - nCount); + break; + default : SetError(FormulaError::IllegalParameter); break; } + if (xResMat) + PushMatrix( xResMat); + else + PushDouble(nMaxCount - nCount); } void ScInterpreter::IterateParametersIf( ScIterFuncIf eFunc ) @@ -5621,199 +5621,199 @@ void ScInterpreter::ScAverageIf() void ScInterpreter::ScCountIf() { - if ( MustHaveParamCount( GetByte(), 2 ) ) + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + + svl::SharedString aString; + double fVal = 0.0; + bool bIsString = true; + switch ( GetStackType() ) { - svl::SharedString aString; - double fVal = 0.0; - bool bIsString = true; - switch ( GetStackType() ) + case svDoubleRef : + case svSingleRef : { - case svDoubleRef : - case svSingleRef : + ScAddress aAdr; + if ( !PopDoubleRefOrSingleRef( aAdr ) ) { - ScAddress aAdr; - if ( !PopDoubleRefOrSingleRef( aAdr ) ) - { - PushInt(0); - return ; - } - ScRefCellValue aCell(*pDok, aAdr); - switch (aCell.meType) - { - case CELLTYPE_VALUE : + PushInt(0); + return ; + } + ScRefCellValue aCell(*pDok, aAdr); + switch (aCell.meType) + { + case CELLTYPE_VALUE : + fVal = GetCellValue(aAdr, aCell); + bIsString = false; + break; + case CELLTYPE_FORMULA : + if (aCell.mpFormula->IsValue()) + { fVal = GetCellValue(aAdr, aCell); bIsString = false; - break; - case CELLTYPE_FORMULA : - if (aCell.mpFormula->IsValue()) - { - fVal = GetCellValue(aAdr, aCell); - bIsString = false; - } - else - GetCellString(aString, aCell); - break; - case CELLTYPE_STRING : - case CELLTYPE_EDIT : + } + else GetCellString(aString, aCell); - break; - default: - fVal = 0.0; - bIsString = false; - } + break; + case CELLTYPE_STRING : + case CELLTYPE_EDIT : + GetCellString(aString, aCell); + break; + default: + fVal = 0.0; + bIsString = false; } - break; + } + break; + case svMatrix: + case svExternalSingleRef: + case svExternalDoubleRef: + { + ScMatValType nType = GetDoubleOrStringFromMatrix(fVal, aString); + bIsString = ScMatrix::IsRealStringType( nType); + } + break; + case svString: + aString = GetString(); + break; + default: + { + fVal = GetDouble(); + bIsString = false; + } + } + double fCount = 0.0; + short nParam = 1; + const SCSIZE nMatRows = GetRefListArrayMaxSize( nParam); + // There's either one RefList and nothing else, or none. + ScMatrixRef xResMat = (nMatRows ? GetNewMat( 1, nMatRows) : nullptr); + SCSIZE nRefListArrayPos = 0; + size_t nRefInList = 0; + while (nParam-- > 0) + { + SCCOL nCol1 = 0; + SCROW nRow1 = 0; + SCTAB nTab1 = 0; + SCCOL nCol2 = 0; + SCROW nRow2 = 0; + SCTAB nTab2 = 0; + ScMatrixRef pQueryMatrix; + switch ( GetStackType() ) + { + case svRefList : + nRefListArrayPos = nRefInList; + [[fallthrough]]; + case svDoubleRef : + { + ScRange aRange; + PopDoubleRef( aRange, nParam, nRefInList); + aRange.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); + } + break; + case svSingleRef : + PopSingleRef( nCol1, nRow1, nTab1 ); + nCol2 = nCol1; + nRow2 = nRow1; + nTab2 = nTab1; + break; case svMatrix: case svExternalSingleRef: case svExternalDoubleRef: { - ScMatValType nType = GetDoubleOrStringFromMatrix(fVal, aString); - bIsString = ScMatrix::IsRealStringType( nType); + pQueryMatrix = GetMatrix(); + if (!pQueryMatrix) + { + PushIllegalParameter(); + return; + } + nCol1 = 0; + nRow1 = 0; + nTab1 = 0; + SCSIZE nC, nR; + pQueryMatrix->GetDimensions( nC, nR); + nCol2 = static_cast<SCCOL>(nC - 1); + nRow2 = static_cast<SCROW>(nR - 1); + nTab2 = 0; } break; - case svString: - aString = GetString(); - break; default: - { - fVal = GetDouble(); - bIsString = false; - } + PopError(); // Propagate it further + PushIllegalParameter(); + return ; } - double fCount = 0.0; - short nParam = 1; - const SCSIZE nMatRows = GetRefListArrayMaxSize( nParam); - // There's either one RefList and nothing else, or none. - ScMatrixRef xResMat = (nMatRows ? GetNewMat( 1, nMatRows) : nullptr); - SCSIZE nRefListArrayPos = 0; - size_t nRefInList = 0; - while (nParam-- > 0) + if ( nTab1 != nTab2 ) { - SCCOL nCol1 = 0; - SCROW nRow1 = 0; - SCTAB nTab1 = 0; - SCCOL nCol2 = 0; - SCROW nRow2 = 0; - SCTAB nTab2 = 0; - ScMatrixRef pQueryMatrix; - switch ( GetStackType() ) - { - case svRefList : - nRefListArrayPos = nRefInList; - [[fallthrough]]; - case svDoubleRef : - { - ScRange aRange; - PopDoubleRef( aRange, nParam, nRefInList); - aRange.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); - } - break; - case svSingleRef : - PopSingleRef( nCol1, nRow1, nTab1 ); - nCol2 = nCol1; - nRow2 = nRow1; - nTab2 = nTab1; - break; - case svMatrix: - case svExternalSingleRef: - case svExternalDoubleRef: - { - pQueryMatrix = GetMatrix(); - if (!pQueryMatrix) - { - PushIllegalParameter(); - return; - } - nCol1 = 0; - nRow1 = 0; - nTab1 = 0; - SCSIZE nC, nR; - pQueryMatrix->GetDimensions( nC, nR); - nCol2 = static_cast<SCCOL>(nC - 1); - nRow2 = static_cast<SCROW>(nR - 1); - nTab2 = 0; - } - break; - default: - PopError(); // Propagate it further - PushIllegalParameter(); - return ; - } - if ( nTab1 != nTab2 ) + PushIllegalParameter(); + return; + } + if (nCol1 > nCol2) + { + PushIllegalParameter(); + return; + } + if (nGlobalError == FormulaError::NONE) + { + ScQueryParam rParam; + rParam.nRow1 = nRow1; + rParam.nRow2 = nRow2; + + ScQueryEntry& rEntry = rParam.GetEntry(0); + ScQueryEntry::Item& rItem = rEntry.GetQueryItem(); + rEntry.bDoQuery = true; + if (!bIsString) { - PushIllegalParameter(); - return; + rItem.meType = ScQueryEntry::ByValue; + rItem.mfVal = fVal; + rEntry.eOp = SC_EQUAL; } - if (nCol1 > nCol2) + else { - PushIllegalParameter(); - return; + rParam.FillInExcelSyntax(pDok->GetSharedStringPool(), aString.getString(), 0, pFormatter); + if (rItem.meType == ScQueryEntry::ByString) + rParam.eSearchType = DetectSearchType(rItem.maString.getString(), pDok); } - if (nGlobalError == FormulaError::NONE) + rParam.nCol1 = nCol1; + rParam.nCol2 = nCol2; + rEntry.nField = nCol1; + if (pQueryMatrix) { - ScQueryParam rParam; - rParam.nRow1 = nRow1; - rParam.nRow2 = nRow2; - - ScQueryEntry& rEntry = rParam.GetEntry(0); - ScQueryEntry::Item& rItem = rEntry.GetQueryItem(); - rEntry.bDoQuery = true; - if (!bIsString) - { - rItem.meType = ScQueryEntry::ByValue; - rItem.mfVal = fVal; - rEntry.eOp = SC_EQUAL; - } - else + // Never case-sensitive. + sc::CompareOptions aOptions( pDok, rEntry, rParam.eSearchType); + ScMatrixRef pResultMatrix = QueryMat( pQueryMatrix, aOptions); + if (nGlobalError != FormulaError::NONE || !pResultMatrix) { - rParam.FillInExcelSyntax(pDok->GetSharedStringPool(), aString.getString(), 0, pFormatter); - if (rItem.meType == ScQueryEntry::ByString) - rParam.eSearchType = DetectSearchType(rItem.maString.getString(), pDok); + PushIllegalParameter(); + return; } - rParam.nCol1 = nCol1; - rParam.nCol2 = nCol2; - rEntry.nField = nCol1; - if (pQueryMatrix) - { - // Never case-sensitive. - sc::CompareOptions aOptions( pDok, rEntry, rParam.eSearchType); - ScMatrixRef pResultMatrix = QueryMat( pQueryMatrix, aOptions); - if (nGlobalError != FormulaError::NONE || !pResultMatrix) - { - PushIllegalParameter(); - return; - } - SCSIZE nSize = pResultMatrix->GetElementCount(); - for (SCSIZE nIndex = 0; nIndex < nSize; ++nIndex) - { - if (pResultMatrix->IsValue( nIndex) && - pResultMatrix->GetDouble( nIndex)) - ++fCount; - } - } - else + SCSIZE nSize = pResultMatrix->GetElementCount(); + for (SCSIZE nIndex = 0; nIndex < nSize; ++nIndex) { - ScCountIfCellIterator aCellIter(pDok, mrContext, nTab1, rParam); - fCount += aCellIter.GetCount(); + if (pResultMatrix->IsValue( nIndex) && + pResultMatrix->GetDouble( nIndex)) + ++fCount; } } else { - PushIllegalParameter(); - return; - } - if (xResMat) - { - xResMat->PutDouble( fCount, 0, nRefListArrayPos); - fCount = 0.0; + ScCountIfCellIterator aCellIter(pDok, mrContext, nTab1, rParam); + fCount += aCellIter.GetCount(); } } - if (xResMat) - PushMatrix( xResMat); else - PushDouble(fCount); + { + PushIllegalParameter(); + return; + } + if (xResMat) + { + xResMat->PutDouble( fCount, 0, nRefListArrayPos); + fCount = 0.0; + } } + if (xResMat) + PushMatrix( xResMat); + else + PushDouble(fCount); } void ScInterpreter::IterateParametersIfs( double(*ResultFunc)( const sc::ParamIfsResult& rRes ) ) @@ -7508,144 +7508,144 @@ void ScInterpreter::ScVLookup() void ScInterpreter::ScSubTotal() { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCountMin( nParamCount, 2 ) ) + if ( !MustHaveParamCountMin( nParamCount, 2 ) ) + return; + + // We must fish the 1st parameter deep from the stack! And push it on top. + const FormulaToken* p = pStack[ sp - nParamCount ]; + PushWithoutError( *p ); + sal_Int32 nFunc = GetInt32(); + mnSubTotalFlags |= SubtotalFlags::IgnoreNestedStAg | SubtotalFlags::IgnoreFiltered; + if (nFunc > 100) { - // We must fish the 1st parameter deep from the stack! And push it on top. - const FormulaToken* p = pStack[ sp - nParamCount ]; - PushWithoutError( *p ); - sal_Int32 nFunc = GetInt32(); - mnSubTotalFlags |= SubtotalFlags::IgnoreNestedStAg | SubtotalFlags::IgnoreFiltered; - if (nFunc > 100) - { - // For opcodes 101 through 111, we need to skip hidden cells. - // Other than that these opcodes are identical to 1 through 11. - mnSubTotalFlags |= SubtotalFlags::IgnoreHidden; - nFunc -= 100; - } + // For opcodes 101 through 111, we need to skip hidden cells. + // Other than that these opcodes are identical to 1 through 11. + mnSubTotalFlags |= SubtotalFlags::IgnoreHidden; + nFunc -= 100; + } - if ( nGlobalError != FormulaError::NONE || nFunc < 1 || nFunc > 11 ) - PushIllegalArgument(); // simulate return on stack, not SetError(...) - else + if ( nGlobalError != FormulaError::NONE || nFunc < 1 || nFunc > 11 ) + PushIllegalArgument(); // simulate return on stack, not SetError(...) + else + { + cPar = nParamCount - 1; + switch( nFunc ) { - cPar = nParamCount - 1; - switch( nFunc ) - { - case SUBTOTAL_FUNC_AVE : ScAverage(); break; - case SUBTOTAL_FUNC_CNT : ScCount(); break; - case SUBTOTAL_FUNC_CNT2 : ScCount2(); break; - case SUBTOTAL_FUNC_MAX : ScMax(); break; - case SUBTOTAL_FUNC_MIN : ScMin(); break; - case SUBTOTAL_FUNC_PROD : ScProduct(); break; - case SUBTOTAL_FUNC_STD : ScStDev(); break; - case SUBTOTAL_FUNC_STDP : ScStDevP(); break; - case SUBTOTAL_FUNC_SUM : ScSum(); break; - case SUBTOTAL_FUNC_VAR : ScVar(); break; - case SUBTOTAL_FUNC_VARP : ScVarP(); break; - default : PushIllegalArgument(); break; - } + case SUBTOTAL_FUNC_AVE : ScAverage(); break; + case SUBTOTAL_FUNC_CNT : ScCount(); break; + case SUBTOTAL_FUNC_CNT2 : ScCount2(); break; + case SUBTOTAL_FUNC_MAX : ScMax(); break; + case SUBTOTAL_FUNC_MIN : ScMin(); break; + case SUBTOTAL_FUNC_PROD : ScProduct(); break; + case SUBTOTAL_FUNC_STD : ScStDev(); break; + case SUBTOTAL_FUNC_STDP : ScStDevP(); break; + case SUBTOTAL_FUNC_SUM : ScSum(); break; + case SUBTOTAL_FUNC_VAR : ScVar(); break; + case SUBTOTAL_FUNC_VARP : ScVarP(); break; + default : PushIllegalArgument(); break; } - mnSubTotalFlags = SubtotalFlags::NONE; - // Get rid of the 1st (fished) parameter. - FormulaConstTokenRef xRef( PopToken()); - Pop(); - PushTokenRef( xRef); } + mnSubTotalFlags = SubtotalFlags::NONE; + // Get rid of the 1st (fished) parameter. + FormulaConstTokenRef xRef( PopToken()); + Pop(); + PushTokenRef( xRef); } void ScInterpreter::ScAggregate() { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCountMin( nParamCount, 3 ) ) - { - const FormulaError nErr = nGlobalError; - nGlobalError = FormulaError::NONE; + if ( !MustHaveParamCountMin( nParamCount, 3 ) ) + return; - // fish the 1st parameter from the stack and push it on top. - const FormulaToken* p = pStack[ sp - nParamCount ]; - PushWithoutError( *p ); - sal_Int32 nFunc = GetInt32(); - // fish the 2nd parameter from the stack and push it on top. - const FormulaToken* p2 = pStack[ sp - ( nParamCount - 1 ) ]; - PushWithoutError( *p2 ); - sal_Int32 nOption = GetInt32(); + const FormulaError nErr = nGlobalError; + nGlobalError = FormulaError::NONE; - if ( nGlobalError != FormulaError::NONE || nFunc < 1 || nFunc > 19 ) + // fish the 1st parameter from the stack and push it on top. + const FormulaToken* p = pStack[ sp - nParamCount ]; + PushWithoutError( *p ); + sal_Int32 nFunc = GetInt32(); + // fish the 2nd parameter from the stack and push it on top. + const FormulaToken* p2 = pStack[ sp - ( nParamCount - 1 ) ]; + PushWithoutError( *p2 ); + sal_Int32 nOption = GetInt32(); + + if ( nGlobalError != FormulaError::NONE || nFunc < 1 || nFunc > 19 ) + { + nGlobalError = nErr; + PushIllegalArgument(); + } + else + { + switch ( nOption) { - nGlobalError = nErr; - PushIllegalArgument(); + case 0 : // ignore nested SUBTOTAL and AGGREGATE functions + mnSubTotalFlags = SubtotalFlags::IgnoreNestedStAg; + break; + case 1 : // ignore hidden rows, nested SUBTOTAL and AGGREGATE functions + mnSubTotalFlags = SubtotalFlags::IgnoreHidden | SubtotalFlags::IgnoreNestedStAg; + break; + case 2 : // ignore error values, nested SUBTOTAL and AGGREGATE functions + mnSubTotalFlags = SubtotalFlags::IgnoreErrVal | SubtotalFlags::IgnoreNestedStAg; + break; + case 3 : // ignore hidden rows, error values, nested SUBTOTAL and AGGREGATE functions + mnSubTotalFlags = SubtotalFlags::IgnoreHidden | SubtotalFlags::IgnoreErrVal | SubtotalFlags::IgnoreNestedStAg; + break; + case 4 : // ignore nothing + mnSubTotalFlags = SubtotalFlags::NONE; + break; + case 5 : // ignore hidden rows + mnSubTotalFlags = SubtotalFlags::IgnoreHidden ; + break; + case 6 : // ignore error values + mnSubTotalFlags = SubtotalFlags::IgnoreErrVal ; + break; + case 7 : // ignore hidden rows and error values + mnSubTotalFlags = SubtotalFlags::IgnoreHidden | SubtotalFlags::IgnoreErrVal ; + break; + default : + nGlobalError = nErr; + PushIllegalArgument(); + return; } - else - { - switch ( nOption) - { - case 0 : // ignore nested SUBTOTAL and AGGREGATE functions - mnSubTotalFlags = SubtotalFlags::IgnoreNestedStAg; - break; - case 1 : // ignore hidden rows, nested SUBTOTAL and AGGREGATE functions - mnSubTotalFlags = SubtotalFlags::IgnoreHidden | SubtotalFlags::IgnoreNestedStAg; - break; - case 2 : // ignore error values, nested SUBTOTAL and AGGREGATE functions - mnSubTotalFlags = SubtotalFlags::IgnoreErrVal | SubtotalFlags::IgnoreNestedStAg; - break; - case 3 : // ignore hidden rows, error values, nested SUBTOTAL and AGGREGATE functions - mnSubTotalFlags = SubtotalFlags::IgnoreHidden | SubtotalFlags::IgnoreErrVal | SubtotalFlags::IgnoreNestedStAg; - break; - case 4 : // ignore nothing - mnSubTotalFlags = SubtotalFlags::NONE; - break; - case 5 : // ignore hidden rows - mnSubTotalFlags = SubtotalFlags::IgnoreHidden ; - break; - case 6 : // ignore error values - mnSubTotalFlags = SubtotalFlags::IgnoreErrVal ; - break; - case 7 : // ignore hidden rows and error values - mnSubTotalFlags = SubtotalFlags::IgnoreHidden | SubtotalFlags::IgnoreErrVal ; - break; - default : - nGlobalError = nErr; - PushIllegalArgument(); - return; - } - if ((mnSubTotalFlags & SubtotalFlags::IgnoreErrVal) == SubtotalFlags::NONE) - nGlobalError = nErr; + if ((mnSubTotalFlags & SubtotalFlags::IgnoreErrVal) == SubtotalFlags::NONE) + nGlobalError = nErr; - cPar = nParamCount - 2; - switch ( nFunc ) - { - case AGGREGATE_FUNC_AVE : ScAverage(); break; - case AGGREGATE_FUNC_CNT : ScCount(); break; - case AGGREGATE_FUNC_CNT2 : ScCount2(); break; - case AGGREGATE_FUNC_MAX : ScMax(); break; - case AGGREGATE_FUNC_MIN : ScMin(); break; - case AGGREGATE_FUNC_PROD : ScProduct(); break; - case AGGREGATE_FUNC_STD : ScStDev(); break; - case AGGREGATE_FUNC_STDP : ScStDevP(); break; - case AGGREGATE_FUNC_SUM : ScSum(); break; - case AGGREGATE_FUNC_VAR : ScVar(); break; - case AGGREGATE_FUNC_VARP : ScVarP(); break; - case AGGREGATE_FUNC_MEDIAN : ScMedian(); break; - case AGGREGATE_FUNC_MODSNGL : ScModalValue(); break; - case AGGREGATE_FUNC_LARGE : ScLarge(); break; - case AGGREGATE_FUNC_SMALL : ScSmall(); break; - case AGGREGATE_FUNC_PERCINC : ScPercentile( true ); break; - case AGGREGATE_FUNC_QRTINC : ScQuartile( true ); break; - case AGGREGATE_FUNC_PERCEXC : ScPercentile( false ); break; - case AGGREGATE_FUNC_QRTEXC : ScQuartile( false ); break; - default: - nGlobalError = nErr; - PushIllegalArgument(); - break; - } - mnSubTotalFlags = SubtotalFlags::NONE; + cPar = nParamCount - 2; + switch ( nFunc ) + { + case AGGREGATE_FUNC_AVE : ScAverage(); break; + case AGGREGATE_FUNC_CNT : ScCount(); break; + case AGGREGATE_FUNC_CNT2 : ScCount2(); break; + case AGGREGATE_FUNC_MAX : ScMax(); break; + case AGGREGATE_FUNC_MIN : ScMin(); break; + case AGGREGATE_FUNC_PROD : ScProduct(); break; + case AGGREGATE_FUNC_STD : ScStDev(); break; + case AGGREGATE_FUNC_STDP : ScStDevP(); break; + case AGGREGATE_FUNC_SUM : ScSum(); break; + case AGGREGATE_FUNC_VAR : ScVar(); break; + case AGGREGATE_FUNC_VARP : ScVarP(); break; + case AGGREGATE_FUNC_MEDIAN : ScMedian(); break; + case AGGREGATE_FUNC_MODSNGL : ScModalValue(); break; + case AGGREGATE_FUNC_LARGE : ScLarge(); break; + case AGGREGATE_FUNC_SMALL : ScSmall(); break; + case AGGREGATE_FUNC_PERCINC : ScPercentile( true ); break; + case AGGREGATE_FUNC_QRTINC : ScQuartile( true ); break; + case AGGREGATE_FUNC_PERCEXC : ScPercentile( false ); break; + case AGGREGATE_FUNC_QRTEXC : ScQuartile( false ); break; + default: + nGlobalError = nErr; + PushIllegalArgument(); + break; } - FormulaConstTokenRef xRef( PopToken()); - // Get rid of the 1st and 2nd (fished) parameters. - Pop(); - Pop(); - PushTokenRef( xRef); + mnSubTotalFlags = SubtotalFlags::NONE; } + FormulaConstTokenRef xRef( PopToken()); + // Get rid of the 1st and 2nd (fished) parameters. + Pop(); + Pop(); + PushTokenRef( xRef); } std::unique_ptr<ScDBQueryParamBase> ScInterpreter::GetDBParams( bool& rMissingField ) @@ -8045,170 +8045,170 @@ void ScInterpreter::ScDBVarP() void ScInterpreter::ScIndirect() { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 1, 2 ) ) - { - // Reference address syntax for INDIRECT is configurable. - FormulaGrammar::AddressConvention eConv = maCalcConfig.meStringRefAddressSyntax; - if (eConv == FormulaGrammar::CONV_UNSPECIFIED) - // Use the current address syntax if unspecified. - eConv = pDok->GetAddressConvention(); + if ( !MustHaveParamCount( nParamCount, 1, 2 ) ) + return; - // either CONV_A1_XL_A1 was explicitly configured, or it wasn't possible - // to determine which syntax to use during doc import - bool bTryXlA1 = (eConv == FormulaGrammar::CONV_A1_XL_A1); + // Reference address syntax for INDIRECT is configurable. + FormulaGrammar::AddressConvention eConv = maCalcConfig.meStringRefAddressSyntax; + if (eConv == FormulaGrammar::CONV_UNSPECIFIED) + // Use the current address syntax if unspecified. + eConv = pDok->GetAddressConvention(); - if (nParamCount == 2 && 0.0 == GetDouble() ) - { - // Overwrite the config and try Excel R1C1. - eConv = FormulaGrammar::CONV_XL_R1C1; - bTryXlA1 = false; - } + // either CONV_A1_XL_A1 was explicitly configured, or it wasn't possible + // to determine which syntax to use during doc import + bool bTryXlA1 = (eConv == FormulaGrammar::CONV_A1_XL_A1); + + if (nParamCount == 2 && 0.0 == GetDouble() ) + { + // Overwrite the config and try Excel R1C1. + eConv = FormulaGrammar::CONV_XL_R1C1; + bTryXlA1 = false; + } - const ScAddress::Details aDetails( bTryXlA1 ? FormulaGrammar::CONV_OOO : eConv, aPos ); - const ScAddress::Details aDetailsXlA1( FormulaGrammar::CONV_XL_A1, aPos ); - SCTAB nTab = aPos.Tab(); - OUString sRefStr = GetString().getString(); - ScRefAddress aRefAd, aRefAd2; - ScAddress::ExternalInfo aExtInfo; - if ( ConvertDoubleRef(pDok, sRefStr, nTab, aRefAd, aRefAd2, aDetails, &aExtInfo) || - ( bTryXlA1 && ConvertDoubleRef(pDok, sRefStr, nTab, aRefAd, - aRefAd2, aDetailsXlA1, &aExtInfo) ) ) + const ScAddress::Details aDetails( bTryXlA1 ? FormulaGrammar::CONV_OOO : eConv, aPos ); + const ScAddress::Details aDetailsXlA1( FormulaGrammar::CONV_XL_A1, aPos ); + SCTAB nTab = aPos.Tab(); + OUString sRefStr = GetString().getString(); + ScRefAddress aRefAd, aRefAd2; + ScAddress::ExternalInfo aExtInfo; + if ( ConvertDoubleRef(pDok, sRefStr, nTab, aRefAd, aRefAd2, aDetails, &aExtInfo) || + ( bTryXlA1 && ConvertDoubleRef(pDok, sRefStr, nTab, aRefAd, + aRefAd2, aDetailsXlA1, &aExtInfo) ) ) + { + if (aExtInfo.mbExternal) { - if (aExtInfo.mbExternal) - { - PushExternalDoubleRef( - aExtInfo.mnFileId, aExtInfo.maTabName, - aRefAd.Col(), aRefAd.Row(), aRefAd.Tab(), - aRefAd2.Col(), aRefAd2.Row(), aRefAd2.Tab()); - } - else - PushDoubleRef( aRefAd, aRefAd2); + PushExternalDoubleRef( + aExtInfo.mnFileId, aExtInfo.maTabName, + aRefAd.Col(), aRefAd.Row(), aRefAd.Tab(), + aRefAd2.Col(), aRefAd2.Row(), aRefAd2.Tab()); } - else if ( ConvertSingleRef(pDok, sRefStr, nTab, aRefAd, aDetails, &aExtInfo) || - ( bTryXlA1 && ConvertSingleRef (pDok, sRefStr, nTab, aRefAd, - aDetailsXlA1, &aExtInfo) ) ) + else + PushDoubleRef( aRefAd, aRefAd2); + } + else if ( ConvertSingleRef(pDok, sRefStr, nTab, aRefAd, aDetails, &aExtInfo) || + ( bTryXlA1 && ConvertSingleRef (pDok, sRefStr, nTab, aRefAd, + aDetailsXlA1, &aExtInfo) ) ) + { + if (aExtInfo.mbExternal) { - if (aExtInfo.mbExternal) - { - PushExternalSingleRef( - aExtInfo.mnFileId, aExtInfo.maTabName, aRefAd.Col(), aRefAd.Row(), aRefAd.Tab()); - } - else - PushSingleRef( aRefAd); + PushExternalSingleRef( + aExtInfo.mnFileId, aExtInfo.maTabName, aRefAd.Col(), aRefAd.Row(), aRefAd.Tab()); } else + PushSingleRef( aRefAd); + } + else + { + do { - do - { - ScRangeData* pData = ScRangeStringConverter::GetRangeDataFromString(sRefStr, nTab, pDok); - if (!pData) - break; + ScRangeData* pData = ScRangeStringConverter::GetRangeDataFromString(sRefStr, nTab, pDok); + if (!pData) + break; - // We need this in order to obtain a good range. - pData->ValidateTabRefs(); + // We need this in order to obtain a good range. + pData->ValidateTabRefs(); - ScRange aRange; + ScRange aRange; - // This is the usual way to treat named ranges containing - // relative references. - if (!pData->IsReference( aRange, aPos)) - break; + // This is the usual way to treat named ranges containing + // relative references. + if (!pData->IsReference( aRange, aPos)) + break; - if (aRange.aStart == aRange.aEnd) - PushSingleRef( aRange.aStart.Col(), aRange.aStart.Row(), - aRange.aStart.Tab()); - else - PushDoubleRef( aRange.aStart.Col(), aRange.aStart.Row(), - aRange.aStart.Tab(), aRange.aEnd.Col(), - aRange.aEnd.Row(), aRange.aEnd.Tab()); + if (aRange.aStart == aRange.aEnd) + PushSingleRef( aRange.aStart.Col(), aRange.aStart.Row(), + aRange.aStart.Tab()); + else + PushDoubleRef( aRange.aStart.Col(), aRange.aStart.Row(), + aRange.aStart.Tab(), aRange.aEnd.Col(), + aRange.aEnd.Row(), aRange.aEnd.Tab()); - // success! - return; - } - while (false); + // success! + return; + } + while (false); - do - { - OUString aName( ScGlobal::getCharClassPtr()->uppercase( sRefStr)); - ScDBCollection::NamedDBs& rDBs = pDok->GetDBCollection()->getNamedDBs(); - const ScDBData* pData = rDBs.findByUpperName( aName); - if (!pData) - break; + do + { + OUString aName( ScGlobal::getCharClassPtr()->uppercase( sRefStr)); + ScDBCollection::NamedDBs& rDBs = pDok->GetDBCollection()->getNamedDBs(); + const ScDBData* pData = rDBs.findByUpperName( aName); + if (!pData) + break; - ScRange aRange; - pData->GetArea( aRange); + ScRange aRange; + pData->GetArea( aRange); - // In Excel, specifying a table name without [] resolves to the - // same as with [], a range that excludes header and totals - // rows and contains only data rows. Do the same. - if (pData->HasHeader()) - aRange.aStart.IncRow(); - if (pData->HasTotals()) - aRange.aEnd.IncRow(-1); + // In Excel, specifying a table name without [] resolves to the + // same as with [], a range that excludes header and totals + // rows and contains only data rows. Do the same. + if (pData->HasHeader()) + aRange.aStart.IncRow(); + if (pData->HasTotals()) + aRange.aEnd.IncRow(-1); - if (aRange.aStart.Row() > aRange.aEnd.Row()) - break; + if (aRange.aStart.Row() > aRange.aEnd.Row()) + break; - if (aRange.aStart == aRange.aEnd) - PushSingleRef( aRange.aStart.Col(), aRange.aStart.Row(), - aRange.aStart.Tab()); - else - PushDoubleRef( aRange.aStart.Col(), aRange.aStart.Row(), - aRange.aStart.Tab(), aRange.aEnd.Col(), - aRange.aEnd.Row(), aRange.aEnd.Tab()); + if (aRange.aStart == aRange.aEnd) + PushSingleRef( aRange.aStart.Col(), aRange.aStart.Row(), + aRange.aStart.Tab()); + else + PushDoubleRef( aRange.aStart.Col(), aRange.aStart.Row(), + aRange.aStart.Tab(), aRange.aEnd.Col(), + aRange.aEnd.Row(), aRange.aEnd.Tab()); - // success! - return; - } - while (false); + // success! + return; + } + while (false); - // It may be even a TableRef. - // Anything else that resolves to one reference could be added - // here, but we don't want to compile every arbitrary string. This - // is already nasty enough... - sal_Int32 nIndex = sRefStr.indexOf('['); - if (nIndex >= 0 && sRefStr.indexOf(']',nIndex+1) > nIndex) + // It may be even a TableRef. + // Anything else that resolves to one reference could be added + // here, but we don't want to compile every arbitrary string. This + // is already nasty enough... + sal_Int32 nIndex = sRefStr.indexOf('['); + if (nIndex >= 0 && sRefStr.indexOf(']',nIndex+1) > nIndex) + { + do { - do - { - ScCompiler aComp( pDok, aPos, pDok->GetGrammar()); - aComp.SetRefConvention( eConv); // must be after grammar - std::unique_ptr<ScTokenArray> pTokArr( aComp.CompileString( sRefStr)); + ScCompiler aComp( pDok, aPos, pDok->GetGrammar()); + aComp.SetRefConvention( eConv); // must be after grammar + std::unique_ptr<ScTokenArray> pTokArr( aComp.CompileString( sRefStr)); - // Whatever... use only the specific case. - if (!pTokArr->HasOpCode( ocTableRef)) - break; + // Whatever... use only the specific case. + if (!pTokArr->HasOpCode( ocTableRef)) + break; - aComp.CompileTokenArray(); + aComp.CompileTokenArray(); - // A syntactically valid reference will generate exactly - // one RPN token, a reference or error. Discard everything - // else as error. - if (pTokArr->GetCodeLen() != 1) - break; + // A syntactically valid reference will generate exactly + // one RPN token, a reference or error. Discard everything + // else as error. + if (pTokArr->GetCodeLen() != 1) + break; - ScTokenRef xTok( pTokArr->FirstRPNToken()); - if (!xTok) - break; + ScTokenRef xTok( pTokArr->FirstRPNToken()); + if (!xTok) + break; - switch (xTok->GetType()) - { - case svSingleRef: - case svDoubleRef: - case svError: - PushTokenRef( xTok); - // success! - return; - default: - ; // nothing - } + switch (xTok->GetType()) + { + case svSingleRef: + case svDoubleRef: + case svError: + PushTokenRef( xTok); + // success! + return; + default: + ; // nothing } - while (false); } - - PushError( FormulaError::NoRef); + while (false); } + + PushError( FormulaError::NoRef); } } @@ -8317,367 +8317,367 @@ void ScInterpreter::ScAddressFunc() void ScInterpreter::ScOffset() { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 3, 5 ) ) + if ( !MustHaveParamCount( nParamCount, 3, 5 ) ) + return; + + bool bNewWidth = false; + bool bNewHeight = false; + sal_Int32 nColNew = 1, nRowNew = 1; + if (nParamCount == 5) { - bool bNewWidth = false; - bool bNewHeight = false; - sal_Int32 nColNew = 1, nRowNew = 1; - if (nParamCount == 5) - { - if (IsMissing()) - PopError(); - else - { - nColNew = GetInt32(); - bNewWidth = true; - } - } - if (nParamCount >= 4) - { - if (IsMissing()) - PopError(); - else - { - nRowNew = GetInt32(); - bNewHeight = true; - } - } - sal_Int32 nColPlus = GetInt32(); - sal_Int32 nRowPlus = GetInt32(); - if (nGlobalError != FormulaError::NONE) + if (IsMissing()) + PopError(); + else { - PushError( nGlobalError); - return; + nColNew = GetInt32(); + bNewWidth = true; } - if (nColNew <= 0 || nRowNew <= 0) + } + if (nParamCount >= 4) + { + if (IsMissing()) + PopError(); + else { - PushIllegalArgument(); - return; + nRowNew = GetInt32(); + bNewHeight = true; } - SCCOL nCol1(0); - SCROW nRow1(0); - SCTAB nTab1(0); - SCCOL nCol2(0); - SCROW nRow2(0); - SCTAB nTab2(0); - switch (GetStackType()) - { - case svSingleRef: - { - PopSingleRef(nCol1, nRow1, nTab1); - if (!bNewWidth && !bNewHeight) - { - nCol1 = static_cast<SCCOL>(static_cast<long>(nCol1) + nColPlus); - nRow1 = static_cast<SCROW>(static_cast<long>(nRow1) + nRowPlus); - if (!pDok->ValidCol(nCol1) || !pDok->ValidRow(nRow1)) - PushIllegalArgument(); - else - PushSingleRef(nCol1, nRow1, nTab1); - } - else - { - nCol1 = static_cast<SCCOL>(static_cast<long>(nCol1)+nColPlus); - nRow1 = static_cast<SCROW>(static_cast<long>(nRow1)+nRowPlus); - nCol2 = static_cast<SCCOL>(static_cast<long>(nCol1)+nColNew-1); - nRow2 = static_cast<SCROW>(static_cast<long>(nRow1)+nRowNew-1); - if (!pDok->ValidCol(nCol1) || !pDok->ValidRow(nRow1) || - !pDok->ValidCol(nCol2) || !pDok->ValidRow(nRow2)) - PushIllegalArgument(); - else - PushDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab1); - } - break; - } - case svExternalSingleRef: + } + sal_Int32 nColPlus = GetInt32(); + sal_Int32 nRowPlus = GetInt32(); + if (nGlobalError != FormulaError::NONE) + { + PushError( nGlobalError); + return; + } + if (nColNew <= 0 || nRowNew <= 0) + { + PushIllegalArgument(); + return; + } + SCCOL nCol1(0); + SCROW nRow1(0); + SCTAB nTab1(0); + SCCOL nCol2(0); + SCROW nRow2(0); + SCTAB nTab2(0); + switch (GetStackType()) + { + case svSingleRef: + { + PopSingleRef(nCol1, nRow1, nTab1); + if (!bNewWidth && !bNewHeight) { - sal_uInt16 nFileId; - OUString aTabName; - ScSingleRefData aRef; - PopExternalSingleRef(nFileId, aTabName, aRef); - ScAddress aAbsRef = aRef.toAbs(pDok, aPos); - nCol1 = aAbsRef.Col(); - nRow1 = aAbsRef.Row(); - nTab1 = aAbsRef.Tab(); - - if (!bNewWidth && !bNewHeight) - { - nCol1 = static_cast<SCCOL>(static_cast<long>(nCol1) + nColPlus); - nRow1 = static_cast<SCROW>(static_cast<long>(nRow1) + nRowPlus); - if (!pDok->ValidCol(nCol1) || !pDok->ValidRow(nRow1)) - PushIllegalArgument(); - else - PushExternalSingleRef(nFileId, aTabName, nCol1, nRow1, nTab1); - } + nCol1 = static_cast<SCCOL>(static_cast<long>(nCol1) + nColPlus); + nRow1 = static_cast<SCROW>(static_cast<long>(nRow1) + nRowPlus); + if (!pDok->ValidCol(nCol1) || !pDok->ValidRow(nRow1)) + PushIllegalArgument(); else - { - nCol1 = static_cast<SCCOL>(static_cast<long>(nCol1)+nColPlus); - nRow1 = static_cast<SCROW>(static_cast<long>(nRow1)+nRowPlus); - nCol2 = static_cast<SCCOL>(static_cast<long>(nCol1)+nColNew-1); - nRow2 = static_cast<SCROW>(static_cast<long>(nRow1)+nRowNew-1); - nTab2 = nTab1; - if (!pDok->ValidCol(nCol1) || !pDok->ValidRow(nRow1) || - !pDok->ValidCol(nCol2) || !pDok->ValidRow(nRow2)) - PushIllegalArgument(); - else - PushExternalDoubleRef(nFileId, aTabName, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); - } - break; + PushSingleRef(nCol1, nRow1, nTab1); } - case svDoubleRef: + else { - PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); - if (!bNewWidth) - nColNew = nCol2 - nCol1 + 1; - if (!bNewHeight) - nRowNew = nRow2 - nRow1 + 1; nCol1 = static_cast<SCCOL>(static_cast<long>(nCol1)+nColPlus); nRow1 = static_cast<SCROW>(static_cast<long>(nRow1)+nRowPlus); nCol2 = static_cast<SCCOL>(static_cast<long>(nCol1)+nColNew-1); nRow2 = static_cast<SCROW>(static_cast<long>(nRow1)+nRowNew-1); if (!pDok->ValidCol(nCol1) || !pDok->ValidRow(nRow1) || - !pDok->ValidCol(nCol2) || !pDok->ValidRow(nRow2) || nTab1 != nTab2) + !pDok->ValidCol(nCol2) || !pDok->ValidRow(nRow2)) PushIllegalArgument(); else PushDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab1); - break; } - case svExternalDoubleRef: + break; + } + case svExternalSingleRef: + { + sal_uInt16 nFileId; + OUString aTabName; + ScSingleRefData aRef; + PopExternalSingleRef(nFileId, aTabName, aRef); + ScAddress aAbsRef = aRef.toAbs(pDok, aPos); + nCol1 = aAbsRef.Col(); + nRow1 = aAbsRef.Row(); + nTab1 = aAbsRef.Tab(); + + if (!bNewWidth && !bNewHeight) + { + nCol1 = static_cast<SCCOL>(static_cast<long>(nCol1) + nColPlus); + nRow1 = static_cast<SCROW>(static_cast<long>(nRow1) + nRowPlus); + if (!pDok->ValidCol(nCol1) || !pDok->ValidRow(nRow1)) + PushIllegalArgument(); + else + PushExternalSingleRef(nFileId, aTabName, nCol1, nRow1, nTab1); + } + else { - sal_uInt16 nFileId; - OUString aTabName; - ScComplexRefData aRef; - PopExternalDoubleRef(nFileId, aTabName, aRef); - ScRange aAbs = aRef.toAbs(pDok, aPos); - nCol1 = aAbs.aStart.Col(); - nRow1 = aAbs.aStart.Row(); - nTab1 = aAbs.aStart.Tab(); - nCol2 = aAbs.aEnd.Col(); - nRow2 = aAbs.aEnd.Row(); - nTab2 = aAbs.aEnd.Tab(); - if (!bNewWidth) - nColNew = nCol2 - nCol1 + 1; - if (!bNewHeight) - nRowNew = nRow2 - nRow1 + 1; nCol1 = static_cast<SCCOL>(static_cast<long>(nCol1)+nColPlus); nRow1 = static_cast<SCROW>(static_cast<long>(nRow1)+nRowPlus); nCol2 = static_cast<SCCOL>(static_cast<long>(nCol1)+nColNew-1); nRow2 = static_cast<SCROW>(static_cast<long>(nRow1)+nRowNew-1); + nTab2 = nTab1; if (!pDok->ValidCol(nCol1) || !pDok->ValidRow(nRow1) || - !pDok->ValidCol(nCol2) || !pDok->ValidRow(nRow2) || nTab1 != nTab2) + !pDok->ValidCol(nCol2) || !pDok->ValidRow(nRow2)) PushIllegalArgument(); else PushExternalDoubleRef(nFileId, aTabName, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); - break; } - default: - PushIllegalParameter(); - break; - } // end switch + break; + } + case svDoubleRef: + { + PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); + if (!bNewWidth) + nColNew = nCol2 - nCol1 + 1; + if (!bNewHeight) + nRowNew = nRow2 - nRow1 + 1; + nCol1 = static_cast<SCCOL>(static_cast<long>(nCol1)+nColPlus); + nRow1 = static_cast<SCROW>(static_cast<long>(nRow1)+nRowPlus); + nCol2 = static_cast<SCCOL>(static_cast<long>(nCol1)+nColNew-1); + nRow2 = static_cast<SCROW>(static_cast<long>(nRow1)+nRowNew-1); + if (!pDok->ValidCol(nCol1) || !pDok->ValidRow(nRow1) || + !pDok->ValidCol(nCol2) || !pDok->ValidRow(nRow2) || nTab1 != nTab2) + PushIllegalArgument(); + else + PushDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab1); + break; } + case svExternalDoubleRef: + { + sal_uInt16 nFileId; + OUString aTabName; + ScComplexRefData aRef; + PopExternalDoubleRef(nFileId, aTabName, aRef); + ScRange aAbs = aRef.toAbs(pDok, aPos); + nCol1 = aAbs.aStart.Col(); + nRow1 = aAbs.aStart.Row(); + nTab1 = aAbs.aStart.Tab(); + nCol2 = aAbs.aEnd.Col(); + nRow2 = aAbs.aEnd.Row(); + nTab2 = aAbs.aEnd.Tab(); + if (!bNewWidth) + nColNew = nCol2 - nCol1 + 1; + if (!bNewHeight) + nRowNew = nRow2 - nRow1 + 1; + nCol1 = static_cast<SCCOL>(static_cast<long>(nCol1)+nColPlus); + nRow1 = static_cast<SCROW>(static_cast<long>(nRow1)+nRowPlus); + nCol2 = static_cast<SCCOL>(static_cast<long>(nCol1)+nColNew-1); + nRow2 = static_cast<SCROW>(static_cast<long>(nRow1)+nRowNew-1); + if (!pDok->ValidCol(nCol1) || !pDok->ValidRow(nRow1) || + !pDok->ValidCol(nCol2) || !pDok->ValidRow(nRow2) || nTab1 != nTab2) + PushIllegalArgument(); + else + PushExternalDoubleRef(nFileId, aTabName, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); + break; + } + default: + PushIllegalParameter(); + break; + } // end switch } void ScInterpreter::ScIndex() { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 1, 4 ) ) + if ( !MustHaveParamCount( nParamCount, 1, 4 ) ) + return; + + sal_uInt32 nArea; + size_t nAreaCount; + SCCOL nCol; + SCROW nRow; + if (nParamCount == 4) + nArea = GetUInt32(); + else + nArea = 1; + if (nParamCount >= 3) + nCol = static_cast<SCCOL>(GetInt16()); + else + nCol = 0; + if (nParamCount >= 2) + nRow = static_cast<SCROW>(GetInt32()); + else + nRow = 0; + if (GetStackType() == svRefList) + nAreaCount = (sp ? pStack[sp-1]->GetRefList()->size() : 0); + else + nAreaCount = 1; // one reference or array or whatever + if (nGlobalError != FormulaError::NONE || nAreaCount == 0 || static_cast<size_t>(nArea) > nAreaCount) { - sal_uInt32 nArea; - size_t nAreaCount; - SCCOL nCol; - SCROW nRow; - if (nParamCount == 4) - nArea = GetUInt32(); - else - nArea = 1; - if (nParamCount >= 3) - nCol = static_cast<SCCOL>(GetInt16()); - else - nCol = 0; - if (nParamCount >= 2) - nRow = static_cast<SCROW>(GetInt32()); - else - nRow = 0; - if (GetStackType() == svRefList) - nAreaCount = (sp ? pStack[sp-1]->GetRefList()->size() : 0); - else - nAreaCount = 1; // one reference or array or whatever - if (nGlobalError != FormulaError::NONE || nAreaCount == 0 || static_cast<size_t>(nArea) > nAreaCount) - { - PushError( FormulaError::NoRef); - return; - } - else if (nArea < 1 || nCol < 0 || nRow < 0) - { - PushIllegalArgument(); - return; - } - switch (GetStackType()) - { - case svMatrix: - case svExternalSingleRef: - case svExternalDoubleRef: + PushError( FormulaError::NoRef); + return; + } + else if (nArea < 1 || nCol < 0 || nRow < 0) + { + PushIllegalArgument(); + return; + } + switch (GetStackType()) + { + case svMatrix: + case svExternalSingleRef: + case svExternalDoubleRef: + { + if (nArea != 1) + SetError(FormulaError::IllegalArgument); + sal_uInt16 nOldSp = sp; + ScMatrixRef pMat = GetMatrix(); + if (pMat) { - if (nArea != 1) - SetError(FormulaError::IllegalArgument); - sal_uInt16 nOldSp = sp; - ScMatrixRef pMat = GetMatrix(); - if (pMat) + SCSIZE nC, nR; + pMat->GetDimensions(nC, nR); + // Access one element of a vector independent of col/row + // orientation? + bool bVector = ((nCol == 0 || nRow == 0) && (nC == 1 || nR == 1)); + SCSIZE nElement = ::std::max( static_cast<SCSIZE>(nCol), + static_cast<SCSIZE>(nRow)); + if (nC == 0 || nR == 0 || + (!bVector && (o3tl::make_unsigned(nCol) > nC || + o3tl::make_unsigned(nRow) > nR)) || + (bVector && nElement > nC * nR)) + PushIllegalArgument(); + else if (nCol == 0 && nRow == 0) + sp = nOldSp; + else if (bVector) { - SCSIZE nC, nR; - pMat->GetDimensions(nC, nR); - // Access one element of a vector independent of col/row - // orientation? - bool bVector = ((nCol == 0 || nRow == 0) && (nC == 1 || nR == 1)); - SCSIZE nElement = ::std::max( static_cast<SCSIZE>(nCol), - static_cast<SCSIZE>(nRow)); - if (nC == 0 || nR == 0 || - (!bVector && (o3tl::make_unsigned(nCol) > nC || - o3tl::make_unsigned(nRow) > nR)) || - (bVector && nElement > nC * nR)) - PushIllegalArgument(); - else if (nCol == 0 && nRow == 0) - sp = nOldSp; - else if (bVector) - { - --nElement; - if (pMat->IsStringOrEmpty( nElement)) - PushString( pMat->GetString(nElement).getString()); - else - PushDouble( pMat->GetDouble( nElement)); - } - else if (nCol == 0) + --nElement; + if (pMat->IsStringOrEmpty( nElement)) + PushString( pMat->GetString(nElement).getString()); + else + PushDouble( pMat->GetDouble( nElement)); + } + else if (nCol == 0) + { + ScMatrixRef pResMat = GetNewMat(nC, 1); + if (pResMat) { - ScMatrixRef pResMat = GetNewMat(nC, 1); - if (pResMat) - { - SCSIZE nRowMinus1 = static_cast<SCSIZE>(nRow - 1); - for (SCSIZE i = 0; i < nC; i++) - if (!pMat->IsStringOrEmpty(i, nRowMinus1)) - pResMat->PutDouble(pMat->GetDouble(i, - nRowMinus1), i, 0); - else - pResMat->PutString(pMat->GetString(i, nRowMinus1), i, 0); + SCSIZE nRowMinus1 = static_cast<SCSIZE>(nRow - 1); + for (SCSIZE i = 0; i < nC; i++) + if (!pMat->IsStringOrEmpty(i, nRowMinus1)) + pResMat->PutDouble(pMat->GetDouble(i, + nRowMinus1), i, 0); + else + pResMat->PutString(pMat->GetString(i, nRowMinus1), i, 0); - PushMatrix(pResMat); - } - else - PushIllegalArgument(); - } - else if (nRow == 0) - { - ScMatrixRef pResMat = GetNewMat(1, nR); - if (pResMat) - { - SCSIZE nColMinus1 = static_cast<SCSIZE>(nCol - 1); - for (SCSIZE i = 0; i < nR; i++) - if (!pMat->IsStringOrEmpty(nColMinus1, i)) - pResMat->PutDouble(pMat->GetDouble(nColMinus1, - i), i); - else - pResMat->PutString(pMat->GetString(nColMinus1, i), i); - PushMatrix(pResMat); - } - else - PushIllegalArgument(); + PushMatrix(pResMat); } else - { - if (!pMat->IsStringOrEmpty( static_cast<SCSIZE>(nCol-1), - static_cast<SCSIZE>(nRow-1))) - PushDouble( pMat->GetDouble( - static_cast<SCSIZE>(nCol-1), - static_cast<SCSIZE>(nRow-1))); - else - PushString( pMat->GetString( - static_cast<SCSIZE>(nCol-1), - static_cast<SCSIZE>(nRow-1)).getString()); - } + PushIllegalArgument(); } - } - break; - case svSingleRef: - { - SCCOL nCol1 = 0; - SCROW nRow1 = 0; - SCTAB nTab1 = 0; - PopSingleRef( nCol1, nRow1, nTab1); - if (nCol > 1 || nRow > 1) - PushIllegalArgument(); - else - PushSingleRef( nCol1, nRow1, nTab1); - } - break; - case svDoubleRef: - case svRefList: - { - SCCOL nCol1 = 0; - SCROW nRow1 = 0; - SCTAB nTab1 = 0; - SCCOL nCol2 = 0; - SCROW nRow2 = 0; - SCTAB nTab2 = 0; - bool bRowArray = false; - if (GetStackType() == svRefList) + else if (nRow == 0) { - FormulaConstTokenRef xRef = PopToken(); - if (nGlobalError != FormulaError::NONE || !xRef) + ScMatrixRef pResMat = GetNewMat(1, nR); + if (pResMat) { - PushIllegalParameter(); - return; + SCSIZE nColMinus1 = static_cast<SCSIZE>(nCol - 1); + for (SCSIZE i = 0; i < nR; i++) + if (!pMat->IsStringOrEmpty(nColMinus1, i)) + pResMat->PutDouble(pMat->GetDouble(nColMinus1, + i), i); + else + pResMat->PutString(pMat->GetString(nColMinus1, i), i); + PushMatrix(pResMat); } - ScRange aRange( ScAddress::UNINITIALIZED); - DoubleRefToRange( (*(xRef->GetRefList()))[nArea-1], aRange); - aRange.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); - if ( nParamCount == 2 && nRow1 == nRow2 ) - bRowArray = true; + else + PushIllegalArgument(); } else { - PopDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); - if ( nParamCount == 2 && nRow1 == nRow2 ) - bRowArray = true; - } - if ( nTab1 != nTab2 || - (nCol > 0 && nCol1+nCol-1 > nCol2) || - (nRow > 0 && nRow1+nRow-1 > nRow2 && !bRowArray ) || - ( nRow > nCol2 - nCol1 + 1 && bRowArray )) - PushIllegalArgument(); - else if (nCol == 0 && nRow == 0) - { - if ( nCol1 == nCol2 && nRow1 == nRow2 ) - PushSingleRef( nCol1, nRow1, nTab1 ); + if (!pMat->IsStringOrEmpty( static_cast<SCSIZE>(nCol-1), + static_cast<SCSIZE>(nRow-1))) + PushDouble( pMat->GetDouble( + static_cast<SCSIZE>(nCol-1), + static_cast<SCSIZE>(nRow-1))); else - PushDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab1 ); + PushString( pMat->GetString( + static_cast<SCSIZE>(nCol-1), + static_cast<SCSIZE>(nRow-1)).getString()); } - else if (nRow == 0) + } + } + break; + case svSingleRef: + { + SCCOL nCol1 = 0; + SCROW nRow1 = 0; + SCTAB nTab1 = 0; + PopSingleRef( nCol1, nRow1, nTab1); + if (nCol > 1 || nRow > 1) + PushIllegalArgument(); + else + PushSingleRef( nCol1, nRow1, nTab1); + } + break; + case svDoubleRef: + case svRefList: + { + SCCOL nCol1 = 0; + SCROW nRow1 = 0; + SCTAB nTab1 = 0; + SCCOL nCol2 = 0; + SCROW nRow2 = 0; + SCTAB nTab2 = 0; + bool bRowArray = false; + if (GetStackType() == svRefList) + { + FormulaConstTokenRef xRef = PopToken(); + if (nGlobalError != FormulaError::NONE || !xRef) { - if ( nRow1 == nRow2 ) - PushSingleRef( nCol1+nCol-1, nRow1, nTab1 ); - else - PushDoubleRef( nCol1+nCol-1, nRow1, nTab1, - nCol1+nCol-1, nRow2, nTab1 ); + PushIllegalParameter(); + return; } - else if (nCol == 0) + ScRange aRange( ScAddress::UNINITIALIZED); + DoubleRefToRange( (*(xRef->GetRefList()))[nArea-1], aRange); + aRange.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); + if ( nParamCount == 2 && nRow1 == nRow2 ) + bRowArray = true; + } + else + { + PopDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); + if ( nParamCount == 2 && nRow1 == nRow2 ) + bRowArray = true; + } + if ( nTab1 != nTab2 || + (nCol > 0 && nCol1+nCol-1 > nCol2) || + (nRow > 0 && nRow1+nRow-1 > nRow2 && !bRowArray ) || + ( nRow > nCol2 - nCol1 + 1 && bRowArray )) + PushIllegalArgument(); + else if (nCol == 0 && nRow == 0) + { + if ( nCol1 == nCol2 && nRow1 == nRow2 ) + PushSingleRef( nCol1, nRow1, nTab1 ); + else + PushDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab1 ); + } + else if (nRow == 0) + { + if ( nRow1 == nRow2 ) + PushSingleRef( nCol1+nCol-1, nRow1, nTab1 ); + else + PushDoubleRef( nCol1+nCol-1, nRow1, nTab1, + nCol1+nCol-1, nRow2, nTab1 ); + } + else if (nCol == 0) + { + if ( nCol1 == nCol2 ) + PushSingleRef( nCol1, nRow1+nRow-1, nTab1 ); + else if ( bRowArray ) { - if ( nCol1 == nCol2 ) - PushSingleRef( nCol1, nRow1+nRow-1, nTab1 ); - else if ( bRowArray ) - { - nCol =static_cast<SCCOL>(nRow); - nRow = 1; - PushSingleRef( nCol1+nCol-1, nRow1+nRow-1, nTab1); - } - else - PushDoubleRef( nCol1, nRow1+nRow-1, nTab1, - nCol2, nRow1+nRow-1, nTab1); + nCol =static_cast<SCCOL>(nRow); + nRow = 1; + PushSingleRef( nCol1+nCol-1, nRow1+nRow-1, nTab1); } else - PushSingleRef( nCol1+nCol-1, nRow1+nRow-1, nTab1); + PushDoubleRef( nCol1, nRow1+nRow-1, nTab1, + nCol2, nRow1+nRow-1, nTab1); } - break; - default: - PushIllegalParameter(); - } + else + PushSingleRef( nCol1+nCol-1, nRow1+nRow-1, nTab1); + } + break; + default: + PushIllegalParameter(); } } @@ -8697,219 +8697,219 @@ void ScInterpreter::ScMultiArea() void ScInterpreter::ScAreas() { sal_uInt8 nParamCount = GetByte(); - if (MustHaveParamCount( nParamCount, 1)) + if (!MustHaveParamCount( nParamCount, 1)) + return; + + size_t nCount = 0; + switch (GetStackType()) { - size_t nCount = 0; - switch (GetStackType()) - { - case svSingleRef: - { - FormulaConstTokenRef xT = PopToken(); - ValidateRef( *xT->GetSingleRef()); - ++nCount; - } - break; - case svDoubleRef: - { - FormulaConstTokenRef xT = PopToken(); - ValidateRef( *xT->GetDoubleRef()); - ++nCount; - } - break; - case svRefList: - { - FormulaConstTokenRef xT = PopToken(); - ValidateRef( *(xT->GetRefList())); - nCount += xT->GetRefList()->size(); - } - break; - default: - SetError( FormulaError::IllegalParameter); - } - PushDouble( double(nCount)); + case svSingleRef: + { + FormulaConstTokenRef xT = PopToken(); + ValidateRef( *xT->GetSingleRef()); + ++nCount; + } + break; + case svDoubleRef: + { + FormulaConstTokenRef xT = PopToken(); + ValidateRef( *xT->GetDoubleRef()); + ++nCount; + } + break; + case svRefList: + { + FormulaConstTokenRef xT = PopToken(); + ValidateRef( *(xT->GetRefList())); + nCount += xT->GetRefList()->size(); + } + break; + default: + SetError( FormulaError::IllegalParameter); } + PushDouble( double(nCount)); } void ScInterpreter::ScCurrency() { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 1, 2 ) ) + if ( !MustHaveParamCount( nParamCount, 1, 2 ) ) + return; + + OUString aStr; + double fDec; + if (nParamCount == 2) { - OUString aStr; - double fDec; - if (nParamCount == 2) + fDec = ::rtl::math::approxFloor(GetDouble()); + if (fDec < -15.0 || fDec > 15.0) { - fDec = ::rtl::math::approxFloor(GetDouble()); - if (fDec < -15.0 || fDec > 15.0) - { - PushIllegalArgument(); - return; - } - } - else - fDec = 2.0; - double fVal = GetDouble(); - double fFac; - if ( fDec != 0.0 ) - fFac = pow( double(10), fDec ); - else - fFac = 1.0; - if (fVal < 0.0) - fVal = ceil(fVal*fFac-0.5)/fFac; - else - fVal = floor(fVal*fFac+0.5)/fFac; - Color* pColor = nullptr; - if ( fDec < 0.0 ) - fDec = 0.0; - sal_uLong nIndex = pFormatter->GetStandardFormat( - SvNumFormatType::CURRENCY, - ScGlobal::eLnge); - if ( static_cast<sal_uInt16>(fDec) != pFormatter->GetFormatPrecision( nIndex ) ) - { - OUString sFormatString = pFormatter->GenerateFormat( - nIndex, - ScGlobal::eLnge, - true, // with thousands separator - false, // not red - static_cast<sal_uInt16>(fDec));// decimal places - if (!pFormatter->GetPreviewString(sFormatString, - fVal, - aStr, - &pColor, - ScGlobal::eLnge)) - SetError(FormulaError::IllegalArgument); - } - else - { - pFormatter->GetOutputString(fVal, nIndex, aStr, &pColor); + PushIllegalArgument(); + return; } - PushString(aStr); } + else + fDec = 2.0; + double fVal = GetDouble(); + double fFac; + if ( fDec != 0.0 ) + fFac = pow( double(10), fDec ); + else + fFac = 1.0; + if (fVal < 0.0) + fVal = ceil(fVal*fFac-0.5)/fFac; + else + fVal = floor(fVal*fFac+0.5)/fFac; + Color* pColor = nullptr; + if ( fDec < 0.0 ) + fDec = 0.0; + sal_uLong nIndex = pFormatter->GetStandardFormat( + SvNumFormatType::CURRENCY, + ScGlobal::eLnge); + if ( static_cast<sal_uInt16>(fDec) != pFormatter->GetFormatPrecision( nIndex ) ) + { + OUString sFormatString = pFormatter->GenerateFormat( + nIndex, + ScGlobal::eLnge, + true, // with thousands separator + false, // not red + static_cast<sal_uInt16>(fDec));// decimal places + if (!pFormatter->GetPreviewString(sFormatString, + fVal, + aStr, + &pColor, + ScGlobal::eLnge)) + SetError(FormulaError::IllegalArgument); + } + else + { + pFormatter->GetOutputString(fVal, nIndex, aStr, &pColor); + } + PushString(aStr); } void ScInterpreter::ScReplace() { - if ( MustHaveParamCount( GetByte(), 4 ) ) + if ( !MustHaveParamCount( GetByte(), 4 ) ) + return; + + OUString aNewStr = GetString().getString(); + sal_Int32 nCount = GetStringPositionArgument(); + sal_Int32 nPos = GetStringPositionArgument(); + OUString aOldStr = GetString().getString(); + if (nPos < 1 || nCount < 0) + PushIllegalArgument(); + else { - OUString aNewStr = GetString().getString(); - sal_Int32 nCount = GetStringPositionArgument(); - sal_Int32 nPos = GetStringPositionArgument(); - OUString aOldStr = GetString().getString(); - if (nPos < 1 || nCount < 0) - PushIllegalArgument(); - else + sal_Int32 nLen = aOldStr.getLength(); + if (nPos > nLen + 1) + nPos = nLen + 1; + if (nCount > nLen - nPos + 1) + nCount = nLen - nPos + 1; + sal_Int32 nIdx = 0; + sal_Int32 nCnt = 0; + while ( nIdx < nLen && nPos > nCnt + 1 ) { - sal_Int32 nLen = aOldStr.getLength(); - if (nPos > nLen + 1) - nPos = nLen + 1; - if (nCount > nLen - nPos + 1) - nCount = nLen - nPos + 1; - sal_Int32 nIdx = 0; - sal_Int32 nCnt = 0; - while ( nIdx < nLen && nPos > nCnt + 1 ) - { - aOldStr.iterateCodePoints( &nIdx ); - ++nCnt; - } - sal_Int32 nStart = nIdx; - while ( nIdx < nLen && nPos + nCount - 1 > nCnt ) - { - aOldStr.iterateCodePoints( &nIdx ); - ++nCnt; - } - aOldStr = aOldStr.replaceAt( nStart, nIdx - nStart, "" ); - if ( CheckStringResultLen( aOldStr, aNewStr ) ) - aOldStr = aOldStr.replaceAt( nStart, 0, aNewStr ); - PushString( aOldStr ); + aOldStr.iterateCodePoints( &nIdx ); + ++nCnt; } + sal_Int32 nStart = nIdx; + while ( nIdx < nLen && nPos + nCount - 1 > nCnt ) + { + aOldStr.iterateCodePoints( &nIdx ); + ++nCnt; + } + aOldStr = aOldStr.replaceAt( nStart, nIdx - nStart, "" ); + if ( CheckStringResultLen( aOldStr, aNewStr ) ) + aOldStr = aOldStr.replaceAt( nStart, 0, aNewStr ); + PushString( aOldStr ); } } void ScInterpreter::ScFixed() { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 1, 3 ) ) + if ( !MustHaveParamCount( nParamCount, 1, 3 ) ) + return; + + OUString aStr; + double fDec; + bool bThousand; + if (nParamCount == 3) + bThousand = !GetBool(); // Param true: no thousands separator + else + bThousand = true; + if (nParamCount >= 2) { - OUString aStr; - double fDec; - bool bThousand; - if (nParamCount == 3) - bThousand = !GetBool(); // Param true: no thousands separator - else - bThousand = true; - if (nParamCount >= 2) + fDec = ::rtl::math::approxFloor(GetDoubleWithDefault( 2.0 )); + if (fDec < -15.0 || fDec > 15.0) { - fDec = ::rtl::math::approxFloor(GetDoubleWithDefault( 2.0 )); - if (fDec < -15.0 || fDec > 15.0) - { - PushIllegalArgument(); - return; - } - } - else - fDec = 2.0; - double fVal = GetDouble(); - double fFac; - if ( fDec != 0.0 ) - fFac = pow( double(10), fDec ); - else - fFac = 1.0; - if (fVal < 0.0) - fVal = ceil(fVal*fFac-0.5)/fFac; - else - fVal = floor(fVal*fFac+0.5)/fFac; - Color* pColor = nullptr; - if (fDec < 0.0) - fDec = 0.0; - sal_uLong nIndex = pFormatter->GetStandardFormat( - SvNumFormatType::NUMBER, - ScGlobal::eLnge); - OUString sFormatString = pFormatter->GenerateFormat( - nIndex, - ScGlobal::eLnge, - bThousand, // with thousands separator - false, // not red - static_cast<sal_uInt16>(fDec));// decimal places - if (!pFormatter->GetPreviewString(sFormatString, - fVal, - aStr, - &pColor, - ScGlobal::eLnge)) PushIllegalArgument(); - else - PushString(aStr); + return; + } } + else + fDec = 2.0; + double fVal = GetDouble(); + double fFac; + if ( fDec != 0.0 ) + fFac = pow( double(10), fDec ); + else + fFac = 1.0; + if (fVal < 0.0) + fVal = ceil(fVal*fFac-0.5)/fFac; + else + fVal = floor(fVal*fFac+0.5)/fFac; + Color* pColor = nullptr; + if (fDec < 0.0) + fDec = 0.0; + sal_uLong nIndex = pFormatter->GetStandardFormat( + SvNumFormatType::NUMBER, + ScGlobal::eLnge); + OUString sFormatString = pFormatter->GenerateFormat( + nIndex, + ScGlobal::eLnge, + bThousand, // with thousands separator + false, // not red + static_cast<sal_uInt16>(fDec));// decimal places + if (!pFormatter->GetPreviewString(sFormatString, + fVal, + aStr, + &pColor, + ScGlobal::eLnge)) + PushIllegalArgument(); + else + PushString(aStr); } void ScInterpreter::ScFind() { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 2, 3 ) ) + if ( !MustHaveParamCount( nParamCount, 2, 3 ) ) + return; + + sal_Int32 nCnt; + if (nParamCount == 3) + nCnt = GetDouble(); + else + nCnt = 1; + OUString sStr = GetString().getString(); + if (nCnt < 1 || nCnt > sStr.getLength()) + PushNoValue(); + else { - sal_Int32 nCnt; - if (nParamCount == 3) - nCnt = GetDouble(); - else - nCnt = 1; - OUString sStr = GetString().getString(); - if (nCnt < 1 || nCnt > sStr.getLength()) + sal_Int32 nPos = sStr.indexOf(GetString().getString(), nCnt - 1); + if (nPos == -1) PushNoValue(); else { - sal_Int32 nPos = sStr.indexOf(GetString().getString(), nCnt - 1); - if (nPos == -1) - PushNoValue(); - else + sal_Int32 nIdx = 0; + nCnt = 0; + while ( nIdx <= nPos ) { - sal_Int32 nIdx = 0; - nCnt = 0; - while ( nIdx <= nPos ) - { - sStr.iterateCodePoints( &nIdx ); - ++nCnt; - } - PushDouble( static_cast<double>(nCnt) ); + sStr.iterateCodePoints( &nIdx ); + ++nCnt; } + PushDouble( static_cast<double>(nCnt) ); } } } @@ -8928,28 +8928,28 @@ void ScInterpreter::ScExact() void ScInterpreter::ScLeft() { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 1, 2 ) ) + if ( !MustHaveParamCount( nParamCount, 1, 2 ) ) + return; + + sal_Int32 n; + if (nParamCount == 2) { - sal_Int32 n; - if (nParamCount == 2) + n = GetStringPositionArgument(); + if (n < 0) { - n = GetStringPositionArgument(); - if (n < 0) - { - PushIllegalArgument(); - return ; - } + PushIllegalArgument(); + return ; } - else - n = 1; - OUString aStr = GetString().getString(); - sal_Int32 nIdx = 0; - sal_Int32 nCnt = 0; - while ( nIdx < aStr.getLength() && n > nCnt++ ) - aStr.iterateCodePoints( &nIdx ); - aStr = aStr.copy( 0, nIdx ); - PushString( aStr ); } + else + n = 1; + OUString aStr = GetString().getString(); + sal_Int32 nIdx = 0; + sal_Int32 nCnt = 0; + while ( nIdx < aStr.getLength() && n > nCnt++ ) + aStr.iterateCodePoints( &nIdx ); + aStr = aStr.copy( 0, nIdx ); + PushString( aStr ); } namespace { @@ -9042,23 +9042,23 @@ static OUString lcl_RightB(const OUString &rStr, sal_Int32 n) void ScInterpreter::ScRightB() { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 1, 2 ) ) + if ( !MustHaveParamCount( nParamCount, 1, 2 ) ) + return; + + sal_Int32 n; + if (nParamCount == 2) { - sal_Int32 n; - if (nParamCount == 2) + n = GetStringPositionArgument(); + if (n < 0) { - n = GetStringPositionArgument(); - if (n < 0) - { - PushIllegalArgument(); - return ; - } + PushIllegalArgument(); + return ; } - else - n = 1; - OUString aStr(lcl_RightB(GetString().getString(), n)); - PushString( aStr ); } + else + n = 1; + OUString aStr(lcl_RightB(GetString().getString(), n)); + PushString( aStr ); } static OUString lcl_LeftB(const OUString &rStr, sal_Int32 n) { @@ -9091,97 +9091,97 @@ static OUString lcl_LeftB(const OUString &rStr, sal_Int32 n) void ScInterpreter::ScLeftB() { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 1, 2 ) ) + if ( !MustHaveParamCount( nParamCount, 1, 2 ) ) + return; + + sal_Int32 n; + if (nParamCount == 2) { - sal_Int32 n; - if (nParamCount == 2) + n = GetStringPositionArgument(); + if (n < 0) { - n = GetStringPositionArgument(); - if (n < 0) - { - PushIllegalArgument(); - return ; - } + PushIllegalArgument(); + return ; } - else - n = 1; - OUString aStr(lcl_LeftB(GetString().getString(), n)); - PushString( aStr ); } + else + n = 1; + OUString aStr(lcl_LeftB(GetString().getString(), n)); + PushString( aStr ); } void ScInterpreter::ScMidB() { - if ( MustHaveParamCount( GetByte(), 3 ) ) + if ( !MustHaveParamCount( GetByte(), 3 ) ) + return; + + const sal_Int32 nCount = GetStringPositionArgument(); + const sal_Int32 nStart = GetStringPositionArgument(); + OUString aStr = GetString().getString(); + if (nStart < 1 || nCount < 0) + PushIllegalArgument(); + else { - const sal_Int32 nCount = GetStringPositionArgument(); - const sal_Int32 nStart = GetStringPositionArgument(); - OUString aStr = GetString().getString(); - if (nStart < 1 || nCount < 0) - PushIllegalArgument(); - else - { - aStr = lcl_LeftB(aStr, nStart + nCount - 1); - sal_Int32 nCnt = getLengthB(aStr) - nStart + 1; - aStr = lcl_RightB(aStr, std::max<sal_Int32>(nCnt,0)); - PushString(aStr); - } + aStr = lcl_LeftB(aStr, nStart + nCount - 1); + sal_Int32 nCnt = getLengthB(aStr) - nStart + 1; + aStr = lcl_RightB(aStr, std::max<sal_Int32>(nCnt,0)); + PushString(aStr); } } void ScInterpreter::ScReplaceB() { - if ( MustHaveParamCount( GetByte(), 4 ) ) + if ( !MustHaveParamCount( GetByte(), 4 ) ) + return; + + OUString aNewStr = GetString().getString(); + const sal_Int32 nCount = GetStringPositionArgument(); + const sal_Int32 nPos = GetStringPositionArgument(); + OUString aOldStr = GetString().getString(); + int nLen = getLengthB( aOldStr ); + if (nPos < 1.0 || nPos > nLen || nCount < 0.0 || nPos + nCount -1 > nLen) + PushIllegalArgument(); + else { - OUString aNewStr = GetString().getString(); - const sal_Int32 nCount = GetStringPositionArgument(); - const sal_Int32 nPos = GetStringPositionArgument(); - OUString aOldStr = GetString().getString(); - int nLen = getLengthB( aOldStr ); - if (nPos < 1.0 || nPos > nLen || nCount < 0.0 || nPos + nCount -1 > nLen) - PushIllegalArgument(); - else - { - // REPLACEB(aOldStr;nPos;nCount;aNewStr) is the same as - // LEFTB(aOldStr;nPos-1) & aNewStr & RIGHT(aOldStr;LENB(aOldStr)-(nPos - 1)-nCount) - OUString aStr1 = lcl_LeftB( aOldStr, nPos - 1 ); - OUString aStr3 = lcl_RightB( aOldStr, nLen - nPos - nCount + 1); + // REPLACEB(aOldStr;nPos;nCount;aNewStr) is the same as + // LEFTB(aOldStr;nPos-1) & aNewStr & RIGHT(aOldStr;LENB(aOldStr)-(nPos - 1)-nCount) + OUString aStr1 = lcl_LeftB( aOldStr, nPos - 1 ); + OUString aStr3 = lcl_RightB( aOldStr, nLen - nPos - nCount + 1); - PushString( aStr1 + aNewStr + aStr3 ); - } + PushString( aStr1 + aNewStr + aStr3 ); } } void ScInterpreter::ScFindB() { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 2, 3 ) ) + if ( !MustHaveParamCount( nParamCount, 2, 3 ) ) + return; + + sal_Int32 nStart; + if ( nParamCount == 3 ) + nStart = GetStringPositionArgument(); + else + nStart = 1; + OUString aStr = GetString().getString(); + int nLen = getLengthB( aStr ); + OUString asStr = GetString().getString(); + int nsLen = getLengthB( asStr ); + if ( nStart < 1 || nStart > nLen - nsLen + 1 ) + PushIllegalArgument(); + else { - sal_Int32 nStart; - if ( nParamCount == 3 ) - nStart = GetStringPositionArgument(); - else - nStart = 1; - OUString aStr = GetString().getString(); - int nLen = getLengthB( aStr ); - OUString asStr = GetString().getString(); - int nsLen = getLengthB( asStr ); - if ( nStart < 1 || nStart > nLen - nsLen + 1 ) - PushIllegalArgument(); + // create a string from sStr starting at nStart + OUString aBuf = lcl_RightB( aStr, nLen - nStart + 1 ); + // search aBuf for asStr + sal_Int32 nPos = aBuf.indexOf( asStr, 0 ); + if ( nPos == -1 ) + PushNoValue(); else { - // create a string from sStr starting at nStart - OUString aBuf = lcl_RightB( aStr, nLen - nStart + 1 ); - // search aBuf for asStr - sal_Int32 nPos = aBuf.indexOf( asStr, 0 ); - if ( nPos == -1 ) - PushNoValue(); - else - { - // obtain byte value of nPos - int nBytePos = lcl_getLengthB( aBuf, nPos ); - PushDouble( nBytePos + nStart ); - } + // obtain byte value of nPos + int nBytePos = lcl_getLengthB( aBuf, nPos ); + PushDouble( nBytePos + nStart ); } } } @@ -9189,44 +9189,44 @@ void ScInterpreter::ScFindB() void ScInterpreter::ScSearchB() { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 2, 3 ) ) + if ( !MustHaveParamCount( nParamCount, 2, 3 ) ) + return; + + sal_Int32 nStart; + if ( nParamCount == 3 ) { - sal_Int32 nStart; - if ( nParamCount == 3 ) + nStart = GetStringPositionArgument(); + if( nStart < 1 ) { - nStart = GetStringPositionArgument(); - if( nStart < 1 ) - { - PushIllegalArgument(); - return; - } + PushIllegalArgument(); + return; } - else - nStart = 1; - OUString aStr = GetString().getString(); - sal_Int32 nLen = getLengthB( aStr ); - OUString asStr = GetString().getString(); - sal_Int32 nsLen = nStart - 1; - if( nsLen >= nLen ) + } + else + nStart = 1; + OUString aStr = GetString().getString(); + sal_Int32 nLen = getLengthB( aStr ); + OUString asStr = GetString().getString(); + sal_Int32 nsLen = nStart - 1; + if( nsLen >= nLen ) + PushNoValue(); + else + { + // create a string from sStr starting at nStart + OUString aSubStr( lcl_RightB( aStr, nLen - nStart + 1 ) ); + // search aSubStr for asStr + sal_Int32 nPos = 0; + sal_Int32 nEndPos = aSubStr.getLength(); + utl::SearchParam::SearchType eSearchType = DetectSearchType( asStr, pDok ); + utl::SearchParam sPar( asStr, eSearchType, false, '~', false ); + utl::TextSearch sT( sPar, *ScGlobal::getCharClassPtr() ); + if ( !sT.SearchForward( aSubStr, &nPos, &nEndPos ) ) PushNoValue(); else { - // create a string from sStr starting at nStart - OUString aSubStr( lcl_RightB( aStr, nLen - nStart + 1 ) ); - // search aSubStr for asStr - sal_Int32 nPos = 0; - sal_Int32 nEndPos = aSubStr.getLength(); - utl::SearchParam::SearchType eSearchType = DetectSearchType( asStr, pDok ); - utl::SearchParam sPar( asStr, eSearchType, false, '~', false ); - utl::TextSearch sT( sPar, *ScGlobal::getCharClassPtr() ); - if ( !sT.SearchForward( aSubStr, &nPos, &nEndPos ) ) - PushNoValue(); - else - { - // obtain byte value of nPos - int nBytePos = lcl_getLengthB( aSubStr, nPos ); - PushDouble( nBytePos + nStart ); - } + // obtain byte value of nPos + int nBytePos = lcl_getLengthB( aSubStr, nPos ); + PushDouble( nBytePos + nStart ); } } } @@ -9234,81 +9234,81 @@ void ScInterpreter::ScSearchB() void ScInterpreter::ScRight() { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 1, 2 ) ) + if ( !MustHaveParamCount( nParamCount, 1, 2 ) ) + return; + + sal_Int32 n; + if (nParamCount == 2) { - sal_Int32 n; - if (nParamCount == 2) + n = GetStringPositionArgument(); + if (n < 0) { - n = GetStringPositionArgument(); - if (n < 0) - { - PushIllegalArgument(); - return ; - } + PushIllegalArgument(); + return ; } - else - n = 1; - OUString aStr = GetString().getString(); - sal_Int32 nLen = aStr.getLength(); - if ( nLen <= n ) - PushString( aStr ); - else + } + else + n = 1; + OUString aStr = GetString().getString(); + sal_Int32 nLen = aStr.getLength(); + if ( nLen <= n ) + PushString( aStr ); + else + { + sal_Int32 nIdx = nLen; + sal_Int32 nCnt = 0; + while ( nIdx > 0 && n > nCnt ) { - sal_Int32 nIdx = nLen; - sal_Int32 nCnt = 0; - while ( nIdx > 0 && n > nCnt ) - { - aStr.iterateCodePoints( &nIdx, -1 ); - ++nCnt; - } - aStr = aStr.copy( nIdx, nLen - nIdx ); - PushString( aStr ); + aStr.iterateCodePoints( &nIdx, -1 ); + ++nCnt; } + aStr = aStr.copy( nIdx, nLen - nIdx ); + PushString( aStr ); } } void ScInterpreter::ScSearch() { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 2, 3 ) ) + if ( !MustHaveParamCount( nParamCount, 2, 3 ) ) + return; + + sal_Int32 nStart; + if (nParamCount == 3) { - sal_Int32 nStart; - if (nParamCount == 3) + nStart = GetStringPositionArgument(); + if( nStart < 1 ) { - nStart = GetStringPositionArgument(); - if( nStart < 1 ) - { - PushIllegalArgument(); - return; - } + PushIllegalArgument(); + return; } - else - nStart = 1; - OUString sStr = GetString().getString(); - OUString SearchStr = GetString().getString(); - sal_Int32 nPos = nStart - 1; - sal_Int32 nEndPos = sStr.getLength(); - if( nPos >= nEndPos ) + } + else + nStart = 1; + OUString sStr = GetString().getString(); + OUString SearchStr = GetString().getString(); + sal_Int32 nPos = nStart - 1; + sal_Int32 nEndPos = sStr.getLength(); + if( nPos >= nEndPos ) + PushNoValue(); + else + { + utl::SearchParam::SearchType eSearchType = DetectSearchType( SearchStr, pDok ); + utl::SearchParam sPar(SearchStr, eSearchType, false, '~', false); + utl::TextSearch sT( sPar, *ScGlobal::getCharClassPtr() ); + bool bBool = sT.SearchForward(sStr, &nPos, &nEndPos); + if (!bBool) PushNoValue(); else { - utl::SearchParam::SearchType eSearchType = DetectSearchType( SearchStr, pDok ); - utl::SearchParam sPar(SearchStr, eSearchType, false, '~', false); - utl::TextSearch sT( sPar, *ScGlobal::getCharClassPtr() ); - bool bBool = sT.SearchForward(sStr, &nPos, &nEndPos); - if (!bBool) - PushNoValue(); - else + sal_Int32 nIdx = 0; + sal_Int32 nCnt = 0; + while ( nIdx <= nPos ) { - sal_Int32 nIdx = 0; - sal_Int32 nCnt = 0; - while ( nIdx <= nPos ) - { - sStr.iterateCodePoints( &nIdx ); - ++nCnt; - } - PushDouble( static_cast<double>(nCnt) ); + sStr.iterateCodePoints( &nIdx ); + ++nCnt; } + PushDouble( static_cast<double>(nCnt) ); } } } @@ -9509,116 +9509,116 @@ void ScInterpreter::ScRegex() void ScInterpreter::ScMid() { - if ( MustHaveParamCount( GetByte(), 3 ) ) + if ( !MustHaveParamCount( GetByte(), 3 ) ) + return; + + const sal_Int32 nSubLen = GetStringPositionArgument(); + const sal_Int32 nStart = GetStringPositionArgument(); + OUString aStr = GetString().getString(); + if ( nStart < 1 || nSubLen < 0 ) + PushIllegalArgument(); + else { - const sal_Int32 nSubLen = GetStringPositionArgument(); - const sal_Int32 nStart = GetStringPositionArgument(); - OUString aStr = GetString().getString(); - if ( nStart < 1 || nSubLen < 0 ) - PushIllegalArgument(); - else + sal_Int32 nLen = aStr.getLength(); + sal_Int32 nIdx = 0; + sal_Int32 nCnt = 0; + while ( nIdx < nLen && nStart - 1 > nCnt ) { - sal_Int32 nLen = aStr.getLength(); - sal_Int32 nIdx = 0; - sal_Int32 nCnt = 0; - while ( nIdx < nLen && nStart - 1 > nCnt ) - { - aStr.iterateCodePoints( &nIdx ); - ++nCnt; - } - sal_Int32 nIdx0 = nIdx; //start position + aStr.iterateCodePoints( &nIdx ); + ++nCnt; + } + sal_Int32 nIdx0 = nIdx; //start position - while ( nIdx < nLen && nStart + nSubLen - 1 > nCnt ) - { - aStr.iterateCodePoints( &nIdx ); - ++nCnt; - } - aStr = aStr.copy( nIdx0, nIdx - nIdx0 ); - PushString( aStr ); + while ( nIdx < nLen && nStart + nSubLen - 1 > nCnt ) + { + aStr.iterateCodePoints( &nIdx ); + ++nCnt; } + aStr = aStr.copy( nIdx0, nIdx - nIdx0 ); + PushString( aStr ); } } void ScInterpreter::ScText() { - if ( MustHaveParamCount( GetByte(), 2 ) ) + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + + OUString sFormatString = GetString().getString(); + svl::SharedString aStr; + bool bString = false; + double fVal = 0.0; + switch (GetStackType()) { - OUString sFormatString = GetString().getString(); - svl::SharedString aStr; - bool bString = false; - double fVal = 0.0; - switch (GetStackType()) - { - case svError: - PopError(); - break; - case svDouble: - fVal = PopDouble(); - break; - default: + case svError: + PopError(); + break; + case svDouble: + fVal = PopDouble(); + break; + default: + { + FormulaConstTokenRef xTok( PopToken()); + if (nGlobalError == FormulaError::NONE) { - FormulaConstTokenRef xTok( PopToken()); - if (nGlobalError == FormulaError::NONE) + PushTokenRef( xTok); + // Temporarily override the ConvertStringToValue() + // error for GetCellValue() / GetCellValueOrZero() + FormulaError nSErr = mnStringNoValueError; + mnStringNoValueError = FormulaError::NotNumericString; + fVal = GetDouble(); + mnStringNoValueError = nSErr; + if (nGlobalError == FormulaError::NotNumericString) { + // Not numeric. + nGlobalError = FormulaError::NONE; PushTokenRef( xTok); - // Temporarily override the ConvertStringToValue() - // error for GetCellValue() / GetCellValueOrZero() - FormulaError nSErr = mnStringNoValueError; - mnStringNoValueError = FormulaError::NotNumericString; - fVal = GetDouble(); - mnStringNoValueError = nSErr; - if (nGlobalError == FormulaError::NotNumericString) - { - // Not numeric. - nGlobalError = FormulaError::NONE; - PushTokenRef( xTok); - aStr = GetString(); - bString = true; - } + aStr = GetString(); + bString = true; } } - } - if (nGlobalError != FormulaError::NONE) - PushError( nGlobalError); - else if (sFormatString.isEmpty()) - { - // Mimic the Excel behaviour that - // * anything numeric returns an empty string - // * text convertible to numeric returns an empty string - // * any other text returns that text - // Conversion was detected above. - if (bString) - PushString( aStr); + } + } + if (nGlobalError != FormulaError::NONE) + PushError( nGlobalError); + else if (sFormatString.isEmpty()) + { + // Mimic the Excel behaviour that + // * anything numeric returns an empty string + // * text convertible to numeric returns an empty string + // * any other text returns that text + // Conversion was detected above. + if (bString) + PushString( aStr); + else + PushString( OUString()); + } + else + { + OUString aResult; + Color* pColor = nullptr; + LanguageType eCellLang; + const ScPatternAttr* pPattern = pDok->GetPattern( + aPos.Col(), aPos.Row(), aPos.Tab() ); + if ( pPattern ) + eCellLang = pPattern->GetItem( ATTR_LANGUAGE_FORMAT ).GetValue(); + else + eCellLang = ScGlobal::eLnge; + if (bString) + { + if (!pFormatter->GetPreviewString( sFormatString, aStr.getString(), + aResult, &pColor, eCellLang)) + PushIllegalArgument(); else - PushString( OUString()); + PushString( aResult); } else { - OUString aResult; - Color* pColor = nullptr; - LanguageType eCellLang; - const ScPatternAttr* pPattern = pDok->GetPattern( - aPos.Col(), aPos.Row(), aPos.Tab() ); - if ( pPattern ) - eCellLang = pPattern->GetItem( ATTR_LANGUAGE_FORMAT ).GetValue(); - else - eCellLang = ScGlobal::eLnge; - if (bString) - { - if (!pFormatter->GetPreviewString( sFormatString, aStr.getString(), - aResult, &pColor, eCellLang)) - PushIllegalArgument(); - else - PushString( aResult); - } + if (!pFormatter->GetPreviewStringGuess( sFormatString, fVal, + aResult, &pColor, eCellLang)) + PushIllegalArgument(); else - { - if (!pFormatter->GetPreviewStringGuess( sFormatString, fVal, - aResult, &pColor, eCellLang)) - PushIllegalArgument(); - else - PushString( aResult); - } + PushString( aResult); } } } @@ -9626,76 +9626,76 @@ void ScInterpreter::ScText() void ScInterpreter::ScSubstitute() { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 3, 4 ) ) + if ( !MustHaveParamCount( nParamCount, 3, 4 ) ) + return; + + sal_Int32 nCnt; + if (nParamCount == 4) { - sal_Int32 nCnt; - if (nParamCount == 4) + nCnt = GetStringPositionArgument(); + if (nCnt < 1) { - nCnt = GetStringPositionArgument(); - if (nCnt < 1) - { - PushIllegalArgument(); - return; - } + PushIllegalArgument(); + return; } - else - nCnt = 0; - OUString sNewStr = GetString().getString(); - OUString sOldStr = GetString().getString(); - OUString sStr = GetString().getString(); - sal_Int32 nPos = 0; - sal_Int32 nCount = 0; - sal_Int32 nNewLen = sNewStr.getLength(); - sal_Int32 nOldLen = sOldStr.getLength(); - while( true ) + } + else + nCnt = 0; + OUString sNewStr = GetString().getString(); + OUString sOldStr = GetString().getString(); + OUString sStr = GetString().getString(); + sal_Int32 nPos = 0; + sal_Int32 nCount = 0; + sal_Int32 nNewLen = sNewStr.getLength(); + sal_Int32 nOldLen = sOldStr.getLength(); + while( true ) + { + nPos = sStr.indexOf( sOldStr, nPos ); + if (nPos != -1) { - nPos = sStr.indexOf( sOldStr, nPos ); - if (nPos != -1) + nCount++; + if( !nCnt || nCount == nCnt ) { - nCount++; - if( !nCnt || nCount == nCnt ) + sStr = sStr.replaceAt(nPos,nOldLen, ""); + if ( CheckStringResultLen( sStr, sNewStr ) ) { - sStr = sStr.replaceAt(nPos,nOldLen, ""); - if ( CheckStringResultLen( sStr, sNewStr ) ) - { - sStr = sStr.replaceAt(nPos, 0, sNewStr); - nPos = sal::static_int_cast<sal_Int32>( nPos + nNewLen ); - } - else - break; + sStr = sStr.replaceAt(nPos, 0, sNewStr); + nPos = sal::static_int_cast<sal_Int32>( nPos + nNewLen ); } else - nPos++; + break; } else - break; + nPos++; } - PushString( sStr ); + else + break; } + PushString( sStr ); } void ScInterpreter::ScRept() { - if ( MustHaveParamCount( GetByte(), 2 ) ) + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + + sal_Int32 nCnt = GetStringPositionArgument(); + OUString aStr = GetString().getString(); + if (nCnt < 0) + PushIllegalArgument(); + else if (static_cast<double>(nCnt) * aStr.getLength() > kScInterpreterMaxStrLen) { - sal_Int32 nCnt = GetStringPositionArgument(); - OUString aStr = GetString().getString(); - if (nCnt < 0) - PushIllegalArgument(); - else if (static_cast<double>(nCnt) * aStr.getLength() > kScInterpreterMaxStrLen) - { - PushError( FormulaError::StringOverflow ); - } - else if (nCnt == 0) - PushString( EMPTY_OUSTRING ); - else - { - const sal_Int32 nLen = aStr.getLength(); - OUStringBuffer aRes(nCnt*nLen); - while( nCnt-- ) - aRes.append(aStr); - PushString( aRes.makeStringAndClear() ); - } + PushError( FormulaError::StringOverflow ); + } + else if (nCnt == 0) + PushString( EMPTY_OUSTRING ); + else + { + const sal_Int32 nLen = aStr.getLength(); + OUStringBuffer aRes(nCnt*nLen); + while( nCnt-- ) + aRes.append(aStr); + PushString( aRes.makeStringAndClear() ); } } diff --git a/sc/source/core/tool/interpr2.cxx b/sc/source/core/tool/interpr2.cxx index 6d202166db54..96716236cfa5 100644 --- a/sc/source/core/tool/interpr2.cxx +++ b/sc/source/core/tool/interpr2.cxx @@ -194,48 +194,48 @@ void ScInterpreter::ScGetDateValue() void ScInterpreter::ScGetDayOfWeek() { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 1, 2 ) ) - { - sal_Int16 nFlag; - if (nParamCount == 2) - nFlag = GetInt16(); - else - nFlag = 1; + if ( !MustHaveParamCount( nParamCount, 1, 2 ) ) + return; - Date aDate = pFormatter->GetNullDate(); - aDate.AddDays( GetInt32()); - int nVal = static_cast<int>(aDate.GetDayOfWeek()); // MONDAY = 0 - switch (nFlag) - { - case 1: // Sunday = 1 - if (nVal == 6) - nVal = 1; - else - nVal += 2; - break; - case 2: // Monday = 1 - nVal += 1; - break; - case 3: // Monday = 0 - ; // nothing - break; - case 11: // Monday = 1 - case 12: // Tuesday = 1 - case 13: // Wednesday = 1 - case 14: // Thursday = 1 - case 15: // Friday = 1 - case 16: // Saturday = 1 - case 17: // Sunday = 1 - if (nVal < nFlag - 11) // x = nFlag - 11 = 0,1,2,3,4,5,6 - nVal += 19 - nFlag; // nVal += (8 - (nFlag - 11) = 8 - x = 8,7,6,5,4,3,2) - else - nVal -= nFlag - 12; // nVal -= ((nFlag - 11) - 1 = x - 1 = -1,0,1,2,3,4,5) - break; - default: - SetError( FormulaError::IllegalArgument); - } - PushInt( nVal ); + sal_Int16 nFlag; + if (nParamCount == 2) + nFlag = GetInt16(); + else + nFlag = 1; + + Date aDate = pFormatter->GetNullDate(); + aDate.AddDays( GetInt32()); + int nVal = static_cast<int>(aDate.GetDayOfWeek()); // MONDAY = 0 + switch (nFlag) + { + case 1: // Sunday = 1 + if (nVal == 6) + nVal = 1; + else + nVal += 2; + break; + case 2: // Monday = 1 + nVal += 1; + break; + case 3: // Monday = 0 + ; // nothing + break; + case 11: // Monday = 1 + case 12: // Tuesday = 1 + case 13: // Wednesday = 1 + case 14: // Thursday = 1 + case 15: // Friday = 1 + case 16: // Saturday = 1 + case 17: // Sunday = 1 + if (nVal < nFlag - 11) // x = nFlag - 11 = 0,1,2,3,4,5,6 + nVal += 19 - nFlag; // nVal += (8 - (nFlag - 11) = 8 - x = 8,7,6,5,4,3,2) + else + nVal -= nFlag - 12; // nVal -= ((nFlag - 11) - 1 = x - 1 = -1,0,1,2,3,4,5) + break; + default: + SetError( FormulaError::IllegalArgument); } + PushInt( nVal ); } void ScInterpreter::ScWeeknumOOo() @@ -253,51 +253,51 @@ void ScInterpreter::ScWeeknumOOo() void ScInterpreter::ScGetWeekOfYear() { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 1, 2 ) ) - { - sal_Int16 nFlag; - if (nParamCount == 1) - nFlag = 1; - else - nFlag = GetInt16(); + if ( !MustHaveParamCount( nParamCount, 1, 2 ) ) + return; - Date aDate = pFormatter->GetNullDate(); - aDate.AddDays( GetInt32()); + sal_Int16 nFlag; + if (nParamCount == 1) + nFlag = 1; + else + nFlag = GetInt16(); - sal_Int32 nMinimumNumberOfDaysInWeek; - DayOfWeek eFirstDayOfWeek; - switch ( nFlag ) - { - case 1 : - eFirstDayOfWeek = SUNDAY; - nMinimumNumberOfDaysInWeek = 1; - break; - case 2 : - eFirstDayOfWeek = MONDAY; - nMinimumNumberOfDaysInWeek = 1; - break; - case 11 : - case 12 : - case 13 : - case 14 : - case 15 : - case 16 : - case 17 : - eFirstDayOfWeek = static_cast<DayOfWeek>( nFlag - 11 ); // MONDAY := 0 - nMinimumNumberOfDaysInWeek = 1; //the week containing January 1 is week 1 - break; - case 21 : - case 150 : - // ISO 8601 - eFirstDayOfWeek = MONDAY; - nMinimumNumberOfDaysInWeek = 4; - break; - default : - PushIllegalArgument(); - return; - } - PushInt( static_cast<int>(aDate.GetWeekOfYear( eFirstDayOfWeek, nMinimumNumberOfDaysInWeek )) ); + Date aDate = pFormatter->GetNullDate(); + aDate.AddDays( GetInt32()); + + sal_Int32 nMinimumNumberOfDaysInWeek; + DayOfWeek eFirstDayOfWeek; + switch ( nFlag ) + { + case 1 : + eFirstDayOfWeek = SUNDAY; + nMinimumNumberOfDaysInWeek = 1; + break; + case 2 : + eFirstDayOfWeek = MONDAY; + nMinimumNumberOfDaysInWeek = 1; + break; + case 11 : + case 12 : + case 13 : + case 14 : + case 15 : + case 16 : + case 17 : + eFirstDayOfWeek = static_cast<DayOfWeek>( nFlag - 11 ); // MONDAY := 0 + nMinimumNumberOfDaysInWeek = 1; //the week containing January 1 is week 1 + break; + case 21 : + case 150 : + // ISO 8601 + eFirstDayOfWeek = MONDAY; + nMinimumNumberOfDaysInWeek = 4; + break; + default : + PushIllegalArgument(); + return; } + PushInt( static_cast<int>(aDate.GetWeekOfYear( eFirstDayOfWeek, nMinimumNumberOfDaysInWeek )) ); } void ScInterpreter::ScGetIsoWeekOfYear() @@ -313,42 +313,42 @@ void ScInterpreter::ScGetIsoWeekOfYear() void ScInterpreter::ScEasterSunday() { nFuncFmtType = SvNumFormatType::DATE; - if ( MustHaveParamCount( GetByte(), 1 ) ) + if ( !MustHaveParamCount( GetByte(), 1 ) ) + return; + + sal_Int16 nDay, nMonth, nYear; + nYear = GetInt16(); + if (nGlobalError != FormulaError::NONE) { - sal_Int16 nDay, nMonth, nYear; - nYear = GetInt16(); - if (nGlobalError != FormulaError::NONE) - { - PushError( nGlobalError); - return; - } - if ( nYear < 100 ) - nYear = pFormatter->ExpandTwoDigitYear( nYear ); - if (nYear < 1583 || nYear > 9956) - { - // Valid Gregorian and maximum year constraints not met. - PushIllegalArgument(); - return; - } - // don't worry, be happy :) - int B,C,D,E,F,G,H,I,K,L,M,N,O; - N = nYear % 19; - B = int(nYear / 100); - C = nYear % 100; - D = int(B / 4); - E = B % 4; - F = int((B + 8) / 25); - G = int((B - F + 1) / 3); - H = (19 * N + B - D - G + 15) % 30; - I = int(C / 4); - K = C % 4; - L = (32 + 2 * E + 2 * I - H - K) % 7; - M = int((N + 11 * H + 22 * L) / 451); - O = H + L - 7 * M + 114; - nDay = sal::static_int_cast<sal_Int16>( O % 31 + 1 ); - nMonth = sal::static_int_cast<sal_Int16>( int(O / 31) ); - PushDouble( GetDateSerial( nYear, nMonth, nDay, true ) ); + PushError( nGlobalError); + return; + } + if ( nYear < 100 ) + nYear = pFormatter->ExpandTwoDigitYear( nYear ); + if (nYear < 1583 || nYear > 9956) + { + // Valid Gregorian and maximum year constraints not met. + PushIllegalArgument(); + return; } + // don't worry, be happy :) + int B,C,D,E,F,G,H,I,K,L,M,N,O; + N = nYear % 19; + B = int(nYear / 100); + C = nYear % 100; + D = int(B / 4); + E = B % 4; + F = int((B + 8) / 25); + G = int((B - F + 1) / 3); + H = (19 * N + B - D - G + 15) % 30; + I = int(C / 4); + K = C % 4; + L = (32 + 2 * E + 2 * I - H - K) % 7; + M = int((N + 11 * H + 22 * L) / 451); + O = H + L - 7 * M + 114; + nDay = sal::static_int_cast<sal_Int16>( O % 31 + 1 ); + nMonth = sal::static_int_cast<sal_Int16>( int(O / 31) ); + PushDouble( GetDateSerial( nYear, nMonth, nDay, true ) ); } FormulaError ScInterpreter::GetWeekendAndHolidayMasks( @@ -512,131 +512,131 @@ FormulaError ScInterpreter::GetWeekendAndHolidayMasks_MS( void ScInterpreter::ScNetWorkdays( bool bOOXML_Version ) { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 2, 4 ) ) + if ( !MustHaveParamCount( nParamCount, 2, 4 ) ) + return; + + vector<double> nSortArray; + bool bWeekendMask[ 7 ]; + const Date& rNullDate = pFormatter->GetNullDate(); + sal_uInt32 nNullDate = Date::DateToDays( rNullDate.GetDay(), rNullDate.GetMonth(), rNullDate.GetYear() ); + FormulaError nErr; + if ( bOOXML_Version ) { - vector<double> nSortArray; - bool bWeekendMask[ 7 ]; - const Date& rNullDate = pFormatter->GetNullDate(); - sal_uInt32 nNullDate = Date::DateToDays( rNullDate.GetDay(), rNullDate.GetMonth(), rNullDate.GetYear() ); - FormulaError nErr; - if ( bOOXML_Version ) + nErr = GetWeekendAndHolidayMasks_MS( nParamCount, nNullDate, + nSortArray, bWeekendMask, false ); + } + else + { + nErr = GetWeekendAndHolidayMasks( nParamCount, nNullDate, + nSortArray, bWeekendMask ); + } + if ( nErr != FormulaError::NONE ) + PushError( nErr ); + else + { + sal_uInt32 nDate2 = GetUInt32(); + sal_uInt32 nDate1 = GetUInt32(); + if (nGlobalError != FormulaError::NONE || (nDate1 > SAL_MAX_UINT32 - nNullDate) || nDate2 > (SAL_MAX_UINT32 - nNullDate)) { - nErr = GetWeekendAndHolidayMasks_MS( nParamCount, nNullDate, - nSortArray, bWeekendMask, false ); + PushIllegalArgument(); + return; } - else + nDate2 += nNullDate; + nDate1 += nNullDate; + + sal_Int32 nCnt = 0; + size_t nRef = 0; + bool bReverse = ( nDate1 > nDate2 ); + if ( bReverse ) { - nErr = GetWeekendAndHolidayMasks( nParamCount, nNullDate, - nSortArray, bWeekendMask ); + sal_uInt32 nTemp = nDate1; + nDate1 = nDate2; + nDate2 = nTemp; } - if ( nErr != FormulaError::NONE ) - PushError( nErr ); - else + size_t nMax = nSortArray.size(); + while ( nDate1 <= nDate2 ) { - sal_uInt32 nDate2 = GetUInt32(); - sal_uInt32 nDate1 = GetUInt32(); - if (nGlobalError != FormulaError::NONE || (nDate1 > SAL_MAX_UINT32 - nNullDate) || nDate2 > (SAL_MAX_UINT32 - nNullDate)) - { - PushIllegalArgument(); - return; - } - nDate2 += nNullDate; - nDate1 += nNullDate; - - sal_Int32 nCnt = 0; - size_t nRef = 0; - bool bReverse = ( nDate1 > nDate2 ); - if ( bReverse ) - { - sal_uInt32 nTemp = nDate1; - nDate1 = nDate2; - nDate2 = nTemp; - } - size_t nMax = nSortArray.size(); - while ( nDate1 <= nDate2 ) + if ( !bWeekendMask[ GetDayOfWeek( nDate1 ) ] ) { - if ( !bWeekendMask[ GetDayOfWeek( nDate1 ) ] ) - { - while ( nRef < nMax && nSortArray.at( nRef ) < nDate1 ) - nRef++; - if ( nRef >= nMax || nSortArray.at( nRef ) != nDate1 ) - nCnt++; - } - ++nDate1; + while ( nRef < nMax && nSortArray.at( nRef ) < nDate1 ) + nRef++; + if ( nRef >= nMax || nSortArray.at( nRef ) != nDate1 ) + nCnt++; } - PushDouble( static_cast<double>( bReverse ? -nCnt : nCnt ) ); + ++nDate1; } + PushDouble( static_cast<double>( bReverse ? -nCnt : nCnt ) ); } } void ScInterpreter::ScWorkday_MS() { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 2, 4 ) ) - { - nFuncFmtType = SvNumFormatType::DATE; - vector<double> nSortArray; - bool bWeekendMask[ 7 ]; - const Date& rNullDate = pFormatter->GetNullDate(); - sal_uInt32 nNullDate = Date::DateToDays( rNullDate.GetDay(), rNullDate.GetMonth(), rNullDate.GetYear() ); - FormulaError nErr = GetWeekendAndHolidayMasks_MS( nParamCount, nNullDate, - nSortArray, bWeekendMask, true ); - if ( nErr != FormulaError::NONE ) - PushError( nErr ); - else + if ( !MustHaveParamCount( nParamCount, 2, 4 ) ) + return; + + nFuncFmtType = SvNumFormatType::DATE; + vector<double> nSortArray; + bool bWeekendMask[ 7 ]; + const Date& rNullDate = pFormatter->GetNullDate(); + sal_uInt32 nNullDate = Date::DateToDays( rNullDate.GetDay(), rNullDate.GetMonth(), rNullDate.GetYear() ); + FormulaError nErr = GetWeekendAndHolidayMasks_MS( nParamCount, nNullDate, + nSortArray, bWeekendMask, true ); + if ( nErr != FormulaError::NONE ) + PushError( nErr ); + else + { + sal_Int32 nDays = GetInt32(); + sal_uInt32 nDate = GetUInt32(); + if (nGlobalError != FormulaError::NONE || (nDate > SAL_MAX_UINT32 - nNullDate)) { - sal_Int32 nDays = GetInt32(); - sal_uInt32 nDate = GetUInt32(); - if (nGlobalError != FormulaError::NONE || (nDate > SAL_MAX_UINT32 - nNullDate)) - { - PushIllegalArgument(); - return; - } - nDate += nNullDate; + PushIllegalArgument(); + return; + } + nDate += nNullDate; - if ( !nDays ) - PushDouble( static_cast<double>( nDate - nNullDate ) ); - else + if ( !nDays ) + PushDouble( static_cast<double>( nDate - nNullDate ) ); + else + { + size_t nMax = nSortArray.size(); + if ( nDays > 0 ) { - size_t nMax = nSortArray.size(); - if ( nDays > 0 ) + size_t nRef = 0; + while ( nDays ) { - size_t nRef = 0; - while ( nDays ) + do { - do - { - ++nDate; - } - while ( bWeekendMask[ GetDayOfWeek( nDate ) ] ); //jump over weekend day(s) + ++nDate; + } + while ( bWeekendMask[ GetDayOfWeek( nDate ) ] ); //jump over weekend day(s) - while ( nRef < nMax && nSortArray.at( nRef ) < nDate ) - nRef++; + while ( nRef < nMax && nSortArray.at( nRef ) < nDate ) + nRef++; - if ( nRef >= nMax || nSortArray.at( nRef ) != nDate || nRef >= nMax ) - nDays--; - } + if ( nRef >= nMax || nSortArray.at( nRef ) != nDate || nRef >= nMax ) + nDays--; } - else + } + else + { + sal_Int16 nRef = nMax - 1; + while ( nDays ) { - sal_Int16 nRef = nMax - 1; - while ( nDays ) + do { - do - { - --nDate; - } - while ( bWeekendMask[ GetDayOfWeek( nDate ) ] ); //jump over weekend day(s) + --nDate; + } + while ( bWeekendMask[ GetDayOfWeek( nDate ) ] ); //jump over weekend day(s) - while ( nRef >= 0 && nSortArray.at( nRef ) > nDate ) - nRef--; + while ( nRef >= 0 && nSortArray.at( nRef ) > nDate ) + nRef--; - if (nRef < 0 || nSortArray.at(nRef) != nDate) - nDays++; - } + if (nRef < 0 || nSortArray.at(nRef) != nDate) + nDays++; } - PushDouble( static_cast<double>( nDate - nNullDate ) ); } + PushDouble( static_cast<double>( nDate - nNullDate ) ); } } } @@ -644,19 +644,19 @@ void ScInterpreter::ScWorkday_MS() void ScInterpreter::ScGetDate() { nFuncFmtType = SvNumFormatType::DATE; - if ( MustHaveParamCount( GetByte(), 3 ) ) + if ( !MustHaveParamCount( GetByte(), 3 ) ) + return; + + sal_Int16 nDay = GetInt16(); + sal_Int16 nMonth = GetInt16(); + if (IsMissing()) + SetError( FormulaError::ParameterExpected); // Year must be given. + sal_Int16 nYear = GetInt16(); + if (nGlobalError != FormulaError::NONE || nYear < 0) + PushIllegalArgument(); + else { - sal_Int16 nDay = GetInt16(); - sal_Int16 nMonth = GetInt16(); - if (IsMissing()) - SetError( FormulaError::ParameterExpected); // Year must be given. - sal_Int16 nYear = GetInt16(); - if (nGlobalError != FormulaError::NONE || nYear < 0) - PushIllegalArgument(); - else - { - PushDouble(GetDateSerial(nYear, nMonth, nDay, false)); - } + PushDouble(GetDateSerial(nYear, nMonth, nDay, false)); } } @@ -714,220 +714,220 @@ void ScInterpreter::ScGetDiffDate360() */ sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 2, 3 ) ) + if ( !MustHaveParamCount( nParamCount, 2, 3 ) ) + return; + + bool bFlag; + if (nParamCount == 3) + bFlag = GetBool(); + else + bFlag = false; + sal_Int32 nDate2 = GetInt32(); + sal_Int32 nDate1 = GetInt32(); + if (nGlobalError != FormulaError::NONE) + PushError( nGlobalError); + else { - bool bFlag; - if (nParamCount == 3) - bFlag = GetBool(); - else - bFlag = false; - sal_Int32 nDate2 = GetInt32(); - sal_Int32 nDate1 = GetInt32(); - if (nGlobalError != FormulaError::NONE) - PushError( nGlobalError); + sal_Int32 nSign; + // #i84934# only for non-US European algorithm swap dates. Else + // follow Excel's meaningless extrapolation for "interoperability". + if (bFlag && (nDate2 < nDate1)) + { + nSign = nDate1; + nDate1 = nDate2; + nDate2 = nSign; + nSign = -1; + } else + nSign = 1; + Date aDate1 = pFormatter->GetNullDate(); + aDate1.AddDays( nDate1); + Date aDate2 = pFormatter->GetNullDate(); + aDate2.AddDays( nDate2); + if (aDate1.GetDay() == 31) + aDate1.AddDays( -1); + else if (!bFlag) { - sal_Int32 nSign; - // #i84934# only for non-US European algorithm swap dates. Else - // follow Excel's meaningless extrapolation for "interoperability". - if (bFlag && (nDate2 < nDate1)) - { - nSign = nDate1; - nDate1 = nDate2; - nDate2 = nSign; - nSign = -1; - } - else - nSign = 1; - Date aDate1 = pFormatter->GetNullDate(); - aDate1.AddDays( nDate1); - Date aDate2 = pFormatter->GetNullDate(); - aDate2.AddDays( nDate2); - if (aDate1.GetDay() == 31) - aDate1.AddDays( -1); - else if (!bFlag) + if (aDate1.GetMonth() == 2) { - if (aDate1.GetMonth() == 2) + switch ( aDate1.GetDay() ) { - switch ( aDate1.GetDay() ) - { - case 28 : - if ( !aDate1.IsLeapYear() ) - aDate1.SetDay(30); - break; - case 29 : + case 28 : + if ( !aDate1.IsLeapYear() ) aDate1.SetDay(30); - break; - } + break; + case 29 : + aDate1.SetDay(30); + break; } } - if (aDate2.GetDay() == 31) + } + if (aDate2.GetDay() == 31) + { + if (!bFlag ) { - if (!bFlag ) - { - if (aDate1.GetDay() == 30) - aDate2.AddDays( -1); - } - else - aDate2.SetDay(30); + if (aDate1.GetDay() == 30) + aDate2.AddDays( -1); } - PushDouble( static_cast<double>(nSign) * - ( static_cast<double>(aDate2.GetDay()) + static_cast<double>(aDate2.GetMonth()) * 30.0 + - static_cast<double>(aDate2.GetYear()) * 360.0 - - static_cast<double>(aDate1.GetDay()) - static_cast<double>(aDate1.GetMonth()) * 30.0 - - static_cast<double>(aDate1.GetYear()) * 360.0) ); + else + aDate2.SetDay(30); } + PushDouble( static_cast<double>(nSign) * + ( static_cast<double>(aDate2.GetDay()) + static_cast<double>(aDate2.GetMonth()) * 30.0 + + static_cast<double>(aDate2.GetYear()) * 360.0 + - static_cast<double>(aDate1.GetDay()) - static_cast<double>(aDate1.GetMonth()) * 30.0 + - static_cast<double>(aDate1.GetYear()) * 360.0) ); } } // fdo#44456 function DATEDIF as defined in ODF1.2 (Par. 6.10.3) void ScInterpreter::ScGetDateDif() { - if ( MustHaveParamCount( GetByte(), 3 ) ) - { - OUString aInterval = GetString().getString(); - sal_Int32 nDate2 = GetInt32(); - sal_Int32 nDate1 = GetInt32(); - - if (nGlobalError != FormulaError::NONE) - { - PushError( nGlobalError); - return; - } + if ( !MustHaveParamCount( GetByte(), 3 ) ) + return; - // Excel doesn't swap dates or return negative numbers, so don't we. - if (nDate1 > nDate2) - { - PushIllegalArgument(); - return; - } + OUString aInterval = GetString().getString(); + sal_Int32 nDate2 = GetInt32(); + sal_Int32 nDate1 = GetInt32(); - double dd = nDate2 - nDate1; - // Zero difference or number of days can be returned immediately. - if (dd == 0.0 || aInterval.equalsIgnoreAsciiCase( "d" )) - { - PushDouble( dd ); - return; - } + if (nGlobalError != FormulaError::NONE) + { + PushError( nGlobalError); + return; + } - // split dates in day, month, year for use with formats other than "d" - sal_uInt16 d1, m1, d2, m2; - sal_Int16 y1, y2; - Date aDate1( pFormatter->GetNullDate()); - aDate1.AddDays( nDate1); - y1 = aDate1.GetYear(); - m1 = aDate1.GetMonth(); - d1 = aDate1.GetDay(); - Date aDate2( pFormatter->GetNullDate()); - aDate2.AddDays( nDate2); - y2 = aDate2.GetYear(); - m2 = aDate2.GetMonth(); - d2 = aDate2.GetDay(); + // Excel doesn't swap dates or return negative numbers, so don't we. + if (nDate1 > nDate2) + { + PushIllegalArgument(); + return; + } - // Close the year 0 gap to calculate year difference. - if (y1 < 0 && y2 > 0) - ++y1; - else if (y1 > 0 && y2 < 0) - ++y2; + double dd = nDate2 - nDate1; + // Zero difference or number of days can be returned immediately. + if (dd == 0.0 || aInterval.equalsIgnoreAsciiCase( "d" )) + { + PushDouble( dd ); + return; + } - if ( aInterval.equalsIgnoreAsciiCase( "m" ) ) + // split dates in day, month, year for use with formats other than "d" + sal_uInt16 d1, m1, d2, m2; + sal_Int16 y1, y2; + Date aDate1( pFormatter->GetNullDate()); + aDate1.AddDays( nDate1); + y1 = aDate1.GetYear(); + m1 = aDate1.GetMonth(); + d1 = aDate1.GetDay(); + Date aDate2( pFormatter->GetNullDate()); + aDate2.AddDays( nDate2); + y2 = aDate2.GetYear(); + m2 = aDate2.GetMonth(); + d2 = aDate2.GetDay(); + + // Close the year 0 gap to calculate year difference. + if (y1 < 0 && y2 > 0) + ++y1; + else if (y1 > 0 && y2 < 0) + ++y2; + + if ( aInterval.equalsIgnoreAsciiCase( "m" ) ) + { + // Return number of months. + int md = m2 - m1 + 12 * (y2 - y1); + if (d1 > d2) + --md; + PushInt( md ); + } + else if ( aInterval.equalsIgnoreAsciiCase( "y" ) ) + { + // Return number of years. + int yd; + if ( y2 > y1 ) { - // Return number of months. - int md = m2 - m1 + 12 * (y2 - y1); - if (d1 > d2) - --md; - PushInt( md ); + if (m2 > m1 || (m2 == m1 && d2 >= d1)) + yd = y2 - y1; // complete years between dates + else + yd = y2 - y1 - 1; // one incomplete year } - else if ( aInterval.equalsIgnoreAsciiCase( "y" ) ) + else { - // Return number of years. - int yd; - if ( y2 > y1 ) - { - if (m2 > m1 || (m2 == m1 && d2 >= d1)) - yd = y2 - y1; // complete years between dates - else - yd = y2 - y1 - 1; // one incomplete year - } - else + // Year is equal as we don't allow reversed arguments, no + // complete year between dates. + yd = 0; + } + PushInt( yd ); + } + else if ( aInterval.equalsIgnoreAsciiCase( "md" ) ) + { + // Return number of days, excluding months and years. + // This is actually the remainder of days when subtracting years + // and months from the difference of dates. Birthday-like 23 years + // and 10 months and 19 days. + + // Algorithm's roll-over behavior extracted from Excel by try and + // error... + // If day1 <= day2 then simply day2 - day1. + // If day1 > day2 then set month1 to month2-1 and year1 to + // year2(-1) and subtract dates, e.g. for 2012-01-28,2012-03-01 set + // 2012-02-28 and then (2012-03-01)-(2012-02-28) => 2 days (leap + // year). + // For 2011-01-29,2011-03-01 the non-existent 2011-02-29 rolls over + // to 2011-03-01 so the result is 0. Same for day 31 in months with + // only 30 days. + + long nd; + if (d1 <= d2) + nd = d2 - d1; + else + { + if (m2 == 1) { - // Year is equal as we don't allow reversed arguments, no - // complete year between dates. - yd = 0; + aDate1.SetYear( y2 == 1 ? -1 : y2 - 1 ); + aDate1.SetMonth( 12 ); } - PushInt( yd ); - } - else if ( aInterval.equalsIgnoreAsciiCase( "md" ) ) - { - // Return number of days, excluding months and years. - // This is actually the remainder of days when subtracting years - // and months from the difference of dates. Birthday-like 23 years - // and 10 months and 19 days. - - // Algorithm's roll-over behavior extracted from Excel by try and - // error... - // If day1 <= day2 then simply day2 - day1. - // If day1 > day2 then set month1 to month2-1 and year1 to - // year2(-1) and subtract dates, e.g. for 2012-01-28,2012-03-01 set - // 2012-02-28 and then (2012-03-01)-(2012-02-28) => 2 days (leap - // year). - // For 2011-01-29,2011-03-01 the non-existent 2011-02-29 rolls over - // to 2011-03-01 so the result is 0. Same for day 31 in months with - // only 30 days. - - long nd; - if (d1 <= d2) - nd = d2 - d1; else { - if (m2 == 1) - { - aDate1.SetYear( y2 == 1 ? -1 : y2 - 1 ); - aDate1.SetMonth( 12 ); - } - else - { - aDate1.SetYear( y2 ); - aDate1.SetMonth( m2 - 1 ); - } - aDate1.Normalize(); - nd = aDate2 - aDate1; - } - PushDouble( nd ); - } - else if ( aInterval.equalsIgnoreAsciiCase( "ym" ) ) - { - // Return number of months, excluding years. - int md = m2 - m1 + 12 * (y2 - y1); - if (d1 > d2) - --md; - md %= 12; - PushInt( md ); - } - else if ( aInterval.equalsIgnoreAsciiCase( "yd" ) ) - { - // Return number of days, excluding years. - - // Condition corresponds with "y". - if (m2 > m1 || (m2 == m1 && d2 >= d1)) aDate1.SetYear( y2 ); - else - aDate1.SetYear( y2 - 1 ); - // XXX NOTE: Excel for the case 1988-06-22,2012-05-11 returns - // 323, whereas the result here is 324. Don't they use the leap - // year of 2012? - // http://www.cpearson.com/excel/datedif.aspx "DATEDIF And Leap - // Years" is not correct and Excel 2010 correctly returns 0 in - // both cases mentioned there. Also using year1 as mentioned - // produces incorrect results in other cases and different from - // Excel 2010. Apparently they fixed some calculations. + aDate1.SetMonth( m2 - 1 ); + } aDate1.Normalize(); - double fd = aDate2 - aDate1; - PushDouble( fd ); + nd = aDate2 - aDate1; } + PushDouble( nd ); + } + else if ( aInterval.equalsIgnoreAsciiCase( "ym" ) ) + { + // Return number of months, excluding years. + int md = m2 - m1 + 12 * (y2 - y1); + if (d1 > d2) + --md; + md %= 12; + PushInt( md ); + } + else if ( aInterval.equalsIgnoreAsciiCase( "yd" ) ) + { + // Return number of days, excluding years. + + // Condition corresponds with "y". + if (m2 > m1 || (m2 == m1 && d2 >= d1)) + aDate1.SetYear( y2 ); else - PushIllegalArgument(); // unsupported format + aDate1.SetYear( y2 - 1 ); + // XXX NOTE: Excel for the case 1988-06-22,2012-05-11 returns + // 323, whereas the result here is 324. Don't they use the leap + // year of 2012? + // http://www.cpearson.com/excel/datedif.aspx "DATEDIF And Leap + // Years" is not correct and Excel 2010 correctly returns 0 in + // both cases mentioned there. Also using year1 as mentioned + // produces incorrect results in other cases and different from + // Excel 2010. Apparently they fixed some calculations. + aDate1.Normalize(); + double fd = aDate2 - aDate1; + PushDouble( fd ); } + else + PushIllegalArgument(); // unsupported format } void ScInterpreter::ScGetTimeValue() @@ -976,36 +976,36 @@ void ScInterpreter::ScInt() void ScInterpreter::RoundNumber( rtl_math_RoundingMode eMode ) { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 1, 2 ) ) + if ( !MustHaveParamCount( nParamCount, 1, 2 ) ) + return; + + double fVal = 0.0; + if (nParamCount == 1) + fVal = ::rtl::math::round( GetDouble(), 0, eMode ); + else { - double fVal = 0.0; - if (nParamCount == 1) - fVal = ::rtl::math::round( GetDouble(), 0, eMode ); + sal_Int16 nDec = GetInt16(); + double fX = GetDouble(); + if ( nGlobalError != FormulaError::NONE || nDec < -20 || nDec > 20 ) + PushIllegalArgument(); else { - sal_Int16 nDec = GetInt16(); - double fX = GetDouble(); - if ( nGlobalError != FormulaError::NONE || nDec < -20 || nDec > 20 ) - PushIllegalArgument(); - else + if ( ( eMode == rtl_math_RoundingMode_Down || + eMode == rtl_math_RoundingMode_Up ) && + nDec < 12 && fmod( fX, 1.0 ) != 0.0 ) { - if ( ( eMode == rtl_math_RoundingMode_Down || - eMode == rtl_math_RoundingMode_Up ) && - nDec < 12 && fmod( fX, 1.0 ) != 0.0 ) - { - // tdf124286 : round to 12 significant digits before rounding - // down or up to avoid unexpected rounding errors - // caused by decimal -> binary -> decimal conversion - double fRes; - RoundSignificant( fX, 12, fRes ); - fVal = ::rtl::math::round( fRes, nDec, eMode ); - } - else - fVal = ::rtl::math::round( fX, nDec, eMode ); + // tdf124286 : round to 12 significant digits before rounding + // down or up to avoid unexpected rounding errors + // caused by decimal -> binary -> decimal conversion + double fRes; + RoundSignificant( fX, 12, fRes ); + fVal = ::rtl::math::round( fRes, nDec, eMode ); } + else + fVal = ::rtl::math::round( fX, nDec, eMode ); } - PushDouble(fVal); } + PushDouble(fVal); } void ScInterpreter::ScRound() @@ -1037,24 +1037,24 @@ void ScInterpreter::RoundSignificant( double fX, double fDigits, double &fRes ) // tdf#106931 void ScInterpreter::ScRoundSignificant() { - if ( MustHaveParamCount( GetByte(), 2 ) ) + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + + double fDigits = ::rtl::math::approxFloor( GetDouble() ); + double fX = GetDouble(); + if ( nGlobalError != FormulaError::NONE || fDigits < 1.0 ) { - double fDigits = ::rtl::math::approxFloor( GetDouble() ); - double fX = GetDouble(); - if ( nGlobalError != FormulaError::NONE || fDigits < 1.0 ) - { - PushIllegalArgument(); - return; - } + PushIllegalArgument(); + return; + } - if ( fX == 0.0 ) - PushDouble( 0.0 ); - else - { - double fRes; - RoundSignificant( fX, fDigits, fRes ); - PushDouble( fRes ); - } + if ( fX == 0.0 ) + PushDouble( 0.0 ); + else + { + double fRes; + RoundSignificant( fX, fDigits, fRes ); + PushDouble( fRes ); } } @@ -1068,39 +1068,39 @@ void ScInterpreter::ScRoundSignificant() void ScInterpreter::ScCeil( bool bODFF ) { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 1, 3 ) ) + if ( !MustHaveParamCount( nParamCount, 1, 3 ) ) + return; + + bool bAbs = nParamCount == 3 && GetBool(); + double fDec, fVal; + if ( nParamCount == 1 ) { - bool bAbs = nParamCount == 3 && GetBool(); - double fDec, fVal; - if ( nParamCount == 1 ) - { - fVal = GetDouble(); + fVal = GetDouble(); + fDec = ( fVal < 0 ? -1 : 1 ); + } + else + { + bool bArgumentMissing = IsMissing(); + fDec = GetDouble(); + fVal = GetDouble(); + if ( bArgumentMissing ) fDec = ( fVal < 0 ? -1 : 1 ); - } - else - { - bool bArgumentMissing = IsMissing(); - fDec = GetDouble(); - fVal = GetDouble(); - if ( bArgumentMissing ) - fDec = ( fVal < 0 ? -1 : 1 ); - } - if ( fVal == 0 || fDec == 0.0 ) - PushInt( 0 ); + } + if ( fVal == 0 || fDec == 0.0 ) + PushInt( 0 ); + else + { + if ( bODFF && fVal * fDec < 0 ) + PushIllegalArgument(); else { - if ( bODFF && fVal * fDec < 0 ) - PushIllegalArgument(); - else - { - if ( fVal * fDec < 0.0 ) - fDec = -fDec; + if ( fVal * fDec < 0.0 ) + fDec = -fDec; - if ( !bAbs && fVal < 0.0 ) - PushDouble(::rtl::math::approxFloor( fVal / fDec ) * fDec ); - else - PushDouble(::rtl::math::approxCeil( fVal / fDec ) * fDec ); - } + if ( !bAbs && fVal < 0.0 ) + PushDouble(::rtl::math::approxFloor( fVal / fDec ) * fDec ); + else + PushDouble(::rtl::math::approxCeil( fVal / fDec ) * fDec ); } } } @@ -1108,42 +1108,42 @@ void ScInterpreter::ScCeil( bool bODFF ) void ScInterpreter::ScCeil_MS() { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 2 ) ) - { - double fDec = GetDouble(); - double fVal = GetDouble(); - if ( fVal == 0 || fDec == 0.0 ) - PushInt(0); - else if ( fVal * fDec > 0 ) - PushDouble(::rtl::math::approxCeil( fVal / fDec ) * fDec ); - else if ( fVal < 0.0 ) - PushDouble(::rtl::math::approxFloor( fVal / -fDec ) * -fDec ); - else - PushIllegalArgument(); - } + if ( !MustHaveParamCount( nParamCount, 2 ) ) + return; + + double fDec = GetDouble(); + double fVal = GetDouble(); + if ( fVal == 0 || fDec == 0.0 ) + PushInt(0); + else if ( fVal * fDec > 0 ) + PushDouble(::rtl::math::approxCeil( fVal / fDec ) * fDec ); + else if ( fVal < 0.0 ) + PushDouble(::rtl::math::approxFloor( fVal / -fDec ) * -fDec ); + else + PushIllegalArgument(); } void ScInterpreter::ScCeil_Precise() { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 1, 2 ) ) + if ( !MustHaveParamCount( nParamCount, 1, 2 ) ) + return; + + double fDec, fVal; + if ( nParamCount == 1 ) { - double fDec, fVal; - if ( nParamCount == 1 ) - { - fVal = GetDouble(); - fDec = 1.0; - } - else - { - fDec = fabs( GetDoubleWithDefault( 1.0 )); - fVal = GetDouble(); - } - if ( fDec == 0.0 || fVal == 0.0 ) - PushInt( 0 ); - else - PushDouble(::rtl::math::approxCeil( fVal / fDec ) * fDec ); + fVal = GetDouble(); + fDec = 1.0; + } + else + { + fDec = fabs( GetDoubleWithDefault( 1.0 )); + fVal = GetDouble(); } + if ( fDec == 0.0 || fVal == 0.0 ) + PushInt( 0 ); + else + PushDouble(::rtl::math::approxCeil( fVal / fDec ) * fDec ); } /** tdf69552 ODFF1.2 function FLOOR and Excel function FLOOR.MATH @@ -1156,39 +1156,39 @@ void ScInterpreter::ScCeil_Precise() void ScInterpreter::ScFloor( bool bODFF ) { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 1, 3 ) ) + if ( !MustHaveParamCount( nParamCount, 1, 3 ) ) + return; + + bool bAbs = ( nParamCount == 3 && GetBool() ); + double fDec, fVal; + if ( nParamCount == 1 ) { - bool bAbs = ( nParamCount == 3 && GetBool() ); - double fDec, fVal; - if ( nParamCount == 1 ) - { - fVal = GetDouble(); + fVal = GetDouble(); + fDec = ( fVal < 0 ? -1 : 1 ); + } + else + { + bool bArgumentMissing = IsMissing(); + fDec = GetDouble(); + fVal = GetDouble(); + if ( bArgumentMissing ) fDec = ( fVal < 0 ? -1 : 1 ); - } - else - { - bool bArgumentMissing = IsMissing(); - fDec = GetDouble(); - fVal = GetDouble(); - if ( bArgumentMissing ) - fDec = ( fVal < 0 ? -1 : 1 ); - } - if ( fDec == 0.0 || fVal == 0.0 ) - PushInt( 0 ); + } + if ( fDec == 0.0 || fVal == 0.0 ) + PushInt( 0 ); + else + { + if ( bODFF && ( fVal * fDec < 0.0 ) ) + PushIllegalArgument(); else { - if ( bODFF && ( fVal * fDec < 0.0 ) ) - PushIllegalArgument(); - else - { - if ( fVal * fDec < 0.0 ) - fDec = -fDec; + if ( fVal * fDec < 0.0 ) + fDec = -fDec; - if ( !bAbs && fVal < 0.0 ) - PushDouble(::rtl::math::approxCeil( fVal / fDec ) * fDec ); - else - PushDouble(::rtl::math::approxFloor( fVal / fDec ) * fDec ); - } + if ( !bAbs && fVal < 0.0 ) + PushDouble(::rtl::math::approxCeil( fVal / fDec ) * fDec ); + else + PushDouble(::rtl::math::approxFloor( fVal / fDec ) * fDec ); } } } @@ -1196,45 +1196,45 @@ void ScInterpreter::ScFloor( bool bODFF ) void ScInterpreter::ScFloor_MS() { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 2 ) ) - { - double fDec = GetDouble(); - double fVal = GetDouble(); + if ( !MustHaveParamCount( nParamCount, 2 ) ) + return; - if ( fVal == 0 ) - PushInt( 0 ); - else if ( fVal * fDec > 0 ) - PushDouble(::rtl::math::approxFloor( fVal / fDec ) * fDec ); - else if ( fDec == 0 ) - PushIllegalArgument(); - else if ( fVal < 0.0 ) - PushDouble(::rtl::math::approxCeil( fVal / -fDec ) * -fDec ); - else - PushIllegalArgument(); - } + double fDec = GetDouble(); + double fVal = GetDouble(); + + if ( fVal == 0 ) + PushInt( 0 ); + else if ( fVal * fDec > 0 ) + PushDouble(::rtl::math::approxFloor( fVal / fDec ) * fDec ); + else if ( fDec == 0 ) + PushIllegalArgument(); + else if ( fVal < 0.0 ) + PushDouble(::rtl::math::approxCeil( fVal / -fDec ) * -fDec ); + else + PushIllegalArgument(); } void ScInterpreter::ScFloor_Precise() { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 1, 2 ) ) + if ( !MustHaveParamCount( nParamCount, 1, 2 ) ) + return; + + double fDec, fVal; + if ( nParamCount == 1 ) { - double fDec, fVal; - if ( nParamCount == 1 ) - { - fVal = GetDouble(); - fDec = 1.0; - } - else - { - fDec = fabs( GetDoubleWithDefault( 1.0 ) ); - fVal = GetDouble(); - } - if ( fDec == 0.0 || fVal == 0.0 ) - PushInt( 0 ); - else - PushDouble(::rtl::math::approxFloor( fVal / fDec ) * fDec ); + fVal = GetDouble(); + fDec = 1.0; + } + else + { + fDec = fabs( GetDoubleWithDefault( 1.0 ) ); + fVal = GetDouble(); } + if ( fDec == 0.0 || fVal == 0.0 ) + PushInt( 0 ); + else + PushDouble(::rtl::math::approxFloor( fVal / fDec ) * fDec ); } void ScInterpreter::ScEven() @@ -1277,19 +1277,19 @@ void ScInterpreter::ScArcTan2() void ScInterpreter::ScLog() { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 1, 2 ) ) - { - double fBase; - if (nParamCount == 2) - fBase = GetDouble(); - else - fBase = 10.0; - double fVal = GetDouble(); - if (fVal > 0.0 && fBase > 0.0 && fBase != 1.0) - PushDouble(log(fVal) / log(fBase)); - else - PushIllegalArgument(); - } + if ( !MustHaveParamCount( nParamCount, 1, 2 ) ) + return; + + double fBase; + if (nParamCount == 2) + fBase = GetDouble(); + else + fBase = 10.0; + double fVal = GetDouble(); + if (fVal > 0.0 && fBase > 0.0 && fBase != 1.0) + PushDouble(log(fVal) / log(fBase)); + else + PushIllegalArgument(); } void ScInterpreter::ScLn() @@ -1314,98 +1314,98 @@ void ScInterpreter::ScNPV() { nFuncFmtType = SvNumFormatType::CURRENCY; short nParamCount = GetByte(); - if ( MustHaveParamCountMin( nParamCount, 2) ) + if ( !MustHaveParamCountMin( nParamCount, 2) ) + return; + + double fVal = 0.0; + // We turn the stack upside down! + ReverseStack( nParamCount); + if (nGlobalError == FormulaError::NONE) { - double fVal = 0.0; - // We turn the stack upside down! - ReverseStack( nParamCount); - if (nGlobalError == FormulaError::NONE) - { - double fCount = 1.0; - double fRate = GetDouble(); - --nParamCount; - size_t nRefInList = 0; - ScRange aRange; - while (nParamCount-- > 0) + double fCount = 1.0; + double fRate = GetDouble(); + --nParamCount; + size_t nRefInList = 0; + ScRange aRange; + while (nParamCount-- > 0) + { + switch (GetStackType()) { - switch (GetStackType()) + case svDouble : + { + fVal += (GetDouble() / pow(1.0 + fRate, fCount)); + fCount++; + } + break; + case svSingleRef : { - case svDouble : + ScAddress aAdr; + PopSingleRef( aAdr ); + ScRefCellValue aCell(*pDok, aAdr); + if (!aCell.hasEmptyValue() && aCell.hasNumeric()) { - fVal += (GetDouble() / pow(1.0 + fRate, fCount)); + double fCellVal = GetCellValue(aAdr, aCell); + fVal += (fCellVal / pow(1.0 + fRate, fCount)); fCount++; } - break; - case svSingleRef : + } + break; + case svDoubleRef : + case svRefList : + { + FormulaError nErr = FormulaError::NONE; + double fCellVal; + PopDoubleRef( aRange, nParamCount, nRefInList); + ScHorizontalValueIterator aValIter( pDok, aRange ); + while ((nErr == FormulaError::NONE) && aValIter.GetNext(fCellVal, nErr)) { - ScAddress aAdr; - PopSingleRef( aAdr ); - ScRefCellValue aCell(*pDok, aAdr); - if (!aCell.hasEmptyValue() && aCell.hasNumeric()) - { - double fCellVal = GetCellValue(aAdr, aCell); - fVal += (fCellVal / pow(1.0 + fRate, fCount)); - fCount++; - } + fVal += (fCellVal / pow(1.0 + fRate, fCount)); + fCount++; } - break; - case svDoubleRef : - case svRefList : + if ( nErr != FormulaError::NONE ) + SetError(nErr); + } + break; + case svMatrix : + case svExternalSingleRef: + case svExternalDoubleRef: + { + ScMatrixRef pMat = GetMatrix(); + if (pMat) { - FormulaError nErr = FormulaError::NONE; - double fCellVal; - PopDoubleRef( aRange, nParamCount, nRefInList); - ScHorizontalValueIterator aValIter( pDok, aRange ); - while ((nErr == FormulaError::NONE) && aValIter.GetNext(fCellVal, nErr)) + SCSIZE nC, nR; + pMat->GetDimensions(nC, nR); + if (nC == 0 || nR == 0) { - fVal += (fCellVal / pow(1.0 + fRate, fCount)); - fCount++; + PushIllegalArgument(); + return; } - if ( nErr != FormulaError::NONE ) - SetError(nErr); - } - break; - case svMatrix : - case svExternalSingleRef: - case svExternalDoubleRef: - { - ScMatrixRef pMat = GetMatrix(); - if (pMat) + else { - SCSIZE nC, nR; - pMat->GetDimensions(nC, nR); - if (nC == 0 || nR == 0) - { - PushIllegalArgument(); - return; - } - else + double fx; + for ( SCSIZE j = 0; j < nC; j++ ) { - double fx; - for ( SCSIZE j = 0; j < nC; j++ ) + for (SCSIZE k = 0; k < nR; ++k) { - for (SCSIZE k = 0; k < nR; ++k) + if (!pMat->IsValue(j,k)) { - if (!pMat->IsValue(j,k)) - { - PushIllegalArgument(); - return; - } - fx = pMat->GetDouble(j,k); - fVal += (fx / pow(1.0 + fRate, fCount)); - fCount++; + PushIllegalArgument(); + return; } + fx = pMat->GetDouble(j,k); + fVal += (fx / pow(1.0 + fRate, fCount)); + fCount++; } } } } - break; - default : SetError(FormulaError::IllegalParameter); break; } + break; + default : SetError(FormulaError::IllegalParameter); break; } } - PushDouble(fVal); } + PushDouble(fVal); } void ScInterpreter::ScIRR() @@ -1477,124 +1477,124 @@ void ScInterpreter::ScIRR() void ScInterpreter::ScMIRR() { // range_of_values ; rate_invest ; rate_reinvest nFuncFmtType = SvNumFormatType::PERCENT; - if ( MustHaveParamCount( GetByte(), 3 ) ) - { - double fRate1_reinvest = GetDouble() + 1; - double fRate1_invest = GetDouble() + 1; + if ( !MustHaveParamCount( GetByte(), 3 ) ) + return; - ScRange aRange; - ScMatrixRef pMat; - SCSIZE nC = 0; - SCSIZE nR = 0; - bool bIsMatrix = false; - switch ( GetStackType() ) - { - case svDoubleRef : - PopDoubleRef( aRange ); - break; - case svMatrix : - case svExternalSingleRef: - case svExternalDoubleRef: + double fRate1_reinvest = GetDouble() + 1; + double fRate1_invest = GetDouble() + 1; + + ScRange aRange; + ScMatrixRef pMat; + SCSIZE nC = 0; + SCSIZE nR = 0; + bool bIsMatrix = false; + switch ( GetStackType() ) + { + case svDoubleRef : + PopDoubleRef( aRange ); + break; + case svMatrix : + case svExternalSingleRef: + case svExternalDoubleRef: + { + pMat = GetMatrix(); + if ( pMat ) { - pMat = GetMatrix(); - if ( pMat ) - { - pMat->GetDimensions( nC, nR ); - if ( nC == 0 || nR == 0 ) - SetError( FormulaError::IllegalArgument ); - bIsMatrix = true; - } - else + pMat->GetDimensions( nC, nR ); + if ( nC == 0 || nR == 0 ) SetError( FormulaError::IllegalArgument ); + bIsMatrix = true; } - break; - default : - SetError( FormulaError::IllegalParameter ); - break; - } + else + SetError( FormulaError::IllegalArgument ); + } + break; + default : + SetError( FormulaError::IllegalParameter ); + break; + } - if ( nGlobalError != FormulaError::NONE ) - PushError( nGlobalError ); - else - { - double fNPV_reinvest = 0.0; - double fPow_reinvest = 1.0; - double fNPV_invest = 0.0; - double fPow_invest = 1.0; - sal_uLong nCount = 0; - bool bHasPosValue = false; - bool bHasNegValue = false; + if ( nGlobalError != FormulaError::NONE ) + PushError( nGlobalError ); + else + { + double fNPV_reinvest = 0.0; + double fPow_reinvest = 1.0; + double fNPV_invest = 0.0; + double fPow_invest = 1.0; + sal_uLong nCount = 0; + bool bHasPosValue = false; + bool bHasNegValue = false; - if ( bIsMatrix ) + if ( bIsMatrix ) + { + double fX; + for ( SCSIZE j = 0; j < nC; j++ ) { - double fX; - for ( SCSIZE j = 0; j < nC; j++ ) + for ( SCSIZE k = 0; k < nR; ++k ) { - for ( SCSIZE k = 0; k < nR; ++k ) - { - if ( !pMat->IsValue( j, k ) ) - continue; - fX = pMat->GetDouble( j, k ); - if ( nGlobalError != FormulaError::NONE ) - break; - - if ( fX > 0.0 ) - { // reinvestments - bHasPosValue = true; - fNPV_reinvest += fX * fPow_reinvest; - } - else if ( fX < 0.0 ) - { // investments - bHasNegValue = true; - fNPV_invest += fX * fPow_invest; - } - fPow_reinvest /= fRate1_reinvest; - fPow_invest /= fRate1_invest; - nCount++; - } - } - } - else - { - ScValueIterator aValIter( pDok, aRange, mnSubTotalFlags ); - double fCellValue; - FormulaError nIterError = FormulaError::NONE; + if ( !pMat->IsValue( j, k ) ) + continue; + fX = pMat->GetDouble( j, k ); + if ( nGlobalError != FormulaError::NONE ) + break; - bool bLoop = aValIter.GetFirst( fCellValue, nIterError ); - while( bLoop ) - { - if( fCellValue > 0.0 ) // reinvestments + if ( fX > 0.0 ) { // reinvestments bHasPosValue = true; - fNPV_reinvest += fCellValue * fPow_reinvest; + fNPV_reinvest += fX * fPow_reinvest; } - else if( fCellValue < 0.0 ) // investments + else if ( fX < 0.0 ) { // investments bHasNegValue = true; - fNPV_invest += fCellValue * fPow_invest; + fNPV_invest += fX * fPow_invest; } fPow_reinvest /= fRate1_reinvest; fPow_invest /= fRate1_invest; nCount++; - - bLoop = aValIter.GetNext( fCellValue, nIterError ); } - - if ( nIterError != FormulaError::NONE ) - SetError( nIterError ); } - if ( !( bHasPosValue && bHasNegValue ) ) - SetError( FormulaError::IllegalArgument ); + } + else + { + ScValueIterator aValIter( pDok, aRange, mnSubTotalFlags ); + double fCellValue; + FormulaError nIterError = FormulaError::NONE; - if ( nGlobalError != FormulaError::NONE ) - PushError( nGlobalError ); - else + bool bLoop = aValIter.GetFirst( fCellValue, nIterError ); + while( bLoop ) { - double fResult = -fNPV_reinvest / fNPV_invest; - fResult *= pow( fRate1_reinvest, static_cast<double>( nCount - 1 ) ); - fResult = pow( fResult, div( 1.0, (nCount - 1)) ); - PushDouble( fResult - 1.0 ); + if( fCellValue > 0.0 ) // reinvestments + { // reinvestments + bHasPosValue = true; + fNPV_reinvest += fCellValue * fPow_reinvest; + } + else if( fCellValue < 0.0 ) // investments + { // investments + bHasNegValue = true; + fNPV_invest += fCellValue * fPow_invest; + } + fPow_reinvest /= fRate1_reinvest; + fPow_invest /= fRate1_invest; + nCount++; + + bLoop = aValIter.GetNext( fCellValue, nIterError ); } + + if ( nIterError != FormulaError::NONE ) + SetError( nIterError ); + } + if ( !( bHasPosValue && bHasNegValue ) ) + SetError( FormulaError::IllegalArgument ); + + if ( nGlobalError != FormulaError::NONE ) + PushError( nGlobalError ); + else + { + double fResult = -fNPV_reinvest / fNPV_invest; + fResult *= pow( fRate1_reinvest, static_cast<double>( nCount - 1 ) ); + fResult = pow( fResult, div( 1.0, (nCount - 1)) ); + PushDouble( fResult - 1.0 ); } } } @@ -1698,23 +1698,23 @@ void ScInterpreter::ScDDB() { nFuncFmtType = SvNumFormatType::CURRENCY; sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 4, 5 ) ) - { - double fFactor; - if (nParamCount == 5) - fFactor = GetDouble(); - else - fFactor = 2.0; - double fPeriod = GetDouble(); - double fLife = GetDouble(); - double fSalvage = GetDouble(); - double fCost = GetDouble(); - if (fCost < 0.0 || fSalvage < 0.0 || fFactor <= 0.0 || fSalvage > fCost - || fPeriod < 1.0 || fPeriod > fLife) - PushIllegalArgument(); - else - PushDouble(ScGetDDB(fCost, fSalvage, fLife, fPeriod, fFactor)); - } + if ( !MustHaveParamCount( nParamCount, 4, 5 ) ) + return; + + double fFactor; + if (nParamCount == 5) + fFactor = GetDouble(); + else + fFactor = 2.0; + double fPeriod = GetDouble(); + double fLife = GetDouble(); + double fSalvage = GetDouble(); + double fCost = GetDouble(); + if (fCost < 0.0 || fSalvage < 0.0 || fFactor <= 0.0 || fSalvage > fCost + || fPeriod < 1.0 || fPeriod > fLife) + PushIllegalArgument(); + else + PushDouble(ScGetDDB(fCost, fSalvage, fLife, fPeriod, fFactor)); } void ScInterpreter::ScDB() @@ -1811,86 +1811,86 @@ void ScInterpreter::ScVDB() { nFuncFmtType = SvNumFormatType::CURRENCY; sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 5, 7 ) ) + if ( !MustHaveParamCount( nParamCount, 5, 7 ) ) + return; + + double fCost, fSalvage, fLife, fStart, fEnd, fFactor, fVdb = 0.0; + bool bNoSwitch; + if (nParamCount == 7) + bNoSwitch = GetBool(); + else + bNoSwitch = false; + if (nParamCount >= 6) + fFactor = GetDouble(); + else + fFactor = 2.0; + fEnd = GetDouble(); + fStart = GetDouble(); + fLife = GetDouble(); + fSalvage = GetDouble(); + fCost = GetDouble(); + if (fStart < 0.0 || fEnd < fStart || fEnd > fLife || fCost < 0.0 + || fSalvage > fCost || fFactor <= 0.0) + PushIllegalArgument(); + else { - double fCost, fSalvage, fLife, fStart, fEnd, fFactor, fVdb = 0.0; - bool bNoSwitch; - if (nParamCount == 7) - bNoSwitch = GetBool(); - else - bNoSwitch = false; - if (nParamCount >= 6) - fFactor = GetDouble(); - else - fFactor = 2.0; - fEnd = GetDouble(); - fStart = GetDouble(); - fLife = GetDouble(); - fSalvage = GetDouble(); - fCost = GetDouble(); - if (fStart < 0.0 || fEnd < fStart || fEnd > fLife || fCost < 0.0 - || fSalvage > fCost || fFactor <= 0.0) - PushIllegalArgument(); - else - { - double fIntStart = ::rtl::math::approxFloor(fStart); - double fIntEnd = ::rtl::math::approxCeil(fEnd); - sal_uLong nLoopStart = static_cast<sal_uLong>(fIntStart); - sal_uLong nLoopEnd = static_cast<sal_uLong>(fIntEnd); + double fIntStart = ::rtl::math::approxFloor(fStart); + double fIntEnd = ::rtl::math::approxCeil(fEnd); + sal_uLong nLoopStart = static_cast<sal_uLong>(fIntStart); + sal_uLong nLoopEnd = static_cast<sal_uLong>(fIntEnd); - fVdb = 0.0; - if (bNoSwitch) + fVdb = 0.0; + if (bNoSwitch) + { + for (sal_uLong i = nLoopStart + 1; i <= nLoopEnd; i++) { - for (sal_uLong i = nLoopStart + 1; i <= nLoopEnd; i++) - { - double fTerm = ScGetDDB(fCost, fSalvage, fLife, static_cast<double>(i), fFactor); + double fTerm = ScGetDDB(fCost, fSalvage, fLife, static_cast<double>(i), fFactor); - //respect partial period in the Beginning/ End: - if ( i == nLoopStart+1 ) - fTerm *= ( std::min( fEnd, fIntStart + 1.0 ) - fStart ); - else if ( i == nLoopEnd ) - fTerm *= ( fEnd + 1.0 - fIntEnd ); + //respect partial period in the Beginning/ End: + if ( i == nLoopStart+1 ) + fTerm *= ( std::min( fEnd, fIntStart + 1.0 ) - fStart ); + else if ( i == nLoopEnd ) + fTerm *= ( fEnd + 1.0 - fIntEnd ); - fVdb += fTerm; - } + fVdb += fTerm; } - else + } + else + { + double fPart = 0.0; + // respect partial period in the Beginning / End: + if ( !::rtl::math::approxEqual( fStart, fIntStart ) || + !::rtl::math::approxEqual( fEnd, fIntEnd ) ) { - double fPart = 0.0; - // respect partial period in the Beginning / End: - if ( !::rtl::math::approxEqual( fStart, fIntStart ) || - !::rtl::math::approxEqual( fEnd, fIntEnd ) ) + if ( !::rtl::math::approxEqual( fStart, fIntStart ) ) { - if ( !::rtl::math::approxEqual( fStart, fIntStart ) ) - { - // part to be subtracted at the beginning - double fTempIntEnd = fIntStart + 1.0; - double fTempValue = fCost - - ScInterVDB( fCost, fSalvage, fLife, fLife, fIntStart, fFactor ); - fPart += ( fStart - fIntStart ) * - ScInterVDB( fTempValue, fSalvage, fLife, fLife - fIntStart, - fTempIntEnd - fIntStart, fFactor); - } - if ( !::rtl::math::approxEqual( fEnd, fIntEnd ) ) - { - // part to be subtracted at the end - double fTempIntStart = fIntEnd - 1.0; - double fTempValue = fCost - - ScInterVDB( fCost, fSalvage, fLife, fLife, fTempIntStart, fFactor ); - fPart += ( fIntEnd - fEnd ) * - ScInterVDB( fTempValue, fSalvage, fLife, fLife - fTempIntStart, - fIntEnd - fTempIntStart, fFactor); - } + // part to be subtracted at the beginning + double fTempIntEnd = fIntStart + 1.0; + double fTempValue = fCost - + ScInterVDB( fCost, fSalvage, fLife, fLife, fIntStart, fFactor ); + fPart += ( fStart - fIntStart ) * + ScInterVDB( fTempValue, fSalvage, fLife, fLife - fIntStart, + fTempIntEnd - fIntStart, fFactor); + } + if ( !::rtl::math::approxEqual( fEnd, fIntEnd ) ) + { + // part to be subtracted at the end + double fTempIntStart = fIntEnd - 1.0; + double fTempValue = fCost - + ScInterVDB( fCost, fSalvage, fLife, fLife, fTempIntStart, fFactor ); + fPart += ( fIntEnd - fEnd ) * + ScInterVDB( fTempValue, fSalvage, fLife, fLife - fTempIntStart, + fIntEnd - fTempIntStart, fFactor); } - // calculate depreciation for whole periods - fCost -= ScInterVDB( fCost, fSalvage, fLife, fLife, fIntStart, fFactor ); - fVdb = ScInterVDB( fCost, fSalvage, fLife, fLife - fIntStart, - fIntEnd - fIntStart, fFactor); - fVdb -= fPart; } + // calculate depreciation for whole periods + fCost -= ScInterVDB( fCost, fSalvage, fLife, fLife, fIntStart, fFactor ); + fVdb = ScInterVDB( fCost, fSalvage, fLife, fLife - fIntStart, + fIntEnd - fIntStart, fFactor); + fVdb -= fPart; } - PushDouble(fVdb); } + PushDouble(fVdb); } void ScInterpreter::ScPDuration() @@ -2269,104 +2269,104 @@ void ScInterpreter::ScPpmt() void ScInterpreter::ScCumIpmt() { nFuncFmtType = SvNumFormatType::CURRENCY; - if ( MustHaveParamCount( GetByte(), 6 ) ) - { - double fRate, fNper, fPv, fStart, fEnd; - double fFlag = GetDoubleWithDefault( -1.0 ); - fEnd = ::rtl::math::approxFloor(GetDouble()); - fStart = ::rtl::math::approxFloor(GetDouble()); - fPv = GetDouble(); - fNper = GetDouble(); - fRate = GetDouble(); - if (fStart < 1.0 || fEnd < fStart || fRate <= 0.0 || - fEnd > fNper || fNper <= 0.0 || fPv <= 0.0 || - ( fFlag != 0.0 && fFlag != 1.0 )) - PushIllegalArgument(); - else + if ( !MustHaveParamCount( GetByte(), 6 ) ) + return; + + double fRate, fNper, fPv, fStart, fEnd; + double fFlag = GetDoubleWithDefault( -1.0 ); + fEnd = ::rtl::math::approxFloor(GetDouble()); + fStart = ::rtl::math::approxFloor(GetDouble()); + fPv = GetDouble(); + fNper = GetDouble(); + fRate = GetDouble(); + if (fStart < 1.0 || fEnd < fStart || fRate <= 0.0 || + fEnd > fNper || fNper <= 0.0 || fPv <= 0.0 || + ( fFlag != 0.0 && fFlag != 1.0 )) + PushIllegalArgument(); + else + { + bool bPayInAdvance = static_cast<bool>(fFlag); + sal_uLong nStart = static_cast<sal_uLong>(fStart); + sal_uLong nEnd = static_cast<sal_uLong>(fEnd) ; + double fPmt = ScGetPMT(fRate, fNper, fPv, 0.0, bPayInAdvance); + double fIpmt = 0.0; + if (nStart == 1) { - bool bPayInAdvance = static_cast<bool>(fFlag); - sal_uLong nStart = static_cast<sal_uLong>(fStart); - sal_uLong nEnd = static_cast<sal_uLong>(fEnd) ; - double fPmt = ScGetPMT(fRate, fNper, fPv, 0.0, bPayInAdvance); - double fIpmt = 0.0; - if (nStart == 1) - { - if (!bPayInAdvance) - fIpmt = -fPv; - nStart++; - } - for (sal_uLong i = nStart; i <= nEnd; i++) - { - if (bPayInAdvance) - fIpmt += ScGetFV(fRate, static_cast<double>(i-2), fPmt, fPv, true) - fPmt; - else - fIpmt += ScGetFV(fRate, static_cast<double>(i-1), fPmt, fPv, false); - } - fIpmt *= fRate; - PushDouble(fIpmt); + if (!bPayInAdvance) + fIpmt = -fPv; + nStart++; } + for (sal_uLong i = nStart; i <= nEnd; i++) + { + if (bPayInAdvance) + fIpmt += ScGetFV(fRate, static_cast<double>(i-2), fPmt, fPv, true) - fPmt; + else + fIpmt += ScGetFV(fRate, static_cast<double>(i-1), fPmt, fPv, false); + } + fIpmt *= fRate; + PushDouble(fIpmt); } } void ScInterpreter::ScCumPrinc() { nFuncFmtType = SvNumFormatType::CURRENCY; - if ( MustHaveParamCount( GetByte(), 6 ) ) - { - double fRate, fNper, fPv, fStart, fEnd; - double fFlag = GetDoubleWithDefault( -1.0 ); - fEnd = ::rtl::math::approxFloor(GetDouble()); - fStart = ::rtl::math::approxFloor(GetDouble()); - fPv = GetDouble(); - fNper = GetDouble(); - fRate = GetDouble(); - if (fStart < 1.0 || fEnd < fStart || fRate <= 0.0 || - fEnd > fNper || fNper <= 0.0 || fPv <= 0.0 || - ( fFlag != 0.0 && fFlag != 1.0 )) - PushIllegalArgument(); - else + if ( !MustHaveParamCount( GetByte(), 6 ) ) + return; + + double fRate, fNper, fPv, fStart, fEnd; + double fFlag = GetDoubleWithDefault( -1.0 ); + fEnd = ::rtl::math::approxFloor(GetDouble()); + fStart = ::rtl::math::approxFloor(GetDouble()); + fPv = GetDouble(); + fNper = GetDouble(); + fRate = GetDouble(); + if (fStart < 1.0 || fEnd < fStart || fRate <= 0.0 || + fEnd > fNper || fNper <= 0.0 || fPv <= 0.0 || + ( fFlag != 0.0 && fFlag != 1.0 )) + PushIllegalArgument(); + else + { + bool bPayInAdvance = static_cast<bool>(fFlag); + double fPmt = ScGetPMT(fRate, fNper, fPv, 0.0, bPayInAdvance); + double fPpmt = 0.0; + sal_uLong nStart = static_cast<sal_uLong>(fStart); + sal_uLong nEnd = static_cast<sal_uLong>(fEnd); + if (nStart == 1) { - bool bPayInAdvance = static_cast<bool>(fFlag); - double fPmt = ScGetPMT(fRate, fNper, fPv, 0.0, bPayInAdvance); - double fPpmt = 0.0; - sal_uLong nStart = static_cast<sal_uLong>(fStart); - sal_uLong nEnd = static_cast<sal_uLong>(fEnd); - if (nStart == 1) - { - if (bPayInAdvance) - fPpmt = fPmt; - else - fPpmt = fPmt + fPv * fRate; - nStart++; - } - for (sal_uLong i = nStart; i <= nEnd; i++) - { - if (bPayInAdvance) - fPpmt += fPmt - (ScGetFV(fRate, static_cast<double>(i-2), fPmt, fPv, true) - fPmt) * fRate; - else - fPpmt += fPmt - ScGetFV(fRate, static_cast<double>(i-1), fPmt, fPv, false) * fRate; - } - PushDouble(fPpmt); + if (bPayInAdvance) + fPpmt = fPmt; + else + fPpmt = fPmt + fPv * fRate; + nStart++; } + for (sal_uLong i = nStart; i <= nEnd; i++) + { + if (bPayInAdvance) + fPpmt += fPmt - (ScGetFV(fRate, static_cast<double>(i-2), fPmt, fPv, true) - fPmt) * fRate; + else + fPpmt += fPmt - ScGetFV(fRate, static_cast<double>(i-1), fPmt, fPv, false) * fRate; + } + PushDouble(fPpmt); } } void ScInterpreter::ScEffect() { nFuncFmtType = SvNumFormatType::PERCENT; - if ( MustHaveParamCount( GetByte(), 2 ) ) + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + + double fPeriods = GetDouble(); + double fNominal = GetDouble(); + if (fPeriods < 1.0 || fNominal < 0.0) + PushIllegalArgument(); + else if ( fNominal == 0.0 ) + PushDouble( 0.0 ); + else { - double fPeriods = GetDouble(); - double fNominal = GetDouble(); - if (fPeriods < 1.0 || fNominal < 0.0) - PushIllegalArgument(); - else if ( fNominal == 0.0 ) - PushDouble( 0.0 ); - else - { - fPeriods = ::rtl::math::approxFloor(fPeriods); - PushDouble(pow(1.0 + fNominal/fPeriods, fPeriods) - 1.0); - } + fPeriods = ::rtl::math::approxFloor(fPeriods); + PushDouble(pow(1.0 + fNominal/fPeriods, fPeriods) - 1.0); } } @@ -2389,23 +2389,23 @@ void ScInterpreter::ScNominal() void ScInterpreter::ScMod() { - if ( MustHaveParamCount( GetByte(), 2 ) ) + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + + double fDenom = GetDouble(); // Denominator + if ( fDenom == 0.0 ) { - double fDenom = GetDouble(); // Denominator - if ( fDenom == 0.0 ) - { - PushError(FormulaError::DivisionByZero); - return; - } - double fNum = GetDouble(); // Numerator - double fRes = ::rtl::math::approxSub( fNum, - ::rtl::math::approxFloor( fNum / fDenom ) * fDenom ); - if ( ( fDenom > 0 && fRes >= 0 && fRes < fDenom ) || - ( fDenom < 0 && fRes <= 0 && fRes > fDenom ) ) - PushDouble( fRes ); - else - PushError( FormulaError::NoValue ); + PushError(FormulaError::DivisionByZero); + return; } + double fNum = GetDouble(); // Numerator + double fRes = ::rtl::math::approxSub( fNum, + ::rtl::math::approxFloor( fNum / fDenom ) * fDenom ); + if ( ( fDenom > 0 && fRes >= 0 && fRes < fDenom ) || + ( fDenom < 0 && fRes <= 0 && fRes > fDenom ) ) + PushDouble( fRes ); + else + PushError( FormulaError::NoValue ); } void ScInterpreter::ScIntersect() @@ -2733,388 +2733,388 @@ void ScInterpreter::ScDde() // application, Topic, Item sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 3, 4 ) ) + if ( !MustHaveParamCount( nParamCount, 3, 4 ) ) + return; + + sal_uInt8 nMode = SC_DDE_DEFAULT; + if (nParamCount == 4) { - sal_uInt8 nMode = SC_DDE_DEFAULT; - if (nParamCount == 4) + sal_uInt32 nTmp = GetUInt32(); + if (nGlobalError != FormulaError::NONE || nTmp > SAL_MAX_UINT8) { - sal_uInt32 nTmp = GetUInt32(); - if (nGlobalError != FormulaError::NONE || nTmp > SAL_MAX_UINT8) - { - PushIllegalArgument(); - return; - } - nMode = static_cast<sal_uInt8>(nTmp); + PushIllegalArgument(); + return; } - OUString aItem = GetString().getString(); - OUString aTopic = GetString().getString(); - OUString aAppl = GetString().getString(); + nMode = static_cast<sal_uInt8>(nTmp); + } + OUString aItem = GetString().getString(); + OUString aTopic = GetString().getString(); + OUString aAppl = GetString().getString(); - if (nMode > SC_DDE_TEXT) - nMode = SC_DDE_DEFAULT; + if (nMode > SC_DDE_TEXT) + nMode = SC_DDE_DEFAULT; - // temporary documents (ScFunctionAccess) have no DocShell - // and no LinkManager -> abort + // temporary documents (ScFunctionAccess) have no DocShell + // and no LinkManager -> abort - //sfx2::LinkManager* pLinkMgr = pDok->GetLinkManager(); - if (!mpLinkManager) - { - PushNoValue(); - return; - } + //sfx2::LinkManager* pLinkMgr = pDok->GetLinkManager(); + if (!mpLinkManager) + { + PushNoValue(); + return; + } - // Need to reinterpret after loading (build links) - pArr->AddRecalcMode( ScRecalcMode::ONLOAD_LENIENT ); + // Need to reinterpret after loading (build links) + pArr->AddRecalcMode( ScRecalcMode::ONLOAD_LENIENT ); - // while the link is not evaluated, idle must be disabled (to avoid circular references) + // while the link is not evaluated, idle must be disabled (to avoid circular references) - bool bOldEnabled = pDok->IsIdleEnabled(); - pDok->EnableIdle(false); + bool bOldEnabled = pDok->IsIdleEnabled(); + pDok->EnableIdle(false); - // Get/ Create link object + // Get/ Create link object - ScDdeLink* pLink = lcl_GetDdeLink( mpLinkManager, aAppl, aTopic, aItem, nMode ); + ScDdeLink* pLink = lcl_GetDdeLink( mpLinkManager, aAppl, aTopic, aItem, nMode ); - //TODO: Save Dde-links (in addition) more efficient at document !!!!! - // ScDdeLink* pLink = pDok->GetDdeLink( aAppl, aTopic, aItem ); + //TODO: Save Dde-links (in addition) more efficient at document !!!!! + // ScDdeLink* pLink = pDok->GetDdeLink( aAppl, aTopic, aItem ); - bool bWasError = ( pMyFormulaCell && pMyFormulaCell->GetRawError() != FormulaError::NONE ); + bool bWasError = ( pMyFormulaCell && pMyFormulaCell->GetRawError() != FormulaError::NONE ); - if (!pLink) + if (!pLink) + { + pLink = new ScDdeLink( pDok, aAppl, aTopic, aItem, nMode ); + mpLinkManager->InsertDDELink( pLink, aAppl, aTopic, aItem ); + if ( mpLinkManager->GetLinks().size() == 1 ) // the first one? { - pLink = new ScDdeLink( pDok, aAppl, aTopic, aItem, nMode ); - mpLinkManager->InsertDDELink( pLink, aAppl, aTopic, aItem ); - if ( mpLinkManager->GetLinks().size() == 1 ) // the first one? - { - SfxBindings* pBindings = pDok->GetViewBindings(); - if (pBindings) - pBindings->Invalidate( SID_LINKS ); // Link-Manager enabled - } - - //if the document was just loaded, but the ScDdeLink entry was missing, then - //don't update this link until the links are updated in response to the users - //decision - if (!pDok->HasLinkFormulaNeedingCheck()) - { - //TODO: evaluate asynchron ??? - pLink->TryUpdate(); // TryUpdate doesn't call Update multiple times - } + SfxBindings* pBindings = pDok->GetViewBindings(); + if (pBindings) + pBindings->Invalidate( SID_LINKS ); // Link-Manager enabled + } - if (pMyFormulaCell) - { - // StartListening after the Update to avoid circular references - pMyFormulaCell->StartListening( *pLink ); - } + //if the document was just loaded, but the ScDdeLink entry was missing, then + //don't update this link until the links are updated in response to the users + //decision + if (!pDok->HasLinkFormulaNeedingCheck()) + { + //TODO: evaluate asynchron ??? + pLink->TryUpdate(); // TryUpdate doesn't call Update multiple times } - else + + if (pMyFormulaCell) { - if (pMyFormulaCell) - pMyFormulaCell->StartListening( *pLink ); + // StartListening after the Update to avoid circular references + pMyFormulaCell->StartListening( *pLink ); } + } + else + { + if (pMyFormulaCell) + pMyFormulaCell->StartListening( *pLink ); + } - // If a new Error from Reschedule appears when the link is executed then reset the errorflag + // If a new Error from Reschedule appears when the link is executed then reset the errorflag - if ( pMyFormulaCell && pMyFormulaCell->GetRawError() != FormulaError::NONE && !bWasError ) - pMyFormulaCell->SetErrCode(FormulaError::NONE); + if ( pMyFormulaCell && pMyFormulaCell->GetRawError() != FormulaError::NONE && !bWasError ) + pMyFormulaCell->SetErrCode(FormulaError::NONE); - // check the value + // check the value - const ScMatrix* pLinkMat = pLink->GetResult(); - if (pLinkMat) + const ScMatrix* pLinkMat = pLink->GetResult(); + if (pLinkMat) + { + SCSIZE nC, nR; + pLinkMat->GetDimensions(nC, nR); + ScMatrixRef pNewMat = GetNewMat( nC, nR); + if (pNewMat) { - SCSIZE nC, nR; - pLinkMat->GetDimensions(nC, nR); - ScMatrixRef pNewMat = GetNewMat( nC, nR); - if (pNewMat) - { - pLinkMat->MatCopy(*pNewMat); // copy - PushMatrix( pNewMat ); - } - else - PushIllegalArgument(); + pLinkMat->MatCopy(*pNewMat); // copy + PushMatrix( pNewMat ); } else - PushNA(); - - pDok->EnableIdle(bOldEnabled); - mpLinkManager->CloseCachedComps(); + PushIllegalArgument(); } + else + PushNA(); + + pDok->EnableIdle(bOldEnabled); + mpLinkManager->CloseCachedComps(); } void ScInterpreter::ScBase() { // Value, Base [, MinLen] sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 2, 3 ) ) - { - static const sal_Unicode pDigits[] = { - '0','1','2','3','4','5','6','7','8','9', - 'A','B','C','D','E','F','G','H','I','J','K','L','M', - 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z', - 0 - }; - static const int nDigits = SAL_N_ELEMENTS(pDigits) - 1; - sal_Int32 nMinLen; - if ( nParamCount == 3 ) - { - double fLen = ::rtl::math::approxFloor( GetDouble() ); - if ( 1.0 <= fLen && fLen < SAL_MAX_UINT16 ) - nMinLen = static_cast<sal_Int32>(fLen); - else if ( fLen == 0.0 ) - nMinLen = 1; - else - nMinLen = 0; // Error - } - else + if ( !MustHaveParamCount( nParamCount, 2, 3 ) ) + return; + + static const sal_Unicode pDigits[] = { + '0','1','2','3','4','5','6','7','8','9', + 'A','B','C','D','E','F','G','H','I','J','K','L','M', + 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z', + 0 + }; + static const int nDigits = SAL_N_ELEMENTS(pDigits) - 1; + sal_Int32 nMinLen; + if ( nParamCount == 3 ) + { + double fLen = ::rtl::math::approxFloor( GetDouble() ); + if ( 1.0 <= fLen && fLen < SAL_MAX_UINT16 ) + nMinLen = static_cast<sal_Int32>(fLen); + else if ( fLen == 0.0 ) nMinLen = 1; - double fBase = ::rtl::math::approxFloor( GetDouble() ); - double fVal = ::rtl::math::approxFloor( GetDouble() ); - double fChars = ((fVal > 0.0 && fBase > 0.0) ? - (ceil( log( fVal ) / log( fBase ) ) + 2.0) : - 2.0); - if ( fChars >= SAL_MAX_UINT16 ) + else nMinLen = 0; // Error - - if ( nGlobalError == FormulaError::NONE && nMinLen && 2 <= fBase && fBase <= nDigits && 0 <= fVal ) - { - const sal_Int32 nConstBuf = 128; - sal_Unicode aBuf[nConstBuf]; - sal_Int32 nBuf = std::max<sal_Int32>( fChars, nMinLen + 1 ); - sal_Unicode* pBuf = (nBuf <= nConstBuf ? aBuf : new sal_Unicode[nBuf]); - for ( sal_Int32 j = 0; j < nBuf; ++j ) + } + else + nMinLen = 1; + double fBase = ::rtl::math::approxFloor( GetDouble() ); + double fVal = ::rtl::math::approxFloor( GetDouble() ); + double fChars = ((fVal > 0.0 && fBase > 0.0) ? + (ceil( log( fVal ) / log( fBase ) ) + 2.0) : + 2.0); + if ( fChars >= SAL_MAX_UINT16 ) + nMinLen = 0; // Error + + if ( nGlobalError == FormulaError::NONE && nMinLen && 2 <= fBase && fBase <= nDigits && 0 <= fVal ) + { + const sal_Int32 nConstBuf = 128; + sal_Unicode aBuf[nConstBuf]; + sal_Int32 nBuf = std::max<sal_Int32>( fChars, nMinLen + 1 ); + sal_Unicode* pBuf = (nBuf <= nConstBuf ? aBuf : new sal_Unicode[nBuf]); + for ( sal_Int32 j = 0; j < nBuf; ++j ) + { + pBuf[j] = '0'; + } + sal_Unicode* p = pBuf + nBuf - 1; + *p = 0; + if ( o3tl::convertsToAtMost(fVal, sal_uLong(~0)) ) + { + sal_uLong nVal = static_cast<sal_uLong>(fVal); + sal_uLong nBase = static_cast<sal_uLong>(fBase); + while ( nVal && p > pBuf ) { - pBuf[j] = '0'; + *--p = pDigits[ nVal % nBase ]; + nVal /= nBase; } - sal_Unicode* p = pBuf + nBuf - 1; - *p = 0; - if ( o3tl::convertsToAtMost(fVal, sal_uLong(~0)) ) - { - sal_uLong nVal = static_cast<sal_uLong>(fVal); - sal_uLong nBase = static_cast<sal_uLong>(fBase); - while ( nVal && p > pBuf ) - { - *--p = pDigits[ nVal % nBase ]; - nVal /= nBase; - } - fVal = static_cast<double>(nVal); - } - else + fVal = static_cast<double>(nVal); + } + else + { + bool bDirt = false; + while ( fVal && p > pBuf ) { - bool bDirt = false; - while ( fVal && p > pBuf ) - { //TODO: roundoff error starting with numbers greater than 2**48 // double fDig = ::rtl::math::approxFloor( fmod( fVal, fBase ) ); // a little bit better: - double fInt = ::rtl::math::approxFloor( fVal / fBase ); - double fMult = fInt * fBase; + double fInt = ::rtl::math::approxFloor( fVal / fBase ); + double fMult = fInt * fBase; #if 0 - // =BASIS(1e308;36) => GPF with - // nDig = (size_t) ::rtl::math::approxFloor( fVal - fMult ); - // in spite off previous test if fVal >= fMult - double fDebug1 = fVal - fMult; - // fVal := 7,5975311883090e+290 - // fMult := 7,5975311883090e+290 - // fDebug1 := 1,3848924157003e+275 <- RoundOff-Error - // fVal != fMult, aber: ::rtl::math::approxEqual( fVal, fMult ) == TRUE - double fDebug2 = ::rtl::math::approxSub( fVal, fMult ); - // and ::rtl::math::approxSub( fVal, fMult ) == 0 - double fDebug3 = ( fInt ? fVal / fInt : 0.0 ); - - // Actual after strange fDebug1 and fVal < fMult is fDebug2 == fBase, but - // anyway it can't be compared, then bDirt is executed an everything is good... - - // prevent compiler warnings - (void)fDebug1; (void)fDebug2; (void)fDebug3; + // =BASIS(1e308;36) => GPF with + // nDig = (size_t) ::rtl::math::approxFloor( fVal - fMult ); + // in spite off previous test if fVal >= fMult + double fDebug1 = fVal - fMult; + // fVal := 7,5975311883090e+290 + // fMult := 7,5975311883090e+290 + // fDebug1 := 1,3848924157003e+275 <- RoundOff-Error + // fVal != fMult, aber: ::rtl::math::approxEqual( fVal, fMult ) == TRUE + double fDebug2 = ::rtl::math::approxSub( fVal, fMult ); + // and ::rtl::math::approxSub( fVal, fMult ) == 0 + double fDebug3 = ( fInt ? fVal / fInt : 0.0 ); + + // Actual after strange fDebug1 and fVal < fMult is fDebug2 == fBase, but + // anyway it can't be compared, then bDirt is executed an everything is good... + + // prevent compiler warnings + (void)fDebug1; (void)fDebug2; (void)fDebug3; #endif - size_t nDig; - if ( fVal < fMult ) - { // something is wrong there - bDirt = true; - nDig = 0; - } - else + size_t nDig; + if ( fVal < fMult ) + { // something is wrong there + bDirt = true; + nDig = 0; + } + else + { + double fDig = ::rtl::math::approxFloor( ::rtl::math::approxSub( fVal, fMult ) ); + if ( bDirt ) { - double fDig = ::rtl::math::approxFloor( ::rtl::math::approxSub( fVal, fMult ) ); - if ( bDirt ) - { - bDirt = false; - --fDig; - } - if ( fDig <= 0.0 ) - nDig = 0; - else if ( fDig >= fBase ) - nDig = static_cast<size_t>(fBase) - 1; - else - nDig = static_cast<size_t>(fDig); + bDirt = false; + --fDig; } - *--p = pDigits[ nDig ]; - fVal = fInt; + if ( fDig <= 0.0 ) + nDig = 0; + else if ( fDig >= fBase ) + nDig = static_cast<size_t>(fBase) - 1; + else + nDig = static_cast<size_t>(fDig); } + *--p = pDigits[ nDig ]; + fVal = fInt; } - if ( fVal ) - PushError( FormulaError::StringOverflow ); - else - { - if ( nBuf - (p - pBuf) <= nMinLen ) - p = pBuf + nBuf - 1 - nMinLen; - PushStringBuffer( p ); - } - if ( pBuf != aBuf ) - delete [] pBuf; } + if ( fVal ) + PushError( FormulaError::StringOverflow ); else - PushIllegalArgument(); + { + if ( nBuf - (p - pBuf) <= nMinLen ) + p = pBuf + nBuf - 1 - nMinLen; + PushStringBuffer( p ); + } + if ( pBuf != aBuf ) + delete [] pBuf; } + else + PushIllegalArgument(); } void ScInterpreter::ScDecimal() { // Text, Base - if ( MustHaveParamCount( GetByte(), 2 ) ) + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + + double fBase = ::rtl::math::approxFloor( GetDouble() ); + OUString aStr = GetString().getString(); + if ( nGlobalError == FormulaError::NONE && 2 <= fBase && fBase <= 36 ) { - double fBase = ::rtl::math::approxFloor( GetDouble() ); - OUString aStr = GetString().getString(); - if ( nGlobalError == FormulaError::NONE && 2 <= fBase && fBase <= 36 ) - { - double fVal = 0.0; - int nBase = static_cast<int>(fBase); - const sal_Unicode* p = aStr.getStr(); - while ( *p == ' ' || *p == '\t' ) - p++; // strip leading white space - if ( nBase == 16 ) - { // evtl. hex-prefix stripped - if ( *p == 'x' || *p == 'X' ) - p++; - else if ( *p == '0' && (*(p+1) == 'x' || *(p+1) == 'X') ) - p += 2; - } - while ( *p ) + double fVal = 0.0; + int nBase = static_cast<int>(fBase); + const sal_Unicode* p = aStr.getStr(); + while ( *p == ' ' || *p == '\t' ) + p++; // strip leading white space + if ( nBase == 16 ) + { // evtl. hex-prefix stripped + if ( *p == 'x' || *p == 'X' ) + p++; + else if ( *p == '0' && (*(p+1) == 'x' || *(p+1) == 'X') ) + p += 2; + } + while ( *p ) + { + int n; + if ( '0' <= *p && *p <= '9' ) + n = *p - '0'; + else if ( 'A' <= *p && *p <= 'Z' ) + n = 10 + (*p - 'A'); + else if ( 'a' <= *p && *p <= 'z' ) + n = 10 + (*p - 'a'); + else + n = nBase; + if ( nBase <= n ) { - int n; - if ( '0' <= *p && *p <= '9' ) - n = *p - '0'; - else if ( 'A' <= *p && *p <= 'Z' ) - n = 10 + (*p - 'A'); - else if ( 'a' <= *p && *p <= 'z' ) - n = 10 + (*p - 'a'); + if ( *(p+1) == 0 && + ( (nBase == 2 && (*p == 'b' || *p == 'B')) + ||(nBase == 16 && (*p == 'h' || *p == 'H')) ) + ) + ; // 101b and F00Dh are ok else - n = nBase; - if ( nBase <= n ) { - if ( *(p+1) == 0 && - ( (nBase == 2 && (*p == 'b' || *p == 'B')) - ||(nBase == 16 && (*p == 'h' || *p == 'H')) ) - ) - ; // 101b and F00Dh are ok - else - { - PushIllegalArgument(); - return ; - } + PushIllegalArgument(); + return ; } - else - fVal = fVal * fBase + n; - p++; - } - PushDouble( fVal ); + else + fVal = fVal * fBase + n; + p++; + } - else - PushIllegalArgument(); + PushDouble( fVal ); } + else + PushIllegalArgument(); } void ScInterpreter::ScConvertOOo() { // Value, FromUnit, ToUnit - if ( MustHaveParamCount( GetByte(), 3 ) ) + if ( !MustHaveParamCount( GetByte(), 3 ) ) + return; + + OUString aToUnit = GetString().getString(); + OUString aFromUnit = GetString().getString(); + double fVal = GetDouble(); + if ( nGlobalError != FormulaError::NONE ) + PushError( nGlobalError); + else { - OUString aToUnit = GetString().getString(); - OUString aFromUnit = GetString().getString(); - double fVal = GetDouble(); - if ( nGlobalError != FormulaError::NONE ) - PushError( nGlobalError); + // first of all search for the given order; if it can't be found then search for the inverse + double fConv; + if ( ScGlobal::GetUnitConverter()->GetValue( fConv, aFromUnit, aToUnit ) ) + PushDouble( fVal * fConv ); + else if ( ScGlobal::GetUnitConverter()->GetValue( fConv, aToUnit, aFromUnit ) ) + PushDouble( fVal / fConv ); else - { - // first of all search for the given order; if it can't be found then search for the inverse - double fConv; - if ( ScGlobal::GetUnitConverter()->GetValue( fConv, aFromUnit, aToUnit ) ) - PushDouble( fVal * fConv ); - else if ( ScGlobal::GetUnitConverter()->GetValue( fConv, aToUnit, aFromUnit ) ) - PushDouble( fVal / fConv ); - else - PushNA(); - } + PushNA(); } } void ScInterpreter::ScRoman() { // Value [Mode] sal_uInt8 nParamCount = GetByte(); - if( MustHaveParamCount( nParamCount, 1, 2 ) ) + if( !MustHaveParamCount( nParamCount, 1, 2 ) ) + return; + + double fMode = (nParamCount == 2) ? ::rtl::math::approxFloor( GetDouble() ) : 0.0; + double fVal = ::rtl::math::approxFloor( GetDouble() ); + if( nGlobalError != FormulaError::NONE ) + PushError( nGlobalError); + else if( (fMode >= 0.0) && (fMode < 5.0) && (fVal >= 0.0) && (fVal < 4000.0) ) { - double fMode = (nParamCount == 2) ? ::rtl::math::approxFloor( GetDouble() ) : 0.0; - double fVal = ::rtl::math::approxFloor( GetDouble() ); - if( nGlobalError != FormulaError::NONE ) - PushError( nGlobalError); - else if( (fMode >= 0.0) && (fMode < 5.0) && (fVal >= 0.0) && (fVal < 4000.0) ) - { - static const sal_Unicode pChars[] = { 'M', 'D', 'C', 'L', 'X', 'V', 'I' }; - static const sal_uInt16 pValues[] = { 1000, 500, 100, 50, 10, 5, 1 }; - static const sal_uInt16 nMaxIndex = sal_uInt16(SAL_N_ELEMENTS(pValues) - 1); + static const sal_Unicode pChars[] = { 'M', 'D', 'C', 'L', 'X', 'V', 'I' }; + static const sal_uInt16 pValues[] = { 1000, 500, 100, 50, 10, 5, 1 }; + static const sal_uInt16 nMaxIndex = sal_uInt16(SAL_N_ELEMENTS(pValues) - 1); + + OUStringBuffer aRoman; + sal_uInt16 nVal = static_cast<sal_uInt16>(fVal); + sal_uInt16 nMode = static_cast<sal_uInt16>(fMode); - OUStringBuffer aRoman; - sal_uInt16 nVal = static_cast<sal_uInt16>(fVal); - sal_uInt16 nMode = static_cast<sal_uInt16>(fMode); + for( sal_uInt16 i = 0; i <= nMaxIndex / 2; i++ ) + { + sal_uInt16 nIndex = 2 * i; + sal_uInt16 nDigit = nVal / pValues[ nIndex ]; - for( sal_uInt16 i = 0; i <= nMaxIndex / 2; i++ ) + if( (nDigit % 5) == 4 ) { - sal_uInt16 nIndex = 2 * i; - sal_uInt16 nDigit = nVal / pValues[ nIndex ]; + // assert can't happen with nVal<4000 precondition + assert( ((nDigit == 4) ? (nIndex >= 1) : (nIndex >= 2))); - if( (nDigit % 5) == 4 ) + sal_uInt16 nIndex2 = (nDigit == 4) ? nIndex - 1 : nIndex - 2; + sal_uInt16 nSteps = 0; + while( (nSteps < nMode) && (nIndex < nMaxIndex) ) + { + nSteps++; + if( pValues[ nIndex2 ] - pValues[ nIndex + 1 ] <= nVal ) + nIndex++; + else + nSteps = nMode; + } + aRoman.append( pChars[ nIndex ] ).append( pChars[ nIndex2 ] ); + nVal = sal::static_int_cast<sal_uInt16>( nVal + pValues[ nIndex ] ); + nVal = sal::static_int_cast<sal_uInt16>( nVal - pValues[ nIndex2 ] ); + } + else + { + if( nDigit > 4 ) { // assert can't happen with nVal<4000 precondition - assert( ((nDigit == 4) ? (nIndex >= 1) : (nIndex >= 2))); - - sal_uInt16 nIndex2 = (nDigit == 4) ? nIndex - 1 : nIndex - 2; - sal_uInt16 nSteps = 0; - while( (nSteps < nMode) && (nIndex < nMaxIndex) ) - { - nSteps++; - if( pValues[ nIndex2 ] - pValues[ nIndex + 1 ] <= nVal ) - nIndex++; - else - nSteps = nMode; - } - aRoman.append( pChars[ nIndex ] ).append( pChars[ nIndex2 ] ); - nVal = sal::static_int_cast<sal_uInt16>( nVal + pValues[ nIndex ] ); - nVal = sal::static_int_cast<sal_uInt16>( nVal - pValues[ nIndex2 ] ); + assert( nIndex >= 1 ); + aRoman.append( pChars[ nIndex - 1 ] ); } - else + sal_Int32 nPad = nDigit % 5; + if (nPad) { - if( nDigit > 4 ) - { - // assert can't happen with nVal<4000 precondition - assert( nIndex >= 1 ); - aRoman.append( pChars[ nIndex - 1 ] ); - } - sal_Int32 nPad = nDigit % 5; - if (nPad) - { - OUStringBuffer aBuf(aRoman); - comphelper::string::padToLength(aBuf, aBuf.getLength() + nPad, - pChars[nIndex]); - aRoman = aBuf.makeStringAndClear(); - } - nVal %= pValues[ nIndex ]; + OUStringBuffer aBuf(aRoman); + comphelper::string::padToLength(aBuf, aBuf.getLength() + nPad, + pChars[nIndex]); + aRoman = aBuf.makeStringAndClear(); } + nVal %= pValues[ nIndex ]; } - - PushString( aRoman.makeStringAndClear() ); } - else - PushIllegalArgument(); + + PushString( aRoman.makeStringAndClear() ); } + else + PushIllegalArgument(); } static bool lcl_GetArabicValue( sal_Unicode cChar, sal_uInt16& rnValue, bool& rbIsDec ) @@ -3193,85 +3193,85 @@ void ScInterpreter::ScArabic() void ScInterpreter::ScHyperLink() { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 1, 2 ) ) - { - double fVal = 0.0; - svl::SharedString aStr; - ScMatValType nResultType = ScMatValType::String; + if ( !MustHaveParamCount( nParamCount, 1, 2 ) ) + return; + + double fVal = 0.0; + svl::SharedString aStr; + ScMatValType nResultType = ScMatValType::String; - if ( nParamCount == 2 ) + if ( nParamCount == 2 ) + { + switch ( GetStackType() ) { - switch ( GetStackType() ) + case svDouble: + fVal = GetDouble(); + nResultType = ScMatValType::Value; + break; + case svString: + aStr = GetString(); + break; + case svSingleRef: + case svDoubleRef: { - case svDouble: - fVal = GetDouble(); - nResultType = ScMatValType::Value; - break; - case svString: - aStr = GetString(); - break; - case svSingleRef: - case svDoubleRef: - { - ScAddress aAdr; - if ( !PopDoubleRefOrSingleRef( aAdr ) ) - break; + ScAddress aAdr; + if ( !PopDoubleRefOrSingleRef( aAdr ) ) + break; - ScRefCellValue aCell(*pDok, aAdr); - if (aCell.hasEmptyValue()) - nResultType = ScMatValType::Empty; - else + ScRefCellValue aCell(*pDok, aAdr); + if (aCell.hasEmptyValue()) + nResultType = ScMatValType::Empty; + else + { + FormulaError nErr = GetCellErrCode(aCell); + if (nErr != FormulaError::NONE) + SetError( nErr); + else if (aCell.hasNumeric()) { - FormulaError nErr = GetCellErrCode(aCell); - if (nErr != FormulaError::NONE) - SetError( nErr); - else if (aCell.hasNumeric()) - { - fVal = GetCellValue(aAdr, aCell); - nResultType = ScMatValType::Value; - } - else - GetCellString(aStr, aCell); + fVal = GetCellValue(aAdr, aCell); + nResultType = ScMatValType::Value; } + else + GetCellString(aStr, aCell); } - break; - case svMatrix: - nResultType = GetDoubleOrStringFromMatrix( fVal, aStr); - break; - case svMissing: - case svEmptyCell: - Pop(); - // mimic xcl - fVal = 0.0; - nResultType = ScMatValType::Value; - break; - default: - PopError(); - SetError( FormulaError::IllegalArgument); } + break; + case svMatrix: + nResultType = GetDoubleOrStringFromMatrix( fVal, aStr); + break; + case svMissing: + case svEmptyCell: + Pop(); + // mimic xcl + fVal = 0.0; + nResultType = ScMatValType::Value; + break; + default: + PopError(); + SetError( FormulaError::IllegalArgument); } - svl::SharedString aUrl = GetString(); - ScMatrixRef pResMat = GetNewMat( 1, 2); - if (nGlobalError != FormulaError::NONE) - { - fVal = CreateDoubleError( nGlobalError); - nResultType = ScMatValType::Value; - } - if (nParamCount == 2 || nGlobalError != FormulaError::NONE) - { - if (ScMatrix::IsValueType( nResultType)) - pResMat->PutDouble( fVal, 0); - else if (ScMatrix::IsRealStringType( nResultType)) - pResMat->PutString(aStr, 0); - else // EmptyType, EmptyPathType, mimic xcl - pResMat->PutDouble( 0.0, 0 ); - } - else - pResMat->PutString(aUrl, 0); - pResMat->PutString(aUrl, 1); - bMatrixFormula = true; - PushMatrix(pResMat); } + svl::SharedString aUrl = GetString(); + ScMatrixRef pResMat = GetNewMat( 1, 2); + if (nGlobalError != FormulaError::NONE) + { + fVal = CreateDoubleError( nGlobalError); + nResultType = ScMatValType::Value; + } + if (nParamCount == 2 || nGlobalError != FormulaError::NONE) + { + if (ScMatrix::IsValueType( nResultType)) + pResMat->PutDouble( fVal, 0); + else if (ScMatrix::IsRealStringType( nResultType)) + pResMat->PutString(aStr, 0); + else // EmptyType, EmptyPathType, mimic xcl + pResMat->PutDouble( 0.0, 0 ); + } + else + pResMat->PutString(aUrl, 0); + pResMat->PutString(aUrl, 1); + bMatrixFormula = true; + PushMatrix(pResMat); } /** Resources at the website of the European Commission: @@ -3322,58 +3322,58 @@ static bool lclConvertMoney( const OUString& aSearchUnit, double& rfRate, int& r void ScInterpreter::ScEuroConvert() { //Value, FromUnit, ToUnit[, FullPrecision, [TriangulationPrecision]] sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 3, 5 ) ) + if ( !MustHaveParamCount( nParamCount, 3, 5 ) ) + return; + + double fPrecision = 0.0; + if ( nParamCount == 5 ) { - double fPrecision = 0.0; - if ( nParamCount == 5 ) + fPrecision = ::rtl::math::approxFloor(GetDouble()); + if ( fPrecision < 3 ) { - fPrecision = ::rtl::math::approxFloor(GetDouble()); - if ( fPrecision < 3 ) - { - PushIllegalArgument(); - return; - } + PushIllegalArgument(); + return; } - bool bFullPrecision = false; - if ( nParamCount >= 4 ) - bFullPrecision = GetBool(); - OUString aToUnit = GetString().getString(); - OUString aFromUnit = GetString().getString(); - double fVal = GetDouble(); - if ( nGlobalError != FormulaError::NONE ) - PushError( nGlobalError); - else + } + bool bFullPrecision = false; + if ( nParamCount >= 4 ) + bFullPrecision = GetBool(); + OUString aToUnit = GetString().getString(); + OUString aFromUnit = GetString().getString(); + double fVal = GetDouble(); + if ( nGlobalError != FormulaError::NONE ) + PushError( nGlobalError); + else + { + double fFromRate; + double fToRate; + int nFromDec; + int nToDec; + if ( lclConvertMoney( aFromUnit, fFromRate, nFromDec ) + && lclConvertMoney( aToUnit, fToRate, nToDec ) ) { - double fFromRate; - double fToRate; - int nFromDec; - int nToDec; - if ( lclConvertMoney( aFromUnit, fFromRate, nFromDec ) - && lclConvertMoney( aToUnit, fToRate, nToDec ) ) + double fRes; + if ( aFromUnit.equalsIgnoreAsciiCase( aToUnit ) ) + fRes = fVal; + else { - double fRes; - if ( aFromUnit.equalsIgnoreAsciiCase( aToUnit ) ) - fRes = fVal; + if ( aFromUnit.equalsIgnoreAsciiCase( "EUR" ) ) + fRes = fVal * fToRate; else { - if ( aFromUnit.equalsIgnoreAsciiCase( "EUR" ) ) - fRes = fVal * fToRate; - else - { - double fIntermediate = fVal / fFromRate; - if ( fPrecision ) - fIntermediate = ::rtl::math::round( fIntermediate, - static_cast<int>(fPrecision) ); - fRes = fIntermediate * fToRate; - } - if ( !bFullPrecision ) - fRes = ::rtl::math::round( fRes, nToDec ); + double fIntermediate = fVal / fFromRate; + if ( fPrecision ) + fIntermediate = ::rtl::math::round( fIntermediate, + static_cast<int>(fPrecision) ); + fRes = fIntermediate * fToRate; } - PushDouble( fRes ); + if ( !bFullPrecision ) + fRes = ::rtl::math::round( fRes, nToDec ); } - else - PushIllegalArgument(); + PushDouble( fRes ); } + else + PushIllegalArgument(); } } @@ -3470,23 +3470,23 @@ void lclAppendBlock( OStringBuffer& rText, sal_Int32 nValue ) lclAppendPow10( rText, nValue / 100, 2 ); nValue %= 100; } - if( nValue > 0 ) + if( nValue <= 0 ) + return; + + sal_Int32 nTen = nValue / 10; + sal_Int32 nOne = nValue % 10; + if( nTen >= 1 ) { - sal_Int32 nTen = nValue / 10; - sal_Int32 nOne = nValue % 10; - if( nTen >= 1 ) - { - if( nTen >= 3 ) - lclAppendDigit( rText, nTen ); - else if( nTen == 2 ) - rText.append( UTF8_TH_20 ); - rText.append( UTF8_TH_10 ); - } - if( (nTen > 0) && (nOne == 1) ) - rText.append( UTF8_TH_11 ); - else if( nOne > 0 ) - lclAppendDigit( rText, nOne ); + if( nTen >= 3 ) + lclAppendDigit( rText, nTen ); + else if( nTen == 2 ) + rText.append( UTF8_TH_20 ); + rText.append( UTF8_TH_10 ); } + if( (nTen > 0) && (nOne == 1) ) + rText.append( UTF8_TH_11 ); + else if( nOne > 0 ) + lclAppendDigit( rText, nOne ); } } // namespace @@ -3494,68 +3494,68 @@ void lclAppendBlock( OStringBuffer& rText, sal_Int32 nValue ) void ScInterpreter::ScBahtText() { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 1 ) ) - { - double fValue = GetDouble(); - if( nGlobalError != FormulaError::NONE ) - { - PushError( nGlobalError); - return; - } - - // sign - bool bMinus = fValue < 0.0; - fValue = fabs( fValue ); + if ( !MustHaveParamCount( nParamCount, 1 ) ) + return; - // round to 2 digits after decimal point, fValue contains Satang as integer - fValue = ::rtl::math::approxFloor( fValue * 100.0 + 0.5 ); + double fValue = GetDouble(); + if( nGlobalError != FormulaError::NONE ) + { + PushError( nGlobalError); + return; + } - // split Baht and Satang - double fBaht = 0.0; - sal_Int32 nSatang = 0; - lclSplitBlock( fBaht, nSatang, fValue, 100.0 ); + // sign + bool bMinus = fValue < 0.0; + fValue = fabs( fValue ); - OStringBuffer aText; + // round to 2 digits after decimal point, fValue contains Satang as integer + fValue = ::rtl::math::approxFloor( fValue * 100.0 + 0.5 ); - // generate text for Baht value - if( fBaht == 0.0 ) - { - if( nSatang == 0 ) - aText.append( UTF8_TH_0 ); - } - else while( fBaht > 0.0 ) - { - OStringBuffer aBlock; - sal_Int32 nBlock = 0; - lclSplitBlock( fBaht, nBlock, fBaht, 1.0e6 ); - if( nBlock > 0 ) - lclAppendBlock( aBlock, nBlock ); - // add leading "million", if there will come more blocks - if( fBaht > 0.0 ) - aBlock.insert( 0, UTF8_TH_1E6 ); + // split Baht and Satang + double fBaht = 0.0; + sal_Int32 nSatang = 0; + lclSplitBlock( fBaht, nSatang, fValue, 100.0 ); - aText.insert(0, aBlock.makeStringAndClear()); - } - if (!aText.isEmpty()) - aText.append( UTF8_TH_BAHT ); + OStringBuffer aText; - // generate text for Satang value + // generate text for Baht value + if( fBaht == 0.0 ) + { if( nSatang == 0 ) - { - aText.append( UTF8_TH_DOT0 ); - } - else - { - lclAppendBlock( aText, nSatang ); - aText.append( UTF8_TH_SATANG ); - } + aText.append( UTF8_TH_0 ); + } + else while( fBaht > 0.0 ) + { + OStringBuffer aBlock; + sal_Int32 nBlock = 0; + lclSplitBlock( fBaht, nBlock, fBaht, 1.0e6 ); + if( nBlock > 0 ) + lclAppendBlock( aBlock, nBlock ); + // add leading "million", if there will come more blocks + if( fBaht > 0.0 ) + aBlock.insert( 0, UTF8_TH_1E6 ); - // add the minus sign - if( bMinus ) - aText.insert( 0, UTF8_TH_MINUS ); + aText.insert(0, aBlock.makeStringAndClear()); + } + if (!aText.isEmpty()) + aText.append( UTF8_TH_BAHT ); - PushString( OStringToOUString(aText.makeStringAndClear(), RTL_TEXTENCODING_UTF8) ); + // generate text for Satang value + if( nSatang == 0 ) + { + aText.append( UTF8_TH_DOT0 ); + } + else + { + lclAppendBlock( aText, nSatang ); + aText.append( UTF8_TH_SATANG ); } + + // add the minus sign + if( bMinus ) + aText.insert( 0, UTF8_TH_MINUS ); + + PushString( OStringToOUString(aText.makeStringAndClear(), RTL_TEXTENCODING_UTF8) ); } void ScInterpreter::ScGetPivotData() diff --git a/sc/source/core/tool/interpr3.cxx b/sc/source/core/tool/interpr3.cxx index 994d821f6d80..c558f97fbe80 100644 --- a/sc/source/core/tool/interpr3.cxx +++ b/sc/source/core/tool/interpr3.cxx @@ -1195,21 +1195,21 @@ void ScInterpreter::ScCombinA() void ScInterpreter::ScPermut() { - if ( MustHaveParamCount( GetByte(), 2 ) ) + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + + double k = ::rtl::math::approxFloor(GetDouble()); + double n = ::rtl::math::approxFloor(GetDouble()); + if (n < 0.0 || k < 0.0 || k > n) + PushIllegalArgument(); + else if (k == 0.0) + PushInt(1); // (n! / (n - 0)!) == 1 + else { - double k = ::rtl::math::approxFloor(GetDouble()); - double n = ::rtl::math::approxFloor(GetDouble()); - if (n < 0.0 || k < 0.0 || k > n) - PushIllegalArgument(); - else if (k == 0.0) - PushInt(1); // (n! / (n - 0)!) == 1 - else - { - double nVal = n; - for (sal_uLong i = static_cast<sal_uLong>(k)-1; i >= 1; i--) - nVal *= n-static_cast<double>(i); - PushDouble(nVal); - } + double nVal = n; + for (sal_uLong i = static_cast<sal_uLong>(k)-1; i >= 1; i--) + nVal *= n-static_cast<double>(i); + PushDouble(nVal); } } @@ -1343,157 +1343,157 @@ void ScInterpreter::ScB() void ScInterpreter::ScBinomDist() { - if ( MustHaveParamCount( GetByte(), 4 ) ) + if ( !MustHaveParamCount( GetByte(), 4 ) ) + return; + + bool bIsCum = GetBool(); // false=mass function; true=cumulative + double p = GetDouble(); + double n = ::rtl::math::approxFloor(GetDouble()); + double x = ::rtl::math::approxFloor(GetDouble()); + double q = (0.5 - p) + 0.5; // get one bit more for p near 1.0 + if (n < 0.0 || x < 0.0 || x > n || p < 0.0 || p > 1.0) { - bool bIsCum = GetBool(); // false=mass function; true=cumulative - double p = GetDouble(); - double n = ::rtl::math::approxFloor(GetDouble()); - double x = ::rtl::math::approxFloor(GetDouble()); - double q = (0.5 - p) + 0.5; // get one bit more for p near 1.0 - if (n < 0.0 || x < 0.0 || x > n || p < 0.0 || p > 1.0) - { - PushIllegalArgument(); - return; - } - if ( p == 0.0) - { - PushDouble( (x==0.0 || bIsCum) ? 1.0 : 0.0 ); - return; - } - if ( p == 1.0) - { - PushDouble( (x==n) ? 1.0 : 0.0); - return; - } - if (!bIsCum) - PushDouble( GetBinomDistPMF(x,n,p)); + PushIllegalArgument(); + return; + } + if ( p == 0.0) + { + PushDouble( (x==0.0 || bIsCum) ? 1.0 : 0.0 ); + return; + } + if ( p == 1.0) + { + PushDouble( (x==n) ? 1.0 : 0.0); + return; + } + if (!bIsCum) + PushDouble( GetBinomDistPMF(x,n,p)); + else + { + if (x == n) + PushDouble(1.0); else { - if (x == n) - PushDouble(1.0); - else + double fFactor = pow(q, n); + if (x == 0.0) + PushDouble(fFactor); + else if (fFactor <= ::std::numeric_limits<double>::min()) { - double fFactor = pow(q, n); - if (x == 0.0) - PushDouble(fFactor); - else if (fFactor <= ::std::numeric_limits<double>::min()) + fFactor = pow(p, n); + if (fFactor <= ::std::numeric_limits<double>::min()) + PushDouble(GetBetaDist(q,n-x,x+1.0)); + else { - fFactor = pow(p, n); - if (fFactor <= ::std::numeric_limits<double>::min()) - PushDouble(GetBetaDist(q,n-x,x+1.0)); - else + if (fFactor > fMachEps) { - if (fFactor > fMachEps) + double fSum = 1.0 - fFactor; + sal_uInt32 max = static_cast<sal_uInt32> (n - x) - 1; + for (sal_uInt32 i = 0; i < max && fFactor > 0.0; i++) { - double fSum = 1.0 - fFactor; - sal_uInt32 max = static_cast<sal_uInt32> (n - x) - 1; - for (sal_uInt32 i = 0; i < max && fFactor > 0.0; i++) - { - fFactor *= (n-i)/(i+1)*q/p; - fSum -= fFactor; - } - PushDouble( (fSum < 0.0) ? 0.0 : fSum ); + fFactor *= (n-i)/(i+1)*q/p; + fSum -= fFactor; } - else - PushDouble(lcl_GetBinomDistRange(n,n-x,n,fFactor,q,p)); + PushDouble( (fSum < 0.0) ? 0.0 : fSum ); } + else + PushDouble(lcl_GetBinomDistRange(n,n-x,n,fFactor,q,p)); } - else - PushDouble( lcl_GetBinomDistRange(n,0.0,x,fFactor,p,q)) ; } + else + PushDouble( lcl_GetBinomDistRange(n,0.0,x,fFactor,p,q)) ; } } } void ScInterpreter::ScCritBinom() { - if ( MustHaveParamCount( GetByte(), 3 ) ) + if ( !MustHaveParamCount( GetByte(), 3 ) ) + return; + + double alpha = GetDouble(); + double p = GetDouble(); + double n = ::rtl::math::approxFloor(GetDouble()); + if (n < 0.0 || alpha < 0.0 || alpha > 1.0 || p < 0.0 || p > 1.0) + PushIllegalArgument(); + else if ( alpha == 0.0 ) + PushDouble( 0.0 ); + else if ( alpha == 1.0 ) + PushDouble( p == 0 ? 0.0 : n ); + else { - double alpha = GetDouble(); - double p = GetDouble(); - double n = ::rtl::math::approxFloor(GetDouble()); - if (n < 0.0 || alpha < 0.0 || alpha > 1.0 || p < 0.0 || p > 1.0) - PushIllegalArgument(); - else if ( alpha == 0.0 ) - PushDouble( 0.0 ); - else if ( alpha == 1.0 ) - PushDouble( p == 0 ? 0.0 : n ); - else + double fFactor; + double q = (0.5 - p) + 0.5; // get one bit more for p near 1.0 + if ( q > p ) // work from the side where the cumulative curve is { - double fFactor; - double q = (0.5 - p) + 0.5; // get one bit more for p near 1.0 - if ( q > p ) // work from the side where the cumulative curve is + // work from 0 upwards + fFactor = pow(q,n); + if (fFactor > ::std::numeric_limits<double>::min()) { - // work from 0 upwards - fFactor = pow(q,n); - if (fFactor > ::std::numeric_limits<double>::min()) + double fSum = fFactor; + sal_uInt32 max = static_cast<sal_uInt32> (n), i; + for (i = 0; i < max && fSum < alpha; i++) { - double fSum = fFactor; - sal_uInt32 max = static_cast<sal_uInt32> (n), i; - for (i = 0; i < max && fSum < alpha; i++) - { - fFactor *= (n-i)/(i+1)*p/q; - fSum += fFactor; - } - PushDouble(i); + fFactor *= (n-i)/(i+1)*p/q; + fSum += fFactor; } - else + PushDouble(i); + } + else + { + // accumulate BinomDist until accumulated BinomDist reaches alpha + double fSum = 0.0; + sal_uInt32 max = static_cast<sal_uInt32> (n), i; + for (i = 0; i < max && fSum < alpha; i++) { - // accumulate BinomDist until accumulated BinomDist reaches alpha - double fSum = 0.0; - sal_uInt32 max = static_cast<sal_uInt32> (n), i; - for (i = 0; i < max && fSum < alpha; i++) + const double x = GetBetaDistPDF( p, ( i + 1 ), ( n - i + 1 ) )/( n + 1 ); + if ( nGlobalError == FormulaError::NONE ) { - const double x = GetBetaDistPDF( p, ( i + 1 ), ( n - i + 1 ) )/( n + 1 ); - if ( nGlobalError == FormulaError::NONE ) - { - fSum += x; - } - else - { - PushNoValue(); - return; - } + fSum += x; } - PushDouble( i - 1 ); + else + { + PushNoValue(); + return; + } + } + PushDouble( i - 1 ); + } + } + else + { + // work from n backwards + fFactor = pow(p, n); + if (fFactor > ::std::numeric_limits<double>::min()) + { + double fSum = 1.0 - fFactor; + sal_uInt32 max = static_cast<sal_uInt32> (n), i; + for (i = 0; i < max && fSum >= alpha; i++) + { + fFactor *= (n-i)/(i+1)*q/p; + fSum -= fFactor; } + PushDouble(n-i); } else { - // work from n backwards - fFactor = pow(p, n); - if (fFactor > ::std::numeric_limits<double>::min()) + // accumulate BinomDist until accumulated BinomDist reaches alpha + double fSum = 0.0; + sal_uInt32 max = static_cast<sal_uInt32> (n), i; + alpha = 1 - alpha; + for (i = 0; i < max && fSum < alpha; i++) { - double fSum = 1.0 - fFactor; - sal_uInt32 max = static_cast<sal_uInt32> (n), i; - for (i = 0; i < max && fSum >= alpha; i++) + const double x = GetBetaDistPDF( q, ( i + 1 ), ( n - i + 1 ) )/( n + 1 ); + if ( nGlobalError == FormulaError::NONE ) { - fFactor *= (n-i)/(i+1)*q/p; - fSum -= fFactor; + fSum += x; } - PushDouble(n-i); - } - else - { - // accumulate BinomDist until accumulated BinomDist reaches alpha - double fSum = 0.0; - sal_uInt32 max = static_cast<sal_uInt32> (n), i; - alpha = 1 - alpha; - for (i = 0; i < max && fSum < alpha; i++) + else { - const double x = GetBetaDistPDF( q, ( i + 1 ), ( n - i + 1 ) )/( n + 1 ); - if ( nGlobalError == FormulaError::NONE ) - { - fSum += x; - } - else - { - PushNoValue(); - return; - } + PushNoValue(); + return; } - PushDouble( n - i + 1 ); } + PushDouble( n - i + 1 ); } } } @@ -1501,46 +1501,46 @@ void ScInterpreter::ScCritBinom() void ScInterpreter::ScNegBinomDist() { - if ( MustHaveParamCount( GetByte(), 3 ) ) + if ( !MustHaveParamCount( GetByte(), 3 ) ) + return; + + double p = GetDouble(); // probability + double s = ::rtl::math::approxFloor(GetDouble()); // No of successes + double f = ::rtl::math::approxFloor(GetDouble()); // No of failures + if ((f + s) <= 1.0 || p < 0.0 || p > 1.0) + PushIllegalArgument(); + else { - double p = GetDouble(); // probability - double s = ::rtl::math::approxFloor(GetDouble()); // No of successes - double f = ::rtl::math::approxFloor(GetDouble()); // No of failures - if ((f + s) <= 1.0 || p < 0.0 || p > 1.0) - PushIllegalArgument(); - else - { - double q = 1.0 - p; - double fFactor = pow(p,s); - for (double i = 0.0; i < f; i++) - fFactor *= (i+s)/(i+1.0)*q; - PushDouble(fFactor); - } + double q = 1.0 - p; + double fFactor = pow(p,s); + for (double i = 0.0; i < f; i++) + fFactor *= (i+s)/(i+1.0)*q; + PushDouble(fFactor); } } void ScInterpreter::ScNegBinomDist_MS() { - if ( MustHaveParamCount( GetByte(), 4 ) ) + if ( !MustHaveParamCount( GetByte(), 4 ) ) + return; + + bool bCumulative = GetBool(); + double p = GetDouble(); // probability + double s = ::rtl::math::approxFloor(GetDouble()); // No of successes + double f = ::rtl::math::approxFloor(GetDouble()); // No of failures + if ( s < 1.0 || f < 0.0 || p < 0.0 || p > 1.0 ) + PushIllegalArgument(); + else { - bool bCumulative = GetBool(); - double p = GetDouble(); // probability - double s = ::rtl::math::approxFloor(GetDouble()); // No of successes - double f = ::rtl::math::approxFloor(GetDouble()); // No of failures - if ( s < 1.0 || f < 0.0 || p < 0.0 || p > 1.0 ) - PushIllegalArgument(); + double q = 1.0 - p; + if ( bCumulative ) + PushDouble( 1.0 - GetBetaDist( q, f + 1, s ) ); else { - double q = 1.0 - p; - if ( bCumulative ) - PushDouble( 1.0 - GetBetaDist( q, f + 1, s ) ); - else - { - double fFactor = pow( p, s ); - for ( double i = 0.0; i < f; i++ ) - fFactor *= ( i + s ) / ( i + 1.0 ) * q; - PushDouble( fFactor ); - } + double fFactor = pow( p, s ); + for ( double i = 0.0; i < f; i++ ) + fFactor *= ( i + s ) / ( i + 1.0 ) * q; + PushDouble( fFactor ); } } } @@ -1616,27 +1616,27 @@ void ScInterpreter::ScStdNormDist_MS() void ScInterpreter::ScExpDist() { - if ( MustHaveParamCount( GetByte(), 3 ) ) + if ( !MustHaveParamCount( GetByte(), 3 ) ) + return; + + double kum = GetDouble(); // 0 or 1 + double lambda = GetDouble(); // lambda + double x = GetDouble(); // x + if (lambda <= 0.0) + PushIllegalArgument(); + else if (kum == 0.0) // density { - double kum = GetDouble(); // 0 or 1 - double lambda = GetDouble(); // lambda - double x = GetDouble(); // x - if (lambda <= 0.0) - PushIllegalArgument(); - else if (kum == 0.0) // density - { - if (x >= 0.0) - PushDouble(lambda * exp(-lambda*x)); - else - PushInt(0); - } - else // distribution - { - if (x > 0.0) - PushDouble(1.0 - exp(-lambda*x)); - else - PushInt(0); - } + if (x >= 0.0) + PushDouble(lambda * exp(-lambda*x)); + else + PushInt(0); + } + else // distribution + { + if (x > 0.0) + PushDouble(1.0 - exp(-lambda*x)); + else + PushInt(0); } } @@ -1764,68 +1764,68 @@ void ScInterpreter::ScChiDist( bool bODFF ) void ScInterpreter::ScWeibull() { - if ( MustHaveParamCount( GetByte(), 4 ) ) - { - double kum = GetDouble(); // 0 or 1 - double beta = GetDouble(); // beta - double alpha = GetDouble(); // alpha - double x = GetDouble(); // x - if (alpha <= 0.0 || beta <= 0.0 || x < 0.0) - PushIllegalArgument(); - else if (kum == 0.0) // Density - PushDouble(alpha/pow(beta,alpha)*pow(x,alpha-1.0)* - exp(-pow(x/beta,alpha))); - else // Distribution - PushDouble(1.0 - exp(-pow(x/beta,alpha))); - } + if ( !MustHaveParamCount( GetByte(), 4 ) ) + return; + + double kum = GetDouble(); // 0 or 1 + double beta = GetDouble(); // beta + double alpha = GetDouble(); // alpha + double x = GetDouble(); // x + if (alpha <= 0.0 || beta <= 0.0 || x < 0.0) + PushIllegalArgument(); + else if (kum == 0.0) // Density + PushDouble(alpha/pow(beta,alpha)*pow(x,alpha-1.0)* + exp(-pow(x/beta,alpha))); + else // Distribution + PushDouble(1.0 - exp(-pow(x/beta,alpha))); } void ScInterpreter::ScPoissonDist( bool bODFF ) { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, ( bODFF ? 2 : 3 ), 3 ) ) + if ( !MustHaveParamCount( nParamCount, ( bODFF ? 2 : 3 ), 3 ) ) + return; + + bool bCumulative = nParamCount != 3 || GetBool(); // default cumulative + double lambda = GetDouble(); // Mean + double x = ::rtl::math::approxFloor(GetDouble()); // discrete distribution + if (lambda <= 0.0 || x < 0.0) + PushIllegalArgument(); + else if (!bCumulative) // Probability mass function { - bool bCumulative = nParamCount != 3 || GetBool(); // default cumulative - double lambda = GetDouble(); // Mean - double x = ::rtl::math::approxFloor(GetDouble()); // discrete distribution - if (lambda <= 0.0 || x < 0.0) - PushIllegalArgument(); - else if (!bCumulative) // Probability mass function + if (lambda >712.0) // underflow in exp(-lambda) + { // accuracy 11 Digits + PushDouble( exp(x*log(lambda)-lambda-GetLogGamma(x+1.0))); + } + else { - if (lambda >712.0) // underflow in exp(-lambda) - { // accuracy 11 Digits - PushDouble( exp(x*log(lambda)-lambda-GetLogGamma(x+1.0))); - } - else - { - double fPoissonVar = 1.0; - for ( double f = 0.0; f < x; ++f ) - fPoissonVar *= lambda / ( f + 1.0 ); - PushDouble( fPoissonVar * exp( -lambda ) ); - } + double fPoissonVar = 1.0; + for ( double f = 0.0; f < x; ++f ) + fPoissonVar *= lambda / ( f + 1.0 ); + PushDouble( fPoissonVar * exp( -lambda ) ); } - else // Cumulative distribution function + } + else // Cumulative distribution function + { + if (lambda > 712.0) // underflow in exp(-lambda) + { // accuracy 12 Digits + PushDouble(GetUpRegIGamma(x+1.0,lambda)); + } + else { - if (lambda > 712.0) // underflow in exp(-lambda) - { // accuracy 12 Digits - PushDouble(GetUpRegIGamma(x+1.0,lambda)); - } + if (x >= 936.0) // result is always indistinguishable from 1 + PushDouble (1.0); else { - if (x >= 936.0) // result is always indistinguishable from 1 - PushDouble (1.0); - else + double fSummand = exp(-lambda); + double fSum = fSummand; + int nEnd = sal::static_int_cast<int>( x ); + for (int i = 1; i <= nEnd; i++) { - double fSummand = exp(-lambda); - double fSum = fSummand; - int nEnd = sal::static_int_cast<int>( x ); - for (int i = 1; i <= nEnd; i++) - { - fSummand = (fSummand * lambda)/static_cast<double>(i); - fSum += fSummand; - } - PushDouble(fSum); + fSummand = (fSummand * lambda)/static_cast<double>(i); + fSum += fSummand; } + PushDouble(fSum); } } } @@ -4625,20 +4625,20 @@ void ScInterpreter::ScRSQ() { // Same as ScPearson()*ScPearson() ScPearson(); - if (nGlobalError == FormulaError::NONE) + if (nGlobalError != FormulaError::NONE) + return; + + switch (GetStackType()) { - switch (GetStackType()) - { - case svDouble: - { - double fVal = PopDouble(); - PushDouble( fVal * fVal); - } - break; - default: - PopError(); - PushNoValue(); - } + case svDouble: + { + double fVal = PopDouble(); + PushDouble( fVal * fVal); + } + break; + default: + PopError(); + PushNoValue(); } } diff --git a/sc/source/core/tool/interpr5.cxx b/sc/source/core/tool/interpr5.cxx index 685a2cfe8689..b4b35ed70215 100644 --- a/sc/source/core/tool/interpr5.cxx +++ b/sc/source/core/tool/interpr5.cxx @@ -130,155 +130,155 @@ double ScInterpreter::ScGetGCD(double fx, double fy) void ScInterpreter::ScGCD() { short nParamCount = GetByte(); - if ( MustHaveParamCountMin( nParamCount, 1 ) ) + if ( !MustHaveParamCountMin( nParamCount, 1 ) ) + return; + + double fx, fy = 0.0; + ScRange aRange; + size_t nRefInList = 0; + while (nGlobalError == FormulaError::NONE && nParamCount-- > 0) { - double fx, fy = 0.0; - ScRange aRange; - size_t nRefInList = 0; - while (nGlobalError == FormulaError::NONE && nParamCount-- > 0) + switch (GetStackType()) { - switch (GetStackType()) + case svDouble : + case svString: + case svSingleRef: { - case svDouble : - case svString: - case svSingleRef: + fx = ::rtl::math::approxFloor( GetDouble()); + if (fx < 0.0) { - fx = ::rtl::math::approxFloor( GetDouble()); - if (fx < 0.0) - { - PushIllegalArgument(); - return; - } - fy = ScGetGCD(fx, fy); + PushIllegalArgument(); + return; } - break; - case svDoubleRef : - case svRefList : + fy = ScGetGCD(fx, fy); + } + break; + case svDoubleRef : + case svRefList : + { + FormulaError nErr = FormulaError::NONE; + PopDoubleRef( aRange, nParamCount, nRefInList); + double nCellVal; + ScValueIterator aValIter( pDok, aRange, mnSubTotalFlags ); + if (aValIter.GetFirst(nCellVal, nErr)) { - FormulaError nErr = FormulaError::NONE; - PopDoubleRef( aRange, nParamCount, nRefInList); - double nCellVal; - ScValueIterator aValIter( pDok, aRange, mnSubTotalFlags ); - if (aValIter.GetFirst(nCellVal, nErr)) + do { - do + fx = ::rtl::math::approxFloor( nCellVal); + if (fx < 0.0) { - fx = ::rtl::math::approxFloor( nCellVal); - if (fx < 0.0) - { - PushIllegalArgument(); - return; - } - fy = ScGetGCD(fx, fy); - } while (nErr == FormulaError::NONE && aValIter.GetNext(nCellVal, nErr)); - } - SetError(nErr); + PushIllegalArgument(); + return; + } + fy = ScGetGCD(fx, fy); + } while (nErr == FormulaError::NONE && aValIter.GetNext(nCellVal, nErr)); } - break; - case svMatrix : - case svExternalSingleRef: - case svExternalDoubleRef: + SetError(nErr); + } + break; + case svMatrix : + case svExternalSingleRef: + case svExternalDoubleRef: + { + ScMatrixRef pMat = GetMatrix(); + if (pMat) { - ScMatrixRef pMat = GetMatrix(); - if (pMat) + SCSIZE nC, nR; + pMat->GetDimensions(nC, nR); + if (nC == 0 || nR == 0) + SetError(FormulaError::IllegalArgument); + else { - SCSIZE nC, nR; - pMat->GetDimensions(nC, nR); - if (nC == 0 || nR == 0) - SetError(FormulaError::IllegalArgument); - else - { - double nVal = pMat->GetGcd(); - fy = ScGetGCD(nVal,fy); - } + double nVal = pMat->GetGcd(); + fy = ScGetGCD(nVal,fy); } } - break; - default : SetError(FormulaError::IllegalParameter); break; } + break; + default : SetError(FormulaError::IllegalParameter); break; } - PushDouble(fy); } + PushDouble(fy); } void ScInterpreter:: ScLCM() { short nParamCount = GetByte(); - if ( MustHaveParamCountMin( nParamCount, 1 ) ) + if ( !MustHaveParamCountMin( nParamCount, 1 ) ) + return; + + double fx, fy = 1.0; + ScRange aRange; + size_t nRefInList = 0; + while (nGlobalError == FormulaError::NONE && nParamCount-- > 0) { - double fx, fy = 1.0; - ScRange aRange; - size_t nRefInList = 0; - while (nGlobalError == FormulaError::NONE && nParamCount-- > 0) + switch (GetStackType()) { - switch (GetStackType()) + case svDouble : + case svString: + case svSingleRef: { - case svDouble : - case svString: - case svSingleRef: + fx = ::rtl::math::approxFloor( GetDouble()); + if (fx < 0.0) { - fx = ::rtl::math::approxFloor( GetDouble()); - if (fx < 0.0) - { - PushIllegalArgument(); - return; - } - if (fx == 0.0 || fy == 0.0) - fy = 0.0; - else - fy = fx * fy / ScGetGCD(fx, fy); + PushIllegalArgument(); + return; } - break; - case svDoubleRef : - case svRefList : + if (fx == 0.0 || fy == 0.0) + fy = 0.0; + else + fy = fx * fy / ScGetGCD(fx, fy); + } + break; + case svDoubleRef : + case svRefList : + { + FormulaError nErr = FormulaError::NONE; + PopDoubleRef( aRange, nParamCount, nRefInList); + double nCellVal; + ScValueIterator aValIter( pDok, aRange, mnSubTotalFlags ); + if (aValIter.GetFirst(nCellVal, nErr)) { - FormulaError nErr = FormulaError::NONE; - PopDoubleRef( aRange, nParamCount, nRefInList); - double nCellVal; - ScValueIterator aValIter( pDok, aRange, mnSubTotalFlags ); - if (aValIter.GetFirst(nCellVal, nErr)) + do { - do + fx = ::rtl::math::approxFloor( nCellVal); + if (fx < 0.0) { - fx = ::rtl::math::approxFloor( nCellVal); - if (fx < 0.0) - { - PushIllegalArgument(); - return; - } - if (fx == 0.0 || fy == 0.0) - fy = 0.0; - else - fy = fx * fy / ScGetGCD(fx, fy); - } while (nErr == FormulaError::NONE && aValIter.GetNext(nCellVal, nErr)); - } - SetError(nErr); + PushIllegalArgument(); + return; + } + if (fx == 0.0 || fy == 0.0) + fy = 0.0; + else + fy = fx * fy / ScGetGCD(fx, fy); + } while (nErr == FormulaError::NONE && aValIter.GetNext(nCellVal, nErr)); } - break; - case svMatrix : - case svExternalSingleRef: - case svExternalDoubleRef: + SetError(nErr); + } + break; + case svMatrix : + case svExternalSingleRef: + case svExternalDoubleRef: + { + ScMatrixRef pMat = GetMatrix(); + if (pMat) { - ScMatrixRef pMat = GetMatrix(); - if (pMat) + SCSIZE nC, nR; + pMat->GetDimensions(nC, nR); + if (nC == 0 || nR == 0) + SetError(FormulaError::IllegalArgument); + else { - SCSIZE nC, nR; - pMat->GetDimensions(nC, nR); - if (nC == 0 || nR == 0) - SetError(FormulaError::IllegalArgument); - else - { - double nVal = pMat->GetLcm(); - fy = (nVal * fy ) / ScGetGCD(nVal, fy); - } + double nVal = pMat->GetLcm(); + fy = (nVal * fy ) / ScGetGCD(nVal, fy); } } - break; - default : SetError(FormulaError::IllegalParameter); break; } + break; + default : SetError(FormulaError::IllegalParameter); break; } - PushDouble(fy); } + PushDouble(fy); } void ScInterpreter::MakeMatNew(ScMatrixRef& rMat, SCSIZE nC, SCSIZE nR) @@ -612,80 +612,80 @@ sc::RangeMatrix ScInterpreter::GetRangeMatrix() void ScInterpreter::ScMatValue() { - if ( MustHaveParamCount( GetByte(), 3 ) ) + if ( !MustHaveParamCount( GetByte(), 3 ) ) + return; + + // 0 to count-1 + // Theoretically we could have GetSize() instead of GetUInt32(), but + // really, practically ... + SCSIZE nR = static_cast<SCSIZE>(GetUInt32()); + SCSIZE nC = static_cast<SCSIZE>(GetUInt32()); + if (nGlobalError != FormulaError::NONE) { - // 0 to count-1 - // Theoretically we could have GetSize() instead of GetUInt32(), but - // really, practically ... - SCSIZE nR = static_cast<SCSIZE>(GetUInt32()); - SCSIZE nC = static_cast<SCSIZE>(GetUInt32()); - if (nGlobalError != FormulaError::NONE) - { - PushError( nGlobalError); - return; - } - switch (GetStackType()) + PushError( nGlobalError); + return; + } + switch (GetStackType()) + { + case svSingleRef : { - case svSingleRef : + ScAddress aAdr; + PopSingleRef( aAdr ); + ScRefCellValue aCell(*pDok, aAdr); + if (aCell.meType == CELLTYPE_FORMULA) { - ScAddress aAdr; - PopSingleRef( aAdr ); - ScRefCellValue aCell(*pDok, aAdr); - if (aCell.meType == CELLTYPE_FORMULA) + FormulaError nErrCode = aCell.mpFormula->GetErrCode(); + if (nErrCode != FormulaError::NONE) + PushError( nErrCode); + else { - FormulaError nErrCode = aCell.mpFormula->GetErrCode(); - if (nErrCode != FormulaError::NONE) - PushError( nErrCode); - else - { - const ScMatrix* pMat = aCell.mpFormula->GetMatrix(); - CalculateMatrixValue(pMat,nC,nR); - } + const ScMatrix* pMat = aCell.mpFormula->GetMatrix(); + CalculateMatrixValue(pMat,nC,nR); } - else - PushIllegalParameter(); } - break; - case svDoubleRef : + else + PushIllegalParameter(); + } + break; + case svDoubleRef : + { + SCCOL nCol1; + SCROW nRow1; + SCTAB nTab1; + SCCOL nCol2; + SCROW nRow2; + SCTAB nTab2; + PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); + if (nCol2 - nCol1 >= static_cast<SCCOL>(nR) && + nRow2 - nRow1 >= static_cast<SCROW>(nC) && + nTab1 == nTab2) { - SCCOL nCol1; - SCROW nRow1; - SCTAB nTab1; - SCCOL nCol2; - SCROW nRow2; - SCTAB nTab2; - PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); - if (nCol2 - nCol1 >= static_cast<SCCOL>(nR) && - nRow2 - nRow1 >= static_cast<SCROW>(nC) && - nTab1 == nTab2) + ScAddress aAdr( sal::static_int_cast<SCCOL>( nCol1 + nR ), + sal::static_int_cast<SCROW>( nRow1 + nC ), nTab1 ); + ScRefCellValue aCell(*pDok, aAdr); + if (aCell.hasNumeric()) + PushDouble(GetCellValue(aAdr, aCell)); + else { - ScAddress aAdr( sal::static_int_cast<SCCOL>( nCol1 + nR ), - sal::static_int_cast<SCROW>( nRow1 + nC ), nTab1 ); - ScRefCellValue aCell(*pDok, aAdr); - if (aCell.hasNumeric()) - PushDouble(GetCellValue(aAdr, aCell)); - else - { - svl::SharedString aStr; - GetCellString(aStr, aCell); - PushString(aStr); - } + svl::SharedString aStr; + GetCellString(aStr, aCell); + PushString(aStr); } - else - PushNoValue(); } - break; - case svMatrix: - { - ScMatrixRef pMat = PopMatrix(); - CalculateMatrixValue(pMat.get(),nC,nR); - } - break; - default: - PopError(); - PushIllegalParameter(); - break; + else + PushNoValue(); } + break; + case svMatrix: + { + ScMatrixRef pMat = PopMatrix(); + CalculateMatrixValue(pMat.get(),nC,nR); + } + break; + default: + PopError(); + PushIllegalParameter(); + break; } } void ScInterpreter::CalculateMatrixValue(const ScMatrix* pMat,SCSIZE nC,SCSIZE nR) @@ -713,24 +713,24 @@ void ScInterpreter::CalculateMatrixValue(const ScMatrix* pMat,SCSIZE nC,SCSIZE n void ScInterpreter::ScEMat() { - if ( MustHaveParamCount( GetByte(), 1 ) ) + if ( !MustHaveParamCount( GetByte(), 1 ) ) + return; + + SCSIZE nDim = static_cast<SCSIZE>(GetUInt32()); + if (nGlobalError != FormulaError::NONE || nDim == 0) + PushIllegalArgument(); + else if (!ScMatrix::IsSizeAllocatable( nDim, nDim)) + PushError( FormulaError::MatrixSize); + else { - SCSIZE nDim = static_cast<SCSIZE>(GetUInt32()); - if (nGlobalError != FormulaError::NONE || nDim == 0) - PushIllegalArgument(); - else if (!ScMatrix::IsSizeAllocatable( nDim, nDim)) - PushError( FormulaError::MatrixSize); - else + ScMatrixRef pRMat = GetNewMat(nDim, nDim); + if (pRMat) { - ScMatrixRef pRMat = GetNewMat(nDim, nDim); - if (pRMat) - { - MEMat(pRMat, nDim); - PushMatrix(pRMat); - } - else - PushIllegalArgument(); + MEMat(pRMat, nDim); + PushMatrix(pRMat); } + else + PushIllegalArgument(); } } @@ -902,46 +902,46 @@ static void lcl_LUP_solve( const ScMatrix* mLU, const SCSIZE n, void ScInterpreter::ScMatDet() { - if ( MustHaveParamCount( GetByte(), 1 ) ) + if ( !MustHaveParamCount( GetByte(), 1 ) ) + return; + + ScMatrixRef pMat = GetMatrix(); + if (!pMat) { - ScMatrixRef pMat = GetMatrix(); - if (!pMat) - { - PushIllegalParameter(); - return; - } - if ( !pMat->IsNumeric() ) - { - PushNoValue(); - return; - } - SCSIZE nC, nR; - pMat->GetDimensions(nC, nR); - if ( nC != nR || nC == 0 ) - PushIllegalArgument(); - else if (!ScMatrix::IsSizeAllocatable( nC, nR)) - PushError( FormulaError::MatrixSize); + PushIllegalParameter(); + return; + } + if ( !pMat->IsNumeric() ) + { + PushNoValue(); + return; + } + SCSIZE nC, nR; + pMat->GetDimensions(nC, nR); + if ( nC != nR || nC == 0 ) + PushIllegalArgument(); + else if (!ScMatrix::IsSizeAllocatable( nC, nR)) + PushError( FormulaError::MatrixSize); + else + { + // LUP decomposition is done inplace, use copy. + ScMatrixRef xLU = pMat->Clone(); + if (!xLU) + PushError( FormulaError::CodeOverflow); else { - // LUP decomposition is done inplace, use copy. - ScMatrixRef xLU = pMat->Clone(); - if (!xLU) - PushError( FormulaError::CodeOverflow); + ::std::vector< SCSIZE> P(nR); + int nDetSign = lcl_LUP_decompose( xLU.get(), nR, P); + if (!nDetSign) + PushInt(0); // singular matrix else { - ::std::vector< SCSIZE> P(nR); - int nDetSign = lcl_LUP_decompose( xLU.get(), nR, P); - if (!nDetSign) - PushInt(0); // singular matrix - else - { - // In an LU matrix the determinant is simply the product of - // all diagonal elements. - double fDet = nDetSign; - for (SCSIZE i=0; i < nR; ++i) - fDet *= xLU->GetDouble( i, i); - PushDouble( fDet); - } + // In an LU matrix the determinant is simply the product of + // all diagonal elements. + double fDet = nDetSign; + for (SCSIZE i=0; i < nR; ++i) + fDet *= xLU->GetDouble( i, i); + PushDouble( fDet); } } } @@ -949,111 +949,111 @@ void ScInterpreter::ScMatDet() void ScInterpreter::ScMatInv() { - if ( MustHaveParamCount( GetByte(), 1 ) ) + if ( !MustHaveParamCount( GetByte(), 1 ) ) + return; + + ScMatrixRef pMat = GetMatrix(); + if (!pMat) { - ScMatrixRef pMat = GetMatrix(); - if (!pMat) - { - PushIllegalParameter(); - return; - } - if ( !pMat->IsNumeric() ) - { - PushNoValue(); - return; - } - SCSIZE nC, nR; - pMat->GetDimensions(nC, nR); + PushIllegalParameter(); + return; + } + if ( !pMat->IsNumeric() ) + { + PushNoValue(); + return; + } + SCSIZE nC, nR; + pMat->GetDimensions(nC, nR); - if (ScCalcConfig::isOpenCLEnabled()) + if (ScCalcConfig::isOpenCLEnabled()) + { + sc::FormulaGroupInterpreter *pInterpreter = sc::FormulaGroupInterpreter::getStatic(); + if (pInterpreter != nullptr) { - sc::FormulaGroupInterpreter *pInterpreter = sc::FormulaGroupInterpreter::getStatic(); - if (pInterpreter != nullptr) + ScMatrixRef xResMat = pInterpreter->inverseMatrix(*pMat); + if (xResMat) { - ScMatrixRef xResMat = pInterpreter->inverseMatrix(*pMat); - if (xResMat) - { - PushMatrix(xResMat); - return; - } + PushMatrix(xResMat); + return; } } + } - if ( nC != nR || nC == 0 ) - PushIllegalArgument(); - else if (!ScMatrix::IsSizeAllocatable( nC, nR)) - PushError( FormulaError::MatrixSize); + if ( nC != nR || nC == 0 ) + PushIllegalArgument(); + else if (!ScMatrix::IsSizeAllocatable( nC, nR)) + PushError( FormulaError::MatrixSize); + else + { + // LUP decomposition is done inplace, use copy. + ScMatrixRef xLU = pMat->Clone(); + // The result matrix. + ScMatrixRef xY = GetNewMat( nR, nR); + if (!xLU || !xY) + PushError( FormulaError::CodeOverflow); else { - // LUP decomposition is done inplace, use copy. - ScMatrixRef xLU = pMat->Clone(); - // The result matrix. - ScMatrixRef xY = GetNewMat( nR, nR); - if (!xLU || !xY) - PushError( FormulaError::CodeOverflow); + ::std::vector< SCSIZE> P(nR); + int nDetSign = lcl_LUP_decompose( xLU.get(), nR, P); + if (!nDetSign) + PushIllegalArgument(); else { - ::std::vector< SCSIZE> P(nR); - int nDetSign = lcl_LUP_decompose( xLU.get(), nR, P); - if (!nDetSign) - PushIllegalArgument(); - else + // Solve equation for each column. + ::std::vector< double> B(nR); + ::std::vector< double> X(nR); + for (SCSIZE j=0; j < nR; ++j) { - // Solve equation for each column. - ::std::vector< double> B(nR); - ::std::vector< double> X(nR); - for (SCSIZE j=0; j < nR; ++j) - { - for (SCSIZE i=0; i < nR; ++i) - B[i] = 0.0; - B[j] = 1.0; - lcl_LUP_solve( xLU.get(), nR, P, B, X); - for (SCSIZE i=0; i < nR; ++i) - xY->PutDouble( X[i], j, i); - } + for (SCSIZE i=0; i < nR; ++i) + B[i] = 0.0; + B[j] = 1.0; + lcl_LUP_solve( xLU.get(), nR, P, B, X); + for (SCSIZE i=0; i < nR; ++i) + xY->PutDouble( X[i], j, i); + } #ifdef DEBUG_SC_LUP_DECOMPOSITION - /* Possible checks for ill-condition: - * 1. Scale matrix, invert scaled matrix. If there are - * elements of the inverted matrix that are several - * orders of magnitude greater than 1 => - * ill-conditioned. - * Just how much is "several orders"? - * 2. Invert the inverted matrix and assess whether the - * result is sufficiently close to the original matrix. - * If not => ill-conditioned. - * Just what is sufficient? - * 3. Multiplying the inverse by the original matrix should - * produce a result sufficiently close to the identity - * matrix. - * Just what is sufficient? - * - * The following is #3. - */ - const double fInvEpsilon = 1.0E-7; - ScMatrixRef xR = GetNewMat( nR, nR); - if (xR) + /* Possible checks for ill-condition: + * 1. Scale matrix, invert scaled matrix. If there are + * elements of the inverted matrix that are several + * orders of magnitude greater than 1 => + * ill-conditioned. + * Just how much is "several orders"? + * 2. Invert the inverted matrix and assess whether the + * result is sufficiently close to the original matrix. + * If not => ill-conditioned. + * Just what is sufficient? + * 3. Multiplying the inverse by the original matrix should + * produce a result sufficiently close to the identity + * matrix. + * Just what is sufficient? + * + * The following is #3. + */ + const double fInvEpsilon = 1.0E-7; + ScMatrixRef xR = GetNewMat( nR, nR); + if (xR) + { + ScMatrix* pR = xR.get(); + lcl_MFastMult( pMat, xY.get(), pR, nR, nR, nR); + fprintf( stderr, "\n%s\n", "ScMatInv(): mult-identity"); + for (SCSIZE i=0; i < nR; ++i) { - ScMatrix* pR = xR.get(); - lcl_MFastMult( pMat, xY.get(), pR, nR, nR, nR); - fprintf( stderr, "\n%s\n", "ScMatInv(): mult-identity"); - for (SCSIZE i=0; i < nR; ++i) + for (SCSIZE j=0; j < nR; ++j) { - for (SCSIZE j=0; j < nR; ++j) - { - double fTmp = pR->GetDouble( j, i); - fprintf( stderr, "%8.2g ", fTmp); - if (fabs( fTmp - (i == j)) > fInvEpsilon) - SetError( FormulaError::IllegalArgument); - } - fprintf( stderr, "\n%s\n", ""); + double fTmp = pR->GetDouble( j, i); + fprintf( stderr, "%8.2g ", fTmp); + if (fabs( fTmp - (i == j)) > fInvEpsilon) + SetError( FormulaError::IllegalArgument); } + fprintf( stderr, "\n%s\n", ""); } -#endif - if (nGlobalError != FormulaError::NONE) - PushError( nGlobalError); - else - PushMatrix( xY); } +#endif + if (nGlobalError != FormulaError::NONE) + PushError( nGlobalError); + else + PushMatrix( xY); } } } @@ -1061,75 +1061,75 @@ void ScInterpreter::ScMatInv() void ScInterpreter::ScMatMult() { - if ( MustHaveParamCount( GetByte(), 2 ) ) + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + + ScMatrixRef pMat2 = GetMatrix(); + ScMatrixRef pMat1 = GetMatrix(); + ScMatrixRef pRMat; + if (pMat1 && pMat2) { - ScMatrixRef pMat2 = GetMatrix(); - ScMatrixRef pMat1 = GetMatrix(); - ScMatrixRef pRMat; - if (pMat1 && pMat2) + if ( pMat1->IsNumeric() && pMat2->IsNumeric() ) { - if ( pMat1->IsNumeric() && pMat2->IsNumeric() ) + SCSIZE nC1, nC2; + SCSIZE nR1, nR2; + pMat1->GetDimensions(nC1, nR1); + pMat2->GetDimensions(nC2, nR2); + if (nC1 != nR2) + PushIllegalArgument(); + else { - SCSIZE nC1, nC2; - SCSIZE nR1, nR2; - pMat1->GetDimensions(nC1, nR1); - pMat2->GetDimensions(nC2, nR2); - if (nC1 != nR2) - PushIllegalArgument(); - else + pRMat = GetNewMat(nC2, nR1); + if (pRMat) { - pRMat = GetNewMat(nC2, nR1); - if (pRMat) + double sum; + for (SCSIZE i = 0; i < nR1; i++) { - double sum; - for (SCSIZE i = 0; i < nR1; i++) + for (SCSIZE j = 0; j < nC2; j++) { - for (SCSIZE j = 0; j < nC2; j++) + sum = 0.0; + for (SCSIZE k = 0; k < nC1; k++) { - sum = 0.0; - for (SCSIZE k = 0; k < nC1; k++) - { - sum += pMat1->GetDouble(k,i)*pMat2->GetDouble(j,k); - } - pRMat->PutDouble(sum, j, i); + sum += pMat1->GetDouble(k,i)*pMat2->GetDouble(j,k); } + pRMat->PutDouble(sum, j, i); } - PushMatrix(pRMat); } - else - PushIllegalArgument(); + PushMatrix(pRMat); } + else + PushIllegalArgument(); } - else - PushNoValue(); } else - PushIllegalParameter(); + PushNoValue(); } + else + PushIllegalParameter(); } void ScInterpreter::ScMatTrans() { - if ( MustHaveParamCount( GetByte(), 1 ) ) + if ( !MustHaveParamCount( GetByte(), 1 ) ) + return; + + ScMatrixRef pMat = GetMatrix(); + ScMatrixRef pRMat; + if (pMat) { - ScMatrixRef pMat = GetMatrix(); - ScMatrixRef pRMat; - if (pMat) + SCSIZE nC, nR; + pMat->GetDimensions(nC, nR); + pRMat = GetNewMat(nR, nC); + if ( pRMat ) { - SCSIZE nC, nR; - pMat->GetDimensions(nC, nR); - pRMat = GetNewMat(nR, nC); - if ( pRMat ) - { - pMat->MatTrans(*pRMat); - PushMatrix(pRMat); - } - else - PushIllegalArgument(); + pMat->MatTrans(*pRMat); + PushMatrix(pRMat); } else - PushIllegalParameter(); + PushIllegalArgument(); } + else + PushIllegalParameter(); } /** Minimum extent of one result matrix dimension. @@ -1230,27 +1230,27 @@ ScMatrixRef ScInterpreter::MatConcat(const ScMatrixRef& pMat1, const ScMatrixRef // for DATE, TIME, DATETIME, DURATION static void lcl_GetDiffDateTimeFmtType( SvNumFormatType& nFuncFmt, SvNumFormatType nFmt1, SvNumFormatType nFmt2 ) { - if ( nFmt1 != SvNumFormatType::UNDEFINED || nFmt2 != SvNumFormatType::UNDEFINED ) + if ( nFmt1 == SvNumFormatType::UNDEFINED && nFmt2 == SvNumFormatType::UNDEFINED ) + return; + + if ( nFmt1 == nFmt2 ) { - if ( nFmt1 == nFmt2 ) - { - if ( nFmt1 == SvNumFormatType::TIME || nFmt1 == SvNumFormatType::DATETIME - || nFmt1 == SvNumFormatType::DURATION ) - nFuncFmt = SvNumFormatType::DURATION; // times result in time duration - // else: nothing special, number (date - date := days) - } - else if ( nFmt1 == SvNumFormatType::UNDEFINED ) - nFuncFmt = nFmt2; // e.g. date + days := date - else if ( nFmt2 == SvNumFormatType::UNDEFINED ) - nFuncFmt = nFmt1; - else + if ( nFmt1 == SvNumFormatType::TIME || nFmt1 == SvNumFormatType::DATETIME + || nFmt1 == SvNumFormatType::DURATION ) + nFuncFmt = SvNumFormatType::DURATION; // times result in time duration + // else: nothing special, number (date - date := days) + } + else if ( nFmt1 == SvNumFormatType::UNDEFINED ) + nFuncFmt = nFmt2; // e.g. date + days := date + else if ( nFmt2 == SvNumFormatType::UNDEFINED ) + nFuncFmt = nFmt1; + else + { + if ( nFmt1 == SvNumFormatType::DATE || nFmt2 == SvNumFormatType::DATE || + nFmt1 == SvNumFormatType::DATETIME || nFmt2 == SvNumFormatType::DATETIME ) { - if ( nFmt1 == SvNumFormatType::DATE || nFmt2 == SvNumFormatType::DATE || - nFmt1 == SvNumFormatType::DATETIME || nFmt2 == SvNumFormatType::DATETIME ) - { - if ( nFmt1 == SvNumFormatType::TIME || nFmt2 == SvNumFormatType::TIME ) - nFuncFmt = SvNumFormatType::DATETIME; // date + time - } + if ( nFmt1 == SvNumFormatType::TIME || nFmt2 == SvNumFormatType::TIME ) + nFuncFmt = SvNumFormatType::DATETIME; // date + time } } } @@ -3297,25 +3297,25 @@ void ScInterpreter::ScMatRef() void ScInterpreter::ScInfo() { - if( MustHaveParamCount( GetByte(), 1 ) ) - { - OUString aStr = GetString().getString(); - ScCellKeywordTranslator::transKeyword(aStr, ScGlobal::GetLocale(), ocInfo); - if( aStr == "SYSTEM" ) - PushString( SC_INFO_OSVERSION ); - else if( aStr == "OSVERSION" ) - PushString( "Windows (32-bit) NT 5.01" ); - else if( aStr == "RELEASE" ) - PushString( ::utl::Bootstrap::getBuildIdData( OUString() ) ); - else if( aStr == "NUMFILE" ) - PushDouble( 1 ); - else if( aStr == "RECALC" ) - PushString( ScResId( pDok->GetAutoCalc() ? STR_RECALC_AUTO : STR_RECALC_MANUAL ) ); - else if (aStr == "DIRECTORY" || aStr == "MEMAVAIL" || aStr == "MEMUSED" || aStr == "ORIGIN" || aStr == "TOTMEM") - PushNA(); - else - PushIllegalArgument(); - } + if( !MustHaveParamCount( GetByte(), 1 ) ) + return; + + OUString aStr = GetString().getString(); + ScCellKeywordTranslator::transKeyword(aStr, ScGlobal::GetLocale(), ocInfo); + if( aStr == "SYSTEM" ) + PushString( SC_INFO_OSVERSION ); + else if( aStr == "OSVERSION" ) + PushString( "Windows (32-bit) NT 5.01" ); + else if( aStr == "RELEASE" ) + PushString( ::utl::Bootstrap::getBuildIdData( OUString() ) ); + else if( aStr == "NUMFILE" ) + PushDouble( 1 ); + else if( aStr == "RECALC" ) + PushString( ScResId( pDok->GetAutoCalc() ? STR_RECALC_AUTO : STR_RECALC_MANUAL ) ); + else if (aStr == "DIRECTORY" || aStr == "MEMAVAIL" || aStr == "MEMUSED" || aStr == "ORIGIN" || aStr == "TOTMEM") + PushNA(); + else + PushIllegalArgument(); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/tool/interpr7.cxx b/sc/source/core/tool/interpr7.cxx index aa3461434570..8678f9e4c68f 100644 --- a/sc/source/core/tool/interpr7.cxx +++ b/sc/source/core/tool/interpr7.cxx @@ -42,203 +42,203 @@ using namespace com::sun::star; void ScInterpreter::ScFilterXML() { sal_uInt8 nParamCount = GetByte(); - if (MustHaveParamCount( nParamCount, 2 ) ) + if (!MustHaveParamCount( nParamCount, 2 ) ) + return; + + SCSIZE nMatCols = 1, nMatRows = 1, nNode = 0; + const ScMatrix* pPathMatrix = nullptr; + // In array/matrix context node elements' results are to be + // subsequently stored. Check this before obtaining any argument from + // the stack so the stack type can be used. + if (pJumpMatrix || IsInArrayContext()) { - SCSIZE nMatCols = 1, nMatRows = 1, nNode = 0; - const ScMatrix* pPathMatrix = nullptr; - // In array/matrix context node elements' results are to be - // subsequently stored. Check this before obtaining any argument from - // the stack so the stack type can be used. - if (pJumpMatrix || IsInArrayContext()) + if (pJumpMatrix) { - if (pJumpMatrix) + // Single result, GetString() will retrieve the corresponding + // argument and JumpMatrix() will store it at the proper + // position. Note that nMatCols and nMatRows are still 1. + SCSIZE nCurCol = 0, nCurRow = 0; + pJumpMatrix->GetPos( nCurCol, nCurRow); + nNode = nCurRow; + } + else if (bMatrixFormula) + { + // If there is no formula cell then continue with a single + // result. + if (pMyFormulaCell) { - // Single result, GetString() will retrieve the corresponding - // argument and JumpMatrix() will store it at the proper - // position. Note that nMatCols and nMatRows are still 1. - SCSIZE nCurCol = 0, nCurRow = 0; - pJumpMatrix->GetPos( nCurCol, nCurRow); - nNode = nCurRow; + SCCOL nCols; + SCROW nRows; + pMyFormulaCell->GetMatColsRows( nCols, nRows); + nMatCols = nCols; + nMatRows = nRows; } - else if (bMatrixFormula) + } + else if (GetStackType() == formula::svMatrix) + { + pPathMatrix = pStack[sp-1]->GetMatrix(); + if (!pPathMatrix) { - // If there is no formula cell then continue with a single - // result. - if (pMyFormulaCell) - { - SCCOL nCols; - SCROW nRows; - pMyFormulaCell->GetMatColsRows( nCols, nRows); - nMatCols = nCols; - nMatRows = nRows; - } + PushIllegalParameter(); + return; } - else if (GetStackType() == formula::svMatrix) - { - pPathMatrix = pStack[sp-1]->GetMatrix(); - if (!pPathMatrix) - { - PushIllegalParameter(); - return; - } - pPathMatrix->GetDimensions( nMatCols, nMatRows); + pPathMatrix->GetDimensions( nMatCols, nMatRows); - /* TODO: it is unclear what should happen if there are - * different path arguments in matrix elements. We may have to - * evaluate each, and for repeated identical paths use - * subsequent nodes. As is, the path at 0,0 is used as obtained - * by GetString(). */ + /* TODO: it is unclear what should happen if there are + * different path arguments in matrix elements. We may have to + * evaluate each, and for repeated identical paths use + * subsequent nodes. As is, the path at 0,0 is used as obtained + * by GetString(). */ - } - } - if (!nMatCols || !nMatRows) - { - PushNoValue(); - return; } + } + if (!nMatCols || !nMatRows) + { + PushNoValue(); + return; + } - OUString aXPathExpression = GetString().getString(); - OUString aString = GetString().getString(); - if(aString.isEmpty() || aXPathExpression.isEmpty()) - { - PushError( FormulaError::NoValue ); - return; - } + OUString aXPathExpression = GetString().getString(); + OUString aString = GetString().getString(); + if(aString.isEmpty() || aXPathExpression.isEmpty()) + { + PushError( FormulaError::NoValue ); + return; + } - OString aOXPathExpression = OUStringToOString( aXPathExpression, RTL_TEXTENCODING_UTF8 ); - const char* pXPathExpr = aOXPathExpression.getStr(); - OString aOString = OUStringToOString( aString, RTL_TEXTENCODING_UTF8 ); - const char* pXML = aOString.getStr(); + OString aOXPathExpression = OUStringToOString( aXPathExpression, RTL_TEXTENCODING_UTF8 ); + const char* pXPathExpr = aOXPathExpression.getStr(); + OString aOString = OUStringToOString( aString, RTL_TEXTENCODING_UTF8 ); + const char* pXML = aOString.getStr(); - std::shared_ptr<xmlParserCtxt> pContext( - xmlNewParserCtxt(), xmlFreeParserCtxt ); + std::shared_ptr<xmlParserCtxt> pContext( + xmlNewParserCtxt(), xmlFreeParserCtxt ); - std::shared_ptr<xmlDoc> pDoc( xmlParseMemory( pXML, aOString.getLength() ), - xmlFreeDoc ); + std::shared_ptr<xmlDoc> pDoc( xmlParseMemory( pXML, aOString.getLength() ), + xmlFreeDoc ); - if(!pDoc) - { - PushError( FormulaError::NoValue ); - return; - } + if(!pDoc) + { + PushError( FormulaError::NoValue ); + return; + } - std::shared_ptr<xmlXPathContext> pXPathCtx( xmlXPathNewContext(pDoc.get()), - xmlXPathFreeContext ); + std::shared_ptr<xmlXPathContext> pXPathCtx( xmlXPathNewContext(pDoc.get()), + xmlXPathFreeContext ); - std::shared_ptr<xmlXPathObject> pXPathObj( xmlXPathEvalExpression(BAD_CAST(pXPathExpr), pXPathCtx.get()), - xmlXPathFreeObject ); + std::shared_ptr<xmlXPathObject> pXPathObj( xmlXPathEvalExpression(BAD_CAST(pXPathExpr), pXPathCtx.get()), + xmlXPathFreeObject ); - if(!pXPathObj) - { - PushError( FormulaError::NoValue ); - return; - } + if(!pXPathObj) + { + PushError( FormulaError::NoValue ); + return; + } - switch(pXPathObj->type) - { - case XPATH_UNDEFINED: - PushNoValue(); - break; - case XPATH_NODESET: + switch(pXPathObj->type) + { + case XPATH_UNDEFINED: + PushNoValue(); + break; + case XPATH_NODESET: + { + xmlNodeSetPtr pNodeSet = pXPathObj->nodesetval; + if(!pNodeSet) { - xmlNodeSetPtr pNodeSet = pXPathObj->nodesetval; - if(!pNodeSet) - { - PushError( FormulaError::NoValue ); - return; - } + PushError( FormulaError::NoValue ); + return; + } - const size_t nSize = pNodeSet->nodeNr; - if (nNode >= nSize) - { - // For pJumpMatrix - PushError( FormulaError::NotAvailable); - return; - } + const size_t nSize = pNodeSet->nodeNr; + if (nNode >= nSize) + { + // For pJumpMatrix + PushError( FormulaError::NotAvailable); + return; + } - /* TODO: for nMatCols>1 IF stack type is svMatrix, i.e. - * pPathMatrix!=nullptr, we may want a result matrix with - * nMatCols columns as well, but clarify first how to treat - * differing path elements. */ + /* TODO: for nMatCols>1 IF stack type is svMatrix, i.e. + * pPathMatrix!=nullptr, we may want a result matrix with + * nMatCols columns as well, but clarify first how to treat + * differing path elements. */ - ScMatrixRef xResMat; - if (nMatRows > 1) + ScMatrixRef xResMat; + if (nMatRows > 1) + { + xResMat = GetNewMat( 1, nMatRows, true); + if (!xResMat) { - xResMat = GetNewMat( 1, nMatRows, true); - if (!xResMat) - { - PushError( FormulaError::CodeOverflow); - return; - } + PushError( FormulaError::CodeOverflow); + return; } + } - for ( ; nNode < nMatRows; ++nNode) + for ( ; nNode < nMatRows; ++nNode) + { + if( nSize > nNode ) { - if( nSize > nNode ) + OUString aResult; + if(pNodeSet->nodeTab[nNode]->type == XML_NAMESPACE_DECL) { - OUString aResult; - if(pNodeSet->nodeTab[nNode]->type == XML_NAMESPACE_DECL) - { - xmlNsPtr ns = reinterpret_cast<xmlNsPtr>(pNodeSet->nodeTab[nNode]); - xmlNodePtr cur = reinterpret_cast<xmlNodePtr>(ns->next); - std::shared_ptr<xmlChar> pChar2(xmlNodeGetContent(cur), xmlFree); - aResult = OStringToOUString(OString(reinterpret_cast<char*>(pChar2.get())), RTL_TEXTENCODING_UTF8); - } - else - { - xmlNodePtr cur = pNodeSet->nodeTab[nNode]; - std::shared_ptr<xmlChar> pChar2(xmlNodeGetContent(cur), xmlFree); - aResult = OStringToOUString(OString(reinterpret_cast<char*>(pChar2.get())), RTL_TEXTENCODING_UTF8); - } - if (xResMat) - xResMat->PutString( mrStrPool.intern( aResult), 0, nNode); - else - PushString(aResult); + xmlNsPtr ns = reinterpret_cast<xmlNsPtr>(pNodeSet->nodeTab[nNode]); + xmlNodePtr cur = reinterpret_cast<xmlNodePtr>(ns->next); + std::shared_ptr<xmlChar> pChar2(xmlNodeGetContent(cur), xmlFree); + aResult = OStringToOUString(OString(reinterpret_cast<char*>(pChar2.get())), RTL_TEXTENCODING_UTF8); } else { - if (xResMat) - xResMat->PutError( FormulaError::NotAvailable, 0, nNode); - else - PushError( FormulaError::NotAvailable ); + xmlNodePtr cur = pNodeSet->nodeTab[nNode]; + std::shared_ptr<xmlChar> pChar2(xmlNodeGetContent(cur), xmlFree); + aResult = OStringToOUString(OString(reinterpret_cast<char*>(pChar2.get())), RTL_TEXTENCODING_UTF8); } + if (xResMat) + xResMat->PutString( mrStrPool.intern( aResult), 0, nNode); + else + PushString(aResult); + } + else + { + if (xResMat) + xResMat->PutError( FormulaError::NotAvailable, 0, nNode); + else + PushError( FormulaError::NotAvailable ); } - if (xResMat) - PushMatrix( xResMat); - } - break; - case XPATH_BOOLEAN: - { - bool bVal = pXPathObj->boolval != 0; - PushDouble(double(bVal)); - } - break; - case XPATH_NUMBER: - { - double fVal = pXPathObj->floatval; - PushDouble(fVal); } - break; - case XPATH_STRING: - PushString(OUString::createFromAscii(reinterpret_cast<char*>(pXPathObj->stringval))); - break; - case XPATH_POINT: - PushNoValue(); - break; - case XPATH_RANGE: - PushNoValue(); - break; - case XPATH_LOCATIONSET: - PushNoValue(); - break; - case XPATH_USERS: - PushNoValue(); - break; - case XPATH_XSLT_TREE: - PushNoValue(); - break; + if (xResMat) + PushMatrix( xResMat); + } + break; + case XPATH_BOOLEAN: + { + bool bVal = pXPathObj->boolval != 0; + PushDouble(double(bVal)); + } + break; + case XPATH_NUMBER: + { + double fVal = pXPathObj->floatval; + PushDouble(fVal); + } + break; + case XPATH_STRING: + PushString(OUString::createFromAscii(reinterpret_cast<char*>(pXPathObj->stringval))); + break; + case XPATH_POINT: + PushNoValue(); + break; + case XPATH_RANGE: + PushNoValue(); + break; + case XPATH_LOCATIONSET: + PushNoValue(); + break; + case XPATH_USERS: + PushNoValue(); + break; + case XPATH_XSLT_TREE: + PushNoValue(); + break; - } } } @@ -276,120 +276,118 @@ static bool lcl_FunctionAccessLoadWebServiceLink( OUString& rResult, ScDocument* void ScInterpreter::ScWebservice() { sal_uInt8 nParamCount = GetByte(); - if (MustHaveParamCount( nParamCount, 1 ) ) + if (!MustHaveParamCount( nParamCount, 1 ) ) + return; + + OUString aURI = GetString().getString(); + + if (aURI.isEmpty()) { - OUString aURI = GetString().getString(); + PushError( FormulaError::NoValue ); + return; + } - if (aURI.isEmpty()) - { - PushError( FormulaError::NoValue ); - return; - } + INetURLObject aObj(aURI, INetProtocol::File); + INetProtocol eProtocol = aObj.GetProtocol(); + if (eProtocol != INetProtocol::Http && eProtocol != INetProtocol::Https) + { + PushError(FormulaError::NoValue); + return; + } - INetURLObject aObj(aURI, INetProtocol::File); - INetProtocol eProtocol = aObj.GetProtocol(); - if (eProtocol != INetProtocol::Http && eProtocol != INetProtocol::Https) + if (!mpLinkManager) + { + if (!pDok->IsFunctionAccess() || pDok->HasLinkFormulaNeedingCheck()) { - PushError(FormulaError::NoValue); - return; + PushError( FormulaError::NoValue); } - - if (!mpLinkManager) + else { - if (!pDok->IsFunctionAccess() || pDok->HasLinkFormulaNeedingCheck()) - { - PushError( FormulaError::NoValue); - } + OUString aResult; + if (lcl_FunctionAccessLoadWebServiceLink( aResult, pDok, aURI)) + PushString( aResult); else - { - OUString aResult; - if (lcl_FunctionAccessLoadWebServiceLink( aResult, pDok, aURI)) - PushString( aResult); - else - PushError( FormulaError::NoValue); - } - return; + PushError( FormulaError::NoValue); } + return; + } - // Need to reinterpret after loading (build links) - pArr->AddRecalcMode( ScRecalcMode::ONLOAD_LENIENT ); + // Need to reinterpret after loading (build links) + pArr->AddRecalcMode( ScRecalcMode::ONLOAD_LENIENT ); - // while the link is not evaluated, idle must be disabled (to avoid circular references) - bool bOldEnabled = pDok->IsIdleEnabled(); - pDok->EnableIdle(false); + // while the link is not evaluated, idle must be disabled (to avoid circular references) + bool bOldEnabled = pDok->IsIdleEnabled(); + pDok->EnableIdle(false); - // Get/ Create link object - ScWebServiceLink* pLink = lcl_GetWebServiceLink(mpLinkManager, aURI); + // Get/ Create link object + ScWebServiceLink* pLink = lcl_GetWebServiceLink(mpLinkManager, aURI); - bool bWasError = (pMyFormulaCell && pMyFormulaCell->GetRawError() != FormulaError::NONE); + bool bWasError = (pMyFormulaCell && pMyFormulaCell->GetRawError() != FormulaError::NONE); - if (!pLink) + if (!pLink) + { + pLink = new ScWebServiceLink(pDok, aURI); + mpLinkManager->InsertFileLink(*pLink, sfx2::SvBaseLinkObjectType::ClientFile, aURI); + if ( mpLinkManager->GetLinks().size() == 1 ) // the first one? { - pLink = new ScWebServiceLink(pDok, aURI); - mpLinkManager->InsertFileLink(*pLink, sfx2::SvBaseLinkObjectType::ClientFile, aURI); - if ( mpLinkManager->GetLinks().size() == 1 ) // the first one? - { - SfxBindings* pBindings = pDok->GetViewBindings(); - if (pBindings) - pBindings->Invalidate( SID_LINKS ); // Link-Manager enabled - } - - //if the document was just loaded, but the ScDdeLink entry was missing, then - //don't update this link until the links are updated in response to the users - //decision - if (!pDok->HasLinkFormulaNeedingCheck()) - { - pLink->Update(); - } + SfxBindings* pBindings = pDok->GetViewBindings(); + if (pBindings) + pBindings->Invalidate( SID_LINKS ); // Link-Manager enabled + } - if (pMyFormulaCell) - { - // StartListening after the Update to avoid circular references - pMyFormulaCell->StartListening(*pLink); - } + //if the document was just loaded, but the ScDdeLink entry was missing, then + //don't update this link until the links are updated in response to the users + //decision + if (!pDok->HasLinkFormulaNeedingCheck()) + { + pLink->Update(); } - else + + if (pMyFormulaCell) { - if (pMyFormulaCell) - pMyFormulaCell->StartListening(*pLink); + // StartListening after the Update to avoid circular references + pMyFormulaCell->StartListening(*pLink); } + } + else + { + if (pMyFormulaCell) + pMyFormulaCell->StartListening(*pLink); + } - // If a new Error from Reschedule appears when the link is executed then reset the errorflag - if (pMyFormulaCell && pMyFormulaCell->GetRawError() != FormulaError::NONE && !bWasError) - pMyFormulaCell->SetErrCode(FormulaError::NONE); + // If a new Error from Reschedule appears when the link is executed then reset the errorflag + if (pMyFormulaCell && pMyFormulaCell->GetRawError() != FormulaError::NONE && !bWasError) + pMyFormulaCell->SetErrCode(FormulaError::NONE); - // check the value - if (pLink->HasResult()) - PushString(pLink->GetResult()); - else if (pDok->HasLinkFormulaNeedingCheck()) + // check the value + if (pLink->HasResult()) + PushString(pLink->GetResult()); + else if (pDok->HasLinkFormulaNeedingCheck()) + { + // If this formula cell is recalculated just after load and the + // expression is exactly WEBSERVICE("literal_URI") (i.e. no other + // calculation involved, not even a cell reference) and a cached + // result is set as hybrid string then use that as result value to + // prevent a #VALUE! result due to the "Automatic update of + // external links has been disabled." + // This will work only once, as the new formula cell result won't + // be a hybrid anymore. + /* TODO: the FormulaError::LinkFormulaNeedingCheck could be used as + * a signal for the formula cell to keep the hybrid string as + * result of the overall formula *iff* no higher prioritized + * ScRecalcMode than ONLOAD_LENIENT is present in the entire + * document (i.e. the formula result could not be influenced by an + * ONLOAD_MUST or ALWAYS recalc, necessary as we don't track + * interim results of subexpressions that could be compared), which + * also means to track setting ScRecalcMode somehow... note this is + * just a vague idea so far and might or might not work. */ + if (pMyFormulaCell && pMyFormulaCell->HasHybridStringResult()) { - // If this formula cell is recalculated just after load and the - // expression is exactly WEBSERVICE("literal_URI") (i.e. no other - // calculation involved, not even a cell reference) and a cached - // result is set as hybrid string then use that as result value to - // prevent a #VALUE! result due to the "Automatic update of - // external links has been disabled." - // This will work only once, as the new formula cell result won't - // be a hybrid anymore. - /* TODO: the FormulaError::LinkFormulaNeedingCheck could be used as - * a signal for the formula cell to keep the hybrid string as - * result of the overall formula *iff* no higher prioritized - * ScRecalcMode than ONLOAD_LENIENT is present in the entire - * document (i.e. the formula result could not be influenced by an - * ONLOAD_MUST or ALWAYS recalc, necessary as we don't track - * interim results of subexpressions that could be compared), which - * also means to track setting ScRecalcMode somehow... note this is - * just a vague idea so far and might or might not work. */ - if (pMyFormulaCell && pMyFormulaCell->HasHybridStringResult()) + if (pMyFormulaCell->GetCode()->GetCodeLen() == 2) { - if (pMyFormulaCell->GetCode()->GetCodeLen() == 2) - { - formula::FormulaToken const * const * pRPN = pMyFormulaCell->GetCode()->GetCode(); - if (pRPN[0]->GetType() == formula::svString && pRPN[1]->GetOpCode() == ocWebservice) - PushString( pMyFormulaCell->GetResultString()); - else - PushError(FormulaError::LinkFormulaNeedingCheck); - } + formula::FormulaToken const * const * pRPN = pMyFormulaCell->GetCode()->GetCode(); + if (pRPN[0]->GetType() == formula::svString && pRPN[1]->GetOpCode() == ocWebservice) + PushString( pMyFormulaCell->GetResultString()); else PushError(FormulaError::LinkFormulaNeedingCheck); } @@ -397,11 +395,13 @@ void ScInterpreter::ScWebservice() PushError(FormulaError::LinkFormulaNeedingCheck); } else - PushError(FormulaError::NoValue); - - pDok->EnableIdle(bOldEnabled); - mpLinkManager->CloseCachedComps(); + PushError(FormulaError::LinkFormulaNeedingCheck); } + else + PushError(FormulaError::NoValue); + + pDok->EnableIdle(bOldEnabled); + mpLinkManager->CloseCachedComps(); } /** @@ -417,38 +417,38 @@ void ScInterpreter::ScWebservice() void ScInterpreter::ScEncodeURL() { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 1 ) ) + if ( !MustHaveParamCount( nParamCount, 1 ) ) + return; + + OUString aStr = GetString().getString(); + if ( aStr.isEmpty() ) { - OUString aStr = GetString().getString(); - if ( aStr.isEmpty() ) - { - PushError( FormulaError::NoValue ); - return; - } + PushError( FormulaError::NoValue ); + return; + } - OString aUtf8Str( aStr.toUtf8()); - const sal_Int32 nLen = aUtf8Str.getLength(); - OStringBuffer aUrlBuf( nLen ); - for ( int i = 0; i < nLen; i++ ) + OString aUtf8Str( aStr.toUtf8()); + const sal_Int32 nLen = aUtf8Str.getLength(); + OStringBuffer aUrlBuf( nLen ); + for ( int i = 0; i < nLen; i++ ) + { + char c = aUtf8Str[ i ]; + if ( rtl::isAsciiAlphanumeric( static_cast<unsigned char>( c ) ) || c == '-' || c == '_' ) + aUrlBuf.append( c ); + else { - char c = aUtf8Str[ i ]; - if ( rtl::isAsciiAlphanumeric( static_cast<unsigned char>( c ) ) || c == '-' || c == '_' ) - aUrlBuf.append( c ); - else - { - aUrlBuf.append( '%' ); - OString convertedChar = OString::number( static_cast<unsigned char>( c ), 16 ).toAsciiUpperCase(); - // RFC 3986 indicates: - // "A percent-encoded octet is encoded as a character triplet, - // consisting of the percent character "%" followed by the two hexadecimal digits - // representing that octet's numeric value" - if (convertedChar.getLength() == 1) - aUrlBuf.append("0"); - aUrlBuf.append(convertedChar); - } + aUrlBuf.append( '%' ); + OString convertedChar = OString::number( static_cast<unsigned char>( c ), 16 ).toAsciiUpperCase(); + // RFC 3986 indicates: + // "A percent-encoded octet is encoded as a character triplet, + // consisting of the percent character "%" followed by the two hexadecimal digits + // representing that octet's numeric value" + if (convertedChar.getLength() == 1) + aUrlBuf.append("0"); + aUrlBuf.append(convertedChar); } - PushString( OUString::fromUtf8( aUrlBuf.makeStringAndClear() ) ); } + PushString( OUString::fromUtf8( aUrlBuf.makeStringAndClear() ) ); } void ScInterpreter::ScDebugVar() @@ -521,45 +521,45 @@ void ScInterpreter::ScErfc() void ScInterpreter::ScColor() { sal_uInt8 nParamCount = GetByte(); - if(MustHaveParamCount(nParamCount, 3, 4)) - { - double nAlpha = 0; - if(nParamCount == 4) - nAlpha = rtl::math::approxFloor(GetDouble()); + if(!MustHaveParamCount(nParamCount, 3, 4)) + return; - if(nAlpha < 0 || nAlpha > 255) - { - PushIllegalArgument(); - return; - } + double nAlpha = 0; + if(nParamCount == 4) + nAlpha = rtl::math::approxFloor(GetDouble()); - double nBlue = rtl::math::approxFloor(GetDouble()); + if(nAlpha < 0 || nAlpha > 255) + { + PushIllegalArgument(); + return; + } - if(nBlue < 0 || nBlue > 255) - { - PushIllegalArgument(); - return; - } + double nBlue = rtl::math::approxFloor(GetDouble()); - double nGreen = rtl::math::approxFloor(GetDouble()); + if(nBlue < 0 || nBlue > 255) + { + PushIllegalArgument(); + return; + } - if(nGreen < 0 || nGreen > 255) - { - PushIllegalArgument(); - return; - } + double nGreen = rtl::math::approxFloor(GetDouble()); - double nRed = rtl::math::approxFloor(GetDouble()); + if(nGreen < 0 || nGreen > 255) + { + PushIllegalArgument(); + return; + } - if(nRed < 0 || nRed > 255) - { - PushIllegalArgument(); - return; - } + double nRed = rtl::math::approxFloor(GetDouble()); - double nVal = 256*256*256*nAlpha + 256*256*nRed + 256*nGreen + nBlue; - PushDouble(nVal); + if(nRed < 0 || nRed > 255) + { + PushIllegalArgument(); + return; } + + double nVal = 256*256*256*nAlpha + 256*256*nRed + 256*nGreen + nBlue; + PushDouble(nVal); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/tool/interpr8.cxx b/sc/source/core/tool/interpr8.cxx index b9e09dfef564..95580dde72db 100644 --- a/sc/source/core/tool/interpr8.cxx +++ b/sc/source/core/tool/interpr8.cxx @@ -1512,20 +1512,164 @@ void ScInterpreter::ScTextJoin_MS() { short nParamCount = GetByte(); - if ( MustHaveParamCountMin( nParamCount, 3 ) ) + if ( !MustHaveParamCountMin( nParamCount, 3 ) ) + return; + + //reverse order of parameter stack to simplify processing + ReverseStack( nParamCount ); + + // get aDelimiters and bSkipEmpty + std::vector< OUString > aDelimiters; + size_t nRefInList = 0; + switch ( GetStackType() ) { - //reverse order of parameter stack to simplify processing - ReverseStack( nParamCount ); + case svString: + case svDouble: + aDelimiters.push_back( GetString().getString() ); + break; + case svSingleRef : + { + ScAddress aAdr; + PopSingleRef( aAdr ); + if ( nGlobalError != FormulaError::NONE ) + break; + ScRefCellValue aCell( *pDok, aAdr ); + if ( !aCell.isEmpty() ) + { + if ( !aCell.hasEmptyValue() ) + { + svl::SharedString aSS; + GetCellString( aSS, aCell); + aDelimiters.push_back( aSS.getString()); + } + } + } + break; + case svDoubleRef : + case svRefList : + { + ScRange aRange; + PopDoubleRef( aRange, nParamCount, nRefInList); + if ( nGlobalError != FormulaError::NONE ) + break; + // we need to read row for row, so we can't use ScCellIterator + SCCOL nCol1, nCol2; + SCROW nRow1, nRow2; + SCTAB nTab1, nTab2; + aRange.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); + if ( nTab1 != nTab2 ) + { + SetError( FormulaError::IllegalParameter); + break; + } + if ( nRow1 > nRow2 ) + std::swap( nRow1, nRow2 ); + if ( nCol1 > nCol2 ) + std::swap( nCol1, nCol2 ); + ScAddress aAdr; + aAdr.SetTab( nTab1 ); + for ( SCROW nRow = nRow1; nRow <= nRow2; nRow++ ) + { + for ( SCCOL nCol = nCol1; nCol <= nCol2; nCol++ ) + { + aAdr.SetRow( nRow ); + aAdr.SetCol( nCol ); + ScRefCellValue aCell( *pDok, aAdr ); + if ( !aCell.isEmpty() ) + { + if ( !aCell.hasEmptyValue() ) + { + svl::SharedString aSS; + GetCellString( aSS, aCell); + aDelimiters.push_back( aSS.getString()); + } + } + else + aDelimiters.emplace_back("" ); + } + } + } + break; + case svMatrix : + case svExternalSingleRef: + case svExternalDoubleRef: + { + ScMatrixRef pMat = GetMatrix(); + if (pMat) + { + SCSIZE nC, nR; + pMat->GetDimensions(nC, nR); + if (nC == 0 || nR == 0) + SetError(FormulaError::IllegalArgument); + else + { + for ( SCSIZE j = 0; j < nC; j++ ) + { + for (SCSIZE k = 0; k < nR; k++ ) + { + if ( !pMat->IsEmpty( j, k ) ) + { + if ( pMat->IsStringOrEmpty( j, k ) ) + aDelimiters.push_back( pMat->GetString( j, k ).getString() ); + else + { + if ( pMat->IsValue( j, k ) ) + aDelimiters.push_back( pMat->GetString( *pFormatter, j, k ).getString() ); + } + } + else + aDelimiters.emplace_back("" ); + } + } + } + } + } + break; + default: + PopError(); + SetError( FormulaError::IllegalArgument); + break; + } + if ( aDelimiters.empty() ) + { + PushIllegalArgument(); + return; + } + SCSIZE nSize = aDelimiters.size(); + bool bSkipEmpty = static_cast< bool >( GetDouble() ); + nParamCount -= 2; - // get aDelimiters and bSkipEmpty - std::vector< OUString > aDelimiters; - size_t nRefInList = 0; + OUStringBuffer aResBuf; + bool bFirst = true; + SCSIZE nIdx = 0; + nRefInList = 0; + // get the strings to be joined + while ( nParamCount-- > 0 && nGlobalError == FormulaError::NONE ) + { switch ( GetStackType() ) { case svString: case svDouble: - aDelimiters.push_back( GetString().getString() ); - break; + { + OUString aStr = GetString().getString(); + if ( !aStr.isEmpty() || !bSkipEmpty ) + { + if ( !bFirst ) + { + aResBuf.append( aDelimiters[ nIdx ] ); + if ( nSize > 1 ) + { + if ( ++nIdx >= nSize ) + nIdx = 0; + } + } + else + bFirst = false; + if (CheckStringResultLen( aResBuf, aStr)) + aResBuf.append( aStr ); + } + } + break; case svSingleRef : { ScAddress aAdr; @@ -1533,15 +1677,34 @@ void ScInterpreter::ScTextJoin_MS() if ( nGlobalError != FormulaError::NONE ) break; ScRefCellValue aCell( *pDok, aAdr ); + OUString aStr; if ( !aCell.isEmpty() ) { if ( !aCell.hasEmptyValue() ) { svl::SharedString aSS; GetCellString( aSS, aCell); - aDelimiters.push_back( aSS.getString()); + aStr = aSS.getString(); } } + else + aStr.clear(); + if ( !aStr.isEmpty() || !bSkipEmpty ) + { + if ( !bFirst ) + { + aResBuf.append( aDelimiters[ nIdx ] ); + if ( nSize > 1 ) + { + if ( ++nIdx >= nSize ) + nIdx = 0; + } + } + else + bFirst = false; + if (CheckStringResultLen( aResBuf, aStr)) + aResBuf.append( aStr ); + } } break; case svDoubleRef : @@ -1567,6 +1730,7 @@ void ScInterpreter::ScTextJoin_MS() std::swap( nCol1, nCol2 ); ScAddress aAdr; aAdr.SetTab( nTab1 ); + OUString aStr; for ( SCROW nRow = nRow1; nRow <= nRow2; nRow++ ) { for ( SCCOL nCol = nCol1; nCol <= nCol2; nCol++ ) @@ -1580,11 +1744,27 @@ void ScInterpreter::ScTextJoin_MS() { svl::SharedString aSS; GetCellString( aSS, aCell); - aDelimiters.push_back( aSS.getString()); + aStr = aSS.getString(); } } else - aDelimiters.emplace_back("" ); + aStr.clear(); + if ( !aStr.isEmpty() || !bSkipEmpty ) + { + if ( !bFirst ) + { + aResBuf.append( aDelimiters[ nIdx ] ); + if ( nSize > 1 ) + { + if ( ++nIdx >= nSize ) + nIdx = 0; + } + } + else + bFirst = false; + if (CheckStringResultLen( aResBuf, aStr)) + aResBuf.append( aStr ); + } } } } @@ -1602,6 +1782,7 @@ void ScInterpreter::ScTextJoin_MS() SetError(FormulaError::IllegalArgument); else { + OUString aStr; for ( SCSIZE j = 0; j < nC; j++ ) { for (SCSIZE k = 0; k < nR; k++ ) @@ -1609,243 +1790,62 @@ void ScInterpreter::ScTextJoin_MS() if ( !pMat->IsEmpty( j, k ) ) { if ( pMat->IsStringOrEmpty( j, k ) ) - aDelimiters.push_back( pMat->GetString( j, k ).getString() ); + aStr = pMat->GetString( j, k ).getString(); else { if ( pMat->IsValue( j, k ) ) - aDelimiters.push_back( pMat->GetString( *pFormatter, j, k ).getString() ); - } - } - else - aDelimiters.emplace_back("" ); - } - } - } - } - } - break; - default: - PopError(); - SetError( FormulaError::IllegalArgument); - break; - } - if ( aDelimiters.empty() ) - { - PushIllegalArgument(); - return; - } - SCSIZE nSize = aDelimiters.size(); - bool bSkipEmpty = static_cast< bool >( GetDouble() ); - nParamCount -= 2; - - OUStringBuffer aResBuf; - bool bFirst = true; - SCSIZE nIdx = 0; - nRefInList = 0; - // get the strings to be joined - while ( nParamCount-- > 0 && nGlobalError == FormulaError::NONE ) - { - switch ( GetStackType() ) - { - case svString: - case svDouble: - { - OUString aStr = GetString().getString(); - if ( !aStr.isEmpty() || !bSkipEmpty ) - { - if ( !bFirst ) - { - aResBuf.append( aDelimiters[ nIdx ] ); - if ( nSize > 1 ) - { - if ( ++nIdx >= nSize ) - nIdx = 0; - } - } - else - bFirst = false; - if (CheckStringResultLen( aResBuf, aStr)) - aResBuf.append( aStr ); - } - } - break; - case svSingleRef : - { - ScAddress aAdr; - PopSingleRef( aAdr ); - if ( nGlobalError != FormulaError::NONE ) - break; - ScRefCellValue aCell( *pDok, aAdr ); - OUString aStr; - if ( !aCell.isEmpty() ) - { - if ( !aCell.hasEmptyValue() ) - { - svl::SharedString aSS; - GetCellString( aSS, aCell); - aStr = aSS.getString(); - } - } - else - aStr.clear(); - if ( !aStr.isEmpty() || !bSkipEmpty ) - { - if ( !bFirst ) - { - aResBuf.append( aDelimiters[ nIdx ] ); - if ( nSize > 1 ) - { - if ( ++nIdx >= nSize ) - nIdx = 0; - } - } - else - bFirst = false; - if (CheckStringResultLen( aResBuf, aStr)) - aResBuf.append( aStr ); - } - } - break; - case svDoubleRef : - case svRefList : - { - ScRange aRange; - PopDoubleRef( aRange, nParamCount, nRefInList); - if ( nGlobalError != FormulaError::NONE ) - break; - // we need to read row for row, so we can't use ScCellIterator - SCCOL nCol1, nCol2; - SCROW nRow1, nRow2; - SCTAB nTab1, nTab2; - aRange.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); - if ( nTab1 != nTab2 ) - { - SetError( FormulaError::IllegalParameter); - break; - } - if ( nRow1 > nRow2 ) - std::swap( nRow1, nRow2 ); - if ( nCol1 > nCol2 ) - std::swap( nCol1, nCol2 ); - ScAddress aAdr; - aAdr.SetTab( nTab1 ); - OUString aStr; - for ( SCROW nRow = nRow1; nRow <= nRow2; nRow++ ) - { - for ( SCCOL nCol = nCol1; nCol <= nCol2; nCol++ ) - { - aAdr.SetRow( nRow ); - aAdr.SetCol( nCol ); - ScRefCellValue aCell( *pDok, aAdr ); - if ( !aCell.isEmpty() ) - { - if ( !aCell.hasEmptyValue() ) - { - svl::SharedString aSS; - GetCellString( aSS, aCell); - aStr = aSS.getString(); - } - } - else - aStr.clear(); - if ( !aStr.isEmpty() || !bSkipEmpty ) - { - if ( !bFirst ) - { - aResBuf.append( aDelimiters[ nIdx ] ); - if ( nSize > 1 ) - { - if ( ++nIdx >= nSize ) - nIdx = 0; + aStr = pMat->GetString( *pFormatter, j, k ).getString(); } } else - bFirst = false; - if (CheckStringResultLen( aResBuf, aStr)) - aResBuf.append( aStr ); - } - } - } - } - break; - case svMatrix : - case svExternalSingleRef: - case svExternalDoubleRef: - { - ScMatrixRef pMat = GetMatrix(); - if (pMat) - { - SCSIZE nC, nR; - pMat->GetDimensions(nC, nR); - if (nC == 0 || nR == 0) - SetError(FormulaError::IllegalArgument); - else - { - OUString aStr; - for ( SCSIZE j = 0; j < nC; j++ ) - { - for (SCSIZE k = 0; k < nR; k++ ) + aStr.clear(); + if ( !aStr.isEmpty() || !bSkipEmpty ) { - if ( !pMat->IsEmpty( j, k ) ) + if ( !bFirst ) { - if ( pMat->IsStringOrEmpty( j, k ) ) - aStr = pMat->GetString( j, k ).getString(); - else + aResBuf.append( aDelimiters[ nIdx ] ); + if ( nSize > 1 ) { - if ( pMat->IsValue( j, k ) ) - aStr = pMat->GetString( *pFormatter, j, k ).getString(); + if ( ++nIdx >= nSize ) + nIdx = 0; } } else - aStr.clear(); - if ( !aStr.isEmpty() || !bSkipEmpty ) - { - if ( !bFirst ) - { - aResBuf.append( aDelimiters[ nIdx ] ); - if ( nSize > 1 ) - { - if ( ++nIdx >= nSize ) - nIdx = 0; - } - } - else - bFirst = false; - if (CheckStringResultLen( aResBuf, aStr)) - aResBuf.append( aStr ); - } + bFirst = false; + if (CheckStringResultLen( aResBuf, aStr)) + aResBuf.append( aStr ); } } } } } - break; - case svMissing : + } + break; + case svMissing : + { + if ( !bSkipEmpty ) { - if ( !bSkipEmpty ) + if ( !bFirst ) { - if ( !bFirst ) + aResBuf.append( aDelimiters[ nIdx ] ); + if ( nSize > 1 ) { - aResBuf.append( aDelimiters[ nIdx ] ); - if ( nSize > 1 ) - { - if ( ++nIdx >= nSize ) - nIdx = 0; - } + if ( ++nIdx >= nSize ) + nIdx = 0; } - else - bFirst = false; } + else + bFirst = false; } - break; - default: - PopError(); - SetError( FormulaError::IllegalArgument); - break; } + break; + default: + PopError(); + SetError( FormulaError::IllegalArgument); + break; } - PushString( aResBuf.makeStringAndClear() ); } + PushString( aResBuf.makeStringAndClear() ); } diff --git a/sc/source/core/tool/jumpmatrix.cxx b/sc/source/core/tool/jumpmatrix.cxx index 517447b3ae2d..e06cfcad900b 100644 --- a/sc/source/core/tool/jumpmatrix.cxx +++ b/sc/source/core/tool/jumpmatrix.cxx @@ -135,30 +135,30 @@ void ScJumpMatrix::GetResMatDimensions(SCSIZE& rCols, SCSIZE& rRows) void ScJumpMatrix::SetNewResMat(SCSIZE nNewCols, SCSIZE nNewRows) { - if (nNewCols > nResMatCols || nNewRows > nResMatRows) + if (nNewCols <= nResMatCols && nNewRows <= nResMatRows) + return; + + FlushBufferOtherThan( BUFFER_NONE, 0, 0); + pMat = pMat->CloneAndExtend(nNewCols, nNewRows); + if (nResMatCols < nNewCols) { - FlushBufferOtherThan( BUFFER_NONE, 0, 0); - pMat = pMat->CloneAndExtend(nNewCols, nNewRows); - if (nResMatCols < nNewCols) - { - pMat->FillDouble( - CreateDoubleError(FormulaError::NotAvailable), - nResMatCols, 0, nNewCols - 1, nResMatRows - 1); - } - if (nResMatRows < nNewRows) - { - pMat->FillDouble( - CreateDoubleError(FormulaError::NotAvailable), - 0, nResMatRows, nNewCols - 1, nNewRows - 1); - } - if (nRows == 1 && nCurCol != 0) - { - nCurCol = 0; - nCurRow = nResMatRows - 1; - } - nResMatCols = nNewCols; - nResMatRows = nNewRows; + pMat->FillDouble( + CreateDoubleError(FormulaError::NotAvailable), + nResMatCols, 0, nNewCols - 1, nResMatRows - 1); + } + if (nResMatRows < nNewRows) + { + pMat->FillDouble( + CreateDoubleError(FormulaError::NotAvailable), + 0, nResMatRows, nNewCols - 1, nNewRows - 1); + } + if (nRows == 1 && nCurCol != 0) + { + nCurCol = 0; + nCurRow = nResMatRows - 1; } + nResMatCols = nNewCols; + nResMatRows = nNewRows; } bool ScJumpMatrix::HasResultMatrix() const diff --git a/sc/source/core/tool/printopt.cxx b/sc/source/core/tool/printopt.cxx index 16b5222a3887..dfbe413c0458 100644 --- a/sc/source/core/tool/printopt.cxx +++ b/sc/source/core/tool/printopt.cxx @@ -91,26 +91,26 @@ ScPrintCfg::ScPrintCfg() : Sequence<Any> aValues = GetProperties(aNames); const Any* pValues = aValues.getConstArray(); OSL_ENSURE(aValues.getLength() == aNames.getLength(), "GetProperties failed"); - if(aValues.getLength() == aNames.getLength()) + if(aValues.getLength() != aNames.getLength()) + return; + + for(int nProp = 0; nProp < aNames.getLength(); nProp++) { - for(int nProp = 0; nProp < aNames.getLength(); nProp++) + OSL_ENSURE(pValues[nProp].hasValue(), "property value missing"); + if(pValues[nProp].hasValue()) { - OSL_ENSURE(pValues[nProp].hasValue(), "property value missing"); - if(pValues[nProp].hasValue()) + switch(nProp) { - switch(nProp) - { - case SCPRINTOPT_EMPTYPAGES: - // reversed - SetSkipEmpty( !ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); - break; - case SCPRINTOPT_ALLSHEETS: - SetAllSheets( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); - break; - case SCPRINTOPT_FORCEBREAKS: - SetForceBreaks( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); - break; - } + case SCPRINTOPT_EMPTYPAGES: + // reversed + SetSkipEmpty( !ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); + break; + case SCPRINTOPT_ALLSHEETS: + SetAllSheets( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); + break; + case SCPRINTOPT_FORCEBREAKS: + SetForceBreaks( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); + break; } } } diff --git a/sc/source/core/tool/progress.cxx b/sc/source/core/tool/progress.cxx index fe9ae274c986..ae1c96cab5e3 100644 --- a/sc/source/core/tool/progress.cxx +++ b/sc/source/core/tool/progress.cxx @@ -154,27 +154,27 @@ void ScProgress::CreateInterpretProgress( ScDocument* pDoc, bool bWait ) void ScProgress::DeleteInterpretProgress() { - if ( nInterpretProgress ) + if ( !nInterpretProgress ) + return; + + /* Do not decrement 'nInterpretProgress', before 'pInterpretProgress' + is deleted. In rare cases, deletion of 'pInterpretProgress' causes + a refresh of the sheet window which may call CreateInterpretProgress + and DeleteInterpretProgress again (from Output::DrawStrings), + resulting in double deletion of 'pInterpretProgress'. */ + if ( nInterpretProgress == 1 ) { - /* Do not decrement 'nInterpretProgress', before 'pInterpretProgress' - is deleted. In rare cases, deletion of 'pInterpretProgress' causes - a refresh of the sheet window which may call CreateInterpretProgress - and DeleteInterpretProgress again (from Output::DrawStrings), - resulting in double deletion of 'pInterpretProgress'. */ - if ( nInterpretProgress == 1 ) + if ( pInterpretProgress != &theDummyInterpretProgress ) { - if ( pInterpretProgress != &theDummyInterpretProgress ) - { - // move pointer to local temporary to avoid double deletion - ScProgress* pTmpProgress = pInterpretProgress; - pInterpretProgress = &theDummyInterpretProgress; - delete pTmpProgress; - } - if ( pInterpretDoc ) - pInterpretDoc->EnableIdle(bIdleWasEnabled); + // move pointer to local temporary to avoid double deletion + ScProgress* pTmpProgress = pInterpretProgress; + pInterpretProgress = &theDummyInterpretProgress; + delete pTmpProgress; } - --nInterpretProgress; + if ( pInterpretDoc ) + pInterpretDoc->EnableIdle(bIdleWasEnabled); } + --nInterpretProgress; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/tool/queryparam.cxx b/sc/source/core/tool/queryparam.cxx index 0e416276324c..705811f10e66 100644 --- a/sc/source/core/tool/queryparam.cxx +++ b/sc/source/core/tool/queryparam.cxx @@ -276,22 +276,22 @@ void ScQueryParamBase::FillInExcelSyntax( } } - if (pFormatter) - { - sal_uInt32 nFormat = 0; - bool bNumber = pFormatter->IsNumberFormat( rItem.maString.getString(), nFormat, rItem.mfVal); - rItem.meType = bNumber ? ScQueryEntry::ByValue : ScQueryEntry::ByString; - - /* TODO: pFormatter currently is also used as a flag whether matching - * empty cells with an empty string is triggered from the interpreter. - * This could be handled independently if all queries should support - * it, needs to be evaluated if that actually is desired. */ - - // (empty = empty) is a match, and (empty <> not-empty) also is a - // match. (empty = 0) is not a match. - rItem.mbMatchEmpty = ((rEntry.eOp == SC_EQUAL && rItem.maString.isEmpty()) - || (rEntry.eOp == SC_NOT_EQUAL && !rItem.maString.isEmpty())); - } + if (!pFormatter) + return; + + sal_uInt32 nFormat = 0; + bool bNumber = pFormatter->IsNumberFormat( rItem.maString.getString(), nFormat, rItem.mfVal); + rItem.meType = bNumber ? ScQueryEntry::ByValue : ScQueryEntry::ByString; + + /* TODO: pFormatter currently is also used as a flag whether matching + * empty cells with an empty string is triggered from the interpreter. + * This could be handled independently if all queries should support + * it, needs to be evaluated if that actually is desired. */ + + // (empty = empty) is a match, and (empty <> not-empty) also is a + // match. (empty = 0) is not a match. + rItem.mbMatchEmpty = ((rEntry.eOp == SC_EQUAL && rItem.maString.isEmpty()) + || (rEntry.eOp == SC_NOT_EQUAL && !rItem.maString.isEmpty())); } ScQueryParamTable::ScQueryParamTable() : diff --git a/sc/source/core/tool/rangelst.cxx b/sc/source/core/tool/rangelst.cxx index 4810566e5fc2..5b156e2d3449 100644 --- a/sc/source/core/tool/rangelst.cxx +++ b/sc/source/core/tool/rangelst.cxx @@ -1237,36 +1237,36 @@ void ScRangePairList::UpdateReference( UpdateRefMode eUpdateRefMode, const ScDocument* pDoc, const ScRange& rWhere, SCCOL nDx, SCROW nDy, SCTAB nDz ) { - if ( !maPairs.empty() ) + if ( maPairs.empty() ) + return; + + SCCOL nCol1; + SCROW nRow1; + SCTAB nTab1; + SCCOL nCol2; + SCROW nRow2; + SCTAB nTab2; + rWhere.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); + for (ScRangePair & rR : maPairs) { - SCCOL nCol1; - SCROW nRow1; - SCTAB nTab1; - SCCOL nCol2; - SCROW nRow2; - SCTAB nTab2; - rWhere.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); - for (ScRangePair & rR : maPairs) + for ( sal_uInt16 j=0; j<2; j++ ) { - for ( sal_uInt16 j=0; j<2; j++ ) + ScRange& rRange = rR.GetRange(j); + SCCOL theCol1; + SCROW theRow1; + SCTAB theTab1; + SCCOL theCol2; + SCROW theRow2; + SCTAB theTab2; + rRange.GetVars( theCol1, theRow1, theTab1, theCol2, theRow2, theTab2 ); + if ( ScRefUpdate::Update( pDoc, eUpdateRefMode, + nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, + nDx, nDy, nDz, + theCol1, theRow1, theTab1, theCol2, theRow2, theTab2 ) + != UR_NOTHING ) { - ScRange& rRange = rR.GetRange(j); - SCCOL theCol1; - SCROW theRow1; - SCTAB theTab1; - SCCOL theCol2; - SCROW theRow2; - SCTAB theTab2; - rRange.GetVars( theCol1, theRow1, theTab1, theCol2, theRow2, theTab2 ); - if ( ScRefUpdate::Update( pDoc, eUpdateRefMode, - nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, - nDx, nDy, nDz, - theCol1, theRow1, theTab1, theCol2, theRow2, theTab2 ) - != UR_NOTHING ) - { - rRange.aStart.Set( theCol1, theRow1, theTab1 ); - rRange.aEnd.Set( theCol2, theRow2, theTab2 ); - } + rRange.aStart.Set( theCol1, theRow1, theTab1 ); + rRange.aEnd.Set( theCol2, theRow2, theTab2 ); } } } diff --git a/sc/source/core/tool/rangenam.cxx b/sc/source/core/tool/rangenam.cxx index b799a6ad0353..1c54fd09ac25 100644 --- a/sc/source/core/tool/rangenam.cxx +++ b/sc/source/core/tool/rangenam.cxx @@ -155,25 +155,25 @@ void ScRangeData::CompileRangeData( const OUString& rSymbol, bool bSetError ) aComp.SetExtendedErrorDetection( ScCompiler::EXTENDED_ERROR_DETECTION_NAME_NO_BREAK); pCode = aComp.CompileString( rSymbol ); pCode->SetFromRangeName(true); - if( pCode->GetCodeError() == FormulaError::NONE ) + if( pCode->GetCodeError() != FormulaError::NONE ) + return; + + FormulaTokenArrayPlainIterator aIter(*pCode); + FormulaToken* p = aIter.GetNextReference(); + if( p ) { - FormulaTokenArrayPlainIterator aIter(*pCode); - FormulaToken* p = aIter.GetNextReference(); - if( p ) - { - // first token is a reference - /* FIXME: wouldn't that need a check if it's exactly one reference? */ - if( p->GetType() == svSingleRef ) - eType = eType | Type::AbsPos; - else - eType = eType | Type::AbsArea; - } - // For manual input set an error for an incomplete formula. - if (!pDoc->IsImportingXML()) - { - aComp.CompileTokenArray(); - pCode->DelRPN(); - } + // first token is a reference + /* FIXME: wouldn't that need a check if it's exactly one reference? */ + if( p->GetType() == svSingleRef ) + eType = eType | Type::AbsPos; + else + eType = eType | Type::AbsArea; + } + // For manual input set an error for an incomplete formula. + if (!pDoc->IsImportingXML()) + { + aComp.CompileTokenArray(); + pCode->DelRPN(); } } @@ -556,48 +556,48 @@ void ScRangeData::ValidateTabRefs() } SCTAB nTabCount = pDoc->GetTableCount(); - if ( nMaxTab >= nTabCount && nMinTab > 0 ) - { - // move position and relative tab refs - // The formulas that use the name are not changed by this + if ( nMaxTab < nTabCount || nMinTab <= 0 ) + return; + + // move position and relative tab refs + // The formulas that use the name are not changed by this - SCTAB nMove = nMinTab; - ScAddress aOldPos = aPos; - aPos.SetTab( aPos.Tab() - nMove ); + SCTAB nMove = nMinTab; + ScAddress aOldPos = aPos; + aPos.SetTab( aPos.Tab() - nMove ); - aIter.Reset(); - while ( ( t = aIter.GetNextReference() ) != nullptr ) + aIter.Reset(); + while ( ( t = aIter.GetNextReference() ) != nullptr ) + { + switch (t->GetType()) { - switch (t->GetType()) + case svSingleRef: + { + ScSingleRefData& rRef = *t->GetSingleRef(); + if (!rRef.IsTabDeleted()) + { + ScAddress aAbs = rRef.toAbs(pDoc, aOldPos); + rRef.SetAddress(pDoc->GetSheetLimits(), aAbs, aPos); + } + } + break; + case svDoubleRef: { - case svSingleRef: + ScComplexRefData& rRef = *t->GetDoubleRef(); + if (!rRef.Ref1.IsTabDeleted()) { - ScSingleRefData& rRef = *t->GetSingleRef(); - if (!rRef.IsTabDeleted()) - { - ScAddress aAbs = rRef.toAbs(pDoc, aOldPos); - rRef.SetAddress(pDoc->GetSheetLimits(), aAbs, aPos); - } + ScAddress aAbs = rRef.Ref1.toAbs(pDoc, aOldPos); + rRef.Ref1.SetAddress(pDoc->GetSheetLimits(), aAbs, aPos); } - break; - case svDoubleRef: + if (!rRef.Ref2.IsTabDeleted()) { - ScComplexRefData& rRef = *t->GetDoubleRef(); - if (!rRef.Ref1.IsTabDeleted()) - { - ScAddress aAbs = rRef.Ref1.toAbs(pDoc, aOldPos); - rRef.Ref1.SetAddress(pDoc->GetSheetLimits(), aAbs, aPos); - } - if (!rRef.Ref2.IsTabDeleted()) - { - ScAddress aAbs = rRef.Ref2.toAbs(pDoc, aOldPos); - rRef.Ref2.SetAddress(pDoc->GetSheetLimits(), aAbs, aPos); - } + ScAddress aAbs = rRef.Ref2.toAbs(pDoc, aOldPos); + rRef.Ref2.SetAddress(pDoc->GetSheetLimits(), aAbs, aPos); } - break; - default: - ; } + break; + default: + ; } } } diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx index 6618fa468a3f..7772ca629fff 100644 --- a/sc/source/core/tool/token.cxx +++ b/sc/source/core/tool/token.cxx @@ -1333,21 +1333,21 @@ void ScTokenArray::CheckForThreading( const FormulaToken& r ) return; } - if (eOp == ocPush) + if (eOp != ocPush) + return; + + switch (r.GetType()) { - switch (r.GetType()) - { - case svExternalDoubleRef: - case svExternalSingleRef: - case svExternalName: - case svMatrix: - SAL_INFO("sc.core.formulagroup", "opcode ocPush: variable type " << StackVarEnumToString(r.GetType()) - << " disables threaded calculation of formula group"); - mbThreadingEnabled = false; - return; - default: - break; - } + case svExternalDoubleRef: + case svExternalSingleRef: + case svExternalName: + case svMatrix: + SAL_INFO("sc.core.formulagroup", "opcode ocPush: variable type " << StackVarEnumToString(r.GetType()) + << " disables threaded calculation of formula group"); + mbThreadingEnabled = false; + return; + default: + break; } } diff --git a/sc/source/core/tool/tokenstringcontext.cxx b/sc/source/core/tool/tokenstringcontext.cxx index b5ec7d5356e3..8a326d081a79 100644 --- a/sc/source/core/tool/tokenstringcontext.cxx +++ b/sc/source/core/tool/tokenstringcontext.cxx @@ -89,18 +89,18 @@ TokenStringContext::TokenStringContext( const ScDocument* pDoc, formula::Formula } // Fetch all relevant bits for external references. - if (pDoc->HasExternalRefManager()) + if (!pDoc->HasExternalRefManager()) + return; + + const ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager(); + maExternalFileNames = pRefMgr->getAllCachedExternalFileNames(); + for (size_t i = 0, n = maExternalFileNames.size(); i < n; ++i) { - const ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager(); - maExternalFileNames = pRefMgr->getAllCachedExternalFileNames(); - for (size_t i = 0, n = maExternalFileNames.size(); i < n; ++i) - { - sal_uInt16 nFileId = static_cast<sal_uInt16>(i); - std::vector<OUString> aTabNames; - pRefMgr->getAllCachedTableNames(nFileId, aTabNames); - if (!aTabNames.empty()) - maExternalCachedTabNames.emplace(nFileId, aTabNames); - } + sal_uInt16 nFileId = static_cast<sal_uInt16>(i); + std::vector<OUString> aTabNames; + pRefMgr->getAllCachedTableNames(nFileId, aTabNames); + if (!aTabNames.empty()) + maExternalCachedTabNames.emplace(nFileId, aTabNames); } } diff --git a/sc/source/core/tool/unitconv.cxx b/sc/source/core/tool/unitconv.cxx index 3d6681a5caa3..9fc54aaed3d2 100644 --- a/sc/source/core/tool/unitconv.cxx +++ b/sc/source/core/tool/unitconv.cxx @@ -57,44 +57,44 @@ ScUnitConverter::ScUnitConverter() const Sequence<OUString> aNodeNames = aConfigItem.GetNodeNames( "" ); long nNodeCount = aNodeNames.getLength(); - if ( nNodeCount ) + if ( !nNodeCount ) + return; + + Sequence<OUString> aValNames( nNodeCount * 3 ); + OUString* pValNameArray = aValNames.getArray(); + const OUString sSlash('/'); + + long nIndex = 0; + for (const OUString& rNode : aNodeNames) { - Sequence<OUString> aValNames( nNodeCount * 3 ); - OUString* pValNameArray = aValNames.getArray(); - const OUString sSlash('/'); - - long nIndex = 0; - for (const OUString& rNode : aNodeNames) - { - OUString sPrefix = rNode + sSlash; - - pValNameArray[nIndex++] = sPrefix + CFGSTR_UNIT_FROM; - pValNameArray[nIndex++] = sPrefix + CFGSTR_UNIT_TO; - pValNameArray[nIndex++] = sPrefix + CFGSTR_UNIT_FACTOR; - } - - Sequence<Any> aProperties = aConfigItem.GetProperties(aValNames); - - if (aProperties.getLength() == aValNames.getLength()) - { - const Any* pProperties = aProperties.getConstArray(); - - OUString sFromUnit; - OUString sToUnit; - double fFactor = 0; - - nIndex = 0; - for (long i=0; i<nNodeCount; i++) - { - pProperties[nIndex++] >>= sFromUnit; - pProperties[nIndex++] >>= sToUnit; - pProperties[nIndex++] >>= fFactor; - - ScUnitConverterData aNew(sFromUnit, sToUnit, fFactor); - OUString const aIndex = aNew.GetIndexString(); - maData.insert(std::make_pair(aIndex, aNew)); - } - } + OUString sPrefix = rNode + sSlash; + + pValNameArray[nIndex++] = sPrefix + CFGSTR_UNIT_FROM; + pValNameArray[nIndex++] = sPrefix + CFGSTR_UNIT_TO; + pValNameArray[nIndex++] = sPrefix + CFGSTR_UNIT_FACTOR; + } + + Sequence<Any> aProperties = aConfigItem.GetProperties(aValNames); + + if (aProperties.getLength() != aValNames.getLength()) + return; + + const Any* pProperties = aProperties.getConstArray(); + + OUString sFromUnit; + OUString sToUnit; + double fFactor = 0; + + nIndex = 0; + for (long i=0; i<nNodeCount; i++) + { + pProperties[nIndex++] >>= sFromUnit; + pProperties[nIndex++] >>= sToUnit; + pProperties[nIndex++] >>= fFactor; + + ScUnitConverterData aNew(sFromUnit, sToUnit, fFactor); + OUString const aIndex = aNew.GetIndexString(); + maData.insert(std::make_pair(aIndex, aNew)); } } |