LCOV - code coverage report
Current view: top level - libreoffice/sc/source/core/data - funcdesc.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 187 469 39.9 %
Date: 2012-12-27 Functions: 26 50 52.0 %
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 "funcdesc.hxx"
      21             : 
      22             : #include "addincol.hxx"
      23             : #include "appoptio.hxx"
      24             : #include "callform.hxx"
      25             : #include "compiler.hxx"
      26             : #include "global.hxx"
      27             : #include "sc.hrc"
      28             : #include "scmod.hxx"
      29             : #include "scresid.hxx"
      30             : 
      31             : #include <rtl/ustring.hxx>
      32             : #include <rtl/ustrbuf.hxx>
      33             : #include <tools/rcid.h>
      34             : #include <tools/resid.hxx>
      35             : #include <unotools/collatorwrapper.hxx>
      36             : 
      37             : #include <numeric>
      38             : #include <boost/scoped_ptr.hpp>
      39             : 
      40         292 : class ScFuncRes : public Resource
      41             : {
      42             : public:
      43             :     ScFuncRes( ResId&, ScFuncDesc*, bool & rbSuppressed );
      44             : 
      45             : private:
      46             :     sal_uInt16 GetNum();
      47             : };
      48             : 
      49             : 
      50             : class ScResourcePublisher : public Resource
      51             : {
      52             : private:
      53          13 :     void FreeResource() { Resource::FreeResource(); }
      54             : public:
      55          13 :     ScResourcePublisher( const ScResId& rId ) : Resource( rId ) {}
      56          13 :     ~ScResourcePublisher() { FreeResource(); }
      57         812 :     bool IsAvailableRes( const ResId& rId ) const
      58         812 :                         { return Resource::IsAvailableRes( rId ); }
      59             : 
      60             : };
      61             : 
      62             : //========================================================================
      63             : // class ScFuncDesc:
      64             : //========================================================================
      65             : 
      66         292 : ScFuncDesc::ScFuncDesc() :
      67             :         pFuncName       (NULL),
      68             :         pFuncDesc       (NULL),
      69             :         ppDefArgNames   (NULL),
      70             :         ppDefArgDescs   (NULL),
      71             :         pDefArgFlags    (NULL),
      72             :         nFIndex         (0),
      73             :         nCategory       (0),
      74             :         nArgCount       (0),
      75             :         bIncomplete     (false),
      76         292 :         bHasSuppressedArgs(false)
      77         292 : {}
      78             : 
      79         876 : ScFuncDesc::~ScFuncDesc()
      80             : {
      81         292 :     Clear();
      82         584 : }
      83             : 
      84         292 : void ScFuncDesc::Clear()
      85             : {
      86         292 :     sal_uInt16 nArgs = nArgCount;
      87         292 :     if (nArgs >= PAIRED_VAR_ARGS)
      88           3 :         nArgs -= PAIRED_VAR_ARGS - 2;
      89         289 :     else if (nArgs >= VAR_ARGS)
      90          37 :         nArgs -= VAR_ARGS - 1;
      91         292 :     if (nArgs)
      92             :     {
      93         877 :         for (sal_uInt16 i=0; i<nArgs; i++ )
      94             :         {
      95         593 :             delete ppDefArgNames[i];
      96         593 :             delete ppDefArgDescs[i];
      97             :         }
      98         284 :         delete [] ppDefArgNames;
      99         284 :         delete [] ppDefArgDescs;
     100         284 :         delete [] pDefArgFlags;
     101             :     }
     102         292 :     nArgCount = 0;
     103         292 :     ppDefArgNames = NULL;
     104         292 :     ppDefArgDescs = NULL;
     105         292 :     pDefArgFlags = NULL;
     106             : 
     107         292 :     delete pFuncName;
     108         292 :     pFuncName = NULL;
     109             : 
     110         292 :     delete pFuncDesc;
     111         292 :     pFuncDesc = NULL;
     112             : 
     113         292 :     nFIndex = 0;
     114         292 :     nCategory = 0;
     115         292 :     sHelpId = rtl::OString();
     116         292 :     bIncomplete = false;
     117         292 :     bHasSuppressedArgs = false;
     118         292 : }
     119             : 
     120           0 : ::rtl::OUString ScFuncDesc::GetParamList() const
     121             : {
     122           0 :     ::rtl::OUString sep(ScCompiler::GetNativeSymbol(ocSep));
     123             : 
     124           0 :     ::rtl::OUStringBuffer aSig;
     125             : 
     126           0 :     if ( nArgCount > 0 )
     127             :     {
     128           0 :         if ( nArgCount < VAR_ARGS )
     129             :         {
     130           0 :             sal_uInt16 nLastSuppressed = nArgCount;
     131           0 :             sal_uInt16 nLastAdded = nArgCount;
     132           0 :             for ( sal_uInt16 i=0; i<nArgCount; i++ )
     133             :             {
     134           0 :                 if (pDefArgFlags[i].bSuppress)
     135           0 :                     nLastSuppressed = i;
     136             :                 else
     137             :                 {
     138           0 :                     nLastAdded = i;
     139           0 :                     aSig.append(*(ppDefArgNames[i]));
     140           0 :                     if ( i != nArgCount-1 )
     141             :                     {
     142           0 :                         aSig.append(sep);
     143           0 :                         aSig.appendAscii( " " );
     144             :                     }
     145             :                 }
     146             :             }
     147             :             // If only suppressed parameters follow the last added parameter,
     148             :             // remove one "; "
     149           0 :             if (nLastSuppressed < nArgCount && nLastAdded < nLastSuppressed &&
     150           0 :                     aSig.getLength() >= 2)
     151           0 :                 aSig.setLength(aSig.getLength() - 2);
     152             :         }
     153           0 :         else if ( nArgCount < PAIRED_VAR_ARGS)
     154             :         {
     155           0 :             sal_uInt16 nFix = nArgCount - VAR_ARGS;
     156           0 :             for ( sal_uInt16 nArg = 0; nArg < nFix; nArg++ )
     157             :             {
     158           0 :                 if (!pDefArgFlags[nArg].bSuppress)
     159             :                 {
     160           0 :                     aSig.append(*(ppDefArgNames[nArg]));
     161           0 :                     aSig.append(sep);
     162           0 :                     aSig.appendAscii( " " );
     163             :                 }
     164             :             }
     165             :             /* NOTE: Currently there are no suppressed var args parameters. If
     166             :              * there were, we'd have to cope with it here and above for the fix
     167             :              * parameters. For now parameters are always added, so no special
     168             :              * treatment of a trailing "; " necessary. */
     169           0 :             aSig.append(*(ppDefArgNames[nFix]));
     170           0 :             aSig.append(sal_Unicode('1'));
     171           0 :             aSig.append(sep);
     172           0 :             aSig.append(sal_Unicode(' '));
     173           0 :             aSig.append(*(ppDefArgNames[nFix]));
     174           0 :             aSig.append(sal_Unicode('2'));
     175           0 :             aSig.append(sep);
     176           0 :             aSig.appendAscii(" ... ");
     177             :         }
     178             :         else
     179             :         {
     180           0 :             sal_uInt16 nFix = nArgCount - PAIRED_VAR_ARGS;
     181           0 :             for ( sal_uInt16 nArg = 0; nArg < nFix; nArg++ )
     182             :             {
     183           0 :                 if (!pDefArgFlags[nArg].bSuppress)
     184             :                 {
     185           0 :                     aSig.append(*(ppDefArgNames[nArg]));
     186           0 :                     aSig.append(sep);
     187           0 :                     aSig.appendAscii( " " );
     188             :                 }
     189             :             }
     190             : 
     191           0 :             aSig.append(*(ppDefArgNames[nFix]));
     192           0 :             aSig.append(sal_Unicode('1'));
     193           0 :             aSig.appendAscii( ", " );
     194           0 :             aSig.append(*(ppDefArgNames[nFix+1]));
     195           0 :             aSig.append(sal_Unicode('1'));
     196           0 :             aSig.append(sep);
     197           0 :             aSig.appendAscii( " " );
     198           0 :             aSig.append(*(ppDefArgNames[nFix]));
     199           0 :             aSig.append(sal_Unicode('2'));
     200           0 :             aSig.appendAscii( ", " );
     201           0 :             aSig.append(*(ppDefArgNames[nFix+1]));
     202           0 :             aSig.append(sal_Unicode('2'));
     203           0 :             aSig.append(sep);
     204           0 :             aSig.appendAscii( " ... " );
     205             :         }
     206             :     }
     207             : 
     208           0 :     return aSig.makeStringAndClear();
     209             : }
     210             : 
     211           0 : ::rtl::OUString ScFuncDesc::getSignature() const
     212             : {
     213           0 :     ::rtl::OUStringBuffer aSig;
     214             : 
     215           0 :     if(pFuncName)
     216             :     {
     217           0 :         aSig.append(*pFuncName);
     218             : 
     219           0 :         ::rtl::OUString aParamList = GetParamList();
     220           0 :         if( !aParamList.isEmpty() )
     221             :         {
     222           0 :             aSig.appendAscii( "( " );
     223           0 :             aSig.append(aParamList);
     224             :             // U+00A0 (NBSP) prevents automatic line break
     225           0 :             aSig.append( static_cast< sal_Unicode >(0xA0) );
     226           0 :             aSig.appendAscii( ")" );
     227             :         }
     228             :         else
     229           0 :             aSig.appendAscii( "()" );
     230             :     }
     231           0 :     return aSig.makeStringAndClear();
     232             : }
     233             : 
     234           0 : ::rtl::OUString ScFuncDesc::getFormula( const ::std::vector< ::rtl::OUString >& _aArguments ) const
     235             : {
     236           0 :     ::rtl::OUString sep = ScCompiler::GetNativeSymbol(ocSep);
     237             : 
     238           0 :     ::rtl::OUStringBuffer aFormula;
     239             : 
     240           0 :     if(pFuncName)
     241             :     {
     242           0 :         aFormula.append( *pFuncName );
     243             : 
     244           0 :         aFormula.appendAscii( "(" );
     245           0 :         ::std::vector< ::rtl::OUString >::const_iterator aIter = _aArguments.begin();
     246           0 :         ::std::vector< ::rtl::OUString >::const_iterator aEnd = _aArguments.end();
     247             : 
     248           0 :         if ( nArgCount > 0 && aIter != aEnd )
     249             :         {
     250           0 :             bool bLastArg = aIter->isEmpty();
     251             : 
     252           0 :             while( aIter != aEnd && !bLastArg )
     253             :             {
     254           0 :                 aFormula.append( *(aIter) );
     255           0 :                 if ( aIter != (aEnd-1) )
     256             :                 {
     257           0 :                     bLastArg = (aIter+1)->isEmpty();
     258           0 :                     if ( !bLastArg )
     259           0 :                         aFormula.append( sep );
     260             :                 }
     261             : 
     262           0 :                 ++aIter;
     263             :             }
     264             :         }
     265             : 
     266           0 :         aFormula.appendAscii( ")" );
     267             :     }
     268           0 :     return aFormula.makeStringAndClear();
     269             : }
     270             : 
     271           0 : sal_uInt16 ScFuncDesc::GetSuppressedArgCount() const
     272             : {
     273           0 :     if (!bHasSuppressedArgs || !pDefArgFlags)
     274           0 :         return nArgCount;
     275             : 
     276           0 :     sal_uInt16 nArgs = nArgCount;
     277           0 :     if (nArgs >= PAIRED_VAR_ARGS)
     278           0 :         nArgs -= PAIRED_VAR_ARGS - 2;
     279           0 :     else if (nArgs >= VAR_ARGS)
     280           0 :         nArgs -= VAR_ARGS - 1;
     281           0 :     sal_uInt16 nCount = nArgs;
     282           0 :     for (sal_uInt16 i=0; i < nArgs; ++i)
     283             :     {
     284           0 :         if (pDefArgFlags[i].bSuppress)
     285           0 :             --nCount;
     286             :     }
     287           0 :     if (nArgCount >= PAIRED_VAR_ARGS)
     288           0 :         nCount += PAIRED_VAR_ARGS - 2;
     289           0 :     else if (nArgCount >= VAR_ARGS)
     290           0 :         nCount += VAR_ARGS - 1;
     291           0 :     return nCount;
     292             : }
     293             : 
     294         291 : ::rtl::OUString ScFuncDesc::getFunctionName() const
     295             : {
     296         291 :     ::rtl::OUString sRet;
     297         291 :     if ( pFuncName )
     298         291 :         sRet = *pFuncName;
     299         291 :     return sRet;
     300             : }
     301             : 
     302           0 : const formula::IFunctionCategory* ScFuncDesc::getCategory() const
     303             : {
     304           0 :     return ScGlobal::GetStarCalcFunctionMgr()->getCategory(nCategory);
     305             : }
     306             : 
     307           0 : ::rtl::OUString ScFuncDesc::getDescription() const
     308             : {
     309           0 :     ::rtl::OUString sRet;
     310           0 :     if ( pFuncDesc )
     311           0 :         sRet = *pFuncDesc;
     312           0 :     return sRet;
     313             : }
     314             : 
     315           0 : xub_StrLen ScFuncDesc::getSuppressedArgumentCount() const
     316             : {
     317           0 :     return GetSuppressedArgCount();
     318             : }
     319             : 
     320           0 : void ScFuncDesc::fillVisibleArgumentMapping(::std::vector<sal_uInt16>& _rArguments) const
     321             : {
     322           0 :     if (!bHasSuppressedArgs || !pDefArgFlags)
     323             :     {
     324           0 :         _rArguments.resize( nArgCount);
     325           0 :         ::std::vector<sal_uInt16>::iterator iter = _rArguments.begin();
     326           0 :         sal_uInt16 value = 0;
     327           0 :         while (iter != _rArguments.end())
     328           0 :             *iter++ = value++;
     329             :     }
     330             : 
     331           0 :     _rArguments.reserve( nArgCount);
     332           0 :     sal_uInt16 nArgs = nArgCount;
     333           0 :     if (nArgs >= PAIRED_VAR_ARGS)
     334           0 :         nArgs -= PAIRED_VAR_ARGS - 2;
     335           0 :     else if (nArgs >= VAR_ARGS)
     336           0 :         nArgs -= VAR_ARGS - 1;
     337           0 :     for (sal_uInt16 i=0; i < nArgs; ++i)
     338             :     {
     339           0 :         if (!pDefArgFlags[i].bSuppress)
     340           0 :             _rArguments.push_back(i);
     341             :     }
     342           0 : }
     343             : 
     344           0 : void ScFuncDesc::initArgumentInfo()  const
     345             : {
     346             :     // get the full argument description
     347             :     // (add-in has to be instantiated to get the type information)
     348             : 
     349           0 :     if ( bIncomplete && pFuncName )
     350             :     {
     351           0 :         ScUnoAddInCollection& rAddIns = *ScGlobal::GetAddInCollection();
     352           0 :         ::rtl::OUString aIntName(rAddIns.FindFunction( *pFuncName, true ));         // pFuncName is upper-case
     353             : 
     354           0 :         if ( !aIntName.isEmpty() )
     355             :         {
     356             :             // GetFuncData with bComplete=true loads the component and updates
     357             :             // the global function list if needed.
     358             : 
     359           0 :             rAddIns.GetFuncData( aIntName, true );
     360             :         }
     361             : 
     362           0 :         if ( bIncomplete )
     363             :         {
     364             :             OSL_FAIL( "couldn't initialize add-in function" );
     365           0 :             const_cast<ScFuncDesc*>(this)->bIncomplete = false;         // even if there was an error, don't try again
     366           0 :         }
     367             :     }
     368           0 : }
     369             : 
     370           0 : ::rtl::OString ScFuncDesc::getHelpId() const
     371             : {
     372           0 :     return sHelpId;
     373             : }
     374             : 
     375           0 : sal_uInt32 ScFuncDesc::getParameterCount() const
     376             : {
     377           0 :     return nArgCount;
     378             : }
     379             : 
     380           0 : ::rtl::OUString ScFuncDesc::getParameterName(sal_uInt32 _nPos) const
     381             : {
     382           0 :     return *(ppDefArgNames[_nPos]);
     383             : }
     384             : 
     385           0 : ::rtl::OUString ScFuncDesc::getParameterDescription(sal_uInt32 _nPos) const
     386             : {
     387           0 :     return *(ppDefArgDescs[_nPos]);
     388             : }
     389             : 
     390           0 : bool ScFuncDesc::isParameterOptional(sal_uInt32 _nPos) const
     391             : {
     392           0 :     return pDefArgFlags[_nPos].bOptional;
     393             : }
     394             : 
     395        2986 : bool ScFuncDesc::compareByName(const ScFuncDesc* a, const ScFuncDesc* b)
     396             : {
     397        2986 :     return (ScGlobal::GetCaseCollator()->compareString(*a->pFuncName, *b->pFuncName ) == COMPARE_LESS);
     398             : }
     399             : 
     400             : //===================================================================
     401             : // class ScFunctionList:
     402             : //===================================================================
     403             : 
     404           1 : ScFunctionList::ScFunctionList() :
     405           1 :         nMaxFuncNameLen ( 0 )
     406             : {
     407           1 :     ScFuncDesc* pDesc = NULL;
     408           1 :     xub_StrLen nStrLen = 0;
     409           1 :     ::std::list<ScFuncDesc*> tmpFuncList;
     410             :     sal_uInt16 nDescBlock[] =
     411             :     {
     412             :         RID_SC_FUNCTION_DESCRIPTIONS1,
     413             :         RID_SC_FUNCTION_DESCRIPTIONS2
     414           1 :     };
     415             : 
     416           3 :     for (sal_uInt16 k = 0; k < SAL_N_ELEMENTS(nDescBlock); ++k)
     417             :     {
     418             :         SAL_WNODEPRECATED_DECLARATIONS_PUSH
     419           2 :         ::std::auto_ptr<ScResourcePublisher> pBlock( new ScResourcePublisher( ScResId( nDescBlock[k] ) ) );
     420             :         SAL_WNODEPRECATED_DECLARATIONS_POP
     421             :         // Browse for all possible OpCodes. This is not the fastest method, but
     422             :         // otherwise the sub resources within the resource blocks and the
     423             :         // resource blocks themselfs would had to be ordered according to
     424             :         // OpCodes, which is utopian..
     425         814 :         for (sal_uInt16 i = 0; i <= SC_OPCODE_LAST_OPCODE_ID; ++i)
     426             :         {
     427         812 :             ScResId aRes(i);
     428         812 :             aRes.SetRT(RSC_RESOURCE);
     429             :             // Sub resource of OpCode available?
     430         812 :             if (pBlock->IsAvailableRes(aRes))
     431             :             {
     432         292 :                 pDesc = new ScFuncDesc;
     433         292 :                 bool bSuppressed = false;
     434         292 :                 ScFuncRes aSubRes( aRes, pDesc, bSuppressed);
     435             :                 // Instead of dealing with this exceptional case at 1001 places
     436             :                 // we simply don't add an entirely suppressed function to the
     437             :                 // list and delete it.
     438         292 :                 if (bSuppressed)
     439           1 :                     delete pDesc;
     440             :                 else
     441             :                 {
     442         291 :                     pDesc->nFIndex = i;
     443         291 :                     tmpFuncList.push_back(pDesc);
     444             : 
     445         291 :                     nStrLen = (*(pDesc->pFuncName)).getLength();
     446         291 :                     if (nStrLen > nMaxFuncNameLen)
     447           8 :                         nMaxFuncNameLen = nStrLen;
     448         292 :                 }
     449             :             }
     450             :         }
     451           2 :     }
     452             : 
     453           1 :     sal_uInt16 nNextId = SC_OPCODE_LAST_OPCODE_ID + 1; // FuncID for AddIn functions
     454             : 
     455             :     // Interpretation of AddIn list
     456           1 :     ::rtl::OUString aDefArgNameValue   = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("value"));
     457           1 :     ::rtl::OUString aDefArgNameString  = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("string"));
     458           1 :     ::rtl::OUString aDefArgNameValues  = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("values"));
     459           1 :     ::rtl::OUString aDefArgNameStrings = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("strings"));
     460           1 :     ::rtl::OUString aDefArgNameCells   = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cells"));
     461           1 :     ::rtl::OUString aDefArgNameNone    = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("none"));
     462           1 :     ::rtl::OUString aDefArgDescValue   = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("a value"));
     463           1 :     ::rtl::OUString aDefArgDescString  = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("a string"));
     464           1 :     ::rtl::OUString aDefArgDescValues  = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("array of values"));
     465           1 :     ::rtl::OUString aDefArgDescStrings = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("array of strings"));
     466           1 :     ::rtl::OUString aDefArgDescCells   = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("range of cells"));
     467           1 :     ::rtl::OUString aDefArgDescNone    = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("none"));
     468             : 
     469           1 :     ::rtl::OUString aArgName, aArgDesc;
     470           1 :     const FuncCollection& rFuncColl = *ScGlobal::GetFuncCollection();
     471           1 :     FuncCollection::const_iterator it = rFuncColl.begin(), itEnd = rFuncColl.end();
     472           1 :     for (; it != itEnd; ++it)
     473             :     {
     474           0 :         const FuncData* pAddInFuncData = it->second;
     475           0 :         pDesc = new ScFuncDesc;
     476           0 :         sal_uInt16 nArgs = pAddInFuncData->GetParamCount() - 1;
     477           0 :         pAddInFuncData->getParamDesc( aArgName, aArgDesc, 0 );
     478           0 :         pDesc->nFIndex     = nNextId++; //  ??? OpCode vergeben
     479           0 :         pDesc->nCategory   = ID_FUNCTION_GRP_ADDINS;
     480           0 :         pDesc->pFuncName   = new OUString(pAddInFuncData->GetInternalName().toAsciiUpperCase());
     481             : 
     482           0 :         ::rtl::OUStringBuffer aBuf(aArgDesc);
     483           0 :         aBuf.append(sal_Unicode('\n'));
     484           0 :         aBuf.appendAscii("( AddIn: ");
     485           0 :         aBuf.append(pAddInFuncData->GetModuleName());
     486           0 :         aBuf.appendAscii(" )");
     487           0 :         pDesc->pFuncDesc = new ::rtl::OUString(aBuf.makeStringAndClear());
     488             : 
     489           0 :         pDesc->nArgCount   = nArgs;
     490           0 :         if (nArgs)
     491             :         {
     492           0 :             pDesc->pDefArgFlags  = new ScFuncDesc::ParameterFlags[nArgs];
     493           0 :             pDesc->ppDefArgNames = new ::rtl::OUString*[nArgs];
     494           0 :             pDesc->ppDefArgDescs = new ::rtl::OUString*[nArgs];
     495           0 :             for (sal_uInt16 j = 0; j < nArgs; ++j)
     496             :             {
     497           0 :                 pDesc->pDefArgFlags[j].bOptional = false;
     498           0 :                 pDesc->pDefArgFlags[j].bSuppress = false;
     499           0 :                 pAddInFuncData->getParamDesc( aArgName, aArgDesc, j+1 );
     500           0 :                 if ( !aArgName.isEmpty() )
     501           0 :                     pDesc->ppDefArgNames[j] = new ::rtl::OUString( aArgName );
     502             :                 else
     503             :                 {
     504           0 :                     switch (pAddInFuncData->GetParamType(j+1))
     505             :                     {
     506             :                         case PTR_DOUBLE:
     507           0 :                             pDesc->ppDefArgNames[j] = new ::rtl::OUString( aDefArgNameValue );
     508           0 :                             break;
     509             :                         case PTR_STRING:
     510           0 :                             pDesc->ppDefArgNames[j] = new ::rtl::OUString( aDefArgNameString );
     511           0 :                             break;
     512             :                         case PTR_DOUBLE_ARR:
     513           0 :                             pDesc->ppDefArgNames[j] = new ::rtl::OUString( aDefArgNameValues );
     514           0 :                             break;
     515             :                         case PTR_STRING_ARR:
     516           0 :                             pDesc->ppDefArgNames[j] = new ::rtl::OUString( aDefArgNameStrings );
     517           0 :                             break;
     518             :                         case PTR_CELL_ARR:
     519           0 :                             pDesc->ppDefArgNames[j] = new ::rtl::OUString( aDefArgNameCells );
     520           0 :                             break;
     521             :                         default:
     522           0 :                             pDesc->ppDefArgNames[j] = new ::rtl::OUString( aDefArgNameNone );
     523           0 :                             break;
     524             :                     }
     525             :                 }
     526           0 :                 if ( !aArgDesc.isEmpty() )
     527           0 :                     pDesc->ppDefArgDescs[j] = new ::rtl::OUString( aArgDesc );
     528             :                 else
     529             :                 {
     530           0 :                     switch (pAddInFuncData->GetParamType(j+1))
     531             :                     {
     532             :                         case PTR_DOUBLE:
     533           0 :                             pDesc->ppDefArgDescs[j] = new ::rtl::OUString( aDefArgDescValue );
     534           0 :                             break;
     535             :                         case PTR_STRING:
     536           0 :                             pDesc->ppDefArgDescs[j] = new ::rtl::OUString( aDefArgDescString );
     537           0 :                             break;
     538             :                         case PTR_DOUBLE_ARR:
     539           0 :                             pDesc->ppDefArgDescs[j] = new ::rtl::OUString( aDefArgDescValues );
     540           0 :                             break;
     541             :                         case PTR_STRING_ARR:
     542           0 :                             pDesc->ppDefArgDescs[j] = new ::rtl::OUString( aDefArgDescStrings );
     543           0 :                             break;
     544             :                         case PTR_CELL_ARR:
     545           0 :                             pDesc->ppDefArgDescs[j] = new ::rtl::OUString( aDefArgDescCells );
     546           0 :                             break;
     547             :                         default:
     548           0 :                             pDesc->ppDefArgDescs[j] = new ::rtl::OUString( aDefArgDescNone );
     549           0 :                             break;
     550             :                     }
     551             :                 }
     552             :             }
     553             :         }
     554             : 
     555           0 :         tmpFuncList.push_back(pDesc);
     556           0 :         nStrLen = (*(pDesc->pFuncName)).getLength();
     557           0 :         if ( nStrLen > nMaxFuncNameLen)
     558           0 :             nMaxFuncNameLen = nStrLen;
     559           0 :     }
     560             : 
     561             :     // StarOne AddIns
     562             : 
     563           1 :     ScUnoAddInCollection* pUnoAddIns = ScGlobal::GetAddInCollection();
     564           1 :     long nUnoCount = pUnoAddIns->GetFuncCount();
     565           1 :     for (long nFunc=0; nFunc<nUnoCount; nFunc++)
     566             :     {
     567           0 :         pDesc = new ScFuncDesc;
     568           0 :         pDesc->nFIndex = nNextId++;
     569             : 
     570           0 :         if ( pUnoAddIns->FillFunctionDesc( nFunc, *pDesc ) )
     571             :         {
     572           0 :             tmpFuncList.push_back(pDesc);
     573           0 :             nStrLen = (*(pDesc->pFuncName)).getLength();
     574           0 :             if (nStrLen > nMaxFuncNameLen)
     575           0 :                 nMaxFuncNameLen = nStrLen;
     576             :         }
     577             :         else
     578           0 :             delete pDesc;
     579             :     }
     580             : 
     581             :     //Move list to vector for better random access performance
     582           1 :     ::std::vector<const ScFuncDesc*> tmp(tmpFuncList.begin(), tmpFuncList.end());
     583           1 :     tmpFuncList.clear();
     584           1 :     aFunctionList.swap(tmp);
     585             : 
     586             :     //Initialize iterator
     587           1 :     aFunctionListIter = aFunctionList.end();
     588           1 : }
     589             : 
     590           2 : ScFunctionList::~ScFunctionList()
     591             : {
     592           1 :     const ScFuncDesc* pDesc = First();
     593         293 :     while (pDesc)
     594             :     {
     595         291 :         delete pDesc;
     596         291 :         pDesc = Next();
     597             :     }
     598           1 : }
     599             : 
     600           2 : const ScFuncDesc* ScFunctionList::First()
     601             : {
     602           2 :     const ScFuncDesc* pDesc = NULL;
     603           2 :     aFunctionListIter = aFunctionList.begin();
     604           2 :     if(aFunctionListIter != aFunctionList.end())
     605           2 :         pDesc = *aFunctionListIter;
     606             : 
     607           2 :     return pDesc;
     608             : }
     609             : 
     610         582 : const ScFuncDesc* ScFunctionList::Next()
     611             : {
     612         582 :     const ScFuncDesc* pDesc = NULL;
     613         582 :     if(aFunctionListIter != aFunctionList.end())
     614             :     {
     615         582 :         if((++aFunctionListIter) != aFunctionList.end())
     616         580 :             pDesc = *aFunctionListIter;
     617             :     }
     618         582 :     return pDesc;
     619             : }
     620             : 
     621           0 : const ScFuncDesc* ScFunctionList::GetFunction( sal_uInt32 nIndex ) const
     622             : {
     623           0 :     const ScFuncDesc* pDesc = NULL;
     624           0 :     if(nIndex < aFunctionList.size())
     625           0 :         pDesc = aFunctionList.at(nIndex);
     626             : 
     627           0 :     return pDesc;
     628             : }
     629             : 
     630             : //===================================================================
     631             : // class ScFunctionCategory:
     632             : //===================================================================
     633             : 
     634          11 : sal_uInt32 ScFunctionCategory::getCount() const
     635             : {
     636          11 :     return m_pCategory->size();
     637             : }
     638             : 
     639           0 : const formula::IFunctionManager* ScFunctionCategory::getFunctionManager() const
     640             : {
     641           0 :     return m_pMgr;
     642             : }
     643             : 
     644          11 : ::rtl::OUString ScFunctionCategory::getName() const
     645             : {
     646          11 :     if ( m_sName.isEmpty() )
     647          11 :         m_sName = ScFunctionMgr::GetCategoryName(m_nCategory+1);
     648          11 :     return m_sName;
     649             : }
     650             : 
     651         291 : const formula::IFunctionDescription* ScFunctionCategory::getFunction(sal_uInt32 _nPos) const
     652             : {
     653         291 :     const ScFuncDesc* pDesc = NULL;
     654         291 :     if(_nPos < m_pCategory->size())
     655         291 :         pDesc = m_pCategory->at(_nPos);
     656         291 :     return pDesc;
     657             : }
     658             : 
     659           0 : sal_uInt32 ScFunctionCategory::getNumber() const
     660             : {
     661           0 :     return m_nCategory;
     662             : }
     663             : 
     664             : //========================================================================
     665             : // class ScFunctionMgr:
     666             : //========================================================================
     667             : 
     668           1 : ScFunctionMgr::ScFunctionMgr() :
     669           1 :     pFuncList( ScGlobal::GetStarCalcFunctionList() )
     670             : {
     671             :     OSL_ENSURE( pFuncList, "Functionlist not found." );
     672           1 :     sal_uInt32 catCount[MAX_FUNCCAT] = {0};
     673             : 
     674           1 :     aCatLists[0] = new ::std::vector<const ScFuncDesc*>();
     675           1 :     aCatLists[0]->reserve(pFuncList->GetCount());
     676             : 
     677             :     // Retrieve all functions, store in cumulative ("All") category, and count
     678             :     // number of functions in each category
     679         292 :     for(const ScFuncDesc* pDesc = pFuncList->First(); pDesc; pDesc = pFuncList->Next())
     680             :     {
     681             :         OSL_ENSURE((pDesc->nCategory) < MAX_FUNCCAT, "Unknown category");
     682         291 :         if ((pDesc->nCategory) < MAX_FUNCCAT)
     683         291 :             ++catCount[pDesc->nCategory];
     684         291 :         aCatLists[0]->push_back(pDesc);
     685             :     }
     686             : 
     687             :     // Sort functions in cumulative category by name
     688           1 :     ::std::sort(aCatLists[0]->begin(), aCatLists[0]->end(), ScFuncDesc::compareByName);
     689             : 
     690             :     // Allocate correct amount of space for categories
     691          12 :     for (sal_uInt16 i = 1; i < MAX_FUNCCAT; ++i)
     692             :     {
     693          11 :         aCatLists[i] = new ::std::vector<const ScFuncDesc*>();
     694          11 :         aCatLists[i]->reserve(catCount[i]);
     695             :     }
     696             : 
     697             :     // Fill categories with the corresponding functions (still sorted by name)
     698         292 :     for(::std::vector<const ScFuncDesc*>::iterator iter = aCatLists[0]->begin(); iter!=aCatLists[0]->end(); ++iter)
     699             :     {
     700         291 :         if (((*iter)->nCategory) < MAX_FUNCCAT)
     701         291 :             aCatLists[(*iter)->nCategory]->push_back(*iter);
     702             :     }
     703             : 
     704             :     // Initialize iterators
     705           1 :     pCurCatListIter = aCatLists[0]->end();
     706           1 :     pCurCatListEnd = aCatLists[0]->end();
     707           1 : }
     708             : 
     709           3 : ScFunctionMgr::~ScFunctionMgr()
     710             : {
     711          13 :     for (sal_uInt16 i = 0; i < MAX_FUNCCAT; ++i)
     712          12 :         delete aCatLists[i];
     713           2 : }
     714             : 
     715           0 : const ScFuncDesc* ScFunctionMgr::Get( const ::rtl::OUString& rFName ) const
     716             : {
     717           0 :     const ScFuncDesc* pDesc = NULL;
     718           0 :     if (rFName.getLength() <= pFuncList->GetMaxFuncNameLen())
     719             :     {
     720           0 :         ::boost::scoped_ptr<ScFuncDesc> dummy(new ScFuncDesc);
     721           0 :         dummy->pFuncName = new ::rtl::OUString(rFName);
     722             :         ::std::vector<const ScFuncDesc*>::iterator lower =
     723           0 :             ::std::lower_bound(aCatLists[0]->begin(), aCatLists[0]->end(),
     724           0 :                         static_cast<const ScFuncDesc*>(dummy.get()), ScFuncDesc::compareByName);
     725             : 
     726           0 :         if(rFName.equalsIgnoreAsciiCase(*(*lower)->pFuncName))
     727           0 :             pDesc = *lower;
     728             :     }
     729           0 :     return pDesc;
     730             : }
     731             : 
     732           0 : const ScFuncDesc* ScFunctionMgr::Get( sal_uInt16 nFIndex ) const
     733             : {
     734             :     const ScFuncDesc* pDesc;
     735           0 :     for (pDesc = First(0); pDesc; pDesc = Next())
     736           0 :         if (pDesc->nFIndex == nFIndex)
     737           0 :             break;
     738           0 :     return pDesc;
     739             : }
     740             : 
     741           0 : const ScFuncDesc* ScFunctionMgr::First( sal_uInt16 nCategory ) const
     742             : {
     743             :     OSL_ENSURE( nCategory < MAX_FUNCCAT, "Unbekannte Kategorie" );
     744           0 :     const ScFuncDesc* pDesc = NULL;
     745           0 :     if ( nCategory < MAX_FUNCCAT )
     746             :     {
     747           0 :         pCurCatListIter = aCatLists[nCategory]->begin();
     748           0 :         pCurCatListEnd = aCatLists[nCategory]->end();
     749           0 :         pDesc = *pCurCatListIter;
     750             :     }
     751             :     else
     752             :     {
     753           0 :         pCurCatListIter = aCatLists[0]->end();
     754           0 :         pCurCatListEnd = aCatLists[0]->end();
     755             :     }
     756           0 :     return pDesc;
     757             : }
     758             : 
     759           0 : const ScFuncDesc* ScFunctionMgr::Next() const
     760             : {
     761           0 :     const ScFuncDesc* pDesc = NULL;
     762           0 :     if ( pCurCatListIter != pCurCatListEnd )
     763             :     {
     764           0 :         if ( (++pCurCatListIter) != pCurCatListEnd )
     765             :         {
     766           0 :             pDesc = *pCurCatListIter;
     767             :         }
     768             :     }
     769           0 :     return pDesc;
     770             : }
     771             : 
     772           1 : sal_uInt32 ScFunctionMgr::getCount() const
     773             : {
     774           1 :     return MAX_FUNCCAT - 1;
     775             : }
     776             : 
     777          11 : const formula::IFunctionCategory* ScFunctionMgr::getCategory(sal_uInt32 nCategory) const
     778             : {
     779          11 :     formula::IFunctionCategory* pRet = NULL;
     780          11 :     if ( nCategory < (MAX_FUNCCAT-1) )
     781             :     {
     782          11 :          pRet = new ScFunctionCategory(const_cast<ScFunctionMgr*>(this),aCatLists[nCategory+1],nCategory); // aCatLists[0] is "all"
     783             :     }
     784          11 :     return pRet;
     785             : }
     786             : 
     787           0 : const formula::IFunctionDescription* ScFunctionMgr::getFunctionByName(const ::rtl::OUString& _sFunctionName) const
     788             : {
     789           0 :     return Get(_sFunctionName);
     790             : }
     791             : 
     792           0 : void ScFunctionMgr::fillLastRecentlyUsedFunctions(::std::vector< const formula::IFunctionDescription*>& _rLastRUFunctions) const
     793             : {
     794           0 :     const ScAppOptions& rAppOpt = SC_MOD()->GetAppOptions();
     795           0 :     sal_uInt16 nLRUFuncCount = Min( rAppOpt.GetLRUFuncListCount(), (sal_uInt16)LRU_MAX );
     796           0 :     sal_uInt16* pLRUListIds = rAppOpt.GetLRUFuncList();
     797             : 
     798           0 :     if ( pLRUListIds )
     799             :     {
     800           0 :         for (sal_uInt16 i = 0; i < nLRUFuncCount; ++i)
     801           0 :             _rLastRUFunctions.push_back( Get( pLRUListIds[i] ) );
     802             :     }
     803           0 : }
     804             : 
     805          11 : ::rtl::OUString ScFunctionMgr::GetCategoryName(sal_uInt32 _nCategoryNumber )
     806             : {
     807          11 :     if ( _nCategoryNumber > SC_FUNCGROUP_COUNT )
     808             :     {
     809             :         OSL_FAIL("Invalid category number!");
     810           0 :         return ::rtl::OUString();
     811             :     }
     812             : 
     813             :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
     814          11 :     ::std::auto_ptr<ScResourcePublisher> pCategories( new ScResourcePublisher( ScResId( RID_FUNCTION_CATEGORIES ) ) );
     815             :     SAL_WNODEPRECATED_DECLARATIONS_POP
     816          11 :     return SC_RESSTR(static_cast<sal_uInt16>(_nCategoryNumber));
     817             : }
     818             : 
     819           0 : sal_Unicode ScFunctionMgr::getSingleToken(const formula::IFunctionManager::EToken _eToken) const
     820             : {
     821           0 :     switch(_eToken)
     822             :     {
     823             :         case eOk:
     824           0 :             return ScCompiler::GetNativeSymbol(ocOpen).GetChar(0);
     825             :         case eClose:
     826           0 :             return ScCompiler::GetNativeSymbol(ocClose).GetChar(0);
     827             :         case eSep:
     828           0 :             return ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
     829             :         case eArrayOpen:
     830           0 :             return ScCompiler::GetNativeSymbol(ocArrayOpen).GetChar(0);
     831             :         case eArrayClose:
     832           0 :             return ScCompiler::GetNativeSymbol(ocArrayClose).GetChar(0);
     833             :     }
     834           0 :     return 0;
     835             : }
     836             : 
     837             : //========================================================================
     838             : // class ScFuncRes:
     839             : //========================================================================
     840             : 
     841         292 : ScFuncRes::ScFuncRes( ResId &aRes, ScFuncDesc* pDesc, bool & rbSuppressed )
     842         292 :  : Resource(aRes)
     843             : {
     844         292 :     rbSuppressed = (bool)GetNum();
     845         292 :     pDesc->nCategory = GetNum();
     846         292 :     pDesc->sHelpId = ReadByteStringRes();
     847         292 :     pDesc->nArgCount = GetNum();
     848         292 :     sal_uInt16 nArgs = pDesc->nArgCount;
     849         292 :     if (nArgs >= PAIRED_VAR_ARGS)
     850           3 :         nArgs -= PAIRED_VAR_ARGS - 2;
     851         289 :     else if (nArgs >= VAR_ARGS)
     852          37 :         nArgs -= VAR_ARGS - 1;
     853         292 :     if (nArgs)
     854             :     {
     855         284 :         pDesc->pDefArgFlags = new ScFuncDesc::ParameterFlags[nArgs];
     856         877 :         for (sal_uInt16 i = 0; i < nArgs; ++i)
     857             :         {
     858         593 :             pDesc->pDefArgFlags[i].bOptional = (bool)GetNum();
     859             :         }
     860             :     }
     861             :     // Need to read the value from the resource even if nArgs==0 to advance the
     862             :     // resource position pointer, so this can't be in the if(nArgs) block above.
     863         292 :     sal_uInt16 nSuppressed = GetNum();
     864         292 :     if (nSuppressed)
     865             :     {
     866           0 :         if (nSuppressed > nArgs)
     867             :         {
     868             :             OSL_TRACE( "ScFuncRes: suppressed parameters count mismatch on OpCode %u: suppressed %d > params %d",
     869             :                     aRes.GetId(), (int)nSuppressed, (int)nArgs);
     870           0 :             nSuppressed = nArgs;    // sanitize
     871             :         }
     872           0 :         for (sal_uInt16 i = 0; i < nSuppressed; ++i)
     873             :         {
     874           0 :             sal_uInt16 nParam = GetNum();
     875           0 :             if (nParam < nArgs)
     876             :             {
     877           0 :                 if (pDesc->nArgCount >= PAIRED_VAR_ARGS && nParam >= nArgs-2)
     878             :                 {
     879           0 :                     OSL_TRACE( "ScFuncRes: PAIRED_VAR_ARGS parameters can't be suppressed, on OpCode %u: param %d >= arg %d-2",
     880             :                             aRes.GetId(), (int)nParam, (int)nArgs);
     881             :                 }
     882           0 :                 else if (pDesc->nArgCount >= VAR_ARGS && nParam == nArgs-1)
     883             :                 {
     884           0 :                     OSL_TRACE( "ScFuncRes: VAR_ARGS parameters can't be suppressed, on OpCode %u: param %d == arg %d-1",
     885             :                             aRes.GetId(), (int)nParam, (int)nArgs);
     886             :                 }
     887             :                 else
     888             :                 {
     889           0 :                     pDesc->pDefArgFlags[nParam].bSuppress = true;
     890           0 :                     pDesc->bHasSuppressedArgs = true;
     891             :                 }
     892             :             }
     893             :             else
     894             :             {
     895             :                 OSL_TRACE( "ScFuncRes: suppressed parameter exceeds count on OpCode %u: param %d >= args %d",
     896             :                         aRes.GetId(), (int)nParam, (int)nArgs);
     897             :             }
     898             :         }
     899             :     }
     900             : 
     901         292 :     pDesc->pFuncName = new ::rtl::OUString( ScCompiler::GetNativeSymbol( static_cast<OpCode>( aRes.GetId())));
     902         292 :     pDesc->pFuncDesc = new ::rtl::OUString( SC_RESSTR(1) );
     903             : 
     904         292 :     if (nArgs)
     905             :     {
     906         284 :         pDesc->ppDefArgNames = new ::rtl::OUString*[nArgs];
     907         284 :         pDesc->ppDefArgDescs = new ::rtl::OUString*[nArgs];
     908         877 :         for (sal_uInt16 i = 0; i < nArgs; ++i)
     909             :         {
     910         593 :             pDesc->ppDefArgNames[i] = new ::rtl::OUString(SC_RESSTR(2*(i+1)  ));
     911         593 :             pDesc->ppDefArgDescs[i] = new ::rtl::OUString(SC_RESSTR(2*(i+1)+1));
     912             :         }
     913             :     }
     914             : 
     915         292 :     FreeResource();
     916         292 : }
     917             : 
     918        1761 : sal_uInt16 ScFuncRes::GetNum()
     919             : {
     920        1761 :     return ReadShortRes();
     921             : }
     922             : 
     923             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10