lok: Hide file linking in section
[LibreOffice.git] / sw / inc / calc.hxx
blob5edec81f5e96a40b55128f0b44cbbc040f4fd0d7
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 #ifndef INCLUDED_SW_INC_CALC_HXX
21 #define INCLUDED_SW_INC_CALC_HXX
23 #include <memory>
24 #include <vector>
25 #include <basic/sbxvar.hxx>
26 #include <unotools/syslocale.hxx>
27 #include <rtl/ustrbuf.hxx>
28 #include <tools/solar.h>
29 #include "swdllapi.h"
31 class CharClass;
32 class LocaleDataWrapper;
33 class SwFieldType;
34 class SwDoc;
35 class SwUserFieldType;
37 #define TBLSZ 47 // should be a prime, because of hash table
39 const sal_Unicode cListDelim = '|';
41 enum SwCalcOper
43 CALC_NAME, CALC_NUMBER, CALC_ENDCALC,
44 CALC_PLUS='+', CALC_MINUS='-', CALC_MUL='*',
45 CALC_DIV='/', CALC_PRINT=';', CALC_ASSIGN='=',
46 CALC_LP='(', CALC_RP=')', CALC_PHD='%',
47 CALC_POW='^',
48 CALC_NOT=256, CALC_AND=257, CALC_OR=258,
49 CALC_XOR=259, CALC_EQ=260, CALC_NEQ=261,
50 CALC_LEQ=262, CALC_GEQ=263, CALC_LES=264,
51 CALC_GRE=265, CALC_SUM=266, CALC_MEAN=267,
52 CALC_SQRT=268, CALC_MIN=269, CALC_MIN_IN=270,
53 CALC_MAX=271, CALC_MAX_IN=272, CALC_SIN=273,
54 CALC_COS=274, CALC_TAN=275, CALC_ASIN=276,
55 CALC_ACOS=278, CALC_ATAN=279, CALC_TDIF=280,
56 CALC_ROUND=281, CALC_DATE=282, CALC_MONTH=283,
57 CALC_DAY=284
60 // Calculate Operations Strings
61 extern const sal_Char sCalc_Add[];
62 extern const sal_Char sCalc_Sub[];
63 extern const sal_Char sCalc_Mul[];
64 extern const sal_Char sCalc_Div[];
65 extern const sal_Char sCalc_Phd[];
66 extern const sal_Char sCalc_Sqrt[];
67 extern const sal_Char sCalc_Pow[];
68 extern const sal_Char sCalc_Or[];
69 extern const sal_Char sCalc_Xor[];
70 extern const sal_Char sCalc_And[];
71 extern const sal_Char sCalc_Not[];
72 extern const sal_Char sCalc_Eq[];
73 extern const sal_Char sCalc_Neq[];
74 extern const sal_Char sCalc_Leq[];
75 extern const sal_Char sCalc_Geq[];
76 extern const sal_Char sCalc_L[];
77 extern const sal_Char sCalc_G[];
78 extern const sal_Char sCalc_Sum[];
79 extern const sal_Char sCalc_Mean[];
80 extern const sal_Char sCalc_Min[];
81 extern const sal_Char sCalc_Max[];
82 extern const sal_Char sCalc_Sin[];
83 extern const sal_Char sCalc_Cos[];
84 extern const sal_Char sCalc_Tan[];
85 extern const sal_Char sCalc_Asin[];
86 extern const sal_Char sCalc_Acos[];
87 extern const sal_Char sCalc_Atan[];
88 extern const sal_Char sCalc_Tdif[];
89 extern const sal_Char sCalc_Round[];
90 extern const sal_Char sCalc_Date[];
92 // Calculate ErrorCodes
93 enum class SwCalcError
95 NONE=0,
96 Syntax, // syntax error
97 DivByZero, // division by zero
98 FaultyBrackets, // faulty brackets
99 OverflowInPower, // overflow in power function
100 Overflow, // overflow
103 class SwSbxValue final : public SbxValue
105 bool m_bVoid;
106 bool m_bDBvalue;
107 public:
108 // always default to a number. otherwise it will become a SbxEMPTY
109 SwSbxValue( long n = 0 ) : m_bVoid(false), m_bDBvalue(false) { PutLong( n ); }
110 SwSbxValue( const double& rD ) : m_bVoid(false), m_bDBvalue(false) { PutDouble( rD ); }
112 bool GetBool() const;
113 double GetDouble() const;
114 SwSbxValue& MakeDouble();
116 bool IsVoidValue() const {return m_bVoid;}
117 void SetVoidValue(bool bSet) {m_bVoid = bSet;}
119 bool IsDBvalue() const {return m_bDBvalue;}
120 void SetDBvalue(bool bSet) {m_bDBvalue = bSet;}
123 // Calculate HashTables for VarTable and Operations
124 struct SwHash
126 SwHash( const OUString& rStr );
127 virtual ~SwHash();
128 OUString aStr;
129 std::unique_ptr<SwHash> pNext;
132 struct SwCalcExp final : public SwHash
134 SwSbxValue nValue;
135 const SwFieldType* pFieldType;
137 SwCalcExp( const OUString& rStr, const SwSbxValue& rVal,
138 const SwFieldType* pFieldType );
141 /// T should be a subclass of SwHash
142 template<class T>
143 class SwHashTable
145 std::vector<std::unique_ptr<T>> m_aData;
146 public:
147 SwHashTable(size_t nSize) : m_aData(nSize) {}
148 std::unique_ptr<T> & operator[](size_t idx) { return m_aData[idx]; }
149 std::unique_ptr<T> const & operator[](size_t idx) const { return m_aData[idx]; }
150 void resize(size_t nSize) { m_aData.resize(nSize); }
152 T* Find( const OUString& rStr, sal_uInt16* pPos = nullptr ) const
154 size_t nTableSize = m_aData.size();
155 sal_uLong ii = 0;
156 for( sal_Int32 n = 0; n < rStr.getLength(); ++n )
158 ii = ii << 1 ^ rStr[n];
160 ii %= nTableSize;
162 if( pPos )
163 *pPos = static_cast<sal_uInt16>(ii);
165 for( T* pEntry = m_aData[ii].get(); pEntry; pEntry = static_cast<T*>(pEntry->pNext.get()) )
167 if( rStr == pEntry->aStr )
169 return pEntry;
172 return nullptr;
178 // if CalcOp != 0, this is a valid operator
179 struct CalcOp;
180 CalcOp* FindOperator( const OUString& rSearch );
182 extern "C" typedef double (*pfCalc)(double);
184 class SwCalc
186 SwHashTable<SwCalcExp> m_aVarTable;
187 OUStringBuffer m_aVarName;
188 OUString m_sCurrSym;
189 OUString m_sCommand;
190 std::vector<const SwUserFieldType*> m_aRekurStack;
191 SwSbxValue m_nLastLeft;
192 SwSbxValue m_nNumberValue;
193 SwCalcExp m_aErrExpr;
194 sal_Int32 m_nCommandPos;
196 SwDoc& m_rDoc;
197 SvtSysLocale const m_aSysLocale;
198 const LocaleDataWrapper* m_pLocaleDataWrapper;
199 CharClass* m_pCharClass;
201 sal_uInt16 m_nListPor;
202 SwCalcOper m_eCurrOper;
203 SwCalcOper m_eCurrListOper;
204 SwCalcError m_eError;
206 SwCalcOper GetToken();
207 SwSbxValue Expr();
208 SwSbxValue Term();
209 SwSbxValue PrimFunc(bool &rChkPow);
210 SwSbxValue Prim();
211 SwSbxValue StdFunc(pfCalc pFnc, bool bChkTrig);
213 static OUString GetColumnName( const OUString& rName );
214 OUString GetDBName( const OUString& rName );
216 SwCalc( const SwCalc& ) = delete;
217 SwCalc& operator=( const SwCalc& ) = delete;
219 public:
220 SwCalc(SwDoc& rD);
221 ~SwCalc() COVERITY_NOEXCEPT_FALSE;
223 SwSbxValue Calculate( const OUString &rStr );
224 OUString GetStrResult( const SwSbxValue& rValue );
225 OUString GetStrResult( double );
227 SwCalcExp* VarInsert( const OUString& r );
228 SwCalcExp* VarLook( const OUString &rStr, bool bIns = false );
229 void VarChange( const OUString& rStr, const SwSbxValue& rValue );
230 void VarChange( const OUString& rStr, double );
231 SwHashTable<SwCalcExp> & GetVarTable() { return m_aVarTable; }
233 bool Push(const SwUserFieldType* pUserFieldType);
234 void Pop();
235 CharClass* GetCharClass();
237 void SetCalcError( SwCalcError eErr ) { m_eError = eErr; }
238 bool IsCalcError() const { return SwCalcError::NONE != m_eError; }
240 static bool Str2Double( const OUString& rStr, sal_Int32& rPos,
241 double& rVal );
242 static bool Str2Double( const OUString& rStr, sal_Int32& rPos,
243 double& rVal, SwDoc const *const pDoc );
245 SW_DLLPUBLIC static bool IsValidVarName( const OUString& rStr,
246 OUString* pValidName = nullptr );
249 #endif
251 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */