947b23c207
Change-Id: I88b082dc61c05761fd162ea4cf1d30940c2dfccd Reviewed-on: https://gerrit.libreoffice.org/c/core/+/159941 Tested-by: Noel Grandin <noel.grandin@collabora.co.uk> Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
221 lines
7.3 KiB
C++
221 lines
7.3 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
*/
|
|
|
|
#ifndef INCLUDED_SW_INC_CALC_HXX
|
|
#define INCLUDED_SW_INC_CALC_HXX
|
|
|
|
#include <memory>
|
|
#include <vector>
|
|
#include <unordered_map>
|
|
#include <i18nlangtag/lang.h>
|
|
#include <basic/sbxvar.hxx>
|
|
#include <unotools/syslocale.hxx>
|
|
#include <rtl/ustrbuf.hxx>
|
|
#include <tools/solar.h>
|
|
#include <tools/long.hxx>
|
|
#include <o3tl/safeint.hxx>
|
|
#include "swdllapi.h"
|
|
|
|
class CharClass;
|
|
class LocaleDataWrapper;
|
|
class SwFieldType;
|
|
class SwDoc;
|
|
class SwUserFieldType;
|
|
|
|
const sal_Unicode cListDelim = '|';
|
|
|
|
enum SwCalcOper
|
|
{
|
|
CALC_NAME, CALC_NUMBER, CALC_ENDCALC,
|
|
CALC_PLUS='+', CALC_MINUS='-', CALC_MUL='*',
|
|
CALC_DIV='/', CALC_PRINT=';', CALC_ASSIGN='=',
|
|
CALC_LP='(', CALC_RP=')', CALC_PHD='%',
|
|
CALC_POW='^',
|
|
CALC_NOT=256, CALC_AND=257, CALC_OR=258,
|
|
CALC_XOR=259, CALC_EQ=260, CALC_NEQ=261,
|
|
CALC_LEQ=262, CALC_GEQ=263, CALC_LES=264,
|
|
CALC_GRE=265, CALC_SUM=266, CALC_MEAN=267,
|
|
CALC_SQRT=268, CALC_MIN=269, CALC_MIN_IN=270,
|
|
CALC_MAX=271, CALC_MAX_IN=272, CALC_SIN=273,
|
|
CALC_COS=274, CALC_TAN=275, CALC_ASIN=276,
|
|
CALC_ACOS=278, CALC_ATAN=279, CALC_TDIF=280,
|
|
CALC_ROUND=281, CALC_DATE=282, CALC_MONTH=283,
|
|
CALC_DAY=284, CALC_PRODUCT=285, CALC_AVERAGE=286,
|
|
CALC_COUNT=287, CALC_SIGN=288, CALC_ABS=289,
|
|
CALC_INT=290
|
|
};
|
|
|
|
// Calculate Operations Strings
|
|
extern const char sCalc_Add[];
|
|
extern const char sCalc_Sub[];
|
|
extern const char sCalc_Mul[];
|
|
extern const char sCalc_Div[];
|
|
extern const char sCalc_Phd[];
|
|
extern const char sCalc_Sqrt[];
|
|
extern const char sCalc_Pow[];
|
|
extern const char sCalc_Or[];
|
|
extern const char sCalc_Xor[];
|
|
extern const char sCalc_And[];
|
|
extern const char sCalc_Not[];
|
|
extern const char sCalc_Eq[];
|
|
extern const char sCalc_Neq[];
|
|
extern const char sCalc_Leq[];
|
|
extern const char sCalc_Geq[];
|
|
extern const char sCalc_L[];
|
|
extern const char sCalc_G[];
|
|
extern const char sCalc_Sum[];
|
|
extern const char sCalc_Mean[];
|
|
extern const char sCalc_Average[];
|
|
extern const char sCalc_Product[];
|
|
extern const char sCalc_Count[];
|
|
extern const char sCalc_Min[];
|
|
extern const char sCalc_Max[];
|
|
extern const char sCalc_Sin[];
|
|
extern const char sCalc_Cos[];
|
|
extern const char sCalc_Tan[];
|
|
extern const char sCalc_Asin[];
|
|
extern const char sCalc_Acos[];
|
|
extern const char sCalc_Atan[];
|
|
extern const char sCalc_Round[];
|
|
extern const char sCalc_Date[];
|
|
extern const char sCalc_Sign[];
|
|
extern const char sCalc_Abs[];
|
|
extern const char sCalc_Int[];
|
|
|
|
// Calculate ErrorCodes
|
|
enum class SwCalcError
|
|
{
|
|
NONE=0,
|
|
NaN, // not a number (not an error, used for interoperability)
|
|
Syntax, // syntax error
|
|
DivByZero, // division by zero
|
|
FaultyBrackets, // faulty brackets
|
|
OverflowInPower, // overflow in power function
|
|
Overflow, // overflow
|
|
};
|
|
|
|
class SwSbxValue final : public SbxValue
|
|
{
|
|
bool m_bVoid;
|
|
bool m_bDBvalue;
|
|
public:
|
|
// always default to a number. otherwise it will become a SbxEMPTY
|
|
SwSbxValue( tools::Long n = 0 ) : m_bVoid(false), m_bDBvalue(false) { PutLong( n ); }
|
|
SwSbxValue( const double& rD ) : m_bVoid(false), m_bDBvalue(false) { PutDouble( rD ); }
|
|
|
|
bool GetBool() const;
|
|
double GetDouble() const;
|
|
SwSbxValue& MakeDouble();
|
|
|
|
bool IsVoidValue() const {return m_bVoid;}
|
|
void SetVoidValue(bool bSet) {m_bVoid = bSet;}
|
|
|
|
bool IsDBvalue() const {return m_bDBvalue;}
|
|
void SetDBvalue(bool bSet) {m_bDBvalue = bSet;}
|
|
};
|
|
|
|
struct SwCalcExp
|
|
{
|
|
SwSbxValue nValue;
|
|
const SwFieldType* pFieldType;
|
|
|
|
SwCalcExp( SwSbxValue aVal, const SwFieldType* pFieldType );
|
|
};
|
|
|
|
|
|
// if CalcOp != 0, this is a valid operator
|
|
struct CalcOp;
|
|
CalcOp* FindOperator( const OUString& rSearch );
|
|
|
|
extern "C" typedef double (*pfCalc)(double);
|
|
|
|
class SwCalc
|
|
{
|
|
std::unordered_map<OUString, SwCalcExp> m_aVarTable;
|
|
OUStringBuffer m_aVarName;
|
|
OUString m_sCurrSym;
|
|
OUString m_sCommand;
|
|
std::vector<const SwUserFieldType*> m_aRekurStack;
|
|
SwSbxValue m_nLastLeft;
|
|
SwSbxValue m_nNumberValue;
|
|
SwCalcExp m_aErrExpr;
|
|
sal_Int32 m_nCommandPos;
|
|
|
|
SwDoc& m_rDoc;
|
|
std::unique_ptr<LocaleDataWrapper> m_xLocaleDataWrapper;
|
|
CharClass* m_pCharClass;
|
|
|
|
sal_uInt16 m_nListPor;
|
|
bool m_bHasNumber; // fix COUNT() and AVERAGE(), if all cells are NaN
|
|
SwCalcOper m_eCurrOper;
|
|
SwCalcOper m_eCurrListOper;
|
|
SwCalcError m_eError;
|
|
|
|
SwCalcOper GetToken();
|
|
SwSbxValue Expr();
|
|
SwSbxValue Term();
|
|
SwSbxValue PrimFunc(bool &rChkPow);
|
|
SwSbxValue Prim();
|
|
SwSbxValue StdFunc(pfCalc pFnc, bool bChkTrig);
|
|
|
|
static OUString GetColumnName( const OUString& rName );
|
|
OUString GetDBName( std::u16string_view rName );
|
|
|
|
SwCalc( const SwCalc& ) = delete;
|
|
SwCalc& operator=( const SwCalc& ) = delete;
|
|
|
|
void ImplDestroy();
|
|
|
|
public:
|
|
SwCalc(SwDoc& rD);
|
|
~SwCalc();
|
|
|
|
SwSbxValue Calculate( const OUString &rStr );
|
|
OUString GetStrResult( const SwSbxValue& rValue );
|
|
OUString GetStrResult( double );
|
|
|
|
SwCalcExp* VarInsert( const OUString& r );
|
|
SwCalcExp* VarLook( const OUString &rStr, bool bIns = false );
|
|
void VarChange( const OUString& rStr, const SwSbxValue& rValue );
|
|
void VarChange( const OUString& rStr, double );
|
|
std::unordered_map<OUString, SwCalcExp> & GetVarTable() { return m_aVarTable; }
|
|
|
|
bool Push(const SwUserFieldType* pUserFieldType);
|
|
void Pop();
|
|
const CharClass* GetCharClass() const;
|
|
void SetCharClass(const LanguageTag& rLanguageTag);
|
|
|
|
void SetCalcError( SwCalcError eErr ) { m_eError = eErr; }
|
|
bool IsCalcError() const { return SwCalcError::NONE != m_eError && SwCalcError::NaN != m_eError; }
|
|
bool IsCalcNotANumber() const { return SwCalcError::NaN == m_eError; }
|
|
|
|
static bool Str2Double( const OUString& rStr, sal_Int32& rPos,
|
|
double& rVal );
|
|
static bool Str2Double( const OUString& rStr, sal_Int32& rPos,
|
|
double& rVal, SwDoc const *const pDoc );
|
|
|
|
static LanguageType GetDocAppScriptLang( SwDoc const & rDoc );
|
|
|
|
SW_DLLPUBLIC static bool IsValidVarName( const OUString& rStr,
|
|
OUString* pValidName = nullptr );
|
|
};
|
|
|
|
#endif
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|