LCOV - code coverage report
Current view: top level - sc/source/filter/excel - xeformula.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 1 1178 0.1 %
Date: 2012-08-25 Functions: 2 177 1.1 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 2 1443 0.1 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : 
      30                 :            : // XXX xelink.hxx MUST be included before xeformula.hxx because of the
      31                 :            : // redifinition of the CREATE_OUSTRING() macro, which is in oox/helper.hxx
      32                 :            : // (indirectly included via xelink.hxx) and ../inc/ftools.hxx (indirectly
      33                 :            : // included via xeformula.hxx) that does an undef first. Ugly.
      34                 :            : #include "xelink.hxx"
      35                 :            : #include "xeformula.hxx"
      36                 :            : 
      37                 :            : #include <list>
      38                 :            : #include <map>
      39                 :            : #include <memory>
      40                 :            : #include "addincol.hxx"
      41                 :            : #include "compiler.hxx"
      42                 :            : #include "document.hxx"
      43                 :            : #include "externalrefmgr.hxx"
      44                 :            : #include "rangelst.hxx"
      45                 :            : #include "token.hxx"
      46                 :            : #include "tokenarray.hxx"
      47                 :            : #include "xehelper.hxx"
      48                 :            : #include "xename.hxx"
      49                 :            : #include "xestream.hxx"
      50                 :            : 
      51                 :            : using namespace ::formula;
      52                 :            : 
      53                 :            : // External reference log =====================================================
      54                 :            : 
      55                 :          0 : XclExpRefLogEntry::XclExpRefLogEntry() :
      56                 :            :     mpUrl( 0 ),
      57                 :            :     mpFirstTab( 0 ),
      58                 :            :     mpLastTab( 0 ),
      59                 :            :     mnFirstXclTab( EXC_TAB_DELETED ),
      60                 :          0 :     mnLastXclTab( EXC_TAB_DELETED )
      61                 :            : {
      62                 :          0 : }
      63                 :            : 
      64                 :            : // Formula compiler ===========================================================
      65                 :            : 
      66                 :            : namespace {
      67                 :            : 
      68                 :            : /** Wrapper structure for a processed Calc formula token with additional
      69                 :            :     settings (whitespaces). */
      70                 :            : struct XclExpScToken
      71                 :            : {
      72                 :            :     const FormulaToken* mpScToken;          /// Currently processed Calc token.
      73                 :            :     sal_uInt8           mnSpaces;           /// Number of spaces before the Calc token.
      74                 :            : 
      75                 :          0 :     inline explicit     XclExpScToken() : mpScToken( 0 ), mnSpaces( 0 ) {}
      76                 :          0 :     inline bool         Is() const { return mpScToken != 0; }
      77         [ #  # ]:          0 :     inline StackVar     GetType() const { return mpScToken ? mpScToken->GetType() : static_cast< StackVar >( svUnknown ); }
      78         [ #  # ]:          0 :     inline OpCode       GetOpCode() const { return mpScToken ? mpScToken->GetOpCode() : static_cast< OpCode >( ocNone ); }
      79                 :            : };
      80                 :            : 
      81                 :            : // ----------------------------------------------------------------------------
      82                 :            : 
      83                 :            : /** Effective token class conversion types. */
      84                 :            : enum XclExpClassConv
      85                 :            : {
      86                 :            :     EXC_CLASSCONV_ORG,          /// Keep original class of the token.
      87                 :            :     EXC_CLASSCONV_VAL,          /// Convert ARR tokens to VAL class (REF remains uncahnged).
      88                 :            :     EXC_CLASSCONV_ARR           /// Convert VAL tokens to ARR class (REF remains uncahnged).
      89                 :            : };
      90                 :            : 
      91                 :            : // ----------------------------------------------------------------------------
      92                 :            : 
      93                 :            : /** Token class conversion and position of a token in the token array. */
      94                 :            : struct XclExpTokenConvInfo
      95                 :            : {
      96                 :            :     sal_uInt16          mnTokPos;       /// Position of the token in the token array.
      97                 :            :     XclFuncParamConv    meConv;         /// Token class conversion type.
      98                 :            :     bool                mbValType;      /// Data type (false = REFTYPE, true = VALTYPE).
      99                 :            : };
     100                 :            : 
     101                 :            : /** Vector of token position and conversion for all operands of an operator,
     102                 :            :     or for all parameters of a function. */
     103                 :          0 : struct XclExpOperandList : public ::std::vector< XclExpTokenConvInfo >
     104                 :            : {
     105         [ #  # ]:          0 :     inline explicit     XclExpOperandList() { reserve( 2 ); }
     106                 :            :     void                AppendOperand( sal_uInt16 nTokPos, XclFuncParamConv eConv, bool bValType );
     107                 :            : };
     108                 :            : 
     109                 :          0 : void XclExpOperandList::AppendOperand( sal_uInt16 nTokPos, XclFuncParamConv eConv, bool bValType )
     110                 :            : {
     111                 :          0 :     resize( size() + 1 );
     112                 :          0 :     XclExpTokenConvInfo& rConvInfo = back();
     113                 :          0 :     rConvInfo.mnTokPos = nTokPos;
     114                 :          0 :     rConvInfo.meConv = eConv;
     115                 :          0 :     rConvInfo.mbValType = bValType;
     116                 :          0 : }
     117                 :            : 
     118                 :            : typedef boost::shared_ptr< XclExpOperandList > XclExpOperandListRef;
     119                 :            : typedef ::std::vector< XclExpOperandListRef > XclExpOperandListVector;
     120                 :            : 
     121                 :            : // ----------------------------------------------------------------------------
     122                 :            : 
     123                 :            : /** Encapsulates all data needed for a call to an external function (macro, add-in). */
     124                 :          0 : struct XclExpExtFuncData
     125                 :            : {
     126                 :            :     String              maFuncName;         /// Name of the function.
     127                 :            :     bool                mbVBasic;           /// True = Visual Basic macro call.
     128                 :            :     bool                mbHidden;           /// True = Create hidden defined name.
     129                 :            : 
     130                 :          0 :     inline explicit     XclExpExtFuncData() : mbVBasic( false ), mbHidden( false ) {}
     131                 :            :     void                Set( const String& rFuncName, bool bVBasic, bool bHidden );
     132                 :            : };
     133                 :            : 
     134                 :          0 : void XclExpExtFuncData::Set( const String& rFuncName, bool bVBasic, bool bHidden )
     135                 :            : {
     136                 :          0 :     maFuncName = rFuncName;
     137                 :          0 :     mbVBasic = bVBasic;
     138                 :          0 :     mbHidden = bHidden;
     139                 :          0 : }
     140                 :            : 
     141                 :            : // ----------------------------------------------------------------------------
     142                 :            : 
     143                 :            : /** Encapsulates all data needed to process an entire function. */
     144 [ #  # ][ #  # ]:          0 : class XclExpFuncData
     145                 :            : {
     146                 :            : public:
     147                 :            :     explicit            XclExpFuncData(
     148                 :            :                             const XclExpScToken& rTokData,
     149                 :            :                             const XclFunctionInfo& rFuncInfo,
     150                 :            :                             const XclExpExtFuncData& rExtFuncData );
     151                 :            : 
     152                 :          0 :     inline const FormulaToken& GetScToken() const { return *mrTokData.mpScToken; }
     153                 :          0 :     inline OpCode       GetOpCode() const { return mrFuncInfo.meOpCode; }
     154                 :          0 :     inline sal_uInt16   GetXclFuncIdx() const { return mrFuncInfo.mnXclFunc; }
     155                 :          0 :     inline bool         IsVolatile() const { return mrFuncInfo.IsVolatile(); }
     156                 :          0 :     inline bool         IsFixedParamCount() const { return mrFuncInfo.IsFixedParamCount(); }
     157                 :          0 :     inline bool         IsMacroFunc() const { return mrFuncInfo.IsMacroFunc(); }
     158                 :          0 :     inline sal_uInt8    GetSpaces() const { return mrTokData.mnSpaces; }
     159                 :          0 :     inline const XclExpExtFuncData& GetExtFuncData() const { return maExtFuncData; }
     160                 :          0 :     inline sal_uInt8    GetReturnClass() const { return mrFuncInfo.mnRetClass; }
     161                 :            : 
     162                 :            :     const XclFuncParamInfo& GetParamInfo() const;
     163                 :            :     bool                IsCalcOnlyParam() const;
     164                 :            :     bool                IsExcelOnlyParam() const;
     165                 :            :     void                IncParamInfoIdx();
     166                 :            : 
     167                 :          0 :     inline sal_uInt8    GetMinParamCount() const { return mrFuncInfo.mnMinParamCount; }
     168                 :          0 :     inline sal_uInt8    GetMaxParamCount() const { return mrFuncInfo.mnMaxParamCount; }
     169                 :          0 :     inline sal_uInt8    GetParamCount() const { return static_cast< sal_uInt8 >( mxOperands->size() ); }
     170                 :            :     void                FinishParam( sal_uInt16 nTokPos );
     171                 :          0 :     inline XclExpOperandListRef GetOperandList() const { return mxOperands; }
     172                 :            : 
     173                 :          0 :     inline ScfUInt16Vec& GetAttrPosVec() { return maAttrPosVec; }
     174                 :          0 :     inline void         AppendAttrPos( sal_uInt16 nPos ) { maAttrPosVec.push_back( nPos ); }
     175                 :            : 
     176                 :            : private:
     177                 :            :     ScfUInt16Vec        maAttrPosVec;       /// Token array positions of tAttr tokens.
     178                 :            :     const XclExpScToken& mrTokData;         /// Data about processed function name token.
     179                 :            :     const XclFunctionInfo& mrFuncInfo;      /// Constant data about processed function.
     180                 :            :     XclExpExtFuncData   maExtFuncData;      /// Data for external functions (macro, add-in).
     181                 :            :     XclExpOperandListRef mxOperands;        /// Class conversion and position of all parameters.
     182                 :            :     const XclFuncParamInfo* mpParamInfo;    /// Information for current parameter.
     183                 :            : };
     184                 :            : 
     185                 :          0 : XclExpFuncData::XclExpFuncData( const XclExpScToken& rTokData,
     186                 :            :         const XclFunctionInfo& rFuncInfo, const XclExpExtFuncData& rExtFuncData ) :
     187                 :            :     mrTokData( rTokData ),
     188                 :            :     mrFuncInfo( rFuncInfo ),
     189                 :            :     maExtFuncData( rExtFuncData ),
     190         [ #  # ]:          0 :     mxOperands( new XclExpOperandList ),
     191 [ #  # ][ #  # ]:          0 :     mpParamInfo( rFuncInfo.mpParamInfos )
                 [ #  # ]
     192                 :            : {
     193                 :            :     OSL_ENSURE( mrTokData.mpScToken, "XclExpFuncData::XclExpFuncData - missing core token" );
     194                 :            :     // set name of an add-in function
     195 [ #  # ][ #  # ]:          0 :     if( (maExtFuncData.maFuncName.Len() == 0) && dynamic_cast< const FormulaExternalToken* >( mrTokData.mpScToken ) )
         [ #  # ][ #  # ]
     196 [ #  # ][ #  # ]:          0 :         maExtFuncData.Set( GetScToken().GetExternal(), true, false );
     197                 :          0 : }
     198                 :            : 
     199                 :          0 : const XclFuncParamInfo& XclExpFuncData::GetParamInfo() const
     200                 :            : {
     201                 :            :     static const XclFuncParamInfo saInvalidInfo = { EXC_PARAM_NONE, EXC_PARAMCONV_ORG, false };
     202         [ #  # ]:          0 :     return mpParamInfo ? *mpParamInfo : saInvalidInfo;
     203                 :            : }
     204                 :            : 
     205                 :          0 : bool XclExpFuncData::IsCalcOnlyParam() const
     206                 :            : {
     207 [ #  # ][ #  # ]:          0 :     return mpParamInfo && (mpParamInfo->meValid == EXC_PARAM_CALCONLY);
     208                 :            : }
     209                 :            : 
     210                 :          0 : bool XclExpFuncData::IsExcelOnlyParam() const
     211                 :            : {
     212 [ #  # ][ #  # ]:          0 :     return mpParamInfo && (mpParamInfo->meValid == EXC_PARAM_EXCELONLY);
     213                 :            : }
     214                 :            : 
     215                 :          0 : void XclExpFuncData::IncParamInfoIdx()
     216                 :            : {
     217         [ #  # ]:          0 :     if( mpParamInfo )
     218                 :            :     {
     219                 :            :         // move pointer to next entry, if something explicit follows
     220 [ #  # ][ #  # ]:          0 :         if( (static_cast<size_t>(mpParamInfo - mrFuncInfo.mpParamInfos + 1) < EXC_FUNCINFO_PARAMINFO_COUNT) && (mpParamInfo[ 1 ].meValid != EXC_PARAM_NONE) )
     221                 :          0 :             ++mpParamInfo;
     222                 :            :         // if last parameter type is 'Excel-only' or 'Calc-only', do not repeat it
     223 [ #  # ][ #  # ]:          0 :         else if( IsExcelOnlyParam() || IsCalcOnlyParam() )
                 [ #  # ]
     224                 :          0 :             mpParamInfo = 0;
     225                 :            :         // otherwise: repeat last parameter class
     226                 :            :     }
     227                 :          0 : }
     228                 :            : 
     229                 :          0 : void XclExpFuncData::FinishParam( sal_uInt16 nTokPos )
     230                 :            : {
     231                 :            :     // write token class conversion info for this parameter
     232                 :          0 :     const XclFuncParamInfo& rParamInfo = GetParamInfo();
     233                 :          0 :     mxOperands->AppendOperand( nTokPos, rParamInfo.meConv, rParamInfo.mbValType );
     234                 :            :     // move to next parameter info structure
     235                 :          0 :     IncParamInfoIdx();
     236                 :          0 : }
     237                 :            : 
     238                 :            : // compiler configuration -----------------------------------------------------
     239                 :            : 
     240                 :            : /** Type of token class handling. */
     241                 :            : enum XclExpFmlaClassType
     242                 :            : {
     243                 :            :     EXC_CLASSTYPE_CELL,         /// Cell formula, shared formula.
     244                 :            :     EXC_CLASSTYPE_ARRAY,        /// Array formula, conditional formatting, data validation.
     245                 :            :     EXC_CLASSTYPE_NAME          /// Defined name, range list.
     246                 :            : };
     247                 :            : 
     248                 :            : /** Configuration data of the formula compiler. */
     249                 :            : struct XclExpCompConfig
     250                 :            : {
     251                 :            :     XclFormulaType      meType;         /// Type of the formula to be created.
     252                 :            :     XclExpFmlaClassType meClassType;    /// Token class handling type.
     253                 :            :     bool                mbLocalLinkMgr; /// True = local (per-sheet) link manager, false = global.
     254                 :            :     bool                mbFromCell;     /// True = Any kind of cell formula (cell, array, shared).
     255                 :            :     bool                mb3DRefOnly;    /// True = Only 3D references allowed (e.g. names).
     256                 :            :     bool                mbAllowArrays;  /// True = Allow inline arrays.
     257                 :            : };
     258                 :            : 
     259                 :            : /** The table containing configuration data for all formula types. */
     260                 :            : static const XclExpCompConfig spConfigTable[] =
     261                 :            : {
     262                 :            :     // formula type         token class type     lclLM  inCell 3dOnly allowArray
     263                 :            :     { EXC_FMLATYPE_CELL,    EXC_CLASSTYPE_CELL,  true,  true,  false, true  },
     264                 :            :     { EXC_FMLATYPE_SHARED,  EXC_CLASSTYPE_CELL,  true,  true,  false, true  },
     265                 :            :     { EXC_FMLATYPE_MATRIX,  EXC_CLASSTYPE_ARRAY, true,  true,  false, true  },
     266                 :            :     { EXC_FMLATYPE_CONDFMT, EXC_CLASSTYPE_ARRAY, true,  false, false, false },
     267                 :            :     { EXC_FMLATYPE_DATAVAL, EXC_CLASSTYPE_ARRAY, true,  false, false, false },
     268                 :            :     { EXC_FMLATYPE_NAME,    EXC_CLASSTYPE_NAME,  false, false, true,  true  },
     269                 :            :     { EXC_FMLATYPE_CHART,   EXC_CLASSTYPE_NAME,  true,  false, true,  true  },
     270                 :            :     { EXC_FMLATYPE_CONTROL, EXC_CLASSTYPE_NAME,  true,  false, false, false },
     271                 :            :     { EXC_FMLATYPE_WQUERY,  EXC_CLASSTYPE_NAME,  true,  false, true,  false },
     272                 :            :     { EXC_FMLATYPE_LISTVAL, EXC_CLASSTYPE_NAME,  true,  false, false, false }
     273                 :            : };
     274                 :            : 
     275                 :            : // ----------------------------------------------------------------------------
     276                 :            : 
     277                 :            : /** Working data of the formula compiler. Used to push onto a stack for recursive calls. */
     278                 :          0 : struct XclExpCompData
     279                 :            : {
     280                 :            :     typedef boost::shared_ptr< ScTokenArray > ScTokenArrayRef;
     281                 :            : 
     282                 :            :     const XclExpCompConfig& mrCfg;          /// Configuration for current formula type.
     283                 :            :     ScTokenArrayRef     mxOwnScTokArr;      /// Own clone of a Calc token array.
     284                 :            :     XclTokenArrayIterator maTokArrIt;       /// Iterator in Calc token array.
     285                 :            :     XclExpLinkManager*  mpLinkMgr;          /// Link manager for current context (local/global).
     286                 :            :     XclExpRefLog*       mpRefLog;           /// Log for external references.
     287                 :            :     const ScAddress*    mpScBasePos;        /// Current cell position of the formula.
     288                 :            : 
     289                 :            :     ScfUInt8Vec         maTokVec;           /// Byte vector containing token data.
     290                 :            :     ScfUInt8Vec         maExtDataVec;       /// Byte vector containing extended data (arrays, stacked NLRs).
     291                 :            :     XclExpOperandListVector maOpListVec;    /// Formula structure, maps operators to their operands.
     292                 :            :     ScfUInt16Vec        maOpPosStack;       /// Stack with positions of operand tokens waiting for an operator.
     293                 :            :     bool                mbStopAtSep;        /// True = Stop subexpression creation at an ocSep token.
     294                 :            :     bool                mbVolatile;         /// True = Formula contains volatile function.
     295                 :            :     bool                mbOk;               /// Current state of the compiler.
     296                 :            : 
     297                 :            :     explicit            XclExpCompData( const XclExpCompConfig* pCfg );
     298                 :            : };
     299                 :            : 
     300                 :          0 : XclExpCompData::XclExpCompData( const XclExpCompConfig* pCfg ) :
     301                 :            :     mrCfg( pCfg ? *pCfg : spConfigTable[ 0 ] ),
     302                 :            :     mpLinkMgr( 0 ),
     303                 :            :     mpRefLog( 0 ),
     304                 :            :     mpScBasePos( 0 ),
     305                 :            :     mbStopAtSep( false ),
     306                 :            :     mbVolatile( false ),
     307 [ #  # ][ #  # ]:          0 :     mbOk( pCfg != 0 )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     308                 :            : {
     309                 :            :     OSL_ENSURE( pCfg, "XclExpFmlaCompImpl::Init - unknown formula type" );
     310                 :          0 : }
     311                 :            : 
     312                 :            : } // namespace
     313                 :            : 
     314                 :            : // ----------------------------------------------------------------------------
     315                 :            : 
     316                 :            : /** Implementation class of the export formula compiler. */
     317 [ #  # ][ #  # ]:          0 : class XclExpFmlaCompImpl : protected XclExpRoot, protected XclTokenArrayHelper
     318                 :            : {
     319                 :            : public:
     320                 :            :     explicit            XclExpFmlaCompImpl( const XclExpRoot& rRoot );
     321                 :            : 
     322                 :            :     /** Creates an Excel token array from the passed Calc token array. */
     323                 :            :     XclTokenArrayRef    CreateFormula(
     324                 :            :                             XclFormulaType eType, const ScTokenArray& rScTokArr,
     325                 :            :                             const ScAddress* pScBasePos = 0, XclExpRefLog* pRefLog = 0 );
     326                 :            :     /** Creates a single error token containing the passed error code. */
     327                 :            :     XclTokenArrayRef    CreateErrorFormula( sal_uInt8 nErrCode );
     328                 :            :     /** Creates a single token for a special cell reference. */
     329                 :            :     XclTokenArrayRef    CreateSpecialRefFormula( sal_uInt8 nTokenId, const XclAddress& rXclPos );
     330                 :            :     /** Creates a single tNameXR token for a reference to an external name. */
     331                 :            :     XclTokenArrayRef    CreateNameXFormula( sal_uInt16 nExtSheet, sal_uInt16 nExtName );
     332                 :            : 
     333                 :            :     /** Returns true, if the passed formula type allows 3D references only. */
     334                 :            :     bool                Is3DRefOnly( XclFormulaType eType ) const;
     335                 :            : 
     336                 :            :     // ------------------------------------------------------------------------
     337                 :            : private:
     338                 :            :     const XclExpCompConfig* GetConfigForType( XclFormulaType eType ) const;
     339                 :          0 :     inline sal_uInt16   GetSize() const { return static_cast< sal_uInt16 >( mxData->maTokVec.size() ); }
     340                 :            : 
     341                 :            :     void                Init( XclFormulaType eType );
     342                 :            :     void                Init( XclFormulaType eType, const ScTokenArray& rScTokArr,
     343                 :            :                             const ScAddress* pScBasePos, XclExpRefLog* pRefLog );
     344                 :            : 
     345                 :            :     void                RecalcTokenClasses();
     346                 :            :     void                RecalcTokenClass( const XclExpTokenConvInfo& rConvInfo, XclFuncParamConv ePrevConv, XclExpClassConv ePrevClassConv, bool bWasRefClass );
     347                 :            : 
     348                 :            :     void                FinalizeFormula();
     349                 :            :     XclTokenArrayRef    CreateTokenArray();
     350                 :            : 
     351                 :            :     // compiler ---------------------------------------------------------------
     352                 :            :     // XclExpScToken: pass-by-value and return-by-value is intended
     353                 :            : 
     354                 :            :     const FormulaToken* GetNextRawToken();
     355                 :            :     const FormulaToken* PeekNextRawToken( bool bSkipSpaces ) const;
     356                 :            : 
     357                 :            :     bool                GetNextToken( XclExpScToken& rTokData );
     358                 :            :     XclExpScToken       GetNextToken();
     359                 :            : 
     360                 :            :     XclExpScToken       Expression( XclExpScToken aTokData, bool bInParentheses, bool bStopAtSep );
     361                 :            :     XclExpScToken       SkipExpression( XclExpScToken aTokData, bool bStopAtSep );
     362                 :            : 
     363                 :            :     XclExpScToken       OrTerm( XclExpScToken aTokData, bool bInParentheses );
     364                 :            :     XclExpScToken       AndTerm( XclExpScToken aTokData, bool bInParentheses );
     365                 :            :     XclExpScToken       CompareTerm( XclExpScToken aTokData, bool bInParentheses );
     366                 :            :     XclExpScToken       ConcatTerm( XclExpScToken aTokData, bool bInParentheses );
     367                 :            :     XclExpScToken       AddSubTerm( XclExpScToken aTokData, bool bInParentheses );
     368                 :            :     XclExpScToken       MulDivTerm( XclExpScToken aTokData, bool bInParentheses );
     369                 :            :     XclExpScToken       PowTerm( XclExpScToken aTokData, bool bInParentheses );
     370                 :            :     XclExpScToken       UnaryPostTerm( XclExpScToken aTokData, bool bInParentheses );
     371                 :            :     XclExpScToken       UnaryPreTerm( XclExpScToken aTokData, bool bInParentheses );
     372                 :            :     XclExpScToken       ListTerm( XclExpScToken aTokData, bool bInParentheses );
     373                 :            :     XclExpScToken       IntersectTerm( XclExpScToken aTokData, bool& rbHasRefOp );
     374                 :            :     XclExpScToken       RangeTerm( XclExpScToken aTokData, bool& rbHasRefOp );
     375                 :            :     XclExpScToken       Factor( XclExpScToken aTokData );
     376                 :            : 
     377                 :            :     // formula structure ------------------------------------------------------
     378                 :            : 
     379                 :            :     void                ProcessDouble( const XclExpScToken& rTokData );
     380                 :            :     void                ProcessString( const XclExpScToken& rTokData );
     381                 :            :     void                ProcessMissing( const XclExpScToken& rTokData );
     382                 :            :     void                ProcessBad( const XclExpScToken& rTokData );
     383                 :            :     void                ProcessParentheses( const XclExpScToken& rTokData );
     384                 :            :     void                ProcessBoolean( const XclExpScToken& rTokData );
     385                 :            :     void                ProcessDdeLink( const XclExpScToken& rTokData );
     386                 :            :     void                ProcessExternal( const XclExpScToken& rTokData );
     387                 :            :     void                ProcessMatrix( const XclExpScToken& rTokData );
     388                 :            : 
     389                 :            :     void                ProcessFunction( const XclExpScToken& rTokData );
     390                 :            :     void                PrepareFunction( XclExpFuncData& rFuncData );
     391                 :            :     void                FinishFunction( XclExpFuncData& rFuncData, sal_uInt8 nCloseSpaces );
     392                 :            :     void                FinishIfFunction( XclExpFuncData& rFuncData );
     393                 :            :     void                FinishChooseFunction( XclExpFuncData& rFuncData );
     394                 :            : 
     395                 :            :     XclExpScToken       ProcessParam( XclExpScToken aTokData, XclExpFuncData& rFuncData );
     396                 :            :     void                PrepareParam( XclExpFuncData& rFuncData );
     397                 :            :     void                FinishParam( XclExpFuncData& rFuncData );
     398                 :            :     void                AppendDefaultParam( XclExpFuncData& rFuncData );
     399                 :            :     void                AppendTrailingParam( XclExpFuncData& rFuncData );
     400                 :            : 
     401                 :            :     // reference handling -----------------------------------------------------
     402                 :            : 
     403                 :            :     SCTAB               GetScTab( const ScSingleRefData& rRefData ) const;
     404                 :            :     bool                IsRef2D( const ScSingleRefData& rRefData ) const;
     405                 :            :     bool                IsRef2D( const ScComplexRefData& rRefData ) const;
     406                 :            : 
     407                 :            :     void                ConvertRefData( ScSingleRefData& rRefData, XclAddress& rXclPos,
     408                 :            :                             bool bNatLangRef, bool bTruncMaxCol, bool bTruncMaxRow ) const;
     409                 :            :     void                ConvertRefData( ScComplexRefData& rRefData, XclRange& rXclRange,
     410                 :            :                             bool bNatLangRef ) const;
     411                 :            : 
     412                 :            :     XclExpRefLogEntry*  GetNewRefLogEntry();
     413                 :            :     void                ProcessCellRef( const XclExpScToken& rTokData );
     414                 :            :     void                ProcessRangeRef( const XclExpScToken& rTokData );
     415                 :            :     void                ProcessExternalCellRef( const XclExpScToken& rTokData );
     416                 :            :     void                ProcessExternalRangeRef( const XclExpScToken& rTokData );
     417                 :            :     void                ProcessDefinedName( const XclExpScToken& rTokData );
     418                 :            :     void                ProcessExternalName( const XclExpScToken& rTokData );
     419                 :            : 
     420                 :            :     // token vector -----------------------------------------------------------
     421                 :            : 
     422                 :            :     void                PushOperandPos( sal_uInt16 nTokPos );
     423                 :            :     void                PushOperatorPos( sal_uInt16 nTokPos, const XclExpOperandListRef& rxOperands );
     424                 :            :     sal_uInt16          PopOperandPos();
     425                 :            : 
     426                 :            :     void                Append( sal_uInt8 nData );
     427                 :            :     void                Append( sal_uInt8 nData, size_t nCount );
     428                 :            :     void                Append( sal_uInt16 nData );
     429                 :            :     void                Append( sal_uInt32 nData );
     430                 :            :     void                Append( double fData );
     431                 :            :     void                Append( const String& rString );
     432                 :            : 
     433                 :            :     void                AppendAddress( const XclAddress& rXclPos );
     434                 :            :     void                AppendRange( const XclRange& rXclRange );
     435                 :            : 
     436                 :            :     void                AppendSpaceToken( sal_uInt8 nType, sal_uInt8 nCount );
     437                 :            : 
     438                 :            :     void                AppendOperandTokenId( sal_uInt8 nTokenId, sal_uInt8 nSpaces = 0 );
     439                 :            :     void                AppendIntToken( sal_uInt16 nValue, sal_uInt8 nSpaces = 0 );
     440                 :            :     void                AppendNumToken( double fValue, sal_uInt8 nSpaces = 0 );
     441                 :            :     void                AppendBoolToken( bool bValue, sal_uInt8 nSpaces = 0 );
     442                 :            :     void                AppendErrorToken( sal_uInt8 nErrCode, sal_uInt8 nSpaces = 0 );
     443                 :            :     void                AppendMissingToken( sal_uInt8 nSpaces = 0 );
     444                 :            :     void                AppendNameToken( sal_uInt16 nNameIdx, sal_uInt8 nSpaces = 0 );
     445                 :            :     void                AppendMissingNameToken( const String& rName, sal_uInt8 nSpaces = 0 );
     446                 :            :     void                AppendNameXToken( sal_uInt16 nExtSheet, sal_uInt16 nExtName, sal_uInt8 nSpaces = 0 );
     447                 :            :     void                AppendMacroCallToken( const XclExpExtFuncData& rExtFuncData, sal_uInt8 nSpaces = 0 );
     448                 :            :     void                AppendAddInCallToken( const XclExpExtFuncData& rExtFuncData, sal_uInt8 nSpaces = 0 );
     449                 :            :     void                AppendEuroToolCallToken( const XclExpExtFuncData& rExtFuncData, sal_uInt8 nSpaces = 0 );
     450                 :            : 
     451                 :            :     void                AppendOperatorTokenId( sal_uInt8 nTokenId, const XclExpOperandListRef& rxOperands, sal_uInt8 nSpaces = 0 );
     452                 :            :     void                AppendUnaryOperatorToken( sal_uInt8 nTokenId, sal_uInt8 nSpaces = 0 );
     453                 :            :     void                AppendBinaryOperatorToken( sal_uInt8 nTokenId, bool bValType, sal_uInt8 nSpaces = 0 );
     454                 :            :     void                AppendLogicalOperatorToken( sal_uInt16 nXclFuncIdx, sal_uInt8 nOpCount );
     455                 :            :     void                AppendFuncToken( const XclExpFuncData& rFuncData );
     456                 :            : 
     457                 :            :     void                AppendParenToken( sal_uInt8 nOpenSpaces = 0, sal_uInt8 nCloseSpaces = 0 );
     458                 :            :     void                AppendJumpToken( XclExpFuncData& rFuncData, sal_uInt8 nAttrType );
     459                 :            : 
     460                 :            :     void                InsertZeros( sal_uInt16 nInsertPos, sal_uInt16 nInsertSize );
     461                 :            :     void                Overwrite( sal_uInt16 nWriteToPos, sal_uInt16 nOffset );
     462                 :            : 
     463                 :            :     void                UpdateAttrGoto( sal_uInt16 nAttrPos );
     464                 :            : 
     465                 :            :     bool                IsSpaceToken( sal_uInt16 nPos ) const;
     466                 :            :     void                RemoveTrailingParen();
     467                 :            : 
     468                 :            :     void                AppendExt( sal_uInt8 nData );
     469                 :            :     void                AppendExt( sal_uInt8 nData, size_t nCount );
     470                 :            :     void                AppendExt( sal_uInt16 nData );
     471                 :            :     void                AppendExt( double fData );
     472                 :            :     void                AppendExt( const String& rString );
     473                 :            : 
     474                 :            :     // ------------------------------------------------------------------------
     475                 :            : private:
     476                 :            :     typedef ::std::map< XclFormulaType, XclExpCompConfig >  XclExpCompConfigMap;
     477                 :            :     typedef boost::shared_ptr< XclExpCompData >             XclExpCompDataRef;
     478                 :            :     typedef ::std::vector< XclExpCompDataRef >              XclExpCompDataVector;
     479                 :            : 
     480                 :            :     XclExpCompConfigMap maCfgMap;       /// Compiler configuration map for all formula types.
     481                 :            :     XclFunctionProvider maFuncProv;     /// Excel function data provider.
     482                 :            :     XclExpCompDataRef   mxData;         /// Working data for current formula.
     483                 :            :     XclExpCompDataVector maDataStack;   /// Stack for working data, when compiler is called recursively.
     484                 :            :     const XclBiff       meBiff;         /// Cached BIFF version to save GetBiff() calls.
     485                 :            :     const SCsCOL        mnMaxAbsCol;    /// Maximum column index.
     486                 :            :     const SCsROW        mnMaxAbsRow;    /// Maximum row index.
     487                 :            :     const SCsCOL        mnMaxScCol;     /// Maximum column index in Calc itself.
     488                 :            :     const SCsROW        mnMaxScRow;     /// Maximum row index in Calc itself.
     489                 :            :     const sal_uInt16    mnMaxColMask;   /// Mask to delete invalid bits in column fields.
     490                 :            :     const sal_uInt32    mnMaxRowMask;   /// Mask to delete invalid bits in row fields.
     491                 :            : };
     492                 :            : 
     493                 :            : // ----------------------------------------------------------------------------
     494                 :            : 
     495                 :          0 : XclExpFmlaCompImpl::XclExpFmlaCompImpl( const XclExpRoot& rRoot ) :
     496                 :            :     XclExpRoot( rRoot ),
     497                 :            :     maFuncProv( rRoot ),
     498                 :          0 :     meBiff( rRoot.GetBiff() ),
     499                 :          0 :     mnMaxAbsCol( static_cast< SCsCOL >( rRoot.GetXclMaxPos().Col() ) ),
     500                 :          0 :     mnMaxAbsRow( static_cast< SCsROW >( rRoot.GetXclMaxPos().Row() ) ),
     501                 :          0 :     mnMaxScCol( static_cast< SCsCOL >( rRoot.GetScMaxPos().Col() ) ),
     502                 :          0 :     mnMaxScRow( static_cast< SCsROW >( rRoot.GetScMaxPos().Row() ) ),
     503                 :          0 :     mnMaxColMask( static_cast< sal_uInt16 >( rRoot.GetXclMaxPos().Col() ) ),
     504 [ #  # ][ #  # ]:          0 :     mnMaxRowMask( static_cast< sal_uInt32 >( rRoot.GetXclMaxPos().Row() ) )
         [ #  # ][ #  # ]
     505                 :            : {
     506                 :            :     // build the configuration map
     507         [ #  # ]:          0 :     for( const XclExpCompConfig* pEntry = spConfigTable; pEntry != STATIC_TABLE_END( spConfigTable ); ++pEntry )
     508         [ #  # ]:          0 :         maCfgMap[ pEntry->meType ] = *pEntry;
     509                 :          0 : }
     510                 :            : 
     511                 :          0 : XclTokenArrayRef XclExpFmlaCompImpl::CreateFormula( XclFormulaType eType,
     512                 :            :         const ScTokenArray& rScTokArr, const ScAddress* pScBasePos, XclExpRefLog* pRefLog )
     513                 :            : {
     514                 :            :     // initialize the compiler
     515                 :          0 :     Init( eType, rScTokArr, pScBasePos, pRefLog );
     516                 :            : 
     517                 :            :     // start compilation, if initialization didn't fail
     518         [ #  # ]:          0 :     if( mxData->mbOk )
     519                 :            :     {
     520         [ #  # ]:          0 :         XclExpScToken aTokData( GetNextToken() );
     521                 :          0 :         sal_uInt16 nScError = rScTokArr.GetCodeError();
     522 [ #  # ][ #  # ]:          0 :         if( (nScError != 0) && (!aTokData.Is() || (aTokData.GetOpCode() == ocStop)) )
         [ #  # ][ #  # ]
     523                 :            :         {
     524                 :            :             // #i50253# convert simple ocStop token to error code formula (e.g. =#VALUE!)
     525 [ #  # ][ #  # ]:          0 :             AppendErrorToken( XclTools::GetXclErrorCode( nScError ), aTokData.mnSpaces );
     526                 :            :         }
     527         [ #  # ]:          0 :         else if( aTokData.Is() )
     528                 :            :         {
     529         [ #  # ]:          0 :             aTokData = Expression( aTokData, false, false );
     530                 :            :         }
     531                 :            :         else
     532                 :            :         {
     533                 :            :             OSL_FAIL( "XclExpFmlaCompImpl::CreateFormula - empty token array" );
     534                 :          0 :             mxData->mbOk = false;
     535                 :            :         }
     536                 :            : 
     537         [ #  # ]:          0 :         if( mxData->mbOk )
     538                 :            :         {
     539                 :            :             // #i44907# auto-generated SUBTOTAL formula cells have trailing ocStop token
     540 [ #  # ][ #  # ]:          0 :             mxData->mbOk = !aTokData.Is() || (aTokData.GetOpCode() == ocStop);
     541                 :            :             OSL_ENSURE( mxData->mbOk, "XclExpFmlaCompImpl::CreateFormula - unknown garbage behind formula" );
     542                 :            :         }
     543                 :            :     }
     544                 :            : 
     545                 :            :     // finalize (add tAttrVolatile token, calculate all token classes)
     546                 :          0 :     RecalcTokenClasses();
     547                 :          0 :     FinalizeFormula();
     548                 :            : 
     549                 :            :     // leave recursive call, create and return the final token array
     550                 :          0 :     return CreateTokenArray();
     551                 :            : }
     552                 :            : 
     553                 :          0 : XclTokenArrayRef XclExpFmlaCompImpl::CreateErrorFormula( sal_uInt8 nErrCode )
     554                 :            : {
     555                 :          0 :     Init( EXC_FMLATYPE_NAME );
     556                 :          0 :     AppendErrorToken( nErrCode );
     557                 :          0 :     return CreateTokenArray();
     558                 :            : }
     559                 :            : 
     560                 :          0 : XclTokenArrayRef XclExpFmlaCompImpl::CreateSpecialRefFormula( sal_uInt8 nTokenId, const XclAddress& rXclPos )
     561                 :            : {
     562                 :          0 :     Init( EXC_FMLATYPE_NAME );
     563                 :          0 :     AppendOperandTokenId( nTokenId );
     564                 :          0 :     Append( static_cast<sal_uInt16>(rXclPos.mnRow) );
     565                 :          0 :     Append( rXclPos.mnCol );    // do not use AppendAddress(), we always need 16-bit column here
     566                 :          0 :     return CreateTokenArray();
     567                 :            : }
     568                 :            : 
     569                 :          0 : XclTokenArrayRef XclExpFmlaCompImpl::CreateNameXFormula( sal_uInt16 nExtSheet, sal_uInt16 nExtName )
     570                 :            : {
     571                 :          0 :     Init( EXC_FMLATYPE_NAME );
     572                 :          0 :     AppendNameXToken( nExtSheet, nExtName );
     573                 :          0 :     return CreateTokenArray();
     574                 :            : }
     575                 :            : 
     576                 :          0 : bool XclExpFmlaCompImpl::Is3DRefOnly( XclFormulaType eType ) const
     577                 :            : {
     578                 :          0 :     const XclExpCompConfig* pCfg = GetConfigForType( eType );
     579 [ #  # ][ #  # ]:          0 :     return pCfg && pCfg->mb3DRefOnly;
     580                 :            : }
     581                 :            : 
     582                 :            : // private --------------------------------------------------------------------
     583                 :            : 
     584                 :          0 : const XclExpCompConfig* XclExpFmlaCompImpl::GetConfigForType( XclFormulaType eType ) const
     585                 :            : {
     586         [ #  # ]:          0 :     XclExpCompConfigMap::const_iterator aIt = maCfgMap.find( eType );
     587                 :            :     OSL_ENSURE( aIt != maCfgMap.end(), "XclExpFmlaCompImpl::GetConfigForType - unknown formula type" );
     588         [ #  # ]:          0 :     return (aIt == maCfgMap.end()) ? 0 : &aIt->second;
     589                 :            : }
     590                 :            : 
     591                 :          0 : void XclExpFmlaCompImpl::Init( XclFormulaType eType )
     592                 :            : {
     593                 :            :     // compiler invoked recursively? - store old working data
     594         [ #  # ]:          0 :     if( mxData.get() )
     595                 :          0 :         maDataStack.push_back( mxData );
     596                 :            :     // new compiler working data structure
     597         [ #  # ]:          0 :     mxData.reset( new XclExpCompData( GetConfigForType( eType ) ) );
     598                 :          0 : }
     599                 :            : 
     600                 :          0 : void XclExpFmlaCompImpl::Init( XclFormulaType eType, const ScTokenArray& rScTokArr,
     601                 :            :         const ScAddress* pScBasePos, XclExpRefLog* pRefLog )
     602                 :            : {
     603                 :            :     // common initialization
     604                 :          0 :     Init( eType );
     605                 :            : 
     606                 :            :     // special initialization
     607      [ #  #  # ]:          0 :     if( mxData->mbOk ) switch( mxData->mrCfg.meType )
                 [ #  # ]
     608                 :            :     {
     609                 :            :         case EXC_FMLATYPE_CELL:
     610                 :            :         case EXC_FMLATYPE_MATRIX:
     611                 :            :         case EXC_FMLATYPE_CHART:
     612                 :          0 :             mxData->mbOk = pScBasePos != 0;
     613                 :            :             OSL_ENSURE( mxData->mbOk, "XclExpFmlaCompImpl::Init - missing cell address" );
     614                 :          0 :             mxData->mpScBasePos = pScBasePos;
     615                 :          0 :         break;
     616                 :            :         case EXC_FMLATYPE_SHARED:
     617                 :          0 :             mxData->mbOk = pScBasePos != 0;
     618                 :            :             OSL_ENSURE( mxData->mbOk, "XclExpFmlaCompImpl::Init - missing cell address" );
     619                 :            :             // clone the passed token array, convert references relative to current cell position
     620                 :          0 :             mxData->mxOwnScTokArr.reset( rScTokArr.Clone() );
     621                 :          0 :             ScCompiler::MoveRelWrap( *mxData->mxOwnScTokArr, GetDocPtr(), *pScBasePos, MAXCOL, MAXROW );
     622                 :            :             // don't remember pScBasePos in mxData->mpScBasePos, shared formulas use real relative refs
     623                 :          0 :         break;
     624                 :            :         default:;
     625                 :            :     }
     626                 :            : 
     627         [ #  # ]:          0 :     if( mxData->mbOk )
     628                 :            :     {
     629                 :            :         // link manager to be used
     630         [ #  # ]:          0 :         mxData->mpLinkMgr = mxData->mrCfg.mbLocalLinkMgr ? &GetLocalLinkManager() : &GetGlobalLinkManager();
     631                 :            : 
     632                 :            :         // token array iterator (use cloned token array if present)
     633         [ #  # ]:          0 :         mxData->maTokArrIt.Init( mxData->mxOwnScTokArr ? *mxData->mxOwnScTokArr : rScTokArr, false );
     634                 :          0 :         mxData->mpRefLog = pRefLog;
     635                 :            :     }
     636                 :          0 : }
     637                 :            : 
     638                 :          0 : void XclExpFmlaCompImpl::RecalcTokenClasses()
     639                 :            : {
     640         [ #  # ]:          0 :     if( mxData->mbOk )
     641                 :            :     {
     642                 :          0 :         mxData->mbOk = mxData->maOpPosStack.size() == 1;
     643                 :            :         OSL_ENSURE( mxData->mbOk, "XclExpFmlaCompImpl::RecalcTokenClasses - position of root token expected on stack" );
     644         [ #  # ]:          0 :         if( mxData->mbOk )
     645                 :            :         {
     646                 :            :             /*  Cell and array formulas start with VAL conversion and VALTYPE
     647                 :            :                 parameter type, defined names start with ARR conversion and
     648                 :            :                 REFTYPE parameter type for the root token. */
     649         [ #  # ]:          0 :             XclExpOperandList aOperands;
     650                 :          0 :             bool bNameFmla = mxData->mrCfg.meClassType == EXC_CLASSTYPE_NAME;
     651         [ #  # ]:          0 :             XclFuncParamConv eParamConv = bNameFmla ? EXC_PARAMCONV_ARR : EXC_PARAMCONV_VAL;
     652         [ #  # ]:          0 :             XclExpClassConv eClassConv = bNameFmla ? EXC_CLASSCONV_ARR : EXC_CLASSCONV_VAL;
     653         [ #  # ]:          0 :             XclExpTokenConvInfo aConvInfo = { PopOperandPos(), eParamConv, !bNameFmla };
     654         [ #  # ]:          0 :             RecalcTokenClass( aConvInfo, eParamConv, eClassConv, bNameFmla );
     655                 :            :         }
     656                 :            : 
     657                 :            :         // clear operand vectors (calls to the expensive InsertZeros() may follow)
     658                 :          0 :         mxData->maOpListVec.clear();
     659                 :          0 :         mxData->maOpPosStack.clear();
     660                 :            :     }
     661                 :          0 : }
     662                 :            : 
     663                 :          0 : void XclExpFmlaCompImpl::RecalcTokenClass( const XclExpTokenConvInfo& rConvInfo,
     664                 :            :         XclFuncParamConv ePrevConv, XclExpClassConv ePrevClassConv, bool bWasRefClass )
     665                 :            : {
     666                 :            :     OSL_ENSURE( rConvInfo.mnTokPos < GetSize(), "XclExpFmlaCompImpl::RecalcTokenClass - invalid token position" );
     667                 :          0 :     sal_uInt8& rnTokenId = mxData->maTokVec[ rConvInfo.mnTokPos ];
     668                 :          0 :     sal_uInt8 nTokClass = GetTokenClass( rnTokenId );
     669                 :            : 
     670                 :            :     // REF tokens in VALTYPE parameters behave like VAL tokens
     671 [ #  # ][ #  # ]:          0 :     if( rConvInfo.mbValType && (nTokClass == EXC_TOKCLASS_REF) )
     672                 :          0 :         ChangeTokenClass( rnTokenId, nTokClass = EXC_TOKCLASS_VAL );
     673                 :            : 
     674                 :            :     // replace RPO conversion of operator with parent conversion
     675         [ #  # ]:          0 :     XclFuncParamConv eConv = (rConvInfo.meConv == EXC_PARAMCONV_RPO) ? ePrevConv : rConvInfo.meConv;
     676                 :            : 
     677                 :            :     // find the effective token class conversion to be performed for this token
     678                 :          0 :     XclExpClassConv eClassConv = EXC_CLASSCONV_ORG;
     679   [ #  #  #  #  :          0 :     switch( eConv )
                #  #  # ]
     680                 :            :     {
     681                 :            :         case EXC_PARAMCONV_ORG:
     682                 :            :             // conversion is forced independent of parent conversion
     683                 :          0 :             eClassConv = EXC_CLASSCONV_ORG;
     684                 :          0 :         break;
     685                 :            :         case EXC_PARAMCONV_VAL:
     686                 :            :             // conversion is forced independent of parent conversion
     687                 :          0 :             eClassConv = EXC_CLASSCONV_VAL;
     688                 :          0 :         break;
     689                 :            :         case EXC_PARAMCONV_ARR:
     690                 :            :             // conversion is forced independent of parent conversion
     691                 :          0 :             eClassConv = EXC_CLASSCONV_ARR;
     692                 :          0 :         break;
     693                 :            :         case EXC_PARAMCONV_RPT:
     694   [ #  #  #  #  :          0 :             switch( ePrevConv )
                      # ]
     695                 :            :             {
     696                 :            :                 case EXC_PARAMCONV_ORG:
     697                 :            :                 case EXC_PARAMCONV_VAL:
     698                 :            :                 case EXC_PARAMCONV_ARR:
     699                 :            :                     /*  If parent token has REF class (REF token in REFTYPE
     700                 :            :                         function parameter), then RPT does not repeat the
     701                 :            :                         previous explicit ORG or ARR conversion, but always
     702                 :            :                         falls back to VAL conversion. */
     703         [ #  # ]:          0 :                     eClassConv = bWasRefClass ? EXC_CLASSCONV_VAL : ePrevClassConv;
     704                 :          0 :                 break;
     705                 :            :                 case EXC_PARAMCONV_RPT:
     706                 :            :                     // nested RPT repeats the previous effective conversion
     707                 :          0 :                     eClassConv = ePrevClassConv;
     708                 :          0 :                 break;
     709                 :            :                 case EXC_PARAMCONV_RPX:
     710                 :            :                     /*  If parent token has REF class (REF token in REFTYPE
     711                 :            :                         function parameter), then RPX repeats the previous
     712                 :            :                         effective conversion (wich will be either ORG or ARR,
     713                 :            :                         but never VAL), otherwise falls back to ORG conversion. */
     714         [ #  # ]:          0 :                     eClassConv = bWasRefClass ? ePrevClassConv : EXC_CLASSCONV_ORG;
     715                 :          0 :                 break;
     716                 :            :                 case EXC_PARAMCONV_RPO: // does not occur
     717                 :          0 :                 break;
     718                 :            :             }
     719                 :          0 :         break;
     720                 :            :         case EXC_PARAMCONV_RPX:
     721                 :            :             /*  If current token still has REF class, set previous effective
     722                 :            :                 conversion as current conversion. This will not have an effect
     723                 :            :                 on the REF token but is needed for RPT parameters of this
     724                 :            :                 function that want to repeat this conversion type. If current
     725                 :            :                 token is VAL or ARR class, the previous ARR conversion will be
     726                 :            :                 repeated on the token, but VAL conversion will not. */
     727                 :            :             eClassConv = ((nTokClass == EXC_TOKCLASS_REF) || (ePrevClassConv == EXC_CLASSCONV_ARR)) ?
     728 [ #  # ][ #  # ]:          0 :                 ePrevClassConv : EXC_CLASSCONV_ORG;
     729                 :          0 :         break;
     730                 :            :         case EXC_PARAMCONV_RPO: // does not occur (see above)
     731                 :          0 :         break;
     732                 :            :     }
     733                 :            : 
     734                 :            :     // do the token class conversion
     735   [ #  #  #  # ]:          0 :     switch( eClassConv )
     736                 :            :     {
     737                 :            :         case EXC_CLASSCONV_ORG:
     738                 :            :             /*  Cell formulas: leave the current token class. Cell formulas
     739                 :            :                 are the only type of formulas where all tokens can keep
     740                 :            :                 their original token class.
     741                 :            :                 Array and defined name formulas: convert VAL to ARR. */
     742 [ #  # ][ #  # ]:          0 :             if( (mxData->mrCfg.meClassType != EXC_CLASSTYPE_CELL) && (nTokClass == EXC_TOKCLASS_VAL) )
                 [ #  # ]
     743                 :          0 :                 ChangeTokenClass( rnTokenId, nTokClass = EXC_TOKCLASS_ARR );
     744                 :          0 :         break;
     745                 :            :         case EXC_CLASSCONV_VAL:
     746                 :            :             // convert ARR to VAL
     747         [ #  # ]:          0 :             if( nTokClass == EXC_TOKCLASS_ARR )
     748                 :          0 :                 ChangeTokenClass( rnTokenId, nTokClass = EXC_TOKCLASS_VAL );
     749                 :          0 :         break;
     750                 :            :         case EXC_CLASSCONV_ARR:
     751                 :            :             // convert VAL to ARR
     752         [ #  # ]:          0 :             if( nTokClass == EXC_TOKCLASS_VAL )
     753                 :          0 :                 ChangeTokenClass( rnTokenId, nTokClass = EXC_TOKCLASS_ARR );
     754                 :          0 :         break;
     755                 :            :     }
     756                 :            : 
     757                 :            :     // do conversion for nested operands, if token is an operator or function
     758         [ #  # ]:          0 :     if( rConvInfo.mnTokPos < mxData->maOpListVec.size() )
     759         [ #  # ]:          0 :         if( const XclExpOperandList* pOperands = mxData->maOpListVec[ rConvInfo.mnTokPos ].get() )
     760 [ #  # ][ #  # ]:          0 :             for( XclExpOperandList::const_iterator aIt = pOperands->begin(), aEnd = pOperands->end(); aIt != aEnd; ++aIt )
     761         [ #  # ]:          0 :                 RecalcTokenClass( *aIt, eConv, eClassConv, nTokClass == EXC_TOKCLASS_REF );
     762                 :          0 : }
     763                 :            : 
     764                 :          0 : void XclExpFmlaCompImpl::FinalizeFormula()
     765                 :            : {
     766         [ #  # ]:          0 :     if( mxData->mbOk )
     767                 :            :     {
     768                 :            :         // Volatile? Add a tAttrVolatile token at the beginning of the token array.
     769         [ #  # ]:          0 :         if( mxData->mbVolatile )
     770                 :            :         {
     771                 :            :             // tAttrSpace token can be extended with volatile flag
     772         [ #  # ]:          0 :             if( !IsSpaceToken( 0 ) )
     773                 :            :             {
     774                 :          0 :                 InsertZeros( 0, 4 );
     775                 :          0 :                 mxData->maTokVec[ 0 ] = EXC_TOKID_ATTR;
     776                 :            :             }
     777                 :          0 :             mxData->maTokVec[ 1 ] |= EXC_TOK_ATTR_VOLATILE;
     778                 :            :         }
     779                 :            : 
     780                 :            :         // Token array too long? -> error
     781                 :          0 :         mxData->mbOk = mxData->maTokVec.size() <= EXC_TOKARR_MAXLEN;
     782                 :            :     }
     783                 :            : 
     784         [ #  # ]:          0 :     if( !mxData->mbOk )
     785                 :            :     {
     786                 :            :         // Any unrecoverable error? -> Create a =#NA formula.
     787                 :          0 :         mxData->maTokVec.clear();
     788                 :          0 :         mxData->maExtDataVec.clear();
     789                 :          0 :         mxData->mbVolatile = false;
     790                 :          0 :         AppendErrorToken( EXC_ERR_NA );
     791                 :            :     }
     792                 :          0 : }
     793                 :            : 
     794                 :          0 : XclTokenArrayRef XclExpFmlaCompImpl::CreateTokenArray()
     795                 :            : {
     796                 :            :     // create the Excel token array from working data before resetting mxData
     797                 :            :     OSL_ENSURE( mxData->mrCfg.mbAllowArrays || mxData->maExtDataVec.empty(), "XclExpFmlaCompImpl::CreateTokenArray - unexpected extended data" );
     798         [ #  # ]:          0 :     if( !mxData->mrCfg.mbAllowArrays )
     799                 :          0 :         mxData->maExtDataVec.clear();
     800 [ #  # ][ #  # ]:          0 :     XclTokenArrayRef xTokArr( new XclTokenArray( mxData->maTokVec, mxData->maExtDataVec, mxData->mbVolatile ) );
                 [ #  # ]
     801         [ #  # ]:          0 :     mxData.reset();
     802                 :            : 
     803                 :            :     // compiler invoked recursively? - restore old working data
     804         [ #  # ]:          0 :     if( !maDataStack.empty() )
     805                 :            :     {
     806 [ #  # ][ #  # ]:          0 :         mxData = maDataStack.back();
     807         [ #  # ]:          0 :         maDataStack.pop_back();
     808                 :            :     }
     809                 :            : 
     810                 :          0 :     return xTokArr;
     811                 :            : }
     812                 :            : 
     813                 :            : // compiler -------------------------------------------------------------------
     814                 :            : 
     815                 :          0 : const FormulaToken* XclExpFmlaCompImpl::GetNextRawToken()
     816                 :            : {
     817                 :          0 :     const FormulaToken* pScToken = mxData->maTokArrIt.Get();
     818                 :          0 :     ++mxData->maTokArrIt;
     819                 :          0 :     return pScToken;
     820                 :            : }
     821                 :            : 
     822                 :          0 : const FormulaToken* XclExpFmlaCompImpl::PeekNextRawToken( bool bSkipSpaces ) const
     823                 :            : {
     824                 :            :     /*  Returns pointer to next raw token in the token array. The token array
     825                 :            :         iterator already points to the next token (A call to GetNextToken()
     826                 :            :         always increases the iterator), so this function just returns the token
     827                 :            :         the iterator points to. To skip space tokens, a copy of the iterator is
     828                 :            :         created and set to the passed skip-spaces mode. If spaces have to be
     829                 :            :         skipped, and the iterator currently points to a space token, the
     830                 :            :         constructor will move it to the next non-space token. */
     831         [ #  # ]:          0 :     XclTokenArrayIterator aTempIt( mxData->maTokArrIt, bSkipSpaces );
     832                 :          0 :     return aTempIt.Get();
     833                 :            : }
     834                 :            : 
     835                 :          0 : bool XclExpFmlaCompImpl::GetNextToken( XclExpScToken& rTokData )
     836                 :            : {
     837                 :          0 :     rTokData.mpScToken = GetNextRawToken();
     838         [ #  # ]:          0 :     rTokData.mnSpaces = (rTokData.GetOpCode() == ocSpaces) ? rTokData.mpScToken->GetByte() : 0;
     839         [ #  # ]:          0 :     while( rTokData.GetOpCode() == ocSpaces )
     840                 :          0 :         rTokData.mpScToken = GetNextRawToken();
     841                 :          0 :     return rTokData.Is();
     842                 :            : }
     843                 :            : 
     844                 :          0 : XclExpScToken XclExpFmlaCompImpl::GetNextToken()
     845                 :            : {
     846                 :          0 :     XclExpScToken aTokData;
     847                 :          0 :     GetNextToken( aTokData );
     848                 :          0 :     return aTokData;
     849                 :            : }
     850                 :            : 
     851                 :            : namespace {
     852                 :            : 
     853                 :            : /** Returns the Excel token ID of a comparison operator or EXC_TOKID_NONE. */
     854                 :          0 : inline sal_uInt8 lclGetCompareTokenId( OpCode eOpCode )
     855                 :            : {
     856   [ #  #  #  #  :          0 :     switch( eOpCode )
                #  #  # ]
     857                 :            :     {
     858                 :          0 :         case ocLess:            return EXC_TOKID_LT;
     859                 :          0 :         case ocLessEqual:       return EXC_TOKID_LE;
     860                 :          0 :         case ocEqual:           return EXC_TOKID_EQ;
     861                 :          0 :         case ocGreaterEqual:    return EXC_TOKID_GE;
     862                 :          0 :         case ocGreater:         return EXC_TOKID_GT;
     863                 :          0 :         case ocNotEqual:        return EXC_TOKID_NE;
     864                 :            :         default:;
     865                 :            :     }
     866                 :          0 :     return EXC_TOKID_NONE;
     867                 :            : }
     868                 :            : 
     869                 :            : /** Returns the Excel token ID of a string concatenation operator or EXC_TOKID_NONE. */
     870                 :          0 : inline sal_uInt8 lclGetConcatTokenId( OpCode eOpCode )
     871                 :            : {
     872         [ #  # ]:          0 :     return (eOpCode == ocAmpersand) ? EXC_TOKID_CONCAT : EXC_TOKID_NONE;
     873                 :            : }
     874                 :            : 
     875                 :            : /** Returns the Excel token ID of an addition/subtraction operator or EXC_TOKID_NONE. */
     876                 :          0 : inline sal_uInt8 lclGetAddSubTokenId( OpCode eOpCode )
     877                 :            : {
     878      [ #  #  # ]:          0 :     switch( eOpCode )
     879                 :            :     {
     880                 :          0 :         case ocAdd:     return EXC_TOKID_ADD;
     881                 :          0 :         case ocSub:     return EXC_TOKID_SUB;
     882                 :            :         default:;
     883                 :            :     }
     884                 :          0 :     return EXC_TOKID_NONE;
     885                 :            : }
     886                 :            : 
     887                 :            : /** Returns the Excel token ID of a multiplication/division operator or EXC_TOKID_NONE. */
     888                 :          0 : inline sal_uInt8 lclGetMulDivTokenId( OpCode eOpCode )
     889                 :            : {
     890      [ #  #  # ]:          0 :     switch( eOpCode )
     891                 :            :     {
     892                 :          0 :         case ocMul:     return EXC_TOKID_MUL;
     893                 :          0 :         case ocDiv:     return EXC_TOKID_DIV;
     894                 :            :         default:;
     895                 :            :     }
     896                 :          0 :     return EXC_TOKID_NONE;
     897                 :            : }
     898                 :            : 
     899                 :            : /** Returns the Excel token ID of a power operator or EXC_TOKID_NONE. */
     900                 :          0 : inline sal_uInt8 lclGetPowTokenId( OpCode eOpCode )
     901                 :            : {
     902         [ #  # ]:          0 :     return (eOpCode == ocPow) ? EXC_TOKID_POWER : EXC_TOKID_NONE;
     903                 :            : }
     904                 :            : 
     905                 :            : /** Returns the Excel token ID of a trailing unary operator or EXC_TOKID_NONE. */
     906                 :          0 : inline sal_uInt8 lclGetUnaryPostTokenId( OpCode eOpCode )
     907                 :            : {
     908         [ #  # ]:          0 :     return (eOpCode == ocPercentSign) ? EXC_TOKID_PERCENT : EXC_TOKID_NONE;
     909                 :            : }
     910                 :            : 
     911                 :            : /** Returns the Excel token ID of a leading unary operator or EXC_TOKID_NONE. */
     912                 :          0 : inline sal_uInt8 lclGetUnaryPreTokenId( OpCode eOpCode )
     913                 :            : {
     914   [ #  #  #  # ]:          0 :     switch( eOpCode )
     915                 :            :     {
     916                 :          0 :         case ocAdd:     return EXC_TOKID_UPLUS;     // +(1)
     917                 :          0 :         case ocNeg:     return EXC_TOKID_UMINUS;    // NEG(1)
     918                 :          0 :         case ocNegSub:  return EXC_TOKID_UMINUS;    // -(1)
     919                 :            :         default:;
     920                 :            :     }
     921                 :          0 :     return EXC_TOKID_NONE;
     922                 :            : }
     923                 :            : 
     924                 :            : /** Returns the Excel token ID of a reference list operator or EXC_TOKID_NONE. */
     925                 :          0 : inline sal_uInt8 lclGetListTokenId( OpCode eOpCode, bool bStopAtSep )
     926                 :            : {
     927 [ #  # ][ #  # ]:          0 :     return ((eOpCode == ocUnion) || (!bStopAtSep && (eOpCode == ocSep))) ? EXC_TOKID_LIST : EXC_TOKID_NONE;
                 [ #  # ]
     928                 :            : }
     929                 :            : 
     930                 :            : /** Returns the Excel token ID of a reference intersection operator or EXC_TOKID_NONE. */
     931                 :          0 : inline sal_uInt8 lclGetIntersectTokenId( OpCode eOpCode )
     932                 :            : {
     933         [ #  # ]:          0 :     return (eOpCode == ocIntersect) ? EXC_TOKID_ISECT : EXC_TOKID_NONE;
     934                 :            : }
     935                 :            : 
     936                 :            : /** Returns the Excel token ID of a reference range operator or EXC_TOKID_NONE. */
     937                 :          0 : inline sal_uInt8 lclGetRangeTokenId( OpCode eOpCode )
     938                 :            : {
     939         [ #  # ]:          0 :     return (eOpCode == ocRange) ? EXC_TOKID_RANGE : EXC_TOKID_NONE;
     940                 :            : }
     941                 :            : 
     942                 :            : } // namespace
     943                 :            : 
     944                 :          0 : XclExpScToken XclExpFmlaCompImpl::Expression( XclExpScToken aTokData, bool bInParentheses, bool bStopAtSep )
     945                 :            : {
     946 [ #  # ][ #  # ]:          0 :     if( mxData->mbOk && aTokData.Is() )
                 [ #  # ]
     947                 :            :     {
     948                 :            :         // remember old stop-at-ocSep mode, restored below
     949                 :          0 :         bool bOldStopAtSep = mxData->mbStopAtSep;
     950                 :          0 :         mxData->mbStopAtSep = bStopAtSep;
     951                 :            :         // start compilation of the subexpression
     952                 :          0 :         aTokData = OrTerm( aTokData, bInParentheses );
     953                 :            :         // restore old stop-at-ocSep mode
     954                 :          0 :         mxData->mbStopAtSep = bOldStopAtSep;
     955                 :            :     }
     956                 :          0 :     return aTokData;
     957                 :            : }
     958                 :            : 
     959                 :          0 : XclExpScToken XclExpFmlaCompImpl::SkipExpression( XclExpScToken aTokData, bool bStopAtSep )
     960                 :            : {
     961 [ #  # ][ #  # ]:          0 :     while( mxData->mbOk && aTokData.Is() && (aTokData.GetOpCode() != ocClose) && (!bStopAtSep || (aTokData.GetOpCode() != ocSep)) )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     962                 :            :     {
     963         [ #  # ]:          0 :         if( aTokData.GetOpCode() == ocOpen )
     964                 :            :         {
     965                 :          0 :             aTokData = SkipExpression( GetNextToken(), false );
     966         [ #  # ]:          0 :             if( mxData->mbOk ) mxData->mbOk = aTokData.GetOpCode() == ocClose;
     967                 :            :         }
     968                 :          0 :         aTokData = GetNextToken();
     969                 :            :     }
     970                 :          0 :     return aTokData;
     971                 :            : }
     972                 :            : 
     973                 :          0 : XclExpScToken XclExpFmlaCompImpl::OrTerm( XclExpScToken aTokData, bool bInParentheses )
     974                 :            : {
     975                 :          0 :     aTokData = AndTerm( aTokData, bInParentheses );
     976                 :          0 :     sal_uInt8 nParamCount = 1;
     977 [ #  # ][ #  # ]:          0 :     while( mxData->mbOk && (aTokData.GetOpCode() == ocOr) )
                 [ #  # ]
     978                 :            :     {
     979                 :          0 :         RemoveTrailingParen();
     980                 :          0 :         aTokData = AndTerm( GetNextToken(), bInParentheses );
     981                 :          0 :         RemoveTrailingParen();
     982                 :          0 :         ++nParamCount;
     983         [ #  # ]:          0 :         if( mxData->mbOk ) mxData->mbOk = nParamCount <= EXC_FUNC_MAXPARAM;
     984                 :            :     }
     985 [ #  # ][ #  # ]:          0 :     if( mxData->mbOk && (nParamCount > 1) )
                 [ #  # ]
     986                 :          0 :         AppendLogicalOperatorToken( EXC_FUNCID_OR, nParamCount );
     987                 :          0 :     return aTokData;
     988                 :            : }
     989                 :            : 
     990                 :          0 : XclExpScToken XclExpFmlaCompImpl::AndTerm( XclExpScToken aTokData, bool bInParentheses )
     991                 :            : {
     992                 :          0 :     aTokData = CompareTerm( aTokData, bInParentheses );
     993                 :          0 :     sal_uInt8 nParamCount = 1;
     994 [ #  # ][ #  # ]:          0 :     while( mxData->mbOk && (aTokData.GetOpCode() == ocAnd) )
                 [ #  # ]
     995                 :            :     {
     996                 :          0 :         RemoveTrailingParen();
     997                 :          0 :         aTokData = CompareTerm( GetNextToken(), bInParentheses );
     998                 :          0 :         RemoveTrailingParen();
     999                 :          0 :         ++nParamCount;
    1000         [ #  # ]:          0 :         if( mxData->mbOk ) mxData->mbOk = nParamCount <= EXC_FUNC_MAXPARAM;
    1001                 :            :     }
    1002 [ #  # ][ #  # ]:          0 :     if( mxData->mbOk && (nParamCount > 1) )
                 [ #  # ]
    1003                 :          0 :         AppendLogicalOperatorToken( EXC_FUNCID_AND, nParamCount );
    1004                 :          0 :     return aTokData;
    1005                 :            : }
    1006                 :            : 
    1007                 :          0 : XclExpScToken XclExpFmlaCompImpl::CompareTerm( XclExpScToken aTokData, bool bInParentheses )
    1008                 :            : {
    1009                 :          0 :     aTokData = ConcatTerm( aTokData, bInParentheses );
    1010                 :          0 :     sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
    1011 [ #  # ][ #  # ]:          0 :     while( mxData->mbOk && ((nOpTokenId = lclGetCompareTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
                 [ #  # ]
    1012                 :            :     {
    1013                 :          0 :         sal_uInt8 nSpaces = aTokData.mnSpaces;
    1014                 :          0 :         aTokData = ConcatTerm( GetNextToken(), bInParentheses );
    1015                 :          0 :         AppendBinaryOperatorToken( nOpTokenId, true, nSpaces );
    1016                 :            :     }
    1017                 :          0 :     return aTokData;
    1018                 :            : }
    1019                 :            : 
    1020                 :          0 : XclExpScToken XclExpFmlaCompImpl::ConcatTerm( XclExpScToken aTokData, bool bInParentheses )
    1021                 :            : {
    1022                 :          0 :     aTokData = AddSubTerm( aTokData, bInParentheses );
    1023                 :          0 :     sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
    1024 [ #  # ][ #  # ]:          0 :     while( mxData->mbOk && ((nOpTokenId = lclGetConcatTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
                 [ #  # ]
    1025                 :            :     {
    1026                 :          0 :         sal_uInt8 nSpaces = aTokData.mnSpaces;
    1027                 :          0 :         aTokData = AddSubTerm( GetNextToken(), bInParentheses );
    1028                 :          0 :         AppendBinaryOperatorToken( nOpTokenId, true, nSpaces );
    1029                 :            :     }
    1030                 :          0 :     return aTokData;
    1031                 :            : }
    1032                 :            : 
    1033                 :          0 : XclExpScToken XclExpFmlaCompImpl::AddSubTerm( XclExpScToken aTokData, bool bInParentheses )
    1034                 :            : {
    1035                 :          0 :     aTokData = MulDivTerm( aTokData, bInParentheses );
    1036                 :          0 :     sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
    1037 [ #  # ][ #  # ]:          0 :     while( mxData->mbOk && ((nOpTokenId = lclGetAddSubTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
                 [ #  # ]
    1038                 :            :     {
    1039                 :          0 :         sal_uInt8 nSpaces = aTokData.mnSpaces;
    1040                 :          0 :         aTokData = MulDivTerm( GetNextToken(), bInParentheses );
    1041                 :          0 :         AppendBinaryOperatorToken( nOpTokenId, true, nSpaces );
    1042                 :            :     }
    1043                 :          0 :     return aTokData;
    1044                 :            : }
    1045                 :            : 
    1046                 :          0 : XclExpScToken XclExpFmlaCompImpl::MulDivTerm( XclExpScToken aTokData, bool bInParentheses )
    1047                 :            : {
    1048                 :          0 :     aTokData = PowTerm( aTokData, bInParentheses );
    1049                 :          0 :     sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
    1050 [ #  # ][ #  # ]:          0 :     while( mxData->mbOk && ((nOpTokenId = lclGetMulDivTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
                 [ #  # ]
    1051                 :            :     {
    1052                 :          0 :         sal_uInt8 nSpaces = aTokData.mnSpaces;
    1053                 :          0 :         aTokData = PowTerm( GetNextToken(), bInParentheses );
    1054                 :          0 :         AppendBinaryOperatorToken( nOpTokenId, true, nSpaces );
    1055                 :            :     }
    1056                 :          0 :     return aTokData;
    1057                 :            : }
    1058                 :            : 
    1059                 :          0 : XclExpScToken XclExpFmlaCompImpl::PowTerm( XclExpScToken aTokData, bool bInParentheses )
    1060                 :            : {
    1061                 :          0 :     aTokData = UnaryPostTerm( aTokData, bInParentheses );
    1062                 :          0 :     sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
    1063 [ #  # ][ #  # ]:          0 :     while( mxData->mbOk && ((nOpTokenId = lclGetPowTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
                 [ #  # ]
    1064                 :            :     {
    1065                 :          0 :         sal_uInt8 nSpaces = aTokData.mnSpaces;
    1066                 :          0 :         aTokData = UnaryPostTerm( GetNextToken(), bInParentheses );
    1067                 :          0 :         AppendBinaryOperatorToken( nOpTokenId, true, nSpaces );
    1068                 :            :     }
    1069                 :          0 :     return aTokData;
    1070                 :            : }
    1071                 :            : 
    1072                 :          0 : XclExpScToken XclExpFmlaCompImpl::UnaryPostTerm( XclExpScToken aTokData, bool bInParentheses )
    1073                 :            : {
    1074                 :          0 :     aTokData = UnaryPreTerm( aTokData, bInParentheses );
    1075                 :          0 :     sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
    1076 [ #  # ][ #  # ]:          0 :     while( mxData->mbOk && ((nOpTokenId = lclGetUnaryPostTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
                 [ #  # ]
    1077                 :            :     {
    1078                 :          0 :         AppendUnaryOperatorToken( nOpTokenId, aTokData.mnSpaces );
    1079                 :          0 :         GetNextToken( aTokData );
    1080                 :            :     }
    1081                 :          0 :     return aTokData;
    1082                 :            : }
    1083                 :            : 
    1084                 :          0 : XclExpScToken XclExpFmlaCompImpl::UnaryPreTerm( XclExpScToken aTokData, bool bInParentheses )
    1085                 :            : {
    1086         [ #  # ]:          0 :     sal_uInt8 nOpTokenId = mxData->mbOk ? lclGetUnaryPreTokenId( aTokData.GetOpCode() ) : EXC_TOKID_NONE;
    1087         [ #  # ]:          0 :     if( nOpTokenId != EXC_TOKID_NONE )
    1088                 :            :     {
    1089                 :          0 :         sal_uInt8 nSpaces = aTokData.mnSpaces;
    1090                 :          0 :         aTokData = UnaryPreTerm( GetNextToken(), bInParentheses );
    1091                 :          0 :         AppendUnaryOperatorToken( nOpTokenId, nSpaces );
    1092                 :            :     }
    1093                 :            :     else
    1094                 :            :     {
    1095                 :          0 :         aTokData = ListTerm( aTokData, bInParentheses );
    1096                 :            :     }
    1097                 :          0 :     return aTokData;
    1098                 :            : }
    1099                 :            : 
    1100                 :          0 : XclExpScToken XclExpFmlaCompImpl::ListTerm( XclExpScToken aTokData, bool bInParentheses )
    1101                 :            : {
    1102         [ #  # ]:          0 :     sal_uInt16 nSubExprPos = GetSize();
    1103                 :          0 :     bool bHasAnyRefOp = false;
    1104                 :          0 :     bool bHasListOp = false;
    1105         [ #  # ]:          0 :     aTokData = IntersectTerm( aTokData, bHasAnyRefOp );
    1106                 :          0 :     sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
    1107 [ #  # ][ #  # ]:          0 :     while( mxData->mbOk && ((nOpTokenId = lclGetListTokenId( aTokData.GetOpCode(), mxData->mbStopAtSep )) != EXC_TOKID_NONE) )
                 [ #  # ]
    1108                 :            :     {
    1109                 :          0 :         sal_uInt8 nSpaces = aTokData.mnSpaces;
    1110 [ #  # ][ #  # ]:          0 :         aTokData = IntersectTerm( GetNextToken(), bHasAnyRefOp );
    1111         [ #  # ]:          0 :         AppendBinaryOperatorToken( nOpTokenId, false, nSpaces );
    1112                 :          0 :         bHasAnyRefOp = bHasListOp = true;
    1113                 :            :     }
    1114         [ #  # ]:          0 :     if( bHasAnyRefOp )
    1115                 :            :     {
    1116                 :            :         // add a tMemFunc token enclosing the entire reference subexpression
    1117         [ #  # ]:          0 :         sal_uInt16 nSubExprSize = GetSize() - nSubExprPos;
    1118         [ #  # ]:          0 :         InsertZeros( nSubExprPos, 3 );
    1119         [ #  # ]:          0 :         mxData->maTokVec[ nSubExprPos ] = GetTokenId( EXC_TOKID_MEMFUNC, EXC_TOKCLASS_REF );
    1120         [ #  # ]:          0 :         Overwrite( nSubExprPos + 1, nSubExprSize );
    1121                 :            :         // update the operand/operator stack (set the list expression as operand of the tMemFunc)
    1122 [ #  # ][ #  # ]:          0 :         XclExpOperandListRef xOperands( new XclExpOperandList );
                 [ #  # ]
    1123 [ #  # ][ #  # ]:          0 :         xOperands->AppendOperand( PopOperandPos(), EXC_PARAMCONV_VAL, false );
    1124 [ #  # ][ #  # ]:          0 :         PushOperatorPos( nSubExprPos, xOperands );
    1125                 :            :     }
    1126                 :            :     // #i86439# enclose list operator into parentheses, e.g. Calc's =AREAS(A1~A2) to Excel's =AREAS((A1;A2))
    1127 [ #  # ][ #  # ]:          0 :     if( bHasListOp && !bInParentheses )
    1128         [ #  # ]:          0 :         AppendParenToken();
    1129                 :          0 :     return aTokData;
    1130                 :            : }
    1131                 :            : 
    1132                 :          0 : XclExpScToken XclExpFmlaCompImpl::IntersectTerm( XclExpScToken aTokData, bool& rbHasRefOp )
    1133                 :            : {
    1134                 :          0 :     aTokData = RangeTerm( aTokData, rbHasRefOp );
    1135                 :          0 :     sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
    1136 [ #  # ][ #  # ]:          0 :     while( mxData->mbOk && ((nOpTokenId = lclGetIntersectTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
                 [ #  # ]
    1137                 :            :     {
    1138                 :          0 :         sal_uInt8 nSpaces = aTokData.mnSpaces;
    1139                 :          0 :         aTokData = RangeTerm( GetNextToken(), rbHasRefOp );
    1140                 :          0 :         AppendBinaryOperatorToken( nOpTokenId, false, nSpaces );
    1141                 :          0 :         rbHasRefOp = true;
    1142                 :            :     }
    1143                 :          0 :     return aTokData;
    1144                 :            : }
    1145                 :            : 
    1146                 :          0 : XclExpScToken XclExpFmlaCompImpl::RangeTerm( XclExpScToken aTokData, bool& rbHasRefOp )
    1147                 :            : {
    1148                 :          0 :     aTokData = Factor( aTokData );
    1149                 :          0 :     sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
    1150 [ #  # ][ #  # ]:          0 :     while( mxData->mbOk && ((nOpTokenId = lclGetRangeTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
                 [ #  # ]
    1151                 :            :     {
    1152                 :          0 :         sal_uInt8 nSpaces = aTokData.mnSpaces;
    1153                 :          0 :         aTokData = Factor( GetNextToken() );
    1154                 :          0 :         AppendBinaryOperatorToken( nOpTokenId, false, nSpaces );
    1155                 :          0 :         rbHasRefOp = true;
    1156                 :            :     }
    1157                 :          0 :     return aTokData;
    1158                 :            : }
    1159                 :            : 
    1160                 :          0 : XclExpScToken XclExpFmlaCompImpl::Factor( XclExpScToken aTokData )
    1161                 :            : {
    1162 [ #  # ][ #  # ]:          0 :     if( !mxData->mbOk || !aTokData.Is() ) return XclExpScToken();
                 [ #  # ]
    1163                 :            : 
    1164   [ #  #  #  #  :          0 :     switch( aTokData.GetType() )
          #  #  #  #  #  
                   #  # ]
    1165                 :            :     {
    1166                 :          0 :         case svUnknown:             mxData->mbOk = false;                   break;
    1167                 :          0 :         case svDouble:              ProcessDouble( aTokData );              break;
    1168                 :          0 :         case svString:              ProcessString( aTokData );              break;
    1169                 :          0 :         case svSingleRef:           ProcessCellRef( aTokData );             break;
    1170                 :          0 :         case svDoubleRef:           ProcessRangeRef( aTokData );            break;
    1171                 :          0 :         case svExternalSingleRef:   ProcessExternalCellRef( aTokData );     break;
    1172                 :          0 :         case svExternalDoubleRef:   ProcessExternalRangeRef( aTokData );    break;
    1173                 :          0 :         case svExternalName:        ProcessExternalName( aTokData );        break;
    1174                 :          0 :         case svMatrix:              ProcessMatrix( aTokData );              break;
    1175                 :          0 :         case svExternal:            ProcessExternal( aTokData );            break;
    1176                 :            : 
    1177   [ #  #  #  #  :          0 :         default: switch( aTokData.GetOpCode() )
             #  #  #  # ]
    1178                 :            :         {
    1179                 :          0 :             case ocNone:        /* do nothing */                    break;
    1180                 :          0 :             case ocMissing:     ProcessMissing( aTokData );         break;
    1181                 :          0 :             case ocBad:         ProcessBad( aTokData );             break;
    1182                 :          0 :             case ocOpen:        ProcessParentheses( aTokData );     break;
    1183                 :          0 :             case ocName:        ProcessDefinedName( aTokData );     break;
    1184                 :            :             case ocFalse:
    1185                 :          0 :             case ocTrue:        ProcessBoolean( aTokData );         break;
    1186                 :          0 :             case ocDde:         ProcessDdeLink( aTokData );         break;
    1187                 :          0 :             default:            ProcessFunction( aTokData );
    1188                 :            :         }
    1189                 :            :     }
    1190                 :            : 
    1191                 :          0 :     return GetNextToken();
    1192                 :            : }
    1193                 :            : 
    1194                 :            : // formula structure ----------------------------------------------------------
    1195                 :            : 
    1196                 :          0 : void XclExpFmlaCompImpl::ProcessDouble( const XclExpScToken& rTokData )
    1197                 :            : {
    1198         [ #  # ]:          0 :     double fValue = rTokData.mpScToken->GetDouble();
    1199                 :            :     double fInt;
    1200                 :          0 :     double fFrac = modf( fValue, &fInt );
    1201 [ #  # ][ #  # ]:          0 :     if( (fFrac == 0.0) && (0.0 <= fInt) && (fInt <= 65535.0) )
                 [ #  # ]
    1202         [ #  # ]:          0 :         AppendIntToken( static_cast< sal_uInt16 >( fInt ), rTokData.mnSpaces );
    1203                 :            :     else
    1204         [ #  # ]:          0 :         AppendNumToken( fValue, rTokData.mnSpaces );
    1205                 :          0 : }
    1206                 :            : 
    1207                 :          0 : void XclExpFmlaCompImpl::ProcessString( const XclExpScToken& rTokData )
    1208                 :            : {
    1209                 :          0 :     AppendOperandTokenId( EXC_TOKID_STR, rTokData.mnSpaces );
    1210                 :          0 :     Append( rTokData.mpScToken->GetString() );
    1211                 :          0 : }
    1212                 :            : 
    1213                 :          0 : void XclExpFmlaCompImpl::ProcessMissing( const XclExpScToken& rTokData )
    1214                 :            : {
    1215                 :          0 :     AppendMissingToken( rTokData.mnSpaces );
    1216                 :          0 : }
    1217                 :            : 
    1218                 :          0 : void XclExpFmlaCompImpl::ProcessBad( const XclExpScToken& rTokData )
    1219                 :            : {
    1220                 :          0 :     AppendErrorToken( EXC_ERR_NA, rTokData.mnSpaces );
    1221                 :          0 : }
    1222                 :            : 
    1223                 :          0 : void XclExpFmlaCompImpl::ProcessParentheses( const XclExpScToken& rTokData )
    1224                 :            : {
    1225 [ #  # ][ #  # ]:          0 :     XclExpScToken aTokData = Expression( GetNextToken(), true, false );
    1226                 :          0 :     mxData->mbOk = aTokData.GetOpCode() == ocClose;
    1227         [ #  # ]:          0 :     AppendParenToken( rTokData.mnSpaces, aTokData.mnSpaces );
    1228                 :          0 : }
    1229                 :            : 
    1230                 :          0 : void XclExpFmlaCompImpl::ProcessBoolean( const XclExpScToken& rTokData )
    1231                 :            : {
    1232                 :          0 :     mxData->mbOk = GetNextToken().GetOpCode() == ocOpen;
    1233         [ #  # ]:          0 :     if( mxData->mbOk ) mxData->mbOk = GetNextToken().GetOpCode() == ocClose;
    1234         [ #  # ]:          0 :     if( mxData->mbOk )
    1235                 :          0 :         AppendBoolToken( rTokData.GetOpCode() == ocTrue, rTokData.mnSpaces );
    1236                 :          0 : }
    1237                 :            : 
    1238                 :            : namespace {
    1239                 :            : 
    1240                 :          0 : inline bool lclGetTokenString( String& rString, const XclExpScToken& rTokData )
    1241                 :            : {
    1242 [ #  # ][ #  # ]:          0 :     bool bIsStr = (rTokData.GetType() == svString) && (rTokData.GetOpCode() == ocPush);
    1243         [ #  # ]:          0 :     if( bIsStr )
    1244                 :          0 :         rString = rTokData.mpScToken->GetString();
    1245                 :          0 :     return bIsStr;
    1246                 :            : }
    1247                 :            : 
    1248                 :            : } // namespace
    1249                 :            : 
    1250                 :          0 : void XclExpFmlaCompImpl::ProcessDdeLink( const XclExpScToken& rTokData )
    1251                 :            : {
    1252 [ #  # ][ #  # ]:          0 :     String aApplic, aTopic, aItem;
                 [ #  # ]
    1253                 :            : 
    1254         [ #  # ]:          0 :     mxData->mbOk = GetNextToken().GetOpCode() == ocOpen;
    1255 [ #  # ][ #  # ]:          0 :     if( mxData->mbOk ) mxData->mbOk = lclGetTokenString( aApplic, GetNextToken() );
                 [ #  # ]
    1256 [ #  # ][ #  # ]:          0 :     if( mxData->mbOk ) mxData->mbOk = GetNextToken().GetOpCode() == ocSep;
    1257 [ #  # ][ #  # ]:          0 :     if( mxData->mbOk ) mxData->mbOk = lclGetTokenString( aTopic, GetNextToken() );
                 [ #  # ]
    1258 [ #  # ][ #  # ]:          0 :     if( mxData->mbOk ) mxData->mbOk = GetNextToken().GetOpCode() == ocSep;
    1259 [ #  # ][ #  # ]:          0 :     if( mxData->mbOk ) mxData->mbOk = lclGetTokenString( aItem, GetNextToken() );
                 [ #  # ]
    1260 [ #  # ][ #  # ]:          0 :     if( mxData->mbOk ) mxData->mbOk = GetNextToken().GetOpCode() == ocClose;
    1261 [ #  # ][ #  # ]:          0 :     if( mxData->mbOk ) mxData->mbOk = aApplic.Len() && aTopic.Len() && aItem.Len();
         [ #  # ][ #  # ]
    1262         [ #  # ]:          0 :     if( mxData->mbOk )
    1263                 :            :     {
    1264                 :            :         sal_uInt16 nExtSheet, nExtName;
    1265 [ #  # ][ #  # ]:          0 :         if( mxData->mpLinkMgr && mxData->mpLinkMgr->InsertDde( nExtSheet, nExtName, aApplic, aTopic, aItem ) )
         [ #  # ][ #  # ]
    1266         [ #  # ]:          0 :             AppendNameXToken( nExtSheet, nExtName, rTokData.mnSpaces );
    1267                 :            :         else
    1268         [ #  # ]:          0 :             AppendErrorToken( EXC_ERR_NA, rTokData.mnSpaces );
    1269 [ #  # ][ #  # ]:          0 :     }
                 [ #  # ]
    1270                 :          0 : }
    1271                 :            : 
    1272                 :          0 : void XclExpFmlaCompImpl::ProcessExternal( const XclExpScToken& rTokData )
    1273                 :            : {
    1274                 :            :     /*  #i47228# Excel import generates svExternal/ocMacro tokens for invalid
    1275                 :            :         names and for external/invalid function calls. This function looks for
    1276                 :            :         the next token in the token array. If it is an opening parenthesis, the
    1277                 :            :         token is processed as external function call, otherwise as undefined name. */
    1278                 :          0 :     const FormulaToken* pNextScToken = PeekNextRawToken( true );
    1279 [ #  # ][ #  # ]:          0 :     if( !pNextScToken || (pNextScToken->GetOpCode() != ocOpen) )
                 [ #  # ]
    1280                 :          0 :         AppendMissingNameToken( rTokData.mpScToken->GetExternal(), rTokData.mnSpaces );
    1281                 :            :     else
    1282                 :          0 :         ProcessFunction( rTokData );
    1283                 :          0 : }
    1284                 :            : 
    1285                 :          0 : void XclExpFmlaCompImpl::ProcessMatrix( const XclExpScToken& rTokData )
    1286                 :            : {
    1287                 :          0 :     const ScMatrix* pMatrix = static_cast< const ScToken* >( rTokData.mpScToken )->GetMatrix();
    1288 [ #  # ][ #  # ]:          0 :     if( pMatrix && mxData->mrCfg.mbAllowArrays )
                 [ #  # ]
    1289                 :            :     {
    1290                 :            :         SCSIZE nScCols, nScRows;
    1291         [ #  # ]:          0 :         pMatrix->GetDimensions( nScCols, nScRows );
    1292                 :            :         OSL_ENSURE( (nScCols > 0) && (nScRows > 0), "XclExpFmlaCompImpl::ProcessMatrix - invalid matrix size" );
    1293         [ #  # ]:          0 :         sal_uInt16 nCols = ::limit_cast< sal_uInt16 >( nScCols, 0, 256 );
    1294         [ #  # ]:          0 :         sal_uInt16 nRows = ::limit_cast< sal_uInt16 >( nScRows, 0, 1024 );
    1295                 :            : 
    1296                 :            :         // create the tArray token
    1297         [ #  # ]:          0 :         AppendOperandTokenId( GetTokenId( EXC_TOKID_ARRAY, EXC_TOKCLASS_ARR ), rTokData.mnSpaces );
    1298 [ #  # ][ #  # ]:          0 :         Append( static_cast< sal_uInt8 >( (meBiff == EXC_BIFF8) ? (nCols - 1) : nCols ) );
    1299 [ #  # ][ #  # ]:          0 :         Append( static_cast< sal_uInt16 >( (meBiff == EXC_BIFF8) ? (nRows - 1) : nRows ) );
    1300         [ #  # ]:          0 :         Append( static_cast< sal_uInt32 >( 0 ) );
    1301                 :            : 
    1302                 :            :         // create the extended data containing the array values
    1303 [ #  # ][ #  # ]:          0 :         AppendExt( static_cast< sal_uInt8 >( (meBiff == EXC_BIFF8) ? (nCols - 1) : nCols ) );
    1304 [ #  # ][ #  # ]:          0 :         AppendExt( static_cast< sal_uInt16 >( (meBiff == EXC_BIFF8) ? (nRows - 1) : nRows ) );
    1305         [ #  # ]:          0 :         for( SCSIZE nScRow = 0; nScRow < nScRows; ++nScRow )
    1306                 :            :         {
    1307         [ #  # ]:          0 :             for( SCSIZE nScCol = 0; nScCol < nScCols; ++nScCol )
    1308                 :            :             {
    1309         [ #  # ]:          0 :                 ScMatrixValue nMatVal = pMatrix->Get( nScCol, nScRow );
    1310         [ #  # ]:          0 :                 if( ScMatrix::IsValueType( nMatVal.nType ) )    // value, boolean, or error
    1311                 :            :                 {
    1312         [ #  # ]:          0 :                     if( ScMatrix::IsBooleanType( nMatVal.nType ) )
    1313                 :            :                     {
    1314         [ #  # ]:          0 :                         AppendExt( EXC_CACHEDVAL_BOOL );
    1315 [ #  # ][ #  # ]:          0 :                         AppendExt( static_cast< sal_uInt8 >( nMatVal.GetBoolean() ? 1 : 0 ) );
    1316         [ #  # ]:          0 :                         AppendExt( 0, 7 );
    1317                 :            :                     }
    1318         [ #  # ]:          0 :                     else if( sal_uInt16 nErr = nMatVal.GetError() )
    1319                 :            :                     {
    1320         [ #  # ]:          0 :                         AppendExt( EXC_CACHEDVAL_ERROR );
    1321 [ #  # ][ #  # ]:          0 :                         AppendExt( XclTools::GetXclErrorCode( nErr ) );
    1322         [ #  # ]:          0 :                         AppendExt( 0, 7 );
    1323                 :            :                     }
    1324                 :            :                     else
    1325                 :            :                     {
    1326         [ #  # ]:          0 :                         AppendExt( EXC_CACHEDVAL_DOUBLE );
    1327         [ #  # ]:          0 :                         AppendExt( nMatVal.fVal );
    1328                 :            :                     }
    1329                 :            :                 }
    1330                 :            :                 else    // string or empty
    1331                 :            :                 {
    1332         [ #  # ]:          0 :                     const String& rStr = nMatVal.GetString();
    1333         [ #  # ]:          0 :                     if( rStr.Len() == 0 )
    1334                 :            :                     {
    1335         [ #  # ]:          0 :                         AppendExt( EXC_CACHEDVAL_EMPTY );
    1336         [ #  # ]:          0 :                         AppendExt( 0, 8 );
    1337                 :            :                     }
    1338                 :            :                     else
    1339                 :            :                     {
    1340         [ #  # ]:          0 :                         AppendExt( EXC_CACHEDVAL_STRING );
    1341         [ #  # ]:          0 :                         AppendExt( rStr );
    1342         [ #  # ]:          0 :                     }
    1343                 :            :                 }
    1344                 :          0 :             }
    1345                 :            :         }
    1346                 :            :     }
    1347                 :            :     else
    1348                 :            :     {
    1349                 :            :         // array in places that do not allow it (cond fmts, data validation)
    1350                 :          0 :         AppendErrorToken( EXC_ERR_NA, rTokData.mnSpaces );
    1351                 :            :     }
    1352                 :          0 : }
    1353                 :            : 
    1354                 :          0 : void XclExpFmlaCompImpl::ProcessFunction( const XclExpScToken& rTokData )
    1355                 :            : {
    1356                 :          0 :     OpCode eOpCode = rTokData.GetOpCode();
    1357         [ #  # ]:          0 :     const XclFunctionInfo* pFuncInfo = maFuncProv.GetFuncInfoFromOpCode( eOpCode );
    1358                 :            : 
    1359         [ #  # ]:          0 :     XclExpExtFuncData aExtFuncData;
    1360                 :            : 
    1361                 :            :     // no exportable function found - try to create an external macro call
    1362 [ #  # ][ #  # ]:          0 :     if( !pFuncInfo && (eOpCode >= SC_OPCODE_START_NO_PAR) )
    1363                 :            :     {
    1364         [ #  # ]:          0 :         const String& rFuncName = ScCompiler::GetNativeSymbol( eOpCode );
    1365         [ #  # ]:          0 :         if( rFuncName.Len() )
    1366                 :            :         {
    1367         [ #  # ]:          0 :             aExtFuncData.Set( rFuncName, true, false );
    1368         [ #  # ]:          0 :             pFuncInfo = maFuncProv.GetFuncInfoFromOpCode( ocMacro );
    1369                 :            :         }
    1370                 :            :     }
    1371                 :            : 
    1372                 :          0 :     mxData->mbOk = pFuncInfo != 0;
    1373         [ #  # ]:          0 :     if( !mxData->mbOk ) return;
    1374                 :            : 
    1375                 :            :     // functions simulated by a macro call in file format
    1376         [ #  # ]:          0 :     if( pFuncInfo->IsMacroFunc() )
    1377 [ #  # ][ #  # ]:          0 :         aExtFuncData.Set( pFuncInfo->GetMacroFuncName(), false, true );
                 [ #  # ]
    1378                 :            : 
    1379         [ #  # ]:          0 :     XclExpFuncData aFuncData( rTokData, *pFuncInfo, aExtFuncData );
    1380                 :          0 :     XclExpScToken aTokData;
    1381                 :            : 
    1382                 :            :     // preparations for special functions, before function processing starts
    1383         [ #  # ]:          0 :     PrepareFunction( aFuncData );
    1384                 :            : 
    1385                 :            :     enum { STATE_START, STATE_OPEN, STATE_PARAM, STATE_SEP, STATE_CLOSE, STATE_END }
    1386                 :          0 :         eState = STATE_START;
    1387   [ #  #  #  #  :          0 :     while( eState != STATE_END ) switch( eState )
           #  # ][ #  # ]
    1388                 :            :     {
    1389                 :            :         case STATE_START:
    1390 [ #  # ][ #  # ]:          0 :             mxData->mbOk = GetNextToken( aTokData ) && (aTokData.GetOpCode() == ocOpen);
                 [ #  # ]
    1391         [ #  # ]:          0 :             eState = mxData->mbOk ? STATE_OPEN : STATE_END;
    1392                 :          0 :         break;
    1393                 :            :         case STATE_OPEN:
    1394         [ #  # ]:          0 :             mxData->mbOk = GetNextToken( aTokData );
    1395 [ #  # ][ #  # ]:          0 :             eState = mxData->mbOk ? ((aTokData.GetOpCode() == ocClose) ? STATE_CLOSE : STATE_PARAM) : STATE_END;
    1396                 :          0 :         break;
    1397                 :            :         case STATE_PARAM:
    1398         [ #  # ]:          0 :             aTokData = ProcessParam( aTokData, aFuncData );
    1399      [ #  #  # ]:          0 :             switch( aTokData.GetOpCode() )
    1400                 :            :             {
    1401                 :          0 :                 case ocSep:     eState = STATE_SEP;                 break;
    1402                 :          0 :                 case ocClose:   eState = STATE_CLOSE;               break;
    1403                 :          0 :                 default:        mxData->mbOk = false;
    1404                 :            :             }
    1405         [ #  # ]:          0 :             if( !mxData->mbOk ) eState = STATE_END;
    1406                 :          0 :         break;
    1407                 :            :         case STATE_SEP:
    1408 [ #  # ][ #  # ]:          0 :             mxData->mbOk = (aFuncData.GetParamCount() < EXC_FUNC_MAXPARAM) && GetNextToken( aTokData );
         [ #  # ][ #  # ]
    1409         [ #  # ]:          0 :             eState = mxData->mbOk ? STATE_PARAM : STATE_END;
    1410                 :          0 :         break;
    1411                 :            :         case STATE_CLOSE:
    1412         [ #  # ]:          0 :             FinishFunction( aFuncData, aTokData.mnSpaces );
    1413                 :          0 :             eState = STATE_END;
    1414                 :          0 :         break;
    1415                 :            :         default:;
    1416 [ #  # ][ #  # ]:          0 :     }
                 [ #  # ]
    1417                 :            : }
    1418                 :            : 
    1419                 :          0 : void XclExpFmlaCompImpl::PrepareFunction( XclExpFuncData& rFuncData )
    1420                 :            : {
    1421      [ #  #  # ]:          0 :     switch( rFuncData.GetOpCode() )
    1422                 :            :     {
    1423                 :            :         case ocCosecant:                // simulate CSC(x) by (1/SIN(x))
    1424                 :            :         case ocSecant:                  // simulate SEC(x) by (1/COS(x))
    1425                 :            :         case ocCot:                     // simulate COT(x) by (1/TAN(x))
    1426                 :            :         case ocCosecantHyp:             // simulate CSCH(x) by (1/SINH(x))
    1427                 :            :         case ocSecantHyp:               // simulate SECH(x) by (1/COSH(x))
    1428                 :            :         case ocCotHyp:                  // simulate COTH(x) by (1/TANH(x))
    1429                 :          0 :             AppendIntToken( 1 );
    1430                 :          0 :         break;
    1431                 :            :         case ocArcCot:                  // simulate ACOT(x) by (PI/2-ATAN(x))
    1432                 :          0 :             AppendNumToken( F_PI2 );
    1433                 :          0 :         break;
    1434                 :            :         default:;
    1435                 :            :     }
    1436                 :          0 : }
    1437                 :            : 
    1438                 :          0 : void XclExpFmlaCompImpl::FinishFunction( XclExpFuncData& rFuncData, sal_uInt8 nCloseSpaces )
    1439                 :            : {
    1440                 :            :     // append missing parameters required in Excel, may modify param count
    1441                 :          0 :     AppendTrailingParam( rFuncData );
    1442                 :            : 
    1443                 :            :     // check if parameter count fits into the limits of the function
    1444                 :          0 :     sal_uInt8 nParamCount = rFuncData.GetParamCount();
    1445 [ #  # ][ #  # ]:          0 :     if( (rFuncData.GetMinParamCount() <= nParamCount) && (nParamCount <= rFuncData.GetMaxParamCount()) )
                 [ #  # ]
    1446                 :            :     {
    1447                 :            :         // first put the tAttrSpace tokens, they must not be included in tAttrGoto handling
    1448                 :          0 :         AppendSpaceToken( EXC_TOK_ATTR_SPACE_SP_CLOSE, nCloseSpaces );
    1449                 :          0 :         AppendSpaceToken( EXC_TOK_ATTR_SPACE_SP, rFuncData.GetSpaces() );
    1450                 :            : 
    1451                 :            :         // add tAttrGoto tokens for IF or CHOOSE functions
    1452         [ #  # ]:          0 :         switch( rFuncData.GetOpCode() )
    1453                 :            :         {
    1454                 :            :             case ocIf:
    1455                 :            :             case ocChose:
    1456                 :          0 :                 AppendJumpToken( rFuncData, EXC_TOK_ATTR_GOTO );
    1457                 :          0 :             break;
    1458                 :            :             default:;
    1459                 :            :         }
    1460                 :            : 
    1461                 :            :         // put the tFunc or tFuncVar token (or another special token, e.g. tAttrSum)
    1462                 :          0 :         AppendFuncToken( rFuncData );
    1463                 :            : 
    1464                 :            :         // update volatile flag - is set if at least one used function is volatile
    1465                 :          0 :         mxData->mbVolatile |= rFuncData.IsVolatile();
    1466                 :            : 
    1467                 :            :         // update jump tokens for specific functions, add additional tokens
    1468   [ #  #  #  #  :          0 :         switch( rFuncData.GetOpCode() )
                      # ]
    1469                 :            :         {
    1470                 :            :             case ocIf:
    1471                 :          0 :                 FinishIfFunction( rFuncData );
    1472                 :          0 :             break;
    1473                 :            :             case ocChose:
    1474                 :          0 :                 FinishChooseFunction( rFuncData );
    1475                 :          0 :             break;
    1476                 :            : 
    1477                 :            :             case ocCosecant:                // simulate CSC(x) by (1/SIN(x))
    1478                 :            :             case ocSecant:                  // simulate SEC(x) by (1/COS(x))
    1479                 :            :             case ocCot:                     // simulate COT(x) by (1/TAN(x))
    1480                 :            :             case ocCosecantHyp:             // simulate CSCH(x) by (1/SINH(x))
    1481                 :            :             case ocSecantHyp:               // simulate SECH(x) by (1/COSH(x))
    1482                 :            :             case ocCotHyp:                  // simulate COTH(x) by (1/TANH(x))
    1483                 :          0 :                 AppendBinaryOperatorToken( EXC_TOKID_DIV, true );
    1484                 :          0 :                 AppendParenToken();
    1485                 :          0 :             break;
    1486                 :            :             case ocArcCot:                  // simulate ACOT(x) by (PI/2-ATAN(x))
    1487                 :          0 :                 AppendBinaryOperatorToken( EXC_TOKID_SUB, true );
    1488                 :          0 :                 AppendParenToken();
    1489                 :          0 :             break;
    1490                 :            : 
    1491                 :            :             default:;
    1492                 :            :         }
    1493                 :            :     }
    1494                 :            :     else
    1495                 :          0 :         mxData->mbOk = false;
    1496                 :          0 : }
    1497                 :            : 
    1498                 :          0 : void XclExpFmlaCompImpl::FinishIfFunction( XclExpFuncData& rFuncData )
    1499                 :            : {
    1500                 :          0 :     sal_uInt16 nParamCount = rFuncData.GetParamCount();
    1501                 :            :     OSL_ENSURE( (nParamCount == 2) || (nParamCount == 3), "XclExpFmlaCompImpl::FinishIfFunction - wrong parameter count" );
    1502                 :          0 :     const ScfUInt16Vec& rAttrPos = rFuncData.GetAttrPosVec();
    1503                 :            :     OSL_ENSURE( nParamCount == rAttrPos.size(), "XclExpFmlaCompImpl::FinishIfFunction - wrong number of tAttr tokens" );
    1504                 :            :     // update tAttrIf token following the condition parameter
    1505                 :          0 :     Overwrite( rAttrPos[ 0 ] + 2, static_cast< sal_uInt16 >( rAttrPos[ 1 ] - rAttrPos[ 0 ] ) );
    1506                 :            :     // update the tAttrGoto tokens following true and false parameters
    1507                 :          0 :     UpdateAttrGoto( rAttrPos[ 1 ] );
    1508         [ #  # ]:          0 :     if( nParamCount == 3 )
    1509                 :          0 :         UpdateAttrGoto( rAttrPos[ 2 ] );
    1510                 :          0 : }
    1511                 :            : 
    1512                 :          0 : void XclExpFmlaCompImpl::FinishChooseFunction( XclExpFuncData& rFuncData )
    1513                 :            : {
    1514                 :          0 :     sal_uInt16 nParamCount = rFuncData.GetParamCount();
    1515                 :          0 :     ScfUInt16Vec& rAttrPos = rFuncData.GetAttrPosVec();
    1516                 :            :     OSL_ENSURE( nParamCount == rAttrPos.size(), "XclExpFmlaCompImpl::FinishChooseFunction - wrong number of tAttr tokens" );
    1517                 :            :     // number of choices is parameter count minus 1
    1518                 :          0 :     sal_uInt16 nChoices = nParamCount - 1;
    1519                 :            :     // tAttrChoose token contains number of choices
    1520                 :          0 :     Overwrite( rAttrPos[ 0 ] + 2, nChoices );
    1521                 :            :     // cache position of the jump table (follows number of choices in tAttrChoose token)
    1522                 :          0 :     sal_uInt16 nJumpArrPos = rAttrPos[ 0 ] + 4;
    1523                 :            :     // size of jump table: number of choices, plus 1 for error position
    1524                 :          0 :     sal_uInt16 nJumpArrSize = 2 * (nChoices + 1);
    1525                 :            :     // insert the jump table into the tAttrChoose token
    1526                 :          0 :     InsertZeros( nJumpArrPos, nJumpArrSize );
    1527                 :            :     // update positions of tAttrGoto tokens after jump table insertion
    1528                 :            :     sal_uInt16 nIdx;
    1529         [ #  # ]:          0 :     for( nIdx = 1; nIdx < nParamCount; ++nIdx )
    1530                 :          0 :         rAttrPos[ nIdx ] = rAttrPos[ nIdx ] + nJumpArrSize;
    1531                 :            :     // update the tAttrGoto tokens (they contain a value one-less to real distance)
    1532         [ #  # ]:          0 :     for( nIdx = 1; nIdx < nParamCount; ++nIdx )
    1533                 :          0 :         UpdateAttrGoto( rAttrPos[ nIdx ] );
    1534                 :            :     // update the distances in the jump table
    1535                 :          0 :     Overwrite( nJumpArrPos, nJumpArrSize );
    1536         [ #  # ]:          0 :     for( nIdx = 1; nIdx < nParamCount; ++nIdx )
    1537                 :          0 :         Overwrite( nJumpArrPos + 2 * nIdx, static_cast< sal_uInt16 >( rAttrPos[ nIdx ] + 4 - nJumpArrPos ) );
    1538                 :          0 : }
    1539                 :            : 
    1540                 :          0 : XclExpScToken XclExpFmlaCompImpl::ProcessParam( XclExpScToken aTokData, XclExpFuncData& rFuncData )
    1541                 :            : {
    1542         [ #  # ]:          0 :     if( rFuncData.IsCalcOnlyParam() )
    1543                 :            :     {
    1544                 :            :         // skip Calc-only parameter, stop at next ocClose or ocSep
    1545                 :          0 :         aTokData = SkipExpression( aTokData, true );
    1546                 :          0 :         rFuncData.IncParamInfoIdx();
    1547                 :            :     }
    1548                 :            :     else
    1549                 :            :     {
    1550                 :            :         // insert Excel-only parameters, modifies param count and class in rFuncData
    1551         [ #  # ]:          0 :         while( rFuncData.IsExcelOnlyParam() )
    1552                 :          0 :             AppendDefaultParam( rFuncData );
    1553                 :            : 
    1554                 :            :         // process the parameter, stop at next ocClose or ocSep
    1555                 :          0 :         PrepareParam( rFuncData );
    1556                 :            :         /*  #i37355# insert tMissArg token for missing parameters --
    1557                 :            :             Excel import filter adds ocMissing token (handled in Factor()),
    1558                 :            :             but Calc itself does not do this if a new formula is entered. */
    1559         [ #  # ]:          0 :         switch( aTokData.GetOpCode() )
    1560                 :            :         {
    1561                 :            :             case ocSep:
    1562                 :          0 :             case ocClose:   AppendMissingToken();   break;  // empty parameter
    1563                 :          0 :             default:        aTokData = Expression( aTokData, false, true );
    1564                 :            :         }
    1565                 :            :         // finalize the parameter and add special tokens, e.g. for IF or CHOOSE parameters
    1566         [ #  # ]:          0 :         if( mxData->mbOk ) FinishParam( rFuncData );
    1567                 :            :     }
    1568                 :          0 :     return aTokData;
    1569                 :            : }
    1570                 :            : 
    1571                 :          0 : void XclExpFmlaCompImpl::PrepareParam( XclExpFuncData& rFuncData )
    1572                 :            : {
    1573                 :            :     // index of this parameter is equal to number of already finished parameters
    1574                 :          0 :     sal_uInt8 nParamIdx = rFuncData.GetParamCount();
    1575                 :            : 
    1576   [ #  #  #  # ]:          0 :     switch( rFuncData.GetOpCode() )
    1577                 :            :     {
    1578                 :            :         case ocIf:
    1579      [ #  #  # ]:          0 :             switch( nParamIdx )
    1580                 :            :             {
    1581                 :            :                 // add a tAttrIf token before true-parameter (second parameter)
    1582                 :          0 :                 case 1:     AppendJumpToken( rFuncData, EXC_TOK_ATTR_IF );      break;
    1583                 :            :                 // add a tAttrGoto token before false-parameter (third parameter)
    1584                 :          0 :                 case 2:     AppendJumpToken( rFuncData, EXC_TOK_ATTR_GOTO );    break;
    1585                 :            :             }
    1586                 :          0 :         break;
    1587                 :            : 
    1588                 :            :         case ocChose:
    1589      [ #  #  # ]:          0 :             switch( nParamIdx )
    1590                 :            :             {
    1591                 :            :                 // do nothing for first parameter
    1592                 :          0 :                 case 0:                                                         break;
    1593                 :            :                 // add a tAttrChoose token before first value parameter (second parameter)
    1594                 :          0 :                 case 1:     AppendJumpToken( rFuncData, EXC_TOK_ATTR_CHOOSE );  break;
    1595                 :            :                 // add a tAttrGoto token before other value parameters
    1596                 :          0 :                 default:    AppendJumpToken( rFuncData, EXC_TOK_ATTR_GOTO );
    1597                 :            :             }
    1598                 :          0 :         break;
    1599                 :            : 
    1600                 :            :         case ocArcCotHyp:               // simulate ACOTH(x) by ATANH(1/(x))
    1601         [ #  # ]:          0 :             if( nParamIdx == 0 )
    1602                 :          0 :                 AppendIntToken( 1 );
    1603                 :          0 :         break;
    1604                 :            :         default:;
    1605                 :            :     }
    1606                 :          0 : }
    1607                 :            : 
    1608                 :          0 : void XclExpFmlaCompImpl::FinishParam( XclExpFuncData& rFuncData )
    1609                 :            : {
    1610                 :            :     // increase parameter count, update operand stack
    1611                 :          0 :     rFuncData.FinishParam( PopOperandPos() );
    1612                 :            : 
    1613                 :            :     // append more tokens for parameters of some special functions
    1614                 :          0 :     sal_uInt8 nParamIdx = rFuncData.GetParamCount() - 1;
    1615         [ #  # ]:          0 :     switch( rFuncData.GetOpCode() )
    1616                 :            :     {
    1617                 :            :         case ocArcCotHyp:               // simulate ACOTH(x) by ATANH(1/(x))
    1618         [ #  # ]:          0 :             if( nParamIdx == 0 )
    1619                 :            :             {
    1620                 :          0 :                 AppendParenToken();
    1621                 :          0 :                 AppendBinaryOperatorToken( EXC_TOKID_DIV, true );
    1622                 :            :             }
    1623                 :          0 :         break;
    1624                 :            :         default:;
    1625                 :            :     }
    1626                 :          0 : }
    1627                 :            : 
    1628                 :          0 : void XclExpFmlaCompImpl::AppendDefaultParam( XclExpFuncData& rFuncData )
    1629                 :            : {
    1630                 :            :     // prepare parameters of some special functions
    1631                 :          0 :     PrepareParam( rFuncData );
    1632                 :            : 
    1633   [ #  #  #  # ]:          0 :     switch( rFuncData.GetOpCode() )
    1634                 :            :     {
    1635                 :            :         case ocExternal:
    1636                 :          0 :             AppendAddInCallToken( rFuncData.GetExtFuncData() );
    1637                 :          0 :         break;
    1638                 :            :         case ocEuroConvert:
    1639                 :          0 :             AppendEuroToolCallToken( rFuncData.GetExtFuncData() );
    1640                 :          0 :         break;
    1641                 :            :         case ocMacro:
    1642                 :          0 :             AppendMacroCallToken( rFuncData.GetExtFuncData() );
    1643                 :          0 :         break;
    1644                 :            :         default:
    1645                 :            :         {
    1646                 :            :             OSL_ENSURE( rFuncData.IsMacroFunc(), "XclExpFmlaCompImpl::AppendDefaultParam - unknown opcode" );
    1647         [ #  # ]:          0 :             if( rFuncData.IsMacroFunc() )
    1648                 :          0 :                 AppendMacroCallToken( rFuncData.GetExtFuncData() );
    1649                 :            :             else
    1650                 :          0 :                 AppendMissingToken();   // to keep parameter count valid
    1651                 :            :         }
    1652                 :            :     }
    1653                 :            : 
    1654                 :            :     // update parameter count, add special parameter tokens
    1655                 :          0 :     FinishParam( rFuncData );
    1656                 :          0 : }
    1657                 :            : 
    1658                 :          0 : void XclExpFmlaCompImpl::AppendTrailingParam( XclExpFuncData& rFuncData )
    1659                 :            : {
    1660                 :          0 :     sal_uInt8 nParamCount = rFuncData.GetParamCount();
    1661   [ #  #  #  #  :          0 :     switch( rFuncData.GetOpCode() )
             #  #  #  #  
                      # ]
    1662                 :            :     {
    1663                 :            :         case ocIf:
    1664         [ #  # ]:          0 :             if( nParamCount == 1 )
    1665                 :            :             {
    1666                 :            :                 // Excel needs at least two parameters in IF function
    1667                 :          0 :                 PrepareParam( rFuncData );
    1668                 :          0 :                 AppendBoolToken( true );
    1669                 :          0 :                 FinishParam( rFuncData );
    1670                 :            :             }
    1671                 :          0 :         break;
    1672                 :            : 
    1673                 :            :         case ocRound:
    1674                 :            :         case ocRoundUp:
    1675                 :            :         case ocRoundDown:
    1676         [ #  # ]:          0 :             if( nParamCount == 1 )
    1677                 :            :             {
    1678                 :            :                 // ROUND, ROUNDUP, ROUNDDOWN functions are fixed to 2 parameters in Excel
    1679                 :          0 :                 PrepareParam( rFuncData );
    1680                 :          0 :                 AppendIntToken( 0 );
    1681                 :          0 :                 FinishParam( rFuncData );
    1682                 :            :             }
    1683                 :          0 :         break;
    1684                 :            : 
    1685                 :            :         case ocIndex:
    1686         [ #  # ]:          0 :             if( nParamCount == 1 )
    1687                 :            :             {
    1688                 :            :                 // INDEX function needs at least 2 parameters in Excel
    1689                 :          0 :                 PrepareParam( rFuncData );
    1690                 :          0 :                 AppendMissingToken();
    1691                 :          0 :                 FinishParam( rFuncData );
    1692                 :            :             }
    1693                 :          0 :         break;
    1694                 :            : 
    1695                 :            :         case ocExternal:
    1696                 :            :         case ocMacro:
    1697                 :            :             // external or macro call without parameters needs the external name reference
    1698         [ #  # ]:          0 :             if( nParamCount == 0 )
    1699                 :          0 :                 AppendDefaultParam( rFuncData );
    1700                 :          0 :         break;
    1701                 :            : 
    1702                 :            :         case ocGammaDist:
    1703         [ #  # ]:          0 :             if( nParamCount == 3 )
    1704                 :            :             {
    1705                 :            :                 // GAMMADIST function needs 4 parameters in Excel
    1706                 :          0 :                 PrepareParam( rFuncData );
    1707                 :          0 :                 AppendIntToken( 1 );
    1708                 :          0 :                 FinishParam( rFuncData );
    1709                 :            :             }
    1710                 :          0 :         break;
    1711                 :            : 
    1712                 :            :         case ocPoissonDist:
    1713         [ #  # ]:          0 :             if( nParamCount == 2 )
    1714                 :            :             {
    1715                 :            :                 // POISSON function needs 3 parameters in Excel
    1716                 :          0 :                 PrepareParam( rFuncData );
    1717                 :          0 :                 AppendIntToken( 1 );
    1718                 :          0 :                 FinishParam( rFuncData );
    1719                 :            :             }
    1720                 :          0 :         break;
    1721                 :            : 
    1722                 :            :         case ocNormDist:
    1723         [ #  # ]:          0 :             if( nParamCount == 3 )
    1724                 :            :             {
    1725                 :            :                 // NORMDIST function needs 4 parameters in Excel
    1726                 :          0 :                 PrepareParam( rFuncData );
    1727                 :          0 :                 AppendBoolToken( true );
    1728                 :          0 :                 FinishParam( rFuncData );
    1729                 :            :             }
    1730                 :          0 :         break;
    1731                 :            : 
    1732                 :            :         case ocLogNormDist:
    1733      [ #  #  # ]:          0 :             switch( nParamCount )
    1734                 :            :              {
    1735                 :            :                 // LOGNORMDIST function needs 3 parameters in Excel
    1736                 :            :                 case 1:
    1737                 :          0 :                     PrepareParam( rFuncData );
    1738                 :          0 :                     AppendIntToken( 0 );
    1739                 :          0 :                     FinishParam( rFuncData );
    1740                 :            :                  // do not break, add next default parameter
    1741                 :            :                 case 2:
    1742                 :          0 :                     PrepareParam( rFuncData );
    1743                 :          0 :                     AppendIntToken( 1 );
    1744                 :          0 :                     FinishParam( rFuncData );
    1745                 :          0 :                     break;
    1746                 :            :                 default:;
    1747                 :            :              }
    1748                 :            : 
    1749                 :          0 :         break;
    1750                 :            : 
    1751                 :            :         default:
    1752                 :            :             // #i108420# function without parameters stored as macro call needs the external name reference
    1753 [ #  # ][ #  # ]:          0 :             if( (nParamCount == 0) && rFuncData.IsMacroFunc() )
                 [ #  # ]
    1754                 :          0 :                 AppendDefaultParam( rFuncData );
    1755                 :            : 
    1756                 :            :     }
    1757                 :          0 : }
    1758                 :            : 
    1759                 :            : // reference handling ---------------------------------------------------------
    1760                 :            : 
    1761                 :            : namespace {
    1762                 :            : 
    1763                 :          0 : inline bool lclIsRefRel2D( const ScSingleRefData& rRefData )
    1764                 :            : {
    1765 [ #  # ][ #  # ]:          0 :     return rRefData.IsColRel() || rRefData.IsRowRel();
    1766                 :            : }
    1767                 :            : 
    1768                 :          0 : inline bool lclIsRefDel2D( const ScSingleRefData& rRefData )
    1769                 :            : {
    1770 [ #  # ][ #  # ]:          0 :     return rRefData.IsColDeleted() || rRefData.IsRowDeleted();
    1771                 :            : }
    1772                 :            : 
    1773                 :          0 : inline bool lclIsRefRel2D( const ScComplexRefData& rRefData )
    1774                 :            : {
    1775 [ #  # ][ #  # ]:          0 :     return lclIsRefRel2D( rRefData.Ref1 ) || lclIsRefRel2D( rRefData.Ref2 );
    1776                 :            : }
    1777                 :            : 
    1778                 :          0 : inline bool lclIsRefDel2D( const ScComplexRefData& rRefData )
    1779                 :            : {
    1780 [ #  # ][ #  # ]:          0 :     return lclIsRefDel2D( rRefData.Ref1 ) || lclIsRefDel2D( rRefData.Ref2 );
    1781                 :            : }
    1782                 :            : 
    1783                 :            : } // namespace
    1784                 :            : 
    1785                 :          0 : SCTAB XclExpFmlaCompImpl::GetScTab( const ScSingleRefData& rRefData ) const
    1786                 :            : {
    1787 [ #  # ][ #  # ]:          0 :     bool bInvTab = rRefData.IsTabDeleted() || (!mxData->mpScBasePos && IsInGlobals() && rRefData.IsTabRel());
         [ #  # ][ #  # ]
    1788         [ #  # ]:          0 :     return bInvTab ? SCTAB_INVALID : static_cast< SCTAB >( rRefData.nTab );
    1789                 :            : }
    1790                 :            : 
    1791                 :          0 : bool XclExpFmlaCompImpl::IsRef2D( const ScSingleRefData& rRefData ) const
    1792                 :            : {
    1793                 :            :     /*  rRefData.IsFlag3D() determines if sheet name is always visible, even on
    1794                 :            :         the own sheet. If 3D references are allowed, the passed reference does
    1795                 :            :         not count as 2D reference. */
    1796                 :          0 :     return (!mxData->mpLinkMgr || !rRefData.IsFlag3D()) && !rRefData.IsTabDeleted() &&
    1797 [ #  # ][ #  # ]:          0 :         (rRefData.IsTabRel() ? (rRefData.nRelTab == 0) : (static_cast< SCTAB >( rRefData.nTab ) == GetCurrScTab()));
         [ #  # ][ #  #  
             #  #  #  # ]
    1798                 :            : }
    1799                 :            : 
    1800                 :          0 : bool XclExpFmlaCompImpl::IsRef2D( const ScComplexRefData& rRefData ) const
    1801                 :            : {
    1802 [ #  # ][ #  # ]:          0 :     return IsRef2D( rRefData.Ref1 ) && IsRef2D( rRefData.Ref2 );
    1803                 :            : }
    1804                 :            : 
    1805                 :          0 : void XclExpFmlaCompImpl::ConvertRefData(
    1806                 :            :     ScSingleRefData& rRefData, XclAddress& rXclPos,
    1807                 :            :     bool bNatLangRef, bool bTruncMaxCol, bool bTruncMaxRow ) const
    1808                 :            : {
    1809         [ #  # ]:          0 :     if( mxData->mpScBasePos )
    1810                 :            :     {
    1811                 :            :         // *** reference position exists (cell, matrix) - convert to absolute ***
    1812                 :          0 :         rRefData.CalcAbsIfRel( *mxData->mpScBasePos );
    1813                 :            : 
    1814                 :            :         // convert column index
    1815                 :          0 :         SCsCOL& rnScCol = rRefData.nCol;
    1816 [ #  # ][ #  # ]:          0 :         if( bTruncMaxCol && (rnScCol == mnMaxScCol) )
    1817                 :          0 :             rnScCol = mnMaxAbsCol;
    1818 [ #  # ][ #  # ]:          0 :         else if( (rnScCol < 0) || (rnScCol > mnMaxAbsCol) )
    1819                 :          0 :             rRefData.SetColDeleted( sal_True );
    1820                 :          0 :         rXclPos.mnCol = static_cast< sal_uInt16 >( rnScCol ) & mnMaxColMask;
    1821                 :            : 
    1822                 :            :         // convert row index
    1823                 :          0 :         SCsROW& rnScRow = rRefData.nRow;
    1824 [ #  # ][ #  # ]:          0 :         if( bTruncMaxRow && (rnScRow == mnMaxScRow) )
    1825                 :          0 :             rnScRow = mnMaxAbsRow;
    1826 [ #  # ][ #  # ]:          0 :         else if( (rnScRow < 0) || (rnScRow > mnMaxAbsRow) )
    1827                 :          0 :             rRefData.SetRowDeleted( sal_True );
    1828                 :          0 :         rXclPos.mnRow = static_cast< sal_uInt32 >( rnScRow ) & mnMaxRowMask;
    1829                 :            :     }
    1830                 :            :     else
    1831                 :            :     {
    1832                 :            :         // *** no reference position (shared, names, condfmt) - use relative values ***
    1833                 :            : 
    1834                 :            :         // convert column index (2-step-cast ScsCOL->sal_Int16->sal_uInt16 to get all bits correctly)
    1835         [ #  # ]:          0 :         sal_Int16 nXclRelCol = static_cast< sal_Int16 >( rRefData.IsColRel() ? rRefData.nRelCol : rRefData.nCol );
    1836                 :          0 :         rXclPos.mnCol = static_cast< sal_uInt16 >( nXclRelCol ) & mnMaxColMask;
    1837                 :            : 
    1838                 :            :         // convert row index (2-step-cast ScsROW->sal_Int16->sal_uInt16 to get all bits correctly)
    1839         [ #  # ]:          0 :         sal_Int16 nXclRelRow = static_cast< sal_Int32 >( rRefData.IsRowRel() ? rRefData.nRelRow : rRefData.nRow );
    1840                 :          0 :         rXclPos.mnRow = static_cast< sal_uInt32 >( nXclRelRow ) & mnMaxRowMask;
    1841                 :            : 
    1842                 :            :         // resolve relative tab index if possible
    1843 [ #  # ][ #  # ]:          0 :         if( rRefData.IsTabRel() && !IsInGlobals() && (GetCurrScTab() < GetDoc().GetTableCount()) )
         [ #  # ][ #  # ]
    1844                 :          0 :             rRefData.nTab = static_cast< SCsTAB >( GetCurrScTab() + rRefData.nRelTab );
    1845                 :            :     }
    1846                 :            : 
    1847                 :            :     // flags for relative column and row
    1848         [ #  # ]:          0 :     if( bNatLangRef )
    1849                 :            :     {
    1850                 :            :         OSL_ENSURE( meBiff == EXC_BIFF8, "XclExpFmlaCompImpl::ConvertRefData - NLRs only for BIFF8" );
    1851                 :            :         // Calc does not support absolute reference mode in natural language references
    1852                 :          0 :         ::set_flag( rXclPos.mnCol, EXC_TOK_NLR_REL );
    1853                 :            :     }
    1854                 :            :     else
    1855                 :            :     {
    1856                 :          0 :         sal_uInt16 rnRelRow = rXclPos.mnRow;
    1857         [ #  # ]:          0 :         sal_uInt16& rnRelField = (meBiff <= EXC_BIFF5) ? rnRelRow : rXclPos.mnCol;
    1858                 :          0 :         ::set_flag( rnRelField, EXC_TOK_REF_COLREL, rRefData.IsColRel() );
    1859                 :          0 :         ::set_flag( rnRelField, EXC_TOK_REF_ROWREL, rRefData.IsRowRel() );
    1860                 :            :     }
    1861                 :          0 : }
    1862                 :            : 
    1863                 :          0 : void XclExpFmlaCompImpl::ConvertRefData(
    1864                 :            :         ScComplexRefData& rRefData, XclRange& rXclRange, bool bNatLangRef ) const
    1865                 :            : {
    1866                 :            :     // convert start and end of the range
    1867                 :          0 :     ConvertRefData( rRefData.Ref1, rXclRange.maFirst, bNatLangRef, false, false );
    1868 [ #  # ][ #  # ]:          0 :     bool bTruncMaxCol = !rRefData.Ref1.IsColDeleted() && (rRefData.Ref1.nCol == 0);
    1869 [ #  # ][ #  # ]:          0 :     bool bTruncMaxRow = !rRefData.Ref1.IsRowDeleted() && (rRefData.Ref1.nRow == 0);
    1870                 :          0 :     ConvertRefData( rRefData.Ref2, rXclRange.maLast, bNatLangRef, bTruncMaxCol, bTruncMaxRow );
    1871                 :          0 : }
    1872                 :            : 
    1873                 :          0 : XclExpRefLogEntry* XclExpFmlaCompImpl::GetNewRefLogEntry()
    1874                 :            : {
    1875         [ #  # ]:          0 :     if( mxData->mpRefLog )
    1876                 :            :     {
    1877                 :          0 :         mxData->mpRefLog->resize( mxData->mpRefLog->size() + 1 );
    1878                 :          0 :         return &mxData->mpRefLog->back();
    1879                 :            :     }
    1880                 :          0 :     return 0;
    1881                 :            : }
    1882                 :            : 
    1883                 :          0 : void XclExpFmlaCompImpl::ProcessCellRef( const XclExpScToken& rTokData )
    1884                 :            : {
    1885                 :            :     // get the Excel address components, adjust internal data in aRefData
    1886 [ #  # ][ #  # ]:          0 :     bool bNatLangRef = (meBiff == EXC_BIFF8) && mxData->mpScBasePos && (rTokData.GetOpCode() == ocColRowName);
                 [ #  # ]
    1887         [ #  # ]:          0 :     ScSingleRefData aRefData = static_cast< const ScToken* >( rTokData.mpScToken )->GetSingleRef();
    1888                 :          0 :     XclAddress aXclPos( ScAddress::UNINITIALIZED );
    1889         [ #  # ]:          0 :     ConvertRefData( aRefData, aXclPos, bNatLangRef, false, false );
    1890                 :            : 
    1891         [ #  # ]:          0 :     if( bNatLangRef )
    1892                 :            :     {
    1893                 :            :         OSL_ENSURE( aRefData.IsColRel() != aRefData.IsRowRel(),
    1894                 :            :             "XclExpFmlaCompImpl::ProcessCellRef - broken natural language reference" );
    1895                 :            :         // create tNlr token for natural language reference
    1896         [ #  # ]:          0 :         sal_uInt8 nSubId = aRefData.IsColRel() ? EXC_TOK_NLR_COLV : EXC_TOK_NLR_ROWV;
    1897         [ #  # ]:          0 :         AppendOperandTokenId( EXC_TOKID_NLR, rTokData.mnSpaces );
    1898         [ #  # ]:          0 :         Append( nSubId );
    1899         [ #  # ]:          0 :         AppendAddress( aXclPos );
    1900                 :            :     }
    1901                 :            :     else
    1902                 :            :     {
    1903                 :            :         // store external cell contents in CRN records
    1904 [ #  # ][ #  # ]:          0 :         if( mxData->mrCfg.mbFromCell && mxData->mpLinkMgr && mxData->mpScBasePos )
         [ #  # ][ #  # ]
    1905         [ #  # ]:          0 :             mxData->mpLinkMgr->StoreCell( aRefData );
    1906                 :            : 
    1907                 :            :         // create the tRef, tRefErr, tRefN, tRef3d, or tRefErr3d token
    1908 [ #  # ][ #  # ]:          0 :         if( !mxData->mrCfg.mb3DRefOnly && IsRef2D( aRefData ) )
         [ #  # ][ #  # ]
    1909                 :            :         {
    1910                 :            :             // 2D reference (not in defined names, but allowed in range lists)
    1911                 :          0 :             sal_uInt8 nBaseId = (!mxData->mpScBasePos && lclIsRefRel2D( aRefData )) ? EXC_TOKID_REFN :
    1912         [ #  # ]:          0 :                 (lclIsRefDel2D( aRefData ) ? EXC_TOKID_REFERR : EXC_TOKID_REF);
           [ #  #  #  # ]
    1913         [ #  # ]:          0 :             AppendOperandTokenId( GetTokenId( nBaseId, EXC_TOKCLASS_REF ), rTokData.mnSpaces );
    1914         [ #  # ]:          0 :             AppendAddress( aXclPos );
    1915                 :            :         }
    1916         [ #  # ]:          0 :         else if( mxData->mpLinkMgr )    // 3D reference
    1917                 :            :         {
    1918                 :            :             // 1-based EXTERNSHEET index and 0-based Excel sheet index
    1919                 :            :             sal_uInt16 nExtSheet, nXclTab;
    1920 [ #  # ][ #  # ]:          0 :             mxData->mpLinkMgr->FindExtSheet( nExtSheet, nXclTab, GetScTab( aRefData ), GetNewRefLogEntry() );
                 [ #  # ]
    1921                 :            :             // write the token
    1922         [ #  # ]:          0 :             sal_uInt8 nBaseId = lclIsRefDel2D( aRefData ) ? EXC_TOKID_REFERR3D : EXC_TOKID_REF3D;
    1923         [ #  # ]:          0 :             AppendOperandTokenId( GetTokenId( nBaseId, EXC_TOKCLASS_REF ), rTokData.mnSpaces );
    1924         [ #  # ]:          0 :             Append( nExtSheet );
    1925         [ #  # ]:          0 :             if( meBiff <= EXC_BIFF5 )
    1926                 :            :             {
    1927         [ #  # ]:          0 :                 Append( 0, 8 );
    1928         [ #  # ]:          0 :                 Append( nXclTab );
    1929         [ #  # ]:          0 :                 Append( nXclTab );
    1930                 :            :             }
    1931         [ #  # ]:          0 :             AppendAddress( aXclPos );
    1932                 :            :         }
    1933                 :            :         else
    1934                 :            :         {
    1935                 :            :             // 3D ref in cond. format, or 2D ref in name
    1936         [ #  # ]:          0 :             AppendErrorToken( EXC_ERR_REF, rTokData.mnSpaces );
    1937                 :            :         }
    1938                 :            :     }
    1939                 :          0 : }
    1940                 :            : 
    1941                 :          0 : void XclExpFmlaCompImpl::ProcessRangeRef( const XclExpScToken& rTokData )
    1942                 :            : {
    1943                 :            :     // get the Excel address components, adjust internal data in aRefData
    1944         [ #  # ]:          0 :     ScComplexRefData aRefData = static_cast< const ScToken* >( rTokData.mpScToken )->GetDoubleRef();
    1945                 :          0 :     XclRange aXclRange( ScAddress::UNINITIALIZED );
    1946         [ #  # ]:          0 :     ConvertRefData( aRefData, aXclRange, false );
    1947                 :            : 
    1948                 :            :     // store external cell contents in CRN records
    1949 [ #  # ][ #  # ]:          0 :     if( mxData->mrCfg.mbFromCell && mxData->mpLinkMgr && mxData->mpScBasePos )
         [ #  # ][ #  # ]
    1950         [ #  # ]:          0 :         mxData->mpLinkMgr->StoreCellRange( aRefData );
    1951                 :            : 
    1952                 :            :     // create the tArea, tAreaErr, tAreaN, tArea3d, or tAreaErr3d token
    1953 [ #  # ][ #  # ]:          0 :     if( !mxData->mrCfg.mb3DRefOnly && IsRef2D( aRefData ) )
         [ #  # ][ #  # ]
    1954                 :            :     {
    1955                 :            :         // 2D reference (not in name formulas, but allowed in range lists)
    1956                 :          0 :         sal_uInt8 nBaseId = (!mxData->mpScBasePos && lclIsRefRel2D( aRefData )) ? EXC_TOKID_AREAN :
    1957         [ #  # ]:          0 :              (lclIsRefDel2D( aRefData ) ? EXC_TOKID_AREAERR : EXC_TOKID_AREA);
           [ #  #  #  # ]
    1958         [ #  # ]:          0 :         AppendOperandTokenId( GetTokenId( nBaseId, EXC_TOKCLASS_REF ), rTokData.mnSpaces );
    1959         [ #  # ]:          0 :         AppendRange( aXclRange );
    1960                 :            :     }
    1961         [ #  # ]:          0 :     else if( mxData->mpLinkMgr )    // 3D reference
    1962                 :            :     {
    1963                 :            :         // 1-based EXTERNSHEET index and 0-based Excel sheet indexes
    1964                 :            :         sal_uInt16 nExtSheet, nFirstXclTab, nLastXclTab;
    1965                 :          0 :         mxData->mpLinkMgr->FindExtSheet( nExtSheet, nFirstXclTab, nLastXclTab,
    1966 [ #  # ][ #  # ]:          0 :             GetScTab( aRefData.Ref1 ), GetScTab( aRefData.Ref2 ), GetNewRefLogEntry() );
           [ #  #  #  # ]
    1967                 :            :         // write the token
    1968         [ #  # ]:          0 :         sal_uInt8 nBaseId = lclIsRefDel2D( aRefData ) ? EXC_TOKID_AREAERR3D : EXC_TOKID_AREA3D;
    1969         [ #  # ]:          0 :         AppendOperandTokenId( GetTokenId( nBaseId, EXC_TOKCLASS_REF ), rTokData.mnSpaces );
    1970         [ #  # ]:          0 :         Append( nExtSheet );
    1971         [ #  # ]:          0 :         if( meBiff <= EXC_BIFF5 )
    1972                 :            :         {
    1973         [ #  # ]:          0 :             Append( 0, 8 );
    1974         [ #  # ]:          0 :             Append( nFirstXclTab );
    1975         [ #  # ]:          0 :             Append( nLastXclTab );
    1976                 :            :         }
    1977         [ #  # ]:          0 :         AppendRange( aXclRange );
    1978                 :            :     }
    1979                 :            :     else
    1980                 :            :     {
    1981                 :            :         // 3D ref in cond. format, or 2D ref in name
    1982         [ #  # ]:          0 :         AppendErrorToken( EXC_ERR_REF, rTokData.mnSpaces );
    1983                 :            :     }
    1984                 :          0 : }
    1985                 :            : 
    1986                 :          0 : void XclExpFmlaCompImpl::ProcessExternalCellRef( const XclExpScToken& rTokData )
    1987                 :            : {
    1988         [ #  # ]:          0 :     if( mxData->mpLinkMgr )
    1989                 :            :     {
    1990                 :            :         // get the Excel address components, adjust internal data in aRefData
    1991         [ #  # ]:          0 :         ScSingleRefData aRefData = static_cast< const ScToken* >( rTokData.mpScToken )->GetSingleRef();
    1992                 :          0 :         XclAddress aXclPos( ScAddress::UNINITIALIZED );
    1993         [ #  # ]:          0 :         ConvertRefData( aRefData, aXclPos, false, false, false );
    1994                 :            : 
    1995                 :            :         // store external cell contents in CRN records
    1996         [ #  # ]:          0 :         sal_uInt16 nFileId = rTokData.mpScToken->GetIndex();
    1997         [ #  # ]:          0 :         const String& rTabName = rTokData.mpScToken->GetString();
    1998 [ #  # ][ #  # ]:          0 :         if( mxData->mrCfg.mbFromCell && mxData->mpScBasePos )
                 [ #  # ]
    1999         [ #  # ]:          0 :             mxData->mpLinkMgr->StoreCell( nFileId, rTabName, aRefData );
    2000                 :            : 
    2001                 :            :         // 1-based EXTERNSHEET index and 0-based Excel sheet indexes
    2002                 :            :         sal_uInt16 nExtSheet, nFirstSBTab, nLastSBTab;
    2003 [ #  # ][ #  # ]:          0 :         mxData->mpLinkMgr->FindExtSheet( nFileId, rTabName, 1, nExtSheet, nFirstSBTab, nLastSBTab, GetNewRefLogEntry() );
    2004                 :            :         // write the token
    2005         [ #  # ]:          0 :         sal_uInt8 nBaseId = lclIsRefDel2D( aRefData ) ? EXC_TOKID_REFERR3D : EXC_TOKID_REF3D;
    2006         [ #  # ]:          0 :         AppendOperandTokenId( GetTokenId( nBaseId, EXC_TOKCLASS_REF ), rTokData.mnSpaces );
    2007         [ #  # ]:          0 :         Append( nExtSheet );
    2008         [ #  # ]:          0 :         if( meBiff <= EXC_BIFF5 )
    2009                 :            :         {
    2010         [ #  # ]:          0 :             Append( 0, 8 );
    2011         [ #  # ]:          0 :             Append( nFirstSBTab );
    2012         [ #  # ]:          0 :             Append( nLastSBTab );
    2013                 :            :         }
    2014         [ #  # ]:          0 :         AppendAddress( aXclPos );
    2015                 :            :     }
    2016                 :            :     else
    2017                 :            :     {
    2018                 :          0 :         AppendErrorToken( EXC_ERR_REF, rTokData.mnSpaces );
    2019                 :            :     }
    2020                 :          0 : }
    2021                 :            : 
    2022                 :          0 : void XclExpFmlaCompImpl::ProcessExternalRangeRef( const XclExpScToken& rTokData )
    2023                 :            : {
    2024         [ #  # ]:          0 :     if( mxData->mpLinkMgr )
    2025                 :            :     {
    2026                 :            :         // get the Excel address components, adjust internal data in aRefData
    2027         [ #  # ]:          0 :         ScComplexRefData aRefData = static_cast< const ScToken* >( rTokData.mpScToken )->GetDoubleRef();
    2028                 :          0 :         XclRange aXclRange( ScAddress::UNINITIALIZED );
    2029         [ #  # ]:          0 :         ConvertRefData( aRefData, aXclRange, false );
    2030                 :            : 
    2031                 :            :         // store external cell contents in CRN records
    2032         [ #  # ]:          0 :         sal_uInt16 nFileId = rTokData.mpScToken->GetIndex();
    2033         [ #  # ]:          0 :         const String& rTabName = rTokData.mpScToken->GetString();
    2034 [ #  # ][ #  # ]:          0 :         if( mxData->mrCfg.mbFromCell && mxData->mpScBasePos )
                 [ #  # ]
    2035         [ #  # ]:          0 :             mxData->mpLinkMgr->StoreCellRange( nFileId, rTabName, aRefData );
    2036                 :            : 
    2037                 :            :         // 1-based EXTERNSHEET index and 0-based Excel sheet indexes
    2038                 :            :         sal_uInt16 nExtSheet, nFirstSBTab, nLastSBTab;
    2039                 :          0 :         sal_uInt16 nTabSpan = static_cast< sal_uInt16 >( aRefData.Ref2.nTab - aRefData.Ref1.nTab + 1 );
    2040 [ #  # ][ #  # ]:          0 :         mxData->mpLinkMgr->FindExtSheet( nFileId, rTabName, nTabSpan, nExtSheet, nFirstSBTab, nLastSBTab, GetNewRefLogEntry() );
    2041                 :            :         // write the token
    2042         [ #  # ]:          0 :         sal_uInt8 nBaseId = lclIsRefDel2D( aRefData ) ? EXC_TOKID_AREAERR3D : EXC_TOKID_AREA3D;
    2043         [ #  # ]:          0 :         AppendOperandTokenId( GetTokenId( nBaseId, EXC_TOKCLASS_REF ), rTokData.mnSpaces );
    2044         [ #  # ]:          0 :         Append( nExtSheet );
    2045         [ #  # ]:          0 :         if( meBiff <= EXC_BIFF5 )
    2046                 :            :         {
    2047         [ #  # ]:          0 :             Append( 0, 8 );
    2048         [ #  # ]:          0 :             Append( nFirstSBTab );
    2049         [ #  # ]:          0 :             Append( nLastSBTab );
    2050                 :            :         }
    2051         [ #  # ]:          0 :         AppendRange( aXclRange );
    2052                 :            :     }
    2053                 :            :     else
    2054                 :            :     {
    2055                 :          0 :         AppendErrorToken( EXC_ERR_REF, rTokData.mnSpaces );
    2056                 :            :     }
    2057                 :          0 : }
    2058                 :            : 
    2059                 :          0 : void XclExpFmlaCompImpl::ProcessDefinedName( const XclExpScToken& rTokData )
    2060                 :            : {
    2061                 :          0 :     SCTAB nTab = SCTAB_GLOBAL;
    2062                 :          0 :     bool bGlobal = rTokData.mpScToken->IsGlobal();
    2063 [ #  # ][ #  # ]:          0 :     if (!bGlobal && mxData->mpScBasePos)
                 [ #  # ]
    2064                 :          0 :         nTab = mxData->mpScBasePos->Tab();
    2065                 :            : 
    2066                 :          0 :     XclExpNameManager& rNameMgr = GetNameManager();
    2067                 :          0 :     sal_uInt16 nNameIdx = rNameMgr.InsertName(nTab, rTokData.mpScToken->GetIndex());
    2068         [ #  # ]:          0 :     if( nNameIdx != 0 )
    2069                 :            :     {
    2070                 :            :         // global names always with tName token, local names dependent on config
    2071                 :          0 :         SCTAB nScTab = rNameMgr.GetScTab( nNameIdx );
    2072 [ #  # ][ #  # ]:          0 :         if( (nScTab == SCTAB_GLOBAL) || (!mxData->mrCfg.mb3DRefOnly && (nScTab == GetCurrScTab())) )
         [ #  # ][ #  # ]
    2073                 :            :         {
    2074                 :          0 :             AppendNameToken( nNameIdx, rTokData.mnSpaces );
    2075                 :            :         }
    2076         [ #  # ]:          0 :         else if( mxData->mpLinkMgr )
    2077                 :            :         {
    2078                 :            :             // use the same special EXTERNNAME to refer to any local name
    2079                 :          0 :             sal_uInt16 nExtSheet = mxData->mpLinkMgr->FindExtSheet( EXC_EXTSH_OWNDOC );
    2080                 :          0 :             AppendNameXToken( nExtSheet, nNameIdx, rTokData.mnSpaces );
    2081                 :            :         }
    2082                 :            :         else
    2083                 :          0 :             AppendErrorToken( EXC_ERR_NAME, rTokData.mnSpaces );
    2084                 :            :         // volatile names (containing volatile functions)
    2085                 :          0 :         mxData->mbVolatile |= rNameMgr.IsVolatile( nNameIdx );
    2086                 :            :     }
    2087                 :            :     else
    2088                 :          0 :         AppendErrorToken( EXC_ERR_NAME, rTokData.mnSpaces );
    2089                 :          0 : }
    2090                 :            : 
    2091                 :          0 : void XclExpFmlaCompImpl::ProcessExternalName( const XclExpScToken& rTokData )
    2092                 :            : {
    2093         [ #  # ]:          0 :     if( mxData->mpLinkMgr )
    2094                 :            :     {
    2095         [ #  # ]:          0 :         ScExternalRefManager& rExtRefMgr = *GetDoc().GetExternalRefManager();
    2096         [ #  # ]:          0 :         sal_uInt16 nFileId = rTokData.mpScToken->GetIndex();
    2097         [ #  # ]:          0 :         const String& rName = rTokData.mpScToken->GetString();
    2098 [ #  # ][ #  # ]:          0 :         ScExternalRefCache::TokenArrayRef xArray = rExtRefMgr.getRangeNameTokens( nFileId, rName );
    2099         [ #  # ]:          0 :         if( xArray.get() )
    2100                 :            :         {
    2101                 :            :             // store external cell contents in CRN records
    2102         [ #  # ]:          0 :             if( mxData->mpScBasePos )
    2103                 :            :             {
    2104 [ #  # ][ #  # ]:          0 :                 for( FormulaToken* pScToken = xArray->First(); pScToken; pScToken = xArray->Next() )
                 [ #  # ]
    2105                 :            :                 {
    2106 [ #  # ][ #  # ]:          0 :                     if( pScToken->IsExternalRef() )
    2107                 :            :                     {
    2108      [ #  #  # ]:          0 :                         switch( pScToken->GetType() )
    2109                 :            :                         {
    2110                 :            :                             case svExternalSingleRef:
    2111                 :            :                             {
    2112         [ #  # ]:          0 :                                 ScSingleRefData aRefData = static_cast< ScToken* >( pScToken )->GetSingleRef();
    2113         [ #  # ]:          0 :                                 aRefData.CalcAbsIfRel( *mxData->mpScBasePos );
    2114 [ #  # ][ #  # ]:          0 :                                 mxData->mpLinkMgr->StoreCell( nFileId, pScToken->GetString(), aRefData );
    2115                 :            :                             }
    2116                 :          0 :                             break;
    2117                 :            :                             case svExternalDoubleRef:
    2118                 :            :                             {
    2119         [ #  # ]:          0 :                                 ScComplexRefData aRefData = static_cast< ScToken* >( pScToken )->GetDoubleRef();
    2120         [ #  # ]:          0 :                                 aRefData.CalcAbsIfRel( *mxData->mpScBasePos );
    2121 [ #  # ][ #  # ]:          0 :                                 mxData->mpLinkMgr->StoreCellRange( nFileId, pScToken->GetString(), aRefData );
    2122                 :            :                             }
    2123                 :            :                             default:
    2124                 :            :                                 ;   // nothing, avoid compiler warning
    2125                 :            :                         }
    2126                 :            :                     }
    2127                 :            :                 }
    2128                 :            :             }
    2129                 :            : 
    2130                 :            :             // insert the new external name and create the tNameX token
    2131                 :          0 :             sal_uInt16 nExtSheet = 0, nExtName = 0;
    2132         [ #  # ]:          0 :             const ::rtl::OUString* pFile = rExtRefMgr.getExternalFileName( nFileId );
    2133 [ #  # ][ #  # ]:          0 :             if( pFile && mxData->mpLinkMgr->InsertExtName( nExtSheet, nExtName, *pFile, rName, xArray ) )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  #  
             #  #  #  # ]
    2134                 :            :             {
    2135         [ #  # ]:          0 :                 AppendNameXToken( nExtSheet, nExtName, rTokData.mnSpaces );
    2136                 :          0 :                 return;
    2137                 :            :             }
    2138 [ #  # ][ #  # ]:          0 :         }
    2139                 :            :     }
    2140                 :            : 
    2141                 :            :     // on any error: create a #NAME? error
    2142                 :          0 :     AppendErrorToken( EXC_ERR_NAME, rTokData.mnSpaces );
    2143                 :            : }
    2144                 :            : 
    2145                 :            : // token vector ---------------------------------------------------------------
    2146                 :            : 
    2147                 :          0 : void XclExpFmlaCompImpl::PushOperandPos( sal_uInt16 nTokPos )
    2148                 :            : {
    2149                 :          0 :     mxData->maOpPosStack.push_back( nTokPos );
    2150                 :          0 : }
    2151                 :            : 
    2152                 :          0 : void XclExpFmlaCompImpl::PushOperatorPos( sal_uInt16 nTokPos, const XclExpOperandListRef& rxOperands )
    2153                 :            : {
    2154                 :          0 :     PushOperandPos( nTokPos );
    2155                 :            :     OSL_ENSURE( rxOperands.get(), "XclExpFmlaCompImpl::AppendOperatorTokenId - missing operand list" );
    2156         [ #  # ]:          0 :     if( mxData->maOpListVec.size() <= nTokPos )
    2157         [ #  # ]:          0 :         mxData->maOpListVec.resize( nTokPos + 1, XclExpOperandListRef() );
    2158                 :          0 :     mxData->maOpListVec[ nTokPos ] = rxOperands;
    2159                 :          0 : }
    2160                 :            : 
    2161                 :          0 : sal_uInt16 XclExpFmlaCompImpl::PopOperandPos()
    2162                 :            : {
    2163                 :            :     OSL_ENSURE( !mxData->mbOk || !mxData->maOpPosStack.empty(), "XclExpFmlaCompImpl::PopOperandPos - token stack broken" );
    2164                 :          0 :     mxData->mbOk &= !mxData->maOpPosStack.empty();
    2165         [ #  # ]:          0 :     if( mxData->mbOk )
    2166                 :            :     {
    2167                 :          0 :         sal_uInt16 nTokPos = mxData->maOpPosStack.back();
    2168                 :          0 :         mxData->maOpPosStack.pop_back();
    2169                 :          0 :         return nTokPos;
    2170                 :            :     }
    2171                 :          0 :     return 0;
    2172                 :            : }
    2173                 :            : 
    2174                 :            : namespace {
    2175                 :            : 
    2176                 :          0 : inline void lclAppend( ScfUInt8Vec& orVector, sal_uInt16 nData )
    2177                 :            : {
    2178                 :          0 :     orVector.resize( orVector.size() + 2 );
    2179 [ #  # ][ #  # ]:          0 :     ShortToSVBT16( nData, &*(orVector.end() - 2) );
    2180                 :          0 : }
    2181                 :            : 
    2182                 :          0 : inline void lclAppend( ScfUInt8Vec& orVector, sal_uInt32 nData )
    2183                 :            : {
    2184                 :          0 :     orVector.resize( orVector.size() + 4 );
    2185 [ #  # ][ #  # ]:          0 :     UInt32ToSVBT32( nData, &*(orVector.end() - 4) );
    2186                 :          0 : }
    2187                 :            : 
    2188                 :          0 : inline void lclAppend( ScfUInt8Vec& orVector, double fData )
    2189                 :            : {
    2190                 :          0 :     orVector.resize( orVector.size() + 8 );
    2191 [ #  # ][ #  # ]:          0 :     DoubleToSVBT64( fData, &*(orVector.end() - 8) );
    2192                 :          0 : }
    2193                 :            : 
    2194                 :          0 : inline void lclAppend( ScfUInt8Vec& orVector, const XclExpRoot& rRoot, const String& rString, XclStrFlags nStrFlags )
    2195                 :            : {
    2196         [ #  # ]:          0 :     XclExpStringRef xXclStr = XclExpStringHelper::CreateString( rRoot, rString, nStrFlags, EXC_TOK_STR_MAXLEN );
    2197                 :          0 :     size_t nSize = orVector.size();
    2198 [ #  # ][ #  # ]:          0 :     orVector.resize( nSize + xXclStr->GetSize() );
    2199 [ #  # ][ #  # ]:          0 :     xXclStr->WriteToMem( &orVector[ nSize ] );
                 [ #  # ]
    2200                 :          0 : }
    2201                 :            : 
    2202                 :            : } // namespace
    2203                 :            : 
    2204                 :          0 : void XclExpFmlaCompImpl::Append( sal_uInt8 nData )
    2205                 :            : {
    2206                 :          0 :     mxData->maTokVec.push_back( nData );
    2207                 :          0 : }
    2208                 :            : 
    2209                 :          0 : void XclExpFmlaCompImpl::Append( sal_uInt8 nData, size_t nCount )
    2210                 :            : {
    2211                 :          0 :     mxData->maTokVec.resize( mxData->maTokVec.size() + nCount, nData );
    2212                 :          0 : }
    2213                 :            : 
    2214                 :          0 : void XclExpFmlaCompImpl::Append( sal_uInt16 nData )
    2215                 :            : {
    2216                 :          0 :     lclAppend( mxData->maTokVec, nData );
    2217                 :          0 : }
    2218                 :            : 
    2219                 :          0 : void XclExpFmlaCompImpl::Append( sal_uInt32 nData )
    2220                 :            : {
    2221                 :          0 :     lclAppend( mxData->maTokVec, nData );
    2222                 :          0 : }
    2223                 :            : 
    2224                 :          0 : void XclExpFmlaCompImpl::Append( double fData )
    2225                 :            : {
    2226                 :          0 :     lclAppend( mxData->maTokVec, fData );
    2227                 :          0 : }
    2228                 :            : 
    2229                 :          0 : void XclExpFmlaCompImpl::Append( const String& rString )
    2230                 :            : {
    2231                 :          0 :     lclAppend( mxData->maTokVec, GetRoot(), rString, EXC_STR_8BITLENGTH );
    2232                 :          0 : }
    2233                 :            : 
    2234                 :          0 : void XclExpFmlaCompImpl::AppendAddress( const XclAddress& rXclPos )
    2235                 :            : {
    2236                 :          0 :     Append( static_cast<sal_uInt16>(rXclPos.mnRow) );
    2237         [ #  # ]:          0 :     if( meBiff <= EXC_BIFF5 )
    2238                 :          0 :         Append( static_cast< sal_uInt8 >( rXclPos.mnCol ) );
    2239                 :            :     else
    2240                 :          0 :         Append( rXclPos.mnCol );
    2241                 :          0 : }
    2242                 :            : 
    2243                 :          0 : void XclExpFmlaCompImpl::AppendRange( const XclRange& rXclRange )
    2244                 :            : {
    2245                 :          0 :     Append( static_cast<sal_uInt16>(rXclRange.maFirst.mnRow) );
    2246                 :          0 :     Append( static_cast<sal_uInt16>(rXclRange.maLast.mnRow) );
    2247         [ #  # ]:          0 :     if( meBiff <= EXC_BIFF5 )
    2248                 :            :     {
    2249                 :          0 :         Append( static_cast< sal_uInt8 >( rXclRange.maFirst.mnCol ) );
    2250                 :          0 :         Append( static_cast< sal_uInt8 >( rXclRange.maLast.mnCol ) );
    2251                 :            :     }
    2252                 :            :     else
    2253                 :            :     {
    2254                 :          0 :         Append( rXclRange.maFirst.mnCol );
    2255                 :          0 :         Append( rXclRange.maLast.mnCol );
    2256                 :            :     }
    2257                 :          0 : }
    2258                 :            : 
    2259                 :          0 : void XclExpFmlaCompImpl::AppendSpaceToken( sal_uInt8 nType, sal_uInt8 nCount )
    2260                 :            : {
    2261         [ #  # ]:          0 :     if( nCount > 0 )
    2262                 :            :     {
    2263                 :          0 :         Append( EXC_TOKID_ATTR );
    2264                 :          0 :         Append( EXC_TOK_ATTR_SPACE );
    2265                 :          0 :         Append( nType );
    2266                 :          0 :         Append( nCount );
    2267                 :            :     }
    2268                 :          0 : }
    2269                 :            : 
    2270                 :          0 : void XclExpFmlaCompImpl::AppendOperandTokenId( sal_uInt8 nTokenId, sal_uInt8 nSpaces )
    2271                 :            : {
    2272                 :          0 :     AppendSpaceToken( EXC_TOK_ATTR_SPACE_SP, nSpaces );
    2273                 :          0 :     PushOperandPos( GetSize() );
    2274                 :          0 :     Append( nTokenId );
    2275                 :          0 : }
    2276                 :            : 
    2277                 :          0 : void XclExpFmlaCompImpl::AppendIntToken( sal_uInt16 nValue, sal_uInt8 nSpaces )
    2278                 :            : {
    2279                 :          0 :     AppendOperandTokenId( EXC_TOKID_INT, nSpaces );
    2280                 :          0 :     Append( nValue );
    2281                 :          0 : }
    2282                 :            : 
    2283                 :          0 : void XclExpFmlaCompImpl::AppendNumToken( double fValue, sal_uInt8 nSpaces )
    2284                 :            : {
    2285                 :          0 :     AppendOperandTokenId( EXC_TOKID_NUM, nSpaces );
    2286                 :          0 :     Append( fValue );
    2287                 :          0 : }
    2288                 :            : 
    2289                 :          0 : void XclExpFmlaCompImpl::AppendBoolToken( bool bValue, sal_uInt8 nSpaces )
    2290                 :            : {
    2291                 :          0 :     AppendOperandTokenId( EXC_TOKID_BOOL, nSpaces );
    2292         [ #  # ]:          0 :     Append( bValue ? EXC_TOK_BOOL_TRUE : EXC_TOK_BOOL_FALSE );
    2293                 :          0 : }
    2294                 :            : 
    2295                 :          0 : void XclExpFmlaCompImpl::AppendErrorToken( sal_uInt8 nErrCode, sal_uInt8 nSpaces )
    2296                 :            : {
    2297                 :          0 :     AppendOperandTokenId( EXC_TOKID_ERR, nSpaces );
    2298                 :          0 :     Append( nErrCode );
    2299                 :          0 : }
    2300                 :            : 
    2301                 :          0 : void XclExpFmlaCompImpl::AppendMissingToken( sal_uInt8 nSpaces )
    2302                 :            : {
    2303                 :          0 :     AppendOperandTokenId( EXC_TOKID_MISSARG, nSpaces );
    2304                 :          0 : }
    2305                 :            : 
    2306                 :          0 : void XclExpFmlaCompImpl::AppendNameToken( sal_uInt16 nNameIdx, sal_uInt8 nSpaces )
    2307                 :            : {
    2308         [ #  # ]:          0 :     if( nNameIdx > 0 )
    2309                 :            :     {
    2310                 :          0 :         AppendOperandTokenId( GetTokenId( EXC_TOKID_NAME, EXC_TOKCLASS_REF ), nSpaces );
    2311                 :          0 :         Append( nNameIdx );
    2312         [ #  # ]:          0 :         Append( 0, (meBiff <= EXC_BIFF5) ? 12 : 2 );
    2313                 :            :     }
    2314                 :            :     else
    2315                 :          0 :         AppendErrorToken( EXC_ERR_NAME );
    2316                 :          0 : }
    2317                 :            : 
    2318                 :          0 : void XclExpFmlaCompImpl::AppendMissingNameToken( const String& rName, sal_uInt8 nSpaces )
    2319                 :            : {
    2320                 :          0 :     sal_uInt16 nNameIdx = GetNameManager().InsertRawName( rName );
    2321                 :          0 :     AppendNameToken( nNameIdx, nSpaces );
    2322                 :          0 : }
    2323                 :            : 
    2324                 :          0 : void XclExpFmlaCompImpl::AppendNameXToken( sal_uInt16 nExtSheet, sal_uInt16 nExtName, sal_uInt8 nSpaces )
    2325                 :            : {
    2326                 :          0 :     AppendOperandTokenId( GetTokenId( EXC_TOKID_NAMEX, EXC_TOKCLASS_REF ), nSpaces );
    2327                 :          0 :     Append( nExtSheet );
    2328         [ #  # ]:          0 :     if( meBiff <= EXC_BIFF5 )
    2329                 :          0 :         Append( 0, 8 );
    2330                 :          0 :     Append( nExtName );
    2331         [ #  # ]:          0 :     Append( 0, (meBiff <= EXC_BIFF5) ? 12 : 2 );
    2332                 :          0 : }
    2333                 :            : 
    2334                 :          0 : void XclExpFmlaCompImpl::AppendMacroCallToken( const XclExpExtFuncData& rExtFuncData, sal_uInt8 nSpaces )
    2335                 :            : {
    2336                 :          0 :     sal_uInt16 nNameIdx = GetNameManager().InsertMacroCall( rExtFuncData.maFuncName, rExtFuncData.mbVBasic, true, rExtFuncData.mbHidden );
    2337                 :          0 :     AppendNameToken( nNameIdx, nSpaces );
    2338                 :          0 : }
    2339                 :            : 
    2340                 :          0 : void XclExpFmlaCompImpl::AppendAddInCallToken( const XclExpExtFuncData& rExtFuncData, sal_uInt8 nSpaces )
    2341                 :            : {
    2342                 :          0 :     ::rtl::OUString aXclFuncName;
    2343 [ #  # ][ #  # ]:          0 :     if( mxData->mpLinkMgr && ScGlobal::GetAddInCollection()->GetExcelName( rExtFuncData.maFuncName, GetUILanguage(), aXclFuncName ) )
         [ #  # ][ #  # ]
                 [ #  # ]
           [ #  #  #  # ]
                 [ #  # ]
    2344                 :            :     {
    2345                 :            :         sal_uInt16 nExtSheet, nExtName;
    2346 [ #  # ][ #  # ]:          0 :         if( mxData->mpLinkMgr->InsertAddIn( nExtSheet, nExtName, aXclFuncName ) )
         [ #  # ][ #  # ]
    2347                 :            :         {
    2348         [ #  # ]:          0 :             AppendNameXToken( nExtSheet, nExtName, nSpaces );
    2349                 :          0 :             return;
    2350                 :            :         }
    2351                 :            :     }
    2352 [ #  # ][ #  # ]:          0 :     AppendMacroCallToken( rExtFuncData, nSpaces );
    2353                 :            : }
    2354                 :            : 
    2355                 :          0 : void XclExpFmlaCompImpl::AppendEuroToolCallToken( const XclExpExtFuncData& rExtFuncData, sal_uInt8 nSpaces )
    2356                 :            : {
    2357                 :            :     sal_uInt16 nExtSheet, nExtName;
    2358 [ #  # ][ #  # ]:          0 :     if( mxData->mpLinkMgr && mxData->mpLinkMgr->InsertEuroTool( nExtSheet, nExtName, rExtFuncData.maFuncName ) )
         [ #  # ][ #  # ]
    2359         [ #  # ]:          0 :         AppendNameXToken( nExtSheet, nExtName, nSpaces );
    2360                 :            :     else
    2361         [ #  # ]:          0 :         AppendMacroCallToken( rExtFuncData, nSpaces );
    2362                 :          0 : }
    2363                 :            : 
    2364                 :          0 : void XclExpFmlaCompImpl::AppendOperatorTokenId( sal_uInt8 nTokenId, const XclExpOperandListRef& rxOperands, sal_uInt8 nSpaces )
    2365                 :            : {
    2366                 :          0 :     AppendSpaceToken( EXC_TOK_ATTR_SPACE_SP, nSpaces );
    2367                 :          0 :     PushOperatorPos( GetSize(), rxOperands );
    2368                 :          0 :     Append( nTokenId );
    2369                 :          0 : }
    2370                 :            : 
    2371                 :          0 : void XclExpFmlaCompImpl::AppendUnaryOperatorToken( sal_uInt8 nTokenId, sal_uInt8 nSpaces )
    2372                 :            : {
    2373 [ #  # ][ #  # ]:          0 :     XclExpOperandListRef xOperands( new XclExpOperandList );
                 [ #  # ]
    2374 [ #  # ][ #  # ]:          0 :     xOperands->AppendOperand( PopOperandPos(), EXC_PARAMCONV_RPO, true );
    2375 [ #  # ][ #  # ]:          0 :     AppendOperatorTokenId( nTokenId, xOperands, nSpaces );
    2376                 :          0 : }
    2377                 :            : 
    2378                 :          0 : void XclExpFmlaCompImpl::AppendBinaryOperatorToken( sal_uInt8 nTokenId, bool bValType, sal_uInt8 nSpaces )
    2379                 :            : {
    2380 [ #  # ][ #  # ]:          0 :     XclExpOperandListRef xOperands( new XclExpOperandList );
                 [ #  # ]
    2381 [ #  # ][ #  # ]:          0 :     xOperands->AppendOperand( PopOperandPos(), EXC_PARAMCONV_RPO, bValType );
    2382 [ #  # ][ #  # ]:          0 :     xOperands->AppendOperand( PopOperandPos(), EXC_PARAMCONV_RPO, bValType );
    2383 [ #  # ][ #  # ]:          0 :     AppendOperatorTokenId( nTokenId, xOperands, nSpaces );
    2384                 :          0 : }
    2385                 :            : 
    2386                 :          0 : void XclExpFmlaCompImpl::AppendLogicalOperatorToken( sal_uInt16 nXclFuncIdx, sal_uInt8 nOpCount )
    2387                 :            : {
    2388 [ #  # ][ #  # ]:          0 :     XclExpOperandListRef xOperands( new XclExpOperandList );
                 [ #  # ]
    2389         [ #  # ]:          0 :     for( sal_uInt8 nOpIdx = 0; nOpIdx < nOpCount; ++nOpIdx  )
    2390 [ #  # ][ #  # ]:          0 :         xOperands->AppendOperand( PopOperandPos(), EXC_PARAMCONV_RPX, false );
    2391         [ #  # ]:          0 :     AppendOperatorTokenId( GetTokenId( EXC_TOKID_FUNCVAR, EXC_TOKCLASS_VAL ), xOperands );
    2392         [ #  # ]:          0 :     Append( nOpCount );
    2393 [ #  # ][ #  # ]:          0 :     Append( nXclFuncIdx );
    2394                 :          0 : }
    2395                 :            : 
    2396                 :          0 : void XclExpFmlaCompImpl::AppendFuncToken( const XclExpFuncData& rFuncData )
    2397                 :            : {
    2398                 :          0 :     sal_uInt16 nXclFuncIdx = rFuncData.GetXclFuncIdx();
    2399                 :          0 :     sal_uInt8 nParamCount = rFuncData.GetParamCount();
    2400                 :          0 :     sal_uInt8 nRetClass = rFuncData.GetReturnClass();
    2401                 :            : 
    2402 [ #  # ][ #  # ]:          0 :     if( (nXclFuncIdx == EXC_FUNCID_SUM) && (nParamCount == 1) )
    2403                 :            :     {
    2404                 :            :         // SUM with only one parameter
    2405         [ #  # ]:          0 :         AppendOperatorTokenId( EXC_TOKID_ATTR, rFuncData.GetOperandList() );
    2406                 :          0 :         Append( EXC_TOK_ATTR_SUM );
    2407                 :          0 :         Append( sal_uInt16( 0 ) );
    2408                 :            :     }
    2409         [ #  # ]:          0 :     else if( rFuncData.IsFixedParamCount() )
    2410                 :            :     {
    2411                 :            :         // fixed number of parameters
    2412         [ #  # ]:          0 :         AppendOperatorTokenId( GetTokenId( EXC_TOKID_FUNC, nRetClass ), rFuncData.GetOperandList() );
    2413                 :          0 :         Append( nXclFuncIdx );
    2414                 :            :     }
    2415                 :            :     else
    2416                 :            :     {
    2417                 :            :         // variable number of parameters
    2418         [ #  # ]:          0 :         AppendOperatorTokenId( GetTokenId( EXC_TOKID_FUNCVAR, nRetClass ), rFuncData.GetOperandList() );
    2419                 :          0 :         Append( nParamCount );
    2420                 :          0 :         Append( nXclFuncIdx );
    2421                 :            :     }
    2422                 :          0 : }
    2423                 :            : 
    2424                 :          0 : void XclExpFmlaCompImpl::AppendParenToken( sal_uInt8 nOpenSpaces, sal_uInt8 nCloseSpaces )
    2425                 :            : {
    2426                 :          0 :     AppendSpaceToken( EXC_TOK_ATTR_SPACE_SP_OPEN, nOpenSpaces );
    2427                 :          0 :     AppendSpaceToken( EXC_TOK_ATTR_SPACE_SP_CLOSE, nCloseSpaces );
    2428                 :          0 :     Append( EXC_TOKID_PAREN );
    2429                 :          0 : }
    2430                 :            : 
    2431                 :          0 : void XclExpFmlaCompImpl::AppendJumpToken( XclExpFuncData& rFuncData, sal_uInt8 nAttrType )
    2432                 :            : {
    2433                 :            :     // store the start position of the token
    2434                 :          0 :     rFuncData.AppendAttrPos( GetSize() );
    2435                 :            :     // create the tAttr token
    2436                 :          0 :     Append( EXC_TOKID_ATTR );
    2437                 :          0 :     Append( nAttrType );
    2438                 :          0 :     Append( sal_uInt16( 0 ) );  // placeholder that will be updated later
    2439                 :          0 : }
    2440                 :            : 
    2441                 :          0 : void XclExpFmlaCompImpl::InsertZeros( sal_uInt16 nInsertPos, sal_uInt16 nInsertSize )
    2442                 :            : {
    2443                 :            :     // insert zeros into the token array
    2444                 :            :     OSL_ENSURE( nInsertPos < mxData->maTokVec.size(), "XclExpFmlaCompImpl::Insert - invalid position" );
    2445 [ #  # ][ #  # ]:          0 :     mxData->maTokVec.insert( mxData->maTokVec.begin() + nInsertPos, nInsertSize, 0 );
    2446                 :            : 
    2447                 :            :     // update positions of operands waiting for an operator
    2448 [ #  # ][ #  # ]:          0 :     for( ScfUInt16Vec::iterator aIt = mxData->maOpPosStack.begin(), aEnd = mxData->maOpPosStack.end(); aIt != aEnd; ++aIt )
                 [ #  # ]
    2449 [ #  # ][ #  # ]:          0 :         if( nInsertPos <= *aIt )
    2450 [ #  # ][ #  # ]:          0 :             *aIt = *aIt + nInsertSize;
    2451                 :            : 
    2452                 :            :     // update operand lists of all operator tokens
    2453         [ #  # ]:          0 :     if( nInsertPos < mxData->maOpListVec.size() )
    2454 [ #  # ][ #  # ]:          0 :         mxData->maOpListVec.insert( mxData->maOpListVec.begin() + nInsertPos, nInsertSize, XclExpOperandListRef() );
    2455 [ #  # ][ #  # ]:          0 :     for( XclExpOperandListVector::iterator aIt = mxData->maOpListVec.begin(), aEnd = mxData->maOpListVec.end(); aIt != aEnd; ++aIt )
    2456         [ #  # ]:          0 :         if( aIt->get() )
    2457 [ #  # ][ #  # ]:          0 :             for( XclExpOperandList::iterator aIt2 = (*aIt)->begin(), aEnd2 = (*aIt)->end(); aIt2 != aEnd2; ++aIt2 )
    2458         [ #  # ]:          0 :                 if( nInsertPos <= aIt2->mnTokPos )
    2459                 :          0 :                     aIt2->mnTokPos = aIt2->mnTokPos + nInsertSize;
    2460                 :          0 : }
    2461                 :            : 
    2462                 :          0 : void XclExpFmlaCompImpl::Overwrite( sal_uInt16 nWriteToPos, sal_uInt16 nOffset )
    2463                 :            : {
    2464                 :            :     OSL_ENSURE( static_cast< size_t >( nWriteToPos + 1 ) < mxData->maTokVec.size(), "XclExpFmlaCompImpl::Overwrite - invalid position" );
    2465                 :          0 :     ShortToSVBT16( nOffset, &mxData->maTokVec[ nWriteToPos ] );
    2466                 :          0 : }
    2467                 :            : 
    2468                 :          0 : void XclExpFmlaCompImpl::UpdateAttrGoto( sal_uInt16 nAttrPos )
    2469                 :            : {
    2470                 :            :     /*  tAttrGoto contains distance from end of tAttr token to position behind
    2471                 :            :         the function token (for IF or CHOOSE function), which is currently at
    2472                 :            :         the end of the token array. Additionally this distance is decreased by
    2473                 :            :         one, for whatever reason. So we have to subtract 4 and 1 from the
    2474                 :            :         distance between the tAttr token start and the end of the token array. */
    2475                 :          0 :     Overwrite( nAttrPos + 2, static_cast< sal_uInt16 >( GetSize() - nAttrPos - 5 ) );
    2476                 :          0 : }
    2477                 :            : 
    2478                 :          0 : bool XclExpFmlaCompImpl::IsSpaceToken( sal_uInt16 nPos ) const
    2479                 :            : {
    2480                 :            :     return
    2481                 :          0 :         (static_cast< size_t >( nPos + 4 ) <= mxData->maTokVec.size()) &&
    2482                 :          0 :         (mxData->maTokVec[ nPos ] == EXC_TOKID_ATTR) &&
    2483         [ #  # ]:          0 :         (mxData->maTokVec[ nPos + 1 ] == EXC_TOK_ATTR_SPACE);
           [ #  #  #  # ]
    2484                 :            : }
    2485                 :            : 
    2486                 :          0 : void XclExpFmlaCompImpl::RemoveTrailingParen()
    2487                 :            : {
    2488                 :            :     // remove trailing tParen token
    2489 [ #  # ][ #  # ]:          0 :     if( !mxData->maTokVec.empty() && (mxData->maTokVec.back() == EXC_TOKID_PAREN) )
                 [ #  # ]
    2490                 :          0 :         mxData->maTokVec.pop_back();
    2491                 :            :     // remove remaining tAttrSpace tokens
    2492 [ #  # ][ #  # ]:          0 :     while( (mxData->maTokVec.size() >= 4) && IsSpaceToken( GetSize() - 4 ) )
                 [ #  # ]
    2493 [ #  # ][ #  # ]:          0 :         mxData->maTokVec.erase( mxData->maTokVec.end() - 4, mxData->maTokVec.end() );
    2494                 :          0 : }
    2495                 :            : 
    2496                 :          0 : void XclExpFmlaCompImpl::AppendExt( sal_uInt8 nData )
    2497                 :            : {
    2498                 :          0 :     mxData->maExtDataVec.push_back( nData );
    2499                 :          0 : }
    2500                 :            : 
    2501                 :          0 : void XclExpFmlaCompImpl::AppendExt( sal_uInt8 nData, size_t nCount )
    2502                 :            : {
    2503                 :          0 :     mxData->maExtDataVec.resize( mxData->maExtDataVec.size() + nCount, nData );
    2504                 :          0 : }
    2505                 :            : 
    2506                 :          0 : void XclExpFmlaCompImpl::AppendExt( sal_uInt16 nData )
    2507                 :            : {
    2508                 :          0 :     lclAppend( mxData->maExtDataVec, nData );
    2509                 :          0 : }
    2510                 :            : 
    2511                 :          0 : void XclExpFmlaCompImpl::AppendExt( double fData )
    2512                 :            : {
    2513                 :          0 :     lclAppend( mxData->maExtDataVec, fData );
    2514                 :          0 : }
    2515                 :            : 
    2516                 :          0 : void XclExpFmlaCompImpl::AppendExt( const String& rString )
    2517                 :            : {
    2518         [ #  # ]:          0 :     lclAppend( mxData->maExtDataVec, GetRoot(), rString, (meBiff == EXC_BIFF8) ? EXC_STR_DEFAULT : EXC_STR_8BITLENGTH );
    2519                 :          0 : }
    2520                 :            : 
    2521                 :            : // ============================================================================
    2522                 :            : 
    2523                 :            : namespace {
    2524                 :            : 
    2525                 :          0 : void lclInitOwnTab( ScSingleRefData& rRef, const ScAddress& rScPos, SCTAB nCurrScTab, bool b3DRefOnly )
    2526                 :            : {
    2527         [ #  # ]:          0 :     if( b3DRefOnly )
    2528                 :            :     {
    2529                 :            :         // no reduction to 2D reference, if global link manager is used
    2530                 :          0 :         rRef.SetFlag3D( sal_True );
    2531                 :            :     }
    2532         [ #  # ]:          0 :     else if( rScPos.Tab() == nCurrScTab )
    2533                 :            :     {
    2534                 :          0 :         rRef.SetTabRel( sal_True );
    2535                 :          0 :         rRef.nRelTab = 0;
    2536                 :            :     }
    2537                 :          0 : }
    2538                 :            : 
    2539                 :          0 : void lclPutCellToTokenArray( ScTokenArray& rScTokArr, const ScAddress& rScPos, SCTAB nCurrScTab, bool b3DRefOnly )
    2540                 :            : {
    2541                 :            :     ScSingleRefData aRef;
    2542                 :          0 :     aRef.InitAddress( rScPos );
    2543                 :          0 :     lclInitOwnTab( aRef, rScPos, nCurrScTab, b3DRefOnly );
    2544         [ #  # ]:          0 :     rScTokArr.AddSingleReference( aRef );
    2545                 :          0 : }
    2546                 :            : 
    2547                 :          0 : void lclPutRangeToTokenArray( ScTokenArray& rScTokArr, const ScRange& rScRange, SCTAB nCurrScTab, bool b3DRefOnly )
    2548                 :            : {
    2549         [ #  # ]:          0 :     if( rScRange.aStart == rScRange.aEnd )
    2550                 :            :     {
    2551                 :          0 :         lclPutCellToTokenArray( rScTokArr, rScRange.aStart, nCurrScTab, b3DRefOnly );
    2552                 :            :     }
    2553                 :            :     else
    2554                 :            :     {
    2555                 :            :         ScComplexRefData aRef;
    2556                 :          0 :         aRef.InitRange( rScRange );
    2557                 :          0 :         lclInitOwnTab( aRef.Ref1, rScRange.aStart, nCurrScTab, b3DRefOnly );
    2558                 :          0 :         lclInitOwnTab( aRef.Ref2, rScRange.aEnd, nCurrScTab, b3DRefOnly );
    2559         [ #  # ]:          0 :         rScTokArr.AddDoubleReference( aRef );
    2560                 :            :     }
    2561                 :          0 : }
    2562                 :            : 
    2563                 :            : } // namespace
    2564                 :            : 
    2565                 :            : // ----------------------------------------------------------------------------
    2566                 :            : 
    2567                 :          0 : XclExpFormulaCompiler::XclExpFormulaCompiler( const XclExpRoot& rRoot ) :
    2568                 :            :     XclExpRoot( rRoot ),
    2569 [ #  # ][ #  # ]:          0 :     mxImpl( new XclExpFmlaCompImpl( rRoot ) )
                 [ #  # ]
    2570                 :            : {
    2571                 :          0 : }
    2572                 :            : 
    2573         [ #  # ]:          0 : XclExpFormulaCompiler::~XclExpFormulaCompiler()
    2574                 :            : {
    2575         [ #  # ]:          0 : }
    2576                 :            : 
    2577                 :          0 : XclTokenArrayRef XclExpFormulaCompiler::CreateFormula(
    2578                 :            :         XclFormulaType eType, const ScTokenArray& rScTokArr,
    2579                 :            :         const ScAddress* pScBasePos, XclExpRefLog* pRefLog )
    2580                 :            : {
    2581                 :          0 :     return mxImpl->CreateFormula( eType, rScTokArr, pScBasePos, pRefLog );
    2582                 :            : }
    2583                 :            : 
    2584                 :          0 : XclTokenArrayRef XclExpFormulaCompiler::CreateFormula( XclFormulaType eType, const ScAddress& rScPos )
    2585                 :            : {
    2586         [ #  # ]:          0 :     ScTokenArray aScTokArr;
    2587 [ #  # ][ #  # ]:          0 :     lclPutCellToTokenArray( aScTokArr, rScPos, GetCurrScTab(), mxImpl->Is3DRefOnly( eType ) );
    2588 [ #  # ][ #  # ]:          0 :     return mxImpl->CreateFormula( eType, aScTokArr );
    2589                 :            : }
    2590                 :            : 
    2591                 :          0 : XclTokenArrayRef XclExpFormulaCompiler::CreateFormula( XclFormulaType eType, const ScRange& rScRange )
    2592                 :            : {
    2593         [ #  # ]:          0 :     ScTokenArray aScTokArr;
    2594 [ #  # ][ #  # ]:          0 :     lclPutRangeToTokenArray( aScTokArr, rScRange, GetCurrScTab(), mxImpl->Is3DRefOnly( eType ) );
    2595 [ #  # ][ #  # ]:          0 :     return mxImpl->CreateFormula( eType, aScTokArr );
    2596                 :            : }
    2597                 :            : 
    2598                 :          0 : XclTokenArrayRef XclExpFormulaCompiler::CreateFormula( XclFormulaType eType, const ScRangeList& rScRanges )
    2599                 :            : {
    2600         [ #  # ]:          0 :     size_t nCount = rScRanges.size();
    2601         [ #  # ]:          0 :     if( nCount == 0 )
    2602         [ #  # ]:          0 :         return XclTokenArrayRef();
    2603                 :            : 
    2604         [ #  # ]:          0 :     ScTokenArray aScTokArr;
    2605                 :          0 :     SCTAB nCurrScTab = GetCurrScTab();
    2606         [ #  # ]:          0 :     bool b3DRefOnly = mxImpl->Is3DRefOnly( eType );
    2607         [ #  # ]:          0 :     for( size_t nIdx = 0; nIdx < nCount; ++nIdx )
    2608                 :            :     {
    2609         [ #  # ]:          0 :         if( nIdx > 0 )
    2610         [ #  # ]:          0 :             aScTokArr.AddOpCode( ocUnion );
    2611 [ #  # ][ #  # ]:          0 :         lclPutRangeToTokenArray( aScTokArr, *rScRanges[ nIdx ], nCurrScTab, b3DRefOnly );
    2612                 :            :     }
    2613 [ #  # ][ #  # ]:          0 :     return mxImpl->CreateFormula( eType, aScTokArr );
    2614                 :            : }
    2615                 :            : 
    2616                 :          0 : XclTokenArrayRef XclExpFormulaCompiler::CreateErrorFormula( sal_uInt8 nErrCode )
    2617                 :            : {
    2618                 :          0 :     return mxImpl->CreateErrorFormula( nErrCode );
    2619                 :            : }
    2620                 :            : 
    2621                 :          0 : XclTokenArrayRef XclExpFormulaCompiler::CreateSpecialRefFormula(
    2622                 :            :         sal_uInt8 nTokenId, const XclAddress& rXclPos )
    2623                 :            : {
    2624                 :          0 :     return mxImpl->CreateSpecialRefFormula( nTokenId, rXclPos );
    2625                 :            : }
    2626                 :            : 
    2627                 :          0 : XclTokenArrayRef XclExpFormulaCompiler::CreateNameXFormula(
    2628                 :            :         sal_uInt16 nExtSheet, sal_uInt16 nExtName )
    2629                 :            : {
    2630                 :          0 :     return mxImpl->CreateNameXFormula( nExtSheet, nExtName );
    2631 [ +  - ][ +  - ]:         24 : }
    2632                 :            : 
    2633                 :            : // ============================================================================
    2634                 :            : 
    2635                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10