LibreOffice Module sw (master) 1
calc.hxx
Go to the documentation of this file.
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#ifndef INCLUDED_SW_INC_CALC_HXX
21#define INCLUDED_SW_INC_CALC_HXX
22
23#include <memory>
24#include <vector>
25#include <i18nlangtag/lang.h>
26#include <basic/sbxvar.hxx>
28#include <rtl/ustrbuf.hxx>
29#include <tools/solar.h>
30#include <tools/long.hxx>
31#include <o3tl/safeint.hxx>
32#include "swdllapi.h"
33
34class CharClass;
36class SwFieldType;
37class SwDoc;
38class SwUserFieldType;
39
40#define TBLSZ 47 // should be a prime, because of hash table
41
43
45{
49 CALC_LP='(', CALC_RP=')', CALC_PHD='%',
51 CALC_NOT=256, CALC_AND=257, CALC_OR=258,
52 CALC_XOR=259, CALC_EQ=260, CALC_NEQ=261,
53 CALC_LEQ=262, CALC_GEQ=263, CALC_LES=264,
62 CALC_INT=290
63};
64
65// Calculate Operations Strings
66extern const char sCalc_Add[];
67extern const char sCalc_Sub[];
68extern const char sCalc_Mul[];
69extern const char sCalc_Div[];
70extern const char sCalc_Phd[];
71extern const char sCalc_Sqrt[];
72extern const char sCalc_Pow[];
73extern const char sCalc_Or[];
74extern const char sCalc_Xor[];
75extern const char sCalc_And[];
76extern const char sCalc_Not[];
77extern const char sCalc_Eq[];
78extern const char sCalc_Neq[];
79extern const char sCalc_Leq[];
80extern const char sCalc_Geq[];
81extern const char sCalc_L[];
82extern const char sCalc_G[];
83extern const char sCalc_Sum[];
84extern const char sCalc_Mean[];
85extern const char sCalc_Average[];
86extern const char sCalc_Product[];
87extern const char sCalc_Count[];
88extern const char sCalc_Min[];
89extern const char sCalc_Max[];
90extern const char sCalc_Sin[];
91extern const char sCalc_Cos[];
92extern const char sCalc_Tan[];
93extern const char sCalc_Asin[];
94extern const char sCalc_Acos[];
95extern const char sCalc_Atan[];
96extern const char sCalc_Round[];
97extern const char sCalc_Date[];
98extern const char sCalc_Sign[];
99extern const char sCalc_Abs[];
100extern const char sCalc_Int[];
101
102// Calculate ErrorCodes
103enum class SwCalcError
104{
105 NONE=0,
106 NaN, // not a number (not an error, used for interoperability)
107 Syntax, // syntax error
108 DivByZero, // division by zero
109 FaultyBrackets, // faulty brackets
110 OverflowInPower, // overflow in power function
111 Overflow, // overflow
112};
113
114class SwSbxValue final : public SbxValue
115{
118public:
119 // always default to a number. otherwise it will become a SbxEMPTY
120 SwSbxValue( tools::Long n = 0 ) : m_bVoid(false), m_bDBvalue(false) { PutLong( n ); }
121 SwSbxValue( const double& rD ) : m_bVoid(false), m_bDBvalue(false) { PutDouble( rD ); }
122
123 bool GetBool() const;
124 double GetDouble() const;
126
127 bool IsVoidValue() const {return m_bVoid;}
128 void SetVoidValue(bool bSet) {m_bVoid = bSet;}
129
130 bool IsDBvalue() const {return m_bDBvalue;}
131 void SetDBvalue(bool bSet) {m_bDBvalue = bSet;}
132};
133
134// Calculate HashTables for VarTable and Operations
135struct SwHash
136{
137 SwHash( OUString aStr );
138 virtual ~SwHash();
139 OUString aStr;
140 std::unique_ptr<SwHash> pNext;
141};
142
143struct SwCalcExp final : public SwHash
144{
147
148 SwCalcExp( const OUString& rStr, SwSbxValue aVal,
149 const SwFieldType* pFieldType );
150};
151
153template<class T>
155{
156 std::vector<std::unique_ptr<T>> m_aData;
157public:
158 SwHashTable(size_t nSize) : m_aData(nSize)
159 {
160 assert(nSize < SAL_MAX_UINT32);
161 }
162 std::unique_ptr<T> & operator[](size_t idx) { return m_aData[idx]; }
163 std::unique_ptr<T> const & operator[](size_t idx) const { return m_aData[idx]; }
164 void resize(size_t nSize) { m_aData.resize(nSize); }
165
166 T* Find( std::u16string_view aStr, sal_uInt32* pPos = nullptr ) const
167 {
168 size_t nTableSize = m_aData.size();
169 assert(nTableSize < SAL_MAX_UINT32);
170 sal_uInt32 ii = 0;
171 for( size_t n = 0; n < aStr.size(); ++n )
172 {
173 ii = ii << 1 ^ aStr[n];
174 }
175 ii %= nTableSize;
176
177 if( pPos )
178 *pPos = ii;
179
180 for( T* pEntry = m_aData[ii].get(); pEntry; pEntry = static_cast<T*>(pEntry->pNext.get()) )
181 {
182 if( aStr == pEntry->aStr )
183 {
184 return pEntry;
185 }
186 }
187 return nullptr;
188 }
189
190};
191
192
193// if CalcOp != 0, this is a valid operator
194struct CalcOp;
195CalcOp* FindOperator( const OUString& rSearch );
196
197extern "C" typedef double (*pfCalc)(double);
198
200{
202 OUStringBuffer m_aVarName;
203 OUString m_sCurrSym;
204 OUString m_sCommand;
205 std::vector<const SwUserFieldType*> m_aRekurStack;
209 sal_Int32 m_nCommandPos;
210
212 std::unique_ptr<LocaleDataWrapper> m_xLocaleDataWrapper;
214
215 sal_uInt16 m_nListPor;
216 bool m_bHasNumber; // fix COUNT() and AVERAGE(), if all cells are NaN
220
224 SwSbxValue PrimFunc(bool &rChkPow);
226 SwSbxValue StdFunc(pfCalc pFnc, bool bChkTrig);
227
228 static OUString GetColumnName( const OUString& rName );
229 OUString GetDBName( std::u16string_view rName );
230
231 SwCalc( const SwCalc& ) = delete;
232 SwCalc& operator=( const SwCalc& ) = delete;
233
234 void ImplDestroy();
235
236public:
237 SwCalc(SwDoc& rD);
238 ~SwCalc();
239
240 SwSbxValue Calculate( const OUString &rStr );
241 OUString GetStrResult( const SwSbxValue& rValue );
242 OUString GetStrResult( double );
243
244 SwCalcExp* VarInsert( const OUString& r );
245 SwCalcExp* VarLook( const OUString &rStr, bool bIns = false );
246 void VarChange( const OUString& rStr, const SwSbxValue& rValue );
247 void VarChange( const OUString& rStr, double );
249
250 bool Push(const SwUserFieldType* pUserFieldType);
251 void Pop();
252 const CharClass* GetCharClass() const;
253 void SetCharClass(const LanguageTag& rLanguageTag);
254
255 void SetCalcError( SwCalcError eErr ) { m_eError = eErr; }
257 bool IsCalcNotANumber() const { return SwCalcError::NaN == m_eError; }
258
259 static bool Str2Double( const OUString& rStr, sal_Int32& rPos,
260 double& rVal );
261 static bool Str2Double( const OUString& rStr, sal_Int32& rPos,
262 double& rVal, SwDoc const *const pDoc );
263
264 static LanguageType GetDocAppScriptLang( SwDoc const & rDoc );
265
266 SW_DLLPUBLIC static bool IsValidVarName( const OUString& rStr,
267 OUString* pValidName = nullptr );
268};
269
270#endif
271
272/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const char sCalc_Sub[]
Definition: calc.cxx:59
const char sCalc_Abs[]
Definition: calc.cxx:91
const char sCalc_Leq[]
Definition: calc.cxx:71
const char sCalc_L[]
Definition: calc.cxx:73
const char sCalc_Mul[]
Definition: calc.cxx:60
const char sCalc_Add[]
Definition: calc.cxx:58
const char sCalc_Neq[]
Definition: calc.cxx:70
const char sCalc_Int[]
Definition: calc.cxx:92
const char sCalc_Min[]
Definition: calc.cxx:77
const char sCalc_Acos[]
Definition: calc.cxx:83
double(* pfCalc)(double)
Definition: calc.hxx:197
const sal_Unicode cListDelim
Definition: calc.hxx:42
const char sCalc_Not[]
Definition: calc.cxx:68
const char sCalc_Eq[]
Definition: calc.cxx:69
const char sCalc_Date[]
Definition: calc.cxx:86
const char sCalc_Sqrt[]
Definition: calc.cxx:63
SwCalcError
Definition: calc.hxx:104
const char sCalc_Sin[]
Definition: calc.cxx:79
const char sCalc_Round[]
Definition: calc.cxx:85
const char sCalc_Asin[]
Definition: calc.cxx:82
const char sCalc_Max[]
Definition: calc.cxx:78
const char sCalc_Count[]
Definition: calc.cxx:89
const char sCalc_And[]
Definition: calc.cxx:67
const char sCalc_Sign[]
Definition: calc.cxx:90
const char sCalc_Sum[]
Definition: calc.cxx:75
const char sCalc_Xor[]
Definition: calc.cxx:66
const char sCalc_Pow[]
Definition: calc.cxx:64
CalcOp * FindOperator(const OUString &rSearch)
Definition: calc.cxx:185
const char sCalc_Or[]
Definition: calc.cxx:65
const char sCalc_Mean[]
Definition: calc.cxx:76
const char sCalc_Div[]
Definition: calc.cxx:61
const char sCalc_Product[]
Definition: calc.cxx:87
const char sCalc_Atan[]
Definition: calc.cxx:84
const char sCalc_Cos[]
Definition: calc.cxx:80
const char sCalc_Tan[]
Definition: calc.cxx:81
const char sCalc_G[]
Definition: calc.cxx:74
SwCalcOper
Definition: calc.hxx:45
@ CALC_SIN
Definition: calc.hxx:56
@ CALC_ACOS
Definition: calc.hxx:58
@ CALC_OR
Definition: calc.hxx:51
@ CALC_TDIF
Definition: calc.hxx:58
@ CALC_ENDCALC
Definition: calc.hxx:46
@ CALC_GEQ
Definition: calc.hxx:53
@ CALC_NOT
Definition: calc.hxx:51
@ CALC_DAY
Definition: calc.hxx:60
@ CALC_PRINT
Definition: calc.hxx:48
@ CALC_PRODUCT
Definition: calc.hxx:60
@ CALC_AND
Definition: calc.hxx:51
@ CALC_NEQ
Definition: calc.hxx:52
@ CALC_MUL
Definition: calc.hxx:47
@ CALC_MAX
Definition: calc.hxx:56
@ CALC_EQ
Definition: calc.hxx:52
@ CALC_ASSIGN
Definition: calc.hxx:48
@ CALC_ROUND
Definition: calc.hxx:59
@ CALC_ATAN
Definition: calc.hxx:58
@ CALC_RP
Definition: calc.hxx:49
@ CALC_XOR
Definition: calc.hxx:52
@ CALC_MIN_IN
Definition: calc.hxx:55
@ CALC_MONTH
Definition: calc.hxx:59
@ CALC_INT
Definition: calc.hxx:62
@ CALC_SIGN
Definition: calc.hxx:61
@ CALC_DATE
Definition: calc.hxx:59
@ CALC_COUNT
Definition: calc.hxx:61
@ CALC_MIN
Definition: calc.hxx:55
@ CALC_SUM
Definition: calc.hxx:54
@ CALC_NAME
Definition: calc.hxx:46
@ CALC_COS
Definition: calc.hxx:57
@ CALC_ASIN
Definition: calc.hxx:57
@ CALC_MAX_IN
Definition: calc.hxx:56
@ CALC_ABS
Definition: calc.hxx:61
@ CALC_GRE
Definition: calc.hxx:54
@ CALC_PHD
Definition: calc.hxx:49
@ CALC_LES
Definition: calc.hxx:53
@ CALC_PLUS
Definition: calc.hxx:47
@ CALC_POW
Definition: calc.hxx:50
@ CALC_AVERAGE
Definition: calc.hxx:60
@ CALC_LEQ
Definition: calc.hxx:53
@ CALC_DIV
Definition: calc.hxx:48
@ CALC_MINUS
Definition: calc.hxx:47
@ CALC_NUMBER
Definition: calc.hxx:46
@ CALC_MEAN
Definition: calc.hxx:54
@ CALC_SQRT
Definition: calc.hxx:55
@ CALC_TAN
Definition: calc.hxx:57
@ CALC_LP
Definition: calc.hxx:49
const char sCalc_Geq[]
Definition: calc.cxx:72
const char sCalc_Phd[]
Definition: calc.cxx:62
const char sCalc_Average[]
Definition: calc.cxx:88
bool PutDouble(double)
bool PutLong(sal_Int32)
Definition: calc.hxx:200
OUString GetStrResult(const SwSbxValue &rValue)
Definition: calc.cxx:391
void SetCalcError(SwCalcError eErr)
Definition: calc.hxx:255
static SW_DLLPUBLIC bool IsValidVarName(const OUString &rStr, OUString *pValidName=nullptr)
Definition: calc.cxx:1420
OUStringBuffer m_aVarName
Definition: calc.hxx:202
void Pop()
Definition: calc.cxx:625
SwSbxValue Prim()
Definition: calc.cxx:1272
OUString m_sCurrSym
Definition: calc.hxx:203
const CharClass * GetCharClass() const
Definition: calc.cxx:632
SwCalcOper GetToken()
Definition: calc.cxx:642
std::vector< const SwUserFieldType * > m_aRekurStack
Definition: calc.hxx:205
~SwCalc()
Definition: calc.cxx:358
void VarChange(const OUString &rStr, const SwSbxValue &rValue)
Definition: calc.cxx:597
SwSbxValue StdFunc(pfCalc pFnc, bool bChkTrig)
Definition: calc.cxx:1048
SwHashTable< SwCalcExp > & GetVarTable()
Definition: calc.hxx:248
SwDoc & m_rDoc
Definition: calc.hxx:211
SwCalcExp * VarInsert(const OUString &r)
Definition: calc.cxx:423
SwCalcError m_eError
Definition: calc.hxx:219
SwSbxValue Expr()
Definition: calc.cxx:1309
SwCalc(const SwCalc &)=delete
void SetCharClass(const LanguageTag &rLanguageTag)
Definition: calc.cxx:637
SwSbxValue Calculate(const OUString &rStr)
Definition: calc.cxx:363
SwSbxValue PrimFunc(bool &rChkPow)
Definition: calc.cxx:1060
OUString m_sCommand
Definition: calc.hxx:204
bool Push(const SwUserFieldType *pUserFieldType)
Definition: calc.cxx:616
SwCalcOper m_eCurrOper
Definition: calc.hxx:217
SwCalc & operator=(const SwCalc &)=delete
SwCalcExp * VarLook(const OUString &rStr, bool bIns=false)
Definition: calc.cxx:429
SwSbxValue m_nLastLeft
Definition: calc.hxx:206
static OUString GetColumnName(const OUString &rName)
Definition: calc.cxx:1344
static LanguageType GetDocAppScriptLang(SwDoc const &rDoc)
Definition: calc.cxx:199
bool IsCalcError() const
Definition: calc.hxx:256
bool m_bHasNumber
Definition: calc.hxx:216
SwHashTable< SwCalcExp > m_aVarTable
Definition: calc.hxx:201
OUString GetDBName(std::u16string_view rName)
Definition: calc.cxx:1357
static bool Str2Double(const OUString &rStr, sal_Int32 &rPos, double &rVal)
Definition: calc.cxx:1393
SwCalcExp m_aErrExpr
Definition: calc.hxx:208
SwSbxValue m_nNumberValue
Definition: calc.hxx:207
bool IsCalcNotANumber() const
Definition: calc.hxx:257
sal_Int32 m_nCommandPos
Definition: calc.hxx:209
CharClass * m_pCharClass
Definition: calc.hxx:213
SwSbxValue Term()
Definition: calc.cxx:867
sal_uInt16 m_nListPor
Definition: calc.hxx:215
std::unique_ptr< LocaleDataWrapper > m_xLocaleDataWrapper
Definition: calc.hxx:212
SwCalcOper m_eCurrListOper
Definition: calc.hxx:218
void ImplDestroy()
Definition: calc.cxx:352
Definition: doc.hxx:197
Instances of SwFields and those derived from it occur 0 to n times.
Definition: fldbas.hxx:247
T should be a subclass of SwHash.
Definition: calc.hxx:155
std::unique_ptr< T > const & operator[](size_t idx) const
Definition: calc.hxx:163
T * Find(std::u16string_view aStr, sal_uInt32 *pPos=nullptr) const
Definition: calc.hxx:166
void resize(size_t nSize)
Definition: calc.hxx:164
std::vector< std::unique_ptr< T > > m_aData
Definition: calc.hxx:156
std::unique_ptr< T > & operator[](size_t idx)
Definition: calc.hxx:162
SwHashTable(size_t nSize)
Definition: calc.hxx:158
bool m_bDBvalue
Definition: calc.hxx:117
bool m_bVoid
Definition: calc.hxx:116
bool IsDBvalue() const
Definition: calc.hxx:130
bool IsVoidValue() const
Definition: calc.hxx:127
bool GetBool() const
Definition: calc.cxx:1462
void SetVoidValue(bool bSet)
Definition: calc.hxx:128
double GetDouble() const
Definition: calc.cxx:1468
SwSbxValue & MakeDouble()
Definition: calc.cxx:1487
SwSbxValue(tools::Long n=0)
Definition: calc.hxx:120
void SetDBvalue(bool bSet)
Definition: calc.hxx:131
SwSbxValue(const double &rD)
Definition: calc.hxx:121
The shared part of a user field.
Definition: usrfld.hxx:35
const sal_uInt16 idx[]
sal_Int64 n
aStr
NONE
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
long Long
Definition: calc.cxx:96
SwSbxValue nValue
Definition: calc.hxx:145
SwCalcExp(const OUString &rStr, SwSbxValue aVal, const SwFieldType *pFieldType)
Definition: calc.cxx:1454
const SwFieldType * pFieldType
Definition: calc.hxx:146
Definition: calc.hxx:136
SwHash(OUString aStr)
Definition: calc.cxx:1445
OUString aStr
Definition: calc.hxx:139
std::unique_ptr< SwHash > pNext
Definition: calc.hxx:140
virtual ~SwHash()
Definition: calc.cxx:1450
#define SW_DLLPUBLIC
Definition: swdllapi.h:28
sal_uInt16 sal_Unicode
#define SAL_MAX_UINT32