From 382ecc31a9480fc0d19dddc917d16a7e744a00e3 Mon Sep 17 00:00:00 2001 From: Noel Grandin Date: Wed, 29 Jul 2020 16:12:49 +0200 Subject: loplugin:flatten in sc/core/tool Change-Id: Ibe5302ee320cf2e89c814dfb34ad42f9d72a25aa Reviewed-on: https://gerrit.libreoffice.org/c/core/+/99700 Tested-by: Jenkins Reviewed-by: Noel Grandin --- sc/source/core/tool/interpr2.cxx | 2782 +++++++++++++++++++------------------- 1 file changed, 1391 insertions(+), 1391 deletions(-) (limited to 'sc/source/core/tool/interpr2.cxx') 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(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(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( 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(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( 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(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( O % 31 + 1 ); - nMonth = sal::static_int_cast( 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( O % 31 + 1 ); + nMonth = sal::static_int_cast( 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 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 { - vector 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 ) + 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)) + if ( !bWeekendMask[ GetDayOfWeek( nDate1 ) ] ) { - PushIllegalArgument(); - return; + while ( nRef < nMax && nSortArray.at( nRef ) < nDate1 ) + nRef++; + if ( nRef >= nMax || nSortArray.at( nRef ) != nDate1 ) + nCnt++; } - 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 ) ] ) - { - while ( nRef < nMax && nSortArray.at( nRef ) < nDate1 ) - nRef++; - if ( nRef >= nMax || nSortArray.at( nRef ) != nDate1 ) - nCnt++; - } - ++nDate1; - } - PushDouble( static_cast( bReverse ? -nCnt : nCnt ) ); + ++nDate1; } + PushDouble( static_cast( bReverse ? -nCnt : nCnt ) ); } } void ScInterpreter::ScWorkday_MS() { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCount( nParamCount, 2, 4 ) ) - { - nFuncFmtType = SvNumFormatType::DATE; - vector 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 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( nDate - nNullDate ) ); - else + if ( !nDays ) + PushDouble( static_cast( 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( nDate - nNullDate ) ); } + PushDouble( static_cast( 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(nSign) * - ( static_cast(aDate2.GetDay()) + static_cast(aDate2.GetMonth()) * 30.0 + - static_cast(aDate2.GetYear()) * 360.0 - - static_cast(aDate1.GetDay()) - static_cast(aDate1.GetMonth()) * 30.0 - - static_cast(aDate1.GetYear()) * 360.0) ); + else + aDate2.SetDay(30); } + PushDouble( static_cast(nSign) * + ( static_cast(aDate2.GetDay()) + static_cast(aDate2.GetMonth()) * 30.0 + + static_cast(aDate2.GetYear()) * 360.0 + - static_cast(aDate1.GetDay()) - static_cast(aDate1.GetMonth()) * 30.0 + - static_cast(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) + double fx; + for ( SCSIZE j = 0; j < nC; j++ ) { - PushIllegalArgument(); - return; - } - else - { - 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( 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( 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(fIntStart); - sal_uLong nLoopEnd = static_cast(fIntEnd); + double fIntStart = ::rtl::math::approxFloor(fStart); + double fIntEnd = ::rtl::math::approxCeil(fEnd); + sal_uLong nLoopStart = static_cast(fIntStart); + sal_uLong nLoopEnd = static_cast(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(i), fFactor); + double fTerm = ScGetDDB(fCost, fSalvage, fLife, static_cast(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(fFlag); + sal_uLong nStart = static_cast(fStart); + sal_uLong nEnd = static_cast(fEnd) ; + double fPmt = ScGetPMT(fRate, fNper, fPv, 0.0, bPayInAdvance); + double fIpmt = 0.0; + if (nStart == 1) { - bool bPayInAdvance = static_cast(fFlag); - sal_uLong nStart = static_cast(fStart); - sal_uLong nEnd = static_cast(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(i-2), fPmt, fPv, true) - fPmt; - else - fIpmt += ScGetFV(fRate, static_cast(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(i-2), fPmt, fPv, true) - fPmt; + else + fIpmt += ScGetFV(fRate, static_cast(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(fFlag); + double fPmt = ScGetPMT(fRate, fNper, fPv, 0.0, bPayInAdvance); + double fPpmt = 0.0; + sal_uLong nStart = static_cast(fStart); + sal_uLong nEnd = static_cast(fEnd); + if (nStart == 1) { - bool bPayInAdvance = static_cast(fFlag); - double fPmt = ScGetPMT(fRate, fNper, fPv, 0.0, bPayInAdvance); - double fPpmt = 0.0; - sal_uLong nStart = static_cast(fStart); - sal_uLong nEnd = static_cast(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(i-2), fPmt, fPv, true) - fPmt) * fRate; - else - fPpmt += fPmt - ScGetFV(fRate, static_cast(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(i-2), fPmt, fPv, true) - fPmt) * fRate; + else + fPpmt += fPmt - ScGetFV(fRate, static_cast(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); } } @@ -2388,24 +2388,24 @@ void ScInterpreter::ScNominal() } void ScInterpreter::ScMod() -{ - if ( MustHaveParamCount( GetByte(), 2 ) ) - { - 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 ); +{ + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + + 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 ); } 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(nTmp); + PushIllegalArgument(); + return; } - OUString aItem = GetString().getString(); - OUString aTopic = GetString().getString(); - OUString aAppl = GetString().getString(); + nMode = static_cast(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(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(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( 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)) ) + } + 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( 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(fVal); + sal_uLong nBase = static_cast(fBase); + while ( nVal && p > pBuf ) { - sal_uLong nVal = static_cast(fVal); - sal_uLong nBase = static_cast(fBase); - while ( nVal && p > pBuf ) - { - *--p = pDigits[ nVal % nBase ]; - nVal /= nBase; - } - fVal = static_cast(nVal); + *--p = pDigits[ nVal % nBase ]; + nVal /= nBase; } - else + fVal = static_cast(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(fBase) - 1; - else - nDig = static_cast(fDig); + bDirt = false; + --fDig; } - *--p = pDigits[ nDig ]; - fVal = fInt; + if ( fDig <= 0.0 ) + nDig = 0; + else if ( fDig >= fBase ) + nDig = static_cast(fBase) - 1; + else + nDig = static_cast(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(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(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(fVal); + sal_uInt16 nMode = static_cast(fMode); - OUStringBuffer aRoman; - sal_uInt16 nVal = static_cast(fVal); - sal_uInt16 nMode = static_cast(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( nVal + pValues[ nIndex ] ); + nVal = sal::static_int_cast( 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( nVal + pValues[ nIndex ] ); - nVal = sal::static_int_cast( 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; - if ( nParamCount == 2 ) + double fVal = 0.0; + svl::SharedString aStr; + ScMatValType nResultType = ScMatValType::String; + + 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(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(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() -- cgit v1.2.3