/src/libreoffice/sw/inc/calc.hxx
Line | Count | Source |
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 | | #pragma once |
21 | | |
22 | | #include <memory> |
23 | | #include <vector> |
24 | | #include <unordered_map> |
25 | | #include <i18nlangtag/lang.h> |
26 | | #include <basic/sbxvar.hxx> |
27 | | #include <unotools/syslocale.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 | | |
34 | | class CharClass; |
35 | | class LocaleDataWrapper; |
36 | | class SwFieldType; |
37 | | class SwDoc; |
38 | | class SwUserFieldType; |
39 | | |
40 | | const sal_Unicode cListDelim = '|'; |
41 | | |
42 | | enum SwCalcOper |
43 | | { |
44 | | CALC_NAME, CALC_NUMBER, CALC_ENDCALC, |
45 | | CALC_PLUS='+', CALC_MINUS='-', CALC_MUL='*', |
46 | | CALC_DIV='/', CALC_PRINT=';', CALC_ASSIGN='=', |
47 | | CALC_LP='(', CALC_RP=')', CALC_PHD='%', |
48 | | CALC_POW='^', |
49 | | CALC_NOT=256, CALC_AND=257, CALC_OR=258, |
50 | | CALC_XOR=259, CALC_EQ=260, CALC_NEQ=261, |
51 | | CALC_LEQ=262, CALC_GEQ=263, CALC_LES=264, |
52 | | CALC_GRE=265, CALC_SUM=266, CALC_MEAN=267, |
53 | | CALC_SQRT=268, CALC_MIN=269, CALC_MIN_IN=270, |
54 | | CALC_MAX=271, CALC_MAX_IN=272, CALC_SIN=273, |
55 | | CALC_COS=274, CALC_TAN=275, CALC_ASIN=276, |
56 | | CALC_ACOS=278, CALC_ATAN=279, CALC_TDIF=280, |
57 | | CALC_ROUND=281, CALC_DATE=282, CALC_MONTH=283, |
58 | | CALC_DAY=284, CALC_PRODUCT=285, CALC_AVERAGE=286, |
59 | | CALC_COUNT=287, CALC_SIGN=288, CALC_ABS=289, |
60 | | CALC_INT=290, CALC_MOD=291, CALC_MOD_IN=292 |
61 | | }; |
62 | | |
63 | | // Calculate Operations Strings |
64 | | inline constexpr OUString sCalc_Add = u"add"_ustr; |
65 | | inline constexpr OUString sCalc_Sub = u"sub"_ustr; |
66 | | inline constexpr OUString sCalc_Mul = u"mul"_ustr; |
67 | | inline constexpr OUString sCalc_Div = u"div"_ustr; |
68 | | inline constexpr OUString sCalc_Phd = u"phd"_ustr; |
69 | | inline constexpr OUString sCalc_Sqrt = u"sqrt"_ustr; |
70 | | inline constexpr OUString sCalc_Pow = u"pow"_ustr; |
71 | | inline constexpr OUString sCalc_Or = u"or"_ustr; |
72 | | inline constexpr OUString sCalc_Xor = u"xor"_ustr; |
73 | | inline constexpr OUString sCalc_And = u"and"_ustr; |
74 | | inline constexpr OUString sCalc_Not = u"not"_ustr; |
75 | | inline constexpr OUString sCalc_Eq = u"eq"_ustr; |
76 | | inline constexpr OUString sCalc_Neq = u"neq"_ustr; |
77 | | inline constexpr OUString sCalc_Leq = u"leq"_ustr; |
78 | | inline constexpr OUString sCalc_Geq = u"geq"_ustr; |
79 | | inline constexpr OUString sCalc_L = u"l"_ustr; |
80 | | inline constexpr OUString sCalc_G = u"g"_ustr; |
81 | | inline constexpr OUString sCalc_Sum = u"sum"_ustr; |
82 | | inline constexpr OUString sCalc_Mean = u"mean"_ustr; |
83 | | inline constexpr OUString sCalc_Min = u"min"_ustr; |
84 | | inline constexpr OUString sCalc_Max = u"max"_ustr; |
85 | | inline constexpr OUString sCalc_Mod = u"mod"_ustr; |
86 | | inline constexpr OUString sCalc_Sin = u"sin"_ustr; |
87 | | inline constexpr OUString sCalc_Cos = u"cos"_ustr; |
88 | | inline constexpr OUString sCalc_Tan = u"tan"_ustr; |
89 | | inline constexpr OUString sCalc_Asin = u"asin"_ustr; |
90 | | inline constexpr OUString sCalc_Acos = u"acos"_ustr; |
91 | | inline constexpr OUString sCalc_Atan = u"atan"_ustr; |
92 | | inline constexpr OUString sCalc_Round= u"round"_ustr; |
93 | | inline constexpr OUString sCalc_Date = u"date"_ustr; |
94 | | inline constexpr OUString sCalc_Product = u"product"_ustr; |
95 | | inline constexpr OUString sCalc_Average = u"average"_ustr; |
96 | | inline constexpr OUString sCalc_Count= u"count"_ustr; |
97 | | inline constexpr OUString sCalc_Sign = u"sign"_ustr; |
98 | | inline constexpr OUString sCalc_Abs = u"abs"_ustr; |
99 | | inline constexpr OUString sCalc_Int = u"int"_ustr; |
100 | | |
101 | | // Calculate ErrorCodes |
102 | | enum class SwCalcError |
103 | | { |
104 | | NONE=0, |
105 | | NaN, // not a number (not an error, used for interoperability) |
106 | | Syntax, // syntax error |
107 | | DivByZero, // division by zero |
108 | | FaultyBrackets, // faulty brackets |
109 | | OverflowInPower, // overflow in power function |
110 | | Overflow, // overflow |
111 | | }; |
112 | | |
113 | | class SwSbxValue final : public SbxValue |
114 | | { |
115 | | bool m_bVoid; |
116 | | bool m_bDBvalue; |
117 | | public: |
118 | | // always default to a number. otherwise it will become a SbxEMPTY |
119 | 5.08k | SwSbxValue( tools::Long n = 0 ) : m_bVoid(false), m_bDBvalue(false) { PutLong( n ); } |
120 | 0 | SwSbxValue( const double& rD ) : m_bVoid(false), m_bDBvalue(false) { PutDouble( rD ); } |
121 | | |
122 | | bool GetBool() const; |
123 | | double GetDouble() const; |
124 | | SwSbxValue& MakeDouble(); |
125 | | |
126 | 1.66k | bool IsVoidValue() const {return m_bVoid;} |
127 | 2.32k | void SetVoidValue(bool bSet) {m_bVoid = bSet;} |
128 | | |
129 | 721 | bool IsDBvalue() const {return m_bDBvalue;} |
130 | 0 | void SetDBvalue(bool bSet) {m_bDBvalue = bSet;} |
131 | | }; |
132 | | |
133 | | struct SwCalcExp |
134 | | { |
135 | | SwSbxValue nValue; |
136 | | const SwFieldType* pFieldType; |
137 | | |
138 | | SwCalcExp( SwSbxValue aVal, const SwFieldType* pFieldType ); |
139 | | }; |
140 | | |
141 | | |
142 | | // if CalcOp != 0, this is a valid operator |
143 | | struct CalcOp; |
144 | | CalcOp* FindOperator( const OUString& rSearch ); |
145 | | |
146 | | extern "C" typedef double (*pfCalc)(double); |
147 | | |
148 | | class SwCalc |
149 | | { |
150 | | std::unordered_map<OUString, SwCalcExp> m_aVarTable; |
151 | | OUStringBuffer m_aVarName; |
152 | | OUString m_sCurrSym; |
153 | | OUString m_sCommand; |
154 | | std::vector<const SwUserFieldType*> m_aRekurStack; |
155 | | SwSbxValue m_nLastLeft; |
156 | | SwSbxValue m_nNumberValue; |
157 | | SwCalcExp m_aErrExpr; |
158 | | sal_Int32 m_nCommandPos; |
159 | | |
160 | | SwDoc& m_rDoc; |
161 | | std::unique_ptr<LocaleDataWrapper> m_xLocaleDataWrapper; |
162 | | CharClass* m_pCharClass; |
163 | | |
164 | | sal_uInt16 m_nListPor; |
165 | | bool m_bHasNumber; // fix COUNT() and AVERAGE(), if all cells are NaN |
166 | | SwCalcOper m_eCurrOper; |
167 | | SwCalcOper m_eCurrListOper; |
168 | | SwCalcError m_eError; |
169 | | |
170 | | SwCalcOper GetToken(); |
171 | | SwSbxValue Expr(); |
172 | | SwSbxValue Term(); |
173 | | SwSbxValue PrimFunc(bool &rChkPow); |
174 | | SwSbxValue Prim(); |
175 | | SwSbxValue StdFunc(pfCalc pFnc, bool bChkTrig); |
176 | | |
177 | | static OUString GetColumnName( const OUString& rName ); |
178 | | OUString GetDBName( std::u16string_view rName ); |
179 | | |
180 | | SwCalc( const SwCalc& ) = delete; |
181 | | SwCalc& operator=( const SwCalc& ) = delete; |
182 | | |
183 | | void ImplDestroy(); |
184 | | |
185 | | public: |
186 | | SwCalc(SwDoc& rD); |
187 | | ~SwCalc(); |
188 | | |
189 | | SwSbxValue Calculate( const OUString &rStr ); |
190 | | OUString GetStrResult( const SwSbxValue& rValue ); |
191 | | OUString GetStrResult( double ); |
192 | | |
193 | | SwCalcExp* VarInsert( const OUString& r ); |
194 | | SwCalcExp* VarLook( const OUString &rStr, bool bIns = false ); |
195 | | void VarChange( const OUString& rStr, const SwSbxValue& rValue ); |
196 | | void VarChange( const OUString& rStr, double ); |
197 | 0 | std::unordered_map<OUString, SwCalcExp> & GetVarTable() { return m_aVarTable; } |
198 | | |
199 | | bool Push(const SwUserFieldType* pUserFieldType); |
200 | | void Pop(); |
201 | | const CharClass* GetCharClass() const; |
202 | | void SetCharClass(const LanguageTag& rLanguageTag); |
203 | | |
204 | 4 | void SetCalcError( SwCalcError eErr ) { m_eError = eErr; } |
205 | 648 | bool IsCalcError() const { return SwCalcError::NONE != m_eError && SwCalcError::NaN != m_eError; } |
206 | 0 | bool IsCalcNotANumber() const { return SwCalcError::NaN == m_eError; } |
207 | | |
208 | | static bool Str2Double( const OUString& rStr, sal_Int32& rPos, |
209 | | double& rVal ); |
210 | | static bool Str2Double( const OUString& rStr, sal_Int32& rPos, |
211 | | double& rVal, SwDoc const *const pDoc ); |
212 | | |
213 | | static LanguageType GetDocAppScriptLang( SwDoc const & rDoc ); |
214 | | |
215 | | SW_DLLPUBLIC static bool IsValidVarName( const OUString& rStr, |
216 | | OUString* pValidName = nullptr ); |
217 | | }; |
218 | | |
219 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |