20 #include <config_features.h>
26 #include <string_view>
40 #include <osl/diagnose.h>
41 #include <rtl/math.hxx>
52 #include <com/sun/star/i18n/KParseTokens.hpp>
53 #include <com/sun/star/i18n/KParseType.hpp>
140 5.0e+0, 0.5e+0, 0.5e-1, 0.5e-2, 0.5e-3, 0.5e-4, 0.5e-5, 0.5e-6,
141 0.5e-7, 0.5e-8, 0.5e-9, 0.5e-10,0.5e-11,0.5e-12,0.5e-13,0.5e-14,
147 i18n::KParseTokens::ANY_LETTER_OR_NUMBER |
148 i18n::KParseTokens::ASC_UNDERSCORE |
149 i18n::KParseTokens::IGNORE_LEADING_WS;
154 & ~i18n::KParseTokens::IGNORE_LEADING_WS;
160 if(
CALC_NAME == static_cast<const CalcOp*>(pFirst)->eOp )
162 if(
CALC_NAME == static_cast<const CalcOp*>(pSecond)->eOp )
163 nRet =
static_cast<const CalcOp*
>(pFirst)->pUName->compareTo(
164 *static_cast<const CalcOp*>(pSecond)->pUName );
166 nRet =
static_cast<const CalcOp*
>(pFirst)->pUName->compareToAscii(
167 static_cast<const CalcOp*>(pSecond)->pName );
171 if(
CALC_NAME == static_cast<const CalcOp*>(pSecond)->eOp )
172 nRet = -1 *
static_cast<const CalcOp*
>(pSecond)->pUName->compareToAscii(
173 static_cast<const CalcOp*>(pFirst)->pName );
175 nRet = strcmp( static_cast<const CalcOp*>(pFirst)->
pName,
176 static_cast<const CalcOp*>(pSecond)->
pName );
188 return static_cast<CalcOp*
>(bsearch( static_cast<void*>(&aSrch),
189 static_cast<void const *>(aOpTable),
210 Date aDate( nDate >> 24, (nDate& 0x00FF0000) >> 16, nDate& 0x0000FFFF );
211 nRet = aDate - rNull;
218 , m_aErrExpr( OUString(),
SwSbxValue(), nullptr )
221 , m_pLocaleDataWrapper( m_aSysLocale.GetLocaleDataPtr() )
224 , m_bHasNumber( false )
248 sNType4[] =
"tables",
256 sNType11[] =
"user_firstname" ,
257 sNType12[] =
"user_lastname" ,
258 sNType13[] =
"user_initials" ,
259 sNType14[] =
"user_company" ,
260 sNType15[] =
"user_street" ,
261 sNType16[] =
"user_country" ,
262 sNType17[] =
"user_zipcode" ,
263 sNType18[] =
"user_city" ,
264 sNType19[] =
"user_title" ,
265 sNType20[] =
"user_position" ,
266 sNType21[] =
"user_tel_work" ,
267 sNType22[] =
"user_tel_home" ,
268 sNType23[] =
"user_fax" ,
269 sNType24[] =
"user_email" ,
270 sNType25[] =
"user_state" ,
273 static const char*
const sNTypeTab[ 27 ] =
275 sNType0, sNType1, sNType2, sNType3, sNType4, sNType5,
276 sNType6, sNType7, sNType8, sNType9, sNType10, sNType11,
277 sNType12, sNType13, sNType14, sNType15, sNType16, sNType17,
278 sNType18, sNType19, sNType20, sNType21, sNType22, sNType23,
284 static sal_uInt16
const aHashValue[ 27 ] =
286 34, 38, 43, 7, 18, 32, 22, 29, 30, 33, 3,
287 28, 24, 40, 9, 11, 26, 45, 4, 23, 36, 44, 19, 5, 1,
293 UserOptToken::Company, UserOptToken::Street, UserOptToken::Country, UserOptToken::Zip,
294 UserOptToken::City, UserOptToken::Title, UserOptToken::Position, UserOptToken::TelephoneWork,
295 UserOptToken::TelephoneHome, UserOptToken::Fax, UserOptToken::Email, UserOptToken::State
298 static sal_uInt16
SwDocStat::*
const aDocStat1[ 3 ] =
309 #error Did you adjust all hash values?
318 for( n = 0; n < 25; ++n )
320 sTmpStr = OUString::createFromAscii(sNTypeTab[n]);
324 m_aVarTable[ aHashValue[ 0 ] ]->nValue.PutBool(
false );
325 m_aVarTable[ aHashValue[ 1 ] ]->nValue.PutBool(
true );
327 m_aVarTable[ aHashValue[ 3 ] ]->nValue.PutDouble( 2.7182818284590452354 );
329 for( n = 0; n < 3; ++n )
331 for( n = 0; n < 4; ++n )
340 for( n = 0; n < 11; ++n )
342 rUserOptions.
GetToken( aAdrToken[ n ] ));
345 sTmpStr = OUString::createFromAscii(sNTypeTab[25]);
397 if( nValue >= DBL_MAX )
408 const sal_Int32 nDecPlaces = 15;
409 OUString aRetStr( ::rtl::math::doubleToUString(
411 rtl_math_StringFormat_Automatic,
437 for(
SwHash* pEntry = rDocTable[ii].
get(); pEntry; pEntry = pEntry->pNext.get() )
439 if( aStr == pEntry->aStr )
443 static_cast<SwCalcFieldType*>(pEntry)->pFieldType );
505 #if HAVE_FEATURE_DBCONNECTIVITY
509 OUString sSourceName(sDBName.getToken(0,
DB_DELIM));
510 OUString sTableName(sDBName.getToken(0,
';').getToken(1,
DB_DELIM));
511 if( pMgr && !sSourceName.isEmpty() && !sTableName.isEmpty() &&
515 OSL_ENSURE(!sColumnName.isEmpty(),
"Missing DB column name");
526 if( sDBNum.equalsIgnoreAsciiCase(sColumnName) )
533 double nNumber = DBL_MAX;
536 if(pMgr->
GetColumnCnt( sSourceName, sTableName, sColumnName,
537 nTmpRec, nLang, sResult, &nNumber ))
539 if (nNumber != DBL_MAX)
562 OSL_ENSURE( !sColumnName.isEmpty(),
"Missing DB column name" );
563 if( sColumnName.equalsIgnoreAsciiCase(
566 #if HAVE_FEATURE_DBCONNECTIVITY
569 OUString sSourceName(sDBName.getToken(0,
DB_DELIM));
570 OUString sTableName(sDBName.getToken(0,
';').getToken(1,
DB_DELIM));
571 if( pMgr && !sSourceName.isEmpty() && !sTableName.isEmpty() &&
602 pFnd =
new SwCalcExp( aStr, rValue,
nullptr );
623 OSL_ENSURE(
m_aRekurStack.size(),
"SwCalc: Pop on an invalid pointer" );
648 bool bSetError =
true;
650 if( aRes.TokenType & (KParseType::ASC_NUMBER | KParseType::UNI_NUMBER) )
656 else if( aRes.TokenType & KParseType::IDENTNAME )
659 aRes.EndPos - nRealStt ) );
706 else if ( aRes.TokenType & KParseType::DOUBLE_QUOTE_STRING )
712 else if( aRes.TokenType & KParseType::ONE_SINGLE_CHAR )
715 aRes.EndPos - nRealStt ));
716 if( 1 ==
aName.getLength() )
776 sal_Int32 nFndPos = aRes.EndPos,
787 nFndPos - nSttPos - 1) );
793 }
while( nFndPos != -1 );
797 if( nSttPos != nFndPos )
799 nFndPos - nSttPos) );
800 aRes.EndPos = nFndPos + 1;
818 else if( aRes.TokenType & KParseType::BOOLEAN )
821 aRes.EndPos - nRealStt ));
822 if( !
aName.isEmpty() )
827 if (
'<' == ch ||
'>' == ch)
834 if( 2 ==
aName.getLength() &&
'=' ==
aName[1] )
836 else if( 1 !=
aName.getLength() )
919 sal_Int32 nYear =
static_cast<sal_Int32
>(floor( left.
GetDouble() ));
920 nYear = nYear & 0x0000FFFF;
921 sal_Int32 nMonth =
static_cast<sal_Int32
>(floor( e.
GetDouble() ));
922 nMonth = ( nMonth & 0x000000FF ) << 16;
923 left.
PutLong( nMonth + nYear );
931 sal_Int32 nYearMonth =
static_cast<sal_Int32
>(floor( left.
GetDouble() ));
932 nYearMonth = nYearMonth & 0x00FFFFFF;
933 sal_Int32 nDay =
static_cast<sal_Int32
>(floor( e.
GetDouble() ));
934 nDay = ( nDay & 0x000000FF ) << 24;
945 sal_Int32 nDec =
static_cast<sal_Int32
>(floor( e.
GetDouble() ));
946 if( nDec < -20 || nDec > 20 )
955 for (sal_Int32
i = 0;
i < nDec; ++
i )
960 for (sal_Int32
i = 0;
i < -nDec; ++
i )
986 while( fNum >= 10.0 )
997 fVal = floor( fVal+ 0.5 +
nRoundVal[ nExp ] );
1033 left.
Compute( eSbxOper, aRight );
1044 if( !bChkTrig || ( nVal > -1 && nVal < 1 ) )
1084 nErg.
PutDouble(
int(0 < nVal) -
int(nVal < 0) );
1108 OSL_FAIL(
"unexpected case. computing binary NOT" );
1123 nErg.PutDouble( aTmp );
1233 SAL_INFO(
"sw.calc",
"sum/product/date/min/max");
1246 SAL_INFO(
"sw.calc",
"syntax error");
1267 if( ( dleft < 0.0 && 0.0 != fraction ) ||
1268 ( 0.0 == dleft && right < 0.0 ) )
1275 dleft = pow(dleft, right );
1276 if( dleft == HUGE_VAL )
1331 nPos = rName.indexOf(
DB_DELIM, nPos + 1);
1334 return rName.copy(nPos + 1);
1344 nPos = rName.indexOf(
DB_DELIM, nPos + 1);
1347 return rName.copy( 0, nPos );
1355 bool lcl_Str2Double(
const OUString& rCommand, sal_Int32& rCommandPos,
1361 rtl_math_ConversionStatus eStatus;
1363 rVal = pLclData->
stringToDouble( rCommand.getStr() + rCommandPos,
1364 rCommand.getStr() + rCommand.getLength(),
1368 rCommandPos =
static_cast<sal_Int32
>(pEnd - rCommand.getStr());
1370 return rtl_math_ConversionStatus_Ok == eStatus &&
1371 nCurrCmdPos != rCommandPos;
1379 return lcl_Str2Double( rCommand, rCommandPos, rVal, aSysLocale.
GetLocaleDataPtr() );
1383 double& rVal,
SwDoc const *
const pDoc )
1386 std::unique_ptr<const LocaleDataWrapper> pLclD;
1396 bool const bRet = lcl_Str2Double(rCommand, rCommandPos, rVal,
1412 if( aRes.TokenType & KParseType::IDENTNAME )
1414 bRet = aRes.EndPos == rStr.getLength();
1417 *pValidName = rStr.copy( aRes.LeadingWhiteSpace,
1418 aRes.EndPos - aRes.LeadingWhiteSpace );
1421 else if( pValidName )
1422 pValidName->clear();
1476 #ifdef STANDALONE_HASHCALC
1484 sNType0[] =
"false", sNType1[] =
"true", sNType2[] =
"pi",
1485 sNType3[] =
"e", sNType4[] =
"tables", sNType5[] =
"graf",
1486 sNType6[] =
"ole", sNType7[] =
"page", sNType8[] =
"para",
1487 sNType9[] =
"word", sNType10[]=
"char",
1488 sNType11[] =
"user_company" , sNType12[] =
"user_firstname" ,
1489 sNType13[] =
"user_lastname" , sNType14[] =
"user_initials",
1490 sNType15[] =
"user_street" , sNType16[] =
"user_country" ,
1491 sNType17[] =
"user_zipcode" , sNType18[] =
"user_city" ,
1492 sNType19[] =
"user_title" , sNType20[] =
"user_position" ,
1493 sNType21[] =
"user_tel_home", sNType22[] =
"user_tel_work",
1494 sNType23[] =
"user_fax" , sNType24[] =
"user_email" ,
1495 sNType25[] =
"user_state", sNType26[] =
"graph"
1498 static const char* sNTypeTab[ 27 ] =
1500 sNType0, sNType1, sNType2, sNType3, sNType4, sNType5,
1501 sNType6, sNType7, sNType8, sNType9, sNType10, sNType11,
1502 sNType12, sNType13, sNType14, sNType15, sNType16, sNType17,
1503 sNType18, sNType19, sNType20, sNType21, sNType22, sNType23,
1504 sNType24, sNType25, sNType26
1507 const unsigned short nTableSize = 47;
1508 int aArr[ nTableSize ] = { 0 };
1511 for(
int n = 0;
n < 27; ++
n )
1513 unsigned int ii = 0;
1514 const char* pp = sNTypeTab[
n ];
1518 ii = ii << 1 ^ *pp++;
1522 ch = aArr[ ii ] ?
'X' :
' ';
1524 printf(
"%-20s -> %3u [%c]\n", sNTypeTab[ n ], ii, ch );
const char sCalc_Average[]
Instances of SwFields and those derived from it occur 0 to n times.
SwCalcExp(const OUString &rStr, const SwSbxValue &rVal, const SwFieldType *pFieldType)
bool PutULong(sal_uInt32)
bool Compare(SbxOperator, const SbxValue &) const
IDocumentStatistics const & getIDocumentStatistics() const
The shared part of a user field.
OUString GetToken(UserOptToken nToken) const
const LocaleDataWrapper * GetLocaleDataPtr() const
sal_uLong nPara
paragraphs for document statistic: non-empty and non-hidden ones
static ShellResource * GetShellRes()
SvNumberFormatter * GetNumberFormatter(bool bCreate=true)
OUString GetOUString() const
sal_uInt16 GetType() const
const char sCalc_Product[]
LanguageType getLanguageType(bool bResolveSystem=true) const
CalcOp * FindOperator(const OUString &rSrch)
bool OpenDataSource(const OUString &rDataSource, const OUString &rTableOrQuery)
open the source while fields are updated - for the calculator only!
constexpr TypedWhichId< SvxLanguageItem > RES_CHRATR_LANGUAGE(10)
LanguageType GetLanguage(SfxItemSet const &aSet, sal_uInt16 nLangWhichId)
SwCalc(const SwCalc &)=delete
const LanguageTag & getLanguageTag() const
const SwFieldType * pFieldType
CharClass * GetCharClass()
std::unique_ptr< SwHash > pNext
static const OUString & GetTypeStr(SwFieldTypesEnum nTypeId)
double stringToDouble(const OUString &rString, bool bUseGroupSep, rtl_math_ConversionStatus *pStatus, sal_Int32 *pParseEnd) const
const sal_Int32 coStartFlags
static LanguageType nLang
IDocumentFieldsAccess const & getIDocumentFieldsAccess() const
OUString ReplacePoint(const OUString &rTmpName, bool bWithCommandType)
static bool Str2Double(const OUString &rStr, sal_Int32 &rPos, double &rVal)
void VarChange(const OUString &rStr, const SwSbxValue &rValue)
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
const SfxPoolItem & GetDefault(sal_uInt16 nFormatHint) const
Get the default attribute in this document.
virtual SbxDataType GetType() const override
SwCalcOper m_eCurrListOper
SwSbxValue StdFunc(pfCalc pFnc, bool bChkTrig)
SwSbxValue & MakeDouble()
constexpr OUStringLiteral aData
#define SAL_N_ELEMENTS(arr)
const OUString & getNumDecimalSep() const
SwDBData const & GetDBData()
static double lcl_ConvertToDateValue(SwDoc &rDoc, sal_Int32 nDate)
SwSbxValue m_nNumberValue
bool GetColumnCnt(const OUString &rSourceName, const OUString &rTableName, const OUString &rColumnName, sal_uInt32 nAbsRecordId, LanguageType nLanguage, OUString &rResult, double *pNumber)
const sal_Int32 coContFlags
static OUString GetColumnName(const OUString &rName)
static sal_Int16 GetI18NScriptTypeOfLanguage(LanguageType nLang)
sal_uInt16 GetWhichOfScript(sal_uInt16 nWhich, sal_uInt16 nScript)
virtual void Clear() override
double GetValue(SwCalc &rCalc)
T * Find(const OUString &rStr, sal_uInt16 *pPos=nullptr) const
SwHash(const OUString &rStr)
static int OperatorCompare(const void *pFirst, const void *pSecond)
OUString lowercase(const OUString &rStr, sal_Int32 nPos, sal_Int32 nCount) const
constexpr T & temporary(T &&x)
static SW_DLLPUBLIC bool IsValidVarName(const OUString &rStr, OUString *pValidName=nullptr)
OUStringBuffer m_aVarName
const OUString & getCurrSymbol() const
OUString GetFirstName() const
SwSbxValue Calculate(const OUString &rStr)
SwHashTable< SwCalcFieldType > const & GetFieldTypeTable() const
~SwCalc() COVERITY_NOEXCEPT_FALSE
const LanguageTag & getLanguageTag() const
SwHashTable< SwCalcExp > m_aVarTable
OUString GetLastName() const
sal_uInt32 GetSelectedRecordId(const OUString &rDataSource, const OUString &rTableOrQuery, sal_Int32 nCommandType=-1)
css::i18n::ParseResult parseAnyToken(const OUString &rStr, sal_Int32 nPos, sal_Int32 nStartCharFlags, const OUString &userDefinedCharactersStart, sal_Int32 nContCharFlags, const OUString &userDefinedCharactersCont) const
const o3tl::enumarray< SvxAdjust, unsigned short > aSvxToUnoAdjust USHRT_MAX
virtual const SwDocStat & GetDocStat() const =0
Document - Statistics.
#define SAL_INFO(area, stream)
bool PutString(const OUString &)
LanguageType GetAppLanguage()
OString strip(const OString &rIn, char c)
virtual SwDocUpdateField & GetUpdateFields() const =0
Reference< XComponentContext > getProcessComponentContext()
OUString GetStrResult(const SwSbxValue &rValue)
static LanguageType GetDocAppScriptLang(SwDoc const &rDoc)
OUString GetContent(sal_uInt32 nFormat=0)
SwCalcExp * VarLook(const OUString &rStr, bool bIns=false)
SwSbxValue PrimFunc(bool &rChkPow)
const LocaleDataWrapper * m_pLocaleDataWrapper
const LanguageTag & GetLanguageTag() const
Degree100 abs(Degree100 x)
const SwGetSetExpType GSE_STRING
String.
SwCalcExp * VarInsert(const OUString &r)
SvtSysLocale m_aSysLocale
const sal_Unicode cListDelim
OUString GetDBName(const OUString &rName)
bool Push(const SwUserFieldType *pUserFieldType)
bool Compute(SbxOperator, const SbxValue &)
CharClass & GetAppCharClass()
SwDBManager * GetDBManager() const
std::vector< const SwUserFieldType * > m_aRekurStack
void SetVoidValue(bool bSet)