/src/libreoffice/i18npool/source/characterclassification/cclass_unicode_parser.cxx
Line | Count | Source |
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 <algorithm> |
22 | | |
23 | | #include <cclass_unicode.hxx> |
24 | | #include <unicode/uchar.h> |
25 | | #include <rtl/character.hxx> |
26 | | #include <rtl/math.hxx> |
27 | | #include <rtl/ustring.hxx> |
28 | | #include <sal/log.hxx> |
29 | | #include <com/sun/star/i18n/KParseTokens.hpp> |
30 | | #include <com/sun/star/i18n/KParseType.hpp> |
31 | | #include <com/sun/star/i18n/LocaleData2.hpp> |
32 | | #include <com/sun/star/i18n/NativeNumberMode.hpp> |
33 | | #include <com/sun/star/i18n/NativeNumberSupplier.hpp> |
34 | | |
35 | | #include <string.h> |
36 | | #include <string_view> |
37 | | |
38 | | using namespace ::com::sun::star::uno; |
39 | | using namespace ::com::sun::star::i18n; |
40 | | using namespace ::com::sun::star::lang; |
41 | | |
42 | 55.2k | #define TOKEN_DIGIT_FLAGS (ParserFlags::CHAR_VALUE | ParserFlags::VALUE | ParserFlags::VALUE_EXP | ParserFlags::VALUE_EXP_VALUE | ParserFlags::VALUE_DIGIT) |
43 | | |
44 | | namespace i18npool { |
45 | | |
46 | | // Default identifier/name specification is [A-Za-z_][A-Za-z0-9_]* |
47 | | |
48 | | const sal_uInt8 cclass_Unicode::nDefCnt = 128; |
49 | | const ParserFlags cclass_Unicode::pDefaultParserTable[ nDefCnt ] = |
50 | | { |
51 | | // (...) == Calc formula compiler specific, commented out and modified |
52 | | |
53 | | /* \0 */ ParserFlags::EXCLUDED, |
54 | | ParserFlags::ILLEGAL, |
55 | | ParserFlags::ILLEGAL, |
56 | | ParserFlags::ILLEGAL, |
57 | | ParserFlags::ILLEGAL, |
58 | | ParserFlags::ILLEGAL, |
59 | | ParserFlags::ILLEGAL, |
60 | | ParserFlags::ILLEGAL, |
61 | | ParserFlags::ILLEGAL, |
62 | | /* 9 \t */ ParserFlags::CHAR_DONTCARE | ParserFlags::WORD_SEP | ParserFlags::VALUE_SEP, // (ParserFlags::ILLEGAL) |
63 | | ParserFlags::ILLEGAL, |
64 | | /* 11 \v */ ParserFlags::CHAR_DONTCARE | ParserFlags::WORD_SEP | ParserFlags::VALUE_SEP, // (ParserFlags::ILLEGAL) |
65 | | ParserFlags::ILLEGAL, |
66 | | ParserFlags::ILLEGAL, |
67 | | ParserFlags::ILLEGAL, |
68 | | ParserFlags::ILLEGAL, |
69 | | ParserFlags::ILLEGAL, |
70 | | ParserFlags::ILLEGAL, |
71 | | ParserFlags::ILLEGAL, |
72 | | ParserFlags::ILLEGAL, |
73 | | ParserFlags::ILLEGAL, |
74 | | ParserFlags::ILLEGAL, |
75 | | ParserFlags::ILLEGAL, |
76 | | ParserFlags::ILLEGAL, |
77 | | ParserFlags::ILLEGAL, |
78 | | ParserFlags::ILLEGAL, |
79 | | ParserFlags::ILLEGAL, |
80 | | ParserFlags::ILLEGAL, |
81 | | ParserFlags::ILLEGAL, |
82 | | ParserFlags::ILLEGAL, |
83 | | ParserFlags::ILLEGAL, |
84 | | ParserFlags::ILLEGAL, |
85 | | /* 32 */ ParserFlags::CHAR_DONTCARE | ParserFlags::WORD_SEP | ParserFlags::VALUE_SEP, |
86 | | /* 33 ! */ ParserFlags::CHAR | ParserFlags::WORD_SEP | ParserFlags::VALUE_SEP, |
87 | | /* 34 " */ ParserFlags::CHAR_STRING | ParserFlags::STRING_SEP, |
88 | | /* 35 # */ ParserFlags::CHAR | ParserFlags::WORD_SEP | ParserFlags::VALUE_SEP, // (ParserFlags::WORD_SEP) |
89 | | /* 36 $ */ ParserFlags::CHAR | ParserFlags::WORD_SEP | ParserFlags::VALUE_SEP, // (ParserFlags::CHAR_WORD | ParserFlags::WORD) |
90 | | /* 37 % */ ParserFlags::CHAR | ParserFlags::WORD_SEP | ParserFlags::VALUE_SEP, // (ParserFlags::VALUE) |
91 | | /* 38 & */ ParserFlags::CHAR | ParserFlags::WORD_SEP | ParserFlags::VALUE_SEP, |
92 | | /* 39 ' */ ParserFlags::NAME_SEP, |
93 | | /* 40 ( */ ParserFlags::CHAR | ParserFlags::WORD_SEP | ParserFlags::VALUE_SEP, |
94 | | /* 41 ) */ ParserFlags::CHAR | ParserFlags::WORD_SEP | ParserFlags::VALUE_SEP, |
95 | | /* 42 * */ ParserFlags::CHAR | ParserFlags::WORD_SEP | ParserFlags::VALUE_SEP, |
96 | | /* 43 + */ ParserFlags::CHAR | ParserFlags::WORD_SEP | ParserFlags::VALUE_SEP | ParserFlags::VALUE_EXP | ParserFlags::VALUE_SIGN, |
97 | | /* 44 , */ ParserFlags::CHAR | ParserFlags::WORD_SEP | ParserFlags::VALUE_SEP, // (ParserFlags::CHAR_VALUE | ParserFlags::VALUE) |
98 | | /* 45 - */ ParserFlags::CHAR | ParserFlags::WORD_SEP | ParserFlags::VALUE_SEP | ParserFlags::VALUE_EXP | ParserFlags::VALUE_SIGN, |
99 | | /* 46 . */ ParserFlags::CHAR | ParserFlags::WORD_SEP | ParserFlags::VALUE_SEP, // (ParserFlags::WORD | ParserFlags::CHAR_VALUE | ParserFlags::VALUE) |
100 | | /* 47 / */ ParserFlags::CHAR | ParserFlags::WORD_SEP | ParserFlags::VALUE_SEP, |
101 | | //for ( i = 48; i < 58; i++ ) |
102 | | /* 48 0 */ TOKEN_DIGIT_FLAGS | ParserFlags::WORD, |
103 | | /* 49 1 */ TOKEN_DIGIT_FLAGS | ParserFlags::WORD, |
104 | | /* 50 2 */ TOKEN_DIGIT_FLAGS | ParserFlags::WORD, |
105 | | /* 51 3 */ TOKEN_DIGIT_FLAGS | ParserFlags::WORD, |
106 | | /* 52 4 */ TOKEN_DIGIT_FLAGS | ParserFlags::WORD, |
107 | | /* 53 5 */ TOKEN_DIGIT_FLAGS | ParserFlags::WORD, |
108 | | /* 54 6 */ TOKEN_DIGIT_FLAGS | ParserFlags::WORD, |
109 | | /* 55 7 */ TOKEN_DIGIT_FLAGS | ParserFlags::WORD, |
110 | | /* 56 8 */ TOKEN_DIGIT_FLAGS | ParserFlags::WORD, |
111 | | /* 57 9 */ TOKEN_DIGIT_FLAGS | ParserFlags::WORD, |
112 | | /* 58 : */ ParserFlags::CHAR | ParserFlags::WORD_SEP | ParserFlags::VALUE_SEP, // (ParserFlags::WORD) |
113 | | /* 59 ; */ ParserFlags::CHAR | ParserFlags::WORD_SEP | ParserFlags::VALUE_SEP, |
114 | | /* 60 < */ ParserFlags::CHAR_BOOL | ParserFlags::WORD_SEP | ParserFlags::VALUE_SEP, |
115 | | /* 61 = */ ParserFlags::CHAR | ParserFlags::BOOL | ParserFlags::WORD_SEP | ParserFlags::VALUE_SEP, |
116 | | /* 62 > */ ParserFlags::CHAR_BOOL | ParserFlags::BOOL | ParserFlags::WORD_SEP | ParserFlags::VALUE_SEP, |
117 | | /* 63 ? */ ParserFlags::CHAR | ParserFlags::WORD_SEP | ParserFlags::VALUE_SEP, // (ParserFlags::CHAR_WORD | ParserFlags::WORD) |
118 | | /* 64 @ */ ParserFlags::CHAR | ParserFlags::WORD_SEP | ParserFlags::VALUE_SEP, // (ParserFlags::ILLEGAL // UNUSED) |
119 | | //for ( i = 65; i < 91; i++ ) |
120 | | /* 65 A */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
121 | | /* 66 B */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
122 | | /* 67 C */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
123 | | /* 68 D */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
124 | | /* 69 E */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
125 | | /* 70 F */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
126 | | /* 71 G */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
127 | | /* 72 H */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
128 | | /* 73 I */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
129 | | /* 74 J */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
130 | | /* 75 K */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
131 | | /* 76 L */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
132 | | /* 77 M */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
133 | | /* 78 N */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
134 | | /* 79 O */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
135 | | /* 80 P */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
136 | | /* 81 Q */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
137 | | /* 82 R */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
138 | | /* 83 S */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
139 | | /* 84 T */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
140 | | /* 85 U */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
141 | | /* 86 V */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
142 | | /* 87 W */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
143 | | /* 88 X */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
144 | | /* 89 Y */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
145 | | /* 90 Z */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
146 | | /* 91 [ */ ParserFlags::CHAR | ParserFlags::WORD_SEP | ParserFlags::VALUE_SEP, // (ParserFlags::ILLEGAL // UNUSED) |
147 | | /* 92 \ */ ParserFlags::CHAR | ParserFlags::WORD_SEP | ParserFlags::VALUE_SEP, // (ParserFlags::ILLEGAL // UNUSED) |
148 | | /* 93 ] */ ParserFlags::CHAR | ParserFlags::WORD_SEP | ParserFlags::VALUE_SEP, // (ParserFlags::ILLEGAL // UNUSED) |
149 | | /* 94 ^ */ ParserFlags::CHAR | ParserFlags::WORD_SEP | ParserFlags::VALUE_SEP, |
150 | | /* 95 _ */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
151 | | /* 96 ` */ ParserFlags::CHAR | ParserFlags::WORD_SEP | ParserFlags::VALUE_SEP, // (ParserFlags::ILLEGAL // UNUSED) |
152 | | //for ( i = 97; i < 123; i++ ) |
153 | | /* 97 a */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
154 | | /* 98 b */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
155 | | /* 99 c */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
156 | | /* 100 d */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
157 | | /* 101 e */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
158 | | /* 102 f */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
159 | | /* 103 g */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
160 | | /* 104 h */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
161 | | /* 105 i */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
162 | | /* 106 j */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
163 | | /* 107 k */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
164 | | /* 108 l */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
165 | | /* 109 m */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
166 | | /* 110 n */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
167 | | /* 111 o */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
168 | | /* 112 p */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
169 | | /* 113 q */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
170 | | /* 114 r */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
171 | | /* 115 s */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
172 | | /* 116 t */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
173 | | /* 117 u */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
174 | | /* 118 v */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
175 | | /* 119 w */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
176 | | /* 120 x */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
177 | | /* 121 y */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
178 | | /* 122 z */ ParserFlags::CHAR_WORD | ParserFlags::WORD, |
179 | | /* 123 { */ ParserFlags::CHAR | ParserFlags::WORD_SEP | ParserFlags::VALUE_SEP, // (ParserFlags::ILLEGAL // UNUSED) |
180 | | /* 124 | */ ParserFlags::CHAR | ParserFlags::WORD_SEP | ParserFlags::VALUE_SEP, // (ParserFlags::ILLEGAL // UNUSED) |
181 | | /* 125 } */ ParserFlags::CHAR | ParserFlags::WORD_SEP | ParserFlags::VALUE_SEP, // (ParserFlags::ILLEGAL // UNUSED) |
182 | | /* 126 ~ */ ParserFlags::CHAR | ParserFlags::WORD_SEP | ParserFlags::VALUE_SEP, // (ParserFlags::ILLEGAL // UNUSED) |
183 | | /* 127 */ ParserFlags::CHAR | ParserFlags::WORD_SEP | ParserFlags::VALUE_SEP // (ParserFlags::ILLEGAL // UNUSED) |
184 | | }; |
185 | | |
186 | | |
187 | | const sal_Int32 cclass_Unicode::pParseTokensType[ nDefCnt ] = |
188 | | { |
189 | | /* \0 */ KParseTokens::ASC_OTHER, |
190 | | KParseTokens::ASC_CONTROL, |
191 | | KParseTokens::ASC_CONTROL, |
192 | | KParseTokens::ASC_CONTROL, |
193 | | KParseTokens::ASC_CONTROL, |
194 | | KParseTokens::ASC_CONTROL, |
195 | | KParseTokens::ASC_CONTROL, |
196 | | KParseTokens::ASC_CONTROL, |
197 | | KParseTokens::ASC_CONTROL, |
198 | | /* 9 \t */ KParseTokens::ASC_CONTROL, |
199 | | KParseTokens::ASC_CONTROL, |
200 | | /* 11 \v */ KParseTokens::ASC_CONTROL, |
201 | | KParseTokens::ASC_CONTROL, |
202 | | KParseTokens::ASC_CONTROL, |
203 | | KParseTokens::ASC_CONTROL, |
204 | | KParseTokens::ASC_CONTROL, |
205 | | KParseTokens::ASC_CONTROL, |
206 | | KParseTokens::ASC_CONTROL, |
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 | | KParseTokens::ASC_CONTROL, |
216 | | KParseTokens::ASC_CONTROL, |
217 | | KParseTokens::ASC_CONTROL, |
218 | | KParseTokens::ASC_CONTROL, |
219 | | KParseTokens::ASC_CONTROL, |
220 | | KParseTokens::ASC_CONTROL, |
221 | | /* 32 */ KParseTokens::ASC_OTHER, |
222 | | /* 33 ! */ KParseTokens::ASC_OTHER, |
223 | | /* 34 " */ KParseTokens::ASC_OTHER, |
224 | | /* 35 # */ KParseTokens::ASC_OTHER, |
225 | | /* 36 $ */ KParseTokens::ASC_DOLLAR, |
226 | | /* 37 % */ KParseTokens::ASC_OTHER, |
227 | | /* 38 & */ KParseTokens::ASC_OTHER, |
228 | | /* 39 ' */ KParseTokens::ASC_OTHER, |
229 | | /* 40 ( */ KParseTokens::ASC_OTHER, |
230 | | /* 41 ) */ KParseTokens::ASC_OTHER, |
231 | | /* 42 * */ KParseTokens::ASC_OTHER, |
232 | | /* 43 + */ KParseTokens::ASC_OTHER, |
233 | | /* 44 , */ KParseTokens::ASC_OTHER, |
234 | | /* 45 - */ KParseTokens::ASC_OTHER, |
235 | | /* 46 . */ KParseTokens::ASC_DOT, |
236 | | /* 47 / */ KParseTokens::ASC_OTHER, |
237 | | //for ( i = 48; i < 58; i++ ) |
238 | | /* 48 0 */ KParseTokens::ASC_DIGIT, |
239 | | /* 49 1 */ KParseTokens::ASC_DIGIT, |
240 | | /* 50 2 */ KParseTokens::ASC_DIGIT, |
241 | | /* 51 3 */ KParseTokens::ASC_DIGIT, |
242 | | /* 52 4 */ KParseTokens::ASC_DIGIT, |
243 | | /* 53 5 */ KParseTokens::ASC_DIGIT, |
244 | | /* 54 6 */ KParseTokens::ASC_DIGIT, |
245 | | /* 55 7 */ KParseTokens::ASC_DIGIT, |
246 | | /* 56 8 */ KParseTokens::ASC_DIGIT, |
247 | | /* 57 9 */ KParseTokens::ASC_DIGIT, |
248 | | /* 58 : */ KParseTokens::ASC_COLON, |
249 | | /* 59 ; */ KParseTokens::ASC_OTHER, |
250 | | /* 60 < */ KParseTokens::ASC_OTHER, |
251 | | /* 61 = */ KParseTokens::ASC_OTHER, |
252 | | /* 62 > */ KParseTokens::ASC_OTHER, |
253 | | /* 63 ? */ KParseTokens::ASC_OTHER, |
254 | | /* 64 @ */ KParseTokens::ASC_OTHER, |
255 | | //for ( i = 65; i < 91; i++ ) |
256 | | /* 65 A */ KParseTokens::ASC_UPALPHA, |
257 | | /* 66 B */ KParseTokens::ASC_UPALPHA, |
258 | | /* 67 C */ KParseTokens::ASC_UPALPHA, |
259 | | /* 68 D */ KParseTokens::ASC_UPALPHA, |
260 | | /* 69 E */ KParseTokens::ASC_UPALPHA, |
261 | | /* 70 F */ KParseTokens::ASC_UPALPHA, |
262 | | /* 71 G */ KParseTokens::ASC_UPALPHA, |
263 | | /* 72 H */ KParseTokens::ASC_UPALPHA, |
264 | | /* 73 I */ KParseTokens::ASC_UPALPHA, |
265 | | /* 74 J */ KParseTokens::ASC_UPALPHA, |
266 | | /* 75 K */ KParseTokens::ASC_UPALPHA, |
267 | | /* 76 L */ KParseTokens::ASC_UPALPHA, |
268 | | /* 77 M */ KParseTokens::ASC_UPALPHA, |
269 | | /* 78 N */ KParseTokens::ASC_UPALPHA, |
270 | | /* 79 O */ KParseTokens::ASC_UPALPHA, |
271 | | /* 80 P */ KParseTokens::ASC_UPALPHA, |
272 | | /* 81 Q */ KParseTokens::ASC_UPALPHA, |
273 | | /* 82 R */ KParseTokens::ASC_UPALPHA, |
274 | | /* 83 S */ KParseTokens::ASC_UPALPHA, |
275 | | /* 84 T */ KParseTokens::ASC_UPALPHA, |
276 | | /* 85 U */ KParseTokens::ASC_UPALPHA, |
277 | | /* 86 V */ KParseTokens::ASC_UPALPHA, |
278 | | /* 87 W */ KParseTokens::ASC_UPALPHA, |
279 | | /* 88 X */ KParseTokens::ASC_UPALPHA, |
280 | | /* 89 Y */ KParseTokens::ASC_UPALPHA, |
281 | | /* 90 Z */ KParseTokens::ASC_UPALPHA, |
282 | | /* 91 [ */ KParseTokens::ASC_OTHER, |
283 | | /* 92 \ */ KParseTokens::ASC_OTHER, |
284 | | /* 93 ] */ KParseTokens::ASC_OTHER, |
285 | | /* 94 ^ */ KParseTokens::ASC_OTHER, |
286 | | /* 95 _ */ KParseTokens::ASC_UNDERSCORE, |
287 | | /* 96 ` */ KParseTokens::ASC_OTHER, |
288 | | //for ( i = 97; i < 123; i++ ) |
289 | | /* 97 a */ KParseTokens::ASC_LOALPHA, |
290 | | /* 98 b */ KParseTokens::ASC_LOALPHA, |
291 | | /* 99 c */ KParseTokens::ASC_LOALPHA, |
292 | | /* 100 d */ KParseTokens::ASC_LOALPHA, |
293 | | /* 101 e */ KParseTokens::ASC_LOALPHA, |
294 | | /* 102 f */ KParseTokens::ASC_LOALPHA, |
295 | | /* 103 g */ KParseTokens::ASC_LOALPHA, |
296 | | /* 104 h */ KParseTokens::ASC_LOALPHA, |
297 | | /* 105 i */ KParseTokens::ASC_LOALPHA, |
298 | | /* 106 j */ KParseTokens::ASC_LOALPHA, |
299 | | /* 107 k */ KParseTokens::ASC_LOALPHA, |
300 | | /* 108 l */ KParseTokens::ASC_LOALPHA, |
301 | | /* 109 m */ KParseTokens::ASC_LOALPHA, |
302 | | /* 110 n */ KParseTokens::ASC_LOALPHA, |
303 | | /* 111 o */ KParseTokens::ASC_LOALPHA, |
304 | | /* 112 p */ KParseTokens::ASC_LOALPHA, |
305 | | /* 113 q */ KParseTokens::ASC_LOALPHA, |
306 | | /* 114 r */ KParseTokens::ASC_LOALPHA, |
307 | | /* 115 s */ KParseTokens::ASC_LOALPHA, |
308 | | /* 116 t */ KParseTokens::ASC_LOALPHA, |
309 | | /* 117 u */ KParseTokens::ASC_LOALPHA, |
310 | | /* 118 v */ KParseTokens::ASC_LOALPHA, |
311 | | /* 119 w */ KParseTokens::ASC_LOALPHA, |
312 | | /* 120 x */ KParseTokens::ASC_LOALPHA, |
313 | | /* 121 y */ KParseTokens::ASC_LOALPHA, |
314 | | /* 122 z */ KParseTokens::ASC_LOALPHA, |
315 | | /* 123 { */ KParseTokens::ASC_OTHER, |
316 | | /* 124 | */ KParseTokens::ASC_OTHER, |
317 | | /* 125 } */ KParseTokens::ASC_OTHER, |
318 | | /* 126 ~ */ KParseTokens::ASC_OTHER, |
319 | | /* 127 */ KParseTokens::ASC_OTHER |
320 | | }; |
321 | | |
322 | | |
323 | | // static |
324 | | const sal_Unicode* cclass_Unicode::StrChr( const sal_Unicode* pStr, sal_uInt32 c ) |
325 | 2.34M | { |
326 | 2.34M | if ( !pStr ) |
327 | 0 | return nullptr; |
328 | 2.34M | sal_Unicode cs[2]; |
329 | 2.34M | auto const n = rtl::splitSurrogates(c, cs); |
330 | 6.97M | while ( *pStr ) |
331 | 4.68M | { |
332 | 4.68M | if ( *pStr == cs[0] && (n == 1 || pStr[1] == cs[1]) ) |
333 | 48.1k | return pStr; |
334 | 4.63M | pStr++; |
335 | 4.63M | } |
336 | 2.29M | return nullptr; |
337 | 2.34M | } |
338 | | |
339 | | |
340 | | sal_Int32 cclass_Unicode::getParseTokensType(sal_uInt32 const c, bool const isFirst) |
341 | 42.0M | { |
342 | 42.0M | if ( c < nDefCnt ) |
343 | 40.6M | return pParseTokensType[ sal_uInt8(c) ]; |
344 | 1.44M | else |
345 | 1.44M | { |
346 | | |
347 | | //! all KParseTokens::UNI_... must be matched |
348 | 1.44M | switch (u_charType(c)) |
349 | 1.44M | { |
350 | 207k | case U_UPPERCASE_LETTER : |
351 | 207k | return KParseTokens::UNI_UPALPHA; |
352 | 540k | case U_LOWERCASE_LETTER : |
353 | 540k | return KParseTokens::UNI_LOALPHA; |
354 | 123 | case U_TITLECASE_LETTER : |
355 | 123 | return KParseTokens::UNI_TITLE_ALPHA; |
356 | 13.1k | case U_MODIFIER_LETTER : |
357 | 13.1k | return KParseTokens::UNI_MODIFIER_LETTER; |
358 | 164k | case U_OTHER_LETTER : |
359 | | // Non_Spacing_Mark could not be as leading character |
360 | 164k | if (isFirst) break; |
361 | 140k | [[fallthrough]]; // treat it as Other_Letter. |
362 | 268k | case U_NON_SPACING_MARK : |
363 | 268k | return KParseTokens::UNI_OTHER_LETTER; |
364 | 5.47k | case U_DECIMAL_DIGIT_NUMBER : |
365 | 5.47k | return KParseTokens::UNI_DIGIT; |
366 | 3.14k | case U_LETTER_NUMBER : |
367 | 3.14k | return KParseTokens::UNI_LETTER_NUMBER; |
368 | 43.1k | case U_OTHER_NUMBER : |
369 | 43.1k | return KParseTokens::UNI_OTHER_NUMBER; |
370 | 1.44M | } |
371 | | |
372 | 365k | return KParseTokens::UNI_OTHER; |
373 | 1.44M | } |
374 | 42.0M | } |
375 | | |
376 | | void cclass_Unicode::setupInternational( const Locale& rLocale ) |
377 | 26.2k | { |
378 | 26.2k | bool bChanged = (aParserLocale.Language != rLocale.Language |
379 | 25.8k | || aParserLocale.Country != rLocale.Country |
380 | 25.8k | || aParserLocale.Variant != rLocale.Variant); |
381 | 26.2k | if ( bChanged ) |
382 | 431 | { |
383 | 431 | aParserLocale.Language = rLocale.Language; |
384 | 431 | aParserLocale.Country = rLocale.Country; |
385 | 431 | aParserLocale.Variant = rLocale.Variant; |
386 | 431 | } |
387 | 26.2k | if ( !mxLocaleData.is() ) |
388 | 431 | { |
389 | 431 | mxLocaleData.set( LocaleData2::create(m_xContext) ); |
390 | 431 | } |
391 | 26.2k | } |
392 | | |
393 | | |
394 | | void cclass_Unicode::setupParserTable( const Locale& rLocale, sal_Int32 startCharTokenType, |
395 | | const OUString& userDefinedCharactersStart, sal_Int32 contCharTokenType, |
396 | | const OUString& userDefinedCharactersCont ) |
397 | 4.36M | { |
398 | 4.36M | bool bIntlEqual = (rLocale.Language == aParserLocale.Language && |
399 | 4.36M | rLocale.Country == aParserLocale.Country && |
400 | 4.36M | rLocale.Variant == aParserLocale.Variant); |
401 | 4.36M | if ( !pTable || !bIntlEqual || |
402 | 4.36M | startCharTokenType != nStartTypes || |
403 | 4.34M | contCharTokenType != nContTypes || |
404 | 4.34M | userDefinedCharactersStart != aStartChars || |
405 | 4.34M | userDefinedCharactersCont != aContChars ) |
406 | 26.2k | initParserTable( rLocale, startCharTokenType, userDefinedCharactersStart, |
407 | 26.2k | contCharTokenType, userDefinedCharactersCont ); |
408 | 4.36M | } |
409 | | |
410 | | |
411 | | void cclass_Unicode::initParserTable( const Locale& rLocale, sal_Int32 startCharTokenType, |
412 | | const OUString& userDefinedCharactersStart, sal_Int32 contCharTokenType, |
413 | | const OUString& userDefinedCharactersCont ) |
414 | 26.2k | { |
415 | | // (Re)Init |
416 | 26.2k | setupInternational( rLocale ); |
417 | | // Memory of pTable is reused. |
418 | 26.2k | if ( !pTable ) |
419 | 431 | pTable.reset(new ParserFlags[nDefCnt]); |
420 | 26.2k | std::copy_n( pDefaultParserTable, nDefCnt, pTable.get() ); |
421 | | // Start and cont tables only need reallocation if different length. |
422 | 26.2k | if ( pStart && userDefinedCharactersStart.getLength() != aStartChars.getLength() ) |
423 | 7.05k | { |
424 | 7.05k | pStart.reset(); |
425 | 7.05k | } |
426 | 26.2k | if ( pCont && userDefinedCharactersCont.getLength() != aContChars.getLength() ) |
427 | 7.05k | { |
428 | 7.05k | pCont.reset(); |
429 | 7.05k | } |
430 | 26.2k | nStartTypes = startCharTokenType; |
431 | 26.2k | nContTypes = contCharTokenType; |
432 | 26.2k | aStartChars = userDefinedCharactersStart; |
433 | 26.2k | aContChars = userDefinedCharactersCont; |
434 | | |
435 | | // specials |
436 | 26.2k | if( mxLocaleData.is() ) |
437 | 26.2k | { |
438 | 26.2k | LocaleDataItem2 aItem = |
439 | 26.2k | mxLocaleData->getLocaleItem2( aParserLocale ); |
440 | | //!TODO: theoretically separators may be a string, adjustment would have to be |
441 | | //! done here and in parsing and in ::rtl::math::stringToDouble() |
442 | 26.2k | cGroupSep = aItem.thousandSeparator[0]; |
443 | 26.2k | cDecimalSep = aItem.decimalSeparator[0]; |
444 | 26.2k | cDecimalSepAlt = aItem.decimalSeparatorAlternative.toChar(); |
445 | 26.2k | } |
446 | | |
447 | 26.2k | SAL_WARN_IF((nContTypes & KParseTokens::GROUP_SEPARATOR_IN_NUMBER) |
448 | 26.2k | && (nContTypes & KParseTokens::GROUP_SEPARATOR_IN_NUMBER_3), |
449 | 26.2k | "i18npool", "only one GROUP_SEPARATOR_IN_NUMBER* should be used"); |
450 | 26.2k | if (nContTypes & KParseTokens::GROUP_SEPARATOR_IN_NUMBER |
451 | 26.2k | || nContTypes & KParseTokens::GROUP_SEPARATOR_IN_NUMBER_3) |
452 | 415 | { |
453 | 415 | if ( cGroupSep < nDefCnt ) |
454 | 415 | pTable[cGroupSep] |= ParserFlags::VALUE; |
455 | 415 | } |
456 | 25.8k | else |
457 | 25.8k | { |
458 | 25.8k | cGroupSep = 0; |
459 | 25.8k | } |
460 | 26.2k | if ( cDecimalSep < nDefCnt ) |
461 | 26.2k | pTable[cDecimalSep] |= ParserFlags::CHAR_VALUE | ParserFlags::VALUE; |
462 | 26.2k | if ( cDecimalSepAlt && cDecimalSepAlt < nDefCnt ) |
463 | 0 | pTable[cDecimalSepAlt] |= ParserFlags::CHAR_VALUE | ParserFlags::VALUE; |
464 | | |
465 | | // Modify characters according to KParseTokens definitions. |
466 | 26.2k | { |
467 | 26.2k | using namespace KParseTokens; |
468 | 26.2k | sal_uInt8 i; |
469 | | |
470 | 26.2k | if ( !(nStartTypes & ASC_UPALPHA) ) |
471 | 2.53k | for ( i = 65; i < 91; i++ ) |
472 | 2.44k | pTable[i] &= ~ParserFlags::CHAR_WORD; // not allowed as start character |
473 | 26.2k | if ( !(nContTypes & ASC_UPALPHA) ) |
474 | 2.53k | for ( i = 65; i < 91; i++ ) |
475 | 2.44k | pTable[i] &= ~ParserFlags::WORD; // not allowed as cont character |
476 | | |
477 | 26.2k | if ( !(nStartTypes & ASC_LOALPHA) ) |
478 | 103k | for ( i = 97; i < 123; i++ ) |
479 | 99.6k | pTable[i] &= ~ParserFlags::CHAR_WORD; // not allowed as start character |
480 | 26.2k | if ( !(nContTypes & ASC_LOALPHA) ) |
481 | 103k | for ( i = 97; i < 123; i++ ) |
482 | 99.6k | pTable[i] &= ~ParserFlags::WORD; // not allowed as cont character |
483 | | |
484 | 26.2k | if ( nStartTypes & ASC_DIGIT ) |
485 | 82.3k | for ( i = 48; i < 58; i++ ) |
486 | 74.8k | pTable[i] |= ParserFlags::CHAR_WORD; // allowed as start character |
487 | 26.2k | if ( !(nContTypes & ASC_DIGIT) ) |
488 | 105k | for ( i = 48; i < 58; i++ ) |
489 | 96.1k | pTable[i] &= ~ParserFlags::WORD; // not allowed as cont character |
490 | | |
491 | 26.2k | if ( !(nStartTypes & ASC_UNDERSCORE) ) |
492 | 19.3k | pTable[95] &= ~ParserFlags::CHAR_WORD; // not allowed as start character |
493 | 26.2k | if ( !(nContTypes & ASC_UNDERSCORE) ) |
494 | 19.3k | pTable[95] &= ~ParserFlags::WORD; // not allowed as cont character |
495 | | |
496 | 26.2k | if ( nStartTypes & ASC_DOLLAR ) |
497 | 3.33k | pTable[36] |= ParserFlags::CHAR_WORD; // allowed as start character |
498 | 26.2k | if ( nContTypes & ASC_DOLLAR ) |
499 | 3.33k | pTable[36] |= ParserFlags::WORD; // allowed as cont character |
500 | | |
501 | 26.2k | if ( nStartTypes & ASC_DOT ) |
502 | 94 | pTable[46] |= ParserFlags::CHAR_WORD; // allowed as start character |
503 | 26.2k | if ( nContTypes & ASC_DOT ) |
504 | 9.61k | pTable[46] |= ParserFlags::WORD; // allowed as cont character |
505 | | |
506 | 26.2k | if ( nStartTypes & ASC_COLON ) |
507 | 0 | pTable[58] |= ParserFlags::CHAR_WORD; // allowed as start character |
508 | 26.2k | if ( nContTypes & ASC_COLON ) |
509 | 0 | pTable[58] |= ParserFlags::WORD; // allowed as cont character |
510 | | |
511 | 26.2k | if ( nStartTypes & ASC_CONTROL ) |
512 | 0 | for ( i = 1; i < 32; i++ ) |
513 | 0 | pTable[i] |= ParserFlags::CHAR_WORD; // allowed as start character |
514 | 26.2k | if ( nContTypes & ASC_CONTROL ) |
515 | 0 | for ( i = 1; i < 32; i++ ) |
516 | 0 | pTable[i] |= ParserFlags::WORD; // allowed as cont character |
517 | | |
518 | 26.2k | if ( nStartTypes & ASC_ANY_BUT_CONTROL ) |
519 | 0 | for ( i = 32; i < nDefCnt; i++ ) |
520 | 0 | pTable[i] |= ParserFlags::CHAR_WORD; // allowed as start character |
521 | 26.2k | if ( nContTypes & ASC_ANY_BUT_CONTROL ) |
522 | 0 | for ( i = 32; i < nDefCnt; i++ ) |
523 | 0 | pTable[i] |= ParserFlags::WORD; // allowed as cont character |
524 | | |
525 | 26.2k | } |
526 | | |
527 | | // Merge in (positively override with) user defined characters. |
528 | | // StartChars |
529 | 26.2k | sal_Int32 nLen = aStartChars.getLength(); |
530 | 26.2k | if ( nLen ) |
531 | 7.06k | { |
532 | 7.06k | if ( !pStart ) |
533 | 7.06k | pStart.reset(new ParserFlags[ nLen ]); |
534 | 7.06k | const sal_Unicode* p = aStartChars.getStr(); |
535 | 17.5k | for ( sal_Int32 j=0; j<nLen; j++, p++ ) |
536 | 10.4k | { |
537 | 10.4k | pStart[j] = ParserFlags::CHAR_WORD; |
538 | 10.4k | if ( *p < nDefCnt ) |
539 | 10.4k | pTable[*p] |= ParserFlags::CHAR_WORD; |
540 | 10.4k | } |
541 | 7.06k | } |
542 | | // ContChars |
543 | 26.2k | nLen = aContChars.getLength(); |
544 | 26.2k | if ( nLen ) |
545 | 7.06k | { |
546 | 7.06k | if ( !pCont ) |
547 | 7.06k | pCont.reset(new ParserFlags[ nLen ]); |
548 | 7.06k | const sal_Unicode* p = aContChars.getStr(); |
549 | 21.2k | for ( sal_Int32 j=0; j<nLen; j++ ) |
550 | 14.1k | { |
551 | 14.1k | pCont[j] = ParserFlags::WORD; |
552 | 14.1k | if ( *p < nDefCnt ) |
553 | 14.1k | pTable[*p] |= ParserFlags::WORD; |
554 | 14.1k | } |
555 | 7.06k | } |
556 | 26.2k | } |
557 | | |
558 | | |
559 | | void cclass_Unicode::destroyParserTable() |
560 | 624k | { |
561 | 624k | pCont.reset(); |
562 | 624k | pStart.reset(); |
563 | 624k | pTable.reset(); |
564 | 624k | } |
565 | | |
566 | | |
567 | | ParserFlags cclass_Unicode::getFlags(sal_uInt32 const c, const cclass_Unicode::ScanState eState) |
568 | 42.2M | { |
569 | 42.2M | ParserFlags nMask; |
570 | 42.2M | if ( c < nDefCnt ) |
571 | 40.7M | nMask = pTable[ sal_uInt8(c) ]; |
572 | 1.45M | else |
573 | 1.45M | nMask = getFlagsExtended(c, eState); |
574 | 42.2M | switch ( eState ) |
575 | 42.2M | { |
576 | 4.44M | case ssGetChar : |
577 | 4.48M | case ssRewindFromValue : |
578 | 4.48M | case ssIgnoreLeadingInRewind : |
579 | 4.56M | case ssGetWordFirstChar : |
580 | 4.56M | if ( !(nMask & ParserFlags::CHAR_WORD) ) |
581 | 2.78M | { |
582 | 2.78M | nMask |= getStartCharsFlags( c ); |
583 | 2.78M | if ( nMask & ParserFlags::CHAR_WORD ) |
584 | 0 | nMask &= ~ParserFlags::EXCLUDED; |
585 | 2.78M | } |
586 | 4.56M | break; |
587 | 8.77M | case ssGetValue : |
588 | 32.0M | case ssGetWord : |
589 | 32.0M | if ( !(nMask & ParserFlags::WORD) ) |
590 | 4.49M | { |
591 | 4.49M | nMask |= getContCharsFlags( c ); |
592 | 4.49M | if ( nMask & ParserFlags::WORD ) |
593 | 48.1k | nMask &= ~ParserFlags::EXCLUDED; |
594 | 4.49M | } |
595 | 32.0M | break; |
596 | 5.56M | default: |
597 | 5.56M | ; // other cases aren't needed, no compiler warning |
598 | 42.2M | } |
599 | 42.2M | return nMask; |
600 | 42.2M | } |
601 | | |
602 | | |
603 | | ParserFlags cclass_Unicode::getFlagsExtended(sal_uInt32 const c, const cclass_Unicode::ScanState eState) const |
604 | 1.45M | { |
605 | 1.45M | if ( c == cGroupSep ) |
606 | 0 | return ParserFlags::VALUE; |
607 | 1.45M | else if ( c == cDecimalSep ) |
608 | 0 | return ParserFlags::CHAR_VALUE | ParserFlags::VALUE; |
609 | 1.45M | else if ( cDecimalSepAlt && c == cDecimalSepAlt ) |
610 | 0 | return ParserFlags::CHAR_VALUE | ParserFlags::VALUE; |
611 | 1.45M | bool bStart = (eState == ssGetChar || eState == ssGetWordFirstChar || |
612 | 1.18M | eState == ssRewindFromValue || eState == ssIgnoreLeadingInRewind); |
613 | 1.45M | sal_Int32 nTypes = (bStart ? nStartTypes : nContTypes); |
614 | | |
615 | | //! all KParseTokens::UNI_... must be matched |
616 | 1.45M | switch (u_charType(c)) |
617 | 1.45M | { |
618 | 210k | case U_UPPERCASE_LETTER : |
619 | 210k | return (nTypes & KParseTokens::UNI_UPALPHA) ? |
620 | 210k | (bStart ? ParserFlags::CHAR_WORD : ParserFlags::WORD) : |
621 | 210k | ParserFlags::ILLEGAL; |
622 | 542k | case U_LOWERCASE_LETTER : |
623 | 542k | return (nTypes & KParseTokens::UNI_LOALPHA) ? |
624 | 540k | (bStart ? ParserFlags::CHAR_WORD : ParserFlags::WORD) : |
625 | 542k | ParserFlags::ILLEGAL; |
626 | 123 | case U_TITLECASE_LETTER : |
627 | 123 | return (nTypes & KParseTokens::UNI_TITLE_ALPHA) ? |
628 | 123 | (bStart ? ParserFlags::CHAR_WORD : ParserFlags::WORD) : |
629 | 123 | ParserFlags::ILLEGAL; |
630 | 13.1k | case U_MODIFIER_LETTER : |
631 | 13.1k | return (nTypes & KParseTokens::UNI_MODIFIER_LETTER) ? |
632 | 13.0k | (bStart ? ParserFlags::CHAR_WORD : ParserFlags::WORD) : |
633 | 13.1k | ParserFlags::ILLEGAL; |
634 | 127k | case U_NON_SPACING_MARK : |
635 | 131k | case U_COMBINING_SPACING_MARK : |
636 | | // Non_Spacing_Mark can't be a leading character, |
637 | | // nor can a spacing combining mark. |
638 | 131k | if (bStart) |
639 | 41.7k | return ParserFlags::ILLEGAL; |
640 | 89.3k | [[fallthrough]]; // treat it as Other_Letter. |
641 | 253k | case U_OTHER_LETTER : |
642 | 253k | return (nTypes & KParseTokens::UNI_OTHER_LETTER) ? |
643 | 245k | (bStart ? ParserFlags::CHAR_WORD : ParserFlags::WORD) : |
644 | 253k | ParserFlags::ILLEGAL; |
645 | 5.47k | case U_DECIMAL_DIGIT_NUMBER : |
646 | 5.47k | return ((nTypes & KParseTokens::UNI_DIGIT) ? |
647 | 2.23k | (bStart ? ParserFlags::CHAR_WORD : ParserFlags::WORD) : |
648 | 5.47k | ParserFlags::ILLEGAL) | TOKEN_DIGIT_FLAGS; |
649 | 3.14k | case U_LETTER_NUMBER : |
650 | 3.14k | return ((nTypes & KParseTokens::UNI_LETTER_NUMBER) ? |
651 | 634 | (bStart ? ParserFlags::CHAR_WORD : ParserFlags::WORD) : |
652 | 3.14k | ParserFlags::ILLEGAL) | TOKEN_DIGIT_FLAGS; |
653 | 46.6k | case U_OTHER_NUMBER : |
654 | 46.6k | return ((nTypes & KParseTokens::UNI_OTHER_NUMBER) ? |
655 | 46.0k | (bStart ? ParserFlags::CHAR_WORD : ParserFlags::WORD) : |
656 | 46.6k | ParserFlags::ILLEGAL) | TOKEN_DIGIT_FLAGS; |
657 | 33.3k | case U_SPACE_SEPARATOR : |
658 | 33.3k | return ((nTypes & KParseTokens::IGNORE_LEADING_WS) ? |
659 | 33.3k | ParserFlags::CHAR_DONTCARE : (bStart ? ParserFlags::CHAR_WORD : (ParserFlags::CHAR_DONTCARE | ParserFlags::WORD_SEP | ParserFlags::VALUE_SEP) )); |
660 | 52.4k | case U_OTHER_PUNCTUATION: |
661 | | // fdo#61754 Let's see (if we not at the start) if this is midletter |
662 | | // punctuation and allow it in a word if it is similarly to |
663 | | // U_NON_SPACING_MARK, for example U+00B7 MIDDLE DOT. |
664 | | // tdf#123575 for U+30FB KATAKANA MIDDLE DOT property is not |
665 | | // U_WB_MIDLETTER but U_WB_KATAKANA instead, explicitly test that |
666 | | // and U+FF65 HALFWIDTH KATAKANA MIDDLE DOT. |
667 | 52.4k | if (bStart || (U_WB_MIDLETTER != u_getIntPropertyValue(c, UCHAR_WORD_BREAK) |
668 | 36.6k | && c != 0x30FB && c != 0xFF65)) |
669 | 47.1k | return ParserFlags::ILLEGAL; |
670 | 5.35k | else |
671 | 5.35k | { |
672 | | //allowing it to continue the word |
673 | 5.35k | return (nTypes & KParseTokens::UNI_OTHER_LETTER) ? |
674 | 5.35k | ParserFlags::WORD : ParserFlags::ILLEGAL; |
675 | 5.35k | } |
676 | 0 | break; |
677 | 1.53k | case U_START_PUNCTUATION: |
678 | | // left angle, double angle and corner brackets |
679 | 1.53k | if (c != 0x3008 && c != 0x300a && c != 0x300c && c != 0x300e) |
680 | 933 | return ParserFlags::ILLEGAL; |
681 | 602 | return bStart ? ParserFlags::CHAR_WORD : ParserFlags::WORD; |
682 | 4.32k | case U_END_PUNCTUATION: |
683 | | // right angle, double angle and corner brackets |
684 | 4.32k | if (c != 0x3009 && c != 0x300b && c != 0x300d && c != 0x300f) |
685 | 2.57k | return ParserFlags::ILLEGAL; |
686 | 1.74k | return bStart ? ParserFlags::CHAR_WORD : ParserFlags::WORD; |
687 | 4.69k | case U_INITIAL_PUNCTUATION: |
688 | | // left single / double quotation marks |
689 | 4.69k | if (c != 0x2018 && c != 0x201c) |
690 | 3.80k | return ParserFlags::ILLEGAL; |
691 | 892 | return bStart ? ParserFlags::CHAR_WORD : ParserFlags::WORD; |
692 | 4.24k | case U_FINAL_PUNCTUATION: |
693 | | // right single / double quotation marks |
694 | 4.24k | if (c != 0x2019 && c != 0x201d) |
695 | 1.88k | return ParserFlags::ILLEGAL; |
696 | 2.35k | return bStart ? ParserFlags::CHAR_WORD : ParserFlags::WORD; |
697 | 1.45M | } |
698 | | |
699 | 238k | return ParserFlags::ILLEGAL; |
700 | 1.45M | } |
701 | | |
702 | | |
703 | | ParserFlags cclass_Unicode::getStartCharsFlags( sal_uInt32 c ) |
704 | 2.78M | { |
705 | 2.78M | if ( pStart ) |
706 | 721k | { |
707 | 721k | const sal_Unicode* pStr = aStartChars.getStr(); |
708 | 721k | const sal_Unicode* p = StrChr( pStr, c ); |
709 | 721k | if ( p ) |
710 | 0 | return pStart[ p - pStr ]; |
711 | 721k | } |
712 | 2.78M | return ParserFlags::ILLEGAL; |
713 | 2.78M | } |
714 | | |
715 | | |
716 | | ParserFlags cclass_Unicode::getContCharsFlags( sal_Unicode c ) |
717 | 4.49M | { |
718 | 4.49M | if ( pCont ) |
719 | 1.61M | { |
720 | 1.61M | const sal_Unicode* pStr = aContChars.getStr(); |
721 | 1.61M | const sal_Unicode* p = StrChr( pStr, c ); |
722 | 1.61M | if ( p ) |
723 | 48.1k | return pCont[ p - pStr ]; |
724 | 1.61M | } |
725 | 4.44M | return ParserFlags::ILLEGAL; |
726 | 4.49M | } |
727 | | |
728 | | |
729 | | void cclass_Unicode::parseText( ParseResult& r, const OUString& rText, sal_Int32 nPos, sal_Int32 nTokenType ) |
730 | 4.36M | { |
731 | 4.36M | assert(r.LeadingWhiteSpace == 0); |
732 | 4.36M | ScanState eState = ssGetChar; |
733 | | |
734 | | //! All the variables below (plus ParseResult) have to be reset on ssRewindFromValue! |
735 | 4.36M | OUStringBuffer aSymbol; |
736 | 4.36M | bool isFirst(true); |
737 | 4.36M | sal_Int32 index(nPos); // index of next code point after current |
738 | 4.36M | sal_Int32 postSymbolIndex(index); // index of code point following last quote |
739 | 4.36M | sal_uInt32 current((index < rText.getLength()) ? rText.iterateCodePoints(&index) : 0); |
740 | 4.36M | sal_uInt32 cLast = 0; |
741 | 4.36M | sal_Int32 nCodePoints(0); |
742 | 4.36M | int nDecSeps = 0; |
743 | 4.36M | bool bQuote = false; |
744 | 4.36M | bool bMightBeWord = true; |
745 | 4.36M | bool bMightBeWordLast = true; |
746 | 4.36M | bool bDecSepAltUsed = false; |
747 | | //! All the variables above (plus ParseResult) have to be reset on ssRewindFromValue! |
748 | 4.36M | sal_Int32 nextCharIndex(nPos); // == index of nextChar |
749 | | |
750 | 46.4M | while ((current != 0) && (eState != ssStop)) |
751 | 42.0M | { |
752 | 42.0M | ++nCodePoints; |
753 | 42.0M | ParserFlags nMask = getFlags(current, eState); |
754 | 42.0M | if ( nMask & ParserFlags::EXCLUDED ) |
755 | 0 | eState = ssBounce; |
756 | 42.0M | if ( bMightBeWord ) |
757 | 25.4M | { // only relevant for ssGetValue fall back |
758 | 25.4M | if ( eState == ssGetChar || eState == ssRewindFromValue || |
759 | 20.9M | eState == ssIgnoreLeadingInRewind ) |
760 | 4.48M | bMightBeWord = bool(nMask & ParserFlags::CHAR_WORD); |
761 | 20.9M | else |
762 | 20.9M | bMightBeWord = bool(nMask & ParserFlags::WORD); |
763 | 25.4M | } |
764 | 42.0M | sal_Int32 nParseTokensType = getParseTokensType(current, isFirst); |
765 | 42.0M | isFirst = false; |
766 | 42.0M | sal_Int32 const nextIndex(nextCharIndex); // == index of char following current |
767 | 42.0M | nextCharIndex = index; // == index of nextChar |
768 | 42.0M | sal_uInt32 nextChar((index < rText.getLength()) ? rText.iterateCodePoints(&index) : 0); |
769 | 42.0M | switch (eState) |
770 | 42.0M | { |
771 | 4.44M | case ssGetChar : |
772 | 4.48M | case ssRewindFromValue : |
773 | 4.48M | case ssIgnoreLeadingInRewind : |
774 | 4.48M | { |
775 | 4.48M | if ( (nMask & ParserFlags::CHAR_VALUE) && eState != ssRewindFromValue |
776 | 1.07M | && eState != ssIgnoreLeadingInRewind ) |
777 | 1.07M | { //! must be first, may fall back to ssGetWord via bMightBeWord |
778 | 1.07M | eState = ssGetValue; |
779 | 1.07M | if ( nMask & ParserFlags::VALUE_DIGIT ) |
780 | 878k | { |
781 | 878k | if (128 <= current) |
782 | 7.29k | r.TokenType = KParseType::UNI_NUMBER; |
783 | 871k | else |
784 | 871k | r.TokenType = KParseType::ASC_NUMBER; |
785 | 878k | } |
786 | 191k | else if (current == cDecimalSep || (bDecSepAltUsed = (cDecimalSepAlt && current == cDecimalSepAlt))) |
787 | 191k | { |
788 | 191k | if (nextChar) |
789 | 186k | ++nDecSeps; |
790 | 4.58k | else |
791 | 4.58k | eState = ssRewindFromValue; |
792 | | // retry for ONE_SINGLE_CHAR or others |
793 | 191k | } |
794 | 1.07M | } |
795 | 3.41M | else if ( nMask & ParserFlags::CHAR_WORD ) |
796 | 859k | { |
797 | 859k | eState = ssGetWord; |
798 | 859k | r.TokenType = KParseType::IDENTNAME; |
799 | 859k | } |
800 | 2.55M | else if ( nMask & ParserFlags::NAME_SEP ) |
801 | 112k | { |
802 | 112k | eState = ssGetWordFirstChar; |
803 | 112k | bQuote = true; |
804 | 112k | postSymbolIndex = nextCharIndex; |
805 | 112k | nParseTokensType = 0; // will be taken of first real character |
806 | 112k | r.TokenType = KParseType::SINGLE_QUOTE_NAME; |
807 | 112k | } |
808 | 2.44M | else if ( nMask & ParserFlags::CHAR_STRING ) |
809 | 125k | { |
810 | 125k | eState = ssGetString; |
811 | 125k | postSymbolIndex = nextCharIndex; |
812 | 125k | nParseTokensType = 0; // will be taken of first real character |
813 | 125k | r.TokenType = KParseType::DOUBLE_QUOTE_STRING; |
814 | 125k | } |
815 | 2.31M | else if ( nMask & ParserFlags::CHAR_DONTCARE ) |
816 | 75.7k | { |
817 | 75.7k | if ( nStartTypes & KParseTokens::IGNORE_LEADING_WS ) |
818 | 73.5k | { |
819 | 73.5k | if (eState == ssRewindFromValue) |
820 | 0 | eState = ssIgnoreLeadingInRewind; |
821 | 73.5k | r.LeadingWhiteSpace = nextCharIndex - nPos; |
822 | 73.5k | nCodePoints--; // exclude leading whitespace |
823 | 73.5k | postSymbolIndex = nextCharIndex; |
824 | 73.5k | nParseTokensType = 0; // wait until real character |
825 | 73.5k | bMightBeWord = true; |
826 | 73.5k | } |
827 | 2.23k | else |
828 | 2.23k | eState = ssBounce; |
829 | 75.7k | } |
830 | 2.24M | else if ( nMask & ParserFlags::CHAR_BOOL ) |
831 | 389k | { |
832 | 389k | eState = ssGetBool; |
833 | 389k | r.TokenType = KParseType::BOOLEAN; |
834 | 389k | } |
835 | 1.85M | else if ( nMask & ParserFlags::CHAR ) |
836 | 1.24M | { //! must be last |
837 | 1.24M | eState = ssStop; |
838 | 1.24M | r.TokenType = KParseType::ONE_SINGLE_CHAR; |
839 | 1.24M | } |
840 | 611k | else |
841 | 611k | eState = ssBounce; // not known |
842 | 4.48M | } |
843 | 4.48M | break; |
844 | 8.63M | case ssGetValue : |
845 | 8.63M | { |
846 | 8.63M | if ( nMask & ParserFlags::VALUE_DIGIT ) |
847 | 7.41M | { |
848 | 7.41M | if (128 <= current) |
849 | 14.0k | r.TokenType = KParseType::UNI_NUMBER; |
850 | 7.40M | else if ( r.TokenType != KParseType::UNI_NUMBER ) |
851 | 7.38M | r.TokenType = KParseType::ASC_NUMBER; |
852 | 7.41M | } |
853 | 8.63M | if ( nMask & ParserFlags::VALUE ) |
854 | 7.60M | { |
855 | 7.60M | if (current == cGroupSep) |
856 | 11.3k | { |
857 | | // depending or requested nContTypes, accept only if |
858 | | // it is followed by 3 digits |
859 | 11.3k | sal_Int32 tempIndex(index); |
860 | 11.3k | sal_uInt32 const nextChar2((tempIndex < rText.getLength()) ? rText.iterateCodePoints(&tempIndex) : 0); |
861 | 11.3k | sal_uInt32 const nextChar3((tempIndex < rText.getLength()) ? rText.iterateCodePoints(&tempIndex) : 0); |
862 | 11.3k | if ((nContTypes & KParseTokens::GROUP_SEPARATOR_IN_NUMBER_3) |
863 | 0 | && getFlags(nextChar, eState) & ParserFlags::VALUE_DIGIT |
864 | 0 | && getFlags(nextChar2, eState) & ParserFlags::VALUE_DIGIT |
865 | 0 | && getFlags(nextChar3, eState) & ParserFlags::VALUE_DIGIT) |
866 | 0 | { |
867 | 0 | nParseTokensType |= KParseTokens::GROUP_SEPARATOR_IN_NUMBER_3; |
868 | 0 | } |
869 | 11.3k | else if ((nContTypes & KParseTokens::GROUP_SEPARATOR_IN_NUMBER_3) == 0 |
870 | 11.3k | && getFlags(nextChar, eState) & ParserFlags::VALUE_DIGIT) |
871 | 8.58k | { |
872 | 8.58k | nParseTokensType |= KParseTokens::GROUP_SEPARATOR_IN_NUMBER; |
873 | 8.58k | } |
874 | 2.80k | else |
875 | 2.80k | { |
876 | | // Trailing group separator character is not a |
877 | | // group separator. |
878 | 2.80k | eState = ssStopBack; |
879 | 2.80k | } |
880 | 11.3k | } |
881 | 7.59M | else if ((current == cDecimalSep || |
882 | 7.41M | (bDecSepAltUsed = (cDecimalSepAlt && current == cDecimalSepAlt))) && |
883 | 179k | ++nDecSeps > 1) |
884 | 75.4k | { |
885 | 75.4k | if (nCodePoints == 2) |
886 | 38.9k | eState = ssRewindFromValue; |
887 | | // consecutive separators |
888 | 36.5k | else |
889 | 36.5k | eState = ssStopBack; |
890 | 75.4k | } |
891 | | // else keep it going |
892 | 7.60M | } |
893 | 1.02M | else if (current == 'E' || current == 'e') |
894 | 90.6k | { |
895 | 90.6k | ParserFlags nNext = getFlags(nextChar, eState); |
896 | 90.6k | if ( nNext & ParserFlags::VALUE_EXP ) |
897 | 60.9k | ; // keep it going |
898 | 29.7k | else if (bMightBeWord && ((nNext & ParserFlags::WORD) || !nextChar)) |
899 | 17.6k | { // might be a numerical name (1.2efg) |
900 | 17.6k | eState = ssGetWord; |
901 | 17.6k | r.TokenType = KParseType::IDENTNAME; |
902 | 17.6k | } |
903 | 12.1k | else |
904 | 12.1k | eState = ssStopBack; |
905 | 90.6k | } |
906 | 932k | else if ( nMask & ParserFlags::VALUE_SIGN ) |
907 | 58.9k | { |
908 | 58.9k | if ( (cLast == 'E') || (cLast == 'e') ) |
909 | 37.8k | { |
910 | 37.8k | ParserFlags nNext = getFlags(nextChar, eState); |
911 | 37.8k | if ( nNext & ParserFlags::VALUE_EXP_VALUE ) |
912 | 34.9k | ; // keep it going |
913 | 2.83k | else if (bMightBeWord && ((nNext & ParserFlags::WORD) || !nextChar)) |
914 | 0 | { // might be a numerical name (1.2e+fg) |
915 | 0 | eState = ssGetWord; |
916 | 0 | r.TokenType = KParseType::IDENTNAME; |
917 | 0 | } |
918 | 2.83k | else |
919 | 2.83k | eState = ssStopBack; |
920 | 37.8k | } |
921 | 21.1k | else if ( bMightBeWord ) |
922 | 0 | { // might be a numerical name (1.2+fg) |
923 | 0 | eState = ssGetWord; |
924 | 0 | r.TokenType = KParseType::IDENTNAME; |
925 | 0 | } |
926 | 21.1k | else |
927 | 21.1k | eState = ssStopBack; |
928 | 58.9k | } |
929 | 873k | else if ( bMightBeWord && (nMask & ParserFlags::WORD) ) |
930 | 300k | { // might be a numerical name (1995.A1) |
931 | 300k | eState = ssGetWord; |
932 | 300k | r.TokenType = KParseType::IDENTNAME; |
933 | 300k | } |
934 | 573k | else |
935 | 573k | eState = ssStopBack; |
936 | 8.63M | } |
937 | 8.63M | break; |
938 | 83.0k | case ssGetWordFirstChar : |
939 | 83.0k | eState = ssGetWord; |
940 | 83.0k | [[fallthrough]]; |
941 | 23.3M | case ssGetWord : |
942 | 23.3M | { |
943 | 23.3M | if ( nMask & ParserFlags::WORD ) |
944 | 19.5M | ; // keep it going |
945 | 3.85M | else if ( nMask & ParserFlags::NAME_SEP ) |
946 | 170k | { |
947 | 170k | if ( bQuote ) |
948 | 40.1k | { |
949 | 40.1k | if ( cLast == '\\' ) |
950 | 834 | { // escaped |
951 | 834 | aSymbol.append( |
952 | 834 | OUString::Concat(rText.subView(postSymbolIndex, nextCharIndex - postSymbolIndex - 2)) |
953 | 834 | + OUString(¤t, 1)); |
954 | 834 | } |
955 | 39.3k | else |
956 | 39.3k | { |
957 | 39.3k | eState = ssStop; |
958 | 39.3k | aSymbol.append(rText.subView(postSymbolIndex, nextCharIndex - postSymbolIndex - 1)); |
959 | 39.3k | } |
960 | 40.1k | postSymbolIndex = nextCharIndex; |
961 | 40.1k | } |
962 | 130k | else |
963 | 130k | eState = ssStopBack; |
964 | 170k | } |
965 | 3.68M | else if ( bQuote ) |
966 | 2.80M | ; // keep it going |
967 | 880k | else |
968 | 880k | eState = ssStopBack; |
969 | 23.3M | } |
970 | 23.3M | break; |
971 | 5.36M | case ssGetString : |
972 | 5.36M | { |
973 | 5.36M | if ( nMask & ParserFlags::STRING_SEP ) |
974 | 70.1k | { |
975 | 70.1k | if ( cLast == '\\' ) |
976 | 2.21k | { // escaped |
977 | 2.21k | aSymbol.append( |
978 | 2.21k | rText.subView(postSymbolIndex, nextCharIndex - postSymbolIndex - 2) |
979 | 2.21k | + OUString(¤t, 1)); |
980 | 2.21k | } |
981 | 67.8k | else if (current == nextChar && |
982 | 5.92k | !(nContTypes & KParseTokens::TWO_DOUBLE_QUOTES_BREAK_STRING) ) |
983 | 5.01k | { // "" => literal " escaped |
984 | 5.01k | aSymbol.append(rText.subView(postSymbolIndex, nextCharIndex - postSymbolIndex)); |
985 | 5.01k | nextCharIndex = index; |
986 | 5.01k | if (index < rText.getLength()) { ++nCodePoints; } |
987 | 5.01k | nextChar = (index < rText.getLength()) ? rText.iterateCodePoints(&index) : 0; |
988 | 5.01k | } |
989 | 62.8k | else |
990 | 62.8k | { |
991 | 62.8k | eState = ssStop; |
992 | 62.8k | aSymbol.append(rText.subView(postSymbolIndex, nextCharIndex - postSymbolIndex - 1)); |
993 | 62.8k | } |
994 | 70.1k | postSymbolIndex = nextCharIndex; |
995 | 70.1k | } |
996 | 5.36M | } |
997 | 5.36M | break; |
998 | 197k | case ssGetBool : |
999 | 197k | { |
1000 | 197k | if ( nMask & ParserFlags::BOOL ) |
1001 | 43.2k | eState = ssStop; // maximum 2: <, >, <>, <=, >= |
1002 | 153k | else |
1003 | 153k | eState = ssStopBack; |
1004 | 197k | } |
1005 | 197k | break; |
1006 | 0 | case ssStopBack : |
1007 | 0 | case ssBounce : |
1008 | 0 | case ssStop : |
1009 | 0 | ; // nothing, no compiler warning |
1010 | 0 | break; |
1011 | 42.0M | } |
1012 | 42.0M | if ( eState == ssRewindFromValue ) |
1013 | 43.5k | { |
1014 | 43.5k | r = ParseResult(); |
1015 | 43.5k | index = nPos; |
1016 | 43.5k | postSymbolIndex = nPos; |
1017 | 43.5k | nextCharIndex = nPos; |
1018 | 43.5k | aSymbol.setLength(0); |
1019 | 43.5k | current = (index < rText.getLength()) ? rText.iterateCodePoints(&index) : 0; |
1020 | 43.5k | nCodePoints = (nPos < rText.getLength()) ? 1 : 0; |
1021 | 43.5k | isFirst = true; |
1022 | 43.5k | cLast = 0; |
1023 | 43.5k | nDecSeps = 0; |
1024 | 43.5k | bQuote = false; |
1025 | 43.5k | bMightBeWord = true; |
1026 | 43.5k | bMightBeWordLast = true; |
1027 | 43.5k | bDecSepAltUsed = false; |
1028 | 43.5k | } |
1029 | 42.0M | else |
1030 | 42.0M | { |
1031 | 42.0M | if ( !(r.TokenType & nTokenType) ) |
1032 | 1.61M | { |
1033 | 1.61M | if ( (r.TokenType & (KParseType::ASC_NUMBER | KParseType::UNI_NUMBER)) |
1034 | 828 | && (nTokenType & KParseType::IDENTNAME) && bMightBeWord ) |
1035 | 0 | ; // keep a number that might be a word |
1036 | 1.61M | else if (r.LeadingWhiteSpace == (nextCharIndex - nPos)) |
1037 | 73.5k | ; // keep ignored white space |
1038 | 1.54M | else if ( !r.TokenType && eState == ssGetValue && (nMask & ParserFlags::VALUE_SEP) ) |
1039 | 186k | ; // keep uncertain value |
1040 | 1.35M | else |
1041 | 1.35M | eState = ssBounce; |
1042 | 1.61M | } |
1043 | 42.0M | if ( eState == ssBounce ) |
1044 | 1.35M | { |
1045 | 1.35M | r.TokenType = 0; |
1046 | 1.35M | eState = ssStopBack; |
1047 | 1.35M | } |
1048 | 42.0M | if ( eState == ssStopBack ) |
1049 | 3.13M | { // put back |
1050 | 3.13M | nextChar = rText.iterateCodePoints(&index, -1); |
1051 | 3.13M | nextCharIndex = nextIndex; |
1052 | 3.13M | --nCodePoints; |
1053 | 3.13M | bMightBeWord = bMightBeWordLast; |
1054 | 3.13M | eState = ssStop; |
1055 | 3.13M | } |
1056 | 42.0M | if ( eState != ssStop ) |
1057 | 37.9M | { |
1058 | 37.9M | if ( !r.StartFlags ) |
1059 | 2.48M | r.StartFlags |= nParseTokensType; |
1060 | 35.4M | else |
1061 | 35.4M | r.ContFlags |= nParseTokensType; |
1062 | 37.9M | } |
1063 | 42.0M | bMightBeWordLast = bMightBeWord; |
1064 | 42.0M | cLast = current; |
1065 | 42.0M | current = nextChar; |
1066 | 42.0M | } |
1067 | 42.0M | } |
1068 | | // r.CharLen is the length in characters (not code units) of the parsed |
1069 | | // token not including any leading white space. |
1070 | 4.36M | r.CharLen = nCodePoints; |
1071 | 4.36M | r.EndPos = nextCharIndex; |
1072 | 4.36M | if ( r.TokenType & KParseType::ASC_NUMBER ) |
1073 | 660k | { |
1074 | 660k | r.Value = rtl_math_uStringToDouble(rText.getStr() + nPos + r.LeadingWhiteSpace, |
1075 | 660k | rText.getStr() + r.EndPos, (bDecSepAltUsed ? cDecimalSepAlt : cDecimalSep), cGroupSep, nullptr, nullptr); |
1076 | 660k | if ( bMightBeWord ) |
1077 | 522k | r.TokenType |= KParseType::IDENTNAME; |
1078 | 660k | } |
1079 | 3.70M | else if ( r.TokenType & KParseType::UNI_NUMBER ) |
1080 | 9.27k | { |
1081 | 9.27k | if ( !xNatNumSup.is() ) |
1082 | 12 | { |
1083 | 12 | if ( m_xContext.is() ) |
1084 | 12 | { |
1085 | 12 | xNatNumSup = NativeNumberSupplier::create( m_xContext ); |
1086 | 12 | } |
1087 | 12 | } |
1088 | 9.27k | OUString aTmp(rText.getStr() + nPos + r.LeadingWhiteSpace, |
1089 | 9.27k | r.EndPos - nPos - r.LeadingWhiteSpace); |
1090 | | // transliterate to ASCII |
1091 | 9.27k | aTmp = xNatNumSup->getNativeNumberString( aTmp, aParserLocale, |
1092 | 9.27k | NativeNumberMode::NATNUM0 ); |
1093 | 9.27k | r.Value = ::rtl::math::stringToDouble( aTmp, cDecimalSep, cGroupSep ); |
1094 | 9.27k | if ( bMightBeWord ) |
1095 | 6.53k | r.TokenType |= KParseType::IDENTNAME; |
1096 | 9.27k | } |
1097 | 3.70M | else if ( r.TokenType & (KParseType::SINGLE_QUOTE_NAME | KParseType::DOUBLE_QUOTE_STRING) ) |
1098 | 157k | { |
1099 | 157k | if (postSymbolIndex < nextCharIndex) |
1100 | 44.6k | { //! open quote |
1101 | 44.6k | aSymbol.append(rText.subView(postSymbolIndex, nextCharIndex - postSymbolIndex - 1)); |
1102 | 44.6k | r.TokenType |= KParseType::MISSING_QUOTE; |
1103 | 44.6k | } |
1104 | 157k | r.DequotedNameOrString = aSymbol.makeStringAndClear(); |
1105 | 157k | } |
1106 | 4.36M | } |
1107 | | |
1108 | | } |
1109 | | |
1110 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |