1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "formula/formulahelper.hxx"
21 #include <unotools/charclass.hxx>
22 #include <unotools/syslocale.hxx>
29 //============================================================================
30 class OEmptyFunctionDescription
: public IFunctionDescription
33 OEmptyFunctionDescription(){}
34 virtual ~OEmptyFunctionDescription(){}
36 virtual OUString
getFunctionName() const { return OUString(); }
37 virtual const IFunctionCategory
* getCategory() const { return NULL
; }
38 virtual OUString
getDescription() const { return OUString(); }
39 virtual xub_StrLen
getSuppressedArgumentCount() const { return 0; }
40 virtual OUString
getFormula(const ::std::vector
< OUString
>& ) const { return OUString(); }
41 virtual void fillVisibleArgumentMapping(::std::vector
<sal_uInt16
>& ) const {}
42 virtual void initArgumentInfo() const {}
43 virtual OUString
getSignature() const { return OUString(); }
44 virtual OString
getHelpId() const { return ""; }
45 virtual sal_uInt32
getParameterCount() const { return 0; }
46 virtual OUString
getParameterName(sal_uInt32
) const { return OUString(); }
47 virtual OUString
getParameterDescription(sal_uInt32
) const { return OUString(); }
48 virtual bool isParameterOptional(sal_uInt32
) const { return sal_False
; }
51 //===================================================================
52 // class FormulaHelper - static Method
53 //===================================================================
55 #define FUNC_NOTFOUND 0xffff
57 FormulaHelper::FormulaHelper(const IFunctionManager
* _pFunctionManager
)
58 :m_pSysLocale(new SvtSysLocale
)
59 ,m_pFunctionManager(_pFunctionManager
)
60 ,open(_pFunctionManager
->getSingleToken(IFunctionManager::eOk
))
61 ,close(_pFunctionManager
->getSingleToken(IFunctionManager::eClose
))
62 ,sep(_pFunctionManager
->getSingleToken(IFunctionManager::eSep
))
63 ,arrayOpen(_pFunctionManager
->getSingleToken(IFunctionManager::eArrayOpen
))
64 ,arrayClose(_pFunctionManager
->getSingleToken(IFunctionManager::eArrayClose
))
66 m_pCharClass
= m_pSysLocale
->GetCharClassPtr();
68 sal_Bool
FormulaHelper::GetNextFunc( const String
& rFormula
,
70 xub_StrLen
& rFStart
, // Input and output
71 xub_StrLen
* pFEnd
, // = NULL
72 const IFunctionDescription
** ppFDesc
, // = NULL
73 ::std::vector
< OUString
>* pArgs
) const // = NULL
75 xub_StrLen nOldStart
= rFStart
;
78 rFStart
= GetFunctionStart( rFormula
, rFStart
, bBack
, ppFDesc
? &aFname
: NULL
);
79 sal_Bool bFound
= ( rFStart
!= FUNC_NOTFOUND
);
84 *pFEnd
= GetFunctionEnd( rFormula
, rFStart
);
89 const OUString
sTemp( aFname
);
90 const sal_uInt32 nCategoryCount
= m_pFunctionManager
->getCount();
91 for(sal_uInt32 j
= 0; j
< nCategoryCount
&& !*ppFDesc
; ++j
)
93 const IFunctionCategory
* pCategory
= m_pFunctionManager
->getCategory(j
);
94 const sal_uInt32 nCount
= pCategory
->getCount();
95 for(sal_uInt32 i
= 0 ; i
< nCount
; ++i
)
97 const IFunctionDescription
* pCurrent
= pCategory
->getFunction(i
);
98 if ( pCurrent
->getFunctionName().equalsIgnoreAsciiCase(sTemp
) )
103 }// for(sal_uInt32 i = 0 ; i < nCount; ++i)
105 if ( *ppFDesc
&& pArgs
)
107 GetArgStrings( *pArgs
,rFormula
, rFStart
, static_cast<sal_uInt16
>((*ppFDesc
)->getParameterCount() ));
111 static OEmptyFunctionDescription s_aFunctionDescription
;
112 *ppFDesc
= &s_aFunctionDescription
;
122 //------------------------------------------------------------------------
124 void FormulaHelper::FillArgStrings( const String
& rFormula
,
127 ::std::vector
< OUString
>& _rArgs
) const
129 xub_StrLen nStart
= 0;
132 sal_Bool bLast
= sal_False
;
134 for ( i
=0; i
<nArgs
&& !bLast
; i
++ )
136 nStart
= GetArgStart( rFormula
, nFuncPos
, i
);
138 if ( i
+1<nArgs
) // last argument?
140 nEnd
= GetArgStart( rFormula
, nFuncPos
, i
+1 );
142 if ( nEnd
!= nStart
)
143 _rArgs
.push_back(rFormula
.Copy( nStart
, nEnd
-1-nStart
));
145 _rArgs
.push_back(String()), bLast
= sal_True
;
149 nEnd
= GetFunctionEnd( rFormula
, nFuncPos
)-1;
151 _rArgs
.push_back( rFormula
.Copy( nStart
, nEnd
-nStart
) );
153 _rArgs
.push_back(String());
158 for ( ; i
<nArgs
; i
++ )
159 _rArgs
.push_back(String());
162 //------------------------------------------------------------------------
164 void FormulaHelper::GetArgStrings( ::std::vector
< OUString
>& _rArgs
165 ,const String
& rFormula
,
167 sal_uInt16 nArgs
) const
171 FillArgStrings( rFormula
, nFuncPos
, nArgs
, _rArgs
);
175 //------------------------------------------------------------------------
177 inline sal_Bool
IsFormulaText( const CharClass
* _pCharClass
,const String
& rStr
, xub_StrLen nPos
)
179 if( _pCharClass
->isLetterNumeric( rStr
, nPos
) )
182 { // In internationalized versions function names may contain a dot
183 // and in every version also an underscore... ;-)
184 sal_Unicode c
= rStr
.GetChar(nPos
);
185 return c
== '.' || c
== '_';
190 xub_StrLen
FormulaHelper::GetFunctionStart( const String
& rFormula
,
193 String
* pFuncName
) const
195 xub_StrLen nStrLen
= rFormula
.Len();
197 if ( nStrLen
< nStart
)
200 xub_StrLen nFStart
= FUNC_NOTFOUND
;
201 xub_StrLen nParPos
= nStart
;
203 sal_Bool bRepeat
, bFound
;
211 while ( !bFound
&& (nParPos
> 0) )
213 if ( rFormula
.GetChar(nParPos
) == '"' )
216 while ( (nParPos
> 0) && rFormula
.GetChar(nParPos
) != '"' )
221 else if ( (bFound
= ( rFormula
.GetChar(nParPos
) == '(' ) ) == sal_False
)
227 while ( !bFound
&& (nParPos
< nStrLen
) )
229 if ( rFormula
.GetChar(nParPos
) == '"' )
232 while ( (nParPos
< nStrLen
) && rFormula
.GetChar(nParPos
) != '"' )
236 else if ( (bFound
= ( rFormula
.GetChar(nParPos
) == '(' ) ) == sal_False
)
241 if ( bFound
&& (nParPos
> 0) )
245 while ( (nFStart
> 0) && IsFormulaText(m_pCharClass
, rFormula
, nFStart
))
253 if ( IsFormulaText( m_pCharClass
,rFormula
, nFStart
) )
257 *pFuncName
= rFormula
.Copy( nFStart
, nParPos
-nFStart
);
259 else // Brackets without function -> keep searching
264 else if (nParPos
> 0)
270 else // No brackets found
272 nFStart
= FUNC_NOTFOUND
;
282 //------------------------------------------------------------------------
284 xub_StrLen
FormulaHelper::GetFunctionEnd( const String
& rStr
, xub_StrLen nStart
) const
286 xub_StrLen nStrLen
= rStr
.Len();
288 if ( nStrLen
< nStart
)
292 bool bInArray
= false;
293 sal_Bool bFound
= sal_False
;
295 while ( !bFound
&& (nStart
< nStrLen
) )
297 sal_Unicode c
= rStr
.GetChar(nStart
);
302 while ( (nStart
< nStrLen
) && rStr
.GetChar(nStart
) != '"' )
305 else if ( c
== open
)
307 else if ( c
== close
)
310 if ( nParCount
== 0 )
312 else if ( nParCount
< 0 )
315 nStart
--; // read one too far
318 else if ( c
== arrayOpen
)
322 else if ( c
== arrayClose
)
328 if ( !bInArray
&& nParCount
== 0 )
331 nStart
--; // read one too far
334 nStart
++; // Set behind found position
340 //------------------------------------------------------------------
342 xub_StrLen
FormulaHelper::GetArgStart( const String
& rStr
, xub_StrLen nStart
, sal_uInt16 nArg
) const
344 xub_StrLen nStrLen
= rStr
.Len();
346 if ( nStrLen
< nStart
)
350 bool bInArray
= false;
351 sal_Bool bFound
= sal_False
;
353 while ( !bFound
&& (nStart
< nStrLen
) )
355 sal_Unicode c
= rStr
.GetChar(nStart
);
360 while ( (nStart
< nStrLen
) && rStr
.GetChar(nStart
) != '"' )
363 else if ( c
== open
)
365 bFound
= ( nArg
== 0 );
368 else if ( c
== close
)
371 bFound
= ( nParCount
== 0 );
373 else if ( c
== arrayOpen
)
377 else if ( c
== arrayClose
)
383 if ( !bInArray
&& nParCount
== 1 )
386 bFound
= ( nArg
== 0 );
394 // =============================================================================
396 // =============================================================================
398 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */