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;
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),
213 Date aDate( nDate >> 24, (nDate& 0x00FF0000) >> 16, nDate& 0x0000FFFF );
214 nRet = aDate - rNull;
221 , m_aErrExpr( OUString(),
SwSbxValue(), nullptr )
226 , m_bHasNumber( false )
249 sNType4[] =
"tables",
257 sNType11[] =
"user_firstname" ,
258 sNType12[] =
"user_lastname" ,
259 sNType13[] =
"user_initials" ,
260 sNType14[] =
"user_company" ,
261 sNType15[] =
"user_street" ,
262 sNType16[] =
"user_country" ,
263 sNType17[] =
"user_zipcode" ,
264 sNType18[] =
"user_city" ,
265 sNType19[] =
"user_title" ,
266 sNType20[] =
"user_position" ,
267 sNType21[] =
"user_tel_work" ,
268 sNType22[] =
"user_tel_home" ,
269 sNType23[] =
"user_fax" ,
270 sNType24[] =
"user_email" ,
271 sNType25[] =
"user_state" ,
274 static const char*
const sNTypeTab[ 27 ] =
276 sNType0, sNType1, sNType2, sNType3, sNType4, sNType5,
277 sNType6, sNType7, sNType8, sNType9, sNType10, sNType11,
278 sNType12, sNType13, sNType14, sNType15, sNType16, sNType17,
279 sNType18, sNType19, sNType20, sNType21, sNType22, sNType23,
285 static sal_uInt16
const aHashValue[ 27 ] =
287 34, 38, 43, 7, 18, 32, 22, 29, 30, 33, 3,
288 28, 24, 40, 9, 11, 26, 45, 4, 23, 36, 44, 19, 5, 1,
294 UserOptToken::Company, UserOptToken::Street, UserOptToken::Country, UserOptToken::Zip,
295 UserOptToken::City, UserOptToken::Title, UserOptToken::Position, UserOptToken::TelephoneWork,
296 UserOptToken::TelephoneHome, UserOptToken::Fax, UserOptToken::Email, UserOptToken::State
299 static sal_uInt16
SwDocStat::*
const aDocStat1[ 3 ] =
310#error Did you adjust all hash values?
319 for(
n = 0;
n < 25; ++
n )
321 sTmpStr = OUString::createFromAscii(sNTypeTab[
n]);
325 m_aVarTable[ aHashValue[ 0 ] ]->nValue.PutBool(
false );
326 m_aVarTable[ aHashValue[ 1 ] ]->nValue.PutBool(
true );
327 m_aVarTable[ aHashValue[ 2 ] ]->nValue.PutDouble( M_PI );
328 m_aVarTable[ aHashValue[ 3 ] ]->nValue.PutDouble( M_E );
330 for(
n = 0;
n < 3; ++
n )
332 for(
n = 0;
n < 4; ++
n )
341 for(
n = 0;
n < 11; ++
n )
343 rUserOptions.
GetToken( aAdrToken[
n ] ));
346 sTmpStr = OUString::createFromAscii(sNTypeTab[25]);
412 const sal_Int32 nDecPlaces = 15;
413 OUString aRetStr( ::rtl::math::doubleToUString(
415 rtl_math_StringFormat_Automatic,
441 for(
SwHash* pEntry = rDocTable[ii].
get(); pEntry; pEntry = pEntry->pNext.get() )
443 if(
aStr == pEntry->aStr )
509#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
512 OUString sSourceName(sDBName.getToken(0,
DB_DELIM));
513 OUString sTableName(sDBName.getToken(0,
';').getToken(1,
DB_DELIM));
514 if( pMgr && !sSourceName.isEmpty() && !sTableName.isEmpty() &&
518 OSL_ENSURE(!sColumnName.isEmpty(),
"Missing DB column name");
529 if( sDBNum.equalsIgnoreAsciiCase(sColumnName) )
536 double nNumber = DBL_MAX;
539 if(pMgr->
GetColumnCnt( sSourceName, sTableName, sColumnName,
540 nTmpRec,
nLang, sResult, &nNumber ))
542 if (nNumber != DBL_MAX)
565 OSL_ENSURE( !sColumnName.isEmpty(),
"Missing DB column name" );
566 if( sColumnName.equalsIgnoreAsciiCase(
569#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
572 OUString sSourceName(sDBName.getToken(0,
DB_DELIM));
573 OUString sTableName(sDBName.getToken(0,
';').getToken(1,
DB_DELIM));
574 if( pMgr && !sSourceName.isEmpty() && !sTableName.isEmpty() &&
626 OSL_ENSURE(
m_aRekurStack.size(),
"SwCalc: Pop on an invalid pointer" );
656 bool bSetError =
true;
658 if( aRes.TokenType & (KParseType::ASC_NUMBER | KParseType::UNI_NUMBER) )
664 else if( aRes.TokenType & KParseType::IDENTNAME )
667 aRes.EndPos - nRealStt ) );
714 else if ( aRes.TokenType & KParseType::DOUBLE_QUOTE_STRING )
720 else if( aRes.TokenType & KParseType::ONE_SINGLE_CHAR )
723 aRes.EndPos - nRealStt ));
724 if( 1 ==
aName.size() )
784 sal_Int32 nFndPos = aRes.EndPos,
795 nFndPos - nSttPos - 1) );
801 }
while( nFndPos != -1 );
805 if( nSttPos != nFndPos )
807 nFndPos - nSttPos) );
808 aRes.EndPos = nFndPos + 1;
826 else if( aRes.TokenType & KParseType::BOOLEAN )
829 aRes.EndPos - nRealStt ));
835 if (
'<' ==
ch ||
'>' ==
ch)
844 else if( 1 !=
aName.size() )
872 sal_uInt16 nSbxOper = USHRT_MAX;
880 left.PutBool(
left.GetBool() && bB );
887 left.PutBool(
left.GetBool() || bB );
894 bool bL =
left.GetBool();
895 left.PutBool(bL != bR);
927 sal_Int32 nYear =
static_cast<sal_Int32
>(floor(
left.GetDouble() ));
928 nYear = nYear & 0x0000FFFF;
929 sal_Int32 nMonth =
static_cast<sal_Int32
>(floor( e.
GetDouble() ));
930 nMonth = ( nMonth & 0x000000FF ) << 16;
931 left.PutLong( nMonth + nYear );
939 sal_Int32 nYearMonth =
static_cast<sal_Int32
>(floor(
left.GetDouble() ));
940 nYearMonth = nYearMonth & 0x00FFFFFF;
941 sal_Int32 nDay =
static_cast<sal_Int32
>(floor( e.
GetDouble() ));
942 nDay = ( nDay & 0x000000FF ) << 24;
953 sal_Int32 nDec =
static_cast<sal_Int32
>(floor( e.
GetDouble() ));
954 if( nDec < -20 || nDec > 20 )
960 fVal =
left.GetDouble();
963 for (sal_Int32
i = 0;
i < nDec; ++
i )
968 for (sal_Int32
i = 0;
i < -nDec; ++
i )
994 while( fNum >= 10.0 )
1003 else if( nExp <= 1 )
1005 fVal = floor( fVal+ 0.5 +
nRoundVal[ nExp ] );
1012 left.PutDouble( fVal );
1022 if( USHRT_MAX != nSbxOper )
1041 left.Compute( eSbxOper, aRight );
1052 if( !bChkTrig || ( nVal > -1 && nVal < 1 ) )
1092 nErg.
PutDouble(
int(0 < nVal) -
int(nVal < 0) );
1100 sal_Int32 nVal =
static_cast<sal_Int32
>(
Prim().
GetDouble() );
1125 OSL_FAIL(
"unexpected case. computing binary NOT" );
1164 nErg =
n->nValue =
Expr();
1250 SAL_INFO(
"sw.calc",
"sum/product/date/min/max");
1263 SAL_INFO(
"sw.calc",
"syntax error");
1284 if( ( dleft < 0.0 && 0.0 != fraction ) ||
1285 ( 0.0 == dleft &&
right < 0.0 ) )
1292 dleft = pow(dleft,
right );
1293 if( dleft == HUGE_VAL )
1351 return rName.copy(
nPos + 1);
1359 if( std::u16string_view::npos !=
nPos )
1363 if( std::u16string_view::npos !=
nPos )
1364 return OUString(rName.substr( 0,
nPos ));
1372 bool lcl_Str2Double(
const OUString& rCommand, sal_Int32& rCommandPos,
1378 rtl_math_ConversionStatus eStatus;
1380 rVal = pLclData->
stringToDouble( rCommand.getStr() + rCommandPos,
1381 rCommand.getStr() + rCommand.getLength(),
1385 rCommandPos =
static_cast<sal_Int32
>(pEnd - rCommand.getStr());
1387 return rtl_math_ConversionStatus_Ok == eStatus &&
1388 nCurrCmdPos != rCommandPos;
1396 return lcl_Str2Double( rCommand, rCommandPos, rVal, &aSysLocale.
GetLocaleData() );
1400 double& rVal,
SwDoc const *
const pDoc )
1403 std::unique_ptr<const LocaleDataWrapper> pLclD;
1413 bool const bRet = lcl_Str2Double(rCommand, rCommandPos, rVal,
1429 if( aRes.TokenType & KParseType::IDENTNAME )
1431 bRet = aRes.EndPos == rStr.getLength();
1434 *pValidName = rStr.copy( aRes.LeadingWhiteSpace,
1435 aRes.EndPos - aRes.LeadingWhiteSpace );
1438 else if( pValidName )
1439 pValidName->clear();
1493#ifdef STANDALONE_HASHCALC
1501 sNType0[] =
"false", sNType1[] =
"true", sNType2[] =
"pi",
1502 sNType3[] =
"e", sNType4[] =
"tables", sNType5[] =
"graf",
1503 sNType6[] =
"ole", sNType7[] =
"page", sNType8[] =
"para",
1504 sNType9[] =
"word", sNType10[]=
"char",
1505 sNType11[] =
"user_company" , sNType12[] =
"user_firstname" ,
1506 sNType13[] =
"user_lastname" , sNType14[] =
"user_initials",
1507 sNType15[] =
"user_street" , sNType16[] =
"user_country" ,
1508 sNType17[] =
"user_zipcode" , sNType18[] =
"user_city" ,
1509 sNType19[] =
"user_title" , sNType20[] =
"user_position" ,
1510 sNType21[] =
"user_tel_home", sNType22[] =
"user_tel_work",
1511 sNType23[] =
"user_fax" , sNType24[] =
"user_email" ,
1512 sNType25[] =
"user_state", sNType26[] =
"graph"
1515 static const char* sNTypeTab[ 27 ] =
1517 sNType0, sNType1, sNType2, sNType3, sNType4, sNType5,
1518 sNType6, sNType7, sNType8, sNType9, sNType10, sNType11,
1519 sNType12, sNType13, sNType14, sNType15, sNType16, sNType17,
1520 sNType18, sNType19, sNType20, sNType21, sNType22, sNType23,
1521 sNType24, sNType25, sNType26
1524 const unsigned short nTableSize = 47;
1525 int aArr[ nTableSize ] = { 0 };
1528 for(
int n = 0;
n < 27; ++
n )
1530 unsigned int ii = 0;
1531 const char* pp = sNTypeTab[
n ];
1535 ii = ii << 1 ^ *pp++;
1539 ch =
aArr[ ii ] ?
'X' :
' ';
1541 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)
static LanguageType GetDocAppScriptLang(SwDoc const &rDoc)
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)
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.
double GetValue(SwCalc &rCalc)
sal_uInt16 GetType() const
OUString GetContent(sal_uInt32 nFormat=0)
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