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 ::rtl::OUString
getFunctionName() const { return ::rtl::OUString(); }
37 virtual const IFunctionCategory
* getCategory() const { return NULL
; }
38 virtual ::rtl::OUString
getDescription() const { return ::rtl::OUString(); }
39 virtual xub_StrLen
getSuppressedArgumentCount() const { return 0; }
40 virtual ::rtl::OUString
getFormula(const ::std::vector
< ::rtl::OUString
>& ) const { return ::rtl::OUString(); }
41 virtual void fillVisibleArgumentMapping(::std::vector
<sal_uInt16
>& ) const {}
42 virtual void initArgumentInfo() const {}
43 virtual ::rtl::OUString
getSignature() const { return ::rtl::OUString(); }
44 virtual rtl::OString
getHelpId() const { return ""; }
45 virtual sal_uInt32
getParameterCount() const { return 0; }
46 virtual ::rtl::OUString
getParameterName(sal_uInt32
) const { return ::rtl::OUString(); }
47 virtual ::rtl::OUString
getParameterDescription(sal_uInt32
) const { return ::rtl::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
< ::rtl::OUString
>* pArgs
) const // = NULL
75 sal_Bool bFound
= sal_False
;
76 xub_StrLen nOldStart
= rFStart
;
79 rFStart
= GetFunctionStart( rFormula
, rFStart
, bBack
, ppFDesc
? &aFname
: NULL
);
80 bFound
= ( rFStart
!= FUNC_NOTFOUND
);
85 *pFEnd
= GetFunctionEnd( rFormula
, rFStart
);
90 const ::rtl::OUString
sTemp( aFname
);
91 const sal_uInt32 nCategoryCount
= m_pFunctionManager
->getCount();
92 for(sal_uInt32 j
= 0; j
< nCategoryCount
&& !*ppFDesc
; ++j
)
94 const IFunctionCategory
* pCategory
= m_pFunctionManager
->getCategory(j
);
95 const sal_uInt32 nCount
= pCategory
->getCount();
96 for(sal_uInt32 i
= 0 ; i
< nCount
; ++i
)
98 const IFunctionDescription
* pCurrent
= pCategory
->getFunction(i
);
99 if ( pCurrent
->getFunctionName().equalsIgnoreAsciiCase(sTemp
) )
104 }// for(sal_uInt32 i = 0 ; i < nCount; ++i)
106 if ( *ppFDesc
&& pArgs
)
108 GetArgStrings( *pArgs
,rFormula
, rFStart
, static_cast<sal_uInt16
>((*ppFDesc
)->getParameterCount() ));
112 static OEmptyFunctionDescription s_aFunctionDescription
;
113 *ppFDesc
= &s_aFunctionDescription
;
123 //------------------------------------------------------------------------
125 void FormulaHelper::FillArgStrings( const String
& rFormula
,
128 ::std::vector
< ::rtl::OUString
>& _rArgs
) const
130 xub_StrLen nStart
= 0;
133 sal_Bool bLast
= sal_False
;
135 for ( i
=0; i
<nArgs
&& !bLast
; i
++ )
137 nStart
= GetArgStart( rFormula
, nFuncPos
, i
);
139 if ( i
+1<nArgs
) // last argument?
141 nEnd
= GetArgStart( rFormula
, nFuncPos
, i
+1 );
143 if ( nEnd
!= nStart
)
144 _rArgs
.push_back(rFormula
.Copy( nStart
, nEnd
-1-nStart
));
146 _rArgs
.push_back(String()), bLast
= sal_True
;
150 nEnd
= GetFunctionEnd( rFormula
, nFuncPos
)-1;
152 _rArgs
.push_back( rFormula
.Copy( nStart
, nEnd
-nStart
) );
154 _rArgs
.push_back(String());
159 for ( ; i
<nArgs
; i
++ )
160 _rArgs
.push_back(String());
163 //------------------------------------------------------------------------
165 void FormulaHelper::GetArgStrings( ::std::vector
< ::rtl::OUString
>& _rArgs
166 ,const String
& rFormula
,
168 sal_uInt16 nArgs
) const
172 FillArgStrings( rFormula
, nFuncPos
, nArgs
, _rArgs
);
176 //------------------------------------------------------------------------
178 inline sal_Bool
IsFormulaText( const CharClass
* _pCharClass
,const String
& rStr
, xub_StrLen nPos
)
180 if( _pCharClass
->isLetterNumeric( rStr
, nPos
) )
183 { // In internationalized versions function names may contain a dot
184 // and in every version also an underscore... ;-)
185 sal_Unicode c
= rStr
.GetChar(nPos
);
186 return c
== '.' || c
== '_';
191 xub_StrLen
FormulaHelper::GetFunctionStart( const String
& rFormula
,
194 String
* pFuncName
) const
196 xub_StrLen nStrLen
= rFormula
.Len();
198 if ( nStrLen
< nStart
)
201 xub_StrLen nFStart
= FUNC_NOTFOUND
;
202 xub_StrLen nParPos
= nStart
;
204 sal_Bool bRepeat
, bFound
;
212 while ( !bFound
&& (nParPos
> 0) )
214 if ( rFormula
.GetChar(nParPos
) == '"' )
217 while ( (nParPos
> 0) && rFormula
.GetChar(nParPos
) != '"' )
222 else if ( (bFound
= ( rFormula
.GetChar(nParPos
) == '(' ) ) == sal_False
)
228 while ( !bFound
&& (nParPos
< nStrLen
) )
230 if ( rFormula
.GetChar(nParPos
) == '"' )
233 while ( (nParPos
< nStrLen
) && rFormula
.GetChar(nParPos
) != '"' )
237 else if ( (bFound
= ( rFormula
.GetChar(nParPos
) == '(' ) ) == sal_False
)
242 if ( bFound
&& (nParPos
> 0) )
246 while ( (nFStart
> 0) && IsFormulaText(m_pCharClass
, rFormula
, nFStart
))
254 if ( IsFormulaText( m_pCharClass
,rFormula
, nFStart
) )
258 *pFuncName
= rFormula
.Copy( nFStart
, nParPos
-nFStart
);
260 else // Brackets without function -> keep searching
265 else if (nParPos
> 0)
271 else // No brackets found
273 nFStart
= FUNC_NOTFOUND
;
283 //------------------------------------------------------------------------
285 xub_StrLen
FormulaHelper::GetFunctionEnd( const String
& rStr
, xub_StrLen nStart
) const
287 xub_StrLen nStrLen
= rStr
.Len();
289 if ( nStrLen
< nStart
)
293 bool bInArray
= false;
294 sal_Bool bFound
= sal_False
;
296 while ( !bFound
&& (nStart
< nStrLen
) )
298 sal_Unicode c
= rStr
.GetChar(nStart
);
303 while ( (nStart
< nStrLen
) && rStr
.GetChar(nStart
) != '"' )
306 else if ( c
== open
)
308 else if ( c
== close
)
311 if ( nParCount
== 0 )
313 else if ( nParCount
< 0 )
316 nStart
--; // read one too far
319 else if ( c
== arrayOpen
)
323 else if ( c
== arrayClose
)
329 if ( !bInArray
&& nParCount
== 0 )
332 nStart
--; // read one too far
335 nStart
++; // Set behind found position
341 //------------------------------------------------------------------
343 xub_StrLen
FormulaHelper::GetArgStart( const String
& rStr
, xub_StrLen nStart
, sal_uInt16 nArg
) const
345 xub_StrLen nStrLen
= rStr
.Len();
347 if ( nStrLen
< nStart
)
351 bool bInArray
= false;
352 sal_Bool bFound
= sal_False
;
354 while ( !bFound
&& (nStart
< nStrLen
) )
356 sal_Unicode c
= rStr
.GetChar(nStart
);
361 while ( (nStart
< nStrLen
) && rStr
.GetChar(nStart
) != '"' )
364 else if ( c
== open
)
366 bFound
= ( nArg
== 0 );
369 else if ( c
== close
)
372 bFound
= ( nParCount
== 0 );
374 else if ( c
== arrayOpen
)
378 else if ( c
== arrayClose
)
384 if ( !bInArray
&& nParCount
== 1 )
387 bFound
= ( nArg
== 0 );
395 // =============================================================================
397 // =============================================================================
399 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */