diff options
author | Daniel Rentz [dr] <daniel.rentz@oracle.com> | 2010-12-14 14:40:00 +0100 |
---|---|---|
committer | Daniel Rentz [dr] <daniel.rentz@oracle.com> | 2010-12-14 14:40:00 +0100 |
commit | 4e7a88638a1293491fb06f3d1d4c0e22cd4c7631 (patch) | |
tree | cba6df4158d76d9761840faaa534a53815e9f718 /oox | |
parent | 518771d95e7dec96e7636719c5da8a74b692cddd (diff) |
dr78: simplified handling of external add-in functions, changed handling of empty function parameters
Diffstat (limited to 'oox')
-rw-r--r-- | oox/inc/oox/xls/formulabase.hxx | 4 | ||||
-rw-r--r-- | oox/inc/oox/xls/formulaparser.hxx | 1 | ||||
-rw-r--r-- | oox/source/xls/formulabase.cxx | 15 | ||||
-rw-r--r-- | oox/source/xls/formulaparser.cxx | 42 |
4 files changed, 45 insertions, 17 deletions
diff --git a/oox/inc/oox/xls/formulabase.hxx b/oox/inc/oox/xls/formulabase.hxx index 510404d2b662..fe4533680424 100644 --- a/oox/inc/oox/xls/formulabase.hxx +++ b/oox/inc/oox/xls/formulabase.hxx @@ -473,8 +473,8 @@ struct FunctionParamInfo containing supported sheet functions. */ enum FunctionLibraryType { - FUNCLIB_EUROTOOL, /// EuroTool add-in with EUROCONVERT function. - FUNCLIB_UNKNOWN /// Unknown library. + FUNCLIB_UNKNOWN = 0, /// Unknown library (must be zero). + FUNCLIB_EUROTOOL /// EuroTool add-in with EUROCONVERT function. }; // ---------------------------------------------------------------------------- diff --git a/oox/inc/oox/xls/formulaparser.hxx b/oox/inc/oox/xls/formulaparser.hxx index 0227e8efee6d..fc3fee3ba43c 100644 --- a/oox/inc/oox/xls/formulaparser.hxx +++ b/oox/inc/oox/xls/formulaparser.hxx @@ -87,6 +87,7 @@ private: const ApiToken* getSingleToken( const ApiToken* pToken, const ApiToken* pTokenEnd ) const; const ApiToken* skipParentheses( const ApiToken* pToken, const ApiToken* pTokenEnd ) const; const ApiToken* findParameters( ParameterPosVector& rParams, const ApiToken* pToken, const ApiToken* pTokenEnd ) const; + void appendEmptyParameter( const FunctionInfo& rFuncInfo, size_t nParam ); void appendCalcOnlyParameter( const FunctionInfo& rFuncInfo, size_t nParam ); void appendRequiredParameters( const FunctionInfo& rFuncInfo, size_t nParamCount ); diff --git a/oox/source/xls/formulabase.cxx b/oox/source/xls/formulabase.cxx index 5e1ed6b35141..c7a11c7c1cdd 100644 --- a/oox/source/xls/formulabase.cxx +++ b/oox/source/xls/formulabase.cxx @@ -237,8 +237,10 @@ const sal_uInt16 FUNCFLAG_MACROCMD = 0x0080; /// Function is a macro- const sal_uInt16 FUNCFLAG_ALWAYSVAR = 0x0100; /// Function is always represented by a tFuncVar token. const sal_uInt16 FUNCFLAG_PARAMPAIRS = 0x0200; /// Optional parameters are expected to appear in pairs. -const sal_uInt16 FUNCFLAG_FUNCLIBMASK = 0xF000; /// Mask for function library bits. -const sal_uInt16 FUNCFLAG_EUROTOOL = 0x1000; /// Function is part of the EuroTool add-in. +/// Converts a function library index (value of enum FunctionLibraryType) to function flags. +#define FUNCLIB_TO_FUNCFLAGS( funclib_index ) static_cast< sal_uInt16 >( static_cast< sal_uInt8 >( funclib_index ) << 12 ) +/// Extracts a function library index (value of enum FunctionLibraryType) from function flags. +#define FUNCFLAGS_TO_FUNCLIB( func_flags ) extractValue< FunctionLibraryType >( func_flags, 12, 4 ) typedef ::boost::shared_ptr< FunctionInfo > FunctionInfoRef; @@ -688,7 +690,7 @@ static const FunctionData saFuncTableBiff5[] = // *** EuroTool add-in *** - { "EUROCONVERT", "EUROCONVERT", NOID, NOID, 3, 5, V, { VR }, FUNCFLAG_EUROTOOL }, + { "EUROCONVERT", "EUROCONVERT", NOID, NOID, 3, 5, V, { VR }, FUNCLIB_TO_FUNCFLAGS( FUNCLIB_EUROTOOL ) }, // *** macro sheet commands *** @@ -925,12 +927,7 @@ void FunctionProviderImpl::initFunc( const FunctionData& rFuncData, sal_uInt8 nM xFuncInfo->maBiffMacroName = CREATE_OUSTRING( "_xlfnodf." ) + xFuncInfo->maOdfFuncName; } - switch( rFuncData.mnFlags & FUNCFLAG_FUNCLIBMASK ) - { - case FUNCFLAG_EUROTOOL: xFuncInfo->meFuncLibType = FUNCLIB_EUROTOOL; break; - default: xFuncInfo->meFuncLibType = FUNCLIB_UNKNOWN; - } - + xFuncInfo->meFuncLibType = FUNCFLAGS_TO_FUNCLIB( rFuncData.mnFlags ); xFuncInfo->mnApiOpCode = -1; xFuncInfo->mnOobFuncId = rFuncData.mnOobFuncId; xFuncInfo->mnBiffFuncId = rFuncData.mnBiffFuncId; diff --git a/oox/source/xls/formulaparser.cxx b/oox/source/xls/formulaparser.cxx index 12deadecd695..bc5d30bc98c4 100644 --- a/oox/source/xls/formulaparser.cxx +++ b/oox/source/xls/formulaparser.cxx @@ -126,7 +126,6 @@ const FunctionInfo* FormulaFinalizer::getFunctionInfo( ApiToken& orFuncToken ) // no success - return null return 0; - } const FunctionInfo* FormulaFinalizer::getExternCallInfo( ApiToken& orFuncToken, const ApiToken& rECToken ) @@ -248,17 +247,29 @@ const ApiToken* FormulaFinalizer::processParameters( if( !aParamInfoIt.isExcelOnlyParam() ) { - // replace empty second and third parameter in IF function with zeros - if( (pRealFuncInfo->mnOobFuncId == OOBIN_FUNC_IF) && ((nParam == 1) || (nParam == 2)) && bIsEmpty ) + // handle empty parameters + if( bIsEmpty ) { - maTokens.append< double >( OPCODE_PUSH, 0.0 ); - bIsEmpty = false; + // append leading space tokens from original token array + while( (pParamBegin < pParamEnd) && (pParamBegin->OpCode == OPCODE_SPACES) ) + maTokens.push_back( *pParamBegin++ ); + // add default values for some empty parameters, or the OPCODE_MISSING token + appendEmptyParameter( *pRealFuncInfo, nParam ); + // reset bIsEmpty flag, if something has been appended in appendEmptyParameter() + bIsEmpty = maTokens.back().OpCode == OPCODE_MISSING; + // skip OPCODE_MISSING token in the original token array + OSL_ENSURE( (pParamBegin == pParamEnd) || (pParamBegin->OpCode == OPCODE_MISSING), "FormulaFinalizer::processParameters - OPCODE_MISSING expected" ); + if( pParamBegin < pParamEnd ) ++pParamBegin; + // append trailing space tokens from original token array + while( (pParamBegin < pParamEnd) && (pParamBegin->OpCode == OPCODE_SPACES) ) + maTokens.push_back( *pParamBegin++ ); } else { - // process all tokens of the parameter + // if parameter is not empty, process all tokens of the parameter processTokens( pParamBegin, pParamEnd ); } + // append parameter separator token maTokens.append( OPCODE_SEP ); } @@ -365,6 +376,25 @@ const ApiToken* FormulaFinalizer::findParameters( ParameterPosVector& rParams, return (pToken < pTokenEnd) ? (pToken + 1) : pTokenEnd; } +void FormulaFinalizer::appendEmptyParameter( const FunctionInfo& rFuncInfo, size_t nParam ) +{ + // remeber old size of the token array + size_t nTokenArraySize = maTokens.size(); + + switch( rFuncInfo.mnOobFuncId ) + { + case OOBIN_FUNC_IF: + if( (nParam == 1) || (nParam == 2) ) + maTokens.append< double >( OPCODE_PUSH, 0.0 ); + break; + default:; + } + + // if no token has been added, append a OPCODE_MISSING token + if( nTokenArraySize == maTokens.size() ) + maTokens.append( OPCODE_MISSING ); +} + void FormulaFinalizer::appendCalcOnlyParameter( const FunctionInfo& rFuncInfo, size_t nParam ) { (void)nParam; // prevent 'unused' warning |