LCOV - code coverage report
Current view: top level - sw/source/core/bastyp - calc.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 205 621 33.0 %
Date: 2012-08-25 Functions: 19 37 51.4 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 252 1270 19.8 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : #if defined(MACOSX)
      30                 :            : #include <stdlib.h>
      31                 :            : #endif
      32                 :            : 
      33                 :            : #include <calc.hxx>
      34                 :            : #include <cctype>
      35                 :            : #include <cfloat>
      36                 :            : #include <climits>
      37                 :            : #include <comphelper/processfactory.hxx>
      38                 :            : #include <comphelper/string.hxx>
      39                 :            : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
      40                 :            : #include <cstdlib>
      41                 :            : #include <dbfld.hxx>
      42                 :            : #include <dbmgr.hxx>
      43                 :            : #include <docfld.hxx>
      44                 :            : #include <docstat.hxx>
      45                 :            : #include <doc.hxx>
      46                 :            : #include <editeng/langitem.hxx>
      47                 :            : #include <editeng/scripttypeitem.hxx>
      48                 :            : #include <editeng/unolingu.hxx>
      49                 :            : #include <expfld.hxx>
      50                 :            : #include <hintids.hxx>
      51                 :            : #include <osl/diagnose.hxx>
      52                 :            : #include <rtl/math.hxx>
      53                 :            : #include <shellres.hxx>
      54                 :            : #include <svl/zforlist.hxx>
      55                 :            : #include <swmodule.hxx>
      56                 :            : #include <swtypes.hxx>
      57                 :            : #include <unotools/charclass.hxx>
      58                 :            : #include <unotools/localedatawrapper.hxx>
      59                 :            : #include <unotools/useroptions.hxx>
      60                 :            : #include <usrfld.hxx>
      61                 :            : #include <viewsh.hxx>
      62                 :            : 
      63                 :            : using namespace ::com::sun::star;
      64                 :            : 
      65                 :            : // shortcut
      66                 :            : #define RESOURCE ViewShell::GetShellRes()
      67                 :            : 
      68                 :            : const sal_Char sCalc_Add[]  =   "add";
      69                 :            : const sal_Char sCalc_Sub[]  =   "sub";
      70                 :            : const sal_Char sCalc_Mul[]  =   "mul";
      71                 :            : const sal_Char sCalc_Div[]  =   "div";
      72                 :            : const sal_Char sCalc_Phd[]  =   "phd";
      73                 :            : const sal_Char sCalc_Sqrt[] =   "sqrt";
      74                 :            : const sal_Char sCalc_Pow[]  =   "pow";
      75                 :            : const sal_Char sCalc_Or[]   =   "or";
      76                 :            : const sal_Char sCalc_Xor[]  =   "xor";
      77                 :            : const sal_Char sCalc_And[]  =   "and";
      78                 :            : const sal_Char sCalc_Not[]  =   "not";
      79                 :            : const sal_Char sCalc_Eq[]   =   "eq";
      80                 :            : const sal_Char sCalc_Neq[]  =   "neq";
      81                 :            : const sal_Char sCalc_Leq[]  =   "leq";
      82                 :            : const sal_Char sCalc_Geq[]  =   "geq";
      83                 :            : const sal_Char sCalc_L[]    =   "l";
      84                 :            : const sal_Char sCalc_G[]    =   "g";
      85                 :            : const sal_Char sCalc_Sum[]  =   "sum";
      86                 :            : const sal_Char sCalc_Mean[] =   "mean";
      87                 :            : const sal_Char sCalc_Min[]  =   "min";
      88                 :            : const sal_Char sCalc_Max[]  =   "max";
      89                 :            : const sal_Char sCalc_Sin[]  =   "sin";
      90                 :            : const sal_Char sCalc_Cos[]  =   "cos";
      91                 :            : const sal_Char sCalc_Tan[]  =   "tan";
      92                 :            : const sal_Char sCalc_Asin[] =   "asin";
      93                 :            : const sal_Char sCalc_Acos[] =   "acos";
      94                 :            : const sal_Char sCalc_Atan[] =   "atan";
      95                 :            : const sal_Char sCalc_Round[]=   "round";
      96                 :            : const sal_Char sCalc_Date[] =   "date";
      97                 :            : 
      98                 :            : // ATTENTION: sorted list of all operators
      99                 :            : struct _CalcOp
     100                 :            : {
     101                 :            :     union{
     102                 :            :         const sal_Char* pName;
     103                 :            :         const String* pUName;
     104                 :            :     };
     105                 :            :     SwCalcOper eOp;
     106                 :            : };
     107                 :            : 
     108                 :            : _CalcOp const aOpTable[] = {
     109                 :            : /* ACOS */    {{sCalc_Acos},       CALC_ACOS},  // Arc cosine
     110                 :            : /* ADD */     {{sCalc_Add},        CALC_PLUS},  // Addition
     111                 :            : /* AND */     {{sCalc_And},        CALC_AND},   // log. AND
     112                 :            : /* ASIN */    {{sCalc_Asin},       CALC_ASIN},  // Arc sine
     113                 :            : /* ATAN */    {{sCalc_Atan},       CALC_ATAN},  // Arc tangent
     114                 :            : /* COS */     {{sCalc_Cos},        CALC_COS},   // Cosine
     115                 :            : /* DATE */    {{sCalc_Date},       CALC_DATE},  // Date
     116                 :            : /* DIV */     {{sCalc_Div},        CALC_DIV},   // Division
     117                 :            : /* EQ */      {{sCalc_Eq},         CALC_EQ},    // Equality
     118                 :            : /* G */       {{sCalc_G},          CALC_GRE},   // Greater than
     119                 :            : /* GEQ */     {{sCalc_Geq},        CALC_GEQ},   // Greater or equal
     120                 :            : /* L */       {{sCalc_L},          CALC_LES},   // Less than
     121                 :            : /* LEQ */     {{sCalc_Leq},        CALC_LEQ},   // Less or equal
     122                 :            : /* MAX */     {{sCalc_Max},        CALC_MAX},   // Maximum value
     123                 :            : /* MEAN */    {{sCalc_Mean},       CALC_MEAN},  // Mean
     124                 :            : /* MIN */     {{sCalc_Min},        CALC_MIN},   // Minimum value
     125                 :            : /* MUL */     {{sCalc_Mul},        CALC_MUL},   // Multiplication
     126                 :            : /* NEQ */     {{sCalc_Neq},        CALC_NEQ},   // Not equal
     127                 :            : /* NOT */     {{sCalc_Not},        CALC_NOT},   // log. NOT
     128                 :            : /* OR */      {{sCalc_Or},         CALC_OR},    // log. OR
     129                 :            : /* PHD */     {{sCalc_Phd},        CALC_PHD},   // Percentage
     130                 :            : /* POW */     {{sCalc_Pow},        CALC_POW},   // Exponentiation
     131                 :            : /* ROUND */   {{sCalc_Round},      CALC_ROUND}, // Rounding
     132                 :            : /* SIN */     {{sCalc_Sin},        CALC_SIN},   // Sine
     133                 :            : /* SQRT */    {{sCalc_Sqrt},       CALC_SQRT},  // Square root
     134                 :            : /* SUB */     {{sCalc_Sub},        CALC_MINUS}, // Subtraction
     135                 :            : /* SUM */     {{sCalc_Sum},        CALC_SUM},   // Sum
     136                 :            : /* TAN */     {{sCalc_Tan},        CALC_TAN},   // Tangent
     137                 :            : /* XOR */     {{sCalc_Xor},        CALC_XOR}    // log. XOR
     138                 :            : };
     139                 :            : 
     140                 :            : double const nRoundVal[] = {
     141                 :            :     5.0e+0, 0.5e+0, 0.5e-1, 0.5e-2, 0.5e-3, 0.5e-4, 0.5e-5, 0.5e-6,
     142                 :            :     0.5e-7, 0.5e-8, 0.5e-9, 0.5e-10,0.5e-11,0.5e-12,0.5e-13,0.5e-14,
     143                 :            :     0.5e-15,0.5e-16
     144                 :            : };
     145                 :            : 
     146                 :            : double const nKorrVal[] = {
     147                 :            :     9, 9e-1, 9e-2, 9e-3, 9e-4, 9e-5, 9e-6, 9e-7, 9e-8,
     148                 :            :     9e-9, 9e-10, 9e-11, 9e-12, 9e-13, 9e-14
     149                 :            : };
     150                 :            : 
     151                 :            : // First character may be any alphabetic or underscore.
     152                 :            : const sal_Int32 coStartFlags =
     153                 :            :         i18n::KParseTokens::ANY_LETTER_OR_NUMBER |
     154                 :            :         i18n::KParseTokens::ASC_UNDERSCORE |
     155                 :            :         i18n::KParseTokens::IGNORE_LEADING_WS;
     156                 :            : 
     157                 :            : // Continuing characters may be any alphanumeric, underscore, or dot.
     158                 :            : const sal_Int32 coContFlags =
     159                 :            :     ( coStartFlags | i18n::KParseTokens::ASC_DOT )
     160                 :            :         & ~i18n::KParseTokens::IGNORE_LEADING_WS;
     161                 :            : 
     162                 :            : extern "C" {
     163                 :        150 : static int SAL_CALL OperatorCompare( const void *pFirst, const void *pSecond)
     164                 :            : {
     165                 :        150 :     int nRet = 0;
     166         [ +  - ]:        150 :     if( CALC_NAME == ((_CalcOp*)pFirst)->eOp )
     167                 :            :     {
     168         [ -  + ]:        150 :         if( CALC_NAME == ((_CalcOp*)pSecond)->eOp )
     169                 :            :             nRet = ((_CalcOp*)pFirst)->pUName->CompareTo(
     170                 :          0 :                    *((_CalcOp*)pSecond)->pUName );
     171                 :            :         else
     172                 :            :             nRet = ((_CalcOp*)pFirst)->pUName->CompareToAscii(
     173                 :        150 :                    ((_CalcOp*)pSecond)->pName );
     174                 :            :     }
     175                 :            :     else
     176                 :            :     {
     177         [ #  # ]:          0 :         if( CALC_NAME == ((_CalcOp*)pSecond)->eOp )
     178                 :            :             nRet = -1 * ((_CalcOp*)pSecond)->pUName->CompareToAscii(
     179                 :          0 :                         ((_CalcOp*)pFirst)->pName );
     180                 :            :         else
     181                 :            :             nRet = strcmp( ((_CalcOp*)pFirst)->pName,
     182                 :          0 :                            ((_CalcOp*)pSecond)->pName );
     183                 :            :     }
     184                 :        150 :     return nRet;
     185                 :            : }
     186                 :            : }// extern "C"
     187                 :            : 
     188                 :         30 : _CalcOp* FindOperator( const String& rSrch )
     189                 :            : {
     190                 :            :     _CalcOp aSrch;
     191                 :         30 :     aSrch.pUName = &rSrch;
     192                 :         30 :     aSrch.eOp = CALC_NAME;
     193                 :            : 
     194                 :            :     return (_CalcOp*)bsearch( (void*) &aSrch,
     195                 :            :                               (void*) aOpTable,
     196                 :            :                               sizeof( aOpTable ) / sizeof( _CalcOp ),
     197                 :            :                               sizeof( _CalcOp ),
     198         [ +  - ]:         30 :                               OperatorCompare );
     199                 :            : }
     200                 :            : 
     201                 :         84 : SwHash* Find( const String& rStr, SwHash** ppTable,
     202                 :            :               sal_uInt16 nTblSize, sal_uInt16* pPos )
     203                 :            : {
     204                 :         84 :     sal_uLong ii = 0;
     205         [ +  + ]:        747 :     for( xub_StrLen n = 0; n < rStr.Len(); ++n )
     206                 :            :     {
     207                 :        663 :         ii = ii << 1 ^ rStr.GetChar( n );
     208                 :            :     }
     209                 :         84 :     ii %= nTblSize;
     210                 :            : 
     211         [ +  - ]:         84 :     if( pPos )
     212                 :         84 :         *pPos = (sal_uInt16)ii;
     213                 :            : 
     214         [ +  + ]:        104 :     for( SwHash* pEntry = *(ppTable+ii); pEntry; pEntry = pEntry->pNext )
     215                 :            :     {
     216         [ -  + ]:         20 :         if( rStr == pEntry->aStr )
     217                 :            :         {
     218                 :          0 :             return pEntry;
     219                 :            :         }
     220                 :            :     }
     221                 :         84 :     return 0;
     222                 :            : }
     223                 :            : 
     224                 :         24 : inline LanguageType GetDocAppScriptLang( SwDoc& rDoc )
     225                 :            : {
     226                 :            :     return ((SvxLanguageItem&)rDoc.GetDefault(
     227                 :            :                GetWhichOfScript( RES_CHRATR_LANGUAGE,
     228                 :         24 :                                  GetI18NScriptTypeOfLanguage( (sal_uInt16)GetAppLanguage() ))
     229                 :         24 :             )).GetLanguage();
     230                 :            : }
     231                 :            : 
     232                 :          0 : double lcl_ConvertToDateValue( SwDoc& rDoc, sal_Int32 nDate )
     233                 :            : {
     234                 :          0 :     double nRet = 0;
     235                 :          0 :     SvNumberFormatter* pFormatter = rDoc.GetNumberFormatter();
     236         [ #  # ]:          0 :     if( pFormatter )
     237                 :            :     {
     238         [ #  # ]:          0 :         Date* pNull = pFormatter->GetNullDate();
     239                 :          0 :         Date aDate( nDate >> 24, (nDate& 0x00FF0000) >> 16, nDate& 0x0000FFFF );
     240         [ #  # ]:          0 :         nRet = aDate - *pNull;
     241                 :            :     }
     242                 :          0 :     return nRet;
     243                 :            : }
     244                 :            : 
     245                 :         24 : SwCalc::SwCalc( SwDoc& rD )
     246                 :            :     : aErrExpr( aEmptyStr, SwSbxValue(), 0 ),
     247                 :            :     rDoc( rD ),
     248         [ +  - ]:         24 :     pLclData( m_aSysLocale.GetLocaleDataPtr() ),
     249         [ +  - ]:         24 :     pCharClass( &GetAppCharClass() ),
     250                 :            :     nListPor( 0 ),
     251 [ +  - ][ +  - ]:         24 :     eError( CALC_NOERR )
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     252                 :            : {
     253         [ +  - ]:         24 :     aErrExpr.aStr.AssignAscii( "~C_ERR~" );
     254                 :         24 :     memset( VarTable, 0, sizeof(VarTable) );
     255         [ +  - ]:         24 :     LanguageType eLang = GetDocAppScriptLang( rDoc );
     256                 :            : 
     257 [ +  - ][ +  - ]:         42 :     if( eLang != SvxLocaleToLanguage( pLclData->getLocale() ) ||
         [ +  + ][ -  + ]
                 [ +  + ]
     258 [ +  - ][ +  - ]:         18 :         eLang != SvxLocaleToLanguage( pCharClass->getLocale() ) )
     259                 :            :     {
     260         [ +  - ]:          6 :         ::com::sun::star::lang::Locale aLocale( SvxCreateLocale( eLang ));
     261                 :            :         ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xMSF(
     262         [ +  - ]:          6 :                             ::comphelper::getProcessServiceFactory() );
     263 [ +  - ][ +  - ]:          6 :         pCharClass = new CharClass( xMSF, aLocale );
     264 [ +  - ][ +  - ]:          6 :         pLclData = new LocaleDataWrapper( xMSF, aLocale );
     265                 :            :     }
     266                 :            : 
     267 [ +  - ][ +  - ]:         24 :     sCurrSym = comphelper::string::strip(pLclData->getCurrSymbol(), ' ');
                 [ +  - ]
     268 [ +  - ][ +  - ]:         24 :     sCurrSym  = pCharClass->lowercase( sCurrSym );
                 [ +  - ]
     269                 :            : 
     270                 :            :     static sal_Char const
     271                 :            :         sNType0[] = "false",
     272                 :            :         sNType1[] = "true",
     273                 :            :         sNType2[] = "pi",
     274                 :            :         sNType3[] = "e",
     275                 :            :         sNType4[] = "tables",
     276                 :            :         sNType5[] = "graf",
     277                 :            :         sNType6[] = "ole",
     278                 :            :         sNType7[] = "page",
     279                 :            :         sNType8[] = "para",
     280                 :            :         sNType9[] = "word",
     281                 :            :         sNType10[]= "char",
     282                 :            : 
     283                 :            :         sNType11[] = "user_firstname" ,
     284                 :            :         sNType12[] = "user_lastname" ,
     285                 :            :         sNType13[] = "user_initials" ,
     286                 :            :         sNType14[] = "user_company" ,
     287                 :            :         sNType15[] = "user_street" ,
     288                 :            :         sNType16[] = "user_country" ,
     289                 :            :         sNType17[] = "user_zipcode" ,
     290                 :            :         sNType18[] = "user_city" ,
     291                 :            :         sNType19[] = "user_title" ,
     292                 :            :         sNType20[] = "user_position" ,
     293                 :            :         sNType21[] = "user_tel_work" ,
     294                 :            :         sNType22[] = "user_tel_home" ,
     295                 :            :         sNType23[] = "user_fax" ,
     296                 :            :         sNType24[] = "user_email" ,
     297                 :            :         sNType25[] = "user_state" ,
     298                 :            :         sNType26[] = "graph"
     299                 :            :         ;
     300                 :            :     static const sal_Char* const sNTypeTab[ 27 ] =
     301                 :            :     {
     302                 :            :         sNType0, sNType1, sNType2, sNType3, sNType4, sNType5,
     303                 :            :         sNType6, sNType7, sNType8, sNType9, sNType10, sNType11,
     304                 :            :         sNType12, sNType13, sNType14, sNType15, sNType16, sNType17,
     305                 :            :         sNType18, sNType19, sNType20, sNType21, sNType22, sNType23,
     306                 :            :         sNType24,
     307                 :            : 
     308                 :            :         // those have two HashIds
     309                 :            :         sNType25, sNType26
     310                 :            :     };
     311                 :            :     static sal_uInt16 const aHashValue[ 27 ] =
     312                 :            :     {
     313                 :            :         34, 38, 43,  7, 18, 32, 22, 29, 30, 33,  3,
     314                 :            :         28, 24, 40,  9, 11, 26, 45,  4, 23, 36, 44, 19,  5,  1,
     315                 :            :         // those have two HashIds
     316                 :            :         11, 38
     317                 :            :     };
     318                 :            :     static sal_uInt16 const aAdrToken[ 12 ] =
     319                 :            :     {
     320                 :            :         USER_OPT_COMPANY, USER_OPT_STREET, USER_OPT_COUNTRY, USER_OPT_ZIP,
     321                 :            :         USER_OPT_CITY, USER_OPT_TITLE, USER_OPT_POSITION, USER_OPT_TELEPHONEWORK,
     322                 :            :         USER_OPT_TELEPHONEHOME, USER_OPT_FAX, USER_OPT_EMAIL, USER_OPT_STATE
     323                 :            :     };
     324                 :            : 
     325                 :            :     static sal_uInt16 SwDocStat::* const aDocStat1[ 3 ] =
     326                 :            :     {
     327                 :            :         &SwDocStat::nTbl, &SwDocStat::nGrf, &SwDocStat::nOLE
     328                 :            :     };
     329                 :            :     static sal_uLong SwDocStat::* const aDocStat2[ 4 ] =
     330                 :            :     {
     331                 :            :         &SwDocStat::nPage, &SwDocStat::nPara,
     332                 :            :         &SwDocStat::nWord, &SwDocStat::nChar
     333                 :            :     };
     334                 :            : 
     335                 :            : #if TBLSZ != 47
     336                 :            : #error Did you adjust all hash values?
     337                 :            : #endif
     338                 :            : 
     339         [ +  - ]:         24 :     const SwDocStat& rDocStat = rDoc.GetDocStat();
     340                 :            : 
     341         [ +  - ]:         24 :     SwSbxValue nVal;
     342         [ +  - ]:         24 :     String sTmpStr;
     343                 :            :     sal_uInt16 n;
     344                 :            : 
     345         [ +  + ]:        624 :     for( n = 0; n < 25; ++n )
     346                 :            :     {
     347         [ +  - ]:        600 :         sTmpStr.AssignAscii( sNTypeTab[ n ] );
     348 [ +  - ][ +  - ]:        600 :         VarTable[ aHashValue[ n ] ] = new SwCalcExp( sTmpStr, nVal, 0 );
     349                 :            :     }
     350                 :            : 
     351         [ +  - ]:         24 :     ((SwCalcExp*)VarTable[ aHashValue[ 0 ] ])->nValue.PutBool( sal_False );
     352         [ +  - ]:         24 :     ((SwCalcExp*)VarTable[ aHashValue[ 1 ] ])->nValue.PutBool( sal_True );
     353         [ +  - ]:         24 :     ((SwCalcExp*)VarTable[ aHashValue[ 2 ] ])->nValue.PutDouble( F_PI );
     354         [ +  - ]:         24 :     ((SwCalcExp*)VarTable[ aHashValue[ 3 ] ])->nValue.PutDouble( 2.7182818284590452354 );
     355                 :            : 
     356         [ +  + ]:         96 :     for( n = 0; n < 3; ++n )
     357         [ +  - ]:         72 :         ((SwCalcExp*)VarTable[ aHashValue[ n + 4 ] ])->nValue.PutLong( rDocStat.*aDocStat1[ n ]  );
     358         [ +  + ]:        120 :     for( n = 0; n < 4; ++n )
     359         [ +  - ]:         96 :         ((SwCalcExp*)VarTable[ aHashValue[ n + 7 ] ])->nValue.PutLong( rDocStat.*aDocStat2[ n ]  );
     360                 :            : 
     361 [ +  - ][ +  - ]:         24 :     SvtUserOptions& rUserOptions = SW_MOD()->GetUserOptions();
     362                 :            : 
     363 [ +  - ][ +  - ]:         24 :     ((SwCalcExp*)VarTable[ aHashValue[ 11 ] ])->nValue.PutString( (String)rUserOptions.GetFirstName() );
         [ +  - ][ +  - ]
                 [ +  - ]
     364 [ +  - ][ +  - ]:         24 :     ((SwCalcExp*)VarTable[ aHashValue[ 12 ] ])->nValue.PutString( (String)rUserOptions.GetLastName() );
         [ +  - ][ +  - ]
                 [ +  - ]
     365 [ +  - ][ +  - ]:         24 :     ((SwCalcExp*)VarTable[ aHashValue[ 13 ] ])->nValue.PutString( (String)rUserOptions.GetID() );
         [ +  - ][ +  - ]
                 [ +  - ]
     366                 :            : 
     367         [ +  + ]:        288 :     for( n = 0; n < 11; ++n )
     368                 :        528 :         ((SwCalcExp*)VarTable[ aHashValue[ n + 14 ] ])->nValue.PutString(
     369 [ +  - ][ +  - ]:        264 :                                         (String)rUserOptions.GetToken( aAdrToken[ n ] ));
         [ +  - ][ +  - ]
                 [ +  - ]
     370                 :            : 
     371 [ +  - ][ +  - ]:         24 :     nVal.PutString( (String)rUserOptions.GetToken( aAdrToken[ 11 ] ));
         [ +  - ][ +  - ]
                 [ +  - ]
     372         [ +  - ]:         24 :     sTmpStr.AssignAscii( sNTypeTab[ 25 ] );
     373 [ +  - ][ +  - ]:         24 :     VarTable[ aHashValue[ 25 ] ]->pNext = new SwCalcExp( sTmpStr, nVal, 0 );
         [ +  - ][ +  - ]
     374                 :            : 
     375                 :         24 : } // SwCalc::SwCalc
     376                 :            : 
     377 [ +  - ][ +  - ]:         24 : SwCalc::~SwCalc()
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     378                 :            : {
     379         [ +  + ]:       1152 :     for( sal_uInt16 n = 0; n < TBLSZ; ++n )
     380 [ +  + ][ +  - ]:       1128 :         delete VarTable[n];
     381                 :            : 
     382 [ +  - ][ +  + ]:         24 :     if( pLclData != m_aSysLocale.GetLocaleDataPtr() )
     383 [ +  - ][ +  - ]:          6 :         delete pLclData;
     384 [ +  - ][ +  + ]:         24 :     if( pCharClass != &GetAppCharClass() )
     385 [ +  - ][ +  - ]:          6 :         delete pCharClass;
     386                 :         24 : }
     387                 :            : 
     388                 :         24 : SwSbxValue SwCalc::Calculate( const String& rStr )
     389                 :            : {
     390                 :         24 :     eError = CALC_NOERR;
     391                 :         24 :     SwSbxValue nResult;
     392                 :            : 
     393         [ -  + ]:         24 :     if( !rStr.Len() )
     394                 :          0 :         return nResult;
     395                 :            : 
     396                 :         24 :     nListPor = 0;
     397                 :         24 :     eCurrListOper = CALC_PLUS; // default: sum
     398                 :            : 
     399         [ +  - ]:         24 :     sCommand = rStr;
     400                 :         24 :     nCommandPos = 0;
     401                 :            : 
     402 [ +  - ][ +  + ]:         48 :     while( (eCurrOper = GetToken()) != CALC_ENDCALC && eError == CALC_NOERR )
         [ +  - ][ +  + ]
     403 [ +  - ][ +  - ]:         24 :         nResult = Expr();
                 [ +  - ]
     404                 :            : 
     405         [ -  + ]:         24 :     if( eError )
     406         [ #  # ]:          0 :         nResult.PutDouble( DBL_MAX );
     407                 :            : 
     408                 :         24 :     return nResult;
     409                 :            : }
     410                 :            : 
     411                 :            : //TODO: provide documentation
     412                 :            : /** ???
     413                 :            : 
     414                 :            :   @param rVal ???
     415                 :            :   @param bRound In previous times <bRound> had a default value of <sal_True>.
     416                 :            :                 There it should be only changed when calculating table cells,
     417                 :            :                 so that no rounding errors would occur while composing a formula.
     418                 :            :                 Now this parameter is ignored.
     419                 :            :   @return ???
     420                 :            : */
     421                 :          0 : String SwCalc::GetStrResult( const SwSbxValue& rVal, sal_Bool bRound )
     422                 :            : {
     423         [ #  # ]:          0 :     if( !rVal.IsDouble() )
     424                 :          0 :         return rVal.GetString();
     425                 :            : 
     426                 :          0 :     return GetStrResult( rVal.GetDouble(), bRound );
     427                 :            : }
     428                 :            : 
     429                 :          0 : String SwCalc::GetStrResult( double nValue, sal_Bool )
     430                 :            : {
     431         [ #  # ]:          0 :     if( nValue >= DBL_MAX )
     432   [ #  #  #  #  :          0 :         switch( eError )
             #  #  #  # ]
     433                 :            :         {
     434 [ #  # ][ #  # ]:          0 :         case CALC_SYNTAX    :   return RESOURCE->aCalc_Syntax;
     435 [ #  # ][ #  # ]:          0 :         case CALC_ZERODIV   :   return RESOURCE->aCalc_ZeroDiv;
     436 [ #  # ][ #  # ]:          0 :         case CALC_BRACK     :   return RESOURCE->aCalc_Brack;
     437 [ #  # ][ #  # ]:          0 :         case CALC_POWERR    :   return RESOURCE->aCalc_Pow;
     438 [ #  # ][ #  # ]:          0 :         case CALC_VARNFND   :   return RESOURCE->aCalc_VarNFnd;
     439 [ #  # ][ #  # ]:          0 :         case CALC_OVERFLOW  :   return RESOURCE->aCalc_Overflow;
     440 [ #  # ][ #  # ]:          0 :         case CALC_WRONGTIME :   return RESOURCE->aCalc_WrongTime;
     441 [ #  # ][ #  # ]:          0 :         default             :   return RESOURCE->aCalc_Default;
     442                 :            :         }
     443                 :            : 
     444                 :          0 :     sal_uInt16  nDec = 15;
     445                 :            :     String aRetStr( ::rtl::math::doubleToUString(
     446                 :            :                         nValue,
     447                 :            :                         rtl_math_StringFormat_Automatic,
     448                 :            :                         nDec,
     449         [ #  # ]:          0 :                         pLclData->getNumDecimalSep()[0],
     450         [ #  # ]:          0 :                         true ));
     451 [ #  # ][ #  # ]:          0 :     return aRetStr;
     452                 :            : }
     453                 :            : 
     454                 :          0 : SwCalcExp* SwCalc::VarInsert( const String &rStr )
     455                 :            : {
     456 [ #  # ][ #  # ]:          0 :     String aStr = pCharClass->lowercase( rStr );
                 [ #  # ]
     457 [ #  # ][ #  # ]:          0 :     return VarLook( aStr, 1 );
     458                 :            : }
     459                 :            : 
     460                 :         24 : SwCalcExp* SwCalc::VarLook( const String& rStr, sal_uInt16 ins )
     461                 :            : {
     462                 :         24 :     aErrExpr.nValue.SetVoidValue(false);
     463                 :            : 
     464                 :         24 :     sal_uInt16 ii = 0;
     465 [ +  - ][ +  - ]:         24 :     String aStr = pCharClass->lowercase( rStr );
                 [ +  - ]
     466                 :            : 
     467         [ +  - ]:         24 :     SwHash* pFnd = Find( aStr, VarTable, TBLSZ, &ii );
     468                 :            : 
     469         [ +  - ]:         24 :     if( !pFnd )
     470                 :            :     {
     471                 :            :         // then check doc
     472         [ +  - ]:         24 :         SwHash** ppDocTbl = rDoc.GetUpdtFlds().GetFldTypeTable();
     473         [ +  + ]:         30 :         for( SwHash* pEntry = *(ppDocTbl+ii); pEntry; pEntry = pEntry->pNext )
     474                 :            :         {
     475 [ +  - ][ +  - ]:          6 :             if( aStr == pEntry->aStr )
     476                 :            :             {
     477                 :            :                 // then insert here
     478                 :            :                 pFnd = new SwCalcExp( aStr, SwSbxValue(),
     479 [ +  - ][ +  - ]:          6 :                                     ((SwCalcFldType*)pEntry)->pFldType );
         [ +  - ][ +  - ]
     480                 :          6 :                 pFnd->pNext = *(VarTable+ii);
     481                 :          6 :                 *(VarTable+ii) = pFnd;
     482                 :          6 :                 break;
     483                 :            :             }
     484                 :            :         }
     485                 :            :     }
     486                 :            : 
     487         [ +  + ]:         24 :     if( pFnd )
     488                 :            :     {
     489                 :          6 :         SwCalcExp* pFndExp = (SwCalcExp*)pFnd;
     490                 :            : 
     491 [ +  - ][ +  - ]:          6 :         if( pFndExp->pFldType && pFndExp->pFldType->Which() == RES_USERFLD )
                 [ +  - ]
     492                 :            :         {
     493                 :          6 :             SwUserFieldType* pUFld = (SwUserFieldType*)pFndExp->pFldType;
     494         [ +  - ]:          6 :             if( nsSwGetSetExpType::GSE_STRING & pUFld->GetType() )
     495                 :            :             {
     496 [ +  - ][ +  - ]:          6 :                 pFndExp->nValue.PutString( pUFld->GetContent() );
         [ +  - ][ +  - ]
     497                 :            :             }
     498         [ #  # ]:          0 :             else if( !pUFld->IsValid() )
     499                 :            :             {
     500                 :            :                 // Save the current values...
     501                 :          0 :                 sal_uInt16          nOld_ListPor        = nListPor;
     502         [ #  # ]:          0 :                 SwSbxValue      nOld_LastLeft       = nLastLeft;
     503         [ #  # ]:          0 :                 SwSbxValue      nOld_NumberValue    = nNumberValue;
     504                 :          0 :                 xub_StrLen      nOld_CommandPos     = nCommandPos;
     505                 :          0 :                 SwCalcOper      eOld_CurrOper       = eCurrOper;
     506                 :          0 :                 SwCalcOper      eOld_CurrListOper   = eCurrListOper;
     507                 :            : 
     508 [ #  # ][ #  # ]:          0 :                 pFndExp->nValue.PutDouble( pUFld->GetValue( *this ) );
     509                 :            : 
     510                 :            :                 // ...and write them back.
     511                 :          0 :                 nListPor        = nOld_ListPor;
     512         [ #  # ]:          0 :                 nLastLeft       = nOld_LastLeft;
     513         [ #  # ]:          0 :                 nNumberValue    = nOld_NumberValue;
     514                 :          0 :                 nCommandPos     = nOld_CommandPos;
     515                 :          0 :                 eCurrOper       = eOld_CurrOper;
     516 [ #  # ][ #  # ]:          0 :                 eCurrListOper   = eOld_CurrListOper;
     517                 :            :             }
     518                 :            :             else
     519                 :            :             {
     520         [ #  # ]:          0 :                 pFndExp->nValue.PutDouble( pUFld->GetValue() );
     521                 :            :             }
     522                 :            :         }
     523                 :          6 :         return pFndExp;
     524                 :            :     }
     525                 :            : 
     526                 :            :     // At this point the "real" case variable has to be used
     527         [ +  - ]:         18 :     String sTmpName( rStr );
     528         [ +  - ]:         18 :     ::ReplacePoint( sTmpName );
     529                 :            : 
     530         [ +  - ]:         18 :     if( !ins )
     531                 :            :     {
     532                 :         18 :         SwNewDBMgr *pMgr = rDoc.GetNewDBMgr();
     533                 :            : 
     534         [ +  - ]:         18 :         String sDBName(GetDBName( sTmpName ));
     535         [ +  - ]:         18 :         String sSourceName(sDBName.GetToken(0, DB_DELIM));
     536 [ +  - ][ +  - ]:         18 :         String sTableName(sDBName.GetToken(0).GetToken(1, DB_DELIM));
                 [ +  - ]
     537 [ +  - ][ -  + ]:         18 :         if( pMgr && sSourceName.Len() && sTableName.Len() &&
         [ #  # ][ #  # ]
                 [ -  + ]
     538         [ #  # ]:          0 :             pMgr->OpenDataSource(sSourceName, sTableName, -1, false))
     539                 :            :         {
     540         [ #  # ]:          0 :             String sColumnName( GetColumnName( sTmpName ));
     541                 :            :             OSL_ENSURE(sColumnName.Len(), "Missing DB column name");
     542                 :            : 
     543 [ #  # ][ #  # ]:          0 :             String sDBNum( SwFieldType::GetTypeStr(TYP_DBSETNUMBERFLD) );
     544 [ #  # ][ #  # ]:          0 :             sDBNum = pCharClass->lowercase(sDBNum);
                 [ #  # ]
     545                 :            : 
     546                 :            :             // Initialize again because this doesn't happen in docfld anymore for
     547                 :            :             // elements != RES_DBFLD. E.g. if there is an expression field before
     548                 :            :             // an DB_Field in a document.
     549 [ #  # ][ #  # ]:          0 :             VarChange( sDBNum, pMgr->GetSelectedRecordId(sSourceName, sTableName));
     550                 :            : 
     551 [ #  # ][ #  # ]:          0 :             if( sDBNum.EqualsIgnoreCaseAscii(sColumnName) )
     552                 :            :             {
     553 [ #  # ][ #  # ]:          0 :                 aErrExpr.nValue.PutLong(long(pMgr->GetSelectedRecordId(sSourceName, sTableName)));
     554                 :          0 :                 return &aErrExpr;
     555                 :            :             }
     556                 :            : 
     557                 :          0 :             sal_uLong nTmpRec = 0;
     558 [ #  # ][ #  # ]:          0 :             if( 0 != ( pFnd = Find( sDBNum, VarTable, TBLSZ ) ) )
     559         [ #  # ]:          0 :                 nTmpRec = ((SwCalcExp*)pFnd)->nValue.GetULong();
     560                 :            : 
     561                 :          0 :             rtl::OUString sResult;
     562                 :          0 :             double nNumber = DBL_MAX;
     563                 :            : 
     564 [ #  # ][ #  # ]:          0 :             long nLang = SvxLocaleToLanguage( pLclData->getLocale() );
     565         [ #  # ]:          0 :             if(pMgr->GetColumnCnt( sSourceName, sTableName, sColumnName,
     566         [ #  # ]:          0 :                                     nTmpRec, nLang, sResult, &nNumber ))
     567                 :            :             {
     568         [ #  # ]:          0 :                 if (nNumber != DBL_MAX)
     569         [ #  # ]:          0 :                     aErrExpr.nValue.PutDouble( nNumber );
     570                 :            :                 else
     571         [ #  # ]:          0 :                     aErrExpr.nValue.PutString( sResult );
     572                 :            : 
     573                 :          0 :                 return &aErrExpr;
     574 [ #  # ][ #  # ]:          0 :             }
         [ #  # ][ #  # ]
                 [ #  # ]
     575                 :            :         }
     576                 :            :         else
     577                 :            :         {
     578                 :            :             //data source was not available - set return to "NoValue"
     579                 :         18 :             aErrExpr.nValue.SetVoidValue(true);
     580                 :            :         }
     581                 :            :         // NEVER save!
     582 [ +  - ][ +  - ]:         18 :         return &aErrExpr;
                 [ +  - ]
     583                 :            :     }
     584                 :            : 
     585 [ #  # ][ #  # ]:          0 :     SwCalcExp* pNewExp = new SwCalcExp( aStr, SwSbxValue(), 0 );
         [ #  # ][ #  # ]
     586                 :          0 :     pNewExp->pNext = VarTable[ ii ];
     587                 :          0 :     VarTable[ ii ] = pNewExp;
     588                 :            : 
     589         [ #  # ]:          0 :     String sColumnName( GetColumnName( sTmpName ));
     590                 :            :     OSL_ENSURE( sColumnName.Len(), "Missing DB column name" );
     591         [ #  # ]:          0 :     if( sColumnName.EqualsIgnoreCaseAscii(
     592 [ #  # ][ #  # ]:          0 :                             SwFieldType::GetTypeStr( TYP_DBSETNUMBERFLD ) ))
     593                 :            :     {
     594                 :          0 :         SwNewDBMgr *pMgr = rDoc.GetNewDBMgr();
     595         [ #  # ]:          0 :         String sDBName(GetDBName( sTmpName ));
     596         [ #  # ]:          0 :         String sSourceName(sDBName.GetToken(0, DB_DELIM));
     597 [ #  # ][ #  # ]:          0 :         String sTableName(sDBName.GetToken(0).GetToken(1, DB_DELIM));
                 [ #  # ]
     598 [ #  # ][ #  # ]:          0 :         if( pMgr && sSourceName.Len() && sTableName.Len() &&
                 [ #  # ]
           [ #  #  #  # ]
                 [ #  # ]
     599         [ #  # ]:          0 :             pMgr->OpenDataSource(sSourceName, sTableName, -1, false) &&
     600                 :          0 :             !pMgr->IsInMerge())
     601                 :            :         {
     602 [ #  # ][ #  # ]:          0 :             pNewExp->nValue.PutULong( pMgr->GetSelectedRecordId(sSourceName, sTableName));
     603                 :            :         }
     604                 :            :         else
     605                 :            :         {
     606                 :          0 :             pNewExp->nValue.SetVoidValue(true);
     607 [ #  # ][ #  # ]:          0 :         }
                 [ #  # ]
     608                 :            :     }
     609                 :            : 
     610 [ #  # ][ +  - ]:         24 :     return pNewExp;
                 [ +  - ]
     611                 :            : }
     612                 :            : 
     613                 :          0 : void SwCalc::VarChange( const String& rStr, double nValue )
     614                 :            : {
     615         [ #  # ]:          0 :     SwSbxValue aVal( nValue );
     616 [ #  # ][ #  # ]:          0 :     VarChange( rStr, aVal );
     617                 :          0 : }
     618                 :            : 
     619                 :          0 : void SwCalc::VarChange( const String& rStr, const SwSbxValue& rValue )
     620                 :            : {
     621 [ #  # ][ #  # ]:          0 :     String aStr = pCharClass->lowercase( rStr );
                 [ #  # ]
     622                 :            : 
     623                 :          0 :     sal_uInt16 nPos = 0;
     624         [ #  # ]:          0 :     SwCalcExp* pFnd = (SwCalcExp*)Find( aStr, VarTable, TBLSZ, &nPos );
     625                 :            : 
     626         [ #  # ]:          0 :     if( !pFnd )
     627                 :            :     {
     628 [ #  # ][ #  # ]:          0 :         pFnd = new SwCalcExp( aStr, SwSbxValue( rValue ), 0 );
         [ #  # ][ #  # ]
     629                 :          0 :         pFnd->pNext = VarTable[ nPos ];
     630                 :          0 :         VarTable[ nPos ] = pFnd;
     631                 :            :     }
     632                 :            :     else
     633                 :            :     {
     634         [ #  # ]:          0 :         pFnd->nValue = rValue;
     635         [ #  # ]:          0 :     }
     636                 :          0 : }
     637                 :            : 
     638                 :          0 : bool SwCalc::Push( const SwUserFieldType* pUserFieldType )
     639                 :            : {
     640 [ #  # ][ #  # ]:          0 :     if( aRekurStk.end() != std::find(aRekurStk.begin(), aRekurStk.end(), pUserFieldType ) )
     641                 :          0 :         return false;
     642                 :            : 
     643                 :          0 :     aRekurStk.push_back( pUserFieldType );
     644                 :          0 :     return true;
     645                 :            : }
     646                 :            : 
     647                 :          0 : void SwCalc::Pop()
     648                 :            : {
     649                 :            :     OSL_ENSURE( aRekurStk.size(), "SwCalc: Pop on an invalid pointer" );
     650                 :            : 
     651                 :          0 :     aRekurStk.pop_back();
     652                 :          0 : }
     653                 :            : 
     654                 :         84 : SwCalcOper SwCalc::GetToken()
     655                 :            : {
     656                 :            : #if OSL_DEBUG_LEVEL > 1
     657                 :            :     // static for switch back to the "old" implementation of the calculator
     658                 :            :     // which doesn't use the I18N routines.
     659                 :            :     static int nUseOld = 0;
     660                 :            :     if( !nUseOld )
     661                 :            :     {
     662                 :            : #endif
     663                 :            : 
     664         [ +  + ]:         84 :     if( nCommandPos >= sCommand.Len() )
     665                 :         48 :         return eCurrOper = CALC_ENDCALC;
     666                 :            : 
     667                 :            :     using namespace ::com::sun::star::i18n;
     668                 :            :     {
     669                 :            :         // Parse any token.
     670                 :            :         ParseResult aRes = pCharClass->parseAnyToken( sCommand, nCommandPos,
     671                 :            :                                                       coStartFlags, aEmptyStr,
     672         [ +  - ]:         36 :                                                       coContFlags, aEmptyStr );
     673                 :            : 
     674                 :         36 :         sal_Bool bSetError = sal_True;
     675                 :         36 :         xub_StrLen nRealStt = nCommandPos + (xub_StrLen)aRes.LeadingWhiteSpace;
     676         [ -  + ]:         36 :         if( aRes.TokenType & (KParseType::ASC_NUMBER | KParseType::UNI_NUMBER) )
     677                 :            :         {
     678         [ #  # ]:          0 :             nNumberValue.PutDouble( aRes.Value );
     679                 :          0 :             eCurrOper = CALC_NUMBER;
     680                 :          0 :             bSetError = sal_False;
     681                 :            :         }
     682         [ +  + ]:         36 :         else if( aRes.TokenType & KParseType::IDENTNAME )
     683                 :            :         {
     684                 :            :             String aName( sCommand.Copy( nRealStt,
     685         [ +  - ]:         30 :                             static_cast<xub_StrLen>(aRes.EndPos) - nRealStt ));
     686                 :            :             //#101436#: The variable may contain a database name. It must not be
     687                 :            :             // converted to lower case! Instead all further comparisons must be
     688                 :            :             // done case-insensitive
     689 [ +  - ][ +  - ]:         30 :             String sLowerCaseName = pCharClass->lowercase( aName );
                 [ +  - ]
     690                 :            :             // catch currency symbol
     691 [ -  + ][ +  - ]:         30 :             if( sLowerCaseName == sCurrSym )
     692                 :            :             {
     693                 :          0 :                 nCommandPos = (xub_StrLen)aRes.EndPos;
     694         [ #  # ]:          0 :                 return GetToken(); // call again
     695                 :            :             }
     696                 :            : 
     697                 :            :             // catch operators
     698         [ +  - ]:         30 :             _CalcOp* pFnd = ::FindOperator( sLowerCaseName );
     699         [ +  + ]:         30 :             if( pFnd )
     700                 :            :             {
     701   [ -  -  -  -  :          6 :                 switch( ( eCurrOper = ((_CalcOp*)pFnd)->eOp ) )
                      + ]
     702                 :            :                 {
     703                 :            :                 case CALC_SUM:
     704                 :            :                 case CALC_MEAN:
     705                 :          0 :                     eCurrListOper = CALC_PLUS;
     706                 :          0 :                     break;
     707                 :            :                 case CALC_MIN:
     708                 :          0 :                     eCurrListOper = CALC_MIN_IN;
     709                 :          0 :                     break;
     710                 :            :                 case CALC_MAX:
     711                 :          0 :                     eCurrListOper = CALC_MAX_IN;
     712                 :          0 :                     break;
     713                 :            :                 case CALC_DATE:
     714                 :          0 :                     eCurrListOper = CALC_MONTH;
     715                 :          0 :                     break;
     716                 :            :                 default:
     717                 :          6 :                     break;
     718                 :            :                 }
     719                 :          6 :                 nCommandPos = (xub_StrLen)aRes.EndPos;
     720                 :          6 :                 return eCurrOper;
     721                 :            :             }
     722         [ +  - ]:         24 :             aVarName = aName;
     723                 :         24 :             eCurrOper = CALC_NAME;
     724 [ +  - ][ +  + ]:         30 :             bSetError = sal_False;
         [ +  - ][ +  + ]
     725                 :            :         }
     726         [ +  - ]:          6 :         else if ( aRes.TokenType & KParseType::DOUBLE_QUOTE_STRING )
     727                 :            :         {
     728 [ +  - ][ +  - ]:          6 :             nNumberValue.PutString( String( aRes.DequotedNameOrString ));
         [ +  - ][ +  - ]
     729                 :          6 :             eCurrOper = CALC_NUMBER;
     730                 :          6 :             bSetError = sal_False;
     731                 :            :         }
     732         [ #  # ]:          0 :         else if( aRes.TokenType & KParseType::ONE_SINGLE_CHAR )
     733                 :            :         {
     734                 :            :             String aName( sCommand.Copy( nRealStt,
     735         [ #  # ]:          0 :                               static_cast<xub_StrLen>(aRes.EndPos) - nRealStt ));
     736         [ #  # ]:          0 :             if( 1 == aName.Len() )
     737                 :            :             {
     738                 :          0 :                 bSetError = sal_False;
     739                 :          0 :                 sal_Unicode ch = aName.GetChar( 0 );
     740   [ #  #  #  #  :          0 :                 switch( ch )
                #  #  # ]
     741                 :            :                 {
     742                 :            :                 case ';':
     743 [ #  # ][ #  # ]:          0 :                     if( CALC_MONTH == eCurrListOper || CALC_DAY == eCurrListOper )
     744                 :            :                     {
     745                 :          0 :                         eCurrOper = eCurrListOper;
     746                 :          0 :                         break;
     747                 :            :                     }
     748                 :            : 
     749                 :            :                 case '\n':
     750                 :          0 :                     eCurrOper = CALC_PRINT;
     751                 :          0 :                     break;
     752                 :            : 
     753                 :            :                 case '%':
     754                 :            :                 case '^':
     755                 :            :                 case '*':
     756                 :            :                 case '/':
     757                 :            :                 case '+':
     758                 :            :                 case '-':
     759                 :            :                 case '(':
     760                 :            :                 case ')':
     761                 :          0 :                     eCurrOper = SwCalcOper(ch);
     762                 :          0 :                     break;
     763                 :            : 
     764                 :            :                 case '=':
     765                 :            :                 case '!':
     766                 :            :                     {
     767                 :            :                         SwCalcOper eTmp2;
     768         [ #  # ]:          0 :                         if( '=' == ch )
     769                 :          0 :                             eCurrOper = SwCalcOper('='), eTmp2 = CALC_EQ;
     770                 :            :                         else
     771                 :          0 :                             eCurrOper = CALC_NOT, eTmp2 = CALC_NEQ;
     772                 :            : 
     773   [ #  #  #  # ]:          0 :                         if( aRes.EndPos < sCommand.Len() &&
                 [ #  # ]
     774                 :          0 :                             '=' == sCommand.GetChar( (xub_StrLen)aRes.EndPos ) )
     775                 :            :                         {
     776                 :          0 :                             eCurrOper = eTmp2;
     777                 :          0 :                             ++aRes.EndPos;
     778                 :            :                         }
     779                 :            :                     }
     780                 :          0 :                     break;
     781                 :            : 
     782                 :            :                 case cListDelim:
     783                 :          0 :                     eCurrOper = eCurrListOper;
     784                 :          0 :                     break;
     785                 :            : 
     786                 :            :                 case '[':
     787         [ #  # ]:          0 :                     if( aRes.EndPos < sCommand.Len() )
     788                 :            :                     {
     789         [ #  # ]:          0 :                         aVarName.Erase();
     790                 :          0 :                         xub_StrLen nFndPos = (xub_StrLen)aRes.EndPos,
     791                 :          0 :                                              nSttPos = nFndPos;
     792                 :            : 
     793         [ #  # ]:          0 :                         do {
     794 [ #  # ][ #  # ]:          0 :                             if( STRING_NOTFOUND != ( nFndPos =
     795                 :          0 :                                 sCommand.Search( ']', nFndPos )) )
     796                 :            :                             {
     797                 :            :                                 // ignore the ]
     798         [ #  # ]:          0 :                                 if( '\\' == sCommand.GetChar(nFndPos-1))
     799                 :            :                                 {
     800                 :            :                                     aVarName += sCommand.Copy( nSttPos,
     801 [ #  # ][ #  # ]:          0 :                                                     nFndPos - nSttPos - 1 );
                 [ #  # ]
     802                 :          0 :                                     nSttPos = ++nFndPos;
     803                 :            :                                 }
     804                 :            :                                 else
     805                 :          0 :                                     break;
     806                 :            :                             }
     807                 :            :                         } while( STRING_NOTFOUND != nFndPos );
     808                 :            : 
     809         [ #  # ]:          0 :                         if( STRING_NOTFOUND != nFndPos )
     810                 :            :                         {
     811         [ #  # ]:          0 :                             if( nSttPos != nFndPos )
     812                 :            :                                 aVarName += sCommand.Copy( nSttPos,
     813 [ #  # ][ #  # ]:          0 :                                                     nFndPos - nSttPos );
                 [ #  # ]
     814                 :          0 :                             aRes.EndPos = nFndPos + 1;
     815                 :          0 :                             eCurrOper = CALC_NAME;
     816                 :            :                         }
     817                 :            :                         else
     818                 :          0 :                             bSetError = sal_True;
     819                 :            :                     }
     820                 :            :                     else
     821                 :            :                     {
     822                 :          0 :                         bSetError = sal_True;
     823                 :            :                     }
     824                 :          0 :                     break;
     825                 :            : 
     826                 :            :                 default:
     827                 :          0 :                     bSetError = sal_True;
     828                 :          0 :                     break;
     829                 :            :                 }
     830         [ #  # ]:          0 :             }
     831                 :            :         }
     832         [ #  # ]:          0 :         else if( aRes.TokenType & KParseType::BOOLEAN )
     833                 :            :         {
     834                 :            :             String aName( sCommand.Copy( nRealStt,
     835         [ #  # ]:          0 :                                          static_cast<xub_StrLen>(aRes.EndPos) - nRealStt ));
     836         [ #  # ]:          0 :             if( aName.Len() )
     837                 :            :             {
     838                 :          0 :                 sal_Unicode ch = aName.GetChar(0);
     839                 :            : 
     840                 :          0 :                 bSetError = sal_True;
     841 [ #  # ][ #  # ]:          0 :                 if ('<' == ch || '>' == ch)
     842                 :            :                 {
     843                 :          0 :                     bSetError = sal_False;
     844                 :            : 
     845         [ #  # ]:          0 :                     SwCalcOper eTmp2 = ('<' == ch) ? CALC_LEQ : CALC_GEQ;
     846         [ #  # ]:          0 :                     eCurrOper = ('<' == ch) ? CALC_LES : CALC_GRE;
     847                 :            : 
     848 [ #  # ][ #  # ]:          0 :                     if( 2 == aName.Len() && '=' == aName.GetChar(1) )
                 [ #  # ]
     849                 :          0 :                         eCurrOper = eTmp2;
     850         [ #  # ]:          0 :                     else if( 1 != aName.Len() )
     851                 :          0 :                         bSetError = sal_True;
     852                 :            :                 }
     853         [ #  # ]:          0 :             }
     854                 :            :         }
     855         [ #  # ]:          0 :         else if( nRealStt == sCommand.Len() )
     856                 :            :         {
     857                 :          0 :             eCurrOper = CALC_ENDCALC;
     858                 :          0 :             bSetError = sal_False;
     859                 :            :         }
     860                 :            : 
     861         [ -  + ]:         30 :         if( bSetError )
     862                 :            :         {
     863                 :          0 :             eError = CALC_SYNTAX;
     864                 :          0 :             eCurrOper = CALC_PRINT;
     865                 :            :         }
     866         [ +  + ]:         36 :         nCommandPos = (xub_StrLen)aRes.EndPos;
     867                 :            :     };
     868                 :            : 
     869                 :            : #if OSL_DEBUG_LEVEL > 1
     870                 :            : #define NextCh( s, n )  (nCommandPos < sCommand.Len() ? sCommand.GetChar( nCommandPos++ ) : 0)
     871                 :            : 
     872                 :            :     }
     873                 :            :     else
     874                 :            :     {
     875                 :            :         sal_Unicode ch;
     876                 :            :         sal_Unicode cTSep = pLclData->getNumThousandSep()[0],
     877                 :            :                     cDSep = pLclData->getNumDecimalSep()[0];
     878                 :            : 
     879                 :            :         do {
     880                 :            :             if( 0 == ( ch = NextCh( sCommand, nCommandPos ) ) )
     881                 :            :                 return eCurrOper = CALC_ENDCALC;
     882                 :            :         } while ( ch == '\t' || ch == ' ' || ch == cTSep );
     883                 :            : 
     884                 :            :         if( ch == cDSep )
     885                 :            :             ch = '.';
     886                 :            : 
     887                 :            :         switch( ch )
     888                 :            :         {
     889                 :            :         case ';':
     890                 :            :             if( CALC_MONTH == eCurrListOper || CALC_DAY == eCurrListOper )
     891                 :            :             {
     892                 :            :                 eCurrOper = eCurrListOper;
     893                 :            :                 break;
     894                 :            :             } // else .. no break
     895                 :            :         case '\n':
     896                 :            :             {
     897                 :            :                 sal_Unicode c;
     898                 :            :                 while( nCommandPos < sCommand.Len() &&
     899                 :            :                        ( ( c = sCommand.GetChar( nCommandPos ) ) == ' ' ||
     900                 :            :                        c == '\t' || c == '\x0a' || c == '\x0d' ))
     901                 :            :                 {
     902                 :            :                     ++nCommandPos;
     903                 :            :                 }
     904                 :            :                 eCurrOper = CALC_PRINT;
     905                 :            :             }
     906                 :            :             break;
     907                 :            : 
     908                 :            :         case '%':
     909                 :            :         case '^':
     910                 :            :         case '*':
     911                 :            :         case '/':
     912                 :            :         case '+':
     913                 :            :         case '-':
     914                 :            :         case '(':
     915                 :            :         case ')':
     916                 :            :             eCurrOper = SwCalcOper(ch);
     917                 :            :             break;
     918                 :            : 
     919                 :            :         case '=':
     920                 :            :             if( '=' == sCommand.GetChar( nCommandPos ) )
     921                 :            :             {
     922                 :            :                 ++nCommandPos;
     923                 :            :                 eCurrOper = CALC_EQ;
     924                 :            :             }
     925                 :            :             else
     926                 :            :             {
     927                 :            :                 eCurrOper = SwCalcOper(ch);
     928                 :            :             }
     929                 :            :             break;
     930                 :            : 
     931                 :            :         case '!':
     932                 :            :             if( '=' == sCommand.GetChar( nCommandPos ) )
     933                 :            :             {
     934                 :            :                 ++nCommandPos;
     935                 :            :                 eCurrOper = CALC_NEQ;
     936                 :            :             }
     937                 :            :             else
     938                 :            :             {
     939                 :            :                 eCurrOper = CALC_NOT;
     940                 :            :             }
     941                 :            :             break;
     942                 :            : 
     943                 :            :         case '>':
     944                 :            :         case '<':
     945                 :            :             eCurrOper = '>' == ch  ? CALC_GRE : CALC_LES;
     946                 :            :             if( '=' == (ch = sCommand.GetChar( nCommandPos ) ) )
     947                 :            :             {
     948                 :            :                 ++nCommandPos;
     949                 :            :                 eCurrOper = CALC_GRE == eCurrOper ? CALC_GEQ : CALC_LEQ;
     950                 :            :             }
     951                 :            :             else if( ' ' != ch )
     952                 :            :             {
     953                 :            :                 eError = CALC_SYNTAX;
     954                 :            :                 eCurrOper = CALC_PRINT;
     955                 :            :             }
     956                 :            :             break;
     957                 :            : 
     958                 :            :         case cListDelim :
     959                 :            :             eCurrOper = eCurrListOper;
     960                 :            :             break;
     961                 :            : 
     962                 :            :         case '0':   case '1':   case '2':   case '3':   case '4':
     963                 :            :         case '5':   case '6':   case '7':   case '8':   case '9':
     964                 :            :         case ',':
     965                 :            :         case '.':
     966                 :            :             {
     967                 :            :                 double nVal;
     968                 :            :                 --nCommandPos; //  back to the first char
     969                 :            :                 if( Str2Double( sCommand, nCommandPos, nVal, pLclData ))
     970                 :            :                 {
     971                 :            :                     nNumberValue.PutDouble( nVal );
     972                 :            :                     eCurrOper = CALC_NUMBER;
     973                 :            :                 }
     974                 :            :                 else
     975                 :            :                 {
     976                 :            :                     // erroneous number
     977                 :            :                     eError = CALC_SYNTAX;
     978                 :            :                     eCurrOper = CALC_PRINT;
     979                 :            :                 }
     980                 :            :             }
     981                 :            :             break;
     982                 :            : 
     983                 :            :         case '[':
     984                 :            :             {
     985                 :            :                 String aStr;
     986                 :            :                 sal_Bool bIgnore = sal_False;
     987                 :            :                 do {
     988                 :            :                     while( 0 != ( ch = NextCh( sCommand, nCommandPos  )) &&
     989                 :            :                            ch != ']' )
     990                 :            :                     {
     991                 :            :                         if( !bIgnore && '\\' == ch )
     992                 :            :                             bIgnore = sal_True;
     993                 :            :                         else if( bIgnore )
     994                 :            :                             bIgnore = sal_False;
     995                 :            :                         aStr += ch;
     996                 :            :                     }
     997                 :            : 
     998                 :            :                     if( !bIgnore )
     999                 :            :                         break;
    1000                 :            : 
    1001                 :            :                     aStr.SetChar( aStr.Len() - 1, ch );
    1002                 :            :                 } while( ch );
    1003                 :            : 
    1004                 :            :                 aVarName = aStr;
    1005                 :            :                 eCurrOper = CALC_NAME;
    1006                 :            :             }
    1007                 :            :             break;
    1008                 :            : 
    1009                 :            :         case '"':
    1010                 :            :             {
    1011                 :            :                 xub_StrLen nStt = nCommandPos;
    1012                 :            :                 while( 0 != ( ch = NextCh( sCommand, nCommandPos ) ) &&
    1013                 :            :                        '"' != ch )
    1014                 :            :                 {
    1015                 :            :                     ;
    1016                 :            :                 }
    1017                 :            : 
    1018                 :            :                 xub_StrLen nLen = nCommandPos - nStt;
    1019                 :            :                 if( '"' == ch )
    1020                 :            :                     --nLen;
    1021                 :            :                 nNumberValue.PutString( sCommand.Copy( nStt, nLen ));
    1022                 :            :                 eCurrOper = CALC_NUMBER;
    1023                 :            :             }
    1024                 :            :             break;
    1025                 :            : 
    1026                 :            :         default:
    1027                 :            :             if (ch && (pCharClass->isLetter( sCommand, nCommandPos - 1) ||
    1028                 :            :                 '_' == ch))
    1029                 :            :             {
    1030                 :            :                 xub_StrLen nStt = nCommandPos-1;
    1031                 :            :                 while( 0 != (ch = NextCh( sCommand, nCommandPos )) &&
    1032                 :            :                        (pCharClass->isLetterNumeric( sCommand, nCommandPos - 1) ||
    1033                 :            :                        ch == '_' || ch == '.' ) )
    1034                 :            :                 {
    1035                 :            :                     ;
    1036                 :            :                 }
    1037                 :            : 
    1038                 :            :                 if( ch )
    1039                 :            :                     --nCommandPos;
    1040                 :            : 
    1041                 :            :                 String aStr( sCommand.Copy( nStt, nCommandPos-nStt ));
    1042                 :            :                 aStr = pCharClass->lowercase( aStr );
    1043                 :            : 
    1044                 :            :                 // catch currency symbol
    1045                 :            :                 if( aStr == sCurrSym )
    1046                 :            :                     return GetToken();  // call again
    1047                 :            : 
    1048                 :            :                 // catch operators
    1049                 :            :                 _CalcOp* pFnd = ::FindOperator( aStr );
    1050                 :            :                 if( pFnd )
    1051                 :            :                 {
    1052                 :            :                     switch( ( eCurrOper = ((_CalcOp*)pFnd)->eOp ) )
    1053                 :            :                     {
    1054                 :            :                     case CALC_SUM :
    1055                 :            :                     case CALC_MEAN :
    1056                 :            :                         eCurrListOper = CALC_PLUS;
    1057                 :            :                         break;
    1058                 :            :                     case CALC_MIN :
    1059                 :            :                         eCurrListOper = CALC_MIN_IN;
    1060                 :            :                         break;
    1061                 :            :                     case CALC_MAX :
    1062                 :            :                         eCurrListOper = CALC_MAX_IN;
    1063                 :            :                         break;
    1064                 :            :                     case CALC_DATE :
    1065                 :            :                         eCurrListOper = CALC_MONTH;
    1066                 :            :                         break;
    1067                 :            :                     default :
    1068                 :            :                         break;
    1069                 :            :                     }
    1070                 :            :                     return eCurrOper;
    1071                 :            :                 }
    1072                 :            :                 aVarName = aStr;
    1073                 :            :                 eCurrOper = CALC_NAME;
    1074                 :            :             }
    1075                 :            :             else
    1076                 :            :             {
    1077                 :            :                 eError = CALC_SYNTAX;
    1078                 :            :                 eCurrOper = CALC_PRINT;
    1079                 :            :             }
    1080                 :            :             break;
    1081                 :            :         }
    1082                 :            :     }
    1083                 :            : #endif
    1084                 :         84 :     return eCurrOper;
    1085                 :            : }
    1086                 :            : 
    1087                 :         24 : SwSbxValue SwCalc::Term()
    1088                 :            : {
    1089                 :         24 :     SwSbxValue left( Prim() );
    1090         [ +  - ]:         24 :     nLastLeft = left;
    1091                 :         30 :     for(;;)
    1092                 :            :     {
    1093                 :         30 :         sal_uInt16 nSbxOper = USHRT_MAX;
    1094                 :            : 
    1095   [ -  -  -  -  :         30 :         switch( eCurrOper )
          +  -  -  -  -  
          -  -  -  -  -  
                -  -  + ]
    1096                 :            :         {
    1097                 :            :         case CALC_AND:
    1098                 :            :             {
    1099         [ #  # ]:          0 :                 GetToken();
    1100 [ #  # ][ #  # ]:          0 :                 sal_Bool bB = Prim().GetBool();
                 [ #  # ]
    1101 [ #  # ][ #  # ]:          0 :                 left.PutBool( left.GetBool() && bB );
         [ #  # ][ #  # ]
    1102                 :            :             }
    1103                 :          0 :             break;
    1104                 :            :         case CALC_OR:
    1105                 :            :             {
    1106         [ #  # ]:          0 :                 GetToken();
    1107 [ #  # ][ #  # ]:          0 :                 sal_Bool bB = Prim().GetBool();
                 [ #  # ]
    1108 [ #  # ][ #  # ]:          0 :                 left.PutBool( left.GetBool() || bB );
         [ #  # ][ #  # ]
    1109                 :            :             }
    1110                 :          0 :             break;
    1111                 :            :         case CALC_XOR:
    1112                 :            :             {
    1113         [ #  # ]:          0 :                 GetToken();
    1114 [ #  # ][ #  # ]:          0 :                 sal_Bool bR = Prim().GetBool();
                 [ #  # ]
    1115         [ #  # ]:          0 :                 sal_Bool bL = left.GetBool();
    1116 [ #  # ][ #  # ]:          0 :                 left.PutBool( (bL && !bR) || (!bL && bR) );
         [ #  # ][ #  # ]
                 [ #  # ]
    1117                 :            :             }
    1118                 :          0 :             break;
    1119                 :            : 
    1120                 :          0 :         case CALC_EQ:   nSbxOper = SbxEQ;   break;
    1121                 :          6 :         case CALC_NEQ:  nSbxOper = SbxNE;   break;
    1122                 :          0 :         case CALC_LEQ:  nSbxOper = SbxLE;   break;
    1123                 :          0 :         case CALC_GEQ:  nSbxOper = SbxGE;   break;
    1124                 :          0 :         case CALC_GRE:  nSbxOper = SbxGT;   break;
    1125                 :          0 :         case CALC_LES:  nSbxOper = SbxLT;   break;
    1126                 :            : 
    1127                 :          0 :         case CALC_MUL:  nSbxOper = SbxMUL;  break;
    1128                 :          0 :         case CALC_DIV:  nSbxOper = SbxDIV;  break;
    1129                 :            : 
    1130                 :            :         case CALC_MIN_IN:
    1131                 :            :             {
    1132         [ #  # ]:          0 :                 GetToken();
    1133         [ #  # ]:          0 :                 SwSbxValue e = Prim();
    1134 [ #  # ][ #  # ]:          0 :                 left = left.GetDouble() < e.GetDouble() ? left : e;
         [ #  # ][ #  # ]
                 [ #  # ]
    1135                 :            :             }
    1136                 :          0 :             break;
    1137                 :            :         case CALC_MAX_IN:
    1138                 :            :             {
    1139         [ #  # ]:          0 :                 GetToken();
    1140         [ #  # ]:          0 :                 SwSbxValue e = Prim();
    1141 [ #  # ][ #  # ]:          0 :                 left = left.GetDouble() > e.GetDouble() ? left : e;
         [ #  # ][ #  # ]
                 [ #  # ]
    1142                 :            :             }
    1143                 :          0 :             break;
    1144                 :            :         case CALC_MONTH:
    1145                 :            :             {
    1146         [ #  # ]:          0 :                 GetToken();
    1147         [ #  # ]:          0 :                 SwSbxValue e = Prim();
    1148         [ #  # ]:          0 :                 sal_Int32 nYear = (sal_Int32) floor( left.GetDouble() );
    1149                 :          0 :                 nYear = nYear & 0x0000FFFF;
    1150         [ #  # ]:          0 :                 sal_Int32 nMonth = (sal_Int32) floor( e.GetDouble() );
    1151                 :          0 :                 nMonth = ( nMonth & 0x000000FF ) << 16;
    1152         [ #  # ]:          0 :                 left.PutLong( nMonth + nYear );
    1153         [ #  # ]:          0 :                 eCurrOper = CALC_DAY;
    1154                 :            :             }
    1155                 :          0 :             break;
    1156                 :            :         case CALC_DAY:
    1157                 :            :             {
    1158         [ #  # ]:          0 :                 GetToken();
    1159         [ #  # ]:          0 :                 SwSbxValue e = Prim();
    1160         [ #  # ]:          0 :                 sal_Int32 nYearMonth = (sal_Int32) floor( left.GetDouble() );
    1161                 :          0 :                 nYearMonth = nYearMonth & 0x00FFFFFF;
    1162         [ #  # ]:          0 :                 sal_Int32 nDay = (sal_Int32) floor( e.GetDouble() );
    1163                 :          0 :                 nDay = ( nDay & 0x000000FF ) << 24;
    1164 [ #  # ][ #  # ]:          0 :                 left = lcl_ConvertToDateValue( rDoc, nDay + nYearMonth );
         [ #  # ][ #  # ]
                 [ #  # ]
    1165                 :            :             }
    1166                 :          0 :             break;
    1167                 :            :         case CALC_ROUND:
    1168                 :            :             {
    1169         [ #  # ]:          0 :                 GetToken();
    1170         [ #  # ]:          0 :                 SwSbxValue e = Prim();
    1171                 :            : 
    1172                 :          0 :                 double fVal = 0;
    1173                 :          0 :                 double fFac = 1;
    1174         [ #  # ]:          0 :                 sal_Int32 nDec = (sal_Int32) floor( e.GetDouble() );
    1175 [ #  # ][ #  # ]:          0 :                 if( nDec < -20 || nDec > 20 )
    1176                 :            :                 {
    1177                 :          0 :                     eError = CALC_OVERFLOW;
    1178         [ #  # ]:          0 :                     left.Clear();
    1179                 :            :                     return left;
    1180                 :            :                 }
    1181         [ #  # ]:          0 :                 fVal = left.GetDouble();
    1182                 :            :                 sal_uInt16 i;
    1183         [ #  # ]:          0 :                 if( nDec >= 0)
    1184                 :            :                 {
    1185         [ #  # ]:          0 :                     for (i = 0; i < (sal_uInt16) nDec; ++i )
    1186                 :          0 :                         fFac *= 10.0;
    1187                 :            :                 }
    1188                 :            :                 else
    1189                 :            :                 {
    1190         [ #  # ]:          0 :                     for (i = 0; i < (sal_uInt16) -nDec; ++i )
    1191                 :          0 :                         fFac /= 10.0;
    1192                 :            :                 }
    1193                 :            : 
    1194                 :          0 :                 fVal *= fFac;
    1195                 :            :                 sal_Bool bSign;
    1196         [ #  # ]:          0 :                 if (fVal < 0.0)
    1197                 :            :                 {
    1198                 :          0 :                     fVal *= -1.0;
    1199                 :          0 :                     bSign = sal_True;
    1200                 :            :                 }
    1201                 :            :                 else
    1202                 :            :                 {
    1203                 :          0 :                     bSign = sal_False;
    1204                 :            :                 }
    1205                 :            : 
    1206                 :            :                 // rounding
    1207                 :          0 :                 double fNum = fVal; // find the exponent
    1208                 :          0 :                 int nExp = 0;
    1209         [ #  # ]:          0 :                 if( fNum > 0 )
    1210                 :            :                 {
    1211         [ #  # ]:          0 :                     while( fNum < 1.0 )
    1212                 :          0 :                         fNum *= 10.0, --nExp;
    1213         [ #  # ]:          0 :                     while( fNum >= 10.0 )
    1214                 :          0 :                         fNum /= 10.0, ++nExp;
    1215                 :            :                 }
    1216                 :          0 :                 nExp = 15 - nExp;
    1217         [ #  # ]:          0 :                 if( nExp > 15 )
    1218                 :          0 :                     nExp = 15;
    1219         [ #  # ]:          0 :                 else if( nExp <= 1 )
    1220                 :          0 :                     nExp = 0;
    1221                 :          0 :                 fVal = floor( fVal+ 0.5 + nRoundVal[ nExp ] );
    1222                 :            : 
    1223         [ #  # ]:          0 :                 if (bSign)
    1224                 :          0 :                     fVal *= -1.0;
    1225                 :            : 
    1226                 :          0 :                 fVal /= fFac;
    1227                 :            : 
    1228 [ #  # ][ #  # ]:          0 :                 left.PutDouble( fVal );
                 [ #  # ]
    1229                 :            :             }
    1230                 :          0 :             break;
    1231                 :            : 
    1232                 :            : //#77448# (=2*3^2 != 18)
    1233                 :            : 
    1234                 :            :         default:
    1235                 :         24 :             return left;
    1236                 :            :         }
    1237                 :            : 
    1238         [ +  - ]:          6 :         if( USHRT_MAX != nSbxOper )
    1239                 :            :         {
    1240                 :            :             // #i47706: cast to SbxOperator AFTER comparing to USHRT_MAX
    1241                 :          6 :             SbxOperator eSbxOper = (SbxOperator)nSbxOper;
    1242                 :            : 
    1243         [ +  - ]:          6 :             GetToken();
    1244 [ +  - ][ +  - ]:          6 :             if( SbxEQ <= eSbxOper && eSbxOper <= SbxGE )
    1245                 :            :             {
    1246 [ +  - ][ +  - ]:          6 :                 left.PutBool( left.Compare( eSbxOper, Prim() ));
         [ +  - ][ +  - ]
    1247                 :            :             }
    1248                 :            :             else
    1249                 :            :             {
    1250         [ #  # ]:          0 :                 SwSbxValue aRight( Prim() );
    1251         [ #  # ]:          0 :                 aRight.MakeDouble();
    1252         [ #  # ]:          0 :                 left.MakeDouble();
    1253                 :            : 
    1254 [ #  # ][ #  # ]:          0 :                 if( SbxDIV == eSbxOper && !aRight.GetDouble() )
         [ #  # ][ #  # ]
    1255                 :          0 :                     eError = CALC_ZERODIV;
    1256                 :            :                 else
    1257 [ #  # ][ #  # ]:          6 :                     left.Compute( eSbxOper, aRight );
    1258                 :            :             }
    1259                 :            :         }
    1260                 :          0 :     }
    1261                 :            : }
    1262                 :            : 
    1263                 :            : extern "C" typedef double (*pfCalc)( double );
    1264                 :            : 
    1265                 :         30 : SwSbxValue SwCalc::Prim()
    1266                 :            : {
    1267                 :         30 :     SwSbxValue nErg;
    1268                 :            : 
    1269                 :         30 :     pfCalc pFnc = 0;
    1270                 :            : 
    1271                 :         30 :     sal_Bool bChkTrig = sal_False, bChkPow = sal_False;
    1272                 :            : 
    1273   [ -  -  -  -  :         30 :     switch( eCurrOper )
          -  -  -  +  +  
          -  -  -  -  -  
                   -  - ]
    1274                 :            :     {
    1275                 :          0 :     case CALC_SIN:  pFnc = &sin;  break;
    1276                 :          0 :     case CALC_COS:  pFnc = &cos;  break;
    1277                 :          0 :     case CALC_TAN:  pFnc = &tan;  break;
    1278                 :          0 :     case CALC_ATAN: pFnc = &atan; break;
    1279                 :          0 :     case CALC_ASIN: pFnc = &asin; bChkTrig = sal_True; break;
    1280                 :          0 :     case CALC_ACOS: pFnc = &acos; bChkTrig = sal_True; break;
    1281                 :            : 
    1282                 :            :     case CALC_NOT:
    1283                 :            :         {
    1284         [ #  # ]:          0 :             GetToken();
    1285 [ #  # ][ #  # ]:          0 :             nErg = Prim();
                 [ #  # ]
    1286 [ #  # ][ #  # ]:          0 :             if( SbxSTRING == nErg.GetType() )
    1287                 :            :             {
    1288 [ #  # ][ #  # ]:          0 :                 nErg.PutBool( 0 == nErg.GetString().Len() );
    1289                 :            :             }
    1290 [ #  # ][ #  # ]:          0 :             else if(SbxBOOL == nErg.GetType() )
    1291                 :            :             {
    1292 [ #  # ][ #  # ]:          0 :                 nErg.PutBool(!nErg.GetBool());
    1293                 :            :             }
    1294                 :            :             // Evaluate arguments manually so that the binary NOT below does not
    1295                 :            :             // get called. We want a BOOLEAN NOT.
    1296 [ #  # ][ #  # ]:          0 :             else if (nErg.IsNumeric())
    1297                 :            :             {
    1298 [ #  # ][ #  # ]:          0 :                 nErg.PutLong( nErg.GetDouble() == 0.0 ? 1 : 0 );
                 [ #  # ]
    1299                 :            :             }
    1300                 :            :             else
    1301                 :            :             {
    1302                 :            :                 OSL_FAIL( "unexpected case. computing binary NOT" );
    1303                 :            :                 //!! computes a binary NOT
    1304         [ #  # ]:          0 :                 nErg.Compute( SbxNOT, nErg );
    1305                 :            :             }
    1306                 :            :         }
    1307                 :          0 :         break;
    1308                 :            : 
    1309                 :            :     case CALC_NUMBER:
    1310 [ +  - ][ -  + ]:          6 :         if( GetToken() == CALC_PHD )
    1311                 :            :         {
    1312         [ #  # ]:          0 :             double aTmp = nNumberValue.GetDouble();
    1313                 :          0 :             aTmp *= 0.01;
    1314         [ #  # ]:          0 :             nErg.PutDouble( aTmp );
    1315         [ #  # ]:          0 :             GetToken();
    1316                 :            :         }
    1317         [ -  + ]:          6 :         else if( eCurrOper == CALC_NAME )
    1318                 :            :         {
    1319                 :          0 :             eError = CALC_SYNTAX;
    1320                 :            :         }
    1321                 :            :         else
    1322                 :            :         {
    1323         [ +  - ]:          6 :             nErg = nNumberValue;
    1324                 :          6 :             bChkPow = sal_True;
    1325                 :            :         }
    1326                 :          6 :         break;
    1327                 :            : 
    1328                 :            :     case CALC_NAME:
    1329 [ +  - ][ -  + ]:         24 :         if( GetToken() == CALC_ASSIGN )
    1330                 :            :         {
    1331         [ #  # ]:          0 :             SwCalcExp* n = VarInsert( aVarName );
    1332         [ #  # ]:          0 :             GetToken();
    1333 [ #  # ][ #  # ]:          0 :             nErg = n->nValue = Expr();
         [ #  # ][ #  # ]
    1334                 :            :         }
    1335                 :            :         else
    1336                 :            :         {
    1337 [ +  - ][ +  - ]:         24 :             nErg = VarLook( aVarName )->nValue;
    1338                 :         24 :             bChkPow = sal_True;
    1339                 :            :         }
    1340                 :         24 :         break;
    1341                 :            : 
    1342                 :            :     case CALC_MINUS:
    1343         [ #  # ]:          0 :         GetToken();
    1344 [ #  # ][ #  # ]:          0 :         nErg.PutDouble( -(Prim().GetDouble()) );
         [ #  # ][ #  # ]
    1345                 :          0 :         break;
    1346                 :            : 
    1347                 :            :     case CALC_LP:
    1348                 :            :         {
    1349         [ #  # ]:          0 :             GetToken();
    1350 [ #  # ][ #  # ]:          0 :             nErg = Expr();
                 [ #  # ]
    1351         [ #  # ]:          0 :             if( eCurrOper != CALC_RP )
    1352                 :            :             {
    1353                 :          0 :                 eError = CALC_BRACK;
    1354                 :            :             }
    1355                 :            :             else
    1356                 :            :             {
    1357         [ #  # ]:          0 :                 GetToken();
    1358                 :          0 :                 bChkPow = sal_True; // in order for =(7)^2 to work
    1359                 :            :             }
    1360                 :            :         }
    1361                 :          0 :         break;
    1362                 :            : 
    1363                 :            :     case CALC_MEAN:
    1364                 :            :         {
    1365                 :          0 :             nListPor = 1;
    1366         [ #  # ]:          0 :             GetToken();
    1367 [ #  # ][ #  # ]:          0 :             nErg = Expr();
                 [ #  # ]
    1368         [ #  # ]:          0 :             double aTmp = nErg.GetDouble();
    1369                 :          0 :             aTmp /= nListPor;
    1370         [ #  # ]:          0 :             nErg.PutDouble( aTmp );
    1371                 :            :         }
    1372                 :          0 :         break;
    1373                 :            : 
    1374                 :            :     case CALC_SQRT:
    1375                 :            :         {
    1376         [ #  # ]:          0 :             GetToken();
    1377 [ #  # ][ #  # ]:          0 :             nErg = Prim();
                 [ #  # ]
    1378 [ #  # ][ #  # ]:          0 :             if( nErg.GetDouble() < 0 )
    1379                 :          0 :                 eError = CALC_OVERFLOW;
    1380                 :            :             else
    1381 [ #  # ][ #  # ]:          0 :                 nErg.PutDouble( sqrt( nErg.GetDouble() ));
    1382                 :            :         }
    1383                 :          0 :         break;
    1384                 :            : 
    1385                 :            :     case CALC_SUM:
    1386                 :            :     case CALC_DATE:
    1387                 :            :     case CALC_MIN:
    1388                 :            :     case CALC_MAX:
    1389         [ #  # ]:          0 :         GetToken();
    1390 [ #  # ][ #  # ]:          0 :         nErg = Expr();
                 [ #  # ]
    1391                 :          0 :         break;
    1392                 :            : 
    1393                 :            :     case CALC_ENDCALC:
    1394         [ #  # ]:          0 :         nErg.Clear();
    1395                 :          0 :         break;
    1396                 :            : 
    1397                 :            :     default:
    1398                 :          0 :         eError = CALC_SYNTAX;
    1399                 :          0 :         break;
    1400                 :            :     }
    1401                 :            : 
    1402         [ -  + ]:         30 :     if( pFnc )
    1403                 :            :     {
    1404         [ #  # ]:          0 :         GetToken();
    1405 [ #  # ][ #  # ]:          0 :         double nVal = Prim().GetDouble();
                 [ #  # ]
    1406 [ #  # ][ #  # ]:          0 :         if( !bChkTrig || ( nVal > -1 && nVal < 1 ) )
                 [ #  # ]
    1407 [ #  # ][ #  # ]:          0 :             nErg.PutDouble( (*pFnc)( nVal ) );
    1408                 :            :         else
    1409                 :          0 :             eError = CALC_OVERFLOW;
    1410                 :            :     }
    1411                 :            : 
    1412 [ +  - ][ -  + ]:         30 :     if( bChkPow && eCurrOper == CALC_POW )
    1413                 :            :     {
    1414         [ #  # ]:          0 :         double dleft = nErg.GetDouble();
    1415         [ #  # ]:          0 :         GetToken();
    1416 [ #  # ][ #  # ]:          0 :         double right = Prim().GetDouble();
                 [ #  # ]
    1417                 :            : 
    1418                 :            :         double fraction, integer;
    1419                 :          0 :         fraction = modf( right, &integer );
    1420 [ #  # ][ #  # ]:          0 :         if( ( dleft < 0.0 && 0.0 != fraction ) ||
         [ #  # ][ #  # ]
    1421                 :            :             ( 0.0 == dleft && right < 0.0 ) )
    1422                 :            :         {
    1423                 :          0 :             eError = CALC_OVERFLOW;
    1424         [ #  # ]:          0 :             nErg.Clear();
    1425                 :            :         }
    1426                 :            :         else
    1427                 :            :         {
    1428                 :          0 :             dleft = pow(dleft, right );
    1429         [ #  # ]:          0 :             if( dleft == HUGE_VAL )
    1430                 :            :             {
    1431                 :          0 :                 eError = CALC_POWERR;
    1432         [ #  # ]:          0 :                 nErg.Clear();
    1433                 :            :             }
    1434                 :            :             else
    1435                 :            :             {
    1436         [ #  # ]:          0 :                 nErg.PutDouble( dleft );
    1437                 :            :             }
    1438                 :            :         }
    1439                 :            :     }
    1440                 :            : 
    1441                 :         30 :     return nErg;
    1442                 :            : }
    1443                 :            : 
    1444                 :         24 : SwSbxValue  SwCalc::Expr()
    1445                 :            : {
    1446 [ +  - ][ +  - ]:         24 :     SwSbxValue left = Term(), right;
    1447         [ +  - ]:         24 :     nLastLeft = left;
    1448                 :          0 :     for(;;)
    1449                 :            :     {
    1450      [ -  -  + ]:         24 :         switch(eCurrOper)
    1451                 :            :         {
    1452                 :            :         case CALC_PLUS:
    1453         [ #  # ]:          0 :             GetToken();
    1454         [ #  # ]:          0 :             left.MakeDouble();
    1455 [ #  # ][ #  # ]:          0 :             ( right = Term() ).MakeDouble();
         [ #  # ][ #  # ]
    1456         [ #  # ]:          0 :             left.Compute( SbxPLUS, right );
    1457                 :          0 :             nListPor++;
    1458                 :          0 :             break;
    1459                 :            : 
    1460                 :            :         case CALC_MINUS:
    1461         [ #  # ]:          0 :             GetToken();
    1462         [ #  # ]:          0 :             left.MakeDouble();
    1463 [ #  # ][ #  # ]:          0 :             ( right = Term() ).MakeDouble();
         [ #  # ][ #  # ]
    1464         [ #  # ]:          0 :             left.Compute( SbxMINUS, right );
    1465                 :          0 :             break;
    1466                 :            : 
    1467                 :            :         default:
    1468                 :         24 :             return left;
    1469                 :            :         }
    1470         [ +  - ]:         24 :     }
    1471                 :            : }
    1472                 :            : 
    1473                 :          0 : String SwCalc::GetColumnName(const String& rName)
    1474                 :            : {
    1475                 :          0 :     xub_StrLen nPos = rName.Search(DB_DELIM);
    1476         [ #  # ]:          0 :     if( STRING_NOTFOUND != nPos )
    1477                 :            :     {
    1478                 :          0 :         nPos = rName.Search(DB_DELIM, nPos + 1);
    1479                 :            : 
    1480         [ #  # ]:          0 :         if( STRING_NOTFOUND != nPos )
    1481                 :          0 :             return rName.Copy(nPos + 1);
    1482                 :            :     }
    1483                 :          0 :     return rName;
    1484                 :            : }
    1485                 :            : 
    1486                 :         18 : String SwCalc::GetDBName(const String& rName)
    1487                 :            : {
    1488         [ +  - ]:         18 :     xub_StrLen nPos = rName.Search(DB_DELIM);
    1489         [ -  + ]:         18 :     if( STRING_NOTFOUND != nPos )
    1490                 :            :     {
    1491         [ #  # ]:          0 :         nPos = rName.Search(DB_DELIM, nPos + 1);
    1492                 :            : 
    1493         [ #  # ]:          0 :         if( STRING_NOTFOUND != nPos )
    1494         [ #  # ]:          0 :             return rName.Copy( 0, nPos );
    1495                 :            :     }
    1496         [ +  - ]:         18 :     SwDBData aData = rDoc.GetDBData();
    1497         [ +  - ]:         18 :     String sRet = aData.sDataSource;
    1498         [ +  - ]:         18 :     sRet += DB_DELIM;
    1499 [ +  - ][ +  - ]:         18 :     sRet += String(aData.sCommand);
                 [ +  - ]
    1500 [ +  - ][ +  - ]:         18 :     return sRet;
    1501                 :            : }
    1502                 :            : 
    1503                 :            : namespace
    1504                 :            : {
    1505                 :          0 :     static bool lcl_Str2Double( const String& rCommand, xub_StrLen& rCommandPos,
    1506                 :            :                                 double& rVal,
    1507                 :            :                                 const LocaleDataWrapper* const pLclData )
    1508                 :            :     {
    1509                 :            :         OSL_ASSERT(pLclData);
    1510                 :          0 :         const xub_Unicode nCurrCmdPos = rCommandPos;
    1511                 :            :         rtl_math_ConversionStatus eStatus;
    1512                 :            :         const sal_Unicode* pEnd;
    1513                 :          0 :         rVal = rtl_math_uStringToDouble( rCommand.GetBuffer() + rCommandPos,
    1514                 :          0 :                                          rCommand.GetBuffer() + rCommand.Len(),
    1515         [ #  # ]:          0 :                                          pLclData->getNumDecimalSep()[0],
    1516         [ #  # ]:          0 :                                          pLclData->getNumThousandSep()[0],
    1517                 :            :                                          &eStatus,
    1518                 :          0 :                                          &pEnd );
    1519                 :          0 :         rCommandPos = static_cast<xub_StrLen>(pEnd - rCommand.GetBuffer());
    1520                 :            : 
    1521                 :            :         return rtl_math_ConversionStatus_Ok == eStatus &&
    1522 [ #  # ][ #  # ]:          0 :                nCurrCmdPos != rCommandPos;
    1523                 :            :     }
    1524                 :            : }
    1525                 :            : 
    1526                 :          0 : bool SwCalc::Str2Double( const String& rCommand, xub_StrLen& rCommandPos,
    1527                 :            :                          double& rVal, const LocaleDataWrapper* const pLclData )
    1528                 :            : {
    1529         [ #  # ]:          0 :     const SvtSysLocale aSysLocale;
    1530                 :            :     return lcl_Str2Double( rCommand, rCommandPos, rVal,
    1531 [ #  # ][ #  # ]:          0 :             pLclData ? pLclData : aSysLocale.GetLocaleDataPtr() );
         [ #  # ][ #  # ]
    1532                 :            : }
    1533                 :            : 
    1534                 :          0 : bool SwCalc::Str2Double( const String& rCommand, xub_StrLen& rCommandPos,
    1535                 :            :                          double& rVal, SwDoc* const pDoc )
    1536                 :            : {
    1537         [ #  # ]:          0 :     const SvtSysLocale aSysLocale;
    1538                 :          0 :     ::std::auto_ptr<const LocaleDataWrapper> pLclD;
    1539         [ #  # ]:          0 :     if( pDoc )
    1540                 :            :     {
    1541         [ #  # ]:          0 :         LanguageType eLang = GetDocAppScriptLang( *pDoc );
    1542         [ #  # ]:          0 :         if (eLang !=
    1543 [ #  # ][ #  # ]:          0 :                 SvxLocaleToLanguage(aSysLocale.GetLocaleData().getLocale()))
                 [ #  # ]
    1544                 :            :         {
    1545                 :            :             pLclD.reset( new LocaleDataWrapper(
    1546                 :            :                             ::comphelper::getProcessServiceFactory(),
    1547 [ #  # ][ #  # ]:          0 :                             SvxCreateLocale( eLang ) ) );
         [ #  # ][ #  # ]
    1548                 :            :         }
    1549                 :            :     }
    1550                 :            : 
    1551                 :            :     bool const bRet = lcl_Str2Double( rCommand, rCommandPos, rVal,
    1552 [ #  # ][ #  # ]:          0 :             (pLclD.get()) ? pLclD.get() : aSysLocale.GetLocaleDataPtr() );
                 [ #  # ]
    1553                 :            : 
    1554 [ #  # ][ #  # ]:          0 :     return bRet;
    1555                 :            : }
    1556                 :            : 
    1557                 :          0 : sal_Bool SwCalc::IsValidVarName( const String& rStr, String* pValidName )
    1558                 :            : {
    1559                 :          0 :     sal_Bool bRet = sal_False;
    1560                 :            :     using namespace ::com::sun::star::i18n;
    1561                 :            :     {
    1562                 :            :         // Parse any token.
    1563         [ #  # ]:          0 :         ParseResult aRes = GetAppCharClass().parseAnyToken( rStr, 0,
    1564                 :            :                                                     coStartFlags, aEmptyStr,
    1565         [ #  # ]:          0 :                                                      coContFlags, aEmptyStr );
    1566                 :            : 
    1567         [ #  # ]:          0 :         if( aRes.TokenType & KParseType::IDENTNAME )
    1568                 :            :         {
    1569                 :          0 :             bRet = aRes.EndPos == rStr.Len();
    1570         [ #  # ]:          0 :             if( pValidName )
    1571                 :            :             {
    1572                 :          0 :                 xub_StrLen nRealStt = (xub_StrLen)aRes.LeadingWhiteSpace;
    1573                 :            :                 *pValidName = rStr.Copy( nRealStt,
    1574 [ #  # ][ #  # ]:          0 :                                   static_cast<xub_StrLen>(aRes.EndPos) - nRealStt );
                 [ #  # ]
    1575                 :            :             }
    1576                 :            :         }
    1577         [ #  # ]:          0 :         else if( pValidName )
    1578         [ #  # ]:          0 :             pValidName->Erase();
    1579                 :            :     }
    1580                 :          0 :     return bRet;
    1581                 :            : }
    1582                 :            : 
    1583                 :        714 : SwHash::SwHash( const String& rStr ) :
    1584                 :            :     aStr( rStr ),
    1585                 :        714 :     pNext( 0 )
    1586                 :            : {
    1587                 :        714 : }
    1588                 :            : 
    1589                 :        693 : SwHash::~SwHash()
    1590                 :            : {
    1591 [ +  + ][ +  - ]:        693 :     delete pNext;
    1592         [ -  + ]:        693 : }
    1593                 :            : 
    1594                 :          9 : void DeleteHashTable( SwHash **ppHashTable, sal_uInt16 nCount )
    1595                 :            : {
    1596         [ +  + ]:        324 :     for ( sal_uInt16 i = 0; i < nCount; ++i )
    1597         [ +  + ]:        315 :         delete *(ppHashTable+i);
    1598         [ +  - ]:          9 :     delete [] ppHashTable;
    1599                 :          9 : }
    1600                 :            : 
    1601                 :        654 : SwCalcExp::SwCalcExp( const String& rStr, const SwSbxValue& rVal,
    1602                 :            :                       const SwFieldType* pType )
    1603                 :            :     : SwHash( rStr ),
    1604                 :            :     nValue( rVal ),
    1605         [ +  - ]:        654 :     pFldType( pType )
    1606                 :            : {
    1607                 :        654 : }
    1608                 :            : 
    1609 [ +  - ][ #  # ]:       1668 : SwSbxValue::~SwSbxValue()
    1610                 :            : {
    1611 [ +  - ][ -  + ]:       1668 : }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1612                 :            : 
    1613                 :         18 : sal_Bool SwSbxValue::GetBool() const
    1614                 :            : {
    1615                 :         18 :     return SbxSTRING == GetType() ? 0 != GetString().Len()
    1616         [ -  + ]:         18 :                                   : 0 != SbxValue::GetBool();
    1617                 :            : }
    1618                 :            : 
    1619                 :          0 : double SwSbxValue::GetDouble() const
    1620                 :            : {
    1621                 :            :     double nRet;
    1622 [ #  # ][ #  # ]:          0 :     if( SbxSTRING == GetType() )
    1623                 :            :     {
    1624                 :          0 :         xub_StrLen nStt = 0;
    1625 [ #  # ][ #  # ]:          0 :         SwCalc::Str2Double( GetString(), nStt, nRet );
    1626                 :            :     }
    1627 [ #  # ][ #  # ]:          0 :     else if (IsBool())
    1628                 :            :     {
    1629 [ #  # ][ #  # ]:          0 :         nRet = 0 != GetBool() ? 1.0 : 0.0;
    1630                 :            :     }
    1631                 :            :     else
    1632                 :            :     {
    1633         [ #  # ]:          0 :         nRet = SbxValue::GetDouble();
    1634                 :            :     }
    1635                 :          0 :     return nRet;
    1636                 :            : }
    1637                 :            : 
    1638                 :          0 : SwSbxValue& SwSbxValue::MakeDouble()
    1639                 :            : {
    1640 [ #  # ][ #  # ]:          0 :     if( GetType() == SbxSTRING  || GetType() == SbxBOOL )
                 [ #  # ]
    1641                 :          0 :         PutDouble( GetDouble() );
    1642                 :          0 :     return *this;
    1643                 :            : }
    1644                 :            : 
    1645                 :            : #ifdef STANDALONE_HASHCALC
    1646                 :            : 
    1647                 :            : // this is example code how to create hash values in the CTOR:
    1648                 :            : 
    1649                 :            : #include <stdio.h>
    1650                 :            : void main()
    1651                 :            : {
    1652                 :            :     static sal_Char
    1653                 :            :         sNType0[] = "false",    sNType1[] = "true",     sNType2[] = "pi",
    1654                 :            :         sNType3[] = "e",        sNType4[] = "tables",   sNType5[] = "graf",
    1655                 :            :         sNType6[] = "ole",      sNType7[] = "page",     sNType8[] = "para",
    1656                 :            :         sNType9[] = "word",     sNType10[]= "char",
    1657                 :            :         sNType11[] = "user_company" ,       sNType12[] = "user_firstname" ,
    1658                 :            :         sNType13[] = "user_lastname" ,      sNType14[] = "user_initials",
    1659                 :            :         sNType15[] = "user_street" ,        sNType16[] = "user_country" ,
    1660                 :            :         sNType17[] = "user_zipcode" ,       sNType18[] = "user_city" ,
    1661                 :            :         sNType19[] = "user_title" ,         sNType20[] = "user_position" ,
    1662                 :            :         sNType21[] = "user_tel_home",       sNType22[] = "user_tel_work",
    1663                 :            :         sNType23[] = "user_fax" ,           sNType24[] = "user_email" ,
    1664                 :            :         sNType25[] = "user_state",          sNType26[] = "graph"
    1665                 :            :         ;
    1666                 :            : 
    1667                 :            :     static const sal_Char* sNTypeTab[ 27 ] =
    1668                 :            :     {
    1669                 :            :         sNType0, sNType1, sNType2, sNType3, sNType4, sNType5,
    1670                 :            :         sNType6, sNType7, sNType8, sNType9, sNType10, sNType11,
    1671                 :            :         sNType12, sNType13, sNType14, sNType15, sNType16, sNType17,
    1672                 :            :         sNType18, sNType19, sNType20, sNType21, sNType22, sNType23,
    1673                 :            :         sNType24, sNType25, sNType26
    1674                 :            :     };
    1675                 :            : 
    1676                 :            :     const unsigned short nTblSize = 47;
    1677                 :            :     int aArr[ nTblSize ] = { 0 };
    1678                 :            :     sal_Char ch;
    1679                 :            : 
    1680                 :            :     for( int n = 0; n < 27; ++n )
    1681                 :            :     {
    1682                 :            :         unsigned long ii = 0;
    1683                 :            :         const sal_Char* pp = sNTypeTab[ n ];
    1684                 :            : 
    1685                 :            :         while( *pp )
    1686                 :            :         {
    1687                 :            :             ii = ii << 1 ^ *pp++;
    1688                 :            :         }
    1689                 :            :         ii %= nTblSize;
    1690                 :            : 
    1691                 :            :         ch = aArr[ ii ] ? 'X' : ' ';
    1692                 :            :         aArr[ ii ] = 1;
    1693                 :            :         printf( "%-20s -> %3d [%c]\n", sNTypeTab[ n ], ii, ch );
    1694                 :            :     }
    1695                 :            : }
    1696                 :            : 
    1697                 :            : #endif
    1698                 :            : 
    1699                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10