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