LCOV - code coverage report
Current view: top level - libreoffice/i18npool/source/characterclassification - cclass_unicode_parser.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 260 373 69.7 %
Date: 2012-12-27 Functions: 11 11 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : #include <cclass_unicode.hxx>
      22             : #include <unicode/uchar.h>
      23             : #include <rtl/math.hxx>
      24             : #include <rtl/ustring.hxx>
      25             : #include <com/sun/star/i18n/KParseTokens.hpp>
      26             : #include <com/sun/star/i18n/KParseType.hpp>
      27             : #include <com/sun/star/i18n/UnicodeType.hpp>
      28             : #include <com/sun/star/i18n/LocaleData.hpp>
      29             : #include <com/sun/star/i18n/NativeNumberMode.hpp>
      30             : #include <com/sun/star/i18n/NativeNumberSupplier.hpp>
      31             : #include <comphelper/processfactory.hxx>
      32             : 
      33             : #include <string.h>     // memcpy()
      34             : 
      35             : using namespace ::com::sun::star::uno;
      36             : using namespace ::com::sun::star::lang;
      37             : using namespace ::rtl;
      38             : 
      39             : namespace com { namespace sun { namespace star { namespace i18n {
      40             : 
      41             : const UPT_FLAG_TYPE cclass_Unicode::TOKEN_ILLEGAL       = 0x00000000;
      42             : const UPT_FLAG_TYPE cclass_Unicode::TOKEN_CHAR          = 0x00000001;
      43             : const UPT_FLAG_TYPE cclass_Unicode::TOKEN_CHAR_BOOL = 0x00000002;
      44             : const UPT_FLAG_TYPE cclass_Unicode::TOKEN_CHAR_WORD = 0x00000004;
      45             : const UPT_FLAG_TYPE cclass_Unicode::TOKEN_CHAR_VALUE    = 0x00000008;
      46             : const UPT_FLAG_TYPE cclass_Unicode::TOKEN_CHAR_STRING   = 0x00000010;
      47             : const UPT_FLAG_TYPE cclass_Unicode::TOKEN_CHAR_DONTCARE= 0x00000020;
      48             : const UPT_FLAG_TYPE cclass_Unicode::TOKEN_BOOL          = 0x00000040;
      49             : const UPT_FLAG_TYPE cclass_Unicode::TOKEN_WORD          = 0x00000080;
      50             : const UPT_FLAG_TYPE cclass_Unicode::TOKEN_WORD_SEP      = 0x00000100;
      51             : const UPT_FLAG_TYPE cclass_Unicode::TOKEN_VALUE     = 0x00000200;
      52             : const UPT_FLAG_TYPE cclass_Unicode::TOKEN_VALUE_SEP = 0x00000400;
      53             : const UPT_FLAG_TYPE cclass_Unicode::TOKEN_VALUE_EXP = 0x00000800;
      54             : const UPT_FLAG_TYPE cclass_Unicode::TOKEN_VALUE_SIGN    = 0x00001000;
      55             : const UPT_FLAG_TYPE cclass_Unicode::TOKEN_VALUE_EXP_VALUE   = 0x00002000;
      56             : const UPT_FLAG_TYPE cclass_Unicode::TOKEN_VALUE_DIGIT   = 0x00004000;
      57             : const UPT_FLAG_TYPE cclass_Unicode::TOKEN_NAME_SEP      = 0x20000000;
      58             : const UPT_FLAG_TYPE cclass_Unicode::TOKEN_STRING_SEP    = 0x40000000;
      59             : const UPT_FLAG_TYPE cclass_Unicode::TOKEN_EXCLUDED      = 0x80000000;
      60             : 
      61             : #define TOKEN_DIGIT_FLAGS (TOKEN_CHAR_VALUE | TOKEN_VALUE | TOKEN_VALUE_EXP | TOKEN_VALUE_EXP_VALUE | TOKEN_VALUE_DIGIT)
      62             : 
      63             : // Default identifier/name specification is [A-Za-z_][A-Za-z0-9_]*
      64             : 
      65             : const sal_uInt8 cclass_Unicode::nDefCnt = 128;
      66             : const UPT_FLAG_TYPE cclass_Unicode::pDefaultParserTable[ nDefCnt ] =
      67             : {
      68             : // (...) == Calc formula compiler specific, commented out and modified
      69             : 
      70             :     /* \0 */    TOKEN_EXCLUDED,
      71             :                 TOKEN_ILLEGAL,
      72             :                 TOKEN_ILLEGAL,
      73             :                 TOKEN_ILLEGAL,
      74             :                 TOKEN_ILLEGAL,
      75             :                 TOKEN_ILLEGAL,
      76             :                 TOKEN_ILLEGAL,
      77             :                 TOKEN_ILLEGAL,
      78             :                 TOKEN_ILLEGAL,
      79             :     /*  9 \t */ TOKEN_CHAR_DONTCARE | TOKEN_WORD_SEP | TOKEN_VALUE_SEP,     // (TOKEN_ILLEGAL)
      80             :                 TOKEN_ILLEGAL,
      81             :     /* 11 \v */ TOKEN_CHAR_DONTCARE | TOKEN_WORD_SEP | TOKEN_VALUE_SEP,     // (TOKEN_ILLEGAL)
      82             :                 TOKEN_ILLEGAL,
      83             :                 TOKEN_ILLEGAL,
      84             :                 TOKEN_ILLEGAL,
      85             :                 TOKEN_ILLEGAL,
      86             :                 TOKEN_ILLEGAL,
      87             :                 TOKEN_ILLEGAL,
      88             :                 TOKEN_ILLEGAL,
      89             :                 TOKEN_ILLEGAL,
      90             :                 TOKEN_ILLEGAL,
      91             :                 TOKEN_ILLEGAL,
      92             :                 TOKEN_ILLEGAL,
      93             :                 TOKEN_ILLEGAL,
      94             :                 TOKEN_ILLEGAL,
      95             :                 TOKEN_ILLEGAL,
      96             :                 TOKEN_ILLEGAL,
      97             :                 TOKEN_ILLEGAL,
      98             :                 TOKEN_ILLEGAL,
      99             :                 TOKEN_ILLEGAL,
     100             :                 TOKEN_ILLEGAL,
     101             :                 TOKEN_ILLEGAL,
     102             :     /*  32   */ TOKEN_CHAR_DONTCARE | TOKEN_WORD_SEP | TOKEN_VALUE_SEP,
     103             :     /*  33 ! */ TOKEN_CHAR | TOKEN_WORD_SEP | TOKEN_VALUE_SEP,
     104             :     /*  34 " */ TOKEN_CHAR_STRING | TOKEN_STRING_SEP,
     105             :     /*  35 # */ TOKEN_CHAR | TOKEN_WORD_SEP | TOKEN_VALUE_SEP,  // (TOKEN_WORD_SEP)
     106             :     /*  36 $ */ TOKEN_CHAR | TOKEN_WORD_SEP | TOKEN_VALUE_SEP,  // (TOKEN_CHAR_WORD | TOKEN_WORD)
     107             :     /*  37 % */ TOKEN_CHAR | TOKEN_WORD_SEP | TOKEN_VALUE_SEP,  // (TOKEN_VALUE)
     108             :     /*  38 & */ TOKEN_CHAR | TOKEN_WORD_SEP | TOKEN_VALUE_SEP,
     109             :     /*  39 ' */ TOKEN_NAME_SEP,
     110             :     /*  40 ( */ TOKEN_CHAR | TOKEN_WORD_SEP | TOKEN_VALUE_SEP,
     111             :     /*  41 ) */ TOKEN_CHAR | TOKEN_WORD_SEP | TOKEN_VALUE_SEP,
     112             :     /*  42 * */ TOKEN_CHAR | TOKEN_WORD_SEP | TOKEN_VALUE_SEP,
     113             :     /*  43 + */ TOKEN_CHAR | TOKEN_WORD_SEP | TOKEN_VALUE_SEP | TOKEN_VALUE_EXP | TOKEN_VALUE_SIGN,
     114             :     /*  44 , */ TOKEN_CHAR | TOKEN_WORD_SEP | TOKEN_VALUE_SEP,  // (TOKEN_CHAR_VALUE | TOKEN_VALUE)
     115             :     /*  45 - */ TOKEN_CHAR | TOKEN_WORD_SEP | TOKEN_VALUE_SEP | TOKEN_VALUE_EXP | TOKEN_VALUE_SIGN,
     116             :     /*  46 . */ TOKEN_CHAR | TOKEN_WORD_SEP | TOKEN_VALUE_SEP,  // (TOKEN_WORD | TOKEN_CHAR_VALUE | TOKEN_VALUE)
     117             :     /*  47 / */ TOKEN_CHAR | TOKEN_WORD_SEP | TOKEN_VALUE_SEP,
     118             :     //for ( i = 48; i < 58; i++ )
     119             :     /*  48 0 */ TOKEN_DIGIT_FLAGS | TOKEN_WORD,
     120             :     /*  49 1 */ TOKEN_DIGIT_FLAGS | TOKEN_WORD,
     121             :     /*  50 2 */ TOKEN_DIGIT_FLAGS | TOKEN_WORD,
     122             :     /*  51 3 */ TOKEN_DIGIT_FLAGS | TOKEN_WORD,
     123             :     /*  52 4 */ TOKEN_DIGIT_FLAGS | TOKEN_WORD,
     124             :     /*  53 5 */ TOKEN_DIGIT_FLAGS | TOKEN_WORD,
     125             :     /*  54 6 */ TOKEN_DIGIT_FLAGS | TOKEN_WORD,
     126             :     /*  55 7 */ TOKEN_DIGIT_FLAGS | TOKEN_WORD,
     127             :     /*  56 8 */ TOKEN_DIGIT_FLAGS | TOKEN_WORD,
     128             :     /*  57 9 */ TOKEN_DIGIT_FLAGS | TOKEN_WORD,
     129             :     /*  58 : */ TOKEN_CHAR | TOKEN_WORD_SEP | TOKEN_VALUE_SEP,  // (TOKEN_WORD)
     130             :     /*  59 ; */ TOKEN_CHAR | TOKEN_WORD_SEP | TOKEN_VALUE_SEP,
     131             :     /*  60 < */ TOKEN_CHAR_BOOL | TOKEN_WORD_SEP | TOKEN_VALUE_SEP,
     132             :     /*  61 = */ TOKEN_CHAR | TOKEN_BOOL | TOKEN_WORD_SEP | TOKEN_VALUE_SEP,
     133             :     /*  62 > */ TOKEN_CHAR_BOOL | TOKEN_BOOL | TOKEN_WORD_SEP | TOKEN_VALUE_SEP,
     134             :     /*  63 ? */ TOKEN_CHAR | TOKEN_WORD_SEP | TOKEN_VALUE_SEP,  // (TOKEN_CHAR_WORD | TOKEN_WORD)
     135             :     /*  64 @ */ TOKEN_CHAR | TOKEN_WORD_SEP | TOKEN_VALUE_SEP,  // (TOKEN_ILLEGAL // UNUSED)
     136             :     //for ( i = 65; i < 91; i++ )
     137             :     /*  65 A */ TOKEN_CHAR_WORD | TOKEN_WORD,
     138             :     /*  66 B */ TOKEN_CHAR_WORD | TOKEN_WORD,
     139             :     /*  67 C */ TOKEN_CHAR_WORD | TOKEN_WORD,
     140             :     /*  68 D */ TOKEN_CHAR_WORD | TOKEN_WORD,
     141             :     /*  69 E */ TOKEN_CHAR_WORD | TOKEN_WORD,
     142             :     /*  70 F */ TOKEN_CHAR_WORD | TOKEN_WORD,
     143             :     /*  71 G */ TOKEN_CHAR_WORD | TOKEN_WORD,
     144             :     /*  72 H */ TOKEN_CHAR_WORD | TOKEN_WORD,
     145             :     /*  73 I */ TOKEN_CHAR_WORD | TOKEN_WORD,
     146             :     /*  74 J */ TOKEN_CHAR_WORD | TOKEN_WORD,
     147             :     /*  75 K */ TOKEN_CHAR_WORD | TOKEN_WORD,
     148             :     /*  76 L */ TOKEN_CHAR_WORD | TOKEN_WORD,
     149             :     /*  77 M */ TOKEN_CHAR_WORD | TOKEN_WORD,
     150             :     /*  78 N */ TOKEN_CHAR_WORD | TOKEN_WORD,
     151             :     /*  79 O */ TOKEN_CHAR_WORD | TOKEN_WORD,
     152             :     /*  80 P */ TOKEN_CHAR_WORD | TOKEN_WORD,
     153             :     /*  81 Q */ TOKEN_CHAR_WORD | TOKEN_WORD,
     154             :     /*  82 R */ TOKEN_CHAR_WORD | TOKEN_WORD,
     155             :     /*  83 S */ TOKEN_CHAR_WORD | TOKEN_WORD,
     156             :     /*  84 T */ TOKEN_CHAR_WORD | TOKEN_WORD,
     157             :     /*  85 U */ TOKEN_CHAR_WORD | TOKEN_WORD,
     158             :     /*  86 V */ TOKEN_CHAR_WORD | TOKEN_WORD,
     159             :     /*  87 W */ TOKEN_CHAR_WORD | TOKEN_WORD,
     160             :     /*  88 X */ TOKEN_CHAR_WORD | TOKEN_WORD,
     161             :     /*  89 Y */ TOKEN_CHAR_WORD | TOKEN_WORD,
     162             :     /*  90 Z */ TOKEN_CHAR_WORD | TOKEN_WORD,
     163             :     /*  91 [ */ TOKEN_CHAR | TOKEN_WORD_SEP | TOKEN_VALUE_SEP,  // (TOKEN_ILLEGAL // UNUSED)
     164             :     /*  92 \ */ TOKEN_CHAR | TOKEN_WORD_SEP | TOKEN_VALUE_SEP,  // (TOKEN_ILLEGAL // UNUSED)
     165             :     /*  93 ] */ TOKEN_CHAR | TOKEN_WORD_SEP | TOKEN_VALUE_SEP,  // (TOKEN_ILLEGAL // UNUSED)
     166             :     /*  94 ^ */ TOKEN_CHAR | TOKEN_WORD_SEP | TOKEN_VALUE_SEP,
     167             :     /*  95 _ */ TOKEN_CHAR_WORD | TOKEN_WORD,
     168             :     /*  96 ` */ TOKEN_CHAR | TOKEN_WORD_SEP | TOKEN_VALUE_SEP,  // (TOKEN_ILLEGAL // UNUSED)
     169             :     //for ( i = 97; i < 123; i++ )
     170             :     /*  97 a */ TOKEN_CHAR_WORD | TOKEN_WORD,
     171             :     /*  98 b */ TOKEN_CHAR_WORD | TOKEN_WORD,
     172             :     /*  99 c */ TOKEN_CHAR_WORD | TOKEN_WORD,
     173             :     /* 100 d */ TOKEN_CHAR_WORD | TOKEN_WORD,
     174             :     /* 101 e */ TOKEN_CHAR_WORD | TOKEN_WORD,
     175             :     /* 102 f */ TOKEN_CHAR_WORD | TOKEN_WORD,
     176             :     /* 103 g */ TOKEN_CHAR_WORD | TOKEN_WORD,
     177             :     /* 104 h */ TOKEN_CHAR_WORD | TOKEN_WORD,
     178             :     /* 105 i */ TOKEN_CHAR_WORD | TOKEN_WORD,
     179             :     /* 106 j */ TOKEN_CHAR_WORD | TOKEN_WORD,
     180             :     /* 107 k */ TOKEN_CHAR_WORD | TOKEN_WORD,
     181             :     /* 108 l */ TOKEN_CHAR_WORD | TOKEN_WORD,
     182             :     /* 109 m */ TOKEN_CHAR_WORD | TOKEN_WORD,
     183             :     /* 110 n */ TOKEN_CHAR_WORD | TOKEN_WORD,
     184             :     /* 111 o */ TOKEN_CHAR_WORD | TOKEN_WORD,
     185             :     /* 112 p */ TOKEN_CHAR_WORD | TOKEN_WORD,
     186             :     /* 113 q */ TOKEN_CHAR_WORD | TOKEN_WORD,
     187             :     /* 114 r */ TOKEN_CHAR_WORD | TOKEN_WORD,
     188             :     /* 115 s */ TOKEN_CHAR_WORD | TOKEN_WORD,
     189             :     /* 116 t */ TOKEN_CHAR_WORD | TOKEN_WORD,
     190             :     /* 117 u */ TOKEN_CHAR_WORD | TOKEN_WORD,
     191             :     /* 118 v */ TOKEN_CHAR_WORD | TOKEN_WORD,
     192             :     /* 119 w */ TOKEN_CHAR_WORD | TOKEN_WORD,
     193             :     /* 120 x */ TOKEN_CHAR_WORD | TOKEN_WORD,
     194             :     /* 121 y */ TOKEN_CHAR_WORD | TOKEN_WORD,
     195             :     /* 122 z */ TOKEN_CHAR_WORD | TOKEN_WORD,
     196             :     /* 123 { */ TOKEN_CHAR | TOKEN_WORD_SEP | TOKEN_VALUE_SEP,  // (TOKEN_ILLEGAL // UNUSED)
     197             :     /* 124 | */ TOKEN_CHAR | TOKEN_WORD_SEP | TOKEN_VALUE_SEP,  // (TOKEN_ILLEGAL // UNUSED)
     198             :     /* 125 } */ TOKEN_CHAR | TOKEN_WORD_SEP | TOKEN_VALUE_SEP,  // (TOKEN_ILLEGAL // UNUSED)
     199             :     /* 126 ~ */ TOKEN_CHAR | TOKEN_WORD_SEP | TOKEN_VALUE_SEP,  // (TOKEN_ILLEGAL // UNUSED)
     200             :     /* 127   */ TOKEN_CHAR | TOKEN_WORD_SEP | TOKEN_VALUE_SEP   // (TOKEN_ILLEGAL // UNUSED)
     201             : };
     202             : 
     203             : 
     204             : const sal_Int32 cclass_Unicode::pParseTokensType[ nDefCnt ] =
     205             : {
     206             :     /* \0 */    KParseTokens::ASC_OTHER,
     207             :                 KParseTokens::ASC_CONTROL,
     208             :                 KParseTokens::ASC_CONTROL,
     209             :                 KParseTokens::ASC_CONTROL,
     210             :                 KParseTokens::ASC_CONTROL,
     211             :                 KParseTokens::ASC_CONTROL,
     212             :                 KParseTokens::ASC_CONTROL,
     213             :                 KParseTokens::ASC_CONTROL,
     214             :                 KParseTokens::ASC_CONTROL,
     215             :     /*  9 \t */ KParseTokens::ASC_CONTROL,
     216             :                 KParseTokens::ASC_CONTROL,
     217             :     /* 11 \v */ KParseTokens::ASC_CONTROL,
     218             :                 KParseTokens::ASC_CONTROL,
     219             :                 KParseTokens::ASC_CONTROL,
     220             :                 KParseTokens::ASC_CONTROL,
     221             :                 KParseTokens::ASC_CONTROL,
     222             :                 KParseTokens::ASC_CONTROL,
     223             :                 KParseTokens::ASC_CONTROL,
     224             :                 KParseTokens::ASC_CONTROL,
     225             :                 KParseTokens::ASC_CONTROL,
     226             :                 KParseTokens::ASC_CONTROL,
     227             :                 KParseTokens::ASC_CONTROL,
     228             :                 KParseTokens::ASC_CONTROL,
     229             :                 KParseTokens::ASC_CONTROL,
     230             :                 KParseTokens::ASC_CONTROL,
     231             :                 KParseTokens::ASC_CONTROL,
     232             :                 KParseTokens::ASC_CONTROL,
     233             :                 KParseTokens::ASC_CONTROL,
     234             :                 KParseTokens::ASC_CONTROL,
     235             :                 KParseTokens::ASC_CONTROL,
     236             :                 KParseTokens::ASC_CONTROL,
     237             :                 KParseTokens::ASC_CONTROL,
     238             :     /*  32   */ KParseTokens::ASC_OTHER,
     239             :     /*  33 ! */ KParseTokens::ASC_OTHER,
     240             :     /*  34 " */ KParseTokens::ASC_OTHER,
     241             :     /*  35 # */ KParseTokens::ASC_OTHER,
     242             :     /*  36 $ */ KParseTokens::ASC_DOLLAR,
     243             :     /*  37 % */ KParseTokens::ASC_OTHER,
     244             :     /*  38 & */ KParseTokens::ASC_OTHER,
     245             :     /*  39 ' */ KParseTokens::ASC_OTHER,
     246             :     /*  40 ( */ KParseTokens::ASC_OTHER,
     247             :     /*  41 ) */ KParseTokens::ASC_OTHER,
     248             :     /*  42 * */ KParseTokens::ASC_OTHER,
     249             :     /*  43 + */ KParseTokens::ASC_OTHER,
     250             :     /*  44 , */ KParseTokens::ASC_OTHER,
     251             :     /*  45 - */ KParseTokens::ASC_OTHER,
     252             :     /*  46 . */ KParseTokens::ASC_DOT,
     253             :     /*  47 / */ KParseTokens::ASC_OTHER,
     254             :     //for ( i = 48; i < 58; i++ )
     255             :     /*  48 0 */ KParseTokens::ASC_DIGIT,
     256             :     /*  49 1 */ KParseTokens::ASC_DIGIT,
     257             :     /*  50 2 */ KParseTokens::ASC_DIGIT,
     258             :     /*  51 3 */ KParseTokens::ASC_DIGIT,
     259             :     /*  52 4 */ KParseTokens::ASC_DIGIT,
     260             :     /*  53 5 */ KParseTokens::ASC_DIGIT,
     261             :     /*  54 6 */ KParseTokens::ASC_DIGIT,
     262             :     /*  55 7 */ KParseTokens::ASC_DIGIT,
     263             :     /*  56 8 */ KParseTokens::ASC_DIGIT,
     264             :     /*  57 9 */ KParseTokens::ASC_DIGIT,
     265             :     /*  58 : */ KParseTokens::ASC_COLON,
     266             :     /*  59 ; */ KParseTokens::ASC_OTHER,
     267             :     /*  60 < */ KParseTokens::ASC_OTHER,
     268             :     /*  61 = */ KParseTokens::ASC_OTHER,
     269             :     /*  62 > */ KParseTokens::ASC_OTHER,
     270             :     /*  63 ? */ KParseTokens::ASC_OTHER,
     271             :     /*  64 @ */ KParseTokens::ASC_OTHER,
     272             :     //for ( i = 65; i < 91; i++ )
     273             :     /*  65 A */ KParseTokens::ASC_UPALPHA,
     274             :     /*  66 B */ KParseTokens::ASC_UPALPHA,
     275             :     /*  67 C */ KParseTokens::ASC_UPALPHA,
     276             :     /*  68 D */ KParseTokens::ASC_UPALPHA,
     277             :     /*  69 E */ KParseTokens::ASC_UPALPHA,
     278             :     /*  70 F */ KParseTokens::ASC_UPALPHA,
     279             :     /*  71 G */ KParseTokens::ASC_UPALPHA,
     280             :     /*  72 H */ KParseTokens::ASC_UPALPHA,
     281             :     /*  73 I */ KParseTokens::ASC_UPALPHA,
     282             :     /*  74 J */ KParseTokens::ASC_UPALPHA,
     283             :     /*  75 K */ KParseTokens::ASC_UPALPHA,
     284             :     /*  76 L */ KParseTokens::ASC_UPALPHA,
     285             :     /*  77 M */ KParseTokens::ASC_UPALPHA,
     286             :     /*  78 N */ KParseTokens::ASC_UPALPHA,
     287             :     /*  79 O */ KParseTokens::ASC_UPALPHA,
     288             :     /*  80 P */ KParseTokens::ASC_UPALPHA,
     289             :     /*  81 Q */ KParseTokens::ASC_UPALPHA,
     290             :     /*  82 R */ KParseTokens::ASC_UPALPHA,
     291             :     /*  83 S */ KParseTokens::ASC_UPALPHA,
     292             :     /*  84 T */ KParseTokens::ASC_UPALPHA,
     293             :     /*  85 U */ KParseTokens::ASC_UPALPHA,
     294             :     /*  86 V */ KParseTokens::ASC_UPALPHA,
     295             :     /*  87 W */ KParseTokens::ASC_UPALPHA,
     296             :     /*  88 X */ KParseTokens::ASC_UPALPHA,
     297             :     /*  89 Y */ KParseTokens::ASC_UPALPHA,
     298             :     /*  90 Z */ KParseTokens::ASC_UPALPHA,
     299             :     /*  91 [ */ KParseTokens::ASC_OTHER,
     300             :     /*  92 \ */ KParseTokens::ASC_OTHER,
     301             :     /*  93 ] */ KParseTokens::ASC_OTHER,
     302             :     /*  94 ^ */ KParseTokens::ASC_OTHER,
     303             :     /*  95 _ */ KParseTokens::ASC_UNDERSCORE,
     304             :     /*  96 ` */ KParseTokens::ASC_OTHER,
     305             :     //for ( i = 97; i < 123; i++ )
     306             :     /*  97 a */ KParseTokens::ASC_LOALPHA,
     307             :     /*  98 b */ KParseTokens::ASC_LOALPHA,
     308             :     /*  99 c */ KParseTokens::ASC_LOALPHA,
     309             :     /* 100 d */ KParseTokens::ASC_LOALPHA,
     310             :     /* 101 e */ KParseTokens::ASC_LOALPHA,
     311             :     /* 102 f */ KParseTokens::ASC_LOALPHA,
     312             :     /* 103 g */ KParseTokens::ASC_LOALPHA,
     313             :     /* 104 h */ KParseTokens::ASC_LOALPHA,
     314             :     /* 105 i */ KParseTokens::ASC_LOALPHA,
     315             :     /* 106 j */ KParseTokens::ASC_LOALPHA,
     316             :     /* 107 k */ KParseTokens::ASC_LOALPHA,
     317             :     /* 108 l */ KParseTokens::ASC_LOALPHA,
     318             :     /* 109 m */ KParseTokens::ASC_LOALPHA,
     319             :     /* 110 n */ KParseTokens::ASC_LOALPHA,
     320             :     /* 111 o */ KParseTokens::ASC_LOALPHA,
     321             :     /* 112 p */ KParseTokens::ASC_LOALPHA,
     322             :     /* 113 q */ KParseTokens::ASC_LOALPHA,
     323             :     /* 114 r */ KParseTokens::ASC_LOALPHA,
     324             :     /* 115 s */ KParseTokens::ASC_LOALPHA,
     325             :     /* 116 t */ KParseTokens::ASC_LOALPHA,
     326             :     /* 117 u */ KParseTokens::ASC_LOALPHA,
     327             :     /* 118 v */ KParseTokens::ASC_LOALPHA,
     328             :     /* 119 w */ KParseTokens::ASC_LOALPHA,
     329             :     /* 120 x */ KParseTokens::ASC_LOALPHA,
     330             :     /* 121 y */ KParseTokens::ASC_LOALPHA,
     331             :     /* 122 z */ KParseTokens::ASC_LOALPHA,
     332             :     /* 123 { */ KParseTokens::ASC_OTHER,
     333             :     /* 124 | */ KParseTokens::ASC_OTHER,
     334             :     /* 125 } */ KParseTokens::ASC_OTHER,
     335             :     /* 126 ~ */ KParseTokens::ASC_OTHER,
     336             :     /* 127   */ KParseTokens::ASC_OTHER
     337             : };
     338             : 
     339             : 
     340             : // static
     341          53 : const sal_Unicode* cclass_Unicode::StrChr( const sal_Unicode* pStr, sal_Unicode c )
     342             : {
     343          53 :     if ( !pStr )
     344           0 :         return NULL;
     345         212 :     while ( *pStr )
     346             :     {
     347         106 :         if ( *pStr == c )
     348           0 :             return pStr;
     349         106 :         pStr++;
     350             :     }
     351          53 :     return NULL;
     352             : }
     353             : 
     354             : 
     355       27113 : sal_Int32 cclass_Unicode::getParseTokensType( const sal_Unicode* aStr, sal_Int32 nPos )
     356             : {
     357       27113 :     sal_Unicode c = aStr[nPos];
     358       27113 :     if ( c < nDefCnt )
     359       26741 :         return pParseTokensType[ sal_uInt8(c) ];
     360             :     else
     361             :     {
     362             : 
     363             :         //! all KParseTokens::UNI_... must be matched
     364         372 :         switch ( u_charType( (sal_uInt32) c ) )
     365             :         {
     366             :             case U_UPPERCASE_LETTER :
     367           0 :                 return KParseTokens::UNI_UPALPHA;
     368             :             case U_LOWERCASE_LETTER :
     369         186 :                 return KParseTokens::UNI_LOALPHA;
     370             :             case U_TITLECASE_LETTER :
     371           0 :                 return KParseTokens::UNI_TITLE_ALPHA;
     372             :             case U_MODIFIER_LETTER :
     373           0 :                 return KParseTokens::UNI_MODIFIER_LETTER;
     374             :             case U_OTHER_LETTER :
     375             :                 // Non_Spacing_Mark could not be as leading character
     376           0 :                 if (nPos == 0) break;
     377             :                 // fall through, treat it as Other_Letter.
     378             :             case U_NON_SPACING_MARK :
     379           0 :                 return KParseTokens::UNI_OTHER_LETTER;
     380             :             case U_DECIMAL_DIGIT_NUMBER :
     381           0 :                 return KParseTokens::UNI_DIGIT;
     382             :             case U_LETTER_NUMBER :
     383           0 :                 return KParseTokens::UNI_LETTER_NUMBER;
     384             :             case U_OTHER_NUMBER :
     385           0 :                 return KParseTokens::UNI_OTHER_NUMBER;
     386             :         }
     387             : 
     388         186 :         return KParseTokens::UNI_OTHER;
     389             :     }
     390             : }
     391             : 
     392       11359 : sal_Bool cclass_Unicode::setupInternational( const Locale& rLocale )
     393             : {
     394       11359 :     sal_Bool bChanged = (aParserLocale.Language != rLocale.Language
     395        1101 :         || aParserLocale.Country != rLocale.Country
     396       12460 :         || aParserLocale.Variant != rLocale.Variant);
     397       11359 :     if ( bChanged )
     398             :     {
     399       10258 :         aParserLocale.Language = rLocale.Language;
     400       10258 :         aParserLocale.Country = rLocale.Country;
     401       10258 :         aParserLocale.Variant = rLocale.Variant;
     402             :     }
     403       11359 :     if ( !mxLocaleData.is() )
     404             :     {
     405       10258 :         mxLocaleData.set( LocaleData::create(m_xContext) );
     406             :     }
     407       11359 :     return bChanged;
     408             : }
     409             : 
     410             : 
     411       11449 : void cclass_Unicode::setupParserTable( const Locale& rLocale, sal_Int32 startCharTokenType,
     412             :             const OUString& userDefinedCharactersStart, sal_Int32 contCharTokenType,
     413             :             const OUString& userDefinedCharactersCont )
     414             : {
     415       11449 :     bool bIntlEqual = (rLocale.Language == aParserLocale.Language &&
     416        1191 :         rLocale.Country == aParserLocale.Country &&
     417       12640 :         rLocale.Variant == aParserLocale.Variant);
     418       11629 :     if ( !pTable || !bIntlEqual ||
     419             :             startCharTokenType != nStartTypes ||
     420             :             contCharTokenType != nContTypes ||
     421          90 :             userDefinedCharactersStart != aStartChars ||
     422          90 :             userDefinedCharactersCont != aContChars )
     423             :         initParserTable( rLocale, startCharTokenType, userDefinedCharactersStart,
     424       11359 :             contCharTokenType, userDefinedCharactersCont );
     425       11449 : }
     426             : 
     427             : 
     428       11359 : void cclass_Unicode::initParserTable( const Locale& rLocale, sal_Int32 startCharTokenType,
     429             :             const OUString& userDefinedCharactersStart, sal_Int32 contCharTokenType,
     430             :             const OUString& userDefinedCharactersCont )
     431             : {
     432             :     // (Re)Init
     433       11359 :     setupInternational( rLocale );
     434             :     // Memory of pTable is reused.
     435       11359 :     if ( !pTable )
     436       10258 :         pTable = new UPT_FLAG_TYPE[nDefCnt];
     437       11359 :     memcpy( pTable, pDefaultParserTable, sizeof(UPT_FLAG_TYPE) * nDefCnt );
     438             :     // Start and cont tables only need reallocation if different length.
     439       11359 :     if ( pStart && userDefinedCharactersStart.getLength() != aStartChars.getLength() )
     440             :     {
     441          76 :         delete [] pStart;
     442          76 :         pStart = NULL;
     443             :     }
     444       11359 :     if ( pCont && userDefinedCharactersCont.getLength() != aContChars.getLength() )
     445             :     {
     446          76 :         delete [] pCont;
     447          76 :         pCont = NULL;
     448             :     }
     449       11359 :     nStartTypes = startCharTokenType;
     450       11359 :     nContTypes = contCharTokenType;
     451       11359 :     aStartChars = userDefinedCharactersStart;
     452       11359 :     aContChars = userDefinedCharactersCont;
     453             : 
     454             :     // specials
     455       11359 :     if( mxLocaleData.is() )
     456             :     {
     457             :         LocaleDataItem aItem =
     458       11359 :             mxLocaleData->getLocaleItem( aParserLocale );
     459             : //!TODO: theoretically separators may be a string, adjustment would have to be
     460             : //! done here and in parsing and in ::rtl::math::stringToDouble()
     461       11359 :         cGroupSep = aItem.thousandSeparator.getStr()[0];
     462       11359 :         cDecimalSep = aItem.decimalSeparator.getStr()[0];
     463             :     }
     464             : 
     465       11359 :     if ( cGroupSep < nDefCnt )
     466       11359 :         pTable[cGroupSep] |= TOKEN_VALUE;
     467       11359 :     if ( cDecimalSep < nDefCnt )
     468       11359 :         pTable[cDecimalSep] |= TOKEN_CHAR_VALUE | TOKEN_VALUE;
     469             : 
     470             :     // Modify characters according to KParseTokens definitions.
     471             :     {
     472             :         using namespace KParseTokens;
     473             :         sal_uInt8 i;
     474             : 
     475       11359 :         if ( !(nStartTypes & ASC_UPALPHA) )
     476       22086 :             for ( i = 65; i < 91; i++ )
     477       21268 :                 pTable[i] &= ~TOKEN_CHAR_WORD;  // not allowed as start character
     478       11359 :         if ( !(nContTypes & ASC_UPALPHA) )
     479       22086 :             for ( i = 65; i < 91; i++ )
     480       21268 :                 pTable[i] &= ~TOKEN_WORD;       // not allowed as cont character
     481             : 
     482       11359 :         if ( !(nStartTypes & ASC_LOALPHA) )
     483       22086 :             for ( i = 97; i < 123; i++ )
     484       21268 :                 pTable[i] &= ~TOKEN_CHAR_WORD;  // not allowed as start character
     485       11359 :         if ( !(nContTypes & ASC_LOALPHA) )
     486       22086 :             for ( i = 97; i < 123; i++ )
     487       21268 :                 pTable[i] &= ~TOKEN_WORD;       // not allowed as cont character
     488             : 
     489       11359 :         if ( nStartTypes & ASC_DIGIT )
     490      123519 :             for ( i = 48; i < 58; i++ )
     491      112290 :                 pTable[i] |= TOKEN_CHAR_WORD;   // allowed as start character
     492       11359 :         if ( !(nContTypes & ASC_DIGIT) )
     493           0 :             for ( i = 48; i < 58; i++ )
     494           0 :                 pTable[i] &= ~TOKEN_WORD;       // not allowed as cont character
     495             : 
     496       11359 :         if ( !(nStartTypes & ASC_UNDERSCORE) )
     497       11201 :             pTable[95] &= ~TOKEN_CHAR_WORD;     // not allowed as start character
     498       11359 :         if ( !(nContTypes & ASC_UNDERSCORE) )
     499       11201 :             pTable[95] &= ~TOKEN_WORD;          // not allowed as cont character
     500             : 
     501       11359 :         if ( nStartTypes & ASC_DOLLAR )
     502          77 :             pTable[36] |= TOKEN_CHAR_WORD;      // allowed as start character
     503       11359 :         if ( nContTypes & ASC_DOLLAR )
     504          77 :             pTable[36] |= TOKEN_WORD;           // allowed as cont character
     505             : 
     506       11359 :         if ( nStartTypes & ASC_DOT )
     507           0 :             pTable[46] |= TOKEN_CHAR_WORD;      // allowed as start character
     508       11359 :         if ( nContTypes & ASC_DOT )
     509       11280 :             pTable[46] |= TOKEN_WORD;           // allowed as cont character
     510             : 
     511       11359 :         if ( nStartTypes & ASC_COLON )
     512           0 :             pTable[58] |= TOKEN_CHAR_WORD;      // allowed as start character
     513       11359 :         if ( nContTypes & ASC_COLON )
     514           0 :             pTable[58] |= TOKEN_WORD;           // allowed as cont character
     515             : 
     516       11359 :         if ( nStartTypes & ASC_CONTROL )
     517           0 :             for ( i = 1; i < 32; i++ )
     518           0 :                 pTable[i] |= TOKEN_CHAR_WORD;   // allowed as start character
     519       11359 :         if ( nContTypes & ASC_CONTROL )
     520           0 :             for ( i = 1; i < 32; i++ )
     521           0 :                 pTable[i] |= TOKEN_WORD;        // allowed as cont character
     522             : 
     523       11359 :         if ( nStartTypes & ASC_ANY_BUT_CONTROL )
     524           0 :             for ( i = 32; i < nDefCnt; i++ )
     525           0 :                 pTable[i] |= TOKEN_CHAR_WORD;   // allowed as start character
     526       11359 :         if ( nContTypes & ASC_ANY_BUT_CONTROL )
     527           0 :             for ( i = 32; i < nDefCnt; i++ )
     528           0 :                 pTable[i] |= TOKEN_WORD;        // allowed as cont character
     529             : 
     530             :     }
     531             : 
     532             :     // Merge in (positively override with) user defined characters.
     533             :     // StartChars
     534       11359 :     sal_Int32 nLen = aStartChars.getLength();
     535       11359 :     if ( nLen )
     536             :     {
     537          77 :         if ( !pStart )
     538          77 :             pStart = new UPT_FLAG_TYPE[ nLen ];
     539          77 :         const sal_Unicode* p = aStartChars.getStr();
     540         231 :         for ( sal_Int32 j=0; j<nLen; j++, p++ )
     541             :         {
     542         154 :             pStart[j] = TOKEN_CHAR_WORD;
     543         154 :             if ( *p < nDefCnt )
     544         154 :                 pTable[*p] |= TOKEN_CHAR_WORD;
     545             :         }
     546             :     }
     547             :     // ContChars
     548       11359 :     nLen = aContChars.getLength();
     549       11359 :     if ( nLen )
     550             :     {
     551          77 :         if ( !pCont )
     552          77 :             pCont = new UPT_FLAG_TYPE[ nLen ];
     553          77 :         const sal_Unicode* p = aContChars.getStr();
     554         231 :         for ( sal_Int32 j=0; j<nLen; j++ )
     555             :         {
     556         154 :             pCont[j] = TOKEN_WORD;
     557         154 :             if ( *p < nDefCnt )
     558         154 :                 pTable[*p] |= TOKEN_WORD;
     559             :         }
     560             :     }
     561       11359 : }
     562             : 
     563             : 
     564       11461 : void cclass_Unicode::destroyParserTable()
     565             : {
     566       11461 :     if ( pCont )
     567           0 :         delete [] pCont;
     568       11461 :     if ( pStart )
     569           0 :         delete [] pStart;
     570       11461 :     if ( pTable )
     571       10255 :         delete [] pTable;
     572       11461 : }
     573             : 
     574             : 
     575       27113 : UPT_FLAG_TYPE cclass_Unicode::getFlags( const sal_Unicode* aStr, sal_Int32 nPos )
     576             : {
     577             :     UPT_FLAG_TYPE nMask;
     578       27113 :     sal_Unicode c = aStr[nPos];
     579       27113 :     if ( c < nDefCnt )
     580       26741 :         nMask = pTable[ sal_uInt8(c) ];
     581             :     else
     582         372 :         nMask = getFlagsExtended( aStr, nPos );
     583       27113 :     switch ( eState )
     584             :     {
     585             :         case ssGetChar :
     586             :         case ssRewindFromValue :
     587             :         case ssIgnoreLeadingInRewind :
     588             :         case ssGetWordFirstChar :
     589       11453 :             if ( !(nMask & TOKEN_CHAR_WORD) )
     590             :             {
     591        5403 :                 nMask |= getStartCharsFlags( c );
     592        5403 :                 if ( nMask & TOKEN_CHAR_WORD )
     593           0 :                     nMask &= ~TOKEN_EXCLUDED;
     594             :             }
     595       11453 :         break;
     596             :         case ssGetValue :
     597             :         case ssGetWord :
     598       15548 :             if ( !(nMask & TOKEN_WORD) )
     599             :             {
     600        5687 :                 nMask |= getContCharsFlags( c );
     601        5687 :                 if ( nMask & TOKEN_WORD )
     602           0 :                     nMask &= ~TOKEN_EXCLUDED;
     603             :             }
     604       15548 :         break;
     605             :         default:
     606             :             ;   // other cases aren't needed, no compiler warning
     607             :     }
     608       27113 :     return nMask;
     609             : }
     610             : 
     611             : 
     612         372 : UPT_FLAG_TYPE cclass_Unicode::getFlagsExtended( const sal_Unicode* aStr, sal_Int32 nPos )
     613             : {
     614         372 :     sal_Unicode c = aStr[nPos];
     615         372 :     if ( c == cGroupSep )
     616           0 :         return TOKEN_VALUE;
     617         372 :     else if ( c == cDecimalSep )
     618           0 :         return TOKEN_CHAR_VALUE | TOKEN_VALUE;
     619             :     using namespace i18n;
     620             :     bool bStart = (eState == ssGetChar || eState == ssGetWordFirstChar ||
     621         372 :             eState == ssRewindFromValue || eState == ssIgnoreLeadingInRewind);
     622         372 :     sal_Int32 nTypes = (bStart ? nStartTypes : nContTypes);
     623             : 
     624             :     //! all KParseTokens::UNI_... must be matched
     625         372 :     switch ( u_charType( (sal_uInt32) c ) )
     626             :     {
     627             :         case U_UPPERCASE_LETTER :
     628             :             return (nTypes & KParseTokens::UNI_UPALPHA) ?
     629             :                 (bStart ? TOKEN_CHAR_WORD : TOKEN_WORD) :
     630           0 :                 TOKEN_ILLEGAL;
     631             :         case U_LOWERCASE_LETTER :
     632             :             return (nTypes & KParseTokens::UNI_LOALPHA) ?
     633             :                 (bStart ? TOKEN_CHAR_WORD : TOKEN_WORD) :
     634         186 :                 TOKEN_ILLEGAL;
     635             :         case U_TITLECASE_LETTER :
     636             :             return (nTypes & KParseTokens::UNI_TITLE_ALPHA) ?
     637             :                 (bStart ? TOKEN_CHAR_WORD : TOKEN_WORD) :
     638           0 :                 TOKEN_ILLEGAL;
     639             :         case U_MODIFIER_LETTER :
     640             :             return (nTypes & KParseTokens::UNI_MODIFIER_LETTER) ?
     641             :                 (bStart ? TOKEN_CHAR_WORD : TOKEN_WORD) :
     642           0 :                 TOKEN_ILLEGAL;
     643             :         case U_NON_SPACING_MARK :
     644             :         case U_COMBINING_SPACING_MARK :
     645             :             // Non_Spacing_Mark can't be a leading character,
     646             :             // nor can a spacing combining mark.
     647           0 :             if (bStart)
     648           0 :                 return TOKEN_ILLEGAL;
     649             :             // fall through, treat it as Other_Letter.
     650             :         case U_OTHER_LETTER :
     651             :             return (nTypes & KParseTokens::UNI_OTHER_LETTER) ?
     652             :                 (bStart ? TOKEN_CHAR_WORD : TOKEN_WORD) :
     653           0 :                 TOKEN_ILLEGAL;
     654             :         case U_DECIMAL_DIGIT_NUMBER :
     655             :             return ((nTypes & KParseTokens::UNI_DIGIT) ?
     656             :                 (bStart ? TOKEN_CHAR_WORD : TOKEN_WORD) :
     657           0 :                 TOKEN_ILLEGAL) | TOKEN_DIGIT_FLAGS;
     658             :         case U_LETTER_NUMBER :
     659             :             return ((nTypes & KParseTokens::UNI_LETTER_NUMBER) ?
     660             :                 (bStart ? TOKEN_CHAR_WORD : TOKEN_WORD) :
     661           0 :                 TOKEN_ILLEGAL) | TOKEN_DIGIT_FLAGS;
     662             :         case U_OTHER_NUMBER :
     663             :             return ((nTypes & KParseTokens::UNI_OTHER_NUMBER) ?
     664             :                 (bStart ? TOKEN_CHAR_WORD : TOKEN_WORD) :
     665           0 :                 TOKEN_ILLEGAL) | TOKEN_DIGIT_FLAGS;
     666             :         case U_SPACE_SEPARATOR :
     667             :             return ((nTypes & KParseTokens::IGNORE_LEADING_WS) ?
     668           0 :                 TOKEN_CHAR_DONTCARE : (bStart ? TOKEN_CHAR_WORD : (TOKEN_CHAR_DONTCARE | TOKEN_WORD_SEP | TOKEN_VALUE_SEP) ));
     669             :     }
     670             : 
     671         186 :     return TOKEN_ILLEGAL;
     672             : }
     673             : 
     674             : 
     675        5403 : UPT_FLAG_TYPE cclass_Unicode::getStartCharsFlags( sal_Unicode c )
     676             : {
     677        5403 :     if ( pStart )
     678             :     {
     679           0 :         const sal_Unicode* pStr = aStartChars.getStr();
     680           0 :         const sal_Unicode* p = StrChr( pStr, c );
     681           0 :         if ( p )
     682           0 :             return pStart[ p - pStr ];
     683             :     }
     684        5403 :     return TOKEN_ILLEGAL;
     685             : }
     686             : 
     687             : 
     688        5687 : UPT_FLAG_TYPE cclass_Unicode::getContCharsFlags( sal_Unicode c )
     689             : {
     690        5687 :     if ( pCont )
     691             :     {
     692          53 :         const sal_Unicode* pStr = aContChars.getStr();
     693          53 :         const sal_Unicode* p = StrChr( pStr, c );
     694          53 :         if ( p )
     695           0 :             return pCont[ p - pStr ];
     696             :     }
     697        5687 :     return TOKEN_ILLEGAL;
     698             : }
     699             : 
     700             : 
     701       11449 : void cclass_Unicode::parseText( ParseResult& r, const OUString& rText, sal_Int32 nPos, sal_Int32 nTokenType )
     702             : {
     703             :     using namespace i18n;
     704       11449 :     const sal_Unicode* const pTextStart = rText.getStr() + nPos;
     705       11449 :     eState = ssGetChar;
     706             : 
     707             :     //! All the variables below (plus ParseResult) have to be resetted on ssRewindFromValue!
     708       11449 :     const sal_Unicode* pSym = pTextStart;
     709       11449 :     const sal_Unicode* pSrc = pSym;
     710       11449 :     OUString aSymbol;
     711       11449 :     sal_Unicode c = *pSrc;
     712       11449 :     sal_Unicode cLast = 0;
     713       11449 :     int nDecSeps = 0;
     714       11449 :     bool bQuote = false;
     715       11449 :     bool bMightBeWord = true;
     716       11449 :     bool bMightBeWordLast = true;
     717             :     //! All the variables above (plus ParseResult) have to be resetted on ssRewindFromValue!
     718             : 
     719       50011 :     while ( (c != 0) && (eState != ssStop) )
     720             :     {
     721       27113 :         UPT_FLAG_TYPE nMask = getFlags( pTextStart, pSrc - pTextStart );
     722       27113 :         if ( nMask & TOKEN_EXCLUDED )
     723           0 :             eState = ssBounce;
     724       27113 :         if ( bMightBeWord )
     725             :         {   // only relevant for ssGetValue fall back
     726       26985 :             if ( eState == ssGetChar || eState == ssRewindFromValue ||
     727             :                     eState == ssIgnoreLeadingInRewind )
     728       11453 :                 bMightBeWord = ((nMask & TOKEN_CHAR_WORD) != 0);
     729             :             else
     730       15532 :                 bMightBeWord = ((nMask & TOKEN_WORD) != 0);
     731             :         }
     732       27113 :         sal_Int32 nParseTokensType = getParseTokensType( pTextStart, pSrc - pTextStart );
     733       27113 :         pSrc++;
     734       27113 :         switch (eState)
     735             :         {
     736             :             case ssGetChar :
     737             :             case ssRewindFromValue :
     738             :             case ssIgnoreLeadingInRewind :
     739             :             {
     740       11453 :                 if ( (nMask & TOKEN_CHAR_VALUE) && eState != ssRewindFromValue
     741             :                         && eState != ssIgnoreLeadingInRewind )
     742             :                 {   //! must be first, may fall back to ssGetWord via bMightBeWord
     743        1652 :                     eState = ssGetValue;
     744        3304 :                     if ( nMask & TOKEN_VALUE_DIGIT )
     745             :                     {
     746        1652 :                         if ( 128 <= c )
     747           0 :                             r.TokenType = KParseType::UNI_NUMBER;
     748             :                         else
     749        1652 :                             r.TokenType = KParseType::ASC_NUMBER;
     750             :                     }
     751           0 :                     else if ( c == cDecimalSep )
     752             :                     {
     753           0 :                         if ( *pSrc )
     754           0 :                             ++nDecSeps;
     755             :                         else
     756           0 :                             eState = ssRewindFromValue;
     757             :                             // retry for ONE_SINGLE_CHAR or others
     758             :                     }
     759             :                 }
     760        9801 :                 else if ( nMask & TOKEN_CHAR_WORD )
     761             :                 {
     762        4398 :                     eState = ssGetWord;
     763        4398 :                     r.TokenType = KParseType::IDENTNAME;
     764             :                 }
     765        5403 :                 else if ( nMask & TOKEN_NAME_SEP )
     766             :                 {
     767           0 :                     eState = ssGetWordFirstChar;
     768           0 :                     bQuote = true;
     769           0 :                     pSym++;
     770           0 :                     nParseTokensType = 0;   // will be taken of first real character
     771           0 :                     r.TokenType = KParseType::SINGLE_QUOTE_NAME;
     772             :                 }
     773        5403 :                 else if ( nMask & TOKEN_CHAR_STRING )
     774             :                 {
     775           8 :                     eState = ssGetString;
     776           8 :                     pSym++;
     777           8 :                     nParseTokensType = 0;   // will be taken of first real character
     778           8 :                     r.TokenType = KParseType::DOUBLE_QUOTE_STRING;
     779             :                 }
     780        5395 :                 else if ( nMask & TOKEN_CHAR_DONTCARE )
     781             :                 {
     782           4 :                     if ( nStartTypes & KParseTokens::IGNORE_LEADING_WS )
     783             :                     {
     784           4 :                         if (eState == ssRewindFromValue)
     785           0 :                             eState = ssIgnoreLeadingInRewind;
     786           4 :                         r.LeadingWhiteSpace++;
     787           4 :                         pSym++;
     788           4 :                         nParseTokensType = 0;   // wait until real character
     789           4 :                         bMightBeWord = true;
     790             :                     }
     791             :                     else
     792           0 :                         eState = ssBounce;
     793             :                 }
     794        5391 :                 else if ( nMask & TOKEN_CHAR_BOOL )
     795             :                 {
     796          96 :                     eState = ssGetBool;
     797          96 :                     r.TokenType = KParseType::BOOLEAN;
     798             :                 }
     799        5295 :                 else if ( nMask & TOKEN_CHAR )
     800             :                 {   //! must be last
     801        5119 :                     eState = ssStop;
     802        5119 :                     r.TokenType = KParseType::ONE_SINGLE_CHAR;
     803             :                 }
     804             :                 else
     805         176 :                     eState = ssBounce;      // not known
     806             :             }
     807       11453 :             break;
     808             :             case ssGetValue :
     809             :             {
     810        1654 :                 if ( nMask & TOKEN_VALUE_DIGIT )
     811             :                 {
     812           4 :                     if ( 128 <= c )
     813           0 :                         r.TokenType = KParseType::UNI_NUMBER;
     814           4 :                     else if ( r.TokenType != KParseType::UNI_NUMBER )
     815           4 :                         r.TokenType = KParseType::ASC_NUMBER;
     816             :                 }
     817        1654 :                 if ( nMask & TOKEN_VALUE )
     818             :                 {
     819          20 :                     if ( c == cDecimalSep && ++nDecSeps > 1 )
     820             :                     {
     821           0 :                         if ( pSrc - pTextStart == 2 )
     822           0 :                             eState = ssRewindFromValue;
     823             :                             // consecutive separators
     824             :                         else
     825           0 :                             eState = ssStopBack;
     826             :                     }
     827             :                     // else keep it going
     828             :                 }
     829        1634 :                 else if ( c == 'E' || c == 'e' )
     830             :                 {
     831           0 :                     UPT_FLAG_TYPE nNext = getFlags( pTextStart, pSrc - pTextStart );
     832           0 :                     if ( nNext & TOKEN_VALUE_EXP )
     833             :                         ;   // keep it going
     834           0 :                     else if ( bMightBeWord && ((nNext & TOKEN_WORD) || !*pSrc) )
     835             :                     {   // might be a numerical name (1.2efg)
     836           0 :                         eState = ssGetWord;
     837           0 :                         r.TokenType = KParseType::IDENTNAME;
     838             :                     }
     839             :                     else
     840           0 :                         eState = ssStopBack;
     841             :                 }
     842        1634 :                 else if ( nMask & TOKEN_VALUE_SIGN )
     843             :                 {
     844          36 :                     if ( (cLast == 'E') || (cLast == 'e') )
     845             :                     {
     846           0 :                         UPT_FLAG_TYPE nNext = getFlags( pTextStart, pSrc - pTextStart );
     847           0 :                         if ( nNext & TOKEN_VALUE_EXP_VALUE )
     848             :                             ;   // keep it going
     849           0 :                         else if ( bMightBeWord && ((nNext & TOKEN_WORD) || !*pSrc) )
     850             :                         {   // might be a numerical name (1.2e+fg)
     851           0 :                             eState = ssGetWord;
     852           0 :                             r.TokenType = KParseType::IDENTNAME;
     853             :                         }
     854             :                         else
     855           0 :                             eState = ssStopBack;
     856             :                     }
     857          36 :                     else if ( bMightBeWord )
     858             :                     {   // might be a numerical name (1.2+fg)
     859           0 :                         eState = ssGetWord;
     860           0 :                         r.TokenType = KParseType::IDENTNAME;
     861             :                     }
     862             :                     else
     863          36 :                         eState = ssStopBack;
     864             :                 }
     865        1598 :                 else if ( bMightBeWord && (nMask & TOKEN_WORD) )
     866             :                 {   // might be a numerical name (1995.A1)
     867           0 :                     eState = ssGetWord;
     868           0 :                     r.TokenType = KParseType::IDENTNAME;
     869             :                 }
     870             :                 else
     871        1598 :                     eState = ssStopBack;
     872             :             }
     873        1654 :             break;
     874             :             case ssGetWordFirstChar :
     875           0 :                 eState = ssGetWord;
     876             :                 // fall thru
     877             :             case ssGetWord :
     878             :             {
     879       13894 :                 if ( nMask & TOKEN_WORD )
     880             :                     ;   // keep it going
     881        4037 :                 else if ( nMask & TOKEN_NAME_SEP )
     882             :                 {
     883           0 :                     if ( bQuote )
     884             :                     {
     885           0 :                         if ( cLast == '\\' )
     886             :                         {   // escaped
     887           0 :                             aSymbol += OUString( pSym, pSrc - pSym - 2 );
     888           0 :                             aSymbol += OUString( &c, 1);
     889             :                         }
     890             :                         else
     891             :                         {
     892           0 :                             eState = ssStop;
     893           0 :                             aSymbol += OUString( pSym, pSrc - pSym - 1 );
     894             :                         }
     895           0 :                         pSym = pSrc;
     896             :                     }
     897             :                     else
     898           0 :                         eState = ssStopBack;
     899             :                 }
     900        4037 :                 else if ( bQuote )
     901             :                     ;   // keep it going
     902             :                 else
     903        4037 :                     eState = ssStopBack;
     904             :             }
     905       13894 :             break;
     906             :             case ssGetString :
     907             :             {
     908          16 :                 if ( nMask & TOKEN_STRING_SEP )
     909             :                 {
     910           8 :                     if ( cLast == '\\' )
     911             :                     {   // escaped
     912           0 :                         aSymbol += OUString( pSym, pSrc - pSym - 2 );
     913           0 :                         aSymbol += OUString( &c, 1);
     914             :                     }
     915           8 :                     else if ( c == *pSrc &&
     916           0 :                             !(nContTypes & KParseTokens::TWO_DOUBLE_QUOTES_BREAK_STRING) )
     917             :                     {   // "" => literal " escaped
     918           0 :                         aSymbol += OUString( pSym, pSrc - pSym );
     919           0 :                         pSrc++;
     920             :                     }
     921             :                     else
     922             :                     {
     923           8 :                         eState = ssStop;
     924           8 :                         aSymbol += OUString( pSym, pSrc - pSym - 1 );
     925             :                     }
     926           8 :                     pSym = pSrc;
     927             :                 }
     928             :             }
     929          16 :             break;
     930             :             case ssGetBool :
     931             :             {
     932          96 :                 if ( (nMask & TOKEN_BOOL) )
     933           8 :                     eState = ssStop;    // maximum 2: <, >, <>, <=, >=
     934             :                 else
     935          88 :                     eState = ssStopBack;
     936             :             }
     937          96 :             break;
     938             :             case ssStopBack :
     939             :             case ssBounce :
     940             :             case ssStop :
     941             :                 ;   // nothing, no compiler warning
     942           0 :             break;
     943             :         }
     944       27113 :         if ( eState == ssRewindFromValue )
     945             :         {
     946           0 :             r = ParseResult();
     947           0 :             pSym = pTextStart;
     948           0 :             pSrc = pSym;
     949           0 :             aSymbol = OUString();
     950           0 :             c = *pSrc;
     951           0 :             cLast = 0;
     952           0 :             nDecSeps = 0;
     953           0 :             bQuote = false;
     954           0 :             bMightBeWord = true;
     955           0 :             bMightBeWordLast = true;
     956             :         }
     957             :         else
     958             :         {
     959       27113 :             if ( !(r.TokenType & nTokenType) )
     960             :             {
     961         180 :                 if ( (r.TokenType & (KParseType::ASC_NUMBER | KParseType::UNI_NUMBER))
     962             :                         && (nTokenType & KParseType::IDENTNAME) && bMightBeWord )
     963             :                     ;   // keep a number that might be a word
     964         180 :                 else if ( r.LeadingWhiteSpace == (pSrc - pTextStart) )
     965             :                     ;   // keep ignored white space
     966         176 :                 else if ( !r.TokenType && eState == ssGetValue && (nMask & TOKEN_VALUE_SEP) )
     967             :                     ;   // keep uncertain value
     968             :                 else
     969         176 :                     eState = ssBounce;
     970             :             }
     971       27113 :             if ( eState == ssBounce )
     972             :             {
     973         176 :                 r.TokenType = 0;
     974         176 :                 eState = ssStopBack;
     975             :             }
     976       27113 :             if ( eState == ssStopBack )
     977             :             {   // put back
     978        5935 :                 pSrc--;
     979        5935 :                 bMightBeWord = bMightBeWordLast;
     980        5935 :                 eState = ssStop;
     981             :             }
     982       27113 :             if ( eState != ssStop )
     983             :             {
     984       16043 :                 if ( !r.StartFlags )
     985        6166 :                     r.StartFlags |= nParseTokensType;
     986             :                 else
     987        9877 :                     r.ContFlags |= nParseTokensType;
     988             :             }
     989       27113 :             bMightBeWordLast = bMightBeWord;
     990       27113 :             cLast = c;
     991       27113 :             c = *pSrc;
     992             :         }
     993             :     }
     994             :     // r.CharLen is the length in characters (not code points) of the parsed
     995             :     // token not including any leading white space, change this calculation if
     996             :     // multi-code-point Unicode characters are to be supported.
     997       11449 :     r.CharLen = pSrc - pTextStart - r.LeadingWhiteSpace;
     998       11449 :     r.EndPos = nPos + (pSrc - pTextStart);
     999       11449 :     if ( r.TokenType & KParseType::ASC_NUMBER )
    1000             :     {
    1001             :         r.Value = rtl_math_uStringToDouble( pTextStart + r.LeadingWhiteSpace,
    1002        1652 :                 pTextStart + r.EndPos, cDecimalSep, cGroupSep, NULL, NULL );
    1003        1652 :         if ( bMightBeWord )
    1004        1636 :             r.TokenType |= KParseType::IDENTNAME;
    1005             :     }
    1006        9797 :     else if ( r.TokenType & KParseType::UNI_NUMBER )
    1007             :     {
    1008           0 :         if ( !xNatNumSup.is() )
    1009             :         {
    1010           0 :             if ( m_xContext.is() )
    1011             :             {
    1012           0 :                 xNatNumSup = NativeNumberSupplier::create( m_xContext );
    1013             :             }
    1014             :         }
    1015             :         OUString aTmp( pTextStart + r.LeadingWhiteSpace, r.EndPos - nPos +
    1016           0 :                 r.LeadingWhiteSpace );
    1017             :         // transliterate to ASCII
    1018           0 :         aTmp = xNatNumSup->getNativeNumberString( aTmp, aParserLocale,
    1019           0 :                 NativeNumberMode::NATNUM0 );
    1020           0 :         r.Value = ::rtl::math::stringToDouble( aTmp, cDecimalSep, cGroupSep, NULL, NULL );
    1021           0 :         if ( bMightBeWord )
    1022           0 :             r.TokenType |= KParseType::IDENTNAME;
    1023             :     }
    1024        9797 :     else if ( r.TokenType & (KParseType::SINGLE_QUOTE_NAME | KParseType::DOUBLE_QUOTE_STRING) )
    1025             :     {
    1026           8 :         if ( pSym < pSrc )
    1027             :         {   //! open quote
    1028           0 :             aSymbol += OUString( pSym, pSrc - pSym );
    1029           0 :             r.TokenType |= KParseType::MISSING_QUOTE;
    1030             :         }
    1031           8 :         r.DequotedNameOrString = aSymbol;
    1032       11449 :     }
    1033       11449 : }
    1034             : 
    1035             : } } } }
    1036             : 
    1037             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10