1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is TransforMiiX XSLT processor code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Jonas Sicking.
19 : * Portions created by the Initial Developer are Copyright (C) 2002
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Jonas Sicking <sicking@bigfoot.com>
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either the GNU General Public License Version 2 or later (the "GPL"), or
27 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : #include "txXSLTNumber.h"
40 : #include "nsGkAtoms.h"
41 : #include "txCore.h"
42 : #include <math.h>
43 : #include "txExpr.h"
44 : #include "txXSLTPatterns.h"
45 : #include "txIXPathContext.h"
46 : #include "txXPathTreeWalker.h"
47 :
48 0 : nsresult txXSLTNumber::createNumber(Expr* aValueExpr, txPattern* aCountPattern,
49 : txPattern* aFromPattern, LevelType aLevel,
50 : Expr* aGroupSize, Expr* aGroupSeparator,
51 : Expr* aFormat, txIEvalContext* aContext,
52 : nsAString& aResult)
53 : {
54 0 : aResult.Truncate();
55 0 : nsresult rv = NS_OK;
56 :
57 : // Parse format
58 0 : txList counters;
59 0 : nsAutoString head, tail;
60 : rv = getCounters(aGroupSize, aGroupSeparator, aFormat, aContext, counters,
61 0 : head, tail);
62 0 : NS_ENSURE_SUCCESS(rv, rv);
63 :
64 : // Create list of values to format
65 0 : txList values;
66 0 : nsAutoString valueString;
67 : rv = getValueList(aValueExpr, aCountPattern, aFromPattern, aLevel,
68 0 : aContext, values, valueString);
69 0 : NS_ENSURE_SUCCESS(rv, rv);
70 :
71 0 : if (!valueString.IsEmpty()) {
72 0 : aResult = valueString;
73 :
74 0 : return NS_OK;
75 : }
76 :
77 : // Create resulting string
78 0 : aResult = head;
79 0 : bool first = true;
80 0 : txListIterator valueIter(&values);
81 0 : txListIterator counterIter(&counters);
82 0 : valueIter.resetToEnd();
83 : PRInt32 value;
84 0 : txFormattedCounter* counter = 0;
85 0 : while ((value = NS_PTR_TO_INT32(valueIter.previous()))) {
86 0 : if (counterIter.hasNext()) {
87 0 : counter = (txFormattedCounter*)counterIter.next();
88 : }
89 :
90 0 : if (!first) {
91 0 : aResult.Append(counter->mSeparator);
92 : }
93 :
94 0 : counter->appendNumber(value, aResult);
95 0 : first = false;
96 : }
97 :
98 0 : aResult.Append(tail);
99 :
100 0 : txListIterator iter(&counters);
101 0 : while (iter.hasNext()) {
102 0 : delete (txFormattedCounter*)iter.next();
103 : }
104 :
105 0 : return NS_OK;
106 : }
107 :
108 : nsresult
109 0 : txXSLTNumber::getValueList(Expr* aValueExpr, txPattern* aCountPattern,
110 : txPattern* aFromPattern, LevelType aLevel,
111 : txIEvalContext* aContext, txList& aValues,
112 : nsAString& aValueString)
113 : {
114 0 : aValueString.Truncate();
115 0 : nsresult rv = NS_OK;
116 :
117 : // If the value attribute exists then use that
118 0 : if (aValueExpr) {
119 0 : nsRefPtr<txAExprResult> result;
120 0 : rv = aValueExpr->evaluate(aContext, getter_AddRefs(result));
121 0 : NS_ENSURE_SUCCESS(rv, rv);
122 :
123 0 : double value = result->numberValue();
124 :
125 0 : if (txDouble::isInfinite(value) || txDouble::isNaN(value) ||
126 : value < 0.5) {
127 0 : txDouble::toString(value, aValueString);
128 0 : return NS_OK;
129 : }
130 :
131 0 : aValues.add(NS_INT32_TO_PTR((PRInt32)floor(value + 0.5)));
132 0 : return NS_OK;
133 : }
134 :
135 :
136 : // Otherwise use count/from/level
137 :
138 0 : txPattern* countPattern = aCountPattern;
139 0 : bool ownsCountPattern = false;
140 0 : const txXPathNode& currNode = aContext->getContextNode();
141 :
142 : // Parse count- and from-attributes
143 :
144 0 : if (!aCountPattern) {
145 0 : ownsCountPattern = true;
146 : txNodeTest* nodeTest;
147 0 : PRUint16 nodeType = txXPathNodeUtils::getNodeType(currNode);
148 0 : switch (nodeType) {
149 : case txXPathNodeType::ELEMENT_NODE:
150 : {
151 : nsCOMPtr<nsIAtom> localName =
152 0 : txXPathNodeUtils::getLocalName(currNode);
153 0 : PRInt32 namespaceID = txXPathNodeUtils::getNamespaceID(currNode);
154 : nodeTest = new txNameTest(0, localName, namespaceID,
155 0 : txXPathNodeType::ELEMENT_NODE);
156 : break;
157 : }
158 : case txXPathNodeType::TEXT_NODE:
159 : case txXPathNodeType::CDATA_SECTION_NODE:
160 : {
161 0 : nodeTest = new txNodeTypeTest(txNodeTypeTest::TEXT_TYPE);
162 0 : break;
163 : }
164 : case txXPathNodeType::PROCESSING_INSTRUCTION_NODE:
165 : {
166 : txNodeTypeTest* typeTest;
167 0 : typeTest = new txNodeTypeTest(txNodeTypeTest::PI_TYPE);
168 0 : if (typeTest) {
169 0 : nsAutoString nodeName;
170 0 : txXPathNodeUtils::getNodeName(currNode, nodeName);
171 0 : typeTest->setNodeName(nodeName);
172 : }
173 0 : nodeTest = typeTest;
174 0 : break;
175 : }
176 : case txXPathNodeType::COMMENT_NODE:
177 : {
178 0 : nodeTest = new txNodeTypeTest(txNodeTypeTest::COMMENT_TYPE);
179 0 : break;
180 : }
181 : case txXPathNodeType::DOCUMENT_NODE:
182 : case txXPathNodeType::ATTRIBUTE_NODE:
183 : default:
184 : {
185 : // this won't match anything as we walk up the tree
186 : // but it's what the spec says to do
187 : nodeTest = new txNameTest(0, nsGkAtoms::_asterix, 0,
188 0 : nodeType);
189 0 : break;
190 : }
191 : }
192 0 : NS_ENSURE_TRUE(nodeTest, NS_ERROR_OUT_OF_MEMORY);
193 :
194 0 : countPattern = new txStepPattern(nodeTest, false);
195 0 : if (!countPattern) {
196 : // XXX error reporting
197 0 : delete nodeTest;
198 0 : return NS_ERROR_OUT_OF_MEMORY;
199 : }
200 : }
201 :
202 :
203 : // Generate list of values depending on the value of the level-attribute
204 :
205 : // level = "single"
206 0 : if (aLevel == eLevelSingle) {
207 0 : txXPathTreeWalker walker(currNode);
208 0 : do {
209 0 : if (aFromPattern && !walker.isOnNode(currNode) &&
210 0 : aFromPattern->matches(walker.getCurrentPosition(), aContext)) {
211 0 : break;
212 : }
213 :
214 0 : if (countPattern->matches(walker.getCurrentPosition(), aContext)) {
215 0 : aValues.add(NS_INT32_TO_PTR(getSiblingCount(walker, countPattern,
216 0 : aContext)));
217 0 : break;
218 : }
219 :
220 : } while (walker.moveToParent());
221 :
222 : // Spec says to only match ancestors that are decendants of the
223 : // ancestor that matches the from-pattern, so keep going to make
224 : // sure that there is an ancestor that does.
225 0 : if (aFromPattern && aValues.getLength()) {
226 : bool hasParent;
227 0 : while ((hasParent = walker.moveToParent())) {
228 0 : if (aFromPattern->matches(walker.getCurrentPosition(), aContext)) {
229 0 : break;
230 : }
231 : }
232 :
233 0 : if (!hasParent) {
234 0 : aValues.clear();
235 : }
236 : }
237 : }
238 : // level = "multiple"
239 0 : else if (aLevel == eLevelMultiple) {
240 : // find all ancestor-or-selfs that matches count until...
241 0 : txXPathTreeWalker walker(currNode);
242 0 : bool matchedFrom = false;
243 0 : do {
244 0 : if (aFromPattern && !walker.isOnNode(currNode) &&
245 0 : aFromPattern->matches(walker.getCurrentPosition(), aContext)) {
246 : //... we find one that matches from
247 0 : matchedFrom = true;
248 0 : break;
249 : }
250 :
251 0 : if (countPattern->matches(walker.getCurrentPosition(), aContext)) {
252 0 : aValues.add(NS_INT32_TO_PTR(getSiblingCount(walker, countPattern,
253 0 : aContext)));
254 : }
255 : } while (walker.moveToParent());
256 :
257 : // Spec says to only match ancestors that are decendants of the
258 : // ancestor that matches the from-pattern, so if none did then
259 : // we shouldn't search anything
260 0 : if (aFromPattern && !matchedFrom) {
261 0 : aValues.clear();
262 : }
263 : }
264 : // level = "any"
265 0 : else if (aLevel == eLevelAny) {
266 0 : PRInt32 value = 0;
267 0 : bool matchedFrom = false;
268 :
269 0 : txXPathTreeWalker walker(currNode);
270 0 : do {
271 0 : if (aFromPattern && !walker.isOnNode(currNode) &&
272 0 : aFromPattern->matches(walker.getCurrentPosition(), aContext)) {
273 0 : matchedFrom = true;
274 0 : break;
275 : }
276 :
277 0 : if (countPattern->matches(walker.getCurrentPosition(), aContext)) {
278 0 : ++value;
279 : }
280 :
281 : } while (getPrevInDocumentOrder(walker));
282 :
283 : // Spec says to only count nodes that follows the first node that
284 : // matches the from pattern. So so if none did then we shouldn't
285 : // count any
286 0 : if (aFromPattern && !matchedFrom) {
287 0 : value = 0;
288 : }
289 :
290 0 : if (value) {
291 0 : aValues.add(NS_INT32_TO_PTR(value));
292 : }
293 : }
294 :
295 0 : if (ownsCountPattern) {
296 0 : delete countPattern;
297 : }
298 :
299 0 : return NS_OK;
300 : }
301 :
302 :
303 : nsresult
304 0 : txXSLTNumber::getCounters(Expr* aGroupSize, Expr* aGroupSeparator,
305 : Expr* aFormat, txIEvalContext* aContext,
306 : txList& aCounters, nsAString& aHead,
307 : nsAString& aTail)
308 : {
309 0 : aHead.Truncate();
310 0 : aTail.Truncate();
311 :
312 0 : nsresult rv = NS_OK;
313 :
314 0 : nsAutoString groupSeparator;
315 0 : PRInt32 groupSize = 0;
316 0 : if (aGroupSize && aGroupSeparator) {
317 0 : nsAutoString sizeStr;
318 0 : rv = aGroupSize->evaluateToString(aContext, sizeStr);
319 0 : NS_ENSURE_SUCCESS(rv, rv);
320 :
321 0 : double size = txDouble::toDouble(sizeStr);
322 0 : groupSize = (PRInt32)size;
323 0 : if ((double)groupSize != size) {
324 0 : groupSize = 0;
325 : }
326 :
327 0 : rv = aGroupSeparator->evaluateToString(aContext, groupSeparator);
328 0 : NS_ENSURE_SUCCESS(rv, rv);
329 : }
330 :
331 0 : nsAutoString format;
332 0 : if (aFormat) {
333 0 : rv = aFormat->evaluateToString(aContext, format);
334 0 : NS_ENSURE_SUCCESS(rv, rv);
335 : }
336 :
337 0 : PRUint32 formatLen = format.Length();
338 0 : PRUint32 formatPos = 0;
339 0 : PRUnichar ch = 0;
340 :
341 : // start with header
342 0 : while (formatPos < formatLen &&
343 0 : !isAlphaNumeric(ch = format.CharAt(formatPos))) {
344 0 : aHead.Append(ch);
345 0 : ++formatPos;
346 : }
347 :
348 : // If there are no formatting tokens we need to create a default one.
349 0 : if (formatPos == formatLen) {
350 : txFormattedCounter* defaultCounter;
351 0 : rv = txFormattedCounter::getCounterFor(NS_LITERAL_STRING("1"), groupSize,
352 0 : groupSeparator, defaultCounter);
353 0 : NS_ENSURE_SUCCESS(rv, rv);
354 :
355 0 : defaultCounter->mSeparator.AssignLiteral(".");
356 0 : rv = aCounters.add(defaultCounter);
357 0 : if (NS_FAILED(rv)) {
358 : // XXX ErrorReport: out of memory
359 0 : delete defaultCounter;
360 0 : return rv;
361 : }
362 :
363 0 : return NS_OK;
364 : }
365 :
366 0 : while (formatPos < formatLen) {
367 0 : nsAutoString sepToken;
368 : // parse separator token
369 0 : if (!aCounters.getLength()) {
370 : // Set the first counters separator to default value so that if
371 : // there is only one formatting token and we're formatting a
372 : // value-list longer then one we use the default separator. This
373 : // won't be used when formatting the first value anyway.
374 0 : sepToken.AssignLiteral(".");
375 : }
376 : else {
377 0 : while (formatPos < formatLen &&
378 0 : !isAlphaNumeric(ch = format.CharAt(formatPos))) {
379 0 : sepToken.Append(ch);
380 0 : ++formatPos;
381 : }
382 : }
383 :
384 : // if we're at the end of the string then the previous token was the tail
385 0 : if (formatPos == formatLen) {
386 0 : aTail = sepToken;
387 0 : return NS_OK;
388 : }
389 :
390 : // parse formatting token
391 0 : nsAutoString numToken;
392 0 : while (formatPos < formatLen &&
393 0 : isAlphaNumeric(ch = format.CharAt(formatPos))) {
394 0 : numToken.Append(ch);
395 0 : ++formatPos;
396 : }
397 :
398 0 : txFormattedCounter* counter = 0;
399 : rv = txFormattedCounter::getCounterFor(numToken, groupSize,
400 0 : groupSeparator, counter);
401 0 : if (NS_FAILED(rv)) {
402 0 : txListIterator iter(&aCounters);
403 0 : while (iter.hasNext()) {
404 0 : delete (txFormattedCounter*)iter.next();
405 : }
406 0 : aCounters.clear();
407 0 : return rv;
408 : }
409 :
410 : // Add to list of counters
411 0 : counter->mSeparator = sepToken;
412 0 : rv = aCounters.add(counter);
413 0 : if (NS_FAILED(rv)) {
414 : // XXX ErrorReport: out of memory
415 0 : txListIterator iter(&aCounters);
416 0 : while (iter.hasNext()) {
417 0 : delete (txFormattedCounter*)iter.next();
418 : }
419 0 : aCounters.clear();
420 0 : return rv;
421 : }
422 : }
423 :
424 0 : return NS_OK;
425 : }
426 :
427 : PRInt32
428 0 : txXSLTNumber::getSiblingCount(txXPathTreeWalker& aWalker,
429 : txPattern* aCountPattern,
430 : txIMatchContext* aContext)
431 : {
432 0 : PRInt32 value = 1;
433 0 : while (aWalker.moveToPreviousSibling()) {
434 0 : if (aCountPattern->matches(aWalker.getCurrentPosition(), aContext)) {
435 0 : ++value;
436 : }
437 : }
438 0 : return value;
439 : }
440 :
441 : bool
442 0 : txXSLTNumber::getPrevInDocumentOrder(txXPathTreeWalker& aWalker)
443 : {
444 0 : if (aWalker.moveToPreviousSibling()) {
445 0 : while (aWalker.moveToLastChild()) {
446 : // do nothing
447 : }
448 0 : return true;
449 : }
450 0 : return aWalker.moveToParent();
451 : }
452 :
453 : #define TX_CHAR_RANGE(ch, a, b) if (ch < a) return false; \
454 : if (ch <= b) return true
455 : #define TX_MATCH_CHAR(ch, a) if (ch < a) return false; \
456 : if (ch == a) return true
457 :
458 0 : bool txXSLTNumber::isAlphaNumeric(PRUnichar ch)
459 : {
460 0 : TX_CHAR_RANGE(ch, 0x0030, 0x0039);
461 0 : TX_CHAR_RANGE(ch, 0x0041, 0x005A);
462 0 : TX_CHAR_RANGE(ch, 0x0061, 0x007A);
463 0 : TX_MATCH_CHAR(ch, 0x00AA);
464 0 : TX_CHAR_RANGE(ch, 0x00B2, 0x00B3);
465 0 : TX_MATCH_CHAR(ch, 0x00B5);
466 0 : TX_CHAR_RANGE(ch, 0x00B9, 0x00BA);
467 0 : TX_CHAR_RANGE(ch, 0x00BC, 0x00BE);
468 0 : TX_CHAR_RANGE(ch, 0x00C0, 0x00D6);
469 0 : TX_CHAR_RANGE(ch, 0x00D8, 0x00F6);
470 0 : TX_CHAR_RANGE(ch, 0x00F8, 0x021F);
471 0 : TX_CHAR_RANGE(ch, 0x0222, 0x0233);
472 0 : TX_CHAR_RANGE(ch, 0x0250, 0x02AD);
473 0 : TX_CHAR_RANGE(ch, 0x02B0, 0x02B8);
474 0 : TX_CHAR_RANGE(ch, 0x02BB, 0x02C1);
475 0 : TX_CHAR_RANGE(ch, 0x02D0, 0x02D1);
476 0 : TX_CHAR_RANGE(ch, 0x02E0, 0x02E4);
477 0 : TX_MATCH_CHAR(ch, 0x02EE);
478 0 : TX_MATCH_CHAR(ch, 0x037A);
479 0 : TX_MATCH_CHAR(ch, 0x0386);
480 0 : TX_CHAR_RANGE(ch, 0x0388, 0x038A);
481 0 : TX_MATCH_CHAR(ch, 0x038C);
482 0 : TX_CHAR_RANGE(ch, 0x038E, 0x03A1);
483 0 : TX_CHAR_RANGE(ch, 0x03A3, 0x03CE);
484 0 : TX_CHAR_RANGE(ch, 0x03D0, 0x03D7);
485 0 : TX_CHAR_RANGE(ch, 0x03DA, 0x03F3);
486 0 : TX_CHAR_RANGE(ch, 0x0400, 0x0481);
487 0 : TX_CHAR_RANGE(ch, 0x048C, 0x04C4);
488 0 : TX_CHAR_RANGE(ch, 0x04C7, 0x04C8);
489 0 : TX_CHAR_RANGE(ch, 0x04CB, 0x04CC);
490 0 : TX_CHAR_RANGE(ch, 0x04D0, 0x04F5);
491 0 : TX_CHAR_RANGE(ch, 0x04F8, 0x04F9);
492 0 : TX_CHAR_RANGE(ch, 0x0531, 0x0556);
493 0 : TX_MATCH_CHAR(ch, 0x0559);
494 0 : TX_CHAR_RANGE(ch, 0x0561, 0x0587);
495 0 : TX_CHAR_RANGE(ch, 0x05D0, 0x05EA);
496 0 : TX_CHAR_RANGE(ch, 0x05F0, 0x05F2);
497 0 : TX_CHAR_RANGE(ch, 0x0621, 0x063A);
498 0 : TX_CHAR_RANGE(ch, 0x0640, 0x064A);
499 0 : TX_CHAR_RANGE(ch, 0x0660, 0x0669);
500 0 : TX_CHAR_RANGE(ch, 0x0671, 0x06D3);
501 0 : TX_MATCH_CHAR(ch, 0x06D5);
502 0 : TX_CHAR_RANGE(ch, 0x06E5, 0x06E6);
503 0 : TX_CHAR_RANGE(ch, 0x06F0, 0x06FC);
504 0 : TX_MATCH_CHAR(ch, 0x0710);
505 0 : TX_CHAR_RANGE(ch, 0x0712, 0x072C);
506 0 : TX_CHAR_RANGE(ch, 0x0780, 0x07A5);
507 0 : TX_CHAR_RANGE(ch, 0x0905, 0x0939);
508 0 : TX_MATCH_CHAR(ch, 0x093D);
509 0 : TX_MATCH_CHAR(ch, 0x0950);
510 0 : TX_CHAR_RANGE(ch, 0x0958, 0x0961);
511 0 : TX_CHAR_RANGE(ch, 0x0966, 0x096F);
512 0 : TX_CHAR_RANGE(ch, 0x0985, 0x098C);
513 0 : TX_CHAR_RANGE(ch, 0x098F, 0x0990);
514 0 : TX_CHAR_RANGE(ch, 0x0993, 0x09A8);
515 0 : TX_CHAR_RANGE(ch, 0x09AA, 0x09B0);
516 0 : TX_MATCH_CHAR(ch, 0x09B2);
517 0 : TX_CHAR_RANGE(ch, 0x09B6, 0x09B9);
518 0 : TX_CHAR_RANGE(ch, 0x09DC, 0x09DD);
519 0 : TX_CHAR_RANGE(ch, 0x09DF, 0x09E1);
520 0 : TX_CHAR_RANGE(ch, 0x09E6, 0x09F1);
521 0 : TX_CHAR_RANGE(ch, 0x09F4, 0x09F9);
522 0 : TX_CHAR_RANGE(ch, 0x0A05, 0x0A0A);
523 0 : TX_CHAR_RANGE(ch, 0x0A0F, 0x0A10);
524 0 : TX_CHAR_RANGE(ch, 0x0A13, 0x0A28);
525 0 : TX_CHAR_RANGE(ch, 0x0A2A, 0x0A30);
526 0 : TX_CHAR_RANGE(ch, 0x0A32, 0x0A33);
527 0 : TX_CHAR_RANGE(ch, 0x0A35, 0x0A36);
528 0 : TX_CHAR_RANGE(ch, 0x0A38, 0x0A39);
529 0 : TX_CHAR_RANGE(ch, 0x0A59, 0x0A5C);
530 0 : TX_MATCH_CHAR(ch, 0x0A5E);
531 0 : TX_CHAR_RANGE(ch, 0x0A66, 0x0A6F);
532 0 : TX_CHAR_RANGE(ch, 0x0A72, 0x0A74);
533 0 : TX_CHAR_RANGE(ch, 0x0A85, 0x0A8B);
534 0 : TX_MATCH_CHAR(ch, 0x0A8D);
535 0 : TX_CHAR_RANGE(ch, 0x0A8F, 0x0A91);
536 0 : TX_CHAR_RANGE(ch, 0x0A93, 0x0AA8);
537 0 : TX_CHAR_RANGE(ch, 0x0AAA, 0x0AB0);
538 0 : TX_CHAR_RANGE(ch, 0x0AB2, 0x0AB3);
539 0 : TX_CHAR_RANGE(ch, 0x0AB5, 0x0AB9);
540 0 : TX_MATCH_CHAR(ch, 0x0ABD);
541 0 : TX_MATCH_CHAR(ch, 0x0AD0);
542 0 : TX_MATCH_CHAR(ch, 0x0AE0);
543 0 : TX_CHAR_RANGE(ch, 0x0AE6, 0x0AEF);
544 0 : TX_CHAR_RANGE(ch, 0x0B05, 0x0B0C);
545 0 : TX_CHAR_RANGE(ch, 0x0B0F, 0x0B10);
546 0 : TX_CHAR_RANGE(ch, 0x0B13, 0x0B28);
547 0 : TX_CHAR_RANGE(ch, 0x0B2A, 0x0B30);
548 0 : TX_CHAR_RANGE(ch, 0x0B32, 0x0B33);
549 0 : TX_CHAR_RANGE(ch, 0x0B36, 0x0B39);
550 0 : TX_MATCH_CHAR(ch, 0x0B3D);
551 0 : TX_CHAR_RANGE(ch, 0x0B5C, 0x0B5D);
552 0 : TX_CHAR_RANGE(ch, 0x0B5F, 0x0B61);
553 0 : TX_CHAR_RANGE(ch, 0x0B66, 0x0B6F);
554 0 : TX_CHAR_RANGE(ch, 0x0B85, 0x0B8A);
555 0 : TX_CHAR_RANGE(ch, 0x0B8E, 0x0B90);
556 0 : TX_CHAR_RANGE(ch, 0x0B92, 0x0B95);
557 0 : TX_CHAR_RANGE(ch, 0x0B99, 0x0B9A);
558 0 : TX_MATCH_CHAR(ch, 0x0B9C);
559 0 : TX_CHAR_RANGE(ch, 0x0B9E, 0x0B9F);
560 0 : TX_CHAR_RANGE(ch, 0x0BA3, 0x0BA4);
561 0 : TX_CHAR_RANGE(ch, 0x0BA8, 0x0BAA);
562 0 : TX_CHAR_RANGE(ch, 0x0BAE, 0x0BB5);
563 0 : TX_CHAR_RANGE(ch, 0x0BB7, 0x0BB9);
564 0 : TX_CHAR_RANGE(ch, 0x0BE7, 0x0BF2);
565 0 : TX_CHAR_RANGE(ch, 0x0C05, 0x0C0C);
566 0 : TX_CHAR_RANGE(ch, 0x0C0E, 0x0C10);
567 0 : TX_CHAR_RANGE(ch, 0x0C12, 0x0C28);
568 0 : TX_CHAR_RANGE(ch, 0x0C2A, 0x0C33);
569 0 : TX_CHAR_RANGE(ch, 0x0C35, 0x0C39);
570 0 : TX_CHAR_RANGE(ch, 0x0C60, 0x0C61);
571 0 : TX_CHAR_RANGE(ch, 0x0C66, 0x0C6F);
572 0 : TX_CHAR_RANGE(ch, 0x0C85, 0x0C8C);
573 0 : TX_CHAR_RANGE(ch, 0x0C8E, 0x0C90);
574 0 : TX_CHAR_RANGE(ch, 0x0C92, 0x0CA8);
575 0 : TX_CHAR_RANGE(ch, 0x0CAA, 0x0CB3);
576 0 : TX_CHAR_RANGE(ch, 0x0CB5, 0x0CB9);
577 0 : TX_MATCH_CHAR(ch, 0x0CDE);
578 0 : TX_CHAR_RANGE(ch, 0x0CE0, 0x0CE1);
579 0 : TX_CHAR_RANGE(ch, 0x0CE6, 0x0CEF);
580 0 : TX_CHAR_RANGE(ch, 0x0D05, 0x0D0C);
581 0 : TX_CHAR_RANGE(ch, 0x0D0E, 0x0D10);
582 0 : TX_CHAR_RANGE(ch, 0x0D12, 0x0D28);
583 0 : TX_CHAR_RANGE(ch, 0x0D2A, 0x0D39);
584 0 : TX_CHAR_RANGE(ch, 0x0D60, 0x0D61);
585 0 : TX_CHAR_RANGE(ch, 0x0D66, 0x0D6F);
586 0 : TX_CHAR_RANGE(ch, 0x0D85, 0x0D96);
587 0 : TX_CHAR_RANGE(ch, 0x0D9A, 0x0DB1);
588 0 : TX_CHAR_RANGE(ch, 0x0DB3, 0x0DBB);
589 0 : TX_MATCH_CHAR(ch, 0x0DBD);
590 0 : TX_CHAR_RANGE(ch, 0x0DC0, 0x0DC6);
591 0 : TX_CHAR_RANGE(ch, 0x0E01, 0x0E30);
592 0 : TX_CHAR_RANGE(ch, 0x0E32, 0x0E33);
593 0 : TX_CHAR_RANGE(ch, 0x0E40, 0x0E46);
594 0 : TX_CHAR_RANGE(ch, 0x0E50, 0x0E59);
595 0 : TX_CHAR_RANGE(ch, 0x0E81, 0x0E82);
596 0 : TX_MATCH_CHAR(ch, 0x0E84);
597 0 : TX_CHAR_RANGE(ch, 0x0E87, 0x0E88);
598 0 : TX_MATCH_CHAR(ch, 0x0E8A);
599 0 : TX_MATCH_CHAR(ch, 0x0E8D);
600 0 : TX_CHAR_RANGE(ch, 0x0E94, 0x0E97);
601 0 : TX_CHAR_RANGE(ch, 0x0E99, 0x0E9F);
602 0 : TX_CHAR_RANGE(ch, 0x0EA1, 0x0EA3);
603 0 : TX_MATCH_CHAR(ch, 0x0EA5);
604 0 : TX_MATCH_CHAR(ch, 0x0EA7);
605 0 : TX_CHAR_RANGE(ch, 0x0EAA, 0x0EAB);
606 0 : TX_CHAR_RANGE(ch, 0x0EAD, 0x0EB0);
607 0 : TX_CHAR_RANGE(ch, 0x0EB2, 0x0EB3);
608 0 : TX_MATCH_CHAR(ch, 0x0EBD);
609 0 : TX_CHAR_RANGE(ch, 0x0EC0, 0x0EC4);
610 0 : TX_MATCH_CHAR(ch, 0x0EC6);
611 0 : TX_CHAR_RANGE(ch, 0x0ED0, 0x0ED9);
612 0 : TX_CHAR_RANGE(ch, 0x0EDC, 0x0EDD);
613 0 : TX_MATCH_CHAR(ch, 0x0F00);
614 0 : TX_CHAR_RANGE(ch, 0x0F20, 0x0F33);
615 0 : TX_CHAR_RANGE(ch, 0x0F40, 0x0F47);
616 0 : TX_CHAR_RANGE(ch, 0x0F49, 0x0F6A);
617 0 : TX_CHAR_RANGE(ch, 0x0F88, 0x0F8B);
618 0 : TX_CHAR_RANGE(ch, 0x1000, 0x1021);
619 0 : TX_CHAR_RANGE(ch, 0x1023, 0x1027);
620 0 : TX_CHAR_RANGE(ch, 0x1029, 0x102A);
621 0 : TX_CHAR_RANGE(ch, 0x1040, 0x1049);
622 0 : TX_CHAR_RANGE(ch, 0x1050, 0x1055);
623 0 : TX_CHAR_RANGE(ch, 0x10A0, 0x10C5);
624 0 : TX_CHAR_RANGE(ch, 0x10D0, 0x10F6);
625 0 : TX_CHAR_RANGE(ch, 0x1100, 0x1159);
626 0 : TX_CHAR_RANGE(ch, 0x115F, 0x11A2);
627 0 : TX_CHAR_RANGE(ch, 0x11A8, 0x11F9);
628 0 : TX_CHAR_RANGE(ch, 0x1200, 0x1206);
629 0 : TX_CHAR_RANGE(ch, 0x1208, 0x1246);
630 0 : TX_MATCH_CHAR(ch, 0x1248);
631 0 : TX_CHAR_RANGE(ch, 0x124A, 0x124D);
632 0 : TX_CHAR_RANGE(ch, 0x1250, 0x1256);
633 0 : TX_MATCH_CHAR(ch, 0x1258);
634 0 : TX_CHAR_RANGE(ch, 0x125A, 0x125D);
635 0 : TX_CHAR_RANGE(ch, 0x1260, 0x1286);
636 0 : TX_MATCH_CHAR(ch, 0x1288);
637 0 : TX_CHAR_RANGE(ch, 0x128A, 0x128D);
638 0 : TX_CHAR_RANGE(ch, 0x1290, 0x12AE);
639 0 : TX_MATCH_CHAR(ch, 0x12B0);
640 0 : TX_CHAR_RANGE(ch, 0x12B2, 0x12B5);
641 0 : TX_CHAR_RANGE(ch, 0x12B8, 0x12BE);
642 0 : TX_MATCH_CHAR(ch, 0x12C0);
643 0 : TX_CHAR_RANGE(ch, 0x12C2, 0x12C5);
644 0 : TX_CHAR_RANGE(ch, 0x12C8, 0x12CE);
645 0 : TX_CHAR_RANGE(ch, 0x12D0, 0x12D6);
646 0 : TX_CHAR_RANGE(ch, 0x12D8, 0x12EE);
647 0 : TX_CHAR_RANGE(ch, 0x12F0, 0x130E);
648 0 : TX_MATCH_CHAR(ch, 0x1310);
649 0 : TX_CHAR_RANGE(ch, 0x1312, 0x1315);
650 0 : TX_CHAR_RANGE(ch, 0x1318, 0x131E);
651 0 : TX_CHAR_RANGE(ch, 0x1320, 0x1346);
652 0 : TX_CHAR_RANGE(ch, 0x1348, 0x135A);
653 0 : TX_CHAR_RANGE(ch, 0x1369, 0x137C);
654 0 : TX_CHAR_RANGE(ch, 0x13A0, 0x13F4);
655 0 : TX_CHAR_RANGE(ch, 0x1401, 0x166C);
656 0 : TX_CHAR_RANGE(ch, 0x166F, 0x1676);
657 0 : TX_CHAR_RANGE(ch, 0x1681, 0x169A);
658 0 : TX_CHAR_RANGE(ch, 0x16A0, 0x16EA);
659 0 : TX_CHAR_RANGE(ch, 0x16EE, 0x16F0);
660 0 : TX_CHAR_RANGE(ch, 0x1780, 0x17B3);
661 0 : TX_CHAR_RANGE(ch, 0x17E0, 0x17E9);
662 0 : TX_CHAR_RANGE(ch, 0x1810, 0x1819);
663 0 : TX_CHAR_RANGE(ch, 0x1820, 0x1877);
664 0 : TX_CHAR_RANGE(ch, 0x1880, 0x18A8);
665 0 : TX_CHAR_RANGE(ch, 0x1E00, 0x1E9B);
666 0 : TX_CHAR_RANGE(ch, 0x1EA0, 0x1EF9);
667 0 : TX_CHAR_RANGE(ch, 0x1F00, 0x1F15);
668 0 : TX_CHAR_RANGE(ch, 0x1F18, 0x1F1D);
669 0 : TX_CHAR_RANGE(ch, 0x1F20, 0x1F45);
670 0 : TX_CHAR_RANGE(ch, 0x1F48, 0x1F4D);
671 0 : TX_CHAR_RANGE(ch, 0x1F50, 0x1F57);
672 0 : TX_MATCH_CHAR(ch, 0x1F59);
673 0 : TX_MATCH_CHAR(ch, 0x1F5B);
674 0 : TX_MATCH_CHAR(ch, 0x1F5D);
675 0 : TX_CHAR_RANGE(ch, 0x1F5F, 0x1F7D);
676 0 : TX_CHAR_RANGE(ch, 0x1F80, 0x1FB4);
677 0 : TX_CHAR_RANGE(ch, 0x1FB6, 0x1FBC);
678 0 : TX_MATCH_CHAR(ch, 0x1FBE);
679 0 : TX_CHAR_RANGE(ch, 0x1FC2, 0x1FC4);
680 0 : TX_CHAR_RANGE(ch, 0x1FC6, 0x1FCC);
681 0 : TX_CHAR_RANGE(ch, 0x1FD0, 0x1FD3);
682 0 : TX_CHAR_RANGE(ch, 0x1FD6, 0x1FDB);
683 0 : TX_CHAR_RANGE(ch, 0x1FE0, 0x1FEC);
684 0 : TX_CHAR_RANGE(ch, 0x1FF2, 0x1FF4);
685 0 : TX_CHAR_RANGE(ch, 0x1FF6, 0x1FFC);
686 0 : TX_MATCH_CHAR(ch, 0x2070);
687 0 : TX_CHAR_RANGE(ch, 0x2074, 0x2079);
688 0 : TX_CHAR_RANGE(ch, 0x207F, 0x2089);
689 0 : TX_MATCH_CHAR(ch, 0x2102);
690 0 : TX_MATCH_CHAR(ch, 0x2107);
691 0 : TX_CHAR_RANGE(ch, 0x210A, 0x2113);
692 0 : TX_MATCH_CHAR(ch, 0x2115);
693 0 : TX_CHAR_RANGE(ch, 0x2119, 0x211D);
694 0 : TX_MATCH_CHAR(ch, 0x2124);
695 0 : TX_MATCH_CHAR(ch, 0x2126);
696 0 : TX_MATCH_CHAR(ch, 0x2128);
697 0 : TX_CHAR_RANGE(ch, 0x212A, 0x212D);
698 0 : TX_CHAR_RANGE(ch, 0x212F, 0x2131);
699 0 : TX_CHAR_RANGE(ch, 0x2133, 0x2139);
700 0 : TX_CHAR_RANGE(ch, 0x2153, 0x2183);
701 0 : TX_CHAR_RANGE(ch, 0x2460, 0x249B);
702 0 : TX_MATCH_CHAR(ch, 0x24EA);
703 0 : TX_CHAR_RANGE(ch, 0x2776, 0x2793);
704 0 : TX_CHAR_RANGE(ch, 0x3005, 0x3007);
705 0 : TX_CHAR_RANGE(ch, 0x3021, 0x3029);
706 0 : TX_CHAR_RANGE(ch, 0x3031, 0x3035);
707 0 : TX_CHAR_RANGE(ch, 0x3038, 0x303A);
708 0 : TX_CHAR_RANGE(ch, 0x3041, 0x3094);
709 0 : TX_CHAR_RANGE(ch, 0x309D, 0x309E);
710 0 : TX_CHAR_RANGE(ch, 0x30A1, 0x30FA);
711 0 : TX_CHAR_RANGE(ch, 0x30FC, 0x30FE);
712 0 : TX_CHAR_RANGE(ch, 0x3105, 0x312C);
713 0 : TX_CHAR_RANGE(ch, 0x3131, 0x318E);
714 0 : TX_CHAR_RANGE(ch, 0x3192, 0x3195);
715 0 : TX_CHAR_RANGE(ch, 0x31A0, 0x31B7);
716 0 : TX_CHAR_RANGE(ch, 0x3220, 0x3229);
717 0 : TX_CHAR_RANGE(ch, 0x3280, 0x3289);
718 0 : TX_MATCH_CHAR(ch, 0x3400);
719 0 : TX_MATCH_CHAR(ch, 0x4DB5);
720 0 : TX_MATCH_CHAR(ch, 0x4E00);
721 0 : TX_MATCH_CHAR(ch, 0x9FA5);
722 0 : TX_CHAR_RANGE(ch, 0xA000, 0xA48C);
723 0 : TX_MATCH_CHAR(ch, 0xAC00);
724 0 : TX_MATCH_CHAR(ch, 0xD7A3);
725 0 : TX_CHAR_RANGE(ch, 0xF900, 0xFA2D);
726 0 : TX_CHAR_RANGE(ch, 0xFB00, 0xFB06);
727 0 : TX_CHAR_RANGE(ch, 0xFB13, 0xFB17);
728 0 : TX_MATCH_CHAR(ch, 0xFB1D);
729 0 : TX_CHAR_RANGE(ch, 0xFB1F, 0xFB28);
730 0 : TX_CHAR_RANGE(ch, 0xFB2A, 0xFB36);
731 0 : TX_CHAR_RANGE(ch, 0xFB38, 0xFB3C);
732 0 : TX_MATCH_CHAR(ch, 0xFB3E);
733 0 : TX_CHAR_RANGE(ch, 0xFB40, 0xFB41);
734 0 : TX_CHAR_RANGE(ch, 0xFB43, 0xFB44);
735 0 : TX_CHAR_RANGE(ch, 0xFB46, 0xFBB1);
736 0 : TX_CHAR_RANGE(ch, 0xFBD3, 0xFD3D);
737 0 : TX_CHAR_RANGE(ch, 0xFD50, 0xFD8F);
738 0 : TX_CHAR_RANGE(ch, 0xFD92, 0xFDC7);
739 0 : TX_CHAR_RANGE(ch, 0xFDF0, 0xFDFB);
740 0 : TX_CHAR_RANGE(ch, 0xFE70, 0xFE72);
741 0 : TX_MATCH_CHAR(ch, 0xFE74);
742 0 : TX_CHAR_RANGE(ch, 0xFE76, 0xFEFC);
743 0 : TX_CHAR_RANGE(ch, 0xFF10, 0xFF19);
744 0 : TX_CHAR_RANGE(ch, 0xFF21, 0xFF3A);
745 0 : TX_CHAR_RANGE(ch, 0xFF41, 0xFF5A);
746 0 : TX_CHAR_RANGE(ch, 0xFF66, 0xFFBE);
747 0 : TX_CHAR_RANGE(ch, 0xFFC2, 0xFFC7);
748 0 : TX_CHAR_RANGE(ch, 0xFFCA, 0xFFCF);
749 0 : TX_CHAR_RANGE(ch, 0xFFD2, 0xFFD7);
750 0 : return false;
751 : }
|