Line data Source code
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 SW_CALC_HXX
21 : #define SW_CALC_HXX
22 :
23 : #include <vector>
24 :
25 : #include <unotools/syslocale.hxx>
26 :
27 : #include <basic/sbxvar.hxx>
28 :
29 : #include "swdllapi.h"
30 :
31 : class CharClass;
32 : class LocaleDataWrapper;
33 : class SwFieldType;
34 : class SwDoc;
35 : class SwUserFieldType;
36 :
37 : #define TBLSZ 47 // should be a prime, because of hash table
38 :
39 : const sal_Unicode cListDelim = '|';
40 :
41 : /******************************************************************************
42 : * Calculate Operations
43 : ******************************************************************************/
44 : enum SwCalcOper
45 : {
46 : CALC_NAME, CALC_NUMBER, CALC_ENDCALC,
47 : CALC_PLUS='+', CALC_MINUS='-', CALC_MUL='*',
48 : CALC_DIV='/', CALC_PRINT=';', CALC_ASSIGN='=',
49 : CALC_LP='(', CALC_RP=')', CALC_PHD='%',
50 : CALC_POW='^',
51 : CALC_LISTOP = cListDelim,
52 : CALC_NOT=256, CALC_AND=257, CALC_OR=258,
53 : CALC_XOR=259, CALC_EQ=260, CALC_NEQ=261,
54 : CALC_LEQ=262, CALC_GEQ=263, CALC_LES=264,
55 : CALC_GRE=265, CALC_SUM=266, CALC_MEAN=267,
56 : CALC_SQRT=268, CALC_MIN=269, CALC_MIN_IN=270,
57 : CALC_MAX=271, CALC_MAX_IN=272, CALC_SIN=273,
58 : CALC_COS=274, CALC_TAN=275, CALC_ASIN=276,
59 : CALC_ACOS=278, CALC_ATAN=279, CALC_TDIF=280,
60 : CALC_ROUND=281, CALC_DATE=282, CALC_MONTH=283,
61 : CALC_DAY=284
62 : };
63 :
64 : //-- Calculate Operations Strings -----------------------------------------
65 :
66 : extern const sal_Char sCalc_Add[];
67 : extern const sal_Char sCalc_Sub[];
68 : extern const sal_Char sCalc_Mul[];
69 : extern const sal_Char sCalc_Div[];
70 : extern const sal_Char sCalc_Phd[];
71 : extern const sal_Char sCalc_Sqrt[];
72 : extern const sal_Char sCalc_Pow[];
73 : extern const sal_Char sCalc_Or[];
74 : extern const sal_Char sCalc_Xor[];
75 : extern const sal_Char sCalc_And[];
76 : extern const sal_Char sCalc_Not[];
77 : extern const sal_Char sCalc_Eq[];
78 : extern const sal_Char sCalc_Neq[];
79 : extern const sal_Char sCalc_Leq[];
80 : extern const sal_Char sCalc_Geq[];
81 : extern const sal_Char sCalc_L[];
82 : extern const sal_Char sCalc_G[];
83 : extern const sal_Char sCalc_Sum[];
84 : extern const sal_Char sCalc_Mean[];
85 : extern const sal_Char sCalc_Min[];
86 : extern const sal_Char sCalc_Max[];
87 : extern const sal_Char sCalc_Sin[];
88 : extern const sal_Char sCalc_Cos[];
89 : extern const sal_Char sCalc_Tan[];
90 : extern const sal_Char sCalc_Asin[];
91 : extern const sal_Char sCalc_Acos[];
92 : extern const sal_Char sCalc_Atan[];
93 : extern const sal_Char sCalc_Tdif[];
94 : extern const sal_Char sCalc_Round[];
95 : extern const sal_Char sCalc_Date[];
96 :
97 : /******************************************************************************
98 : * Calculate ErrorCodes
99 : ******************************************************************************/
100 : enum SwCalcError
101 : {
102 : CALC_NOERR=0,
103 : CALC_SYNTAX, // syntax error
104 : CALC_ZERODIV, // division by zero
105 : CALC_BRACK, // faulty brackets
106 : CALC_POWERR, // overflow in power function
107 : CALC_VARNFND, // variable was not found
108 : CALC_OVERFLOW, // overflow
109 : CALC_WRONGTIME // wrong time format
110 : };
111 :
112 10 : class SwSbxValue : public SbxValue
113 : {
114 : bool bVoid;
115 : public:
116 : // always default to a number. otherwise it will become a SbxEMPTY
117 18 : SwSbxValue( long n = 0 ) : bVoid(false) { PutLong( n ); }
118 0 : SwSbxValue( const double& rD ) : bVoid(false) { PutDouble( rD ); }
119 56 : SwSbxValue( const SwSbxValue& rVal ) :
120 : SvRefBase( rVal ),
121 : SbxValue( rVal ),
122 56 : bVoid(rVal.bVoid)
123 56 : {}
124 : virtual ~SwSbxValue();
125 :
126 :
127 : sal_Bool GetBool() const;
128 : double GetDouble() const;
129 : SwSbxValue& MakeDouble();
130 :
131 1 : bool IsVoidValue() {return bVoid;}
132 2 : void SetVoidValue(bool bSet) {bVoid = bSet;}
133 : };
134 :
135 : /******************************************************************************
136 : * Calculate HashTables for VarTable und Operations
137 : ******************************************************************************/
138 : struct SwHash
139 : {
140 : SwHash( const String& rStr );
141 : virtual ~SwHash();
142 : String aStr;
143 : SwHash *pNext;
144 : };
145 :
146 110 : struct SwCalcExp : public SwHash
147 : {
148 : SwSbxValue nValue;
149 : const SwFieldType* pFldType;
150 :
151 : SwCalcExp( const String& rStr, const SwSbxValue& rVal,
152 : const SwFieldType* pFldType = 0 );
153 : };
154 :
155 : SwHash* Find( const String& rSrch, SwHash** ppTable,
156 : sal_uInt16 nTblSize, sal_uInt16* pPos = 0 );
157 :
158 : void DeleteHashTable( SwHash** ppTable, sal_uInt16 nTblSize );
159 :
160 : // if _CalcOp != 0, this is a valid operator
161 : struct _CalcOp;
162 : _CalcOp* FindOperator( const String& rSearch );
163 :
164 : /******************************************************************************
165 : * class SwCalc
166 : ******************************************************************************/
167 : class SwCalc
168 : {
169 : SwHash* VarTable[ TBLSZ ];
170 : String aVarName, sCurrSym;
171 : String sCommand;
172 : std::vector<const SwUserFieldType*> aRekurStk;
173 : SwSbxValue nLastLeft;
174 : SwSbxValue nNumberValue;
175 : SwCalcExp aErrExpr;
176 : xub_StrLen nCommandPos;
177 :
178 : SwDoc& rDoc;
179 : SvtSysLocale m_aSysLocale;
180 : const LocaleDataWrapper* pLclData;
181 : CharClass* pCharClass;
182 :
183 : sal_uInt16 nListPor;
184 : SwCalcOper eCurrOper;
185 : SwCalcOper eCurrListOper;
186 : SwCalcError eError;
187 :
188 :
189 : SwCalcOper GetToken();
190 : SwSbxValue Expr();
191 : SwSbxValue Term();
192 : SwSbxValue Prim();
193 :
194 : sal_Bool ParseTime( sal_uInt16*, sal_uInt16*, sal_uInt16* );
195 :
196 : String GetColumnName( const String& rName );
197 : String GetDBName( const String& rName );
198 :
199 : // dont call this methods
200 : SwCalc( const SwCalc& );
201 : SwCalc& operator=( const SwCalc& );
202 :
203 : public:
204 : SwCalc( SwDoc& rD );
205 : ~SwCalc();
206 :
207 : SwSbxValue Calculate( const String &rStr );
208 : String GetStrResult( const SwSbxValue& rValue, sal_Bool bRound = sal_True );
209 : String GetStrResult( double, sal_Bool bRound = sal_True );
210 :
211 : SwCalcExp* VarInsert( const String& r );
212 : SwCalcExp* VarLook( const String &rStr, sal_uInt16 ins = 0 );
213 : void VarChange( const String& rStr, const SwSbxValue& rValue );
214 : void VarChange( const String& rStr, double );
215 0 : SwHash** GetVarTable() { return VarTable; }
216 :
217 : bool Push(const SwUserFieldType* pUserFieldType);
218 : void Pop();
219 :
220 0 : void SetCalcError( SwCalcError eErr ) { eError = eErr; }
221 0 : sal_Bool IsCalcError() const { return 0 != eError; }
222 :
223 : static bool Str2Double( const String& rStr, xub_StrLen& rPos,
224 : double& rVal,
225 : LocaleDataWrapper const*const pData = 0 );
226 : static bool Str2Double( const String& rStr, xub_StrLen& rPos,
227 : double& rVal, SwDoc *const pDoc );
228 :
229 : SW_DLLPUBLIC static sal_Bool IsValidVarName( const String& rStr,
230 : String* pValidName = 0 );
231 : };
232 :
233 : #endif
234 :
235 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|