summaryrefslogtreecommitdiff
path: root/oox
diff options
context:
space:
mode:
authorDaniel Rentz [dr] <daniel.rentz@oracle.com>2010-12-14 14:40:00 +0100
committerDaniel Rentz [dr] <daniel.rentz@oracle.com>2010-12-14 14:40:00 +0100
commit4e7a88638a1293491fb06f3d1d4c0e22cd4c7631 (patch)
treecba6df4158d76d9761840faaa534a53815e9f718 /oox
parent518771d95e7dec96e7636719c5da8a74b692cddd (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.hxx4
-rw-r--r--oox/inc/oox/xls/formulaparser.hxx1
-rw-r--r--oox/source/xls/formulabase.cxx15
-rw-r--r--oox/source/xls/formulaparser.cxx42
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