20#include <config_features.h>
21#include <config_fuzzers.h>
40#include <osl/diagnose.h>
41#include <rtl/math.hxx>
53#include <com/sun/star/i18n/KParseTokens.hpp>
54#include <com/sun/star/i18n/KParseType.hpp>
143 5.0e+0, 0.5e+0, 0.5e-1, 0.5e-2, 0.5e-3, 0.5e-4, 0.5e-5, 0.5e-6,
144 0.5e-7, 0.5e-8, 0.5e-9, 0.5e-10,0.5e-11,0.5e-12,0.5e-13,0.5e-14,
150 i18n::KParseTokens::ANY_LETTER_OR_NUMBER |
151 i18n::KParseTokens::ASC_UNDERSCORE |
152 i18n::KParseTokens::IGNORE_LEADING_WS;
156 (
coStartFlags | i18n::KParseTokens::ASC_DOT | i18n::KParseTokens::GROUP_SEPARATOR_IN_NUMBER)
157 & ~i18n::KParseTokens::IGNORE_LEADING_WS;
166 nRet =
static_cast<const CalcOp*
>(pFirst)->pUName->compareTo(
169 nRet =
static_cast<const CalcOp*
>(pFirst)->pUName->compareToAscii(
175 nRet = -1 *
static_cast<const CalcOp*
>(pSecond)->
pUName->compareToAscii(
178 nRet = strcmp(
static_cast<const CalcOp*
>(pFirst)->
pName,
191 return static_cast<CalcOp*
>(bsearch(
static_cast<void*
>(&aSrch),
192 static_cast<void const *
>(
aOpTable),
214 Date aDate( nDate >> 24, (nDate& 0x00FF0000) >> 16, nDate& 0x0000FFFF );
215 nRet = aDate - rNull;
222 , m_aErrExpr( OUString(),
SwSbxValue(), nullptr )
227 , m_bHasNumber( false )
250 sNType4[] =
"tables",
258 sNType11[] =
"user_firstname" ,
259 sNType12[] =
"user_lastname" ,
260 sNType13[] =
"user_initials" ,
261 sNType14[] =
"user_company" ,
262 sNType15[] =
"user_street" ,
263 sNType16[] =
"user_country" ,
264 sNType17[] =
"user_zipcode" ,
265 sNType18[] =
"user_city" ,
266 sNType19[] =
"user_title" ,
267 sNType20[] =
"user_position" ,
268 sNType21[] =
"user_tel_work" ,
269 sNType22[] =
"user_tel_home" ,
270 sNType23[] =
"user_fax" ,
271 sNType24[] =
"user_email" ,
272 sNType25[] =
"user_state" ,
275 static const char*
const sNTypeTab[ 27 ] =
277 sNType0, sNType1, sNType2, sNType3, sNType4, sNType5,
278 sNType6, sNType7, sNType8, sNType9, sNType10, sNType11,
279 sNType12, sNType13, sNType14, sNType15, sNType16, sNType17,
280 sNType18, sNType19, sNType20, sNType21, sNType22, sNType23,
286 static sal_uInt16
const aHashValue[ 27 ] =
288 34, 38, 43, 7, 18, 32, 22, 29, 30, 33, 3,
289 28, 24, 40, 9, 11, 26, 45, 4, 23, 36, 44, 19, 5, 1,
295 UserOptToken::Company, UserOptToken::Street, UserOptToken::Country, UserOptToken::Zip,
296 UserOptToken::City, UserOptToken::Title, UserOptToken::Position, UserOptToken::TelephoneWork,
297 UserOptToken::TelephoneHome, UserOptToken::Fax, UserOptToken::Email, UserOptToken::State
300 static sal_uInt16
SwDocStat::*
const aDocStat1[ 3 ] =
311#error Did you adjust all hash values?
320 for(
n = 0;
n < 25; ++
n )
322 sTmpStr = OUString::createFromAscii(sNTypeTab[
n]);
326 m_aVarTable[ aHashValue[ 0 ] ]->nValue.PutBool(
false );
327 m_aVarTable[ aHashValue[ 1 ] ]->nValue.PutBool(
true );
328 m_aVarTable[ aHashValue[ 2 ] ]->nValue.PutDouble( M_PI );
329 m_aVarTable[ aHashValue[ 3 ] ]->nValue.PutDouble( M_E );
331 for(
n = 0;
n < 3; ++
n )
333 for(
n = 0;
n < 4; ++
n )
342 for(
n = 0;
n < 11; ++
n )
344 rUserOptions.
GetToken( aAdrToken[
n ] ));
347 sTmpStr = OUString::createFromAscii(sNTypeTab[25]);
413 const sal_Int32 nDecPlaces = 15;
414 OUString aRetStr( ::rtl::math::doubleToUString(
416 rtl_math_StringFormat_Automatic,
442 for(
SwHash* pEntry = rDocTable[ii].
get(); pEntry; pEntry = pEntry->pNext.get() )
444 if(
aStr == pEntry->aStr )
510#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
513 OUString sSourceName(sDBName.getToken(0,
DB_DELIM));
514 OUString sTableName(sDBName.getToken(0,
';').getToken(1,
DB_DELIM));
515 if( pMgr && !sSourceName.isEmpty() && !sTableName.isEmpty() &&
519 OSL_ENSURE(!sColumnName.isEmpty(),
"Missing DB column name");
530 if( sDBNum.equalsIgnoreAsciiCase(sColumnName) )
537 double nNumber = DBL_MAX;
540 if(pMgr->
GetColumnCnt( sSourceName, sTableName, sColumnName,
541 nTmpRec,
nLang, sResult, &nNumber ))
543 if (nNumber != DBL_MAX)
566 OSL_ENSURE( !sColumnName.isEmpty(),
"Missing DB column name" );
567 if( sColumnName.equalsIgnoreAsciiCase(
570#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
573 OUString sSourceName(sDBName.getToken(0,
DB_DELIM));
574 OUString sTableName(sDBName.getToken(0,
';').getToken(1,
DB_DELIM));
575 if( pMgr && !sSourceName.isEmpty() && !sTableName.isEmpty() &&
627 OSL_ENSURE(
m_aRekurStack.size(),
"SwCalc: Pop on an invalid pointer" );
657 bool bSetError =
true;
659 if( aRes.TokenType & (KParseType::ASC_NUMBER | KParseType::UNI_NUMBER) )
665 else if( aRes.TokenType & KParseType::IDENTNAME )
668 aRes.EndPos - nRealStt ) );
715 else if ( aRes.TokenType & KParseType::DOUBLE_QUOTE_STRING )
721 else if( aRes.TokenType & KParseType::ONE_SINGLE_CHAR )
724 aRes.EndPos - nRealStt ));
725 if( 1 ==
aName.size() )
785 sal_Int32 nFndPos = aRes.EndPos,
796 nFndPos - nSttPos - 1) );
802 }
while( nFndPos != -1 );
806 if( nSttPos != nFndPos )
808 nFndPos - nSttPos) );
809 aRes.EndPos = nFndPos + 1;
827 else if( aRes.TokenType & KParseType::BOOLEAN )
830 aRes.EndPos - nRealStt ));
836 if (
'<' ==
ch ||
'>' ==
ch)
845 else if( 1 !=
aName.size() )
873 sal_uInt16 nSbxOper = USHRT_MAX;
881 left.PutBool(
left.GetBool() && bB );
888 left.PutBool(
left.GetBool() || bB );
895 bool bL =
left.GetBool();
896 left.PutBool(bL != bR);
928 sal_Int32 nYear =
static_cast<sal_Int32
>(floor(
left.GetDouble() ));
929 nYear = nYear & 0x0000FFFF;
930 sal_Int32 nMonth =
static_cast<sal_Int32
>(floor( e.
GetDouble() ));
931 nMonth = ( nMonth & 0x000000FF ) << 16;
932 left.PutLong( nMonth + nYear );
940 sal_Int32 nYearMonth =
static_cast<sal_Int32
>(floor(
left.GetDouble() ));
941 nYearMonth = nYearMonth & 0x00FFFFFF;
942 sal_Int32 nDay =
static_cast<sal_Int32
>(floor( e.
GetDouble() ));
943 nDay = ( nDay & 0x000000FF ) << 24;
954 sal_Int32 nDec =
static_cast<sal_Int32
>(floor( e.
GetDouble() ));
955 if( nDec < -20 || nDec > 20 )
961 fVal =
left.GetDouble();
964 for (sal_Int32
i = 0;
i < nDec; ++
i )
969 for (sal_Int32
i = 0;
i < -nDec; ++
i )
995 while( fNum >= 10.0 )
1004 else if( nExp <= 1 )
1006 fVal = floor( fVal+ 0.5 +
nRoundVal[ nExp ] );
1013 left.PutDouble( fVal );
1023 if( USHRT_MAX != nSbxOper )
1042 left.Compute( eSbxOper, aRight );
1053 if( !bChkTrig || ( nVal > -1 && nVal < 1 ) )
1093 nErg.
PutDouble(
int(0 < nVal) -
int(nVal < 0) );
1101 sal_Int32 nVal =
static_cast<sal_Int32
>(
Prim().
GetDouble() );
1126 OSL_FAIL(
"unexpected case. computing binary NOT" );
1165 nErg =
n->nValue =
Expr();
1251 SAL_INFO(
"sw.calc",
"sum/product/date/min/max");
1264 SAL_INFO(
"sw.calc",
"syntax error");
1285 if( ( dleft < 0.0 && 0.0 != fraction ) ||
1286 ( 0.0 == dleft &&
right < 0.0 ) )
1293 dleft = pow(dleft,
right );
1294 if( dleft == HUGE_VAL )
1352 return rName.copy(
nPos + 1);
1360 if( std::u16string_view::npos !=
nPos )
1364 if( std::u16string_view::npos !=
nPos )
1365 return OUString(rName.substr( 0,
nPos ));
1373 bool lcl_Str2Double(
const OUString& rCommand, sal_Int32& rCommandPos,
1379 rtl_math_ConversionStatus eStatus;
1381 rVal = pLclData->
stringToDouble( rCommand.getStr() + rCommandPos,
1382 rCommand.getStr() + rCommand.getLength(),
1386 rCommandPos =
static_cast<sal_Int32
>(pEnd - rCommand.getStr());
1388 return rtl_math_ConversionStatus_Ok == eStatus &&
1389 nCurrCmdPos != rCommandPos;
1397 return lcl_Str2Double( rCommand, rCommandPos, rVal, &aSysLocale.
GetLocaleData() );
1401 double& rVal,
SwDoc const *
const pDoc )
1404 std::unique_ptr<const LocaleDataWrapper> pLclD;
1414 bool const bRet = lcl_Str2Double(rCommand, rCommandPos, rVal,
1430 if( aRes.TokenType & KParseType::IDENTNAME )
1432 bRet = aRes.EndPos == rStr.getLength();
1435 *pValidName = rStr.copy( aRes.LeadingWhiteSpace,
1436 aRes.EndPos - aRes.LeadingWhiteSpace );
1439 else if( pValidName )
1440 pValidName->clear();
1494#ifdef STANDALONE_HASHCALC
1502 sNType0[] =
"false", sNType1[] =
"true", sNType2[] =
"pi",
1503 sNType3[] =
"e", sNType4[] =
"tables", sNType5[] =
"graf",
1504 sNType6[] =
"ole", sNType7[] =
"page", sNType8[] =
"para",
1505 sNType9[] =
"word", sNType10[]=
"char",
1506 sNType11[] =
"user_company" , sNType12[] =
"user_firstname" ,
1507 sNType13[] =
"user_lastname" , sNType14[] =
"user_initials",
1508 sNType15[] =
"user_street" , sNType16[] =
"user_country" ,
1509 sNType17[] =
"user_zipcode" , sNType18[] =
"user_city" ,
1510 sNType19[] =
"user_title" , sNType20[] =
"user_position" ,
1511 sNType21[] =
"user_tel_home", sNType22[] =
"user_tel_work",
1512 sNType23[] =
"user_fax" , sNType24[] =
"user_email" ,
1513 sNType25[] =
"user_state", sNType26[] =
"graph"
1516 static const char* sNTypeTab[ 27 ] =
1518 sNType0, sNType1, sNType2, sNType3, sNType4, sNType5,
1519 sNType6, sNType7, sNType8, sNType9, sNType10, sNType11,
1520 sNType12, sNType13, sNType14, sNType15, sNType16, sNType17,
1521 sNType18, sNType19, sNType20, sNType21, sNType22, sNType23,
1522 sNType24, sNType25, sNType26
1525 const unsigned short nTableSize = 47;
1526 int aArr[ nTableSize ] = { 0 };
1529 for(
int n = 0;
n < 27; ++
n )
1531 unsigned int ii = 0;
1532 const char* pp = sNTypeTab[
n ];
1536 ii = ii << 1 ^ *pp++;
1540 ch =
aArr[ ii ] ?
'X' :
' ';
1542 printf(
"%-20s -> %3u [%c]\n", sNTypeTab[ n ], ii, ch );
CalcOp * FindOperator(const OUString &rSrch)
const sal_Int32 coStartFlags
static double lcl_ConvertToDateValue(SwDoc &rDoc, sal_Int32 nDate)
const char sCalc_Product[]
static int OperatorCompare(const void *pFirst, const void *pSecond)
const sal_Int32 coContFlags
const char sCalc_Average[]
const sal_Unicode cListDelim
css::i18n::ParseResult parseAnyToken(const OUString &rStr, sal_Int32 nPos, sal_Int32 nStartCharFlags, const OUString &userDefinedCharactersStart, sal_Int32 nContCharFlags, const OUString &userDefinedCharactersCont) const
OUString lowercase(const OUString &rStr, sal_Int32 nPos, sal_Int32 nCount) const
const LanguageTag & getLanguageTag() const
virtual SwDocUpdateField & GetUpdateFields() const =0
virtual const SwDocStat & GetDocStat() const =0
Document - Statistics.
LanguageType getLanguageType(bool bResolveSystem=true) const
double stringToDouble(std::u16string_view aString, bool bUseGroupSep, rtl_math_ConversionStatus *pStatus, sal_Int32 *pParseEnd) const
OUString GetOUString() const
bool Compute(SbxOperator, const SbxValue &)
bool PutString(const OUString &)
bool PutULong(sal_uInt32)
virtual SbxDataType GetType() const override
virtual void Clear() override
const LanguageTag & GetLanguageTag() const
const LocaleDataWrapper & GetLocaleData() const
OUString GetFirstName() const
OUString GetToken(UserOptToken nToken) const
OUString GetLastName() const
OUString GetStrResult(const SwSbxValue &rValue)
static SW_DLLPUBLIC bool IsValidVarName(const OUString &rStr, OUString *pValidName=nullptr)
OUStringBuffer m_aVarName
const CharClass * GetCharClass() const
std::vector< const SwUserFieldType * > m_aRekurStack
void VarChange(const OUString &rStr, const SwSbxValue &rValue)
SwSbxValue StdFunc(pfCalc pFnc, bool bChkTrig)
SwCalcExp * VarInsert(const OUString &r)
SwCalc(const SwCalc &)=delete
void SetCharClass(const LanguageTag &rLanguageTag)
SwSbxValue Calculate(const OUString &rStr)
SwSbxValue PrimFunc(bool &rChkPow)
bool Push(const SwUserFieldType *pUserFieldType)
SwCalcExp * VarLook(const OUString &rStr, bool bIns=false)
static OUString GetColumnName(const OUString &rName)
static LanguageType GetDocAppScriptLang(SwDoc const &rDoc)
SwHashTable< SwCalcExp > m_aVarTable
OUString GetDBName(std::u16string_view rName)
static bool Str2Double(const OUString &rStr, sal_Int32 &rPos, double &rVal)
SwSbxValue m_nNumberValue
std::unique_ptr< LocaleDataWrapper > m_xLocaleDataWrapper
SwCalcOper m_eCurrListOper
bool OpenDataSource(const OUString &rDataSource, const OUString &rTableOrQuery)
open the source while fields are updated - for the calculator only!
bool GetColumnCnt(const OUString &rSourceName, const OUString &rTableName, const OUString &rColumnName, sal_uInt32 nAbsRecordId, LanguageType nLanguage, OUString &rResult, double *pNumber)
sal_uInt32 GetSelectedRecordId(const OUString &rDataSource, const OUString &rTableOrQuery, sal_Int32 nCommandType=-1)
SwHashTable< SwCalcFieldType > const & GetFieldTypeTable() const
SwDBData const & GetDBData()
SwDBManager * GetDBManager() const
IDocumentFieldsAccess const & getIDocumentFieldsAccess() const
const SfxPoolItem & GetDefault(sal_uInt16 nFormatHint) const
Get the default attribute in this document.
SvNumberFormatter * GetNumberFormatter(bool bCreate=true)
IDocumentStatistics const & getIDocumentStatistics() const
Instances of SwFields and those derived from it occur 0 to n times.
static const OUString & GetTypeStr(SwFieldTypesEnum nTypeId)
T * Find(std::u16string_view aStr, sal_uInt32 *pPos=nullptr) const
void SetVoidValue(bool bSet)
SwSbxValue & MakeDouble()
The shared part of a user field.
OUString GetContent(sal_uInt32 nFormat=0) const
double GetValue(SwCalc &rCalc)
sal_uInt16 GetType() const
static ShellResource * GetShellRes()
#define suppress_fun_call_w_exception(expr)
OUString ReplacePoint(const OUString &rTmpName, bool bWithCommandType)
constexpr TypedWhichId< SvxLanguageItem > RES_CHRATR_LANGUAGE(10)
sal_uInt16 GetWhichOfScript(sal_uInt16 nWhich, sal_uInt16 nScript)
CharClass & GetAppCharClass()
LanguageType GetAppLanguage()
#define SAL_INFO(area, stream)
#define SAL_N_ELEMENTS(arr)
constexpr OUStringLiteral aData
sal_Int16 GetI18NScriptTypeOfLanguage(LanguageType nLang)
OString strip(const OString &rIn, char c)
const SwGetSetExpType GSE_STRING
String.
constexpr T & temporary(T &&x)
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
SwNodeOffset abs(const SwNodeOffset &a)
static LanguageType nLang
SwCalcExp(const OUString &rStr, SwSbxValue aVal, const SwFieldType *pFieldType)
const SwFieldType * pFieldType
sal_uLong nPara
paragraphs for document statistic: non-empty and non-hidden ones
std::unique_ptr< SwHash > pNext