LCOV - code coverage report
Current view: top level - i18npool/source/characterclassification - cclass_unicode_parser.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 297 393 75.6 %
Date: 2014-04-11 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>
      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         107 : const sal_Unicode* cclass_Unicode::StrChr( const sal_Unicode* pStr, sal_Unicode c )
     342             : {
     343         107 :     if ( !pStr )
     344           0 :         return NULL;
     345         428 :     while ( *pStr )
     346             :     {
     347         214 :         if ( *pStr == c )
     348           0 :             return pStr;
     349         214 :         pStr++;
     350             :     }
     351         107 :     return NULL;
     352             : }
     353             : 
     354             : 
     355      452058 : sal_Int32 cclass_Unicode::getParseTokensType( const sal_Unicode* aStr, sal_Int32 nPos )
     356             : {
     357      452058 :     sal_Unicode c = aStr[nPos];
     358      452058 :     if ( c < nDefCnt )
     359      450612 :         return pParseTokensType[ sal_uInt8(c) ];
     360             :     else
     361             :     {
     362             : 
     363             :         //! all KParseTokens::UNI_... must be matched
     364        1446 :         switch ( u_charType( (sal_uInt32) c ) )
     365             :         {
     366             :             case U_UPPERCASE_LETTER :
     367          54 :                 return KParseTokens::UNI_UPALPHA;
     368             :             case U_LOWERCASE_LETTER :
     369         802 :                 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           6 :                 if (nPos == 0) break;
     377             :                 // fall through, treat it as Other_Letter.
     378             :             case U_NON_SPACING_MARK :
     379           3 :                 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         587 :         return KParseTokens::UNI_OTHER;
     389             :     }
     390             : }
     391             : 
     392       33468 : sal_Bool cclass_Unicode::setupInternational( const Locale& rLocale )
     393             : {
     394       33468 :     sal_Bool bChanged = (aParserLocale.Language != rLocale.Language
     395       16322 :         || aParserLocale.Country != rLocale.Country
     396       49790 :         || aParserLocale.Variant != rLocale.Variant);
     397       33468 :     if ( bChanged )
     398             :     {
     399       17146 :         aParserLocale.Language = rLocale.Language;
     400       17146 :         aParserLocale.Country = rLocale.Country;
     401       17146 :         aParserLocale.Variant = rLocale.Variant;
     402             :     }
     403       33468 :     if ( !mxLocaleData.is() )
     404             :     {
     405       17146 :         mxLocaleData.set( LocaleData::create(m_xContext) );
     406             :     }
     407       33468 :     return bChanged;
     408             : }
     409             : 
     410             : 
     411      102775 : void cclass_Unicode::setupParserTable( const Locale& rLocale, sal_Int32 startCharTokenType,
     412             :             const OUString& userDefinedCharactersStart, sal_Int32 contCharTokenType,
     413             :             const OUString& userDefinedCharactersCont )
     414             : {
     415      188404 :     bool bIntlEqual = (rLocale.Language == aParserLocale.Language &&
     416      188404 :         rLocale.Country == aParserLocale.Country &&
     417      188404 :         rLocale.Variant == aParserLocale.Variant);
     418      376808 :     if ( !pTable || !bIntlEqual ||
     419      154936 :             startCharTokenType != nStartTypes ||
     420      138614 :             contCharTokenType != nContTypes ||
     421      241389 :             userDefinedCharactersStart != aStartChars ||
     422       69307 :             userDefinedCharactersCont != aContChars )
     423             :         initParserTable( rLocale, startCharTokenType, userDefinedCharactersStart,
     424       33468 :             contCharTokenType, userDefinedCharactersCont );
     425      102775 : }
     426             : 
     427             : 
     428       33468 : 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       33468 :     setupInternational( rLocale );
     434             :     // Memory of pTable is reused.
     435       33468 :     if ( !pTable )
     436       17146 :         pTable = new UPT_FLAG_TYPE[nDefCnt];
     437       33468 :     memcpy( pTable, pDefaultParserTable, sizeof(UPT_FLAG_TYPE) * nDefCnt );
     438             :     // Start and cont tables only need reallocation if different length.
     439       33468 :     if ( pStart && userDefinedCharactersStart.getLength() != aStartChars.getLength() )
     440             :     {
     441         166 :         delete [] pStart;
     442         166 :         pStart = NULL;
     443             :     }
     444       33468 :     if ( pCont && userDefinedCharactersCont.getLength() != aContChars.getLength() )
     445             :     {
     446         166 :         delete [] pCont;
     447         166 :         pCont = NULL;
     448             :     }
     449       33468 :     nStartTypes = startCharTokenType;
     450       33468 :     nContTypes = contCharTokenType;
     451       33468 :     aStartChars = userDefinedCharactersStart;
     452       33468 :     aContChars = userDefinedCharactersCont;
     453             : 
     454             :     // specials
     455       33468 :     if( mxLocaleData.is() )
     456             :     {
     457             :         LocaleDataItem aItem =
     458       33468 :             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       33468 :         cGroupSep = aItem.thousandSeparator[0];
     462       33468 :         cDecimalSep = aItem.decimalSeparator[0];
     463             :     }
     464             : 
     465       33468 :     if ( cGroupSep < nDefCnt )
     466       33466 :         pTable[cGroupSep] |= TOKEN_VALUE;
     467       33468 :     if ( cDecimalSep < nDefCnt )
     468       33468 :         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       33468 :         if ( !(nStartTypes & ASC_UPALPHA) )
     476      462132 :             for ( i = 65; i < 91; i++ )
     477      445016 :                 pTable[i] &= ~TOKEN_CHAR_WORD;  // not allowed as start character
     478       33468 :         if ( !(nContTypes & ASC_UPALPHA) )
     479      462132 :             for ( i = 65; i < 91; i++ )
     480      445016 :                 pTable[i] &= ~TOKEN_WORD;       // not allowed as cont character
     481             : 
     482       33468 :         if ( !(nStartTypes & ASC_LOALPHA) )
     483      462132 :             for ( i = 97; i < 123; i++ )
     484      445016 :                 pTable[i] &= ~TOKEN_CHAR_WORD;  // not allowed as start character
     485       33468 :         if ( !(nContTypes & ASC_LOALPHA) )
     486      462132 :             for ( i = 97; i < 123; i++ )
     487      445016 :                 pTable[i] &= ~TOKEN_WORD;       // not allowed as cont character
     488             : 
     489       33468 :         if ( nStartTypes & ASC_DIGIT )
     490      192258 :             for ( i = 48; i < 58; i++ )
     491      174780 :                 pTable[i] |= TOKEN_CHAR_WORD;   // allowed as start character
     492       33468 :         if ( !(nContTypes & ASC_DIGIT) )
     493      175890 :             for ( i = 48; i < 58; i++ )
     494      159900 :                 pTable[i] &= ~TOKEN_WORD;       // not allowed as cont character
     495             : 
     496       33468 :         if ( !(nStartTypes & ASC_UNDERSCORE) )
     497       33106 :             pTable[95] &= ~TOKEN_CHAR_WORD;     // not allowed as start character
     498       33468 :         if ( !(nContTypes & ASC_UNDERSCORE) )
     499       33106 :             pTable[95] &= ~TOKEN_WORD;          // not allowed as cont character
     500             : 
     501       33468 :         if ( nStartTypes & ASC_DOLLAR )
     502         167 :             pTable[36] |= TOKEN_CHAR_WORD;      // allowed as start character
     503       33468 :         if ( nContTypes & ASC_DOLLAR )
     504         167 :             pTable[36] |= TOKEN_WORD;           // allowed as cont character
     505             : 
     506       33468 :         if ( nStartTypes & ASC_DOT )
     507       17116 :             pTable[46] |= TOKEN_CHAR_WORD;      // allowed as start character
     508       33468 :         if ( nContTypes & ASC_DOT )
     509       17289 :             pTable[46] |= TOKEN_WORD;           // allowed as cont character
     510             : 
     511       33468 :         if ( nStartTypes & ASC_COLON )
     512           0 :             pTable[58] |= TOKEN_CHAR_WORD;      // allowed as start character
     513       33468 :         if ( nContTypes & ASC_COLON )
     514           0 :             pTable[58] |= TOKEN_WORD;           // allowed as cont character
     515             : 
     516       33468 :         if ( nStartTypes & ASC_CONTROL )
     517           0 :             for ( i = 1; i < 32; i++ )
     518           0 :                 pTable[i] |= TOKEN_CHAR_WORD;   // allowed as start character
     519       33468 :         if ( nContTypes & ASC_CONTROL )
     520           0 :             for ( i = 1; i < 32; i++ )
     521           0 :                 pTable[i] |= TOKEN_WORD;        // allowed as cont character
     522             : 
     523       33468 :         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       33468 :         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       33468 :     sal_Int32 nLen = aStartChars.getLength();
     535       33468 :     if ( nLen )
     536             :     {
     537         167 :         if ( !pStart )
     538         167 :             pStart = new UPT_FLAG_TYPE[ nLen ];
     539         167 :         const sal_Unicode* p = aStartChars.getStr();
     540         501 :         for ( sal_Int32 j=0; j<nLen; j++, p++ )
     541             :         {
     542         334 :             pStart[j] = TOKEN_CHAR_WORD;
     543         334 :             if ( *p < nDefCnt )
     544         334 :                 pTable[*p] |= TOKEN_CHAR_WORD;
     545             :         }
     546             :     }
     547             :     // ContChars
     548       33468 :     nLen = aContChars.getLength();
     549       33468 :     if ( nLen )
     550             :     {
     551         167 :         if ( !pCont )
     552         167 :             pCont = new UPT_FLAG_TYPE[ nLen ];
     553         167 :         const sal_Unicode* p = aContChars.getStr();
     554         501 :         for ( sal_Int32 j=0; j<nLen; j++ )
     555             :         {
     556         334 :             pCont[j] = TOKEN_WORD;
     557         334 :             if ( *p < nDefCnt )
     558         334 :                 pTable[*p] |= TOKEN_WORD;
     559             :         }
     560             :     }
     561       33468 : }
     562             : 
     563             : 
     564       29713 : void cclass_Unicode::destroyParserTable()
     565             : {
     566       29713 :     if ( pCont )
     567           0 :         delete [] pCont;
     568       29713 :     if ( pStart )
     569           0 :         delete [] pStart;
     570       29713 :     if ( pTable )
     571       17124 :         delete [] pTable;
     572       29713 : }
     573             : 
     574             : 
     575      452058 : UPT_FLAG_TYPE cclass_Unicode::getFlags( const sal_Unicode* aStr, sal_Int32 nPos )
     576             : {
     577             :     UPT_FLAG_TYPE nMask;
     578      452058 :     sal_Unicode c = aStr[nPos];
     579      452058 :     if ( c < nDefCnt )
     580      450612 :         nMask = pTable[ sal_uInt8(c) ];
     581             :     else
     582        1446 :         nMask = getFlagsExtended( aStr, nPos );
     583      452058 :     switch ( eState )
     584             :     {
     585             :         case ssGetChar :
     586             :         case ssRewindFromValue :
     587             :         case ssIgnoreLeadingInRewind :
     588             :         case ssGetWordFirstChar :
     589      102791 :             if ( !(nMask & TOKEN_CHAR_WORD) )
     590             :             {
     591       25286 :                 nMask |= getStartCharsFlags( c );
     592       25286 :                 if ( nMask & TOKEN_CHAR_WORD )
     593           0 :                     nMask &= ~TOKEN_EXCLUDED;
     594             :             }
     595      102791 :         break;
     596             :         case ssGetValue :
     597             :         case ssGetWord :
     598      348356 :             if ( !(nMask & TOKEN_WORD) )
     599             :             {
     600       28425 :                 nMask |= getContCharsFlags( c );
     601       28425 :                 if ( nMask & TOKEN_WORD )
     602           0 :                     nMask &= ~TOKEN_EXCLUDED;
     603             :             }
     604      348356 :         break;
     605             :         default:
     606             :             ;   // other cases aren't needed, no compiler warning
     607             :     }
     608      452058 :     return nMask;
     609             : }
     610             : 
     611             : 
     612        1446 : UPT_FLAG_TYPE cclass_Unicode::getFlagsExtended( const sal_Unicode* aStr, sal_Int32 nPos )
     613             : {
     614        1446 :     sal_Unicode c = aStr[nPos];
     615        1446 :     if ( c == cGroupSep )
     616           0 :         return TOKEN_VALUE;
     617        1446 :     else if ( c == cDecimalSep )
     618           0 :         return TOKEN_CHAR_VALUE | TOKEN_VALUE;
     619             :     using namespace i18n;
     620        1758 :     bool bStart = (eState == ssGetChar || eState == ssGetWordFirstChar ||
     621        1758 :             eState == ssRewindFromValue || eState == ssIgnoreLeadingInRewind);
     622        1446 :     sal_Int32 nTypes = (bStart ? nStartTypes : nContTypes);
     623             : 
     624             :     //! all KParseTokens::UNI_... must be matched
     625        1446 :     switch ( u_charType( (sal_uInt32) c ) )
     626             :     {
     627             :         case U_UPPERCASE_LETTER :
     628          54 :             return (nTypes & KParseTokens::UNI_UPALPHA) ?
     629             :                 (bStart ? TOKEN_CHAR_WORD : TOKEN_WORD) :
     630          54 :                 TOKEN_ILLEGAL;
     631             :         case U_LOWERCASE_LETTER :
     632         802 :             return (nTypes & KParseTokens::UNI_LOALPHA) ?
     633             :                 (bStart ? TOKEN_CHAR_WORD : TOKEN_WORD) :
     634         802 :                 TOKEN_ILLEGAL;
     635             :         case U_TITLECASE_LETTER :
     636           0 :             return (nTypes & KParseTokens::UNI_TITLE_ALPHA) ?
     637             :                 (bStart ? TOKEN_CHAR_WORD : TOKEN_WORD) :
     638           0 :                 TOKEN_ILLEGAL;
     639             :         case U_MODIFIER_LETTER :
     640           0 :             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           6 :             return (nTypes & KParseTokens::UNI_OTHER_LETTER) ?
     652             :                 (bStart ? TOKEN_CHAR_WORD : TOKEN_WORD) :
     653           6 :                 TOKEN_ILLEGAL;
     654             :         case U_DECIMAL_DIGIT_NUMBER :
     655           0 :             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           0 :             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           0 :             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           0 :             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             :         case U_OTHER_PUNCTUATION:
     670             :             // fdo#61754 Lets see (if we not at the start) if this is midletter
     671             :             // punctuation and allow it in a word if it is similarly to
     672             :             // U_NON_SPACING_MARK
     673          66 :             if (bStart || U_WB_MIDLETTER != u_getIntPropertyValue(c, UCHAR_WORD_BREAK))
     674          66 :                 return TOKEN_ILLEGAL;
     675             :             else
     676             :             {
     677             :                 //allowing it to continue the word
     678           0 :                 return (nTypes & KParseTokens::UNI_OTHER_LETTER) ?
     679           0 :                     TOKEN_WORD : TOKEN_ILLEGAL;
     680             :             }
     681             :             break;
     682             :     }
     683             : 
     684         518 :     return TOKEN_ILLEGAL;
     685             : }
     686             : 
     687             : 
     688       25286 : UPT_FLAG_TYPE cclass_Unicode::getStartCharsFlags( sal_Unicode c )
     689             : {
     690       25286 :     if ( pStart )
     691             :     {
     692           1 :         const sal_Unicode* pStr = aStartChars.getStr();
     693           1 :         const sal_Unicode* p = StrChr( pStr, c );
     694           1 :         if ( p )
     695           0 :             return pStart[ p - pStr ];
     696             :     }
     697       25286 :     return TOKEN_ILLEGAL;
     698             : }
     699             : 
     700             : 
     701       28425 : UPT_FLAG_TYPE cclass_Unicode::getContCharsFlags( sal_Unicode c )
     702             : {
     703       28425 :     if ( pCont )
     704             :     {
     705         106 :         const sal_Unicode* pStr = aContChars.getStr();
     706         106 :         const sal_Unicode* p = StrChr( pStr, c );
     707         106 :         if ( p )
     708           0 :             return pCont[ p - pStr ];
     709             :     }
     710       28425 :     return TOKEN_ILLEGAL;
     711             : }
     712             : 
     713             : 
     714      102775 : void cclass_Unicode::parseText( ParseResult& r, const OUString& rText, sal_Int32 nPos, sal_Int32 nTokenType )
     715             : {
     716             :     using namespace i18n;
     717      102775 :     const sal_Unicode* const pTextStart = rText.getStr() + nPos;
     718      102775 :     eState = ssGetChar;
     719             : 
     720             :     //! All the variables below (plus ParseResult) have to be resetted on ssRewindFromValue!
     721      102775 :     const sal_Unicode* pSym = pTextStart;
     722      102775 :     const sal_Unicode* pSrc = pSym;
     723      102775 :     OUString aSymbol;
     724      102775 :     sal_Unicode c = *pSrc;
     725      102775 :     sal_Unicode cLast = 0;
     726      102775 :     int nDecSeps = 0;
     727      102775 :     bool bQuote = false;
     728      102775 :     bool bMightBeWord = true;
     729      102775 :     bool bMightBeWordLast = true;
     730             :     //! All the variables above (plus ParseResult) have to be resetted on ssRewindFromValue!
     731             : 
     732      657608 :     while ( (c != 0) && (eState != ssStop) )
     733             :     {
     734      452058 :         UPT_FLAG_TYPE nMask = getFlags( pTextStart, pSrc - pTextStart );
     735      452058 :         if ( nMask & TOKEN_EXCLUDED )
     736           0 :             eState = ssBounce;
     737      452058 :         if ( bMightBeWord )
     738             :         {   // only relevant for ssGetValue fall back
     739      799471 :             if ( eState == ssGetChar || eState == ssRewindFromValue ||
     740      348340 :                     eState == ssIgnoreLeadingInRewind )
     741      102791 :                 bMightBeWord = ((nMask & TOKEN_CHAR_WORD) != 0);
     742             :             else
     743      348340 :                 bMightBeWord = ((nMask & TOKEN_WORD) != 0);
     744             :         }
     745      452058 :         sal_Int32 nParseTokensType = getParseTokensType( pTextStart, pSrc - pTextStart );
     746      452058 :         pSrc++;
     747      452058 :         switch (eState)
     748             :         {
     749             :             case ssGetChar :
     750             :             case ssRewindFromValue :
     751             :             case ssIgnoreLeadingInRewind :
     752             :             {
     753      102791 :                 if ( (nMask & TOKEN_CHAR_VALUE) && eState != ssRewindFromValue
     754        1329 :                         && eState != ssIgnoreLeadingInRewind )
     755             :                 {   //! must be first, may fall back to ssGetWord via bMightBeWord
     756        1329 :                     eState = ssGetValue;
     757        2658 :                     if ( nMask & TOKEN_VALUE_DIGIT )
     758             :                     {
     759        1323 :                         if ( 128 <= c )
     760           0 :                             r.TokenType = KParseType::UNI_NUMBER;
     761             :                         else
     762        1323 :                             r.TokenType = KParseType::ASC_NUMBER;
     763             :                     }
     764           6 :                     else if ( c == cDecimalSep )
     765             :                     {
     766           6 :                         if ( *pSrc )
     767           0 :                             ++nDecSeps;
     768             :                         else
     769           6 :                             eState = ssRewindFromValue;
     770             :                             // retry for ONE_SINGLE_CHAR or others
     771             :                     }
     772             :                 }
     773      101462 :                 else if ( nMask & TOKEN_CHAR_WORD )
     774             :                 {
     775       76179 :                     eState = ssGetWord;
     776       76179 :                     r.TokenType = KParseType::IDENTNAME;
     777             :                 }
     778       25283 :                 else if ( nMask & TOKEN_NAME_SEP )
     779             :                 {
     780           0 :                     eState = ssGetWordFirstChar;
     781           0 :                     bQuote = true;
     782           0 :                     pSym++;
     783           0 :                     nParseTokensType = 0;   // will be taken of first real character
     784           0 :                     r.TokenType = KParseType::SINGLE_QUOTE_NAME;
     785             :                 }
     786       25283 :                 else if ( nMask & TOKEN_CHAR_STRING )
     787             :                 {
     788         148 :                     eState = ssGetString;
     789         148 :                     pSym++;
     790         148 :                     nParseTokensType = 0;   // will be taken of first real character
     791         148 :                     r.TokenType = KParseType::DOUBLE_QUOTE_STRING;
     792             :                 }
     793       25135 :                 else if ( nMask & TOKEN_CHAR_DONTCARE )
     794             :                 {
     795          10 :                     if ( nStartTypes & KParseTokens::IGNORE_LEADING_WS )
     796             :                     {
     797          10 :                         if (eState == ssRewindFromValue)
     798           0 :                             eState = ssIgnoreLeadingInRewind;
     799          10 :                         r.LeadingWhiteSpace++;
     800          10 :                         pSym++;
     801          10 :                         nParseTokensType = 0;   // wait until real character
     802          10 :                         bMightBeWord = true;
     803             :                     }
     804             :                     else
     805           0 :                         eState = ssBounce;
     806             :                 }
     807       25125 :                 else if ( nMask & TOKEN_CHAR_BOOL )
     808             :                 {
     809        1408 :                     eState = ssGetBool;
     810        1408 :                     r.TokenType = KParseType::BOOLEAN;
     811             :                 }
     812       23717 :                 else if ( nMask & TOKEN_CHAR )
     813             :                 {   //! must be last
     814       16690 :                     eState = ssStop;
     815       16690 :                     r.TokenType = KParseType::ONE_SINGLE_CHAR;
     816             :                 }
     817             :                 else
     818        7027 :                     eState = ssBounce;      // not known
     819             :             }
     820      102791 :             break;
     821             :             case ssGetValue :
     822             :             {
     823        1431 :                 if ( nMask & TOKEN_VALUE_DIGIT )
     824             :                 {
     825         128 :                     if ( 128 <= c )
     826           0 :                         r.TokenType = KParseType::UNI_NUMBER;
     827         128 :                     else if ( r.TokenType != KParseType::UNI_NUMBER )
     828         128 :                         r.TokenType = KParseType::ASC_NUMBER;
     829             :                 }
     830        1431 :                 if ( nMask & TOKEN_VALUE )
     831             :                 {
     832         144 :                     if ( c == cDecimalSep && ++nDecSeps > 1 )
     833             :                     {
     834           0 :                         if ( pSrc - pTextStart == 2 )
     835           0 :                             eState = ssRewindFromValue;
     836             :                             // consecutive separators
     837             :                         else
     838           0 :                             eState = ssStopBack;
     839             :                     }
     840             :                     // else keep it going
     841             :                 }
     842        1287 :                 else if ( c == 'E' || c == 'e' )
     843             :                 {
     844           0 :                     UPT_FLAG_TYPE nNext = getFlags( pTextStart, pSrc - pTextStart );
     845           0 :                     if ( nNext & TOKEN_VALUE_EXP )
     846             :                         ;   // keep it going
     847           0 :                     else if ( bMightBeWord && ((nNext & TOKEN_WORD) || !*pSrc) )
     848             :                     {   // might be a numerical name (1.2efg)
     849           0 :                         eState = ssGetWord;
     850           0 :                         r.TokenType = KParseType::IDENTNAME;
     851             :                     }
     852             :                     else
     853           0 :                         eState = ssStopBack;
     854             :                 }
     855        1287 :                 else if ( nMask & TOKEN_VALUE_SIGN )
     856             :                 {
     857          30 :                     if ( (cLast == 'E') || (cLast == 'e') )
     858             :                     {
     859           0 :                         UPT_FLAG_TYPE nNext = getFlags( pTextStart, pSrc - pTextStart );
     860           0 :                         if ( nNext & TOKEN_VALUE_EXP_VALUE )
     861             :                             ;   // keep it going
     862           0 :                         else if ( bMightBeWord && ((nNext & TOKEN_WORD) || !*pSrc) )
     863             :                         {   // might be a numerical name (1.2e+fg)
     864           0 :                             eState = ssGetWord;
     865           0 :                             r.TokenType = KParseType::IDENTNAME;
     866             :                         }
     867             :                         else
     868           0 :                             eState = ssStopBack;
     869             :                     }
     870          30 :                     else if ( bMightBeWord )
     871             :                     {   // might be a numerical name (1.2+fg)
     872           0 :                         eState = ssGetWord;
     873           0 :                         r.TokenType = KParseType::IDENTNAME;
     874             :                     }
     875             :                     else
     876          30 :                         eState = ssStopBack;
     877             :                 }
     878        1257 :                 else if ( bMightBeWord && (nMask & TOKEN_WORD) )
     879             :                 {   // might be a numerical name (1995.A1)
     880           0 :                     eState = ssGetWord;
     881           0 :                     r.TokenType = KParseType::IDENTNAME;
     882             :                 }
     883             :                 else
     884        1257 :                     eState = ssStopBack;
     885             :             }
     886        1431 :             break;
     887             :             case ssGetWordFirstChar :
     888           0 :                 eState = ssGetWord;
     889             :                 // fall thru
     890             :             case ssGetWord :
     891             :             {
     892      346925 :                 if ( nMask & TOKEN_WORD )
     893             :                     ;   // keep it going
     894       27122 :                 else if ( nMask & TOKEN_NAME_SEP )
     895             :                 {
     896          16 :                     if ( bQuote )
     897             :                     {
     898           0 :                         if ( cLast == '\\' )
     899             :                         {   // escaped
     900           0 :                             aSymbol += OUString( pSym, pSrc - pSym - 2 );
     901           0 :                             aSymbol += OUString( &c, 1);
     902             :                         }
     903             :                         else
     904             :                         {
     905           0 :                             eState = ssStop;
     906           0 :                             aSymbol += OUString( pSym, pSrc - pSym - 1 );
     907             :                         }
     908           0 :                         pSym = pSrc;
     909             :                     }
     910             :                     else
     911          16 :                         eState = ssStopBack;
     912             :                 }
     913       27106 :                 else if ( bQuote )
     914             :                     ;   // keep it going
     915             :                 else
     916       27106 :                     eState = ssStopBack;
     917             :             }
     918      346925 :             break;
     919             :             case ssGetString :
     920             :             {
     921         207 :                 if ( nMask & TOKEN_STRING_SEP )
     922             :                 {
     923          76 :                     if ( cLast == '\\' )
     924             :                     {   // escaped
     925           0 :                         aSymbol += OUString( pSym, pSrc - pSym - 2 );
     926           0 :                         aSymbol += OUString( &c, 1);
     927             :                     }
     928          76 :                     else if ( c == *pSrc &&
     929           0 :                             !(nContTypes & KParseTokens::TWO_DOUBLE_QUOTES_BREAK_STRING) )
     930             :                     {   // "" => literal " escaped
     931           0 :                         aSymbol += OUString( pSym, pSrc - pSym );
     932           0 :                         pSrc++;
     933             :                     }
     934             :                     else
     935             :                     {
     936          76 :                         eState = ssStop;
     937          76 :                         aSymbol += OUString( pSym, pSrc - pSym - 1 );
     938             :                     }
     939          76 :                     pSym = pSrc;
     940             :                 }
     941             :             }
     942         207 :             break;
     943             :             case ssGetBool :
     944             :             {
     945         704 :                 if ( (nMask & TOKEN_BOOL) )
     946           8 :                     eState = ssStop;    // maximum 2: <, >, <>, <=, >=
     947             :                 else
     948         696 :                     eState = ssStopBack;
     949             :             }
     950         704 :             break;
     951             :             case ssStopBack :
     952             :             case ssBounce :
     953             :             case ssStop :
     954             :                 ;   // nothing, no compiler warning
     955           0 :             break;
     956             :         }
     957      452058 :         if ( eState == ssRewindFromValue )
     958             :         {
     959           6 :             r = ParseResult();
     960           6 :             pSym = pTextStart;
     961           6 :             pSrc = pSym;
     962           6 :             aSymbol = OUString();
     963           6 :             c = *pSrc;
     964           6 :             cLast = 0;
     965           6 :             nDecSeps = 0;
     966           6 :             bQuote = false;
     967           6 :             bMightBeWord = true;
     968           6 :             bMightBeWordLast = true;
     969             :         }
     970             :         else
     971             :         {
     972      452052 :             if ( !(r.TokenType & nTokenType) )
     973             :             {
     974       16346 :                 if ( (r.TokenType & (KParseType::ASC_NUMBER | KParseType::UNI_NUMBER))
     975         192 :                         && (nTokenType & KParseType::IDENTNAME) && bMightBeWord )
     976             :                     ;   // keep a number that might be a word
     977       16194 :                 else if ( r.LeadingWhiteSpace == (pSrc - pTextStart) )
     978             :                     ;   // keep ignored white space
     979       16184 :                 else if ( !r.TokenType && eState == ssGetValue && (nMask & TOKEN_VALUE_SEP) )
     980             :                     ;   // keep uncertain value
     981             :                 else
     982       16184 :                     eState = ssBounce;
     983             :             }
     984      452052 :             if ( eState == ssBounce )
     985             :             {
     986       16184 :                 r.TokenType = 0;
     987       16184 :                 eState = ssStopBack;
     988             :             }
     989      452052 :             if ( eState == ssStopBack )
     990             :             {   // put back
     991       45249 :                 pSrc--;
     992       45249 :                 bMightBeWord = bMightBeWordLast;
     993       45249 :                 eState = ssStop;
     994             :             }
     995      452052 :             if ( eState != ssStop )
     996             :             {
     997      398367 :                 if ( !r.StartFlags )
     998       78362 :                     r.StartFlags |= nParseTokensType;
     999             :                 else
    1000      320005 :                     r.ContFlags |= nParseTokensType;
    1001             :             }
    1002      452052 :             bMightBeWordLast = bMightBeWord;
    1003      452052 :             cLast = c;
    1004      452052 :             c = *pSrc;
    1005             :         }
    1006             :     }
    1007             :     // r.CharLen is the length in characters (not code points) of the parsed
    1008             :     // token not including any leading white space, change this calculation if
    1009             :     // multi-code-point Unicode characters are to be supported.
    1010      102775 :     r.CharLen = pSrc - pTextStart - r.LeadingWhiteSpace;
    1011      102775 :     r.EndPos = nPos + (pSrc - pTextStart);
    1012      102775 :     if ( r.TokenType & KParseType::ASC_NUMBER )
    1013             :     {
    1014             :         r.Value = rtl_math_uStringToDouble( pTextStart + r.LeadingWhiteSpace,
    1015        1283 :                 pTextStart + r.EndPos, cDecimalSep, cGroupSep, NULL, NULL );
    1016        1283 :         if ( bMightBeWord )
    1017        1267 :             r.TokenType |= KParseType::IDENTNAME;
    1018             :     }
    1019      101492 :     else if ( r.TokenType & KParseType::UNI_NUMBER )
    1020             :     {
    1021           0 :         if ( !xNatNumSup.is() )
    1022             :         {
    1023           0 :             if ( m_xContext.is() )
    1024             :             {
    1025           0 :                 xNatNumSup = NativeNumberSupplier::create( m_xContext );
    1026             :             }
    1027             :         }
    1028           0 :         OUString aTmp( pTextStart + r.LeadingWhiteSpace, r.EndPos - nPos +
    1029           0 :                 r.LeadingWhiteSpace );
    1030             :         // transliterate to ASCII
    1031           0 :         aTmp = xNatNumSup->getNativeNumberString( aTmp, aParserLocale,
    1032           0 :                 NativeNumberMode::NATNUM0 );
    1033           0 :         r.Value = ::rtl::math::stringToDouble( aTmp, cDecimalSep, cGroupSep, NULL, NULL );
    1034           0 :         if ( bMightBeWord )
    1035           0 :             r.TokenType |= KParseType::IDENTNAME;
    1036             :     }
    1037      101492 :     else if ( r.TokenType & (KParseType::SINGLE_QUOTE_NAME | KParseType::DOUBLE_QUOTE_STRING) )
    1038             :     {
    1039          76 :         if ( pSym < pSrc )
    1040             :         {   //! open quote
    1041           0 :             aSymbol += OUString( pSym, pSrc - pSym );
    1042           0 :             r.TokenType |= KParseType::MISSING_QUOTE;
    1043             :         }
    1044          76 :         r.DequotedNameOrString = aSymbol;
    1045      102775 :     }
    1046      102775 : }
    1047             : 
    1048             : } } } }
    1049             : 
    1050             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10