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-17 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         106 : const sal_Unicode* cclass_Unicode::StrChr( const sal_Unicode* pStr, sal_Unicode c )
     342             : {
     343         106 :     if ( !pStr )
     344           0 :         return NULL;
     345         424 :     while ( *pStr )
     346             :     {
     347         212 :         if ( *pStr == c )
     348           0 :             return pStr;
     349         212 :         pStr++;
     350             :     }
     351         106 :     return NULL;
     352             : }
     353             : 
     354             : 
     355       55680 : sal_Int32 cclass_Unicode::getParseTokensType( const sal_Unicode* aStr, sal_Int32 nPos )
     356             : {
     357       55680 :     sal_Unicode c = aStr[nPos];
     358       55680 :     if ( c < nDefCnt )
     359       54936 :         return pParseTokensType[ sal_uInt8(c) ];
     360             :     else
     361             :     {
     362             : 
     363             :         //! all KParseTokens::UNI_... must be matched
     364         744 :         switch ( u_charType( (sal_uInt32) c ) )
     365             :         {
     366             :             case U_UPPERCASE_LETTER :
     367           0 :                 return KParseTokens::UNI_UPALPHA;
     368             :             case U_LOWERCASE_LETTER :
     369         372 :                 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         372 :         return KParseTokens::UNI_OTHER;
     389             :     }
     390             : }
     391             : 
     392       22658 : sal_Bool cclass_Unicode::setupInternational( const Locale& rLocale )
     393             : {
     394       22658 :     sal_Bool bChanged = (aParserLocale.Language != rLocale.Language
     395        2204 :         || aParserLocale.Country != rLocale.Country
     396       24862 :         || aParserLocale.Variant != rLocale.Variant);
     397       22658 :     if ( bChanged )
     398             :     {
     399       20454 :         aParserLocale.Language = rLocale.Language;
     400       20454 :         aParserLocale.Country = rLocale.Country;
     401       20454 :         aParserLocale.Variant = rLocale.Variant;
     402             :     }
     403       22658 :     if ( !mxLocaleData.is() )
     404             :     {
     405       20454 :         mxLocaleData.set( LocaleData::create(m_xContext) );
     406             :     }
     407       22658 :     return bChanged;
     408             : }
     409             : 
     410             : 
     411       23070 : void cclass_Unicode::setupParserTable( const Locale& rLocale, sal_Int32 startCharTokenType,
     412             :             const OUString& userDefinedCharactersStart, sal_Int32 contCharTokenType,
     413             :             const OUString& userDefinedCharactersCont )
     414             : {
     415       23070 :     bool bIntlEqual = (rLocale.Language == aParserLocale.Language &&
     416        2616 :         rLocale.Country == aParserLocale.Country &&
     417       25686 :         rLocale.Variant == aParserLocale.Variant);
     418       23894 :     if ( !pTable || !bIntlEqual ||
     419             :             startCharTokenType != nStartTypes ||
     420             :             contCharTokenType != nContTypes ||
     421         412 :             userDefinedCharactersStart != aStartChars ||
     422         412 :             userDefinedCharactersCont != aContChars )
     423             :         initParserTable( rLocale, startCharTokenType, userDefinedCharactersStart,
     424       22658 :             contCharTokenType, userDefinedCharactersCont );
     425       23070 : }
     426             : 
     427             : 
     428       22658 : 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       22658 :     setupInternational( rLocale );
     434             :     // Memory of pTable is reused.
     435       22658 :     if ( !pTable )
     436       20454 :         pTable = new UPT_FLAG_TYPE[nDefCnt];
     437       22658 :     memcpy( pTable, pDefaultParserTable, sizeof(UPT_FLAG_TYPE) * nDefCnt );
     438             :     // Start and cont tables only need reallocation if different length.
     439       22658 :     if ( pStart && userDefinedCharactersStart.getLength() != aStartChars.getLength() )
     440             :     {
     441         154 :         delete [] pStart;
     442         154 :         pStart = NULL;
     443             :     }
     444       22658 :     if ( pCont && userDefinedCharactersCont.getLength() != aContChars.getLength() )
     445             :     {
     446         154 :         delete [] pCont;
     447         154 :         pCont = NULL;
     448             :     }
     449       22658 :     nStartTypes = startCharTokenType;
     450       22658 :     nContTypes = contCharTokenType;
     451       22658 :     aStartChars = userDefinedCharactersStart;
     452       22658 :     aContChars = userDefinedCharactersCont;
     453             : 
     454             :     // specials
     455       22658 :     if( mxLocaleData.is() )
     456             :     {
     457             :         LocaleDataItem aItem =
     458       22658 :             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       22658 :         cGroupSep = aItem.thousandSeparator.getStr()[0];
     462       22658 :         cDecimalSep = aItem.decimalSeparator.getStr()[0];
     463             :     }
     464             : 
     465       22658 :     if ( cGroupSep < nDefCnt )
     466       22658 :         pTable[cGroupSep] |= TOKEN_VALUE;
     467       22658 :     if ( cDecimalSep < nDefCnt )
     468       22658 :         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       22658 :         if ( !(nStartTypes & ASC_UPALPHA) )
     476       44172 :             for ( i = 65; i < 91; i++ )
     477       42536 :                 pTable[i] &= ~TOKEN_CHAR_WORD;  // not allowed as start character
     478       22658 :         if ( !(nContTypes & ASC_UPALPHA) )
     479       44172 :             for ( i = 65; i < 91; i++ )
     480       42536 :                 pTable[i] &= ~TOKEN_WORD;       // not allowed as cont character
     481             : 
     482       22658 :         if ( !(nStartTypes & ASC_LOALPHA) )
     483       44172 :             for ( i = 97; i < 123; i++ )
     484       42536 :                 pTable[i] &= ~TOKEN_CHAR_WORD;  // not allowed as start character
     485       22658 :         if ( !(nContTypes & ASC_LOALPHA) )
     486       44172 :             for ( i = 97; i < 123; i++ )
     487       42536 :                 pTable[i] &= ~TOKEN_WORD;       // not allowed as cont character
     488             : 
     489       22658 :         if ( nStartTypes & ASC_DIGIT )
     490      246378 :             for ( i = 48; i < 58; i++ )
     491      223980 :                 pTable[i] |= TOKEN_CHAR_WORD;   // allowed as start character
     492       22658 :         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       22658 :         if ( !(nStartTypes & ASC_UNDERSCORE) )
     497       22330 :             pTable[95] &= ~TOKEN_CHAR_WORD;     // not allowed as start character
     498       22658 :         if ( !(nContTypes & ASC_UNDERSCORE) )
     499       22330 :             pTable[95] &= ~TOKEN_WORD;          // not allowed as cont character
     500             : 
     501       22658 :         if ( nStartTypes & ASC_DOLLAR )
     502         154 :             pTable[36] |= TOKEN_CHAR_WORD;      // allowed as start character
     503       22658 :         if ( nContTypes & ASC_DOLLAR )
     504         154 :             pTable[36] |= TOKEN_WORD;           // allowed as cont character
     505             : 
     506       22658 :         if ( nStartTypes & ASC_DOT )
     507           0 :             pTable[46] |= TOKEN_CHAR_WORD;      // allowed as start character
     508       22658 :         if ( nContTypes & ASC_DOT )
     509       22488 :             pTable[46] |= TOKEN_WORD;           // allowed as cont character
     510             : 
     511       22658 :         if ( nStartTypes & ASC_COLON )
     512           0 :             pTable[58] |= TOKEN_CHAR_WORD;      // allowed as start character
     513       22658 :         if ( nContTypes & ASC_COLON )
     514           0 :             pTable[58] |= TOKEN_WORD;           // allowed as cont character
     515             : 
     516       22658 :         if ( nStartTypes & ASC_CONTROL )
     517           0 :             for ( i = 1; i < 32; i++ )
     518           0 :                 pTable[i] |= TOKEN_CHAR_WORD;   // allowed as start character
     519       22658 :         if ( nContTypes & ASC_CONTROL )
     520           0 :             for ( i = 1; i < 32; i++ )
     521           0 :                 pTable[i] |= TOKEN_WORD;        // allowed as cont character
     522             : 
     523       22658 :         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       22658 :         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       22658 :     sal_Int32 nLen = aStartChars.getLength();
     535       22658 :     if ( nLen )
     536             :     {
     537         154 :         if ( !pStart )
     538         154 :             pStart = new UPT_FLAG_TYPE[ nLen ];
     539         154 :         const sal_Unicode* p = aStartChars.getStr();
     540         462 :         for ( sal_Int32 j=0; j<nLen; j++, p++ )
     541             :         {
     542         308 :             pStart[j] = TOKEN_CHAR_WORD;
     543         308 :             if ( *p < nDefCnt )
     544         308 :                 pTable[*p] |= TOKEN_CHAR_WORD;
     545             :         }
     546             :     }
     547             :     // ContChars
     548       22658 :     nLen = aContChars.getLength();
     549       22658 :     if ( nLen )
     550             :     {
     551         154 :         if ( !pCont )
     552         154 :             pCont = new UPT_FLAG_TYPE[ nLen ];
     553         154 :         const sal_Unicode* p = aContChars.getStr();
     554         462 :         for ( sal_Int32 j=0; j<nLen; j++ )
     555             :         {
     556         308 :             pCont[j] = TOKEN_WORD;
     557         308 :             if ( *p < nDefCnt )
     558         308 :                 pTable[*p] |= TOKEN_WORD;
     559             :         }
     560             :     }
     561       22658 : }
     562             : 
     563             : 
     564       22915 : void cclass_Unicode::destroyParserTable()
     565             : {
     566       22915 :     if ( pCont )
     567           0 :         delete [] pCont;
     568       22915 :     if ( pStart )
     569           0 :         delete [] pStart;
     570       22915 :     if ( pTable )
     571       20438 :         delete [] pTable;
     572       22915 : }
     573             : 
     574             : 
     575       55680 : UPT_FLAG_TYPE cclass_Unicode::getFlags( const sal_Unicode* aStr, sal_Int32 nPos )
     576             : {
     577             :     UPT_FLAG_TYPE nMask;
     578       55680 :     sal_Unicode c = aStr[nPos];
     579       55680 :     if ( c < nDefCnt )
     580       54936 :         nMask = pTable[ sal_uInt8(c) ];
     581             :     else
     582         744 :         nMask = getFlagsExtended( aStr, nPos );
     583       55680 :     switch ( eState )
     584             :     {
     585             :         case ssGetChar :
     586             :         case ssRewindFromValue :
     587             :         case ssIgnoreLeadingInRewind :
     588             :         case ssGetWordFirstChar :
     589       23078 :             if ( !(nMask & TOKEN_CHAR_WORD) )
     590             :             {
     591       10770 :                 nMask |= getStartCharsFlags( c );
     592       10770 :                 if ( nMask & TOKEN_CHAR_WORD )
     593           0 :                     nMask &= ~TOKEN_EXCLUDED;
     594             :             }
     595       23078 :         break;
     596             :         case ssGetValue :
     597             :         case ssGetWord :
     598       32378 :             if ( !(nMask & TOKEN_WORD) )
     599             :             {
     600       11490 :                 nMask |= getContCharsFlags( c );
     601       11490 :                 if ( nMask & TOKEN_WORD )
     602           0 :                     nMask &= ~TOKEN_EXCLUDED;
     603             :             }
     604       32378 :         break;
     605             :         default:
     606             :             ;   // other cases aren't needed, no compiler warning
     607             :     }
     608       55680 :     return nMask;
     609             : }
     610             : 
     611             : 
     612         744 : UPT_FLAG_TYPE cclass_Unicode::getFlagsExtended( const sal_Unicode* aStr, sal_Int32 nPos )
     613             : {
     614         744 :     sal_Unicode c = aStr[nPos];
     615         744 :     if ( c == cGroupSep )
     616           0 :         return TOKEN_VALUE;
     617         744 :     else if ( c == cDecimalSep )
     618           0 :         return TOKEN_CHAR_VALUE | TOKEN_VALUE;
     619             :     using namespace i18n;
     620             :     bool bStart = (eState == ssGetChar || eState == ssGetWordFirstChar ||
     621         744 :             eState == ssRewindFromValue || eState == ssIgnoreLeadingInRewind);
     622         744 :     sal_Int32 nTypes = (bStart ? nStartTypes : nContTypes);
     623             : 
     624             :     //! all KParseTokens::UNI_... must be matched
     625         744 :     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         372 :                 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         372 :     return TOKEN_ILLEGAL;
     672             : }
     673             : 
     674             : 
     675       10770 : UPT_FLAG_TYPE cclass_Unicode::getStartCharsFlags( sal_Unicode c )
     676             : {
     677       10770 :     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       10770 :     return TOKEN_ILLEGAL;
     685             : }
     686             : 
     687             : 
     688       11490 : UPT_FLAG_TYPE cclass_Unicode::getContCharsFlags( sal_Unicode c )
     689             : {
     690       11490 :     if ( pCont )
     691             :     {
     692         106 :         const sal_Unicode* pStr = aContChars.getStr();
     693         106 :         const sal_Unicode* p = StrChr( pStr, c );
     694         106 :         if ( p )
     695           0 :             return pCont[ p - pStr ];
     696             :     }
     697       11490 :     return TOKEN_ILLEGAL;
     698             : }
     699             : 
     700             : 
     701       23070 : void cclass_Unicode::parseText( ParseResult& r, const OUString& rText, sal_Int32 nPos, sal_Int32 nTokenType )
     702             : {
     703             :     using namespace i18n;
     704       23070 :     const sal_Unicode* const pTextStart = rText.getStr() + nPos;
     705       23070 :     eState = ssGetChar;
     706             : 
     707             :     //! All the variables below (plus ParseResult) have to be resetted on ssRewindFromValue!
     708       23070 :     const sal_Unicode* pSym = pTextStart;
     709       23070 :     const sal_Unicode* pSrc = pSym;
     710       23070 :     OUString aSymbol;
     711       23070 :     sal_Unicode c = *pSrc;
     712       23070 :     sal_Unicode cLast = 0;
     713       23070 :     int nDecSeps = 0;
     714       23070 :     bool bQuote = false;
     715       23070 :     bool bMightBeWord = true;
     716       23070 :     bool bMightBeWordLast = true;
     717             :     //! All the variables above (plus ParseResult) have to be resetted on ssRewindFromValue!
     718             : 
     719      101820 :     while ( (c != 0) && (eState != ssStop) )
     720             :     {
     721       55680 :         UPT_FLAG_TYPE nMask = getFlags( pTextStart, pSrc - pTextStart );
     722       55680 :         if ( nMask & TOKEN_EXCLUDED )
     723           0 :             eState = ssBounce;
     724       55680 :         if ( bMightBeWord )
     725             :         {   // only relevant for ssGetValue fall back
     726       55424 :             if ( eState == ssGetChar || eState == ssRewindFromValue ||
     727             :                     eState == ssIgnoreLeadingInRewind )
     728       23078 :                 bMightBeWord = ((nMask & TOKEN_CHAR_WORD) != 0);
     729             :             else
     730       32346 :                 bMightBeWord = ((nMask & TOKEN_WORD) != 0);
     731             :         }
     732       55680 :         sal_Int32 nParseTokensType = getParseTokensType( pTextStart, pSrc - pTextStart );
     733       55680 :         pSrc++;
     734       55680 :         switch (eState)
     735             :         {
     736             :             case ssGetChar :
     737             :             case ssRewindFromValue :
     738             :             case ssIgnoreLeadingInRewind :
     739             :             {
     740       23078 :                 if ( (nMask & TOKEN_CHAR_VALUE) && eState != ssRewindFromValue
     741             :                         && eState != ssIgnoreLeadingInRewind )
     742             :                 {   //! must be first, may fall back to ssGetWord via bMightBeWord
     743        3304 :                     eState = ssGetValue;
     744        6608 :                     if ( nMask & TOKEN_VALUE_DIGIT )
     745             :                     {
     746        3304 :                         if ( 128 <= c )
     747           0 :                             r.TokenType = KParseType::UNI_NUMBER;
     748             :                         else
     749        3304 :                             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       19774 :                 else if ( nMask & TOKEN_CHAR_WORD )
     761             :                 {
     762        9004 :                     eState = ssGetWord;
     763        9004 :                     r.TokenType = KParseType::IDENTNAME;
     764             :                 }
     765       10770 :                 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       10770 :                 else if ( nMask & TOKEN_CHAR_STRING )
     774             :                 {
     775          16 :                     eState = ssGetString;
     776          16 :                     pSym++;
     777          16 :                     nParseTokensType = 0;   // will be taken of first real character
     778          16 :                     r.TokenType = KParseType::DOUBLE_QUOTE_STRING;
     779             :                 }
     780       10754 :                 else if ( nMask & TOKEN_CHAR_DONTCARE )
     781             :                 {
     782           8 :                     if ( nStartTypes & KParseTokens::IGNORE_LEADING_WS )
     783             :                     {
     784           8 :                         if (eState == ssRewindFromValue)
     785           0 :                             eState = ssIgnoreLeadingInRewind;
     786           8 :                         r.LeadingWhiteSpace++;
     787           8 :                         pSym++;
     788           8 :                         nParseTokensType = 0;   // wait until real character
     789           8 :                         bMightBeWord = true;
     790             :                     }
     791             :                     else
     792           0 :                         eState = ssBounce;
     793             :                 }
     794       10746 :                 else if ( nMask & TOKEN_CHAR_BOOL )
     795             :                 {
     796         192 :                     eState = ssGetBool;
     797         192 :                     r.TokenType = KParseType::BOOLEAN;
     798             :                 }
     799       10554 :                 else if ( nMask & TOKEN_CHAR )
     800             :                 {   //! must be last
     801       10202 :                     eState = ssStop;
     802       10202 :                     r.TokenType = KParseType::ONE_SINGLE_CHAR;
     803             :                 }
     804             :                 else
     805         352 :                     eState = ssBounce;      // not known
     806             :             }
     807       23078 :             break;
     808             :             case ssGetValue :
     809             :             {
     810        3308 :                 if ( nMask & TOKEN_VALUE_DIGIT )
     811             :                 {
     812           8 :                     if ( 128 <= c )
     813           0 :                         r.TokenType = KParseType::UNI_NUMBER;
     814           8 :                     else if ( r.TokenType != KParseType::UNI_NUMBER )
     815           8 :                         r.TokenType = KParseType::ASC_NUMBER;
     816             :                 }
     817        3308 :                 if ( nMask & TOKEN_VALUE )
     818             :                 {
     819          40 :                     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        3268 :                 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        3268 :                 else if ( nMask & TOKEN_VALUE_SIGN )
     843             :                 {
     844          72 :                     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          72 :                     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          72 :                         eState = ssStopBack;
     864             :                 }
     865        3196 :                 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        3196 :                     eState = ssStopBack;
     872             :             }
     873        3308 :             break;
     874             :             case ssGetWordFirstChar :
     875           0 :                 eState = ssGetWord;
     876             :                 // fall thru
     877             :             case ssGetWord :
     878             :             {
     879       29070 :                 if ( nMask & TOKEN_WORD )
     880             :                     ;   // keep it going
     881        8190 :                 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        8190 :                 else if ( bQuote )
     901             :                     ;   // keep it going
     902             :                 else
     903        8190 :                     eState = ssStopBack;
     904             :             }
     905       29070 :             break;
     906             :             case ssGetString :
     907             :             {
     908          32 :                 if ( nMask & TOKEN_STRING_SEP )
     909             :                 {
     910          16 :                     if ( cLast == '\\' )
     911             :                     {   // escaped
     912           0 :                         aSymbol += OUString( pSym, pSrc - pSym - 2 );
     913           0 :                         aSymbol += OUString( &c, 1);
     914             :                     }
     915          16 :                     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          16 :                         eState = ssStop;
     924          16 :                         aSymbol += OUString( pSym, pSrc - pSym - 1 );
     925             :                     }
     926          16 :                     pSym = pSrc;
     927             :                 }
     928             :             }
     929          32 :             break;
     930             :             case ssGetBool :
     931             :             {
     932         192 :                 if ( (nMask & TOKEN_BOOL) )
     933          16 :                     eState = ssStop;    // maximum 2: <, >, <>, <=, >=
     934             :                 else
     935         176 :                     eState = ssStopBack;
     936             :             }
     937         192 :             break;
     938             :             case ssStopBack :
     939             :             case ssBounce :
     940             :             case ssStop :
     941             :                 ;   // nothing, no compiler warning
     942           0 :             break;
     943             :         }
     944       55680 :         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       55680 :             if ( !(r.TokenType & nTokenType) )
     960             :             {
     961         360 :                 if ( (r.TokenType & (KParseType::ASC_NUMBER | KParseType::UNI_NUMBER))
     962             :                         && (nTokenType & KParseType::IDENTNAME) && bMightBeWord )
     963             :                     ;   // keep a number that might be a word
     964         360 :                 else if ( r.LeadingWhiteSpace == (pSrc - pTextStart) )
     965             :                     ;   // keep ignored white space
     966         352 :                 else if ( !r.TokenType && eState == ssGetValue && (nMask & TOKEN_VALUE_SEP) )
     967             :                     ;   // keep uncertain value
     968             :                 else
     969         352 :                     eState = ssBounce;
     970             :             }
     971       55680 :             if ( eState == ssBounce )
     972             :             {
     973         352 :                 r.TokenType = 0;
     974         352 :                 eState = ssStopBack;
     975             :             }
     976       55680 :             if ( eState == ssStopBack )
     977             :             {   // put back
     978       11986 :                 pSrc--;
     979       11986 :                 bMightBeWord = bMightBeWordLast;
     980       11986 :                 eState = ssStop;
     981             :             }
     982       55680 :             if ( eState != ssStop )
     983             :             {
     984       33460 :                 if ( !r.StartFlags )
     985       12540 :                     r.StartFlags |= nParseTokensType;
     986             :                 else
     987       20920 :                     r.ContFlags |= nParseTokensType;
     988             :             }
     989       55680 :             bMightBeWordLast = bMightBeWord;
     990       55680 :             cLast = c;
     991       55680 :             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       23070 :     r.CharLen = pSrc - pTextStart - r.LeadingWhiteSpace;
     998       23070 :     r.EndPos = nPos + (pSrc - pTextStart);
     999       23070 :     if ( r.TokenType & KParseType::ASC_NUMBER )
    1000             :     {
    1001             :         r.Value = rtl_math_uStringToDouble( pTextStart + r.LeadingWhiteSpace,
    1002        3304 :                 pTextStart + r.EndPos, cDecimalSep, cGroupSep, NULL, NULL );
    1003        3304 :         if ( bMightBeWord )
    1004        3272 :             r.TokenType |= KParseType::IDENTNAME;
    1005             :     }
    1006       19766 :     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       19766 :     else if ( r.TokenType & (KParseType::SINGLE_QUOTE_NAME | KParseType::DOUBLE_QUOTE_STRING) )
    1025             :     {
    1026          16 :         if ( pSym < pSrc )
    1027             :         {   //! open quote
    1028           0 :             aSymbol += OUString( pSym, pSrc - pSym );
    1029           0 :             r.TokenType |= KParseType::MISSING_QUOTE;
    1030             :         }
    1031          16 :         r.DequotedNameOrString = aSymbol;
    1032       23070 :     }
    1033       23070 : }
    1034             : 
    1035             : } } } }
    1036             : 
    1037             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10