LCOV - code coverage report
Current view: top level - starmath/source - parse.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 666 1139 58.5 %
Date: 2012-08-25 Functions: 31 48 64.6 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 507 1425 35.6 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*
       3                 :            :  * This file is part of the LibreOffice project.
       4                 :            :  *
       5                 :            :  * This Source Code Form is subject to the terms of the Mozilla Public
       6                 :            :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7                 :            :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8                 :            :  *
       9                 :            :  * This file incorporates work covered by the following license notice:
      10                 :            :  *
      11                 :            :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12                 :            :  *   contributor license agreements. See the NOTICE file distributed
      13                 :            :  *   with this work for additional information regarding copyright
      14                 :            :  *   ownership. The ASF licenses this file to you under the Apache
      15                 :            :  *   License, Version 2.0 (the "License"); you may not use this file
      16                 :            :  *   except in compliance with the License. You may obtain a copy of
      17                 :            :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18                 :            :  */
      19                 :            : 
      20                 :            : #include <stdio.h>
      21                 :            : 
      22                 :            : #define SMDLL 1
      23                 :            : 
      24                 :            : #include <com/sun/star/i18n/UnicodeType.hpp>
      25                 :            : #include <i18npool/lang.h>
      26                 :            : #include <unotools/charclass.hxx>
      27                 :            : #include <editeng/unolingu.hxx>
      28                 :            : #include <unotools/syslocale.hxx>
      29                 :            : #include <sal/macros.h>
      30                 :            : #include "parse.hxx"
      31                 :            : #include "starmath.hrc"
      32                 :            : #include "smdll.hxx"
      33                 :            : #include "smmod.hxx"
      34                 :            : #include "config.hxx"
      35                 :            : 
      36                 :            : #include "node.hxx"
      37                 :            : 
      38                 :            : using namespace ::com::sun::star;
      39                 :            : using namespace ::com::sun::star::i18n;
      40                 :            : 
      41                 :            : ///////////////////////////////////////////////////////////////////////////
      42                 :            : 
      43                 :            : namespace {
      44                 :            : template < typename T >
      45                 :      24264 : T* lcl_popOrZero( ::std::stack<T*> & rStack )
      46                 :            : {
      47         [ -  + ]:      24264 :     if (rStack.empty())
      48                 :          0 :         return 0;
      49                 :      24264 :     T* pTmp = rStack.top();
      50                 :      24264 :     rStack.pop();
      51                 :      24264 :     return pTmp;
      52                 :            : }
      53                 :            : }
      54                 :            : 
      55                 :            : static inline bool strnccmp(const String &u1, xub_StrLen nIdx,
      56                 :            :                               const sal_Char *s2, xub_StrLen nLen)
      57                 :            : {
      58                 :            :     return u1.EqualsIgnoreCaseAscii( s2, nIdx, nLen );
      59                 :            : }
      60                 :            : 
      61                 :            : static const sal_Unicode aDelimiterTable[] =
      62                 :            : {
      63                 :            :     ' ',    '\t',   '\n',   '\r',   '+',    '-',    '*',    '/',    '=',    '#',
      64                 :            :     '%',    '\\',   '"',    '~',    '`',    '>',    '<',    '&',    '|',    '(',
      65                 :            :     ')',    '{',    '}',    '[',    ']',    '^',    '_',
      66                 :            :     '\0'    // end of list symbol
      67                 :            : };
      68                 :            : 
      69                 :            : 
      70                 :      11370 : static inline bool IsDigit( sal_Unicode cChar )
      71                 :            : {
      72 [ +  - ][ +  + ]:      11370 :     return '0' <= cChar && cChar <= '9';
      73                 :            : }
      74                 :            : 
      75                 :            : ///////////////////////////////////////////////////////////////////////////
      76                 :            : 
      77                 :      28420 : SmToken::SmToken() :
      78                 :            :     eType       (TUNKNOWN),
      79                 :      28420 :     cMathChar   ('\0')
      80                 :            : {
      81                 :      28420 :     nGroup = nCol = nRow = nLevel = 0;
      82                 :      28420 : }
      83                 :            : 
      84                 :          0 : SmToken::SmToken(SmTokenType eTokenType,
      85                 :            :                  sal_Unicode cMath,
      86                 :            :                  const sal_Char* pText,
      87                 :            :                  sal_uLong nTokenGroup,
      88                 :          0 :                  sal_uInt16 nTokenLevel) {
      89                 :          0 :     eType = eTokenType;
      90                 :          0 :     cMathChar = cMath;
      91         [ #  # ]:          0 :     aText.AssignAscii(pText);
      92                 :          0 :     nGroup = nTokenGroup;
      93                 :          0 :     nLevel = nTokenLevel;
      94                 :          0 :     nCol = nRow = 0;
      95                 :          0 : }
      96                 :            : 
      97                 :            : ///////////////////////////////////////////////////////////////////////////
      98                 :            : 
      99                 :            : 
     100                 :            : static const SmTokenTableEntry aTokenTable[] =
     101                 :            : {
     102                 :            :     { "Im" , TIM, MS_IM, TGSTANDALONE, 5 },
     103                 :            :     { "MZ23", TDEBUG, '\0', TGATTRIBUT, 0 },
     104                 :            :     { "Re" , TRE, MS_RE, TGSTANDALONE, 5 },
     105                 :            :     { "abs", TABS, '\0', TGUNOPER, 13 },
     106                 :            :     { "arcosh", TACOSH, '\0', TGFUNCTION, 5 },
     107                 :            :     { "arcoth", TACOTH, '\0', TGFUNCTION, 5 },
     108                 :            :     { "acute", TACUTE, MS_ACUTE, TGATTRIBUT, 5 },
     109                 :            :     { "aleph" , TALEPH, MS_ALEPH, TGSTANDALONE, 5 },
     110                 :            :     { "alignb", TALIGNC, '\0', TGALIGN | TGDISCARDED, 0},
     111                 :            :     { "alignc", TALIGNC, '\0', TGALIGN, 0},
     112                 :            :     { "alignl", TALIGNL, '\0', TGALIGN, 0},
     113                 :            :     { "alignm", TALIGNC, '\0', TGALIGN | TGDISCARDED, 0},
     114                 :            :     { "alignr", TALIGNR, '\0', TGALIGN, 0},
     115                 :            :     { "alignt", TALIGNC, '\0', TGALIGN | TGDISCARDED, 0},
     116                 :            :     { "and", TAND, MS_AND, TGPRODUCT, 0},
     117                 :            :     { "approx", TAPPROX, MS_APPROX, TGRELATION, 0},
     118                 :            :     { "arccos", TACOS, '\0', TGFUNCTION, 5},
     119                 :            :     { "arccot", TACOT, '\0', TGFUNCTION, 5},
     120                 :            :     { "arcsin", TASIN, '\0', TGFUNCTION, 5},
     121                 :            :     { "arctan", TATAN, '\0', TGFUNCTION, 5},
     122                 :            :     { "arsinh", TASINH, '\0', TGFUNCTION, 5},
     123                 :            :     { "artanh", TATANH, '\0', TGFUNCTION, 5},
     124                 :            :     { "backepsilon" , TBACKEPSILON, MS_BACKEPSILON, TGSTANDALONE, 5},
     125                 :            :     { "bar", TBAR, MS_BAR, TGATTRIBUT, 5},
     126                 :            :     { "binom", TBINOM, '\0', 0, 5 },
     127                 :            :     { "black", TBLACK, '\0', TGCOLOR, 0},
     128                 :            :     { "blue", TBLUE, '\0', TGCOLOR, 0},
     129                 :            :     { "bold", TBOLD, '\0', TGFONTATTR, 5},
     130                 :            :     { "boper", TBOPER, '\0', TGPRODUCT, 0},
     131                 :            :     { "breve", TBREVE, MS_BREVE, TGATTRIBUT, 5},
     132                 :            :     { "bslash", TBACKSLASH, MS_BACKSLASH, TGPRODUCT, 0 },
     133                 :            :     { "cdot", TCDOT, MS_CDOT, TGPRODUCT, 0},
     134                 :            :     { "check", TCHECK, MS_CHECK, TGATTRIBUT, 5},
     135                 :            :     { "circ" , TCIRC, MS_CIRC, TGSTANDALONE, 5},
     136                 :            :     { "circle", TCIRCLE, MS_CIRCLE, TGATTRIBUT, 5},
     137                 :            :     { "color", TCOLOR, '\0', TGFONTATTR, 5},
     138                 :            :     { "coprod", TCOPROD, MS_COPROD, TGOPER, 5},
     139                 :            :     { "cos", TCOS, '\0', TGFUNCTION, 5},
     140                 :            :     { "cosh", TCOSH, '\0', TGFUNCTION, 5},
     141                 :            :     { "cot", TCOT, '\0', TGFUNCTION, 5},
     142                 :            :     { "coth", TCOTH, '\0', TGFUNCTION, 5},
     143                 :            :     { "csub", TCSUB, '\0', TGPOWER, 0},
     144                 :            :     { "csup", TCSUP, '\0', TGPOWER, 0},
     145                 :            :     { "cyan", TCYAN, '\0', TGCOLOR, 0},
     146                 :            :     { "dddot", TDDDOT, MS_DDDOT, TGATTRIBUT, 5},
     147                 :            :     { "ddot", TDDOT, MS_DDOT, TGATTRIBUT, 5},
     148                 :            :     { "def", TDEF, MS_DEF, TGRELATION, 0},
     149                 :            :     { "div", TDIV, MS_DIV, TGPRODUCT, 0},
     150                 :            :     { "divides", TDIVIDES, MS_LINE, TGRELATION, 0},
     151                 :            :     { "dlarrow" , TDLARROW, MS_DLARROW, TGSTANDALONE, 5},
     152                 :            :     { "dlrarrow" , TDLRARROW, MS_DLRARROW, TGSTANDALONE, 5},
     153                 :            :     { "dot", TDOT, MS_DOT, TGATTRIBUT, 5},
     154                 :            :     { "dotsaxis", TDOTSAXIS, MS_DOTSAXIS, TGSTANDALONE, 5}, // 5 to continue expression
     155                 :            :     { "dotsdiag", TDOTSDIAG, MS_DOTSUP, TGSTANDALONE, 5},   //
     156                 :            :     { "dotsdown", TDOTSDOWN, MS_DOTSDOWN, TGSTANDALONE, 5},  //
     157                 :            :     { "dotslow", TDOTSLOW, MS_DOTSLOW, TGSTANDALONE, 5},    //
     158                 :            :     { "dotsup", TDOTSUP, MS_DOTSUP, TGSTANDALONE, 5},      //
     159                 :            :     { "dotsvert", TDOTSVERT, MS_DOTSVERT, TGSTANDALONE, 5}, //
     160                 :            :     { "downarrow" , TDOWNARROW, MS_DOWNARROW, TGSTANDALONE, 5},
     161                 :            :     { "drarrow" , TDRARROW, MS_DRARROW, TGSTANDALONE, 5},
     162                 :            :     { "emptyset" , TEMPTYSET, MS_EMPTYSET, TGSTANDALONE, 5},
     163                 :            :     { "equiv", TEQUIV, MS_EQUIV, TGRELATION, 0},
     164                 :            :     { "exists", TEXISTS, MS_EXISTS, TGSTANDALONE, 5},
     165                 :            :     { "notexists", TNOTEXISTS, MS_NOTEXISTS, TGSTANDALONE, 5},
     166                 :            :     { "exp", TEXP, '\0', TGFUNCTION, 5},
     167                 :            :     { "fact", TFACT, MS_FACT, TGUNOPER, 5},
     168                 :            :     { "fixed", TFIXED, '\0', TGFONT, 0},
     169                 :            :     { "font", TFONT, '\0', TGFONTATTR, 5},
     170                 :            :     { "forall", TFORALL, MS_FORALL, TGSTANDALONE, 5},
     171                 :            :     { "from", TFROM, '\0', TGLIMIT, 0},
     172                 :            :     { "func", TFUNC, '\0', TGFUNCTION, 5},
     173                 :            :     { "ge", TGE, MS_GE, TGRELATION, 0},
     174                 :            :     { "geslant", TGESLANT, MS_GESLANT, TGRELATION, 0 },
     175                 :            :     { "gg", TGG, MS_GG, TGRELATION, 0},
     176                 :            :     { "grave", TGRAVE, MS_GRAVE, TGATTRIBUT, 5},
     177                 :            :     { "green", TGREEN, '\0', TGCOLOR, 0},
     178                 :            :     { "gt", TGT, MS_GT, TGRELATION, 0},
     179                 :            :     { "hat", THAT, MS_HAT, TGATTRIBUT, 5},
     180                 :            :     { "hbar" , THBAR, MS_HBAR, TGSTANDALONE, 5},
     181                 :            :     { "iiint", TIIINT, MS_IIINT, TGOPER, 5},
     182                 :            :     { "iint", TIINT, MS_IINT, TGOPER, 5},
     183                 :            :     { "in", TIN, MS_IN, TGRELATION, 0},
     184                 :            :     { "infinity" , TINFINITY, MS_INFINITY, TGSTANDALONE, 5},
     185                 :            :     { "infty" , TINFINITY, MS_INFINITY, TGSTANDALONE, 5},
     186                 :            :     { "int", TINT, MS_INT, TGOPER, 5},
     187                 :            :     { "intersection", TINTERSECT, MS_INTERSECT, TGPRODUCT, 0},
     188                 :            :     { "ital", TITALIC, '\0', TGFONTATTR, 5},
     189                 :            :     { "italic", TITALIC, '\0', TGFONTATTR, 5},
     190                 :            :     { "lambdabar" , TLAMBDABAR, MS_LAMBDABAR, TGSTANDALONE, 5},
     191                 :            :     { "langle", TLANGLE, MS_LANGLE, TGLBRACES, 5},
     192                 :            :     { "lbrace", TLBRACE, MS_LBRACE, TGLBRACES, 5},
     193                 :            :     { "lceil", TLCEIL, MS_LCEIL, TGLBRACES, 5},
     194                 :            :     { "ldbracket", TLDBRACKET, MS_LDBRACKET, TGLBRACES, 5},
     195                 :            :     { "ldline", TLDLINE, MS_DLINE, TGLBRACES, 5},
     196                 :            :     { "le", TLE, MS_LE, TGRELATION, 0},
     197                 :            :     { "left", TLEFT, '\0', 0, 5},
     198                 :            :     { "leftarrow" , TLEFTARROW, MS_LEFTARROW, TGSTANDALONE, 5},
     199                 :            :     { "leslant", TLESLANT, MS_LESLANT, TGRELATION, 0 },
     200                 :            :     { "lfloor", TLFLOOR, MS_LFLOOR, TGLBRACES, 5},
     201                 :            :     { "lim", TLIM, '\0', TGOPER, 5},
     202                 :            :     { "liminf", TLIMINF, '\0', TGOPER, 5},
     203                 :            :     { "limsup", TLIMSUP, '\0', TGOPER, 5},
     204                 :            :     { "lint", TLINT, MS_LINT, TGOPER, 5},
     205                 :            :     { "ll", TLL, MS_LL, TGRELATION, 0},
     206                 :            :     { "lline", TLLINE, MS_LINE, TGLBRACES, 5},
     207                 :            :     { "llint", TLLINT, MS_LLINT, TGOPER, 5},
     208                 :            :     { "lllint", TLLLINT, MS_LLLINT, TGOPER, 5},
     209                 :            :     { "ln", TLN, '\0', TGFUNCTION, 5},
     210                 :            :     { "log", TLOG, '\0', TGFUNCTION, 5},
     211                 :            :     { "lsub", TLSUB, '\0', TGPOWER, 0},
     212                 :            :     { "lsup", TLSUP, '\0', TGPOWER, 0},
     213                 :            :     { "lt", TLT, MS_LT, TGRELATION, 0},
     214                 :            :     { "magenta", TMAGENTA, '\0', TGCOLOR, 0},
     215                 :            :     { "matrix", TMATRIX, '\0', 0, 5},
     216                 :            :     { "minusplus", TMINUSPLUS, MS_MINUSPLUS, TGUNOPER | TGSUM, 5},
     217                 :            :     { "mline", TMLINE, MS_LINE, 0, 0},      //! nicht in TGRBRACES, Level 0
     218                 :            :     { "nabla", TNABLA, MS_NABLA, TGSTANDALONE, 5},
     219                 :            :     { "nbold", TNBOLD, '\0', TGFONTATTR, 5},
     220                 :            :     { "ndivides", TNDIVIDES, MS_NDIVIDES, TGRELATION, 0},
     221                 :            :     { "neg", TNEG, MS_NEG, TGUNOPER, 5 },
     222                 :            :     { "neq", TNEQ, MS_NEQ, TGRELATION, 0},
     223                 :            :     { "newline", TNEWLINE, '\0', 0, 0},
     224                 :            :     { "ni", TNI, MS_NI, TGRELATION, 0},
     225                 :            :     { "nitalic", TNITALIC, '\0', TGFONTATTR, 5},
     226                 :            :     { "none", TNONE, '\0', TGLBRACES | TGRBRACES, 0},
     227                 :            :     { "nospace", TNOSPACE, '\0', TGSTANDALONE, 5},
     228                 :            :     { "notin", TNOTIN, MS_NOTIN, TGRELATION, 0},
     229                 :            :     { "nroot", TNROOT, MS_SQRT, TGUNOPER, 5},
     230                 :            :     { "nsubset", TNSUBSET, MS_NSUBSET, TGRELATION, 0 },
     231                 :            :     { "nsupset", TNSUPSET, MS_NSUPSET, TGRELATION, 0 },
     232                 :            :     { "nsubseteq", TNSUBSETEQ, MS_NSUBSETEQ, TGRELATION, 0 },
     233                 :            :     { "nsupseteq", TNSUPSETEQ, MS_NSUPSETEQ, TGRELATION, 0 },
     234                 :            :     { "odivide", TODIVIDE, MS_ODIVIDE, TGPRODUCT, 0},
     235                 :            :     { "odot", TODOT, MS_ODOT, TGPRODUCT, 0},
     236                 :            :     { "ominus", TOMINUS, MS_OMINUS, TGSUM, 0},
     237                 :            :     { "oper", TOPER, '\0', TGOPER, 5},
     238                 :            :     { "oplus", TOPLUS, MS_OPLUS, TGSUM, 0},
     239                 :            :     { "or", TOR, MS_OR, TGSUM, 0},
     240                 :            :     { "ortho", TORTHO, MS_ORTHO, TGRELATION, 0},
     241                 :            :     { "otimes", TOTIMES, MS_OTIMES, TGPRODUCT, 0},
     242                 :            :     { "over", TOVER, '\0', TGPRODUCT, 0},
     243                 :            :     { "overbrace", TOVERBRACE, MS_OVERBRACE, TGPRODUCT, 5},
     244                 :            :     { "overline", TOVERLINE, '\0', TGATTRIBUT, 5},
     245                 :            :     { "overstrike", TOVERSTRIKE, '\0', TGATTRIBUT, 5},
     246                 :            :     { "owns", TNI, MS_NI, TGRELATION, 0},
     247                 :            :     { "parallel", TPARALLEL, MS_DLINE, TGRELATION, 0},
     248                 :            :     { "partial", TPARTIAL, MS_PARTIAL, TGSTANDALONE, 5 },
     249                 :            :     { "phantom", TPHANTOM, '\0', TGFONTATTR, 5},
     250                 :            :     { "plusminus", TPLUSMINUS, MS_PLUSMINUS, TGUNOPER | TGSUM, 5},
     251                 :            :     { "prec", TPRECEDES, MS_PRECEDES, TGRELATION, 0 },
     252                 :            :     { "preccurlyeq", TPRECEDESEQUAL, MS_PRECEDESEQUAL, TGRELATION, 0 },
     253                 :            :     { "precsim", TPRECEDESEQUIV, MS_PRECEDESEQUIV, TGRELATION, 0 },
     254                 :            :     { "nprec", TNOTPRECEDES, MS_NOTPRECEDES, TGRELATION, 0 },
     255                 :            :     { "prod", TPROD, MS_PROD, TGOPER, 5},
     256                 :            :     { "prop", TPROP, MS_PROP, TGRELATION, 0},
     257                 :            :     { "rangle", TRANGLE, MS_RANGLE, TGRBRACES, 0},  //! 0 to terminate expression
     258                 :            :     { "rbrace", TRBRACE, MS_RBRACE, TGRBRACES, 0},  //
     259                 :            :     { "rceil", TRCEIL, MS_RCEIL, TGRBRACES, 0}, //
     260                 :            :     { "rdbracket", TRDBRACKET, MS_RDBRACKET, TGRBRACES, 0}, //
     261                 :            :     { "rdline", TRDLINE, MS_DLINE, TGRBRACES, 0},   //
     262                 :            :     { "red", TRED, '\0', TGCOLOR, 0},
     263                 :            :     { "rfloor", TRFLOOR, MS_RFLOOR, TGRBRACES, 0},  //! 0 to terminate expression
     264                 :            :     { "right", TRIGHT, '\0', 0, 0},
     265                 :            :     { "rightarrow" , TRIGHTARROW, MS_RIGHTARROW, TGSTANDALONE, 5},
     266                 :            :     { "rline", TRLINE, MS_LINE, TGRBRACES, 0},  //! 0 to terminate expression
     267                 :            :     { "rsub", TRSUB, '\0', TGPOWER, 0},
     268                 :            :     { "rsup", TRSUP, '\0', TGPOWER, 0},
     269                 :            :     { "sans", TSANS, '\0', TGFONT, 0},
     270                 :            :     { "serif", TSERIF, '\0', TGFONT, 0},
     271                 :            :     { "setC" , TSETC, MS_SETC, TGSTANDALONE, 5},
     272                 :            :     { "setN" , TSETN, MS_SETN, TGSTANDALONE, 5},
     273                 :            :     { "setQ" , TSETQ, MS_SETQ, TGSTANDALONE, 5},
     274                 :            :     { "setR" , TSETR, MS_SETR, TGSTANDALONE, 5},
     275                 :            :     { "setZ" , TSETZ, MS_SETZ, TGSTANDALONE, 5},
     276                 :            :     { "setminus", TBACKSLASH, MS_BACKSLASH, TGPRODUCT, 0 },
     277                 :            :     { "sim", TSIM, MS_SIM, TGRELATION, 0},
     278                 :            :     { "simeq", TSIMEQ, MS_SIMEQ, TGRELATION, 0},
     279                 :            :     { "sin", TSIN, '\0', TGFUNCTION, 5},
     280                 :            :     { "sinh", TSINH, '\0', TGFUNCTION, 5},
     281                 :            :     { "size", TSIZE, '\0', TGFONTATTR, 5},
     282                 :            :     { "slash", TSLASH, MS_SLASH, TGPRODUCT, 0 },
     283                 :            :     { "sqrt", TSQRT, MS_SQRT, TGUNOPER, 5},
     284                 :            :     { "stack", TSTACK, '\0', 0, 5},
     285                 :            :     { "sub", TRSUB, '\0', TGPOWER, 0},
     286                 :            :     { "subset", TSUBSET, MS_SUBSET, TGRELATION, 0},
     287                 :            :     { "succ", TSUCCEEDS, MS_SUCCEEDS, TGRELATION, 0 },
     288                 :            :     { "succcurlyeq", TSUCCEEDSEQUAL, MS_SUCCEEDSEQUAL, TGRELATION, 0 },
     289                 :            :     { "succsim", TSUCCEEDSEQUIV, MS_SUCCEEDSEQUIV, TGRELATION, 0 },
     290                 :            :     { "nsucc", TNOTSUCCEEDS, MS_NOTSUCCEEDS, TGRELATION, 0 },
     291                 :            :     { "subseteq", TSUBSETEQ, MS_SUBSETEQ, TGRELATION, 0},
     292                 :            :     { "sum", TSUM, MS_SUM, TGOPER, 5},
     293                 :            :     { "sup", TRSUP, '\0', TGPOWER, 0},
     294                 :            :     { "supset", TSUPSET, MS_SUPSET, TGRELATION, 0},
     295                 :            :     { "supseteq", TSUPSETEQ, MS_SUPSETEQ, TGRELATION, 0},
     296                 :            :     { "tan", TTAN, '\0', TGFUNCTION, 5},
     297                 :            :     { "tanh", TTANH, '\0', TGFUNCTION, 5},
     298                 :            :     { "tilde", TTILDE, MS_TILDE, TGATTRIBUT, 5},
     299                 :            :     { "times", TTIMES, MS_TIMES, TGPRODUCT, 0},
     300                 :            :     { "to", TTO, '\0', TGLIMIT, 0},
     301                 :            :     { "toward", TTOWARD, MS_RIGHTARROW, TGRELATION, 0},
     302                 :            :     { "transl", TTRANSL, MS_TRANSL, TGRELATION, 0},
     303                 :            :     { "transr", TTRANSR, MS_TRANSR, TGRELATION, 0},
     304                 :            :     { "underbrace", TUNDERBRACE, MS_UNDERBRACE, TGPRODUCT, 5},
     305                 :            :     { "underline", TUNDERLINE, '\0', TGATTRIBUT, 5},
     306                 :            :     { "union", TUNION, MS_UNION, TGSUM, 0},
     307                 :            :     { "uoper", TUOPER, '\0', TGUNOPER, 5},
     308                 :            :     { "uparrow" , TUPARROW, MS_UPARROW, TGSTANDALONE, 5},
     309                 :            :     { "vec", TVEC, MS_VEC, TGATTRIBUT, 5},
     310                 :            :     { "white", TWHITE, '\0', TGCOLOR, 0},
     311                 :            :     { "widebslash", TWIDEBACKSLASH, MS_BACKSLASH, TGPRODUCT, 0 },
     312                 :            :     { "widehat", TWIDEHAT, MS_HAT, TGATTRIBUT, 5},
     313                 :            :     { "widetilde", TWIDETILDE, MS_TILDE, TGATTRIBUT, 5},
     314                 :            :     { "wideslash", TWIDESLASH, MS_SLASH, TGPRODUCT, 0 },
     315                 :            :     { "widevec", TWIDEVEC, MS_VEC, TGATTRIBUT, 5},
     316                 :            :     { "wp" , TWP, MS_WP, TGSTANDALONE, 5},
     317                 :            :     { "yellow", TYELLOW, '\0', TGCOLOR, 0},
     318                 :            :     { "", TEND, '\0', 0, 0}
     319                 :            : };
     320                 :            : 
     321                 :       9138 : const SmTokenTableEntry * SmParser::GetTokenTableEntry( const String &rName )
     322                 :            : {
     323                 :       9138 :     const SmTokenTableEntry * pRes = 0;
     324         [ +  - ]:       9138 :     if (rName.Len())
     325                 :            :     {
     326         [ +  + ]:    1561936 :         for (size_t i = 0; i < SAL_N_ELEMENTS(aTokenTable); ++i)
     327                 :            :         {
     328         [ +  + ]:    1552798 :             if (rName.EqualsIgnoreCaseAscii( aTokenTable[i].pIdent ))
     329                 :            :             {
     330                 :       4962 :                 pRes = &aTokenTable[i];
     331                 :       4962 :                 break;
     332                 :            :             }
     333                 :            :         }
     334                 :            :     }
     335                 :            : 
     336                 :       9138 :     return pRes;
     337                 :            : }
     338                 :            : 
     339                 :            : 
     340                 :            : ///////////////////////////////////////////////////////////////////////////
     341                 :            : 
     342                 :            : #if OSL_DEBUG_LEVEL > 1
     343                 :            : 
     344                 :            : bool SmParser::IsDelimiter( const String &rTxt, xub_StrLen nPos )
     345                 :            :     // returns 'true' iff cChar is '\0' or a delimeter
     346                 :            : {
     347                 :            :     OSL_ENSURE( nPos <= rTxt.Len(), "index out of range" );
     348                 :            : 
     349                 :            :     sal_Unicode cChar = rTxt.GetChar( nPos );
     350                 :            :     if(!cChar)
     351                 :            :         return true;
     352                 :            : 
     353                 :            :     // check if 'cChar' is in the delimeter table
     354                 :            :     const sal_Unicode *pDelim = &aDelimiterTable[0];
     355                 :            :     for ( ;  *pDelim != 0;  pDelim++)
     356                 :            :         if (*pDelim == cChar)
     357                 :            :             break;
     358                 :            : 
     359                 :            : 
     360                 :            :     sal_Int16 nTypJp = SM_MOD()->GetSysLocale().GetCharClass().getType( rTxt, nPos );
     361                 :            :     bool bIsDelim = (*pDelim != 0 ||
     362                 :            :             nTypJp == com::sun::star::i18n::UnicodeType::SPACE_SEPARATOR ||
     363                 :            :             nTypJp == com::sun::star::i18n::UnicodeType::CONTROL);
     364                 :            : 
     365                 :            :     return bIsDelim;
     366                 :            : }
     367                 :            : 
     368                 :            : #endif
     369                 :            : 
     370                 :          0 : void SmParser::Insert(const String &rText, sal_uInt16 nPos)
     371                 :            : {
     372                 :          0 :     m_aBufferString.Insert(rText, nPos);
     373                 :            : 
     374                 :          0 :     xub_StrLen  nLen = rText.Len();
     375                 :          0 :     m_nBufferIndex = m_nBufferIndex + nLen;
     376                 :          0 :     m_nTokenIndex  = m_nTokenIndex + nLen;
     377                 :          0 : }
     378                 :            : 
     379                 :            : 
     380                 :          0 : void SmParser::Replace( sal_uInt16 nPos, sal_uInt16 nLen, const String &rText )
     381                 :            : {
     382                 :            :     OSL_ENSURE( nPos + nLen <= m_aBufferString.Len(), "argument mismatch" );
     383                 :            : 
     384                 :          0 :     m_aBufferString.Replace( nPos, nLen, rText );
     385                 :          0 :     sal_Int16  nChg = rText.Len() - nLen;
     386                 :          0 :     m_nBufferIndex = m_nBufferIndex + nChg;
     387                 :          0 :     m_nTokenIndex = m_nTokenIndex + nChg;
     388                 :          0 : }
     389                 :            : 
     390                 :            : 
     391                 :            : // First character may be any alphabetic
     392                 :            : const sal_Int32 coStartFlags =
     393                 :            :         KParseTokens::ANY_LETTER_OR_NUMBER |
     394                 :            :         KParseTokens::IGNORE_LEADING_WS;
     395                 :            : 
     396                 :            : // Continuing characters may be any alphanumeric or dot.
     397                 :            : const sal_Int32 coContFlags =
     398                 :            :     ((coStartFlags | KParseTokens::ASC_DOT) & ~KParseTokens::IGNORE_LEADING_WS)
     399                 :            :     | KParseTokens::TWO_DOUBLE_QUOTES_BREAK_STRING;
     400                 :            : 
     401                 :            : // First character for numbers, may be any numeric or dot
     402                 :            : const sal_Int32 coNumStartFlags =
     403                 :            :         KParseTokens::ASC_DIGIT |
     404                 :            :         KParseTokens::ASC_DOT |
     405                 :            :         KParseTokens::IGNORE_LEADING_WS;
     406                 :            : // Continuing characters for numbers, may be any numeric or dot.
     407                 :            : const sal_Int32 coNumContFlags =
     408                 :            :     (coNumStartFlags | KParseTokens::ASC_DOT) & ~KParseTokens::IGNORE_LEADING_WS;
     409                 :            : 
     410                 :      26828 : void SmParser::NextToken()
     411                 :            : {
     412 [ +  + ][ +  - ]:      26828 :     static const String aEmptyStr;
         [ +  - ][ #  # ]
     413                 :            : 
     414                 :      26828 :     xub_StrLen  nBufLen = m_aBufferString.Len();
     415                 :      26828 :     ParseResult aRes;
     416                 :            :     xub_StrLen  nRealStart;
     417                 :            :     bool        bCont;
     418                 :      26828 :     bool        bNumStart = false;
     419 [ +  - ][ +  - ]:      26828 :     CharClass   aCC(SM_MOD()->GetSysLocale().GetCharClass().getLocale());
         [ +  - ][ +  - ]
                 [ +  - ]
     420         [ -  + ]:      26828 :     do
     421                 :            :     {
     422                 :            :         // skip white spaces
     423         [ +  + ]:      67106 :         while (UnicodeType::SPACE_SEPARATOR ==
     424         [ +  - ]:      40278 :                         aCC.getType( m_aBufferString, m_nBufferIndex ))
     425                 :      13450 :            ++m_nBufferIndex;
     426                 :            : 
     427                 :      26828 :         sal_Int32 nStartFlags = coStartFlags;
     428                 :      26828 :         sal_Int32 nContFlags  = coContFlags;
     429                 :      26828 :         sal_Unicode cFirstChar = m_aBufferString.GetChar( m_nBufferIndex );
     430                 :            :         aRes = aCC.parseAnyToken( m_aBufferString, m_nBufferIndex,
     431                 :            :                                             nStartFlags, aEmptyStr,
     432         [ +  - ]:      26828 :                                             nContFlags, aEmptyStr );
     433                 :            : 
     434                 :            :         // #i45779# parse numbers correctly
     435                 :            :         // i.e. independent from the locale setting.
     436                 :            :         // (note that #i11752# remains fixed)
     437 [ +  + ][ +  + ]:      26828 :         if ((aRes.TokenType & KParseType::IDENTNAME) && IsDigit( cFirstChar ))
                 [ +  + ]
     438                 :            :         {
     439                 :       2232 :             ParseResult aTmpRes;
     440         [ +  - ]:       2232 :             lang::Locale aOldLoc( aCC.getLocale() );
     441         [ +  - ]:       2232 :             aCC.setLocale( m_aDotLoc );
     442                 :            :             aTmpRes = aCC.parsePredefinedToken(
     443                 :            :                             KParseType::ASC_NUMBER,
     444                 :            :                             m_aBufferString, m_nBufferIndex,
     445                 :            :                             KParseTokens::ASC_DIGIT, aEmptyStr,
     446         [ +  - ]:       2232 :                             KParseTokens::ASC_DIGIT | KParseTokens::ASC_DOT, aEmptyStr );
     447         [ +  - ]:       2232 :             aCC.setLocale( aOldLoc );
     448         [ +  - ]:       2232 :             if (aTmpRes.TokenType & KParseType::ASC_NUMBER)
     449                 :       2232 :                 aRes.TokenType = aTmpRes.TokenType;
     450                 :            :         }
     451                 :            : 
     452                 :      26828 :         nRealStart = m_nBufferIndex + sal::static_int_cast< xub_StrLen >(aRes.LeadingWhiteSpace);
     453                 :      26828 :         m_nBufferIndex = nRealStart;
     454                 :            : 
     455                 :      26828 :         bCont = false;
     456   [ +  +  -  + ]:      27350 :         if ( aRes.TokenType == 0  &&
         [ -  + ][ +  + ]
     457                 :            :                 nRealStart < nBufLen &&
     458                 :        522 :                 '\n' == m_aBufferString.GetChar( nRealStart ) )
     459                 :            :         {
     460                 :            :             // keep data needed for tokens row and col entry up to date
     461                 :          0 :             ++m_Row;
     462                 :          0 :             m_nBufferIndex = m_nColOff = nRealStart + 1;
     463                 :          0 :             bCont = true;
     464                 :            :         }
     465         [ +  + ]:      26828 :         else if (aRes.TokenType & KParseType::ONE_SINGLE_CHAR)
     466                 :            :         {
     467         [ +  - ]:      13324 :             String aName( m_aBufferString.Copy( nRealStart, 2 ));
     468 [ +  - ][ -  + ]:      13324 :             if ( aName.EqualsAscii( "%%" ))
     469                 :            :             {
     470                 :            :                 //SkipComment
     471                 :          0 :                 m_nBufferIndex = nRealStart + 2;
     472   [ #  #  #  # ]:          0 :                 while (m_nBufferIndex < nBufLen  &&
                 [ #  # ]
     473                 :          0 :                     '\n' != m_aBufferString.GetChar( m_nBufferIndex ))
     474                 :          0 :                     ++m_nBufferIndex;
     475                 :          0 :                 bCont = true;
     476         [ +  - ]:      13324 :             }
     477                 :            :         }
     478                 :            : 
     479                 :            :     } while (bCont);
     480                 :            : 
     481                 :            :     // set index of current token
     482                 :      26828 :     m_nTokenIndex = m_nBufferIndex;
     483                 :            : 
     484                 :      26828 :     m_aCurToken.nRow   = m_Row;
     485                 :      26828 :     m_aCurToken.nCol   = nRealStart - m_nColOff + 1;
     486                 :            : 
     487                 :      26828 :     bool bHandled = true;
     488         [ +  + ]:      26828 :     if (nRealStart >= nBufLen)
     489                 :            :     {
     490                 :       1324 :         m_aCurToken.eType    = TEND;
     491                 :       1324 :         m_aCurToken.cMathChar = '\0';
     492                 :       1324 :         m_aCurToken.nGroup       = 0;
     493                 :       1324 :         m_aCurToken.nLevel       = 0;
     494         [ +  - ]:       1324 :         m_aCurToken.aText.Erase();
     495                 :            :     }
     496 [ +  + ][ -  + ]:      25504 :     else if ((aRes.TokenType & (KParseType::ASC_NUMBER | KParseType::UNI_NUMBER))
                 [ #  # ]
     497                 :            :              || (bNumStart && (aRes.TokenType & KParseType::IDENTNAME)))
     498                 :            :     {
     499                 :       2268 :         sal_Int32 n = aRes.EndPos - nRealStart;
     500                 :            :         OSL_ENSURE( n >= 0, "length < 0" );
     501                 :       2268 :         m_aCurToken.eType      = TNUMBER;
     502                 :       2268 :         m_aCurToken.cMathChar  = '\0';
     503                 :       2268 :         m_aCurToken.nGroup     = 0;
     504                 :       2268 :         m_aCurToken.nLevel     = 5;
     505 [ +  - ][ +  - ]:       2268 :         m_aCurToken.aText      = m_aBufferString.Copy( nRealStart, sal::static_int_cast< xub_StrLen >(n) );
                 [ +  - ]
     506                 :            : 
     507                 :            : #if OSL_DEBUG_LEVEL > 1
     508                 :            :         if (!IsDelimiter( m_aBufferString, static_cast< xub_StrLen >(aRes.EndPos) ))
     509                 :            :         {
     510                 :            :             OSL_FAIL( "identifier really finished? (compatibility!)" );
     511                 :            :         }
     512                 :            : #endif
     513                 :            :     }
     514         [ -  + ]:      23236 :     else if (aRes.TokenType & KParseType::DOUBLE_QUOTE_STRING)
     515                 :            :     {
     516                 :          0 :         m_aCurToken.eType      = TTEXT;
     517                 :          0 :         m_aCurToken.cMathChar  = '\0';
     518                 :          0 :         m_aCurToken.nGroup     = 0;
     519                 :          0 :         m_aCurToken.nLevel     = 5;
     520         [ #  # ]:          0 :         m_aCurToken.aText     = aRes.DequotedNameOrString;
     521                 :          0 :         m_aCurToken.nRow       = m_Row;
     522                 :          0 :         m_aCurToken.nCol       = nRealStart - m_nColOff + 2;
     523                 :            :     }
     524         [ +  + ]:      23236 :     else if (aRes.TokenType & KParseType::IDENTNAME)
     525                 :            :     {
     526                 :       9138 :         sal_Int32 n = aRes.EndPos - nRealStart;
     527                 :            :         OSL_ENSURE( n >= 0, "length < 0" );
     528         [ +  - ]:       9138 :         String aName( m_aBufferString.Copy( nRealStart, sal::static_int_cast< xub_StrLen >(n) ) );
     529         [ +  - ]:       9138 :         const SmTokenTableEntry *pEntry = GetTokenTableEntry( aName );
     530                 :            : 
     531         [ +  + ]:       9138 :         if (pEntry)
     532                 :            :         {
     533                 :       4962 :             m_aCurToken.eType      = pEntry->eType;
     534                 :       4962 :             m_aCurToken.cMathChar  = pEntry->cMathChar;
     535                 :       4962 :             m_aCurToken.nGroup     = pEntry->nGroup;
     536                 :       4962 :             m_aCurToken.nLevel     = pEntry->nLevel;
     537         [ +  - ]:       4962 :             m_aCurToken.aText.AssignAscii( pEntry->pIdent );
     538                 :            :         }
     539                 :            :         else
     540                 :            :         {
     541                 :       4176 :             m_aCurToken.eType      = TIDENT;
     542                 :       4176 :             m_aCurToken.cMathChar  = '\0';
     543                 :       4176 :             m_aCurToken.nGroup     = 0;
     544                 :       4176 :             m_aCurToken.nLevel     = 5;
     545         [ +  - ]:       4176 :             m_aCurToken.aText      = aName;
     546                 :            : 
     547                 :            : #if OSL_DEBUG_LEVEL > 1
     548                 :            :             if (!IsDelimiter( m_aBufferString, static_cast< xub_StrLen >(aRes.EndPos) ))
     549                 :            :             {
     550                 :            :                 OSL_FAIL( "identifier really finished? (compatibility!)" );
     551                 :            :             }
     552                 :            : #endif
     553         [ +  - ]:       9138 :         }
     554                 :            :     }
     555 [ +  + ][ -  + ]:      14098 :     else if (aRes.TokenType == 0  &&  '_' == m_aBufferString.GetChar( nRealStart ))
                 [ -  + ]
     556                 :            :     {
     557                 :          0 :         m_aCurToken.eType    = TRSUB;
     558                 :          0 :         m_aCurToken.cMathChar = '\0';
     559                 :          0 :         m_aCurToken.nGroup       = TGPOWER;
     560                 :          0 :         m_aCurToken.nLevel       = 0;
     561         [ #  # ]:          0 :         m_aCurToken.aText.AssignAscii( "_" );
     562                 :            : 
     563                 :          0 :         aRes.EndPos = nRealStart + 1;
     564                 :            :     }
     565         [ +  + ]:      14098 :     else if (aRes.TokenType & KParseType::BOOLEAN)
     566                 :            :     {
     567                 :        252 :         sal_Int32   &rnEndPos = aRes.EndPos;
     568                 :            :         String  aName( m_aBufferString.Copy( nRealStart,
     569         [ +  - ]:        252 :                         sal::static_int_cast< xub_StrLen >(rnEndPos - nRealStart) ));
     570         [ +  - ]:        252 :         if (2 >= aName.Len())
     571                 :            :         {
     572                 :        252 :             sal_Unicode ch = aName.GetChar( 0 );
     573      [ +  +  - ]:        252 :             switch (ch)
     574                 :            :             {
     575                 :            :                 case '<':
     576                 :            :                     {
     577         [ -  + ]:        234 :                         if (m_aBufferString.Copy( nRealStart, 2 ).
     578 [ +  - ][ +  - ]:        234 :                                 EqualsAscii( "<<" ))
                 [ +  - ]
     579                 :            :                         {
     580                 :          0 :                             m_aCurToken.eType    = TLL;
     581                 :          0 :                             m_aCurToken.cMathChar = MS_LL;
     582                 :          0 :                             m_aCurToken.nGroup       = TGRELATION;
     583                 :          0 :                             m_aCurToken.nLevel       = 0;
     584         [ #  # ]:          0 :                             m_aCurToken.aText.AssignAscii( "<<" );
     585                 :            : 
     586                 :          0 :                             rnEndPos = nRealStart + 2;
     587                 :            :                         }
     588         [ -  + ]:        234 :                         else if (m_aBufferString.Copy( nRealStart, 2 ).
     589 [ +  - ][ +  - ]:        234 :                                 EqualsAscii( "<=" ))
                 [ +  - ]
     590                 :            :                         {
     591                 :          0 :                             m_aCurToken.eType    = TLE;
     592                 :          0 :                             m_aCurToken.cMathChar = MS_LE;
     593                 :          0 :                             m_aCurToken.nGroup       = TGRELATION;
     594                 :          0 :                             m_aCurToken.nLevel       = 0;
     595         [ #  # ]:          0 :                             m_aCurToken.aText.AssignAscii( "<=" );
     596                 :            : 
     597                 :          0 :                             rnEndPos = nRealStart + 2;
     598                 :            :                         }
     599         [ -  + ]:        234 :                         else if (m_aBufferString.Copy( nRealStart, 2 ).
     600 [ +  - ][ +  - ]:        234 :                                 EqualsAscii( "<>" ))
                 [ +  - ]
     601                 :            :                         {
     602                 :          0 :                             m_aCurToken.eType    = TNEQ;
     603                 :          0 :                             m_aCurToken.cMathChar = MS_NEQ;
     604                 :          0 :                             m_aCurToken.nGroup       = TGRELATION;
     605                 :          0 :                             m_aCurToken.nLevel       = 0;
     606         [ #  # ]:          0 :                             m_aCurToken.aText.AssignAscii( "<>" );
     607                 :            : 
     608                 :          0 :                             rnEndPos = nRealStart + 2;
     609                 :            :                         }
     610         [ +  + ]:        234 :                         else if (m_aBufferString.Copy( nRealStart, 3 ).
     611 [ +  - ][ +  - ]:        234 :                                 EqualsAscii( "<?>" ))
                 [ +  - ]
     612                 :            :                         {
     613                 :        108 :                             m_aCurToken.eType    = TPLACE;
     614                 :        108 :                             m_aCurToken.cMathChar = MS_PLACE;
     615                 :        108 :                             m_aCurToken.nGroup       = 0;
     616                 :        108 :                             m_aCurToken.nLevel       = 5;
     617         [ +  - ]:        108 :                             m_aCurToken.aText.AssignAscii( "<?>" );
     618                 :            : 
     619                 :        108 :                             rnEndPos = nRealStart + 3;
     620                 :            :                         }
     621                 :            :                         else
     622                 :            :                         {
     623                 :        126 :                             m_aCurToken.eType    = TLT;
     624                 :        126 :                             m_aCurToken.cMathChar = MS_LT;
     625                 :        126 :                             m_aCurToken.nGroup       = TGRELATION;
     626                 :        126 :                             m_aCurToken.nLevel       = 0;
     627         [ +  - ]:        126 :                             m_aCurToken.aText.AssignAscii( "<" );
     628                 :            :                         }
     629                 :            :                     }
     630                 :        234 :                     break;
     631                 :            :                 case '>':
     632                 :            :                     {
     633         [ -  + ]:         18 :                         if (m_aBufferString.Copy( nRealStart, 2 ).
     634 [ +  - ][ +  - ]:         18 :                                 EqualsAscii( ">=" ))
                 [ +  - ]
     635                 :            :                         {
     636                 :          0 :                             m_aCurToken.eType    = TGE;
     637                 :          0 :                             m_aCurToken.cMathChar = MS_GE;
     638                 :          0 :                             m_aCurToken.nGroup       = TGRELATION;
     639                 :          0 :                             m_aCurToken.nLevel       = 0;
     640         [ #  # ]:          0 :                             m_aCurToken.aText.AssignAscii( ">=" );
     641                 :            : 
     642                 :          0 :                             rnEndPos = nRealStart + 2;
     643                 :            :                         }
     644         [ -  + ]:         18 :                         else if (m_aBufferString.Copy( nRealStart, 2 ).
     645 [ +  - ][ +  - ]:         18 :                                 EqualsAscii( ">>" ))
                 [ +  - ]
     646                 :            :                         {
     647                 :          0 :                             m_aCurToken.eType    = TGG;
     648                 :          0 :                             m_aCurToken.cMathChar = MS_GG;
     649                 :          0 :                             m_aCurToken.nGroup       = TGRELATION;
     650                 :          0 :                             m_aCurToken.nLevel       = 0;
     651         [ #  # ]:          0 :                             m_aCurToken.aText.AssignAscii( ">>" );
     652                 :            : 
     653                 :          0 :                             rnEndPos = nRealStart + 2;
     654                 :            :                         }
     655                 :            :                         else
     656                 :            :                         {
     657                 :         18 :                             m_aCurToken.eType    = TGT;
     658                 :         18 :                             m_aCurToken.cMathChar = MS_GT;
     659                 :         18 :                             m_aCurToken.nGroup       = TGRELATION;
     660                 :         18 :                             m_aCurToken.nLevel       = 0;
     661         [ +  - ]:         18 :                             m_aCurToken.aText.AssignAscii( ">" );
     662                 :            :                         }
     663                 :            :                     }
     664                 :         18 :                     break;
     665                 :            :                 default:
     666                 :        252 :                     bHandled = false;
     667                 :            :             }
     668         [ +  - ]:        252 :         }
     669                 :            :     }
     670         [ +  + ]:      13846 :     else if (aRes.TokenType & KParseType::ONE_SINGLE_CHAR)
     671                 :            :     {
     672                 :      13324 :         sal_Int32   &rnEndPos = aRes.EndPos;
     673                 :            :         String  aName( m_aBufferString.Copy( nRealStart,
     674         [ +  - ]:      13324 :                             sal::static_int_cast< xub_StrLen >(rnEndPos - nRealStart) ) );
     675                 :            : 
     676         [ +  - ]:      13324 :         if (1 == aName.Len())
     677                 :            :         {
     678                 :      13324 :             sal_Unicode ch = aName.GetChar( 0 );
     679   [ -  +  +  +  :      13324 :             switch (ch)
          +  -  +  -  +  
          -  +  -  +  +  
          -  +  +  -  +  
                   +  + ]
     680                 :            :             {
     681                 :            :                 case '%':
     682                 :            :                     {
     683                 :            :                         //! modifies aRes.EndPos
     684                 :            : 
     685                 :            :                         OSL_ENSURE( rnEndPos >= nBufLen  ||
     686                 :            :                                     '%' != m_aBufferString.GetChar( sal::static_int_cast< xub_StrLen >(rnEndPos) ),
     687                 :            :                                 "unexpected comment start" );
     688                 :            : 
     689                 :            :                         // get identifier of user-defined character
     690                 :            :                         ParseResult aTmpRes = aCC.parseAnyToken(
     691                 :            :                                 m_aBufferString, rnEndPos,
     692                 :            :                                 KParseTokens::ANY_LETTER,
     693                 :            :                                 aEmptyStr,
     694                 :            :                                 coContFlags,
     695         [ #  # ]:          0 :                                 aEmptyStr );
     696                 :            : 
     697                 :            :                         xub_StrLen nTmpStart = sal::static_int_cast< xub_StrLen >(rnEndPos +
     698                 :          0 :                                                     aTmpRes.LeadingWhiteSpace);
     699                 :            : 
     700                 :            :                         // default setting for the case that no identifier
     701                 :            :                         // i.e. a valid symbol-name is following the '%'
     702                 :            :                         // character
     703                 :          0 :                         m_aCurToken.eType      = TTEXT;
     704                 :          0 :                         m_aCurToken.cMathChar  = '\0';
     705                 :          0 :                         m_aCurToken.nGroup     = 0;
     706                 :          0 :                         m_aCurToken.nLevel     = 5;
     707 [ #  # ][ #  # ]:          0 :                         m_aCurToken.aText      = String();
                 [ #  # ]
     708                 :          0 :                         m_aCurToken.nRow       = sal::static_int_cast< xub_StrLen >(m_Row);
     709                 :          0 :                         m_aCurToken.nCol       = nTmpStart - m_nColOff;
     710                 :            : 
     711         [ #  # ]:          0 :                         if (aTmpRes.TokenType & KParseType::IDENTNAME)
     712                 :            :                         {
     713                 :            : 
     714                 :          0 :                             xub_StrLen n = sal::static_int_cast< xub_StrLen >(aTmpRes.EndPos - nTmpStart);
     715                 :          0 :                             m_aCurToken.eType      = TSPECIAL;
     716 [ #  # ][ #  # ]:          0 :                             m_aCurToken.aText      = m_aBufferString.Copy( sal::static_int_cast< xub_StrLen >(nTmpStart-1), n+1 );
                 [ #  # ]
     717                 :            : 
     718                 :            :                             OSL_ENSURE( aTmpRes.EndPos > rnEndPos,
     719                 :            :                                     "empty identifier" );
     720         [ #  # ]:          0 :                             if (aTmpRes.EndPos > rnEndPos)
     721                 :          0 :                                 rnEndPos = aTmpRes.EndPos;
     722                 :            :                             else
     723                 :          0 :                                 ++rnEndPos;
     724                 :          0 :                         }
     725                 :            : 
     726                 :            :                         // if no symbol-name was found we start-over with
     727                 :            :                         // finding the next token right afer the '%' sign.
     728                 :            :                         // I.e. we leave rnEndPos unmodified.
     729                 :            :                     }
     730                 :          0 :                     break;
     731                 :            :                 case '[':
     732                 :            :                     {
     733                 :        108 :                         m_aCurToken.eType    = TLBRACKET;
     734                 :        108 :                         m_aCurToken.cMathChar = MS_LBRACKET;
     735                 :        108 :                         m_aCurToken.nGroup       = TGLBRACES;
     736                 :        108 :                         m_aCurToken.nLevel       = 5;
     737         [ +  - ]:        108 :                         m_aCurToken.aText.AssignAscii( "[" );
     738                 :            :                     }
     739                 :        108 :                     break;
     740                 :            :                 case '\\':
     741                 :            :                     {
     742                 :         90 :                         m_aCurToken.eType    = TESCAPE;
     743                 :         90 :                         m_aCurToken.cMathChar = '\0';
     744                 :         90 :                         m_aCurToken.nGroup       = 0;
     745                 :         90 :                         m_aCurToken.nLevel       = 5;
     746         [ +  - ]:         90 :                         m_aCurToken.aText.AssignAscii( "\\" );
     747                 :            :                     }
     748                 :         90 :                     break;
     749                 :            :                 case ']':
     750                 :            :                     {
     751                 :        108 :                         m_aCurToken.eType    = TRBRACKET;
     752                 :        108 :                         m_aCurToken.cMathChar = MS_RBRACKET;
     753                 :        108 :                         m_aCurToken.nGroup       = TGRBRACES;
     754                 :        108 :                         m_aCurToken.nLevel       = 0;
     755         [ +  - ]:        108 :                         m_aCurToken.aText.AssignAscii( "]" );
     756                 :            :                     }
     757                 :        108 :                     break;
     758                 :            :                 case '^':
     759                 :            :                     {
     760                 :        594 :                         m_aCurToken.eType    = TRSUP;
     761                 :        594 :                         m_aCurToken.cMathChar = '\0';
     762                 :        594 :                         m_aCurToken.nGroup       = TGPOWER;
     763                 :        594 :                         m_aCurToken.nLevel       = 0;
     764         [ +  - ]:        594 :                         m_aCurToken.aText.AssignAscii( "^" );
     765                 :            :                     }
     766                 :        594 :                     break;
     767                 :            :                 case '`':
     768                 :            :                     {
     769                 :          0 :                         m_aCurToken.eType    = TSBLANK;
     770                 :          0 :                         m_aCurToken.cMathChar = '\0';
     771                 :          0 :                         m_aCurToken.nGroup       = TGBLANK;
     772                 :          0 :                         m_aCurToken.nLevel       = 5;
     773         [ #  # ]:          0 :                         m_aCurToken.aText.AssignAscii( "`" );
     774                 :            :                     }
     775                 :          0 :                     break;
     776                 :            :                 case '{':
     777                 :            :                     {
     778                 :       4896 :                         m_aCurToken.eType    = TLGROUP;
     779                 :       4896 :                         m_aCurToken.cMathChar = MS_LBRACE;
     780                 :       4896 :                         m_aCurToken.nGroup       = 0;
     781                 :       4896 :                         m_aCurToken.nLevel       = 5;
     782         [ +  - ]:       4896 :                         m_aCurToken.aText.AssignAscii( "{" );
     783                 :            :                     }
     784                 :       4896 :                     break;
     785                 :            :                 case '|':
     786                 :            :                     {
     787                 :          0 :                         m_aCurToken.eType    = TOR;
     788                 :          0 :                         m_aCurToken.cMathChar = MS_OR;
     789                 :          0 :                         m_aCurToken.nGroup       = TGSUM;
     790                 :          0 :                         m_aCurToken.nLevel       = 0;
     791         [ #  # ]:          0 :                         m_aCurToken.aText.AssignAscii( "|" );
     792                 :            :                     }
     793                 :          0 :                     break;
     794                 :            :                 case '}':
     795                 :            :                     {
     796                 :       4878 :                         m_aCurToken.eType    = TRGROUP;
     797                 :       4878 :                         m_aCurToken.cMathChar = MS_RBRACE;
     798                 :       4878 :                         m_aCurToken.nGroup       = 0;
     799                 :       4878 :                         m_aCurToken.nLevel       = 0;
     800         [ +  - ]:       4878 :                         m_aCurToken.aText.AssignAscii( "}" );
     801                 :            :                     }
     802                 :       4878 :                     break;
     803                 :            :                 case '~':
     804                 :            :                     {
     805                 :          0 :                         m_aCurToken.eType    = TBLANK;
     806                 :          0 :                         m_aCurToken.cMathChar = '\0';
     807                 :          0 :                         m_aCurToken.nGroup       = TGBLANK;
     808                 :          0 :                         m_aCurToken.nLevel       = 5;
     809         [ #  # ]:          0 :                         m_aCurToken.aText.AssignAscii( "~" );
     810                 :            :                     }
     811                 :          0 :                     break;
     812                 :            :                 case '#':
     813                 :            :                     {
     814         [ +  + ]:        216 :                         if (m_aBufferString.Copy( nRealStart, 2 ).
     815 [ +  - ][ +  - ]:        216 :                                 EqualsAscii( "##" ))
                 [ +  - ]
     816                 :            :                         {
     817                 :         36 :                             m_aCurToken.eType    = TDPOUND;
     818                 :         36 :                             m_aCurToken.cMathChar = '\0';
     819                 :         36 :                             m_aCurToken.nGroup       = 0;
     820                 :         36 :                             m_aCurToken.nLevel       = 0;
     821         [ +  - ]:         36 :                             m_aCurToken.aText.AssignAscii( "##" );
     822                 :            : 
     823                 :         36 :                             rnEndPos = nRealStart + 2;
     824                 :            :                         }
     825                 :            :                         else
     826                 :            :                         {
     827                 :        180 :                             m_aCurToken.eType    = TPOUND;
     828                 :        180 :                             m_aCurToken.cMathChar = '\0';
     829                 :        180 :                             m_aCurToken.nGroup       = 0;
     830                 :        180 :                             m_aCurToken.nLevel       = 0;
     831         [ +  - ]:        180 :                             m_aCurToken.aText.AssignAscii( "#" );
     832                 :            :                         }
     833                 :            :                     }
     834                 :        216 :                     break;
     835                 :            :                 case '&':
     836                 :            :                     {
     837                 :          0 :                         m_aCurToken.eType    = TAND;
     838                 :          0 :                         m_aCurToken.cMathChar = MS_AND;
     839                 :          0 :                         m_aCurToken.nGroup       = TGPRODUCT;
     840                 :          0 :                         m_aCurToken.nLevel       = 0;
     841         [ #  # ]:          0 :                         m_aCurToken.aText.AssignAscii( "&" );
     842                 :            :                     }
     843                 :          0 :                     break;
     844                 :            :                 case '(':
     845                 :            :                     {
     846                 :        504 :                         m_aCurToken.eType    = TLPARENT;
     847                 :        504 :                         m_aCurToken.cMathChar = MS_LPARENT;
     848                 :        504 :                         m_aCurToken.nGroup       = TGLBRACES;
     849                 :        504 :                         m_aCurToken.nLevel       = 5;     //! 0 to continue expression
     850         [ +  - ]:        504 :                         m_aCurToken.aText.AssignAscii( "(" );
     851                 :            :                     }
     852                 :        504 :                     break;
     853                 :            :                 case ')':
     854                 :            :                     {
     855                 :        504 :                         m_aCurToken.eType    = TRPARENT;
     856                 :        504 :                         m_aCurToken.cMathChar = MS_RPARENT;
     857                 :        504 :                         m_aCurToken.nGroup       = TGRBRACES;
     858                 :        504 :                         m_aCurToken.nLevel       = 0;     //! 0 to terminate expression
     859         [ +  - ]:        504 :                         m_aCurToken.aText.AssignAscii( ")" );
     860                 :            :                     }
     861                 :        504 :                     break;
     862                 :            :                 case '*':
     863                 :            :                     {
     864                 :          0 :                         m_aCurToken.eType    = TMULTIPLY;
     865                 :          0 :                         m_aCurToken.cMathChar = MS_MULTIPLY;
     866                 :          0 :                         m_aCurToken.nGroup       = TGPRODUCT;
     867                 :          0 :                         m_aCurToken.nLevel       = 0;
     868         [ #  # ]:          0 :                         m_aCurToken.aText.AssignAscii( "*" );
     869                 :            :                     }
     870                 :          0 :                     break;
     871                 :            :                 case '+':
     872                 :            :                     {
     873         [ -  + ]:        612 :                         if (m_aBufferString.Copy( nRealStart, 2 ).
     874 [ +  - ][ +  - ]:        612 :                                 EqualsAscii( "+-" ))
                 [ +  - ]
     875                 :            :                         {
     876                 :          0 :                             m_aCurToken.eType    = TPLUSMINUS;
     877                 :          0 :                             m_aCurToken.cMathChar = MS_PLUSMINUS;
     878                 :          0 :                             m_aCurToken.nGroup       = TGUNOPER | TGSUM;
     879                 :          0 :                             m_aCurToken.nLevel       = 5;
     880         [ #  # ]:          0 :                             m_aCurToken.aText.AssignAscii( "+-" );
     881                 :            : 
     882                 :          0 :                             rnEndPos = nRealStart + 2;
     883                 :            :                         }
     884                 :            :                         else
     885                 :            :                         {
     886                 :        612 :                             m_aCurToken.eType    = TPLUS;
     887                 :        612 :                             m_aCurToken.cMathChar = MS_PLUS;
     888                 :        612 :                             m_aCurToken.nGroup       = TGUNOPER | TGSUM;
     889                 :        612 :                             m_aCurToken.nLevel       = 5;
     890         [ +  - ]:        612 :                             m_aCurToken.aText.AssignAscii( "+" );
     891                 :            :                         }
     892                 :            :                     }
     893                 :        612 :                     break;
     894                 :            :                 case '-':
     895                 :            :                     {
     896         [ -  + ]:        112 :                         if (m_aBufferString.Copy( nRealStart, 2 ).
     897 [ +  - ][ +  - ]:        112 :                                 EqualsAscii( "-+" ))
                 [ +  - ]
     898                 :            :                         {
     899                 :          0 :                             m_aCurToken.eType    = TMINUSPLUS;
     900                 :          0 :                             m_aCurToken.cMathChar = MS_MINUSPLUS;
     901                 :          0 :                             m_aCurToken.nGroup       = TGUNOPER | TGSUM;
     902                 :          0 :                             m_aCurToken.nLevel       = 5;
     903         [ #  # ]:          0 :                             m_aCurToken.aText.AssignAscii( "-+" );
     904                 :            : 
     905                 :          0 :                             rnEndPos = nRealStart + 2;
     906                 :            :                         }
     907                 :            :                         else
     908                 :            :                         {
     909                 :        112 :                             m_aCurToken.eType    = TMINUS;
     910                 :        112 :                             m_aCurToken.cMathChar = MS_MINUS;
     911                 :        112 :                             m_aCurToken.nGroup       = TGUNOPER | TGSUM;
     912                 :        112 :                             m_aCurToken.nLevel       = 5;
     913         [ +  - ]:        112 :                             m_aCurToken.aText.AssignAscii( "-" );
     914                 :            :                         }
     915                 :            :                     }
     916                 :        112 :                     break;
     917                 :            :                 case '.':
     918                 :            :                     {
     919                 :            :                         // for compatibility with SO5.2
     920                 :            :                         // texts like .34 ...56 ... h ...78..90
     921                 :            :                         // will be treated as numbers
     922                 :          0 :                         m_aCurToken.eType     = TNUMBER;
     923                 :          0 :                         m_aCurToken.cMathChar = '\0';
     924                 :          0 :                         m_aCurToken.nGroup       = 0;
     925                 :          0 :                         m_aCurToken.nLevel    = 5;
     926                 :            : 
     927                 :          0 :                         xub_StrLen nTxtStart = m_nBufferIndex;
     928                 :            :                         sal_Unicode cChar;
     929         [ #  # ]:          0 :                         do
           [ #  #  #  # ]
     930                 :            :                         {
     931                 :          0 :                             cChar = m_aBufferString.GetChar( ++m_nBufferIndex );
     932                 :            :                         }
     933                 :          0 :                         while ( cChar == '.' || IsDigit( cChar ) );
     934                 :            : 
     935                 :          0 :                         m_aCurToken.aText = m_aBufferString.Copy( sal::static_int_cast< xub_StrLen >(nTxtStart),
     936 [ #  # ][ #  # ]:          0 :                                                             sal::static_int_cast< xub_StrLen >(m_nBufferIndex - nTxtStart) );
                 [ #  # ]
     937                 :          0 :                         aRes.EndPos = m_nBufferIndex;
     938                 :            :                     }
     939                 :          0 :                     break;
     940                 :            :                 case '/':
     941                 :            :                     {
     942                 :         36 :                         m_aCurToken.eType    = TDIVIDEBY;
     943                 :         36 :                         m_aCurToken.cMathChar = MS_SLASH;
     944                 :         36 :                         m_aCurToken.nGroup       = TGPRODUCT;
     945                 :         36 :                         m_aCurToken.nLevel       = 0;
     946         [ +  - ]:         36 :                         m_aCurToken.aText.AssignAscii( "/" );
     947                 :            :                     }
     948                 :         36 :                     break;
     949                 :            :                 case '=':
     950                 :            :                     {
     951                 :        432 :                         m_aCurToken.eType    = TASSIGN;
     952                 :        432 :                         m_aCurToken.cMathChar = MS_ASSIGN;
     953                 :        432 :                         m_aCurToken.nGroup       = TGRELATION;
     954                 :        432 :                         m_aCurToken.nLevel       = 0;
     955         [ +  - ]:        432 :                         m_aCurToken.aText.AssignAscii( "=" );
     956                 :            :                     }
     957                 :        432 :                     break;
     958                 :            :                 default:
     959                 :      13324 :                     bHandled = false;
     960                 :            :             }
     961         [ +  - ]:      13324 :         }
     962                 :            :     }
     963                 :            :     else
     964                 :        522 :         bHandled = false;
     965                 :            : 
     966         [ +  + ]:      26828 :     if (!bHandled)
     967                 :            :     {
     968                 :        756 :         m_aCurToken.eType      = TCHARACTER;
     969                 :        756 :         m_aCurToken.cMathChar  = '\0';
     970                 :        756 :         m_aCurToken.nGroup     = 0;
     971                 :        756 :         m_aCurToken.nLevel     = 5;
     972 [ +  - ][ +  - ]:        756 :         m_aCurToken.aText      = m_aBufferString.Copy( nRealStart, 1 );
                 [ +  - ]
     973                 :            : 
     974                 :        756 :         aRes.EndPos = nRealStart + 1;
     975                 :            :     }
     976                 :            : 
     977         [ +  + ]:      26828 :     if (TEND != m_aCurToken.eType)
     978         [ +  - ]:      26828 :         m_nBufferIndex = sal::static_int_cast< xub_StrLen >(aRes.EndPos);
     979                 :      26828 : }
     980                 :            : 
     981                 :            : 
     982                 :            : ////////////////////////////////////////
     983                 :            : // grammar
     984                 :            : //
     985                 :            : 
     986                 :            : 
     987                 :       1324 : void SmParser::Table()
     988                 :            : {
     989         [ +  - ]:       1324 :     SmNodeArray  LineArray;
     990                 :            : 
     991         [ +  - ]:       1324 :     Line();
     992         [ -  + ]:       1324 :     while (m_aCurToken.eType == TNEWLINE)
     993                 :            :     {
     994         [ #  # ]:          0 :         NextToken();
     995         [ #  # ]:          0 :         Line();
     996                 :            :     }
     997                 :            : 
     998         [ -  + ]:       1324 :     if (m_aCurToken.eType != TEND)
     999         [ #  # ]:          0 :         Error(PE_UNEXPECTED_CHAR);
    1000                 :            : 
    1001                 :       1324 :     sal_uLong n = m_aNodeStack.size();
    1002                 :            : 
    1003         [ +  - ]:       1324 :     LineArray.resize(n);
    1004                 :            : 
    1005         [ +  + ]:       2648 :     for (sal_uLong i = 0; i < n; i++)
    1006                 :            :     {
    1007         [ +  - ]:       1324 :         LineArray[n - (i + 1)] = m_aNodeStack.top();
    1008         [ +  - ]:       1324 :         m_aNodeStack.pop();
    1009                 :            :     }
    1010                 :            : 
    1011 [ +  - ][ +  - ]:       1324 :     SmStructureNode *pSNode = new SmTableNode(m_aCurToken);
    1012         [ +  - ]:       1324 :     pSNode->SetSubNodes(LineArray);
    1013         [ +  - ]:       1324 :     m_aNodeStack.push(pSNode);
    1014                 :       1324 : }
    1015                 :            : 
    1016                 :            : 
    1017                 :       7194 : void SmParser::Align()
    1018                 :            :     // parse alignment info (if any), then go on with rest of expression
    1019                 :            : {
    1020                 :       7194 :     SmStructureNode *pSNode = 0;
    1021                 :       7194 :     bool    bNeedGroupClose = false;
    1022                 :            : 
    1023         [ -  + ]:       7194 :     if (TokenInGroup(TGALIGN))
    1024                 :            :     {
    1025         [ #  # ]:          0 :         if (CONVERT_40_TO_50 == GetConversion())
    1026                 :            :             // encapsulate expression to be aligned in group braces
    1027                 :            :             // (here group-open brace)
    1028 [ #  # ][ #  # ]:          0 :         {   Insert(rtl::OUString('{'), GetTokenIndex());
                 [ #  # ]
    1029                 :          0 :             bNeedGroupClose = true;
    1030                 :            : 
    1031                 :            :             // get first valid align statement in sequence
    1032                 :            :             // (the dominant one in 4.0) and erase all others (especially old
    1033                 :            :             // discarded tokens) from command string.
    1034         [ #  # ]:          0 :             while (TokenInGroup(TGALIGN))
    1035                 :            :             {
    1036 [ #  # ][ #  # ]:          0 :                 if (TokenInGroup(TGDISCARDED) || pSNode)
                 [ #  # ]
    1037                 :            :                 {
    1038                 :          0 :                     m_nBufferIndex = GetTokenIndex();
    1039                 :          0 :                     m_aBufferString.Erase(m_nBufferIndex, m_aCurToken.aText.Len());
    1040                 :            :                 }
    1041                 :            :                 else
    1042         [ #  # ]:          0 :                     pSNode = new SmAlignNode(m_aCurToken);
    1043                 :            : 
    1044                 :          0 :                 NextToken();
    1045                 :            :             }
    1046                 :            :         }
    1047                 :            :         else
    1048                 :            :         {
    1049         [ #  # ]:          0 :             pSNode = new SmAlignNode(m_aCurToken);
    1050                 :            : 
    1051                 :          0 :             NextToken();
    1052                 :            : 
    1053                 :            :             // allow for just one align statement in 5.0
    1054 [ #  # ][ #  # ]:          0 :             if (CONVERT_40_TO_50 != GetConversion() && TokenInGroup(TGALIGN))
                 [ #  # ]
    1055                 :          0 :             {   Error(PE_DOUBLE_ALIGN);
    1056                 :       7194 :                 return;
    1057                 :            :             }
    1058                 :            :         }
    1059                 :            :     }
    1060                 :            : 
    1061                 :       7194 :     Expression();
    1062                 :            : 
    1063         [ -  + ]:       7194 :     if (bNeedGroupClose)
    1064 [ #  # ][ #  # ]:          0 :         Insert(rtl::OUString('}'), GetTokenIndex());
                 [ #  # ]
    1065                 :            : 
    1066         [ -  + ]:       7194 :     if (pSNode)
    1067                 :            :     {
    1068                 :          0 :         pSNode->SetSubNodes(lcl_popOrZero(m_aNodeStack), 0);
    1069         [ #  # ]:          0 :         m_aNodeStack.push(pSNode);
    1070                 :            :     }
    1071                 :            : }
    1072                 :            : 
    1073                 :            : 
    1074                 :       1324 : void SmParser::Line()
    1075                 :            : {
    1076                 :       1324 :     sal_uInt16  n = 0;
    1077         [ +  - ]:       1324 :     SmNodeArray  ExpressionArray;
    1078                 :            : 
    1079         [ +  - ]:       1324 :     ExpressionArray.resize(n);
    1080                 :            : 
    1081                 :            :     // start with single expression that may have an alignment statement
    1082                 :            :     // (and go on with expressions that must not have alignment
    1083                 :            :     // statements in 'while' loop below. See also 'Expression()'.)
    1084 [ +  + ][ +  - ]:       1324 :     if (m_aCurToken.eType != TEND  &&  m_aCurToken.eType != TNEWLINE)
    1085         [ +  - ]:       1290 :     {   Align();
    1086         [ +  - ]:       1290 :         ExpressionArray.resize(++n);
    1087         [ +  - ]:       1290 :         ExpressionArray[n - 1] = lcl_popOrZero(m_aNodeStack);
    1088                 :            :     }
    1089                 :            : 
    1090 [ -  + ][ #  # ]:       1324 :     while (m_aCurToken.eType != TEND  &&  m_aCurToken.eType != TNEWLINE)
                 [ -  + ]
    1091         [ #  # ]:          0 :     {   if (CONVERT_40_TO_50 != GetConversion())
    1092         [ #  # ]:          0 :             Expression();
    1093                 :            :         else
    1094         [ #  # ]:          0 :             Align();
    1095         [ #  # ]:          0 :         ExpressionArray.resize(++n);
    1096         [ #  # ]:          0 :         ExpressionArray[n - 1] = lcl_popOrZero(m_aNodeStack);
    1097                 :            :     }
    1098                 :            : 
    1099                 :            :     //If there's no expression, add an empty one.
    1100                 :            :     //this is to avoid a formula tree without any caret
    1101                 :            :     //positions, in visual formula editor.
    1102         [ +  + ]:       1324 :     if(ExpressionArray.empty())
    1103 [ +  - ][ +  - ]:         34 :         ExpressionArray.push_back(new SmExpressionNode(SmToken()));
         [ +  - ][ +  - ]
                 [ +  - ]
    1104                 :            : 
    1105 [ +  - ][ +  - ]:       1324 :     SmStructureNode *pSNode = new SmLineNode(m_aCurToken);
    1106         [ +  - ]:       1324 :     pSNode->SetSubNodes(ExpressionArray);
    1107         [ +  - ]:       1324 :     m_aNodeStack.push(pSNode);
    1108                 :       1324 : }
    1109                 :            : 
    1110                 :            : 
    1111                 :       7194 : void SmParser::Expression()
    1112                 :            : {
    1113                 :       7194 :     bool bUseExtraSpaces = true;
    1114         [ +  + ]:       7194 :     if (!m_aNodeStack.empty())
    1115                 :            :     {
    1116         [ +  - ]:        468 :         SmNode *pNode = m_aNodeStack.top();
    1117         [ +  - ]:        468 :         m_aNodeStack.pop();
    1118         [ -  + ]:        468 :         if (pNode->GetToken().eType == TNOSPACE)
    1119                 :          0 :             bUseExtraSpaces = false;
    1120                 :            :         else
    1121         [ +  - ]:        468 :             m_aNodeStack.push(pNode);  // push the node from above again (now to be used as argument to this current 'nospace' node)
    1122                 :            :     }
    1123                 :            : 
    1124                 :       7194 :     sal_uInt16       n = 0;
    1125         [ +  - ]:       7194 :     SmNodeArray  RelationArray;
    1126                 :            : 
    1127         [ +  - ]:       7194 :     RelationArray.resize(n);
    1128                 :            : 
    1129         [ +  - ]:       7194 :     Relation();
    1130         [ +  - ]:       7194 :     RelationArray.resize(++n);
    1131         [ +  - ]:       7194 :     RelationArray[n - 1] = lcl_popOrZero(m_aNodeStack);
    1132                 :            : 
    1133         [ +  + ]:       9912 :     while (m_aCurToken.nLevel >= 4)
    1134         [ +  - ]:       2718 :     {   Relation();
    1135         [ +  - ]:       2718 :         RelationArray.resize(++n);
    1136         [ +  - ]:       2718 :         RelationArray[n - 1] = lcl_popOrZero(m_aNodeStack);
    1137                 :            :     }
    1138                 :            : 
    1139 [ +  - ][ +  - ]:       7194 :     SmExpressionNode *pSNode = new SmExpressionNode(m_aCurToken);
    1140         [ +  - ]:       7194 :     pSNode->SetSubNodes(RelationArray);
    1141                 :       7194 :     pSNode->SetUseExtraSpaces(bUseExtraSpaces);
    1142         [ +  - ]:       7194 :     m_aNodeStack.push(pSNode);
    1143                 :       7194 : }
    1144                 :            : 
    1145                 :            : 
    1146                 :      10308 : void SmParser::Relation()
    1147                 :            : {
    1148                 :      10308 :     Sum();
    1149         [ +  + ]:      10884 :     while (TokenInGroup(TGRELATION))
    1150                 :            :     {
    1151         [ +  - ]:        576 :         SmStructureNode *pSNode  = new SmBinHorNode(m_aCurToken);
    1152                 :        576 :         SmNode *pFirst = lcl_popOrZero(m_aNodeStack);
    1153                 :            : 
    1154                 :        576 :         OpSubSup();
    1155                 :        576 :         SmNode *pSecond = lcl_popOrZero(m_aNodeStack);
    1156                 :            : 
    1157                 :        576 :         Sum();
    1158                 :            : 
    1159                 :        576 :         pSNode->SetSubNodes(pFirst, pSecond, lcl_popOrZero(m_aNodeStack));
    1160         [ +  - ]:        576 :         m_aNodeStack.push(pSNode);
    1161                 :            :     }
    1162                 :      10308 : }
    1163                 :            : 
    1164                 :            : 
    1165                 :      11028 : void SmParser::Sum()
    1166                 :            : {
    1167                 :      11028 :     Product();
    1168         [ +  + ]:      11734 :     while (TokenInGroup(TGSUM))
    1169                 :            :     {
    1170         [ +  - ]:        706 :         SmStructureNode *pSNode  = new SmBinHorNode(m_aCurToken);
    1171                 :        706 :         SmNode *pFirst = lcl_popOrZero(m_aNodeStack);
    1172                 :            : 
    1173                 :        706 :         OpSubSup();
    1174                 :        706 :         SmNode *pSecond = lcl_popOrZero(m_aNodeStack);
    1175                 :            : 
    1176                 :        706 :         Product();
    1177                 :            : 
    1178                 :        706 :         pSNode->SetSubNodes(pFirst, pSecond, lcl_popOrZero(m_aNodeStack));
    1179         [ +  - ]:        706 :         m_aNodeStack.push(pSNode);
    1180                 :            :     }
    1181                 :      11028 : }
    1182                 :            : 
    1183                 :            : 
    1184                 :      11734 : void SmParser::Product()
    1185                 :            : {
    1186                 :      11734 :     Power();
    1187                 :            : 
    1188         [ +  + ]:      12348 :     while (TokenInGroup(TGPRODUCT))
    1189                 :            :     {   SmStructureNode *pSNode;
    1190                 :        614 :         SmNode *pFirst = lcl_popOrZero(m_aNodeStack),
    1191                 :            :                *pOper;
    1192                 :        614 :         bool bSwitchArgs = false;
    1193                 :            : 
    1194                 :        614 :         SmTokenType eType = m_aCurToken.eType;
    1195   [ +  -  +  -  :        614 :         switch (eType)
                      + ]
    1196                 :            :         {
    1197                 :            :             case TOVER:
    1198         [ +  - ]:        504 :                 pSNode = new SmBinVerNode(m_aCurToken);
    1199         [ +  - ]:        504 :                 pOper = new SmRectangleNode(m_aCurToken);
    1200                 :        504 :                 NextToken();
    1201                 :        504 :                 break;
    1202                 :            : 
    1203                 :            :             case TBOPER:
    1204         [ #  # ]:          0 :                 pSNode = new SmBinHorNode(m_aCurToken);
    1205                 :            : 
    1206                 :          0 :                 NextToken();
    1207                 :            : 
    1208                 :            :                 //Let the glyph node know it's a binary operation
    1209                 :          0 :                 m_aCurToken.eType = TBOPER;
    1210                 :          0 :                 m_aCurToken.nGroup = TGPRODUCT;
    1211                 :            : 
    1212                 :          0 :                 GlyphSpecial();
    1213                 :          0 :                 pOper = lcl_popOrZero(m_aNodeStack);
    1214                 :          0 :                 break;
    1215                 :            : 
    1216                 :            :             case TOVERBRACE :
    1217                 :            :             case TUNDERBRACE :
    1218         [ +  - ]:         72 :                 pSNode = new SmVerticalBraceNode(m_aCurToken);
    1219         [ +  - ]:         72 :                 pOper = new SmMathSymbolNode(m_aCurToken);
    1220                 :            : 
    1221                 :         72 :                 NextToken();
    1222                 :         72 :                 break;
    1223                 :            : 
    1224                 :            :             case TWIDEBACKSLASH:
    1225                 :            :             case TWIDESLASH:
    1226                 :            :             {
    1227         [ #  # ]:          0 :                 SmBinDiagonalNode *pSTmp = new SmBinDiagonalNode(m_aCurToken);
    1228                 :          0 :                 pSTmp->SetAscending(eType == TWIDESLASH);
    1229                 :          0 :                 pSNode = pSTmp;
    1230                 :            : 
    1231         [ #  # ]:          0 :                 pOper = new SmPolyLineNode(m_aCurToken);
    1232                 :          0 :                 NextToken();
    1233                 :            : 
    1234                 :          0 :                 bSwitchArgs = true;
    1235                 :          0 :                 break;
    1236                 :            :             }
    1237                 :            : 
    1238                 :            :             default:
    1239         [ +  - ]:         38 :                 pSNode = new SmBinHorNode(m_aCurToken);
    1240                 :            : 
    1241                 :         38 :                 OpSubSup();
    1242                 :         38 :                 pOper = lcl_popOrZero(m_aNodeStack);
    1243                 :            :         }
    1244                 :            : 
    1245                 :        614 :         Power();
    1246                 :            : 
    1247         [ -  + ]:        614 :         if (bSwitchArgs)
    1248                 :            :         {
    1249                 :            :             //! vgl siehe SmBinDiagonalNode::Arrange
    1250                 :          0 :             pSNode->SetSubNodes(pFirst, lcl_popOrZero(m_aNodeStack), pOper);
    1251                 :            :         }
    1252                 :            :         else
    1253                 :            :         {
    1254                 :        614 :             pSNode->SetSubNodes(pFirst, pOper, lcl_popOrZero(m_aNodeStack));
    1255                 :            :         }
    1256         [ +  - ]:        614 :         m_aNodeStack.push(pSNode);
    1257                 :            :     }
    1258                 :      11734 : }
    1259                 :            : 
    1260                 :            : 
    1261                 :      13528 : void SmParser::SubSup(sal_uLong nActiveGroup)
    1262                 :            : {
    1263                 :            :     OSL_ENSURE(nActiveGroup == TGPOWER  ||  nActiveGroup == TGLIMIT,
    1264                 :            :                "Sm: wrong token group");
    1265                 :            : 
    1266         [ +  + ]:      13528 :     if (!TokenInGroup(nActiveGroup))
    1267                 :            :         // already finish
    1268                 :      13528 :         return;
    1269                 :            : 
    1270 [ +  - ][ +  - ]:       1170 :     SmSubSupNode *pNode = new SmSubSupNode(m_aCurToken);
    1271                 :            :     //! Of course 'm_aCurToken' is just the first sub-/supscript token.
    1272                 :            :     //! It should be of no further interest. The positions of the
    1273                 :            :     //! sub-/supscripts will be identified by the corresponding subnodes
    1274                 :            :     //! index in the 'aSubNodes' array (enum value from 'SmSubSup').
    1275                 :            : 
    1276                 :       1170 :     pNode->SetUseLimits(nActiveGroup == TGLIMIT);
    1277                 :            : 
    1278                 :            :     // initialize subnodes array
    1279         [ +  - ]:       1170 :     SmNodeArray  aSubNodes;
    1280         [ +  - ]:       1170 :     aSubNodes.resize(1 + SUBSUP_NUM_ENTRIES);
    1281         [ +  - ]:       1170 :     aSubNodes[0] = lcl_popOrZero(m_aNodeStack);
    1282         [ +  + ]:       8190 :     for (sal_uInt16 i = 1;  i < aSubNodes.size();  i++)
    1283                 :       7020 :         aSubNodes[i] = NULL;
    1284                 :            : 
    1285                 :            :     // process all sub-/supscripts
    1286                 :       1170 :     int  nIndex = 0;
    1287         [ +  + ]:       2664 :     while (TokenInGroup(nActiveGroup))
    1288                 :       1494 :     {   SmTokenType  eType (m_aCurToken.eType);
    1289                 :            : 
    1290                 :            :         // skip sub-/supscript token
    1291         [ +  - ]:       1494 :         NextToken();
    1292                 :            : 
    1293                 :            :         // get sub-/supscript node on top of stack
    1294 [ +  + ][ +  + ]:       1494 :         if (eType == TFROM  ||  eType == TTO)
    1295                 :            :         {
    1296                 :            :             // parse limits in old 4.0 and 5.0 style
    1297         [ +  - ]:        396 :             Relation();
    1298                 :            :         }
    1299                 :            :         else
    1300         [ +  - ]:       1098 :             Term();
    1301                 :            : 
    1302   [ +  +  +  +  :       1494 :         switch (eType)
                +  +  - ]
    1303                 :        216 :         {   case TRSUB :    nIndex = (int) RSUB;    break;
    1304                 :        666 :             case TRSUP :    nIndex = (int) RSUP;    break;
    1305                 :            :             case TFROM :
    1306                 :        252 :             case TCSUB :    nIndex = (int) CSUB;    break;
    1307                 :            :             case TTO :
    1308                 :        216 :             case TCSUP :    nIndex = (int) CSUP;    break;
    1309                 :         72 :             case TLSUB :    nIndex = (int) LSUB;    break;
    1310                 :         72 :             case TLSUP :    nIndex = (int) LSUP;    break;
    1311                 :            :             default :
    1312                 :            :                 OSL_FAIL("Sm: unknown case");
    1313                 :            :         }
    1314                 :       1494 :         nIndex++;
    1315                 :            :         OSL_ENSURE(1 <= nIndex  &&  nIndex <= 1 + SUBSUP_NUM_ENTRIES,
    1316                 :            :                    "SmParser::Power() : sub-/supscript index falsch");
    1317                 :            : 
    1318                 :            :         // set sub-/supscript if not already done
    1319         [ -  + ]:       1494 :         if (aSubNodes[nIndex] != NULL)
    1320         [ #  # ]:          0 :             Error(PE_DOUBLE_SUBSUPSCRIPT);
    1321         [ +  - ]:       1494 :         aSubNodes[nIndex] = lcl_popOrZero(m_aNodeStack);
    1322                 :            :     }
    1323                 :            : 
    1324         [ +  - ]:       1170 :     pNode->SetSubNodes(aSubNodes);
    1325         [ +  - ]:      13528 :     m_aNodeStack.push(pNode);
    1326                 :            : }
    1327                 :            : 
    1328                 :            : 
    1329                 :       1338 : void SmParser::OpSubSup()
    1330                 :            : {
    1331                 :            :     // push operator symbol
    1332 [ +  - ][ +  - ]:       1338 :     m_aNodeStack.push(new SmMathSymbolNode(m_aCurToken));
    1333                 :            :     // skip operator token
    1334                 :       1338 :     NextToken();
    1335                 :            :     // get sub- supscripts if any
    1336         [ -  + ]:       1338 :     if (TokenInGroup(TGPOWER))
    1337                 :          0 :         SubSup(TGPOWER);
    1338                 :       1338 : }
    1339                 :            : 
    1340                 :            : 
    1341                 :      13276 : void SmParser::Power()
    1342                 :            : {
    1343                 :            :     // get body for sub- supscripts on top of stack
    1344                 :      13276 :     Term();
    1345                 :            : 
    1346                 :      13276 :     SubSup(TGPOWER);
    1347                 :      13276 : }
    1348                 :            : 
    1349                 :            : 
    1350                 :          0 : void SmParser::Blank()
    1351                 :            : {
    1352                 :            :     OSL_ENSURE(TokenInGroup(TGBLANK), "Sm : wrong token");
    1353         [ #  # ]:          0 :     SmBlankNode *pBlankNode = new SmBlankNode(m_aCurToken);
    1354                 :            : 
    1355         [ #  # ]:          0 :     while (TokenInGroup(TGBLANK))
    1356                 :            :     {
    1357                 :          0 :         pBlankNode->IncreaseBy(m_aCurToken);
    1358                 :          0 :         NextToken();
    1359                 :            :     }
    1360                 :            : 
    1361                 :            :     // Blanks am Zeilenende ignorieren wenn die entsprechende Option gesetzt ist
    1362         [ #  # ]:          0 :     if ( m_aCurToken.eType == TNEWLINE ||
           [ #  #  #  # ]
                 [ #  # ]
    1363                 :          0 :              (m_aCurToken.eType == TEND && SM_MOD()->GetConfig()->IsIgnoreSpacesRight()) )
    1364                 :            :     {
    1365                 :          0 :         pBlankNode->Clear();
    1366                 :            :     }
    1367                 :            : 
    1368         [ #  # ]:          0 :     m_aNodeStack.push(pBlankNode);
    1369                 :          0 : }
    1370                 :            : 
    1371                 :            : 
    1372                 :      14374 : void SmParser::Term()
    1373                 :            : {
    1374   [ +  +  +  -  :      14374 :     switch (m_aCurToken.eType)
          -  +  +  -  +  
             -  +  +  +  
                      + ]
    1375                 :            :     {
    1376                 :            :         case TESCAPE :
    1377                 :         90 :             Escape();
    1378                 :         90 :             break;
    1379                 :            : 
    1380                 :            :         case TNOSPACE :
    1381                 :            :         case TLGROUP :
    1382                 :            :         {
    1383                 :       4716 :             bool bNoSpace = m_aCurToken.eType == TNOSPACE;
    1384         [ -  + ]:       4716 :             if (bNoSpace)   // push 'no space' node and continue to parse expression
    1385                 :            :             {
    1386 [ #  # ][ #  # ]:          0 :                 m_aNodeStack.push(new SmExpressionNode(m_aCurToken));
    1387                 :          0 :                 NextToken();
    1388                 :            :             }
    1389         [ -  + ]:       4716 :             if (m_aCurToken.eType != TLGROUP)
    1390                 :            :             {
    1391                 :          0 :                 m_aNodeStack.pop();    // get rid of the 'no space' node pushed above
    1392                 :          0 :                 Term();
    1393                 :            :             }
    1394                 :            :             else
    1395                 :            :             {
    1396                 :       4716 :                 NextToken();
    1397                 :            : 
    1398                 :            :                 // allow for empty group
    1399         [ -  + ]:       4716 :                 if (m_aCurToken.eType == TRGROUP)
    1400                 :            :                 {
    1401         [ #  # ]:          0 :                     if (bNoSpace)   // get rid of the 'no space' node pushed above
    1402                 :          0 :                         m_aNodeStack.pop();
    1403         [ #  # ]:          0 :                     SmStructureNode *pSNode = new SmExpressionNode(m_aCurToken);
    1404                 :          0 :                     pSNode->SetSubNodes(NULL, NULL);
    1405         [ #  # ]:          0 :                     m_aNodeStack.push(pSNode);
    1406                 :            : 
    1407                 :          0 :                     NextToken();
    1408                 :            :                 }
    1409                 :            :                 else    // go as usual
    1410                 :            :                 {
    1411                 :       4716 :                     Align();
    1412         [ -  + ]:       4716 :                     if (m_aCurToken.eType != TRGROUP)
    1413                 :          0 :                         Error(PE_RGROUP_EXPECTED);
    1414                 :            :                     else
    1415                 :       4716 :                         NextToken();
    1416                 :            :                 }
    1417                 :            :             }
    1418                 :            :         }
    1419                 :       4716 :         break;
    1420                 :            : 
    1421                 :            :         case TLEFT :
    1422                 :        774 :             Brace();
    1423                 :        774 :             break;
    1424                 :            : 
    1425                 :            :         case TBLANK :
    1426                 :            :         case TSBLANK :
    1427                 :          0 :             Blank();
    1428                 :          0 :             break;
    1429                 :            : 
    1430                 :            :         case TTEXT :
    1431 [ #  # ][ #  # ]:          0 :             m_aNodeStack.push(new SmTextNode(m_aCurToken, FNT_TEXT));
    1432                 :          0 :             NextToken();
    1433                 :          0 :             break;
    1434                 :            :         case TIDENT :
    1435                 :            :         case TCHARACTER :
    1436 [ +  - ][ +  - ]:       4932 :             m_aNodeStack.push(new SmTextNode(m_aCurToken, FNT_VARIABLE));
    1437                 :       4932 :             NextToken();
    1438                 :       4932 :             break;
    1439                 :            :         case TNUMBER :
    1440 [ +  - ][ +  - ]:       2268 :             m_aNodeStack.push(new SmTextNode(m_aCurToken, FNT_NUMBER));
    1441                 :       2268 :             NextToken();
    1442                 :       2268 :             break;
    1443                 :            : 
    1444                 :            :         case TLEFTARROW :
    1445                 :            :         case TRIGHTARROW :
    1446                 :            :         case TUPARROW :
    1447                 :            :         case TDOWNARROW :
    1448                 :            :         case TSETN :
    1449                 :            :         case TSETZ :
    1450                 :            :         case TSETQ :
    1451                 :            :         case TSETR :
    1452                 :            :         case TSETC :
    1453                 :            :         case THBAR :
    1454                 :            :         case TLAMBDABAR :
    1455                 :            :         case TCIRC :
    1456                 :            :         case TDRARROW :
    1457                 :            :         case TDLARROW :
    1458                 :            :         case TDLRARROW :
    1459                 :            :         case TBACKEPSILON :
    1460                 :            :         case TALEPH :
    1461                 :            :         case TIM :
    1462                 :            :         case TRE :
    1463                 :            :         case TWP :
    1464                 :            :         case TEMPTYSET :
    1465                 :            :         case TINFINITY :
    1466                 :            :         case TEXISTS :
    1467                 :            :         case TNOTEXISTS :
    1468                 :            :         case TFORALL :
    1469                 :            :         case TPARTIAL :
    1470                 :            :         case TNABLA :
    1471                 :            :         case TTOWARD :
    1472                 :            :         case TDOTSAXIS :
    1473                 :            :         case TDOTSDIAG :
    1474                 :            :         case TDOTSDOWN :
    1475                 :            :         case TDOTSLOW :
    1476                 :            :         case TDOTSUP :
    1477                 :            :         case TDOTSVERT :
    1478 [ #  # ][ #  # ]:          0 :             m_aNodeStack.push(new SmMathSymbolNode(m_aCurToken));
    1479                 :          0 :             NextToken();
    1480                 :          0 :             break;
    1481                 :            : 
    1482                 :            :         case TPLACE:
    1483 [ +  - ][ +  - ]:        108 :             m_aNodeStack.push(new SmPlaceNode(m_aCurToken));
    1484                 :        108 :             NextToken();
    1485                 :        108 :             break;
    1486                 :            : 
    1487                 :            :         case TSPECIAL:
    1488                 :          0 :             Special();
    1489                 :          0 :             break;
    1490                 :            : 
    1491                 :            :         case TBINOM:
    1492                 :         72 :             Binom();
    1493                 :         72 :             break;
    1494                 :            : 
    1495                 :            :         case TSTACK:
    1496                 :         90 :             Stack();
    1497                 :         90 :             break;
    1498                 :            : 
    1499                 :            :         case TMATRIX:
    1500                 :         36 :             Matrix();
    1501                 :         36 :             break;
    1502                 :            : 
    1503                 :            :         default:
    1504         [ +  + ]:       1288 :             if (TokenInGroup(TGLBRACES))
    1505                 :         36 :             {   Brace();
    1506                 :            :             }
    1507         [ +  + ]:       1252 :             else if (TokenInGroup(TGOPER))
    1508                 :        258 :             {   Operator();
    1509                 :            :             }
    1510         [ +  + ]:        994 :             else if (TokenInGroup(TGUNOPER))
    1511                 :        126 :             {   UnOper();
    1512                 :            :             }
    1513   [ +  +  -  + ]:       1228 :             else if (    TokenInGroup(TGATTRIBUT)
                 [ +  + ]
    1514                 :        360 :                      ||  TokenInGroup(TGFONTATTR))
    1515         [ +  - ]:        508 :             {   SmStructureNodeArray  aArray;
    1516                 :            : 
    1517                 :            :                 bool    bIsAttr;
    1518                 :        508 :                 sal_uInt16  n = 0;
    1519   [ +  +  -  + ]:       1524 :                 while (true == (bIsAttr = TokenInGroup(TGATTRIBUT))
                 [ +  + ]
    1520                 :        508 :                        ||  TokenInGroup(TGFONTATTR))
    1521         [ +  - ]:        508 :                 {   aArray.resize(n + 1);
    1522                 :            : 
    1523         [ +  - ]:        508 :                     if (bIsAttr)
    1524         [ +  - ]:        508 :                         Attribut();
    1525                 :            :                     else
    1526         [ #  # ]:          0 :                         FontAttribut();
    1527                 :            : 
    1528         [ +  - ]:        508 :                     SmNode* pTmp = lcl_popOrZero(m_aNodeStack);
    1529                 :            : 
    1530                 :            :                     // check if casting in following line is ok
    1531                 :            :                     OSL_ENSURE(pTmp && !pTmp->IsVisible(), "Sm : Ooops...");
    1532                 :            : 
    1533                 :        508 :                     aArray[n] = (SmStructureNode *) pTmp;
    1534                 :        508 :                     n++;
    1535                 :            :                 }
    1536                 :            : 
    1537         [ +  - ]:        508 :                 Power();
    1538                 :            : 
    1539         [ +  - ]:        508 :                 SmNode *pFirstNode = lcl_popOrZero(m_aNodeStack);
    1540         [ +  + ]:       1016 :                 while (n > 0)
    1541         [ +  - ]:        508 :                 {   aArray[n - 1]->SetSubNodes(0, pFirstNode);
    1542                 :        508 :                     pFirstNode = aArray[n - 1];
    1543                 :        508 :                     n--;
    1544                 :            :                 }
    1545         [ +  - ]:        508 :                 m_aNodeStack.push(pFirstNode);
    1546                 :            :             }
    1547         [ +  - ]:        360 :             else if (TokenInGroup(TGFUNCTION))
    1548         [ +  - ]:        360 :             {   if (CONVERT_40_TO_50 != GetConversion())
    1549                 :        360 :                 {   Function();
    1550                 :            :                 }
    1551                 :            :                 else    // encapsulate old 4.0 style parsing in braces
    1552                 :            :                 {
    1553                 :            :                     // insert opening brace
    1554 [ #  # ][ #  # ]:          0 :                     Insert(rtl::OUString('{'), GetTokenIndex());
                 [ #  # ]
    1555                 :            : 
    1556                 :            :                     //
    1557                 :            :                     // parse in 4.0 style
    1558                 :            :                     //
    1559                 :          0 :                     Function();
    1560                 :            : 
    1561                 :          0 :                     SmNode *pFunc = lcl_popOrZero(m_aNodeStack);
    1562                 :            : 
    1563         [ #  # ]:          0 :                     if (m_aCurToken.eType == TLPARENT)
    1564                 :          0 :                     {   Term();
    1565                 :            :                     }
    1566                 :            :                     else
    1567                 :          0 :                     {   Align();
    1568                 :            :                     }
    1569                 :            : 
    1570                 :            :                     // insert closing brace
    1571 [ #  # ][ #  # ]:          0 :                     Insert(rtl::OUString('}'), GetTokenIndex());
                 [ #  # ]
    1572                 :            : 
    1573         [ #  # ]:          0 :                     SmStructureNode *pSNode = new SmExpressionNode(pFunc->GetToken());
    1574                 :          0 :                     pSNode->SetSubNodes(pFunc, lcl_popOrZero(m_aNodeStack));
    1575         [ #  # ]:          0 :                     m_aNodeStack.push(pSNode);
    1576                 :            :                 }
    1577                 :            :             }
    1578                 :            :             else
    1579                 :          0 :                 Error(PE_UNEXPECTED_CHAR);
    1580                 :            :     }
    1581                 :      14374 : }
    1582                 :            : 
    1583                 :            : 
    1584                 :         90 : void SmParser::Escape()
    1585                 :            : {
    1586         [ +  - ]:         90 :     NextToken();
    1587                 :            : 
    1588         [ +  - ]:         90 :     switch (m_aCurToken.eType)
    1589                 :            :     {
    1590                 :            :         case TLPARENT :
    1591                 :            :         case TRPARENT :
    1592                 :            :         case TLBRACKET :
    1593                 :            :         case TRBRACKET :
    1594                 :            :         case TLDBRACKET :
    1595                 :            :         case TRDBRACKET :
    1596                 :            :         case TLBRACE :
    1597                 :            :         case TLGROUP :
    1598                 :            :         case TRBRACE :
    1599                 :            :         case TRGROUP :
    1600                 :            :         case TLANGLE :
    1601                 :            :         case TRANGLE :
    1602                 :            :         case TLCEIL :
    1603                 :            :         case TRCEIL :
    1604                 :            :         case TLFLOOR :
    1605                 :            :         case TRFLOOR :
    1606                 :            :         case TLLINE :
    1607                 :            :         case TRLINE :
    1608                 :            :         case TLDLINE :
    1609                 :            :         case TRDLINE :
    1610                 :         90 :             break;
    1611                 :            :         default:
    1612         [ #  # ]:          0 :             Error(PE_UNEXPECTED_TOKEN);
    1613                 :            :     }
    1614                 :            : 
    1615 [ +  - ][ +  - ]:         90 :     SmNode *pNode = new SmMathSymbolNode(m_aCurToken);
    1616         [ +  - ]:         90 :     m_aNodeStack.push(pNode);
    1617                 :            : 
    1618         [ +  - ]:         90 :     NextToken();
    1619                 :         90 : }
    1620                 :            : 
    1621                 :            : 
    1622                 :        258 : void SmParser::Operator()
    1623                 :            : {
    1624         [ +  - ]:        258 :     if (TokenInGroup(TGOPER))
    1625         [ +  - ]:        258 :     {   SmStructureNode *pSNode = new SmOperNode(m_aCurToken);
    1626                 :            : 
    1627                 :            :         // put operator on top of stack
    1628                 :        258 :         Oper();
    1629                 :            : 
    1630 [ -  + ][ +  + ]:        258 :         if (TokenInGroup(TGLIMIT) || TokenInGroup(TGPOWER))
                 [ +  + ]
    1631                 :        252 :             SubSup(m_aCurToken.nGroup);
    1632                 :        258 :         SmNode *pOperator = lcl_popOrZero(m_aNodeStack);
    1633                 :            : 
    1634                 :            :         // get argument
    1635                 :        258 :         Power();
    1636                 :            : 
    1637                 :        258 :         pSNode->SetSubNodes(pOperator, lcl_popOrZero(m_aNodeStack));
    1638         [ +  - ]:        258 :         m_aNodeStack.push(pSNode);
    1639                 :            :     }
    1640                 :        258 : }
    1641                 :            : 
    1642                 :            : 
    1643                 :        258 : void SmParser::Oper()
    1644                 :            : {
    1645                 :        258 :     SmTokenType  eType (m_aCurToken.eType);
    1646                 :        258 :     SmNode      *pNode = NULL;
    1647                 :            : 
    1648   [ +  +  -  -  :        258 :     switch (eType)
                      - ]
    1649                 :            :     {
    1650                 :            :         case TSUM :
    1651                 :            :         case TPROD :
    1652                 :            :         case TCOPROD :
    1653                 :            :         case TINT :
    1654                 :            :         case TIINT :
    1655                 :            :         case TIIINT :
    1656                 :            :         case TLINT :
    1657                 :            :         case TLLINT :
    1658                 :            :         case TLLLINT :
    1659 [ +  - ][ +  - ]:        222 :             pNode = new SmMathSymbolNode(m_aCurToken);
    1660                 :        222 :             break;
    1661                 :            : 
    1662                 :            :         case TLIM :
    1663                 :            :         case TLIMSUP :
    1664                 :            :         case TLIMINF :
    1665                 :            :             {
    1666                 :         36 :                 const sal_Char* pLim = 0;
    1667   [ +  -  -  - ]:         36 :                 switch (eType)
    1668                 :            :                 {
    1669                 :         36 :                     case TLIM :     pLim = "lim";       break;
    1670                 :          0 :                     case TLIMSUP :  pLim = "lim sup";   break;
    1671                 :          0 :                     case TLIMINF :  pLim = "lim inf";   break;
    1672                 :            :                     default:
    1673                 :          0 :                         break;
    1674                 :            :                 }
    1675         [ +  - ]:         36 :                 if( pLim )
    1676         [ +  - ]:         36 :                     m_aCurToken.aText.AssignAscii( pLim );
    1677 [ +  - ][ +  - ]:         36 :                 pNode = new SmTextNode(m_aCurToken, FNT_TEXT);
    1678                 :            :             }
    1679                 :         36 :             break;
    1680                 :            : 
    1681                 :            :         case TOVERBRACE :
    1682                 :            :         case TUNDERBRACE :
    1683 [ #  # ][ #  # ]:          0 :                 pNode = new SmMathSymbolNode(m_aCurToken);
    1684                 :          0 :             break;
    1685                 :            : 
    1686                 :            :         case TOPER :
    1687         [ #  # ]:          0 :             NextToken();
    1688                 :            : 
    1689                 :            :             OSL_ENSURE(m_aCurToken.eType == TSPECIAL, "Sm: wrong token");
    1690 [ #  # ][ #  # ]:          0 :             pNode = new SmGlyphSpecialNode(m_aCurToken);
    1691                 :          0 :             break;
    1692                 :            : 
    1693                 :            :         default :
    1694                 :            :             OSL_FAIL("Sm: unknown case");
    1695                 :            :     }
    1696         [ +  - ]:        258 :     m_aNodeStack.push(pNode);
    1697                 :            : 
    1698         [ +  - ]:        258 :     NextToken();
    1699                 :        258 : }
    1700                 :            : 
    1701                 :            : 
    1702                 :        126 : void SmParser::UnOper()
    1703                 :            : {
    1704                 :            :     OSL_ENSURE(TokenInGroup(TGUNOPER), "Sm: wrong token");
    1705                 :            : 
    1706         [ +  - ]:        126 :     SmToken      aNodeToken = m_aCurToken;
    1707                 :        126 :     SmTokenType  eType      = m_aCurToken.eType;
    1708                 :        126 :     bool         bIsPostfix = eType == TFACT;
    1709                 :            : 
    1710                 :            :     SmStructureNode *pSNode;
    1711                 :        126 :     SmNode *pOper   = 0,
    1712                 :        126 :            *pExtra  = 0,
    1713                 :            :            *pArg;
    1714                 :            : 
    1715   [ +  +  -  +  :        126 :     switch (eType)
                      - ]
    1716                 :            :     {
    1717                 :            :         case TABS :
    1718                 :            :         case TSQRT :
    1719         [ +  - ]:         72 :             NextToken();
    1720                 :         72 :             break;
    1721                 :            : 
    1722                 :            :         case TNROOT :
    1723         [ +  - ]:         36 :             NextToken();
    1724         [ +  - ]:         36 :             Power();
    1725         [ +  - ]:         36 :             pExtra = lcl_popOrZero(m_aNodeStack);
    1726                 :         36 :             break;
    1727                 :            : 
    1728                 :            :         case TUOPER :
    1729         [ #  # ]:          0 :             NextToken();
    1730                 :            :             //Let the glyph know what it is...
    1731                 :          0 :             m_aCurToken.eType = TUOPER;
    1732                 :          0 :             m_aCurToken.nGroup = TGUNOPER;
    1733         [ #  # ]:          0 :             GlyphSpecial();
    1734         [ #  # ]:          0 :             pOper = lcl_popOrZero(m_aNodeStack);
    1735                 :          0 :             break;
    1736                 :            : 
    1737                 :            :         case TPLUS :
    1738                 :            :         case TMINUS :
    1739                 :            :         case TPLUSMINUS :
    1740                 :            :         case TMINUSPLUS :
    1741                 :            :         case TNEG :
    1742                 :            :         case TFACT :
    1743         [ +  - ]:         18 :             OpSubSup();
    1744         [ +  - ]:         18 :             pOper = lcl_popOrZero(m_aNodeStack);
    1745                 :         18 :             break;
    1746                 :            : 
    1747                 :            :         default :
    1748         [ #  # ]:          0 :             Error(PE_UNOPER_EXPECTED);
    1749                 :            :     }
    1750                 :            : 
    1751                 :            :     // get argument
    1752         [ +  - ]:        126 :     Power();
    1753         [ +  - ]:        126 :     pArg = lcl_popOrZero(m_aNodeStack);
    1754                 :            : 
    1755         [ -  + ]:        126 :     if (eType == TABS)
    1756 [ #  # ][ #  # ]:          0 :     {   pSNode = new SmBraceNode(aNodeToken);
    1757                 :          0 :         pSNode->SetScaleMode(SCALE_HEIGHT);
    1758                 :            : 
    1759                 :            :         // build nodes for left & right lines
    1760                 :            :         // (text, group, level of the used token are of no interrest here)
    1761                 :            :         // we'll use row & column of the keyword for abs
    1762                 :          0 :         aNodeToken.eType = TABS;
    1763                 :            :         //
    1764                 :          0 :         aNodeToken.cMathChar = MS_LINE;
    1765 [ #  # ][ #  # ]:          0 :         SmNode* pLeft = new SmMathSymbolNode(aNodeToken);
    1766                 :            :         //
    1767                 :          0 :         aNodeToken.cMathChar = MS_LINE;
    1768 [ #  # ][ #  # ]:          0 :         SmNode* pRight = new SmMathSymbolNode(aNodeToken);
    1769                 :            : 
    1770         [ #  # ]:          0 :         pSNode->SetSubNodes(pLeft, pArg, pRight);
    1771                 :            :     }
    1772 [ +  + ][ +  + ]:        126 :     else if (eType == TSQRT  ||  eType == TNROOT)
    1773 [ +  - ][ +  - ]:        108 :     {   pSNode = new SmRootNode(aNodeToken);
    1774 [ +  - ][ +  - ]:        108 :         pOper = new SmRootSymbolNode(aNodeToken);
    1775         [ +  - ]:        108 :         pSNode->SetSubNodes(pExtra, pOper, pArg);
    1776                 :            :     }
    1777                 :            :     else
    1778 [ +  - ][ +  - ]:         18 :     {   pSNode = new SmUnHorNode(aNodeToken);
    1779                 :            : 
    1780         [ -  + ]:         18 :         if (bIsPostfix)
    1781         [ #  # ]:          0 :             pSNode->SetSubNodes(pArg, pOper);
    1782                 :            :         else
    1783                 :            :             // prefix operator
    1784         [ +  - ]:         18 :             pSNode->SetSubNodes(pOper, pArg);
    1785                 :            :     }
    1786                 :            : 
    1787 [ +  - ][ +  - ]:        126 :     m_aNodeStack.push(pSNode);
    1788                 :        126 : }
    1789                 :            : 
    1790                 :            : 
    1791                 :        508 : void SmParser::Attribut()
    1792                 :            : {
    1793                 :            :     OSL_ENSURE(TokenInGroup(TGATTRIBUT), "Sm: wrong token group");
    1794                 :            : 
    1795         [ +  - ]:        508 :     SmStructureNode *pSNode = new SmAttributNode(m_aCurToken);
    1796                 :            :     SmNode      *pAttr;
    1797                 :        508 :     SmScaleMode  eScaleMode = SCALE_NONE;
    1798                 :            : 
    1799                 :            :     // get appropriate node for the attribut itself
    1800      [ +  +  + ]:        508 :     switch (m_aCurToken.eType)
    1801                 :            :     {   case TUNDERLINE :
    1802                 :            :         case TOVERLINE :
    1803                 :            :         case TOVERSTRIKE :
    1804         [ +  - ]:         72 :             pAttr = new SmRectangleNode(m_aCurToken);
    1805                 :         72 :             eScaleMode = SCALE_WIDTH;
    1806                 :         72 :             break;
    1807                 :            : 
    1808                 :            :         case TWIDEVEC :
    1809                 :            :         case TWIDEHAT :
    1810                 :            :         case TWIDETILDE :
    1811         [ +  - ]:        216 :             pAttr = new SmMathSymbolNode(m_aCurToken);
    1812                 :        216 :             eScaleMode = SCALE_WIDTH;
    1813                 :        216 :             break;
    1814                 :            : 
    1815                 :            :         default :
    1816         [ +  - ]:        220 :             pAttr = new SmMathSymbolNode(m_aCurToken);
    1817                 :            :     }
    1818                 :            : 
    1819                 :        508 :     NextToken();
    1820                 :            : 
    1821                 :        508 :     pSNode->SetSubNodes(pAttr, 0);
    1822                 :        508 :     pSNode->SetScaleMode(eScaleMode);
    1823         [ +  - ]:        508 :     m_aNodeStack.push(pSNode);
    1824                 :        508 : }
    1825                 :            : 
    1826                 :            : 
    1827                 :          0 : void SmParser::FontAttribut()
    1828                 :            : {
    1829                 :            :     OSL_ENSURE(TokenInGroup(TGFONTATTR), "Sm: wrong token group");
    1830                 :            : 
    1831   [ #  #  #  #  :          0 :     switch (m_aCurToken.eType)
                      # ]
    1832                 :            :     {
    1833                 :            :         case TITALIC :
    1834                 :            :         case TNITALIC :
    1835                 :            :         case TBOLD :
    1836                 :            :         case TNBOLD :
    1837                 :            :         case TPHANTOM :
    1838 [ #  # ][ #  # ]:          0 :             m_aNodeStack.push(new SmFontNode(m_aCurToken));
    1839                 :          0 :             NextToken();
    1840                 :          0 :             break;
    1841                 :            : 
    1842                 :            :         case TSIZE :
    1843                 :          0 :             FontSize();
    1844                 :          0 :             break;
    1845                 :            : 
    1846                 :            :         case TFONT :
    1847                 :          0 :             Font();
    1848                 :          0 :             break;
    1849                 :            : 
    1850                 :            :         case TCOLOR :
    1851                 :          0 :             Color();
    1852                 :          0 :             break;
    1853                 :            : 
    1854                 :            :         default :
    1855                 :            :             OSL_FAIL("Sm: unknown case");
    1856                 :            :     }
    1857                 :          0 : }
    1858                 :            : 
    1859                 :            : 
    1860                 :          0 : void SmParser::Color()
    1861                 :            : {
    1862                 :            :     OSL_ENSURE(m_aCurToken.eType == TCOLOR, "Sm : Ooops...");
    1863                 :            : 
    1864                 :            :     // last color rules, get that one
    1865         [ #  # ]:          0 :     SmToken  aToken;
    1866         [ #  # ]:          0 :     do
    1867         [ #  # ]:          0 :     {   NextToken();
    1868                 :            : 
    1869         [ #  # ]:          0 :         if (TokenInGroup(TGCOLOR))
    1870         [ #  # ]:          0 :         {   aToken = m_aCurToken;
    1871         [ #  # ]:          0 :             NextToken();
    1872                 :            :         }
    1873                 :            :         else
    1874         [ #  # ]:          0 :             Error(PE_COLOR_EXPECTED);
    1875                 :            :     } while (m_aCurToken.eType == TCOLOR);
    1876                 :            : 
    1877 [ #  # ][ #  # ]:          0 :     m_aNodeStack.push(new SmFontNode(aToken));
         [ #  # ][ #  # ]
    1878                 :          0 : }
    1879                 :            : 
    1880                 :            : 
    1881                 :          0 : void SmParser::Font()
    1882                 :            : {
    1883                 :            :     OSL_ENSURE(m_aCurToken.eType == TFONT, "Sm : Ooops...");
    1884                 :            : 
    1885                 :            :     // last font rules, get that one
    1886         [ #  # ]:          0 :     SmToken  aToken;
    1887         [ #  # ]:          0 :     do
    1888         [ #  # ]:          0 :     {   NextToken();
    1889                 :            : 
    1890         [ #  # ]:          0 :         if (TokenInGroup(TGFONT))
    1891         [ #  # ]:          0 :         {   aToken = m_aCurToken;
    1892         [ #  # ]:          0 :             NextToken();
    1893                 :            :         }
    1894                 :            :         else
    1895         [ #  # ]:          0 :             Error(PE_FONT_EXPECTED);
    1896                 :            :     } while (m_aCurToken.eType == TFONT);
    1897                 :            : 
    1898 [ #  # ][ #  # ]:          0 :     m_aNodeStack.push(new SmFontNode(aToken));
         [ #  # ][ #  # ]
    1899                 :          0 : }
    1900                 :            : 
    1901                 :            : 
    1902                 :            : // gets number used as arguments in Math formulas (e.g. 'size' command)
    1903                 :            : // Format: no negative numbers, must start with a digit, no exponent notation, ...
    1904                 :          0 : bool lcl_IsNumber(const rtl::OUString& rText)
    1905                 :            : {
    1906                 :          0 :     bool bPoint = false;
    1907                 :          0 :     const sal_Unicode* pBuffer = rText.getStr();
    1908         [ #  # ]:          0 :     for(sal_Int32 nPos = 0; nPos < rText.getLength(); nPos++, pBuffer++)
    1909                 :            :     {
    1910                 :          0 :         const sal_Unicode cChar = *pBuffer;
    1911         [ #  # ]:          0 :         if(cChar == '.')
    1912                 :            :         {
    1913         [ #  # ]:          0 :             if(bPoint)
    1914                 :          0 :                 return false;
    1915                 :            :             else
    1916                 :          0 :                 bPoint = true;
    1917                 :            :         }
    1918         [ #  # ]:          0 :         else if ( !IsDigit( cChar ) )
    1919                 :          0 :             return false;
    1920                 :            :     }
    1921                 :          0 :     return true;
    1922                 :            : }
    1923                 :            : 
    1924                 :          0 : void SmParser::FontSize()
    1925                 :            : {
    1926                 :            :     OSL_ENSURE(m_aCurToken.eType == TSIZE, "Sm : Ooops...");
    1927                 :            : 
    1928                 :            :     sal_uInt16   Type;
    1929 [ #  # ][ #  # ]:          0 :     SmFontNode *pFontNode = new SmFontNode(m_aCurToken);
    1930                 :            : 
    1931         [ #  # ]:          0 :     NextToken();
    1932                 :            : 
    1933   [ #  #  #  #  :          0 :     switch (m_aCurToken.eType)
                   #  # ]
    1934                 :            :     {
    1935                 :          0 :         case TNUMBER:   Type = FNTSIZ_ABSOLUT;  break;
    1936                 :          0 :         case TPLUS:     Type = FNTSIZ_PLUS;     break;
    1937                 :          0 :         case TMINUS:    Type = FNTSIZ_MINUS;    break;
    1938                 :          0 :         case TMULTIPLY: Type = FNTSIZ_MULTIPLY; break;
    1939                 :          0 :         case TDIVIDEBY: Type = FNTSIZ_DIVIDE;   break;
    1940                 :            : 
    1941                 :            :         default:
    1942 [ #  # ][ #  # ]:          0 :             delete pFontNode;
    1943         [ #  # ]:          0 :             Error(PE_SIZE_EXPECTED);
    1944                 :            :             return;
    1945                 :            :     }
    1946                 :            : 
    1947         [ #  # ]:          0 :     if (Type != FNTSIZ_ABSOLUT)
    1948                 :            :     {
    1949         [ #  # ]:          0 :         NextToken();
    1950         [ #  # ]:          0 :         if (m_aCurToken.eType != TNUMBER)
    1951                 :            :         {
    1952 [ #  # ][ #  # ]:          0 :             delete pFontNode;
    1953         [ #  # ]:          0 :             Error(PE_SIZE_EXPECTED);
    1954                 :            :             return;
    1955                 :            :         }
    1956                 :            :     }
    1957                 :            : 
    1958                 :            :     // get number argument
    1959         [ #  # ]:          0 :     Fraction  aValue( 1L );
    1960 [ #  # ][ #  # ]:          0 :     if (lcl_IsNumber( m_aCurToken.aText ))
    1961                 :            :     {
    1962         [ #  # ]:          0 :         double fTmp = rtl::OUString(m_aCurToken.aText).toDouble();
    1963         [ #  # ]:          0 :         if (fTmp != 0.0)
    1964                 :            :         {
    1965 [ #  # ][ #  # ]:          0 :             aValue = fTmp;
    1966                 :            : 
    1967                 :            :             //!! keep the numerator and denominator from being to large
    1968                 :            :             //!! otherwise ongoing multiplications may result in overflows
    1969                 :            :             //!! (for example in SmNode::SetFontSize the font size calculated
    1970                 :            :             //!! may become 0 because of this!!! Happens e.g. for ftmp = 2.9 with Linux
    1971                 :            :             //!! or ftmp = 1.11111111111111111... (11/9) on every platform.)
    1972         [ #  # ]:          0 :             if (aValue.GetDenominator() > 1000)
    1973                 :            :             {
    1974                 :          0 :                 long nNum   = aValue.GetNumerator();
    1975                 :          0 :                 long nDenom = aValue.GetDenominator();
    1976         [ #  # ]:          0 :                 while (nDenom > 1000)
    1977                 :            :                 {
    1978                 :          0 :                     nNum    /= 10;
    1979                 :          0 :                     nDenom  /= 10;
    1980                 :            :                 }
    1981 [ #  # ][ #  # ]:          0 :                 aValue = Fraction( nNum, nDenom );
    1982                 :            :             }
    1983                 :            :         }
    1984                 :            :     }
    1985                 :            : 
    1986         [ #  # ]:          0 :     NextToken();
    1987                 :            : 
    1988         [ #  # ]:          0 :     pFontNode->SetSizeParameter(aValue, Type);
    1989         [ #  # ]:          0 :     m_aNodeStack.push(pFontNode);
    1990                 :            : }
    1991                 :            : 
    1992                 :            : 
    1993                 :        810 : void SmParser::Brace()
    1994                 :            : {
    1995                 :            :     OSL_ENSURE(m_aCurToken.eType == TLEFT  ||  TokenInGroup(TGLBRACES),
    1996                 :            :         "Sm: kein Klammer Ausdruck");
    1997                 :            : 
    1998         [ +  - ]:        810 :     SmStructureNode *pSNode  = new SmBraceNode(m_aCurToken);
    1999                 :        810 :     SmNode *pBody   = 0,
    2000                 :        810 :            *pLeft   = 0,
    2001                 :        810 :            *pRight  = 0;
    2002                 :        810 :     SmScaleMode   eScaleMode = SCALE_NONE;
    2003                 :        810 :     SmParseError  eError     = PE_NONE;
    2004                 :            : 
    2005         [ +  + ]:        810 :     if (m_aCurToken.eType == TLEFT)
    2006                 :        774 :     {   NextToken();
    2007                 :            : 
    2008                 :        774 :         eScaleMode = SCALE_HEIGHT;
    2009                 :            : 
    2010                 :            :         // check for left bracket
    2011 [ #  # ][ +  - ]:        774 :         if (TokenInGroup(TGLBRACES) || TokenInGroup(TGRBRACES))
                 [ -  + ]
    2012                 :            :         {
    2013         [ +  - ]:        774 :             pLeft = new SmMathSymbolNode(m_aCurToken);
    2014                 :            : 
    2015                 :        774 :             NextToken();
    2016                 :        774 :             Bracebody(true);
    2017                 :        774 :             pBody = lcl_popOrZero(m_aNodeStack);
    2018                 :            : 
    2019         [ +  - ]:        774 :             if (m_aCurToken.eType == TRIGHT)
    2020                 :        774 :             {   NextToken();
    2021                 :            : 
    2022                 :            :                 // check for right bracket
    2023 [ +  - ][ +  - ]:        774 :                 if (TokenInGroup(TGLBRACES) || TokenInGroup(TGRBRACES))
                 [ +  + ]
    2024                 :            :                 {
    2025         [ +  - ]:        774 :                     pRight = new SmMathSymbolNode(m_aCurToken);
    2026                 :        774 :                     NextToken();
    2027                 :            :                 }
    2028                 :            :                 else
    2029                 :          0 :                     eError = PE_RBRACE_EXPECTED;
    2030                 :            :             }
    2031                 :            :             else
    2032                 :          0 :                 eError = PE_RIGHT_EXPECTED;
    2033                 :            :         }
    2034                 :            :         else
    2035                 :          0 :             eError = PE_LBRACE_EXPECTED;
    2036                 :            :     }
    2037                 :            :     else
    2038                 :            :     {
    2039         [ +  - ]:         36 :         if (TokenInGroup(TGLBRACES))
    2040                 :            :         {
    2041         [ +  - ]:         36 :             pLeft = new SmMathSymbolNode(m_aCurToken);
    2042                 :            : 
    2043                 :         36 :             NextToken();
    2044                 :         36 :             Bracebody(false);
    2045                 :         36 :             pBody = lcl_popOrZero(m_aNodeStack);
    2046                 :            : 
    2047                 :         36 :             SmTokenType  eExpectedType = TUNKNOWN;
    2048   [ +  +  -  -  :         36 :             switch (pLeft->GetToken().eType)
          -  -  -  -  -  
                      - ]
    2049                 :         18 :             {   case TLPARENT :     eExpectedType = TRPARENT;   break;
    2050                 :         18 :                 case TLBRACKET :    eExpectedType = TRBRACKET;  break;
    2051                 :          0 :                 case TLBRACE :      eExpectedType = TRBRACE;    break;
    2052                 :          0 :                 case TLDBRACKET :   eExpectedType = TRDBRACKET; break;
    2053                 :          0 :                 case TLLINE :       eExpectedType = TRLINE;     break;
    2054                 :          0 :                 case TLDLINE :      eExpectedType = TRDLINE;    break;
    2055                 :          0 :                 case TLANGLE :      eExpectedType = TRANGLE;    break;
    2056                 :          0 :                 case TLFLOOR :      eExpectedType = TRFLOOR;    break;
    2057                 :          0 :                 case TLCEIL :       eExpectedType = TRCEIL;     break;
    2058                 :            :                 default :
    2059                 :            :                     OSL_FAIL("Sm: unknown case");
    2060                 :            :             }
    2061                 :            : 
    2062         [ +  - ]:         36 :             if (m_aCurToken.eType == eExpectedType)
    2063                 :            :             {
    2064         [ +  - ]:         36 :                 pRight = new SmMathSymbolNode(m_aCurToken);
    2065                 :         36 :                 NextToken();
    2066                 :            :             }
    2067                 :            :             else
    2068                 :          0 :                 eError = PE_PARENT_MISMATCH;
    2069                 :            :         }
    2070                 :            :         else
    2071                 :          0 :             eError = PE_LBRACE_EXPECTED;
    2072                 :            :     }
    2073                 :            : 
    2074         [ +  - ]:        810 :     if (eError == PE_NONE)
    2075                 :            :     {   OSL_ENSURE(pLeft,  "Sm: NULL pointer");
    2076                 :            :         OSL_ENSURE(pRight, "Sm: NULL pointer");
    2077                 :        810 :         pSNode->SetSubNodes(pLeft, pBody, pRight);
    2078                 :        810 :         pSNode->SetScaleMode(eScaleMode);
    2079         [ +  - ]:        810 :         m_aNodeStack.push(pSNode);
    2080                 :            :     }
    2081                 :            :     else
    2082         [ #  # ]:          0 :     {   delete pSNode;
    2083         [ #  # ]:          0 :         delete pBody;
    2084         [ #  # ]:          0 :         delete pLeft;
    2085         [ #  # ]:          0 :         delete pRight;
    2086                 :            : 
    2087                 :          0 :         Error(eError);
    2088                 :            :     }
    2089                 :        810 : }
    2090                 :            : 
    2091                 :            : 
    2092                 :        810 : void SmParser::Bracebody(bool bIsLeftRight)
    2093                 :            : {
    2094 [ +  - ][ +  - ]:        810 :     SmStructureNode *pBody = new SmBracebodyNode(m_aCurToken);
    2095         [ +  - ]:        810 :     SmNodeArray      aNodes;
    2096                 :        810 :     sal_uInt16           nNum = 0;
    2097                 :            : 
    2098                 :            :     // get body if any
    2099         [ +  + ]:        810 :     if (bIsLeftRight)
    2100                 :            :     {
    2101 [ +  - ][ +  + ]:        990 :         do
                 [ +  + ]
    2102                 :            :         {
    2103         [ +  + ]:        990 :             if (m_aCurToken.eType == TMLINE)
    2104                 :            :             {
    2105 [ +  - ][ +  - ]:        108 :                 m_aNodeStack.push(new SmMathSymbolNode(m_aCurToken));
                 [ +  - ]
    2106         [ +  - ]:        108 :                 NextToken();
    2107                 :        108 :                 nNum++;
    2108                 :            :             }
    2109         [ +  + ]:        882 :             else if (m_aCurToken.eType != TRIGHT)
    2110         [ +  - ]:        846 :             {   Align();
    2111                 :        846 :                 nNum++;
    2112                 :            : 
    2113 [ +  + ][ -  + ]:        846 :                 if (m_aCurToken.eType != TMLINE  &&  m_aCurToken.eType != TRIGHT)
    2114         [ #  # ]:          0 :                     Error(PE_RIGHT_EXPECTED);
    2115                 :            :             }
    2116                 :            :         } while (m_aCurToken.eType != TEND  &&  m_aCurToken.eType != TRIGHT);
    2117                 :            :     }
    2118                 :            :     else
    2119                 :            :     {
    2120   [ +  -  -  + ]:         72 :         do
                 [ -  + ]
    2121                 :            :         {
    2122         [ -  + ]:         36 :             if (m_aCurToken.eType == TMLINE)
    2123                 :            :             {
    2124 [ #  # ][ #  # ]:          0 :                 m_aNodeStack.push(new SmMathSymbolNode(m_aCurToken));
                 [ #  # ]
    2125         [ #  # ]:          0 :                 NextToken();
    2126                 :          0 :                 nNum++;
    2127                 :            :             }
    2128         [ -  + ]:         36 :             else if (!TokenInGroup(TGRBRACES))
    2129         [ #  # ]:          0 :             {   Align();
    2130                 :          0 :                 nNum++;
    2131                 :            : 
    2132 [ #  # ][ #  # ]:          0 :                 if (m_aCurToken.eType != TMLINE  &&  !TokenInGroup(TGRBRACES))
                 [ #  # ]
    2133         [ #  # ]:          0 :                     Error(PE_RBRACE_EXPECTED);
    2134                 :            :             }
    2135                 :         36 :         } while (m_aCurToken.eType != TEND  &&  !TokenInGroup(TGRBRACES));
    2136                 :            :     }
    2137                 :            : 
    2138                 :            :     // build argument vector in parsing order
    2139         [ +  - ]:        810 :     aNodes.resize(nNum);
    2140         [ +  + ]:       1764 :     for (sal_uInt16 i = 0;  i < nNum;  i++)
    2141                 :            :     {
    2142         [ +  - ]:        954 :         aNodes[nNum - 1 - i] = lcl_popOrZero(m_aNodeStack);
    2143                 :            :     }
    2144                 :            : 
    2145         [ +  - ]:        810 :     pBody->SetSubNodes(aNodes);
    2146         [ +  + ]:        810 :     pBody->SetScaleMode(bIsLeftRight ? SCALE_HEIGHT : SCALE_NONE);
    2147         [ +  - ]:        810 :     m_aNodeStack.push(pBody);
    2148                 :        810 : }
    2149                 :            : 
    2150                 :            : 
    2151                 :        360 : void SmParser::Function()
    2152                 :            : {
    2153      [ -  +  - ]:        360 :     switch (m_aCurToken.eType)
    2154                 :            :     {
    2155                 :            :         case TFUNC:
    2156                 :          0 :             NextToken();    // skip "FUNC"-statement
    2157                 :            :             // fall through
    2158                 :            : 
    2159                 :            :         case TSIN :
    2160                 :            :         case TCOS :
    2161                 :            :         case TTAN :
    2162                 :            :         case TCOT :
    2163                 :            :         case TASIN :
    2164                 :            :         case TACOS :
    2165                 :            :         case TATAN :
    2166                 :            :         case TACOT :
    2167                 :            :         case TSINH :
    2168                 :            :         case TCOSH :
    2169                 :            :         case TTANH :
    2170                 :            :         case TCOTH :
    2171                 :            :         case TASINH :
    2172                 :            :         case TACOSH :
    2173                 :            :         case TATANH :
    2174                 :            :         case TACOTH :
    2175                 :            :         case TLN :
    2176                 :            :         case TLOG :
    2177                 :            :         case TEXP :
    2178 [ +  - ][ +  - ]:        360 :             m_aNodeStack.push(new SmTextNode(m_aCurToken, FNT_FUNCTION));
    2179                 :        360 :             NextToken();
    2180                 :        360 :             break;
    2181                 :            : 
    2182                 :            :         default:
    2183                 :          0 :             Error(PE_FUNC_EXPECTED);
    2184                 :            :     }
    2185                 :        360 : }
    2186                 :            : 
    2187                 :            : 
    2188                 :         72 : void SmParser::Binom()
    2189                 :            : {
    2190         [ +  - ]:         72 :     SmNodeArray  ExpressionArray;
    2191 [ +  - ][ +  - ]:         72 :     SmStructureNode *pSNode = new SmTableNode(m_aCurToken);
    2192                 :            : 
    2193         [ +  - ]:         72 :     NextToken();
    2194                 :            : 
    2195         [ +  - ]:         72 :     Sum();
    2196         [ +  - ]:         72 :     Sum();
    2197                 :            : 
    2198         [ +  - ]:         72 :     ExpressionArray.resize(2);
    2199                 :            : 
    2200         [ +  + ]:        216 :     for (int i = 0;  i < 2;  i++)
    2201                 :            :     {
    2202         [ +  - ]:        144 :         ExpressionArray[2 - (i + 1)] = lcl_popOrZero(m_aNodeStack);
    2203                 :            :     }
    2204                 :            : 
    2205         [ +  - ]:         72 :     pSNode->SetSubNodes(ExpressionArray);
    2206         [ +  - ]:         72 :     m_aNodeStack.push(pSNode);
    2207                 :         72 : }
    2208                 :            : 
    2209                 :            : 
    2210                 :         90 : void SmParser::Stack()
    2211                 :            : {
    2212         [ +  - ]:         90 :     SmNodeArray  ExpressionArray;
    2213         [ +  - ]:         90 :     NextToken();
    2214         [ +  - ]:         90 :     if (m_aCurToken.eType == TLGROUP)
    2215                 :            :     {
    2216                 :         90 :         sal_uInt16 n = 0;
    2217                 :            : 
    2218         [ +  + ]:        198 :         do
    2219                 :            :         {
    2220         [ +  - ]:        198 :             NextToken();
    2221         [ +  - ]:        198 :             Align();
    2222                 :        198 :             n++;
    2223                 :            :         }
    2224                 :            :         while (m_aCurToken.eType == TPOUND);
    2225                 :            : 
    2226         [ +  - ]:         90 :         ExpressionArray.resize(n);
    2227                 :            : 
    2228         [ +  + ]:        288 :         for (sal_uInt16 i = 0; i < n; i++)
    2229                 :            :         {
    2230         [ +  - ]:        198 :             ExpressionArray[n - (i + 1)] = lcl_popOrZero(m_aNodeStack);
    2231                 :            :         }
    2232                 :            : 
    2233         [ -  + ]:         90 :         if (m_aCurToken.eType != TRGROUP)
    2234         [ #  # ]:          0 :             Error(PE_RGROUP_EXPECTED);
    2235                 :            : 
    2236         [ +  - ]:         90 :         NextToken();
    2237                 :            : 
    2238                 :            :         //We need to let the table node know it context
    2239                 :            :         //it's used in SmNodeToTextVisitor
    2240         [ +  - ]:         90 :         SmToken aTok = m_aCurToken;
    2241                 :         90 :         aTok.eType = TSTACK;
    2242 [ +  - ][ +  - ]:         90 :         SmStructureNode *pSNode = new SmTableNode(aTok);
    2243         [ +  - ]:         90 :         pSNode->SetSubNodes(ExpressionArray);
    2244 [ +  - ][ +  - ]:         90 :         m_aNodeStack.push(pSNode);
    2245                 :            :     }
    2246                 :            :     else
    2247         [ #  # ]:         90 :         Error(PE_LGROUP_EXPECTED);
    2248                 :         90 : }
    2249                 :            : 
    2250                 :            : 
    2251                 :         36 : void SmParser::Matrix()
    2252                 :            : {
    2253         [ +  - ]:         36 :     SmNodeArray  ExpressionArray;
    2254                 :            : 
    2255         [ +  - ]:         36 :     NextToken();
    2256         [ +  - ]:         36 :     if (m_aCurToken.eType == TLGROUP)
    2257                 :            :     {
    2258                 :         36 :         sal_uInt16 c = 0;
    2259                 :            : 
    2260         [ +  + ]:         72 :         do
    2261                 :            :         {
    2262         [ +  - ]:         72 :             NextToken();
    2263         [ +  - ]:         72 :             Align();
    2264                 :         72 :             c++;
    2265                 :            :         }
    2266                 :            :         while (m_aCurToken.eType == TPOUND);
    2267                 :            : 
    2268                 :         36 :         sal_uInt16 r = 1;
    2269                 :            : 
    2270         [ +  + ]:         72 :         while (m_aCurToken.eType == TDPOUND)
    2271                 :            :         {
    2272         [ +  - ]:         36 :             NextToken();
    2273         [ +  + ]:        108 :             for (sal_uInt16 i = 0; i < c; i++)
    2274                 :            :             {
    2275         [ +  - ]:         72 :                 Align();
    2276         [ +  + ]:         72 :                 if (i < (c - 1))
    2277                 :            :                 {
    2278         [ +  - ]:         36 :                     if (m_aCurToken.eType == TPOUND)
    2279                 :            :                     {
    2280         [ +  - ]:         36 :                         NextToken();
    2281                 :            :                     }
    2282                 :            :                     else
    2283         [ #  # ]:          0 :                         Error(PE_POUND_EXPECTED);
    2284                 :            :                 }
    2285                 :            :             }
    2286                 :            : 
    2287                 :         36 :             r++;
    2288                 :            :         }
    2289                 :            : 
    2290                 :         36 :         long nRC = r * c;
    2291                 :            : 
    2292         [ +  - ]:         36 :         ExpressionArray.resize(nRC);
    2293                 :            : 
    2294         [ +  + ]:        180 :         for (sal_uInt16 i = 0; i < (nRC); i++)
    2295                 :            :         {
    2296         [ +  - ]:        144 :             ExpressionArray[(nRC) - (i + 1)] = lcl_popOrZero(m_aNodeStack);
    2297                 :            :         }
    2298                 :            : 
    2299         [ -  + ]:         36 :         if (m_aCurToken.eType != TRGROUP)
    2300         [ #  # ]:          0 :             Error(PE_RGROUP_EXPECTED);
    2301                 :            : 
    2302         [ +  - ]:         36 :         NextToken();
    2303                 :            : 
    2304 [ +  - ][ +  - ]:         36 :         SmMatrixNode *pMNode = new SmMatrixNode(m_aCurToken);
    2305         [ +  - ]:         36 :         pMNode->SetSubNodes(ExpressionArray);
    2306         [ +  - ]:         36 :         pMNode->SetRowCol(r, c);
    2307         [ +  - ]:         36 :         m_aNodeStack.push(pMNode);
    2308                 :            :     }
    2309                 :            :     else
    2310         [ #  # ]:         36 :         Error(PE_LGROUP_EXPECTED);
    2311                 :         36 : }
    2312                 :            : 
    2313                 :            : 
    2314                 :          0 : void SmParser::Special()
    2315                 :            : {
    2316                 :          0 :     bool bReplace = false;
    2317                 :          0 :     String &rName = m_aCurToken.aText;
    2318         [ #  # ]:          0 :     String aNewName;
    2319                 :            : 
    2320         [ #  # ]:          0 :     if (CONVERT_NONE == GetConversion())
    2321                 :            :     {
    2322                 :            :         // conversion of symbol names for 6.0 (XML) file format
    2323                 :            :         // (name change on import / export.
    2324                 :            :         // UI uses localized names XML file format does not.)
    2325 [ #  # ][ #  # ]:          0 :         if( rName.Len() && rName.GetChar( 0 ) == sal_Unicode( '%' ) )
                 [ #  # ]
    2326                 :            :         {
    2327         [ #  # ]:          0 :             if (IsImportSymbolNames())
    2328                 :            :             {
    2329 [ #  # ][ #  # ]:          0 :                 const SmLocalizedSymbolData &rLSD = SM_MOD()->GetLocSymbolData();
    2330 [ #  # ][ #  # ]:          0 :                 aNewName = rLSD.GetUiSymbolName( rName.Copy( 1 ) );
         [ #  # ][ #  # ]
                 [ #  # ]
    2331                 :          0 :                 bReplace = true;
    2332                 :            :             }
    2333         [ #  # ]:          0 :             else if (IsExportSymbolNames())
    2334                 :            :             {
    2335 [ #  # ][ #  # ]:          0 :                 const SmLocalizedSymbolData &rLSD = SM_MOD()->GetLocSymbolData();
    2336 [ #  # ][ #  # ]:          0 :                 aNewName = rLSD.GetExportSymbolName( rName.Copy( 1 ) );
         [ #  # ][ #  # ]
                 [ #  # ]
    2337                 :          0 :                 bReplace = true;
    2338                 :            :             }
    2339                 :            :         }
    2340         [ #  # ]:          0 :         if( aNewName.Len() )
    2341         [ #  # ]:          0 :             aNewName.Insert( '%', 0 );
    2342                 :            :     }
    2343                 :            :     else    // 5.0 <-> 6.0 formula text (symbol name) conversion
    2344                 :            :     {
    2345                 :          0 :         LanguageType nLanguage = GetLanguage();
    2346 [ #  # ][ #  # ]:          0 :         SmLocalizedSymbolData &rData = SM_MOD()->GetLocSymbolData();
    2347                 :          0 :         const ResStringArray *pFrom = 0;
    2348                 :          0 :         const ResStringArray *pTo   = 0;
    2349         [ #  # ]:          0 :         if (CONVERT_50_TO_60 == GetConversion())
    2350                 :            :         {
    2351         [ #  # ]:          0 :             pFrom = rData.Get50NamesArray( nLanguage );
    2352         [ #  # ]:          0 :             pTo   = rData.Get60NamesArray( nLanguage );
    2353                 :            :         }
    2354         [ #  # ]:          0 :         else if (CONVERT_60_TO_50 == GetConversion())
    2355                 :            :         {
    2356         [ #  # ]:          0 :             pFrom = rData.Get60NamesArray( nLanguage );
    2357         [ #  # ]:          0 :             pTo   = rData.Get50NamesArray( nLanguage );
    2358                 :            :         }
    2359 [ #  # ][ #  # ]:          0 :         if (pFrom  &&  pTo)
    2360                 :            :         {
    2361                 :            :             OSL_ENSURE( pFrom->Count() == pTo->Count(),
    2362                 :            :                     "array length mismatch" );
    2363                 :          0 :             sal_uInt16 nCount = sal::static_int_cast< sal_uInt16 >(pFrom->Count());
    2364         [ #  # ]:          0 :             for (sal_uInt16 i = 0;  i < nCount;  ++i)
    2365                 :            :             {
    2366 [ #  # ][ #  # ]:          0 :                 if (pFrom->GetString(i).equals(rName))
                 [ #  # ]
    2367                 :            :                 {
    2368 [ #  # ][ #  # ]:          0 :                     aNewName = pTo->GetString(i);
    2369                 :          0 :                     bReplace = true;
    2370                 :            :                 }
    2371                 :            :             }
    2372                 :            :         }
    2373                 :            :         // else:
    2374                 :            :         // conversion arrays not found or (usually)
    2375                 :            :         // conversion not necessary
    2376                 :            :     }
    2377                 :            : 
    2378 [ #  # ][ #  # ]:          0 :     if (bReplace  &&  aNewName.Len()  &&  rName != aNewName)
         [ #  # ][ #  # ]
                 [ #  # ]
    2379                 :            :     {
    2380         [ #  # ]:          0 :         Replace( GetTokenIndex(), rName.Len(), aNewName );
    2381         [ #  # ]:          0 :         rName = aNewName;
    2382                 :            :     }
    2383                 :            : 
    2384                 :            :     // add symbol name to list of used symbols
    2385         [ #  # ]:          0 :     const String aSymbolName( m_aCurToken.aText.Copy( 1 ) );
    2386         [ #  # ]:          0 :     if (aSymbolName.Len() > 0 )
    2387         [ #  # ]:          0 :         AddToUsedSymbols( aSymbolName );
    2388                 :            : 
    2389 [ #  # ][ #  # ]:          0 :     m_aNodeStack.push(new SmSpecialNode(m_aCurToken));
                 [ #  # ]
    2390 [ #  # ][ #  # ]:          0 :     NextToken();
                 [ #  # ]
    2391                 :          0 : }
    2392                 :            : 
    2393                 :            : 
    2394                 :          0 : void SmParser::GlyphSpecial()
    2395                 :            : {
    2396 [ #  # ][ #  # ]:          0 :     m_aNodeStack.push(new SmGlyphSpecialNode(m_aCurToken));
    2397                 :          0 :     NextToken();
    2398                 :          0 : }
    2399                 :            : 
    2400                 :            : 
    2401                 :          0 : void SmParser::Error(SmParseError eError)
    2402                 :            : {
    2403         [ #  # ]:          0 :     SmStructureNode *pSNode = new SmExpressionNode(m_aCurToken);
    2404         [ #  # ]:          0 :     SmErrorNode     *pErr   = new SmErrorNode(eError, m_aCurToken);
    2405                 :          0 :     pSNode->SetSubNodes(pErr, 0);
    2406                 :            : 
    2407                 :            :     //! put a structure node on the stack (instead of the error node itself)
    2408                 :            :     //! because sometimes such a node is expected in order to attach some
    2409                 :            :     //! subnodes
    2410         [ #  # ]:          0 :     m_aNodeStack.push(pSNode);
    2411                 :            : 
    2412                 :          0 :     AddError(eError, pSNode);
    2413                 :            : 
    2414                 :          0 :     NextToken();
    2415                 :          0 : }
    2416                 :            : 
    2417                 :            : 
    2418                 :            : // end gramar
    2419                 :            : 
    2420                 :            : 
    2421                 :        460 : SmParser::SmParser()
    2422 [ +  - ][ +  - ]:        460 :     : m_aDotLoc( SvxCreateLocale( LANGUAGE_ENGLISH_US ) )
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
    2423                 :            : {
    2424                 :        460 :     m_eConversion = CONVERT_NONE;
    2425                 :        460 :     bImportSymNames = m_bExportSymNames = false;
    2426 [ +  - ][ +  - ]:        460 :     m_nLang = Application::GetSettings().GetUILanguage();
    2427                 :        460 : }
    2428                 :            : 
    2429                 :       1324 : SmNode *SmParser::Parse(const String &rBuffer)
    2430                 :            : {
    2431                 :       1324 :     ClearUsedSymbols();
    2432                 :            : 
    2433 [ +  - ][ +  - ]:       1324 :     m_aBufferString = convertLineEnd(rBuffer, LINEEND_LF);
    2434                 :       1324 :     m_nBufferIndex  = 0;
    2435                 :       1324 :     m_nTokenIndex   = 0;
    2436                 :       1324 :     m_Row           = 1;
    2437                 :       1324 :     m_nColOff       = 0;
    2438                 :       1324 :     m_nCurError     = -1;
    2439                 :            : 
    2440         [ -  + ]:       1324 :     for ( size_t i = 0, n = m_aErrDescList.size(); i < n; ++i )
    2441         [ #  # ]:          0 :         delete m_aErrDescList[ i ];
    2442                 :       1324 :     m_aErrDescList.clear();
    2443                 :            : 
    2444         [ -  + ]:       1324 :     while ( !m_aNodeStack.empty() )
    2445                 :          0 :         m_aNodeStack.pop();
    2446                 :            : 
    2447                 :       1324 :     SetLanguage( Application::GetSettings().GetUILanguage() );
    2448                 :       1324 :     NextToken();
    2449                 :       1324 :     Table();
    2450                 :            : 
    2451                 :       1324 :     SmNode* result = lcl_popOrZero(m_aNodeStack);
    2452                 :       1324 :     return result;
    2453                 :            : }
    2454                 :            : 
    2455                 :          0 : SmNode *SmParser::ParseExpression(const String &rBuffer)
    2456                 :            : {
    2457 [ #  # ][ #  # ]:          0 :     m_aBufferString = convertLineEnd(rBuffer, LINEEND_LF);
    2458                 :          0 :     m_nBufferIndex  = 0;
    2459                 :          0 :     m_nTokenIndex   = 0;
    2460                 :          0 :     m_Row           = 1;
    2461                 :          0 :     m_nColOff       = 0;
    2462                 :          0 :     m_nCurError     = -1;
    2463                 :            : 
    2464         [ #  # ]:          0 :     for ( size_t i = 0, n = m_aErrDescList.size(); i < n; ++i )
    2465         [ #  # ]:          0 :         delete m_aErrDescList[ i ];
    2466                 :          0 :     m_aErrDescList.clear();
    2467                 :            : 
    2468         [ #  # ]:          0 :     while ( !m_aNodeStack.empty() )
    2469                 :          0 :         m_aNodeStack.pop();
    2470                 :            : 
    2471                 :          0 :     SetLanguage( Application::GetSettings().GetUILanguage() );
    2472                 :          0 :     NextToken();
    2473                 :          0 :     Expression();
    2474                 :            : 
    2475                 :          0 :     SmNode* result = lcl_popOrZero(m_aNodeStack);
    2476                 :          0 :     return result;
    2477                 :            : }
    2478                 :            : 
    2479                 :            : 
    2480                 :          0 : size_t SmParser::AddError(SmParseError Type, SmNode *pNode)
    2481                 :            : {
    2482 [ #  # ][ #  # ]:          0 :     SmErrorDesc *pErrDesc = new SmErrorDesc;
    2483                 :            : 
    2484                 :          0 :     pErrDesc->Type  = Type;
    2485                 :          0 :     pErrDesc->pNode = pNode;
    2486 [ #  # ][ #  # ]:          0 :     pErrDesc->Text  = String(SmResId(RID_ERR_IDENT));
         [ #  # ][ #  # ]
    2487                 :            : 
    2488                 :            :     sal_uInt16  nRID;
    2489   [ #  #  #  #  :          0 :     switch (Type)
          #  #  #  #  #  
             #  #  #  #  
                      # ]
    2490                 :            :     {
    2491                 :          0 :         case PE_UNEXPECTED_CHAR:     nRID = RID_ERR_UNEXPECTEDCHARACTER;    break;
    2492                 :          0 :         case PE_LGROUP_EXPECTED:     nRID = RID_ERR_LGROUPEXPECTED;         break;
    2493                 :          0 :         case PE_RGROUP_EXPECTED:     nRID = RID_ERR_RGROUPEXPECTED;         break;
    2494                 :          0 :         case PE_LBRACE_EXPECTED:     nRID = RID_ERR_LBRACEEXPECTED;         break;
    2495                 :          0 :         case PE_RBRACE_EXPECTED:     nRID = RID_ERR_RBRACEEXPECTED;         break;
    2496                 :          0 :         case PE_FUNC_EXPECTED:       nRID = RID_ERR_FUNCEXPECTED;           break;
    2497                 :          0 :         case PE_UNOPER_EXPECTED:     nRID = RID_ERR_UNOPEREXPECTED;         break;
    2498                 :          0 :         case PE_BINOPER_EXPECTED:    nRID = RID_ERR_BINOPEREXPECTED;        break;
    2499                 :          0 :         case PE_SYMBOL_EXPECTED:     nRID = RID_ERR_SYMBOLEXPECTED;         break;
    2500                 :          0 :         case PE_IDENTIFIER_EXPECTED: nRID = RID_ERR_IDENTEXPECTED;          break;
    2501                 :          0 :         case PE_POUND_EXPECTED:      nRID = RID_ERR_POUNDEXPECTED;          break;
    2502                 :          0 :         case PE_COLOR_EXPECTED:      nRID = RID_ERR_COLOREXPECTED;          break;
    2503                 :          0 :         case PE_RIGHT_EXPECTED:      nRID = RID_ERR_RIGHTEXPECTED;          break;
    2504                 :            : 
    2505                 :            :         default:
    2506                 :          0 :             nRID = RID_ERR_UNKOWN;
    2507                 :            :     }
    2508 [ #  # ][ #  # ]:          0 :     pErrDesc->Text += SM_RESSTR(nRID);
                 [ #  # ]
    2509                 :            : 
    2510         [ #  # ]:          0 :     m_aErrDescList.push_back( pErrDesc );
    2511                 :            : 
    2512                 :          0 :     return m_aErrDescList.size()-1;
    2513                 :            : }
    2514                 :            : 
    2515                 :            : 
    2516                 :          0 : const SmErrorDesc *SmParser::NextError()
    2517                 :            : {
    2518         [ #  # ]:          0 :     if ( !m_aErrDescList.empty() )
    2519         [ #  # ]:          0 :         if (m_nCurError > 0) return m_aErrDescList[ --m_nCurError ];
    2520                 :            :         else
    2521                 :            :         {
    2522                 :          0 :             m_nCurError = 0;
    2523                 :          0 :             return m_aErrDescList[ m_nCurError ];
    2524                 :            :         }
    2525                 :          0 :     else return NULL;
    2526                 :            : }
    2527                 :            : 
    2528                 :            : 
    2529                 :          0 : const SmErrorDesc *SmParser::PrevError()
    2530                 :            : {
    2531         [ #  # ]:          0 :     if ( !m_aErrDescList.empty() )
    2532         [ #  # ]:          0 :         if (m_nCurError < (int) (m_aErrDescList.size() - 1)) return m_aErrDescList[ ++m_nCurError ];
    2533                 :            :         else
    2534                 :            :         {
    2535                 :          0 :             m_nCurError = (int) (m_aErrDescList.size() - 1);
    2536                 :          0 :             return m_aErrDescList[ m_nCurError ];
    2537                 :            :         }
    2538                 :          0 :     else return NULL;
    2539                 :            : }
    2540                 :            : 
    2541                 :            : 
    2542                 :          0 : const SmErrorDesc *SmParser::GetError(size_t i)
    2543                 :            : {
    2544         [ #  # ]:          0 :     if ( i < m_aErrDescList.size() )
    2545                 :          0 :         return m_aErrDescList[ i ];
    2546                 :            : 
    2547         [ #  # ]:          0 :     if ( (size_t)m_nCurError < m_aErrDescList.size() )
    2548                 :          0 :         return m_aErrDescList[ m_nCurError ];
    2549                 :            : 
    2550                 :          0 :     return NULL;
    2551 [ +  - ][ +  - ]:         30 : }
    2552                 :            : 
    2553                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10