LCOV - code coverage report
Current view: top level - libreoffice/sc/source/filter/excel - xlformula.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 87 218 39.9 %
Date: 2012-12-27 Functions: 20 37 54.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "xlformula.hxx"
      21             : 
      22             : #include "compiler.hxx"
      23             : #include "rangenam.hxx"
      24             : #include "token.hxx"
      25             : #include "tokenarray.hxx"
      26             : #include "xestream.hxx"
      27             : #include "xistream.hxx"
      28             : #include "xlroot.hxx"
      29             : 
      30             : #include <comphelper/string.hxx>
      31             : 
      32             : using namespace ::formula;
      33             : 
      34             : // Function data ==============================================================
      35             : 
      36        2280 : String XclFunctionInfo::GetMacroFuncName() const
      37             : {
      38        2280 :     if( IsMacroFunc() )
      39        2280 :         return String( mpcMacroName, RTL_TEXTENCODING_UTF8 );
      40           0 :     return EMPTY_STRING;
      41             : }
      42             : 
      43             : // abbreviations for function return token class
      44             : const sal_uInt8 R = EXC_TOKCLASS_REF;
      45             : const sal_uInt8 V = EXC_TOKCLASS_VAL;
      46             : const sal_uInt8 A = EXC_TOKCLASS_ARR;
      47             : 
      48             : // abbreviations for parameter infos
      49             : #define RO   { EXC_PARAM_REGULAR,   EXC_PARAMCONV_ORG, false }
      50             : #define RV   { EXC_PARAM_REGULAR,   EXC_PARAMCONV_VAL, false }
      51             : #define RA   { EXC_PARAM_REGULAR,   EXC_PARAMCONV_ARR, false }
      52             : #define RR   { EXC_PARAM_REGULAR,   EXC_PARAMCONV_RPT, false }
      53             : #define RX   { EXC_PARAM_REGULAR,   EXC_PARAMCONV_RPX, false }
      54             : #define VO   { EXC_PARAM_REGULAR,   EXC_PARAMCONV_ORG, true  }
      55             : #define VV   { EXC_PARAM_REGULAR,   EXC_PARAMCONV_VAL, true  }
      56             : #define VA   { EXC_PARAM_REGULAR,   EXC_PARAMCONV_ARR, true  }
      57             : #define VR   { EXC_PARAM_REGULAR,   EXC_PARAMCONV_RPT, true  }
      58             : #define VX   { EXC_PARAM_REGULAR,   EXC_PARAMCONV_RPX, true  }
      59             : #define RO_E { EXC_PARAM_EXCELONLY, EXC_PARAMCONV_ORG, false }
      60             : #define VR_E { EXC_PARAM_EXCELONLY, EXC_PARAMCONV_RPT, true  }
      61             : #define C    { EXC_PARAM_CALCONLY,  EXC_PARAMCONV_ORG, false }
      62             : 
      63             : const sal_uInt16 NOID = SAL_MAX_UINT16;     /// No BIFF/OOBIN function identifier available.
      64             : const sal_uInt8 MX    = 30;                 /// Maximum parameter count.
      65             : 
      66             : #define EXC_FUNCNAME( ascii )       "_xlfn." ascii
      67             : #define EXC_FUNCNAME_ODF( ascii )   "_xlfnodf." ascii
      68             : 
      69             : /** Functions new in BIFF2. */
      70             : static const XclFunctionInfo saFuncTable_2[] =
      71             : {
      72             :     { ocCount,              0,      0,  MX, V, { RX }, 0, 0 },
      73             :     { ocIf,                 1,      2,  3,  R, { VO, RO }, 0, 0 },
      74             :     { ocIsNA,               2,      1,  1,  V, { VR }, 0, 0 },
      75             :     { ocIsError,            3,      1,  1,  V, { VR }, 0, 0 },
      76             :     { ocSum,                4,      0,  MX, V, { RX }, 0, 0 },
      77             :     { ocAverage,            5,      1,  MX, V, { RX }, 0, 0 },
      78             :     { ocMin,                6,      1,  MX, V, { RX }, 0, 0 },
      79             :     { ocMax,                7,      1,  MX, V, { RX }, 0, 0 },
      80             :     { ocRow,                8,      0,  1,  V, { RO }, 0, 0 },
      81             :     { ocColumn,             9,      0,  1,  V, { RO }, 0, 0 },
      82             :     { ocNotAvail,           10,     0,  0,  V, {}, 0, 0 },
      83             :     { ocNPV,                11,     2,  MX, V, { VR, RX }, 0, 0 },
      84             :     { ocStDev,              12,     1,  MX, V, { RX }, 0, 0 },
      85             :     { ocCurrency,           13,     1,  2,  V, { VR }, 0, 0 },
      86             :     { ocFixed,              14,     1,  2,  V, { VR, VR, C }, 0, 0 },
      87             :     { ocSin,                15,     1,  1,  V, { VR }, 0, 0 },
      88             :     { ocCosecant,           15,     1,  1,  V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 },
      89             :     { ocCos,                16,     1,  1,  V, { VR }, 0, 0 },
      90             :     { ocSecant,             16,     1,  1,  V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 },
      91             :     { ocTan,                17,     1,  1,  V, { VR }, 0, 0 },
      92             :     { ocCot,                17,     1,  1,  V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 },
      93             :     { ocArcTan,             18,     1,  1,  V, { VR }, 0, 0 },
      94             :     { ocArcCot,             18,     1,  1,  V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 },
      95             :     { ocPi,                 19,     0,  0,  V, {}, 0, 0 },
      96             :     { ocSqrt,               20,     1,  1,  V, { VR }, 0, 0 },
      97             :     { ocExp,                21,     1,  1,  V, { VR }, 0, 0 },
      98             :     { ocLn,                 22,     1,  1,  V, { VR }, 0, 0 },
      99             :     { ocLog10,              23,     1,  1,  V, { VR }, 0, 0 },
     100             :     { ocAbs,                24,     1,  1,  V, { VR }, 0, 0 },
     101             :     { ocInt,                25,     1,  1,  V, { VR }, 0, 0 },
     102             :     { ocPlusMinus,          26,     1,  1,  V, { VR }, 0, 0 },
     103             :     { ocRound,              27,     2,  2,  V, { VR }, 0, 0 },
     104             :     { ocLookup,             28,     2,  3,  V, { VR, RA }, 0, 0 },
     105             :     { ocIndex,              29,     2,  4,  R, { RA, VV }, 0, 0 },
     106             :     { ocRept,               30,     2,  2,  V, { VR }, 0, 0 },
     107             :     { ocMid,                31,     3,  3,  V, { VR }, 0, 0 },
     108             :     { ocLen,                32,     1,  1,  V, { VR }, 0, 0 },
     109             :     { ocValue,              33,     1,  1,  V, { VR }, 0, 0 },
     110             :     { ocTrue,               34,     0,  0,  V, {}, 0, 0 },
     111             :     { ocFalse,              35,     0,  0,  V, {}, 0, 0 },
     112             :     { ocAnd,                36,     1,  MX, V, { RX }, 0, 0 },
     113             :     { ocOr,                 37,     1,  MX, V, { RX }, 0, 0 },
     114             :     { ocNot,                38,     1,  1,  V, { VR }, 0, 0 },
     115             :     { ocMod,                39,     2,  2,  V, { VR }, 0, 0 },
     116             :     { ocDBCount,            40,     3,  3,  V, { RO, RR }, 0, 0 },
     117             :     { ocDBSum,              41,     3,  3,  V, { RO, RR }, 0, 0 },
     118             :     { ocDBAverage,          42,     3,  3,  V, { RO, RR }, 0, 0 },
     119             :     { ocDBMin,              43,     3,  3,  V, { RO, RR }, 0, 0 },
     120             :     { ocDBMax,              44,     3,  3,  V, { RO, RR }, 0, 0 },
     121             :     { ocDBStdDev,           45,     3,  3,  V, { RO, RR }, 0, 0 },
     122             :     { ocVar,                46,     1,  MX, V, { RX }, 0, 0 },
     123             :     { ocDBVar,              47,     3,  3,  V, { RO, RR }, 0, 0 },
     124             :     { ocText,               48,     2,  2,  V, { VR }, 0, 0 },
     125             :     { ocRGP,                49,     1,  2,  A, { RA, RA, C, C }, 0, 0 },
     126             :     { ocTrend,              50,     1,  3,  A, { RA, RA, RA, C }, 0, 0 },
     127             :     { ocRKP,                51,     1,  2,  A, { RA, RA, C, C }, 0, 0 },
     128             :     { ocGrowth,             52,     1,  3,  A, { RA, RA, RA, C }, 0, 0 },
     129             :     { ocBW,                 56,     3,  5,  V, { VR }, 0, 0 },
     130             :     { ocZW,                 57,     3,  5,  V, { VR }, 0, 0 },
     131             :     { ocZZR,                58,     3,  5,  V, { VR }, 0, 0 },
     132             :     { ocRMZ,                59,     3,  5,  V, { VR }, 0, 0 },
     133             :     { ocZins,               60,     3,  6,  V, { VR }, 0, 0 },
     134             :     { ocMIRR,               61,     3,  3,  V, { RA, VR }, 0, 0 },
     135             :     { ocIRR,                62,     1,  2,  V, { RA, VR }, 0, 0 },
     136             :     { ocRandom,             63,     0,  0,  V, {}, EXC_FUNCFLAG_VOLATILE, 0 },
     137             :     { ocMatch,              64,     2,  3,  V, { VR, RX, RR }, 0, 0 },
     138             :     { ocGetDate,            65,     3,  3,  V, { VR }, 0, 0 },
     139             :     { ocGetTime,            66,     3,  3,  V, { VR }, 0, 0 },
     140             :     { ocGetDay,             67,     1,  1,  V, { VR }, 0, 0 },
     141             :     { ocGetMonth,           68,     1,  1,  V, { VR }, 0, 0 },
     142             :     { ocGetYear,            69,     1,  1,  V, { VR }, 0, 0 },
     143             :     { ocGetDayOfWeek,       70,     1,  1,  V, { VR, C }, 0, 0 },
     144             :     { ocGetHour,            71,     1,  1,  V, { VR }, 0, 0 },
     145             :     { ocGetMin,             72,     1,  1,  V, { VR }, 0, 0 },
     146             :     { ocGetSec,             73,     1,  1,  V, { VR }, 0, 0 },
     147             :     { ocGetActTime,         74,     0,  0,  V, {}, EXC_FUNCFLAG_VOLATILE, 0 },
     148             :     { ocAreas,              75,     1,  1,  V, { RO }, 0, 0 },
     149             :     { ocRows,               76,     1,  1,  V, { RO }, 0, 0 },
     150             :     { ocColumns,            77,     1,  1,  V, { RO }, 0, 0 },
     151             :     { ocOffset,             78,     3,  5,  R, { RO, VR }, EXC_FUNCFLAG_VOLATILE, 0 },
     152             :     { ocSearch,             82,     2,  3,  V, { VR }, 0, 0 },
     153             :     { ocMatTrans,           83,     1,  1,  A, { VO }, 0, 0 },
     154             :     { ocType,               86,     1,  1,  V, { VX }, 0, 0 },
     155             :     { ocArcTan2,            97,     2,  2,  V, { VR }, 0, 0 },
     156             :     { ocArcSin,             98,     1,  1,  V, { VR }, 0, 0 },
     157             :     { ocArcCos,             99,     1,  1,  V, { VR }, 0, 0 },
     158             :     { ocChose,              100,    2,  MX, R, { VO, RO }, 0, 0 },
     159             :     { ocHLookup,            101,    3,  3,  V, { VV, RO, RO, C }, 0, 0 },
     160             :     { ocVLookup,            102,    3,  3,  V, { VV, RO, RO, C }, 0, 0 },
     161             :     { ocIsRef,              105,    1,  1,  V, { RX }, 0, 0 },
     162             :     { ocLog,                109,    1,  2,  V, { VR }, 0, 0 },
     163             :     { ocChar,               111,    1,  1,  V, { VR }, 0, 0 },
     164             :     { ocLower,              112,    1,  1,  V, { VR }, 0, 0 },
     165             :     { ocUpper,              113,    1,  1,  V, { VR }, 0, 0 },
     166             :     { ocPropper,            114,    1,  1,  V, { VR }, 0, 0 },
     167             :     { ocLeft,               115,    1,  2,  V, { VR }, 0, 0 },
     168             :     { ocRight,              116,    1,  2,  V, { VR }, 0, 0 },
     169             :     { ocExact,              117,    2,  2,  V, { VR }, 0, 0 },
     170             :     { ocTrim,               118,    1,  1,  V, { VR }, 0, 0 },
     171             :     { ocReplace,            119,    4,  4,  V, { VR }, 0, 0 },
     172             :     { ocSubstitute,         120,    3,  4,  V, { VR }, 0, 0 },
     173             :     { ocCode,               121,    1,  1,  V, { VR }, 0, 0 },
     174             :     { ocFind,               124,    2,  3,  V, { VR }, 0, 0 },
     175             :     { ocCell,               125,    1,  2,  V, { VV, RO }, EXC_FUNCFLAG_VOLATILE, 0 },
     176             :     { ocIsErr,              126,    1,  1,  V, { VR }, 0, 0 },
     177             :     { ocIsString,           127,    1,  1,  V, { VR }, 0, 0 },
     178             :     { ocIsValue,            128,    1,  1,  V, { VR }, 0, 0 },
     179             :     { ocIsEmpty,            129,    1,  1,  V, { VR }, 0, 0 },
     180             :     { ocT,                  130,    1,  1,  V, { RO }, 0, 0 },
     181             :     { ocN,                  131,    1,  1,  V, { RO }, 0, 0 },
     182             :     { ocGetDateValue,       140,    1,  1,  V, { VR }, 0, 0 },
     183             :     { ocGetTimeValue,       141,    1,  1,  V, { VR }, 0, 0 },
     184             :     { ocLIA,                142,    3,  3,  V, { VR }, 0, 0 },
     185             :     { ocDIA,                143,    4,  4,  V, { VR }, 0, 0 },
     186             :     { ocGDA,                144,    4,  5,  V, { VR }, 0, 0 },
     187             :     { ocIndirect,           148,    1,  2,  R, { VR }, EXC_FUNCFLAG_VOLATILE, 0 },
     188             :     { ocClean,              162,    1,  1,  V, { VR }, 0, 0 },
     189             :     { ocMatDet,             163,    1,  1,  V, { VA }, 0, 0 },
     190             :     { ocMatInv,             164,    1,  1,  A, { VA }, 0, 0 },
     191             :     { ocMatMult,            165,    2,  2,  A, { VA }, 0, 0 },
     192             :     { ocZinsZ,              167,    4,  6,  V, { VR }, 0, 0 },
     193             :     { ocKapz,               168,    4,  6,  V, { VR }, 0, 0 },
     194             :     { ocCount2,             169,    0,  MX, V, { RX }, 0, 0 },
     195             :     { ocProduct,            183,    0,  MX, V, { RX }, 0, 0 },
     196             :     { ocFact,               184,    1,  1,  V, { VR }, 0, 0 },
     197             :     { ocDBProduct,          189,    3,  3,  V, { RO, RR }, 0, 0 },
     198             :     { ocIsNonString,        190,    1,  1,  V, { VR }, 0, 0 },
     199             :     { ocStDevP,             193,    1,  MX, V, { RX }, 0, 0 },
     200             :     { ocVarP,               194,    1,  MX, V, { RX }, 0, 0 },
     201             :     { ocDBStdDevP,          195,    3,  3,  V, { RO, RR }, 0, 0 },
     202             :     { ocDBVarP,             196,    3,  3,  V, { RO, RR }, 0, 0 },
     203             :     { ocTrunc,              197,    1,  1,  V, { VR, C }, 0, 0 },
     204             :     { ocIsLogical,          198,    1,  1,  V, { VR }, 0, 0 },
     205             :     { ocDBCount2,           199,    3,  3,  V, { RO, RR }, 0, 0 },
     206             :     { ocCurrency,           204,    1,  2,  V, { VR }, EXC_FUNCFLAG_IMPORTONLY, 0 },
     207             :     { ocRoundUp,            212,    2,  2,  V, { VR }, 0, 0 },
     208             :     { ocRoundDown,          213,    2,  2,  V, { VR }, 0, 0 },
     209             :     { ocExternal,           255,    1,  MX, R, { RO_E, RO }, EXC_FUNCFLAG_IMPORTONLY, 0 }
     210             : };
     211             : 
     212             : /** Functions new in BIFF3. */
     213             : static const XclFunctionInfo saFuncTable_3[] =
     214             : {
     215             :     { ocRGP,                49,     1,  4,  A, { RA, RA, VV }, 0, 0 },          // BIFF2: 1-2, BIFF3: 1-4
     216             :     { ocTrend,              50,     1,  4,  A, { RA, RA, RA, VV }, 0, 0 },      // BIFF2: 1-3, BIFF3: 1-4
     217             :     { ocRKP,                51,     1,  4,  A, { RA, RA, VV }, 0, 0 },          // BIFF2: 1-2, BIFF3: 1-4
     218             :     { ocGrowth,             52,     1,  4,  A, { RA, RA, RA, VV }, 0, 0 },      // BIFF2: 1-3, BIFF3: 1-4
     219             :     { ocTrunc,              197,    1,  2,  V, { VR }, 0, 0 },                  // BIFF2: 1,   BIFF3: 1-2
     220             :     { ocAddress,            219,    2,  5,  V, { VR }, 0, 0 },
     221             :     { ocGetDiffDate360,     220,    2,  2,  V, { VR, VR, C }, 0, 0 },
     222             :     { ocGetActDate,         221,    0,  0,  V, {}, EXC_FUNCFLAG_VOLATILE, 0 },
     223             :     { ocVBD,                222,    5,  7,  V, { VR }, 0, 0 },
     224             :     { ocMedian,             227,    1,  MX, V, { RX }, 0, 0 },
     225             :     { ocSumProduct,         228,    1,  MX, V, { VA }, 0, 0 },
     226             :     { ocSinHyp,             229,    1,  1,  V, { VR }, 0, 0 },
     227             :     { ocCosecantHyp,        229,    1,  1,  V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 },
     228             :     { ocCosHyp,             230,    1,  1,  V, { VR }, 0, 0 },
     229             :     { ocSecantHyp,          230,    1,  1,  V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 },
     230             :     { ocTanHyp,             231,    1,  1,  V, { VR }, 0, 0 },
     231             :     { ocCotHyp,             231,    1,  1,  V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 },
     232             :     { ocArcSinHyp,          232,    1,  1,  V, { VR }, 0, 0 },
     233             :     { ocArcCosHyp,          233,    1,  1,  V, { VR }, 0, 0 },
     234             :     { ocArcTanHyp,          234,    1,  1,  V, { VR }, 0, 0 },
     235             :     { ocArcCotHyp,          234,    1,  1,  V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 },
     236             :     { ocDBGet,              235,    3,  3,  V, { RO, RR }, 0, 0 },
     237             :     { ocInfo,               244,    1,  1,  V, { VR }, EXC_FUNCFLAG_VOLATILE, 0 }
     238             : };
     239             : 
     240             : /** Functions new in BIFF4. */
     241             : static const XclFunctionInfo saFuncTable_4[] =
     242             : {
     243             :     { ocFixed,              14,     1,  3,  V, { VR }, 0, 0 },                  // BIFF2-3: 1-2, BIFF4: 1-3
     244             :     { ocAsc,                214,    1,  1,  V, { VR }, 0, 0 },
     245             :     { ocJis,                215,    1,  1,  V, { VR }, 0, 0 },
     246             :     { ocRank,               216,    2,  3,  V, { VR, RO, VR }, 0, 0 },
     247             :     { ocGDA2,               247,    4,  5,  V, { VR }, 0, 0 },
     248             :     { ocFrequency,          252,    2,  2,  A, { RA }, 0, 0 },
     249             :     { ocErrorType,          261,    1,  1,  V, { VR }, 0, 0 },
     250             :     { ocAveDev,             269,    1,  MX, V, { RX }, 0, 0 },
     251             :     { ocBetaDist,           270,    3,  5,  V, { VR }, 0, 0 },
     252             :     { ocGammaLn,            271,    1,  1,  V, { VR }, 0, 0 },
     253             :     { ocBetaInv,            272,    3,  5,  V, { VR }, 0, 0 },
     254             :     { ocBinomDist,          273,    4,  4,  V, { VR }, 0, 0 },
     255             :     { ocChiDist,            274,    2,  2,  V, { VR }, 0, 0 },
     256             :     { ocChiInv,             275,    2,  2,  V, { VR }, 0, 0 },
     257             :     { ocKombin,             276,    2,  2,  V, { VR }, 0, 0 },
     258             :     { ocConfidence,         277,    3,  3,  V, { VR }, 0, 0 },
     259             :     { ocKritBinom,          278,    3,  3,  V, { VR }, 0, 0 },
     260             :     { ocEven,               279,    1,  1,  V, { VR }, 0, 0 },
     261             :     { ocExpDist,            280,    3,  3,  V, { VR }, 0, 0 },
     262             :     { ocFDist,              281,    3,  3,  V, { VR }, 0, 0 },
     263             :     { ocFInv,               282,    3,  3,  V, { VR }, 0, 0 },
     264             :     { ocFisher,             283,    1,  1,  V, { VR }, 0, 0 },
     265             :     { ocFisherInv,          284,    1,  1,  V, { VR }, 0, 0 },
     266             :     { ocFloor,              285,    2,  2,  V, { VR, VR, C }, 0, 0 },
     267             :     { ocGammaDist,          286,    4,  4,  V, { VR }, 0, 0 },
     268             :     { ocGammaInv,           287,    3,  3,  V, { VR }, 0, 0 },
     269             :     { ocCeil,               288,    2,  2,  V, { VR, VR, C }, 0, 0 },
     270             :     { ocHypGeomDist,        289,    4,  4,  V, { VR }, 0, 0 },
     271             :     { ocLogNormDist,        290,    3,  3,  V, { VR }, 0, 0 },
     272             :     { ocLogInv,             291,    3,  3,  V, { VR }, 0, 0 },
     273             :     { ocNegBinomVert,       292,    3,  3,  V, { VR }, 0, 0 },
     274             :     { ocNormDist,           293,    4,  4,  V, { VR }, 0, 0 },
     275             :     { ocStdNormDist,        294,    1,  1,  V, { VR }, 0, 0 },
     276             :     { ocNormInv,            295,    3,  3,  V, { VR }, 0, 0 },
     277             :     { ocSNormInv,           296,    1,  1,  V, { VR }, 0, 0 },
     278             :     { ocStandard,           297,    3,  3,  V, { VR }, 0, 0 },
     279             :     { ocOdd,                298,    1,  1,  V, { VR }, 0, 0 },
     280             :     { ocVariationen,        299,    2,  2,  V, { VR }, 0, 0 },
     281             :     { ocPoissonDist,        300,    3,  3,  V, { VR }, 0, 0 },
     282             :     { ocTDist,              301,    3,  3,  V, { VR }, 0, 0 },
     283             :     { ocWeibull,            302,    4,  4,  V, { VR }, 0, 0 },
     284             :     { ocSumXMY2,            303,    2,  2,  V, { VA }, 0, 0 },
     285             :     { ocSumX2MY2,           304,    2,  2,  V, { VA }, 0, 0 },
     286             :     { ocSumX2DY2,           305,    2,  2,  V, { VA }, 0, 0 },
     287             :     { ocChiTest,            306,    2,  2,  V, { VA }, 0, 0 },
     288             :     { ocCorrel,             307,    2,  2,  V, { VA }, 0, 0 },
     289             :     { ocCovar,              308,    2,  2,  V, { VA }, 0, 0 },
     290             :     { ocForecast,           309,    3,  3,  V, { VR, VA }, 0, 0 },
     291             :     { ocFTest,              310,    2,  2,  V, { VA }, 0, 0 },
     292             :     { ocIntercept,          311,    2,  2,  V, { VA }, 0, 0 },
     293             :     { ocPearson,            312,    2,  2,  V, { VA }, 0, 0 },
     294             :     { ocRSQ,                313,    2,  2,  V, { VA }, 0, 0 },
     295             :     { ocSTEYX,              314,    2,  2,  V, { VA }, 0, 0 },
     296             :     { ocSlope,              315,    2,  2,  V, { VA }, 0, 0 },
     297             :     { ocTTest,              316,    4,  4,  V, { VA, VA, VR }, 0, 0 },
     298             :     { ocProb,               317,    3,  4,  V, { VA, VA, VR }, 0, 0 },
     299             :     { ocDevSq,              318,    1,  MX, V, { RX }, 0, 0 },
     300             :     { ocGeoMean,            319,    1,  MX, V, { RX }, 0, 0 },
     301             :     { ocHarMean,            320,    1,  MX, V, { RX }, 0, 0 },
     302             :     { ocSumSQ,              321,    0,  MX, V, { RX }, 0, 0 },
     303             :     { ocKurt,               322,    1,  MX, V, { RX }, 0, 0 },
     304             :     { ocSchiefe,            323,    1,  MX, V, { RX }, 0, 0 },
     305             :     { ocZTest,              324,    2,  3,  V, { RX, VR }, 0, 0 },
     306             :     { ocLarge,              325,    2,  2,  V, { RX, VR }, 0, 0 },
     307             :     { ocSmall,              326,    2,  2,  V, { RX, VR }, 0, 0 },
     308             :     { ocQuartile,           327,    2,  2,  V, { RX, VR }, 0, 0 },
     309             :     { ocPercentile,         328,    2,  2,  V, { RX, VR }, 0, 0 },
     310             :     { ocPercentrank,        329,    2,  3,  V, { RX, VR, VR_E }, 0, 0 },
     311             :     { ocModalValue,         330,    1,  MX, V, { VA }, 0, 0 },
     312             :     { ocTrimMean,           331,    2,  2,  V, { RX, VR }, 0, 0 },
     313             :     { ocTInv,               332,    2,  2,  V, { VR }, 0, 0 }
     314             : };
     315             : 
     316             : /** Functions new in BIFF5/BIFF7. Unsupported functions: DATESTRING, NUMBERSTRING. */
     317             : static const XclFunctionInfo saFuncTable_5[] =
     318             : {
     319             :     { ocGetDayOfWeek,       70,     1,  2,  V, { VR }, 0, 0 },                  // BIFF2-4: 1, BIFF5: 1-2
     320             :     { ocHLookup,            101,    3,  4,  V, { VV, RO, RO, VV }, 0, 0 },      // BIFF2-4: 3, BIFF5: 3-4
     321             :     { ocVLookup,            102,    3,  4,  V, { VV, RO, RO, VV }, 0, 0 },      // BIFF2-4: 3, BIFF5: 3-4
     322             :     { ocGetDiffDate360,     220,    2,  3,  V, { VR }, 0, 0 },                  // BIFF3-4: 2, BIFF5: 2-3
     323             :     { ocMacro,              255,    1,  MX, R, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY, 0 },
     324             :     { ocExternal,           255,    1,  MX, R, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY, 0 },
     325             :     { ocConcat,             336,    0,  MX, V, { VR }, 0, 0 },
     326             :     { ocPower,              337,    2,  2,  V, { VR }, 0, 0 },
     327             :     { ocRad,                342,    1,  1,  V, { VR }, 0, 0 },
     328             :     { ocDeg,                343,    1,  1,  V, { VR }, 0, 0 },
     329             :     { ocSubTotal,           344,    2,  MX, V, { VR, RO }, 0, 0 },
     330             :     { ocSumIf,              345,    2,  3,  V, { RO, VR, RO }, 0, 0 },
     331             :     { ocCountIf,            346,    2,  2,  V, { RO, VR }, 0, 0 },
     332             :     { ocCountEmptyCells,    347,    1,  1,  V, { RO }, 0, 0 },
     333             :     { ocISPMT,              350,    4,  4,  V, { VR }, 0, 0 },
     334             :     { ocGetDateDif,         351,    3,  3,  V, { VR }, 0, 0 },
     335             :     { ocNoName,             352,    1,  1,  V, { VR }, EXC_FUNCFLAG_IMPORTONLY, 0 },    // DATESTRING
     336             :     { ocNoName,             353,    2,  2,  V, { VR }, EXC_FUNCFLAG_IMPORTONLY, 0 },    // NUMBERSTRING
     337             :     { ocRoman,              354,    1,  2,  V, { VR }, 0, 0 }
     338             : };
     339             : 
     340             : /** Functions new in BIFF8. Unsupported functions: PHONETIC. */
     341             : static const XclFunctionInfo saFuncTable_8[] =
     342             : {
     343             :     { ocGetPivotData,       358,    2,  MX, V, { RR, RR, VR }, 0, 0 },
     344             :     { ocHyperLink,          359,    1,  2,  V, { VV, VO }, 0, 0 },
     345             :     { ocNoName,             360,    1,  1,  V, { RO }, EXC_FUNCFLAG_IMPORTONLY, 0 },    // PHONETIC
     346             :     { ocAverageA,           361,    1,  MX, V, { RX }, 0, 0 },
     347             :     { ocMaxA,               362,    1,  MX, V, { RX }, 0, 0 },
     348             :     { ocMinA,               363,    1,  MX, V, { RX }, 0, 0 },
     349             :     { ocStDevPA,            364,    1,  MX, V, { RX }, 0, 0 },
     350             :     { ocVarPA,              365,    1,  MX, V, { RX }, 0, 0 },
     351             :     { ocStDevA,             366,    1,  MX, V, { RX }, 0, 0 },
     352             :     { ocVarA,               367,    1,  MX, V, { RX }, 0, 0 },
     353             :     { ocBahtText,           368,    1,  1,  V, { VR }, EXC_FUNCFLAG_IMPORTONLY, EXC_FUNCNAME( "BAHTTEXT" ) },
     354             :     { ocBahtText,           255,    2,  2,  V, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY, EXC_FUNCNAME( "BAHTTEXT" ) },
     355             :     { ocEuroConvert,        255,    4,  6,  V, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY, "EUROCONVERT" }
     356             : };
     357             : 
     358             : /** Functions new in OOXML. */
     359             : static const XclFunctionInfo saFuncTable_Oox[] =
     360             : {
     361             :     { ocCountIfs,           NOID,   2,  MX, V, { RO, VR }, EXC_FUNCFLAG_IMPORTONLY|EXC_FUNCFLAG_PARAMPAIRS, EXC_FUNCNAME( "COUNTIFS" ) },
     362             :     { ocCountIfs,           255,    3,  MX, V, { RO_E, RO, VR }, EXC_FUNCFLAG_EXPORTONLY|EXC_FUNCFLAG_PARAMPAIRS, EXC_FUNCNAME( "COUNTIFS" ) },
     363             :     { ocSumIfs,             NOID,   3,  MX, V, { RO, RO, VR }, EXC_FUNCFLAG_IMPORTONLY|EXC_FUNCFLAG_PARAMPAIRS, EXC_FUNCNAME( "SUMIFS" ) },
     364             :     { ocSumIfs,             255,    4,  MX, V, { RO_E, RO, RO, VR }, EXC_FUNCFLAG_EXPORTONLY|EXC_FUNCFLAG_PARAMPAIRS, EXC_FUNCNAME( "SUMIFS" ) },
     365             :     { ocAverageIf,          NOID,   2,  3,  V, { RO, VR, RO }, EXC_FUNCFLAG_IMPORTONLY, EXC_FUNCNAME( "AVERAGEIF" ) },
     366             :     { ocAverageIf,          255,    3,  4,  V, { RO_E, RO, VR, RO }, EXC_FUNCFLAG_EXPORTONLY, EXC_FUNCNAME( "AVERAGEIF" ) },
     367             :     { ocAverageIfs,         NOID,   3,  MX, V, { RO, RO, VR }, EXC_FUNCFLAG_IMPORTONLY|EXC_FUNCFLAG_PARAMPAIRS, EXC_FUNCNAME( "AVERAGEIFS" ) },
     368             :     { ocAverageIfs,         255,    4,  MX, V, { RO_E, RO, RO, VR }, EXC_FUNCFLAG_EXPORTONLY|EXC_FUNCFLAG_PARAMPAIRS, EXC_FUNCNAME( "AVERAGEIFS" ) }
     369             : };
     370             : 
     371             : #define EXC_FUNCENTRY_ODF( opcode, minparam, maxparam, flags, asciiname ) \
     372             :     { opcode, NOID, minparam,     maxparam,     V, { VR },       EXC_FUNCFLAG_IMPORTONLY|(flags), EXC_FUNCNAME_ODF( asciiname ) }, \
     373             :     { opcode,  255, (minparam)+1, (maxparam)+1, V, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY|(flags), EXC_FUNCNAME_ODF( asciiname ) }
     374             : 
     375             : /** Functions defined by OpenFormula, but not supported by Calc (ocNoName) or by Excel (defined op-code). */
     376             : static const XclFunctionInfo saFuncTable_Odf[] =
     377             : {
     378             :     EXC_FUNCENTRY_ODF( ocArabic,        1,  1,  0,  "ARABIC" ),
     379             :     EXC_FUNCENTRY_ODF( ocB,             3,  4,  0,  "B" ),
     380             :     EXC_FUNCENTRY_ODF( ocBase,          2,  3,  0,  "BASE" ),
     381             :     EXC_FUNCENTRY_ODF( ocBitAnd,        2,  2,  0,  "BITAND" ),
     382             :     EXC_FUNCENTRY_ODF( ocBitLshift,     2,  2,  0,  "BITLSHIFT" ),
     383             :     EXC_FUNCENTRY_ODF( ocBitOr,         2,  2,  0,  "BITOR" ),
     384             :     EXC_FUNCENTRY_ODF( ocBitRshift,     2,  2,  0,  "BITRSHIFT" ),
     385             :     EXC_FUNCENTRY_ODF( ocBitXor,        2,  2,  0,  "BITXOR" ),
     386             :     EXC_FUNCENTRY_ODF( ocChiSqDist,     2,  3,  0,  "CHISQDIST" ),
     387             :     EXC_FUNCENTRY_ODF( ocChiSqInv,      2,  2,  0,  "CHISQINV" ),
     388             :     EXC_FUNCENTRY_ODF( ocKombin2,       2,  2,  0,  "COMBINA" ),
     389             :     EXC_FUNCENTRY_ODF( ocGetDiffDate,   2,  2,  0,  "DAYS" ),
     390             :     EXC_FUNCENTRY_ODF( ocDecimal,       2,  2,  0,  "DECIMAL" ),
     391             :     EXC_FUNCENTRY_ODF( ocFDist,         3,  4,  0,  "FDIST" ),
     392             :     EXC_FUNCENTRY_ODF( ocFInv,          3,  3,  0,  "FINV" ),
     393             :     EXC_FUNCENTRY_ODF( ocFormula,       1,  1,  0,  "FORMULA" ),
     394             :     EXC_FUNCENTRY_ODF( ocGamma,         1,  1,  0,  "GAMMA" ),
     395             :     EXC_FUNCENTRY_ODF( ocGauss,         1,  1,  0,  "GAUSS" ),
     396             :     EXC_FUNCENTRY_ODF( ocNoName,        2,  2,  0,  "IFNA" ),
     397             :     EXC_FUNCENTRY_ODF( ocIsFormula,     1,  1,  0,  "ISFORMULA" ),
     398             :     EXC_FUNCENTRY_ODF( ocWeek,          1,  2,  0,  "ISOWEEKNUM" ),
     399             :     EXC_FUNCENTRY_ODF( ocMatrixUnit,    1,  1,  0,  "MUNIT" ),
     400             :     EXC_FUNCENTRY_ODF( ocNumberValue,   2,  2,  0,  "NUMBERVALUE" ),
     401             :     EXC_FUNCENTRY_ODF( ocLaufz,         3,  3,  0,  "PDURATION" ),
     402             :     EXC_FUNCENTRY_ODF( ocVariationen2,  2,  2,  0,  "PERMUTATIONA" ),
     403             :     EXC_FUNCENTRY_ODF( ocPhi,           1,  1,  0,  "PHI" ),
     404             :     EXC_FUNCENTRY_ODF( ocZGZ,           3,  3,  0,  "RRI" ),
     405             :     EXC_FUNCENTRY_ODF( ocTable,         0,  1,  0,  "SHEET" ),
     406             :     EXC_FUNCENTRY_ODF( ocTables,        0,  1,  0,  "SHEETS" ),
     407             :     EXC_FUNCENTRY_ODF( ocNoName,        1,  MX, 0,  "SKEWP" ),
     408             :     EXC_FUNCENTRY_ODF( ocUnichar,       1,  1,  0,  "UNICHAR" ),
     409             :     EXC_FUNCENTRY_ODF( ocUnicode,       1,  1,  0,  "UNICODE" ),
     410             :     EXC_FUNCENTRY_ODF( ocXor,           1,  MX, 0,  "XOR" )
     411             : };
     412             : 
     413             : #undef EXC_FUNCENTRY_ODF
     414             : 
     415             : // ----------------------------------------------------------------------------
     416             : 
     417          61 : XclFunctionProvider::XclFunctionProvider( const XclRoot& rRoot )
     418             : {
     419             :     void (XclFunctionProvider::*pFillFunc)( const XclFunctionInfo*, const XclFunctionInfo* ) =
     420          61 :         rRoot.IsImport() ? &XclFunctionProvider::FillXclFuncMap : &XclFunctionProvider::FillScFuncMap;
     421             : 
     422             :     /*  Only read/write functions supported in the current BIFF version.
     423             :         Function tables from later BIFF versions may overwrite single functions
     424             :         from earlier tables. */
     425          61 :     XclBiff eBiff = rRoot.GetBiff();
     426          61 :     if( eBiff >= EXC_BIFF2 )
     427          61 :         (this->*pFillFunc)( saFuncTable_2, STATIC_ARRAY_END( saFuncTable_2 ) );
     428          61 :     if( eBiff >= EXC_BIFF3 )
     429          61 :         (this->*pFillFunc)( saFuncTable_3, STATIC_ARRAY_END( saFuncTable_3 ) );
     430          61 :     if( eBiff >= EXC_BIFF4 )
     431          61 :         (this->*pFillFunc)( saFuncTable_4, STATIC_ARRAY_END( saFuncTable_4 ) );
     432          61 :     if( eBiff >= EXC_BIFF5 )
     433          61 :         (this->*pFillFunc)( saFuncTable_5, STATIC_ARRAY_END( saFuncTable_5 ) );
     434          61 :     if( eBiff >= EXC_BIFF8 )
     435          61 :         (this->*pFillFunc)( saFuncTable_8, STATIC_ARRAY_END( saFuncTable_8 ) );
     436          61 :     (this->*pFillFunc)( saFuncTable_Oox, STATIC_ARRAY_END( saFuncTable_Oox ) );
     437          61 :     (this->*pFillFunc)( saFuncTable_Odf, STATIC_ARRAY_END( saFuncTable_Odf ) );
     438          61 : }
     439             : 
     440        2712 : const XclFunctionInfo* XclFunctionProvider::GetFuncInfoFromXclFunc( sal_uInt16 nXclFunc ) const
     441             : {
     442             :     // only in import filter allowed
     443             :     OSL_ENSURE( !maXclFuncMap.empty(), "XclFunctionProvider::GetFuncInfoFromXclFunc - wrong filter" );
     444        2712 :     XclFuncMap::const_iterator aIt = maXclFuncMap.find( nXclFunc );
     445        2712 :     return (aIt == maXclFuncMap.end()) ? 0 : aIt->second;
     446             : }
     447             : 
     448           1 : const XclFunctionInfo* XclFunctionProvider::GetFuncInfoFromXclMacroName( const String& rXclMacroName ) const
     449             : {
     450             :     // only in import filter allowed, but do not test maXclMacroNameMap, it may be empty for old BIFF versions
     451             :     OSL_ENSURE( !maXclFuncMap.empty(), "XclFunctionProvider::GetFuncInfoFromXclMacroName - wrong filter" );
     452           1 :     XclMacroNameMap::const_iterator aIt = maXclMacroNameMap.find( rXclMacroName );
     453           1 :     return (aIt == maXclMacroNameMap.end()) ? 0 : aIt->second;
     454             : }
     455             : 
     456           0 : const XclFunctionInfo* XclFunctionProvider::GetFuncInfoFromOpCode( OpCode eOpCode ) const
     457             : {
     458             :     // only in export filter allowed
     459             :     OSL_ENSURE( !maScFuncMap.empty(), "XclFunctionProvider::GetFuncInfoFromOpCode - wrong filter" );
     460           0 :     ScFuncMap::const_iterator aIt = maScFuncMap.find( eOpCode );
     461           0 :     return (aIt == maScFuncMap.end()) ? 0 : aIt->second;
     462             : }
     463             : 
     464         420 : void XclFunctionProvider::FillXclFuncMap( const XclFunctionInfo* pBeg, const XclFunctionInfo* pEnd )
     465             : {
     466       20700 :     for( const XclFunctionInfo* pIt = pBeg; pIt != pEnd; ++pIt )
     467             :     {
     468       20280 :         if( !::get_flag( pIt->mnFlags, EXC_FUNCFLAG_EXPORTONLY ) )
     469             :         {
     470       17340 :             if( pIt->mnXclFunc != NOID )
     471       15120 :                 maXclFuncMap[ pIt->mnXclFunc ] = pIt;
     472       17340 :             if( pIt->IsMacroFunc() )
     473        2280 :                 maXclMacroNameMap[ pIt->GetMacroFuncName() ] = pIt;
     474             :         }
     475             :     }
     476         420 : }
     477             : 
     478           7 : void XclFunctionProvider::FillScFuncMap( const XclFunctionInfo* pBeg, const XclFunctionInfo* pEnd )
     479             : {
     480         345 :     for( const XclFunctionInfo* pIt = pBeg; pIt != pEnd; ++pIt )
     481         338 :         if( !::get_flag( pIt->mnFlags, EXC_FUNCFLAG_IMPORTONLY ) )
     482         295 :             maScFuncMap[ pIt->meOpCode ] = pIt;
     483           7 : }
     484             : 
     485             : // Token array ================================================================
     486             : 
     487          83 : XclTokenArray::XclTokenArray( bool bVolatile ) :
     488          83 :     mbVolatile( bVolatile )
     489             : {
     490          83 : }
     491             : 
     492           8 : XclTokenArray::XclTokenArray( ScfUInt8Vec& rTokVec, ScfUInt8Vec& rExtDataVec, bool bVolatile ) :
     493           8 :     mbVolatile( bVolatile )
     494             : {
     495           8 :     maTokVec.swap( rTokVec );
     496           8 :     maExtDataVec.swap( rExtDataVec );
     497           8 : }
     498             : 
     499         249 : sal_uInt16 XclTokenArray::GetSize() const
     500             : {
     501             :     OSL_ENSURE( maTokVec.size() <= 0xFFFF, "XclTokenArray::GetSize - array too long" );
     502         249 :     return limit_cast< sal_uInt16 >( maTokVec.size() );
     503             : }
     504             : 
     505          83 : void XclTokenArray::ReadSize( XclImpStream& rStrm )
     506             : {
     507             :     sal_uInt16 nSize;
     508          83 :     rStrm >> nSize;
     509          83 :     maTokVec.resize( nSize );
     510          83 : }
     511             : 
     512          83 : void XclTokenArray::ReadArray( XclImpStream& rStrm )
     513             : {
     514          83 :     if( !maTokVec.empty() )
     515          83 :         rStrm.Read( &maTokVec.front(), GetSize() );
     516          83 : }
     517             : 
     518          82 : void XclTokenArray::Read( XclImpStream& rStrm )
     519             : {
     520          82 :     ReadSize( rStrm );
     521          82 :     ReadArray( rStrm );
     522          82 : }
     523             : 
     524           0 : void XclTokenArray::WriteSize( XclExpStream& rStrm ) const
     525             : {
     526           0 :     rStrm << GetSize();
     527           0 : }
     528             : 
     529           0 : void XclTokenArray::WriteArray( XclExpStream& rStrm ) const
     530             : {
     531           0 :     if( !maTokVec.empty() )
     532           0 :         rStrm.Write( &maTokVec.front(), GetSize() );
     533           0 :     if( !maExtDataVec.empty() )
     534           0 :         rStrm.Write( &maExtDataVec.front(), maExtDataVec.size() );
     535           0 : }
     536             : 
     537           0 : void XclTokenArray::Write( XclExpStream& rStrm ) const
     538             : {
     539           0 :     WriteSize( rStrm );
     540           0 :     WriteArray( rStrm );
     541           0 : }
     542             : 
     543           0 : bool XclTokenArray::operator==( const XclTokenArray& rTokArr ) const
     544             : {
     545           0 :     return (mbVolatile == rTokArr.mbVolatile) && (maTokVec == rTokArr.maTokVec) && (maExtDataVec == rTokArr.maExtDataVec);
     546             : }
     547             : 
     548          82 : XclImpStream& operator>>( XclImpStream& rStrm, XclTokenArray& rTokArr )
     549             : {
     550          82 :     rTokArr.Read( rStrm );
     551          82 :     return rStrm;
     552             : }
     553             : 
     554           0 : XclImpStream& operator>>( XclImpStream& rStrm, XclTokenArrayRef& rxTokArr )
     555             : {
     556           0 :     if( !rxTokArr )
     557           0 :         rxTokArr.reset( new XclTokenArray );
     558           0 :     rxTokArr->Read( rStrm );
     559           0 :     return rStrm;
     560             : }
     561             : 
     562           0 : XclExpStream& operator<<( XclExpStream& rStrm, const XclTokenArray& rTokArr )
     563             : {
     564           0 :     rTokArr.Write( rStrm );
     565           0 :     return rStrm;
     566             : }
     567             : 
     568           0 : XclExpStream& operator<<( XclExpStream& rStrm, const XclTokenArrayRef& rxTokArr )
     569             : {
     570           0 :     if( rxTokArr )
     571           0 :         rxTokArr->Write( rStrm );
     572             :     else
     573           0 :         rStrm << sal_uInt16( 0 );
     574           0 :     return rStrm;
     575             : }
     576             : 
     577             : // ----------------------------------------------------------------------------
     578             : 
     579           8 : XclTokenArrayIterator::XclTokenArrayIterator() :
     580             :     mppScTokenBeg( 0 ),
     581             :     mppScTokenEnd( 0 ),
     582             :     mppScToken( 0 ),
     583           8 :     mbSkipSpaces( false )
     584             : {
     585           8 : }
     586             : 
     587           0 : XclTokenArrayIterator::XclTokenArrayIterator( const ScTokenArray& rScTokArr, bool bSkipSpaces )
     588             : {
     589           0 :     Init( rScTokArr, bSkipSpaces );
     590           0 : }
     591             : 
     592           0 : XclTokenArrayIterator::XclTokenArrayIterator( const XclTokenArrayIterator& rTokArrIt, bool bSkipSpaces ) :
     593             :     mppScTokenBeg( rTokArrIt.mppScTokenBeg ),
     594             :     mppScTokenEnd( rTokArrIt.mppScTokenEnd ),
     595             :     mppScToken( rTokArrIt.mppScToken ),
     596           0 :     mbSkipSpaces( bSkipSpaces )
     597             : {
     598           0 :     SkipSpaces();
     599           0 : }
     600             : 
     601           8 : void XclTokenArrayIterator::Init( const ScTokenArray& rScTokArr, bool bSkipSpaces )
     602             : {
     603           8 :     sal_uInt16 nTokArrLen = rScTokArr.GetLen();
     604           8 :     mppScTokenBeg = static_cast< const FormulaToken* const* >( nTokArrLen ? rScTokArr.GetArray() : 0 );
     605           8 :     mppScTokenEnd = mppScTokenBeg ? (mppScTokenBeg + nTokArrLen) : 0;
     606           8 :     mppScToken = (mppScTokenBeg != mppScTokenEnd) ? mppScTokenBeg : 0;
     607           8 :     mbSkipSpaces = bSkipSpaces;
     608           8 :     SkipSpaces();
     609           8 : }
     610             : 
     611          16 : XclTokenArrayIterator& XclTokenArrayIterator::operator++()
     612             : {
     613          16 :     NextRawToken();
     614          16 :     SkipSpaces();
     615          16 :     return *this;
     616             : }
     617             : 
     618          16 : void XclTokenArrayIterator::NextRawToken()
     619             : {
     620          16 :     if( mppScToken )
     621           8 :         if( (++mppScToken == mppScTokenEnd) || !*mppScToken )
     622           8 :             mppScToken = 0;
     623          16 : }
     624             : 
     625          24 : void XclTokenArrayIterator::SkipSpaces()
     626             : {
     627          24 :     if( mbSkipSpaces )
     628           0 :         while( Is() && ((*this)->GetOpCode() == ocSpaces) )
     629           0 :             NextRawToken();
     630          24 : }
     631             : 
     632             : // strings and string lists ---------------------------------------------------
     633             : 
     634           0 : bool XclTokenArrayHelper::GetTokenString( String& rString, const FormulaToken& rScToken )
     635             : {
     636           0 :     bool bIsStr = (rScToken.GetType() == svString) && (rScToken.GetOpCode() == ocPush);
     637           0 :     if( bIsStr ) rString = rScToken.GetString();
     638           0 :     return bIsStr;
     639             : }
     640             : 
     641           0 : bool XclTokenArrayHelper::GetString( String& rString, const ScTokenArray& rScTokArr )
     642             : {
     643           0 :     XclTokenArrayIterator aIt( rScTokArr, true );
     644             :     // something is following the string token -> error
     645           0 :     return aIt.Is() && GetTokenString( rString, *aIt ) && !++aIt;
     646             : }
     647             : 
     648           0 : bool XclTokenArrayHelper::GetStringList( String& rStringList, const ScTokenArray& rScTokArr, sal_Unicode cSep )
     649             : {
     650           0 :     bool bRet = true;
     651           0 :     String aString;
     652           0 :     XclTokenArrayIterator aIt( rScTokArr, true );
     653           0 :     enum { STATE_START, STATE_STR, STATE_SEP, STATE_END } eState = STATE_START;
     654           0 :     while( eState != STATE_END ) switch( eState )
     655             :     {
     656             :         case STATE_START:
     657           0 :             eState = aIt.Is() ? STATE_STR : STATE_END;
     658           0 :         break;
     659             :         case STATE_STR:
     660           0 :             bRet = GetTokenString( aString, *aIt );
     661           0 :             if( bRet ) rStringList.Append( aString );
     662           0 :             eState = (bRet && (++aIt).Is()) ? STATE_SEP : STATE_END;
     663           0 :         break;
     664             :         case STATE_SEP:
     665           0 :             bRet = aIt->GetOpCode() == ocSep;
     666           0 :             if( bRet ) rStringList.Append( cSep );
     667           0 :             eState = (bRet && (++aIt).Is()) ? STATE_STR : STATE_END;
     668           0 :         break;
     669             :         default:;
     670             :     }
     671           0 :     return bRet;
     672             : }
     673             : 
     674           0 : void XclTokenArrayHelper::ConvertStringToList( ScTokenArray& rScTokArr, sal_Unicode cStringSep, bool bTrimLeadingSpaces )
     675             : {
     676           0 :     String aString;
     677           0 :     if( GetString( aString, rScTokArr ) )
     678             :     {
     679           0 :         rScTokArr.Clear();
     680           0 :         xub_StrLen nTokenCnt = comphelper::string::getTokenCount(aString, cStringSep);
     681           0 :         xub_StrLen nStringIx = 0;
     682           0 :         for( xub_StrLen nToken = 0; nToken < nTokenCnt; ++nToken )
     683             :         {
     684           0 :             String aToken( aString.GetToken( 0, cStringSep, nStringIx ) );
     685           0 :             if( bTrimLeadingSpaces )
     686           0 :                 aToken = comphelper::string::stripStart(aToken, ' ');
     687           0 :             if( nToken > 0 )
     688           0 :                 rScTokArr.AddOpCode( ocSep );
     689           0 :             rScTokArr.AddString( aToken );
     690           0 :         }
     691           0 :     }
     692           0 : }
     693             : 
     694             : // shared formulas ------------------------------------------------------------
     695             : 
     696           0 : const ScTokenArray* XclTokenArrayHelper::GetSharedFormula( const XclRoot& rRoot, const ScTokenArray& rScTokArr )
     697             : {
     698           0 :     if( rScTokArr.GetLen() == 1 )
     699           0 :         if( const FormulaToken* pScToken = rScTokArr.GetArray()[ 0 ] )
     700           0 :             if( pScToken->GetOpCode() == ocName )
     701           0 :                 if( ScRangeData* pData = rRoot.GetNamedRanges().findByIndex( pScToken->GetIndex() ) )
     702           0 :                     if( pData->HasType( RT_SHARED ) )
     703           0 :                         return pData->GetCode();
     704           0 :     return 0;
     705             : }
     706             : 
     707             : // multiple operations --------------------------------------------------------
     708             : 
     709             : namespace {
     710             : 
     711           0 : inline bool lclGetAddress( ScAddress& rAddress, const FormulaToken& rToken )
     712             : {
     713           0 :     OpCode eOpCode = rToken.GetOpCode();
     714           0 :     bool bIsSingleRef = (eOpCode == ocPush) && (rToken.GetType() == svSingleRef);
     715           0 :     if( bIsSingleRef )
     716             :     {
     717           0 :         const ScSingleRefData& rRef = static_cast<const ScToken&>(rToken).GetSingleRef();
     718           0 :         rAddress.Set( rRef.nCol, rRef.nRow, rRef.nTab );
     719           0 :         bIsSingleRef = !rRef.IsDeleted();
     720             :     }
     721           0 :     return bIsSingleRef;
     722             : }
     723             : 
     724             : } // namespace
     725             : 
     726           0 : bool XclTokenArrayHelper::GetMultipleOpRefs( XclMultipleOpRefs& rRefs, const ScTokenArray& rScTokArr )
     727             : {
     728           0 :     rRefs.mbDblRefMode = false;
     729             :     enum
     730             :     {
     731             :         stBegin, stTableOp, stOpen, stFormula, stFormulaSep,
     732             :         stColFirst, stColFirstSep, stColRel, stColRelSep,
     733             :         stRowFirst, stRowFirstSep, stRowRel, stClose, stError
     734           0 :     } eState = stBegin;     // last read token
     735           0 :     for( XclTokenArrayIterator aIt( rScTokArr, true ); aIt.Is() && (eState != stError); ++aIt )
     736             :     {
     737           0 :         OpCode eOpCode = aIt->GetOpCode();
     738           0 :         bool bIsSep = eOpCode == ocSep;
     739           0 :         switch( eState )
     740             :         {
     741             :             case stBegin:
     742           0 :                 eState = (eOpCode == ocTableOp) ? stTableOp : stError;
     743           0 :             break;
     744             :             case stTableOp:
     745           0 :                 eState = (eOpCode == ocOpen) ? stOpen : stError;
     746           0 :             break;
     747             :             case stOpen:
     748           0 :                 eState = lclGetAddress( rRefs.maFmlaScPos, *aIt ) ? stFormula : stError;
     749           0 :             break;
     750             :             case stFormula:
     751           0 :                 eState = bIsSep ? stFormulaSep : stError;
     752           0 :             break;
     753             :             case stFormulaSep:
     754           0 :                 eState = lclGetAddress( rRefs.maColFirstScPos, *aIt ) ? stColFirst : stError;
     755           0 :             break;
     756             :             case stColFirst:
     757           0 :                 eState = bIsSep ? stColFirstSep : stError;
     758           0 :             break;
     759             :             case stColFirstSep:
     760           0 :                 eState = lclGetAddress( rRefs.maColRelScPos, *aIt ) ? stColRel : stError;
     761           0 :             break;
     762             :             case stColRel:
     763           0 :                 eState = bIsSep ? stColRelSep : ((eOpCode == ocClose) ? stClose : stError);
     764           0 :             break;
     765             :             case stColRelSep:
     766           0 :                 eState = lclGetAddress( rRefs.maRowFirstScPos, *aIt ) ? stRowFirst : stError;
     767           0 :                 rRefs.mbDblRefMode = true;
     768           0 :             break;
     769             :             case stRowFirst:
     770           0 :                 eState = bIsSep ? stRowFirstSep : stError;
     771           0 :             break;
     772             :             case stRowFirstSep:
     773           0 :                 eState = lclGetAddress( rRefs.maRowRelScPos, *aIt ) ? stRowRel : stError;
     774           0 :             break;
     775             :             case stRowRel:
     776           0 :                 eState = (eOpCode == ocClose) ? stClose : stError;
     777           0 :             break;
     778             :             default:
     779           0 :                 eState = stError;
     780             :         }
     781             :     }
     782           0 :     return eState == stClose;
     783           9 : }
     784             : 
     785             : // ============================================================================
     786             : 
     787             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10