ReactOS 0.4.16-dev-2207-geb15453
numbers.c
Go to the documentation of this file.
1/*
2 * numbers.c: Implementation of the XSLT number functions
3 *
4 * Reference:
5 * http://www.w3.org/TR/1999/REC-xslt-19991116
6 *
7 * See Copyright for the status of this software.
8 *
9 * daniel@veillard.com
10 * Bjorn Reese <breese@users.sourceforge.net>
11 */
12
13#define IN_LIBXSLT
14#include "libxslt.h"
15
16#include <math.h>
17#include <limits.h>
18#include <float.h>
19#include <string.h>
20
21#include <libxml/xmlmemory.h>
23#include <libxml/xpath.h>
25#include <libxml/encoding.h>
26#include "xsltutils.h"
27#include "pattern.h"
28#include "templates.h"
29#include "transform.h"
30#include "numbersInternals.h"
31
32#ifndef FALSE
33# define FALSE (0 == 1)
34# define TRUE (1 == 1)
35#endif
36
37#define SYMBOL_QUOTE ((xmlChar)'\'')
38
39#define DEFAULT_TOKEN '0'
40#define DEFAULT_SEPARATOR "."
41
42#define MAX_TOKENS 1024
43
48 int token;
49 int width;
50};
51
52typedef struct _xsltFormat xsltFormat;
59};
60
61static char alpha_upper_list[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
62static char alpha_lower_list[] = "abcdefghijklmnopqrstuvwxyz";
64
65/*
66 * **** Start temp insert ****
67 *
68 * The following routine xsltUTF8Charcmp will be replaced with calls to
69 * the corresponding libxml routine at a later date (when other
70 * inter-library dependencies require it).
71 */
72
81static int
83 int len = xmlUTF8Strsize(utf1, 1);
84
85 if (len < 1)
86 return -1;
87 if (utf1 == NULL ) {
88 if (utf2 == NULL)
89 return 0;
90 return -1;
91 }
92 return xmlStrncmp(utf1, utf2, len);
93}
94
95static int
99}
100
101/***** Stop temp insert *****/
102/************************************************************************
103 * *
104 * Utility functions *
105 * *
106 ************************************************************************/
107
108#define IS_SPECIAL(self,letter) \
109 ((xsltUTF8Charcmp((letter), (self)->zeroDigit) == 0) || \
110 (xsltUTF8Charcmp((letter), (self)->digit) == 0) || \
111 (xsltUTF8Charcmp((letter), (self)->decimalPoint) == 0) || \
112 (xsltUTF8Charcmp((letter), (self)->grouping) == 0) || \
113 (xsltUTF8Charcmp((letter), (self)->patternSeparator) == 0))
114
115#define IS_DIGIT_ZERO(x) xsltIsDigitZero(x)
116#define IS_DIGIT_ONE(x) xsltIsDigitZero((x)-1)
117
118static int
120{
121 /*
122 * Reference: ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
123 *
124 * There a many more digit ranges in newer Unicode versions. These
125 * are only the zeros that match Digit in XML 1.0 (IS_DIGIT macro).
126 */
127 switch (ch) {
128 case 0x0030: case 0x0660: case 0x06F0: case 0x0966:
129 case 0x09E6: case 0x0A66: case 0x0AE6: case 0x0B66:
130 case 0x0C66: case 0x0CE6: case 0x0D66: case 0x0E50:
131 case 0x0ED0: case 0x0F20:
132 return TRUE;
133 default:
134 return FALSE;
135 }
136}
137
138static void
140 double number,
141 int digit_zero,
142 int width,
143 int digitsPerGroup,
144 int groupingCharacter,
145 int groupingCharacterLen)
146{
147 /*
148 * This used to be
149 * xmlChar temp_string[sizeof(double) * CHAR_BIT * sizeof(xmlChar) + 4];
150 * which would be length 68 on x86 arch. It was changed to be a longer,
151 * fixed length in order to try to cater for (reasonable) UTF8
152 * separators and numeric characters. The max UTF8 char size will be
153 * 6 or less, so the value used [500] should be *much* larger than needed
154 */
155 xmlChar temp_string[500];
157 xmlChar temp_char[6];
158 int i;
159 int val;
160 int len;
161
162 /* Build buffer from back */
163 pointer = &temp_string[sizeof(temp_string)] - 1; /* last char */
164 *pointer = 0;
165 i = 0;
166 while (pointer > temp_string) {
167 if ((i >= width) && (fabs(number) < 1.0))
168 break; /* for */
169 if ((i > 0) && (groupingCharacter != 0) &&
170 (digitsPerGroup > 0) &&
171 ((i % digitsPerGroup) == 0)) {
172 if (pointer - groupingCharacterLen < temp_string) {
173 i = -1; /* flag error */
174 break;
175 }
176 pointer -= groupingCharacterLen;
177 xmlCopyCharMultiByte(pointer, groupingCharacter);
178 }
179
180 val = digit_zero + (int)fmod(number, 10.0);
181 if (val < 0x80) { /* shortcut if ASCII */
182 if (pointer <= temp_string) { /* Check enough room */
183 i = -1;
184 break;
185 }
186 *(--pointer) = val;
187 }
188 else {
189 /*
190 * Here we have a multibyte character. It's a little messy,
191 * because until we generate the char we don't know how long
192 * it is. So, we generate it into the buffer temp_char, then
193 * copy from there into temp_string.
194 */
195 len = xmlCopyCharMultiByte(temp_char, val);
196 if ( (pointer - len) < temp_string ) {
197 i = -1;
198 break;
199 }
200 pointer -= len;
201 memcpy(pointer, temp_char, len);
202 }
203 number /= 10.0;
204 ++i;
205 }
206 if (i < 0)
208 "xsltNumberFormatDecimal: Internal buffer size exceeded\n");
209 xmlBufferCat(buffer, pointer);
210}
211
212static void
214 xmlBufferPtr buffer,
215 double number,
216 int is_upper)
217{
218 char temp_string[sizeof(double) * CHAR_BIT * sizeof(xmlChar) + 1];
219 char *pointer;
220 int i;
221 char *alpha_list;
222 double alpha_size = (double)(sizeof(alpha_upper_list) - 1);
223
224 /*
225 * XSLT 1.0 isn't clear on how to handle zero, but XSLT 2.0 says:
226 *
227 * For all format tokens other than the first kind above (one that
228 * consists of decimal digits), there may be implementation-defined
229 * lower and upper bounds on the range of numbers that can be
230 * formatted using this format token; indeed, for some numbering
231 * sequences there may be intrinsic limits. [...] Numbers that fall
232 * outside this range must be formatted using the format token 1.
233 *
234 * The "a" token has an intrinsic lower limit of 1.
235 */
236 if (number < 1.0) {
238 data->digitsPerGroup,
239 data->groupingCharacter,
240 data->groupingCharacterLen);
241 return;
242 }
243
244 /* Build buffer from back */
245 pointer = &temp_string[sizeof(temp_string)];
246 *(--pointer) = 0;
247 alpha_list = (is_upper) ? alpha_upper_list : alpha_lower_list;
248
249 for (i = 1; i < (int)sizeof(temp_string); i++) {
250 number--;
251 *(--pointer) = alpha_list[((int)fmod(number, alpha_size))];
252 number /= alpha_size;
253 if (number < 1.0)
254 break; /* for */
255 }
256 xmlBufferCCat(buffer, pointer);
257}
258
259static void
261 xmlBufferPtr buffer,
262 double number,
263 int is_upper)
264{
265 /*
266 * See discussion in xsltNumberFormatAlpha. Also use a reasonable upper
267 * bound to avoid denial of service.
268 */
269 if (number < 1.0 || number > 5000.0) {
271 data->digitsPerGroup,
272 data->groupingCharacter,
273 data->groupingCharacterLen);
274 return;
275 }
276
277 /*
278 * Based on an example by Jim Walsh
279 */
280 while (number >= 1000.0) {
281 xmlBufferCCat(buffer, (is_upper) ? "M" : "m");
282 number -= 1000.0;
283 }
284 if (number >= 900.0) {
285 xmlBufferCCat(buffer, (is_upper) ? "CM" : "cm");
286 number -= 900.0;
287 }
288 while (number >= 500.0) {
289 xmlBufferCCat(buffer, (is_upper) ? "D" : "d");
290 number -= 500.0;
291 }
292 if (number >= 400.0) {
293 xmlBufferCCat(buffer, (is_upper) ? "CD" : "cd");
294 number -= 400.0;
295 }
296 while (number >= 100.0) {
297 xmlBufferCCat(buffer, (is_upper) ? "C" : "c");
298 number -= 100.0;
299 }
300 if (number >= 90.0) {
301 xmlBufferCCat(buffer, (is_upper) ? "XC" : "xc");
302 number -= 90.0;
303 }
304 while (number >= 50.0) {
305 xmlBufferCCat(buffer, (is_upper) ? "L" : "l");
306 number -= 50.0;
307 }
308 if (number >= 40.0) {
309 xmlBufferCCat(buffer, (is_upper) ? "XL" : "xl");
310 number -= 40.0;
311 }
312 while (number >= 10.0) {
313 xmlBufferCCat(buffer, (is_upper) ? "X" : "x");
314 number -= 10.0;
315 }
316 if (number >= 9.0) {
317 xmlBufferCCat(buffer, (is_upper) ? "IX" : "ix");
318 number -= 9.0;
319 }
320 while (number >= 5.0) {
321 xmlBufferCCat(buffer, (is_upper) ? "V" : "v");
322 number -= 5.0;
323 }
324 if (number >= 4.0) {
325 xmlBufferCCat(buffer, (is_upper) ? "IV" : "iv");
326 number -= 4.0;
327 }
328 while (number >= 1.0) {
329 xmlBufferCCat(buffer, (is_upper) ? "I" : "i");
330 number--;
331 }
332}
333
334static void
336 xsltFormatPtr tokens)
337{
338 int ix = 0;
339 int j;
340 int val;
341 int len;
342
346
347
348 tokens->start = NULL;
349 tokens->tokens[0].separator = NULL;
350 tokens->end = NULL;
351
352 /*
353 * Insert initial non-alphanumeric token.
354 * There is always such a token in the list, even if NULL
355 */
357 if (format[ix] == 0) /* if end of format string */
358 break; /* while */
359 ix += len;
360 }
361 if (ix > 0)
362 tokens->start = xmlStrndup(format, ix);
363
364
365 for (tokens->nTokens = 0; tokens->nTokens < MAX_TOKENS;
366 tokens->nTokens++) {
367 if (format[ix] == 0)
368 break; /* for */
369
370 /*
371 * separator has already been parsed (except for the first
372 * number) in tokens->end, recover it.
373 */
374 if (tokens->nTokens > 0) {
375 tokens->tokens[tokens->nTokens].separator = tokens->end;
376 tokens->end = NULL;
377 }
378
380 if (IS_DIGIT_ONE(val) ||
382 tokens->tokens[tokens->nTokens].width = 1;
383 while (IS_DIGIT_ZERO(val)) {
384 tokens->tokens[tokens->nTokens].width++;
385 ix += len;
387 }
388 if (IS_DIGIT_ONE(val)) {
389 tokens->tokens[tokens->nTokens].token = val - 1;
390 ix += len;
392 } else {
393 tokens->tokens[tokens->nTokens].token = '0';
394 tokens->tokens[tokens->nTokens].width = 1;
395 }
396 } else if ( (val == 'A') ||
397 (val == 'a') ||
398 (val == 'I') ||
399 (val == 'i') ) {
400 tokens->tokens[tokens->nTokens].token = val;
401 ix += len;
403 } else {
404 /* XSLT section 7.7
405 * "Any other format token indicates a numbering sequence
406 * that starts with that token. If an implementation does
407 * not support a numbering sequence that starts with that
408 * token, it must use a format token of 1."
409 */
410 tokens->tokens[tokens->nTokens].token = '0';
411 tokens->tokens[tokens->nTokens].width = 1;
412 }
413 /*
414 * Skip over remaining alphanumeric characters from the Nd
415 * (Number, decimal digit), Nl (Number, letter), No (Number,
416 * other), Lu (Letter, uppercase), Ll (Letter, lowercase), Lt
417 * (Letters, titlecase), Lm (Letters, modifiers), and Lo
418 * (Letters, other (uncased)) Unicode categories. This happens
419 * to correspond to the Letter and Digit classes from XML (and
420 * one wonders why XSLT doesn't refer to these instead).
421 */
422 while (xsltIsLetterDigit(val)) {
423 ix += len;
425 }
426
427 /*
428 * Insert temporary non-alphanumeric final tooken.
429 */
430 j = ix;
431 while (!xsltIsLetterDigit(val)) {
432 if (val == 0)
433 break; /* while */
434 ix += len;
436 }
437 if (ix > j)
438 tokens->end = xmlStrndup(&format[j], ix - j);
439 }
440}
441
442static void
444 double *numbers,
445 int numbers_max,
446 xsltFormatPtr tokens,
447 xmlBufferPtr buffer)
448{
449 int i = 0;
450 double number;
452
453 /*
454 * Handle initial non-alphanumeric token
455 */
456 if (tokens->start != NULL)
457 xmlBufferCat(buffer, tokens->start);
458
459 for (i = 0; i < numbers_max; i++) {
460 /* Insert number */
461 number = numbers[(numbers_max - 1) - i];
462 /* Round to nearest like XSLT 2.0 */
463 number = floor(number + 0.5);
464 /*
465 * XSLT 1.0 isn't clear on how to handle negative numbers, but XSLT
466 * 2.0 says:
467 *
468 * It is a non-recoverable dynamic error if any undiscarded item
469 * in the atomized sequence supplied as the value of the value
470 * attribute of xsl:number cannot be converted to an integer, or
471 * if the resulting integer is less than 0 (zero).
472 */
473 if (number < 0.0) {
475 "xsl-number : negative value\n");
476 /* Recover by treating negative values as zero. */
477 number = 0.0;
478 }
479 if (i < tokens->nTokens) {
480 /*
481 * The "n"th format token will be used to format the "n"th
482 * number in the list
483 */
484 token = &(tokens->tokens[i]);
485 } else if (tokens->nTokens > 0) {
486 /*
487 * If there are more numbers than format tokens, then the
488 * last format token will be used to format the remaining
489 * numbers.
490 */
491 token = &(tokens->tokens[tokens->nTokens - 1]);
492 } else {
493 /*
494 * If there are no format tokens, then a format token of
495 * 1 is used to format all numbers.
496 */
498 }
499
500 /* Print separator, except for the first number */
501 if (i > 0) {
502 if (token->separator != NULL)
503 xmlBufferCat(buffer, token->separator);
504 else
505 xmlBufferCCat(buffer, DEFAULT_SEPARATOR);
506 }
507
508 switch (xmlXPathIsInf(number)) {
509 case -1:
510 xmlBufferCCat(buffer, "-Infinity");
511 break;
512 case 1:
513 xmlBufferCCat(buffer, "Infinity");
514 break;
515 default:
516 if (xmlXPathIsNaN(number)) {
517 xmlBufferCCat(buffer, "NaN");
518 } else {
519
520 switch (token->token) {
521 case 'A':
523 break;
524 case 'a':
526 break;
527 case 'I':
529 break;
530 case 'i':
532 break;
533 default:
534 if (IS_DIGIT_ZERO(token->token)) {
536 number,
537 token->token,
538 token->width,
539 data->digitsPerGroup,
540 data->groupingCharacter,
541 data->groupingCharacterLen);
542 }
543 break;
544 }
545 }
546
547 }
548 }
549
550 /*
551 * Handle final non-alphanumeric token
552 */
553 if (tokens->end != NULL)
554 xmlBufferCat(buffer, tokens->end);
555
556}
557
558static int
560 xmlNodePtr node,
561 xsltCompMatchPtr countPat,
562 xmlNodePtr cur)
563{
564 if (countPat != NULL) {
565 return xsltTestCompMatchList(context, node, countPat);
566 }
567 else {
568 /*
569 * 7.7 Numbering
570 *
571 * If count attribute is not specified, then it defaults to the
572 * pattern that matches any node with the same node type as the
573 * current node and, if the current node has an expanded-name, with
574 * the same expanded-name as the current node.
575 */
576 if (node->type != cur->type)
577 return 0;
578 if (node->type == XML_NAMESPACE_DECL)
579 /*
580 * Namespace nodes have no preceding siblings and no parents
581 * that are namespace nodes. This means that node == cur.
582 */
583 return 1;
584 /* TODO: Skip node types without expanded names like text nodes. */
585 if (!xmlStrEqual(node->name, cur->name))
586 return 0;
587 if (node->ns == cur->ns)
588 return 1;
589 if ((node->ns == NULL) || (cur->ns == NULL))
590 return 0;
591 return (xmlStrEqual(node->ns->href, cur->ns->href));
592 }
593}
594
595static int
597 xmlNodePtr node,
598 xsltCompMatchPtr countPat,
599 xsltCompMatchPtr fromPat,
600 double *array)
601{
602 int amount = 0;
603 int cnt = 0;
604 xmlNodePtr cur = node;
605
606 while (cur != NULL) {
607 /* process current node */
608 if (xsltTestCompMatchCount(context, cur, countPat, node))
609 cnt++;
610 if ((fromPat != NULL) &&
611 xsltTestCompMatchList(context, cur, fromPat)) {
612 break; /* while */
613 }
614
615 /* Skip to next preceding or ancestor */
616 if ((cur->type == XML_DOCUMENT_NODE) ||
617#ifdef LIBXML_DOCB_ENABLED
618 (cur->type == XML_DOCB_DOCUMENT_NODE) ||
619#endif
620 (cur->type == XML_HTML_DOCUMENT_NODE))
621 break; /* while */
622
623 if (cur->type == XML_NAMESPACE_DECL) {
624 /*
625 * The XPath module stores the parent of a namespace node in
626 * the ns->next field.
627 */
628 cur = (xmlNodePtr) ((xmlNsPtr) cur)->next;
629 } else if (cur->type == XML_ATTRIBUTE_NODE) {
630 cur = cur->parent;
631 } else {
632 while ((cur->prev != NULL) && ((cur->prev->type == XML_DTD_NODE) ||
633 (cur->prev->type == XML_XINCLUDE_START) ||
634 (cur->prev->type == XML_XINCLUDE_END)))
635 cur = cur->prev;
636 if (cur->prev != NULL) {
637 for (cur = cur->prev; cur->last != NULL; cur = cur->last);
638 } else {
639 cur = cur->parent;
640 }
641 }
642 }
643
644 array[amount++] = (double) cnt;
645
646 return(amount);
647}
648
649static int
651 xmlNodePtr node,
652 xsltCompMatchPtr countPat,
653 xsltCompMatchPtr fromPat,
654 double *array,
655 int max)
656{
657 int amount = 0;
658 int cnt;
659 xmlNodePtr oldCtxtNode;
660 xmlNodePtr ancestor;
661 xmlNodePtr preceding;
662 xmlXPathParserContextPtr parser;
663
664 oldCtxtNode = context->xpathCtxt->node;
665 parser = xmlXPathNewParserContext(NULL, context->xpathCtxt);
666 if (parser) {
667 /* ancestor-or-self::*[count] */
668 ancestor = node;
669 while ((ancestor != NULL) && (ancestor->type != XML_DOCUMENT_NODE)) {
670 if ((fromPat != NULL) &&
671 xsltTestCompMatchList(context, ancestor, fromPat))
672 break; /* for */
673
674 /*
675 * The xmlXPathNext* iterators require that the context node is
676 * set to the start node. Calls to xsltTestCompMatch* may also
677 * leave the context node in an undefined state, so make sure
678 * that the context node is reset before each iterator invocation.
679 */
680
681 if (xsltTestCompMatchCount(context, ancestor, countPat, node)) {
682 /* count(preceding-sibling::*) */
683 cnt = 1;
684 context->xpathCtxt->node = ancestor;
685 preceding = xmlXPathNextPrecedingSibling(parser, ancestor);
686 while (preceding != NULL) {
687 if (xsltTestCompMatchCount(context, preceding, countPat,
688 node))
689 cnt++;
690 context->xpathCtxt->node = ancestor;
691 preceding =
692 xmlXPathNextPrecedingSibling(parser, preceding);
693 }
694 array[amount++] = (double)cnt;
695 if (amount >= max)
696 break; /* for */
697 }
698 context->xpathCtxt->node = node;
699 ancestor = xmlXPathNextAncestor(parser, ancestor);
700 }
701 xmlXPathFreeParserContext(parser);
702 }
703 context->xpathCtxt->node = oldCtxtNode;
704 return amount;
705}
706
707static int
709 xmlNodePtr node,
710 const xmlChar *value,
711 double *number)
712{
713 int amount = 0;
714 xmlBufferPtr pattern;
715 xmlXPathObjectPtr obj;
716
717 pattern = xmlBufferCreate();
718 if (pattern != NULL) {
719 xmlBufferCCat(pattern, "number(");
720 xmlBufferCat(pattern, value);
721 xmlBufferCCat(pattern, ")");
722 context->node = node;
723 obj = xmlXPathEvalExpression(xmlBufferContent(pattern),
724 context);
725 if (obj != NULL) {
726 *number = obj->floatval;
727 amount++;
728 xmlXPathFreeObject(obj);
729 }
730 xmlBufferFree(pattern);
731 }
732 return amount;
733}
734
743void
746 xmlNodePtr node)
747{
748 xmlBufferPtr output = NULL;
749 int amount, i;
750 double number;
751 xsltFormat tokens;
752
753 if (data->format != NULL) {
754 xsltNumberFormatTokenize(data->format, &tokens);
755 }
756 else {
758
759 /* The format needs to be recomputed each time */
760 if (data->has_format == 0)
761 return;
763 (const xmlChar *) "format",
765 if (format == NULL)
766 return;
769 }
770
771 output = xmlBufferCreate();
772 if (output == NULL)
773 goto XSLT_NUMBER_FORMAT_END;
774
775 /*
776 * Evaluate the XPath expression to find the value(s)
777 */
778 if (data->value) {
779 amount = xsltNumberFormatGetValue(ctxt->xpathCtxt,
780 node,
781 data->value,
782 &number);
783 if (amount == 1) {
785 &number,
786 1,
787 &tokens,
788 output);
789 }
790
791 } else if (data->level) {
792
793 if (xmlStrEqual(data->level, (const xmlChar *) "single")) {
795 node,
796 data->countPat,
797 data->fromPat,
798 &number,
799 1);
800 if (amount == 1) {
802 &number,
803 1,
804 &tokens,
805 output);
806 }
807 } else if (xmlStrEqual(data->level, (const xmlChar *) "multiple")) {
808 double numarray[1024];
809 int max = sizeof(numarray)/sizeof(numarray[0]);
811 node,
812 data->countPat,
813 data->fromPat,
814 numarray,
815 max);
816 if (amount > 0) {
818 numarray,
819 amount,
820 &tokens,
821 output);
822 }
823 } else if (xmlStrEqual(data->level, (const xmlChar *) "any")) {
824 amount = xsltNumberFormatGetAnyLevel(ctxt,
825 node,
826 data->countPat,
827 data->fromPat,
828 &number);
829 if (amount > 0) {
831 &number,
832 1,
833 &tokens,
834 output);
835 }
836 }
837
838 /*
839 * Unlike `match` patterns, `count` and `from` patterns can contain
840 * variable references, so we have to clear the pattern match
841 * cache if the "direct" matching algorithm was used.
842 */
843 if (data->countPat != NULL)
844 xsltCompMatchClearCache(ctxt, data->countPat);
845 if (data->fromPat != NULL)
846 xsltCompMatchClearCache(ctxt, data->fromPat);
847 }
848 /* Insert number as text node */
849 xsltCopyTextString(ctxt, ctxt->insert, xmlBufferContent(output), 0);
850
851 xmlBufferFree(output);
852
853XSLT_NUMBER_FORMAT_END:
854 if (tokens.start != NULL)
855 xmlFree(tokens.start);
856 if (tokens.end != NULL)
857 xmlFree(tokens.end);
858 for (i = 0;i < tokens.nTokens;i++) {
859 if (tokens.tokens[i].separator != NULL)
860 xmlFree(tokens.tokens[i].separator);
861 }
862}
863
864static int
866{
867 /* will hold total length of prefix/suffix without quote characters */
868 int count=0;
869 int len;
870
871 while (1) {
872 /*
873 * prefix / suffix ends at end of string or at
874 * first 'special' character
875 */
876 if (**format == 0)
877 return count;
878 /* if next character 'escaped' just count it */
879 if (**format == SYMBOL_QUOTE) {
880 if (*++(*format) == 0)
881 return -1;
882 }
883 else if (IS_SPECIAL(self, *format))
884 return count;
885 /*
886 * else treat percent/per-mille as special cases,
887 * depending on whether +ve or -ve
888 */
889 else {
890 /*
891 * for +ve prefix/suffix, allow only a
892 * single occurence of either
893 */
894 if (xsltUTF8Charcmp(*format, self->percent) == 0) {
895 if (info->is_multiplier_set)
896 return -1;
897 info->multiplier = 100;
898 info->is_multiplier_set = TRUE;
899 } else if (xsltUTF8Charcmp(*format, self->permille) == 0) {
900 if (info->is_multiplier_set)
901 return -1;
902 info->multiplier = 1000;
903 info->is_multiplier_set = TRUE;
904 }
905 }
906
907 if ((len=xmlUTF8Strsize(*format, 1)) < 1)
908 return -1;
909 count += len;
910 *format += len;
911 }
912}
913
956xmlXPathError
959 double number,
960 xmlChar **result)
961{
962 xmlXPathError status = XPATH_EXPRESSION_OK;
963 xmlBufferPtr buffer;
964 xmlChar *the_format, *prefix = NULL, *suffix = NULL;
965 xmlChar *nprefix, *nsuffix = NULL;
966 int prefix_length, suffix_length = 0, nprefix_length, nsuffix_length;
967 int exp10;
968 double scale;
969 int j, len = 0;
970 int self_grouping_len;
972 /*
973 * delayed_multiplier allows a 'trailing' percent or
974 * permille to be treated as suffix
975 */
976 int delayed_multiplier = 0;
977 /* flag to show no -ve format present for -ve number */
978 char default_sign = 0;
979 /* flag to show error found, should use default format */
980 char found_error = 0;
981
982 if (xmlStrlen(format) <= 0) {
984 "xsltFormatNumberConversion : "
985 "Invalid format (0-length)\n");
986 }
987 *result = NULL;
988 if (xmlXPathIsNaN(number)) {
989 if ((self == NULL) || (self->noNumber == NULL))
990 *result = xmlStrdup(BAD_CAST "NaN");
991 else
992 *result = xmlStrdup(self->noNumber);
993 return(status);
994 }
995
996 format_info.integer_hash = 0;
997 format_info.integer_digits = 0;
998 format_info.frac_digits = 0;
999 format_info.frac_hash = 0;
1000 format_info.group = -1;
1001 format_info.multiplier = 1;
1002 format_info.add_decimal = FALSE;
1003 format_info.is_multiplier_set = FALSE;
1004 format_info.is_negative_pattern = FALSE;
1005
1006 the_format = format;
1007
1008 /*
1009 * First we process the +ve pattern to get percent / permille,
1010 * as well as main format
1011 */
1012 prefix = the_format;
1013 prefix_length = xsltFormatNumberPreSuffix(self, &the_format, &format_info);
1014 if (prefix_length < 0) {
1015 found_error = 1;
1016 goto OUTPUT_NUMBER;
1017 }
1018
1019 /*
1020 * Here we process the "number" part of the format. It gets
1021 * a little messy because of the percent/per-mille - if that
1022 * appears at the end, it may be part of the suffix instead
1023 * of part of the number, so the variable delayed_multiplier
1024 * is used to handle it
1025 */
1026 self_grouping_len = xmlStrlen(self->grouping);
1027 while ((*the_format != 0) &&
1028 (xsltUTF8Charcmp(the_format, self->decimalPoint) != 0) &&
1029 (xsltUTF8Charcmp(the_format, self->patternSeparator) != 0)) {
1030
1031 if (delayed_multiplier != 0) {
1032 format_info.multiplier = delayed_multiplier;
1033 format_info.is_multiplier_set = TRUE;
1034 delayed_multiplier = 0;
1035 }
1036 if (xsltUTF8Charcmp(the_format, self->digit) == 0) {
1037 if (format_info.integer_digits > 0) {
1038 found_error = 1;
1039 goto OUTPUT_NUMBER;
1040 }
1041 format_info.integer_hash++;
1042 if (format_info.group >= 0)
1043 format_info.group++;
1044 } else if (xsltUTF8Charcmp(the_format, self->zeroDigit) == 0) {
1045 format_info.integer_digits++;
1046 if (format_info.group >= 0)
1047 format_info.group++;
1048 } else if ((self_grouping_len > 0) &&
1049 (!xmlStrncmp(the_format, self->grouping, self_grouping_len))) {
1050 /* Reset group count */
1051 format_info.group = 0;
1052 the_format += self_grouping_len;
1053 continue;
1054 } else if (xsltUTF8Charcmp(the_format, self->percent) == 0) {
1055 if (format_info.is_multiplier_set) {
1056 found_error = 1;
1057 goto OUTPUT_NUMBER;
1058 }
1059 delayed_multiplier = 100;
1060 } else if (xsltUTF8Charcmp(the_format, self->permille) == 0) {
1061 if (format_info.is_multiplier_set) {
1062 found_error = 1;
1063 goto OUTPUT_NUMBER;
1064 }
1065 delayed_multiplier = 1000;
1066 } else
1067 break; /* while */
1068
1069 if ((len=xmlUTF8Strsize(the_format, 1)) < 1) {
1070 found_error = 1;
1071 goto OUTPUT_NUMBER;
1072 }
1073 the_format += len;
1074
1075 }
1076
1077 /* We have finished the integer part, now work on fraction */
1078 if ( (*the_format != 0) &&
1079 (xsltUTF8Charcmp(the_format, self->decimalPoint) == 0) ) {
1080 format_info.add_decimal = TRUE;
1081 if ((len = xmlUTF8Strsize(the_format, 1)) < 1) {
1082 found_error = 1;
1083 goto OUTPUT_NUMBER;
1084 }
1085 the_format += len; /* Skip over the decimal */
1086 }
1087
1088 while (*the_format != 0) {
1089
1090 if (xsltUTF8Charcmp(the_format, self->zeroDigit) == 0) {
1091 if (format_info.frac_hash != 0) {
1092 found_error = 1;
1093 goto OUTPUT_NUMBER;
1094 }
1095 format_info.frac_digits++;
1096 } else if (xsltUTF8Charcmp(the_format, self->digit) == 0) {
1097 format_info.frac_hash++;
1098 } else if (xsltUTF8Charcmp(the_format, self->percent) == 0) {
1099 if (format_info.is_multiplier_set) {
1100 found_error = 1;
1101 goto OUTPUT_NUMBER;
1102 }
1103 delayed_multiplier = 100;
1104 if ((len = xmlUTF8Strsize(the_format, 1)) < 1) {
1105 found_error = 1;
1106 goto OUTPUT_NUMBER;
1107 }
1108 the_format += len;
1109 continue; /* while */
1110 } else if (xsltUTF8Charcmp(the_format, self->permille) == 0) {
1111 if (format_info.is_multiplier_set) {
1112 found_error = 1;
1113 goto OUTPUT_NUMBER;
1114 }
1115 delayed_multiplier = 1000;
1116 if ((len = xmlUTF8Strsize(the_format, 1)) < 1) {
1117 found_error = 1;
1118 goto OUTPUT_NUMBER;
1119 }
1120 the_format += len;
1121 continue; /* while */
1122 } else if (xsltUTF8Charcmp(the_format, self->grouping) != 0) {
1123 break; /* while */
1124 }
1125 if ((len = xmlUTF8Strsize(the_format, 1)) < 1) {
1126 found_error = 1;
1127 goto OUTPUT_NUMBER;
1128 }
1129 the_format += len;
1130 if (delayed_multiplier != 0) {
1131 format_info.multiplier = delayed_multiplier;
1132 delayed_multiplier = 0;
1133 format_info.is_multiplier_set = TRUE;
1134 }
1135 }
1136
1137 /*
1138 * If delayed_multiplier is set after processing the
1139 * "number" part, should be in suffix
1140 */
1141 if (delayed_multiplier != 0) {
1142 the_format -= len;
1143 delayed_multiplier = 0;
1144 }
1145
1146 suffix = the_format;
1147 suffix_length = xsltFormatNumberPreSuffix(self, &the_format, &format_info);
1148 if ( (suffix_length < 0) ||
1149 ((*the_format != 0) &&
1150 (xsltUTF8Charcmp(the_format, self->patternSeparator) != 0)) ) {
1151 found_error = 1;
1152 goto OUTPUT_NUMBER;
1153 }
1154
1155 /*
1156 * We have processed the +ve prefix, number part and +ve suffix.
1157 * If the number is -ve, we must substitute the -ve prefix / suffix
1158 */
1159 if (number < 0) {
1160 /*
1161 * Note that j is the number of UTF8 chars before the separator,
1162 * not the number of bytes! (bug 151975)
1163 */
1165 if (j < 0) {
1166 /* No -ve pattern present, so use default signing */
1167 default_sign = 1;
1168 }
1169 else {
1170 /* Skip over pattern separator (accounting for UTF8) */
1171 the_format = (xmlChar *)xmlUTF8Strpos(format, j + 1);
1172 /*
1173 * Flag changes interpretation of percent/permille
1174 * in -ve pattern
1175 */
1176 format_info.is_negative_pattern = TRUE;
1177 format_info.is_multiplier_set = FALSE;
1178
1179 /* First do the -ve prefix */
1180 nprefix = the_format;
1181 nprefix_length = xsltFormatNumberPreSuffix(self,
1182 &the_format, &format_info);
1183 if (nprefix_length<0) {
1184 found_error = 1;
1185 goto OUTPUT_NUMBER;
1186 }
1187
1188 while (*the_format != 0) {
1189 if ( (xsltUTF8Charcmp(the_format, (self)->percent) == 0) ||
1190 (xsltUTF8Charcmp(the_format, (self)->permille)== 0) ) {
1191 if (format_info.is_multiplier_set) {
1192 found_error = 1;
1193 goto OUTPUT_NUMBER;
1194 }
1195 format_info.is_multiplier_set = TRUE;
1196 delayed_multiplier = 1;
1197 }
1198 else if (IS_SPECIAL(self, the_format))
1199 delayed_multiplier = 0;
1200 else
1201 break; /* while */
1202 if ((len = xmlUTF8Strsize(the_format, 1)) < 1) {
1203 found_error = 1;
1204 goto OUTPUT_NUMBER;
1205 }
1206 the_format += len;
1207 }
1208 if (delayed_multiplier != 0) {
1209 format_info.is_multiplier_set = FALSE;
1210 the_format -= len;
1211 }
1212
1213 /* Finally do the -ve suffix */
1214 if (*the_format != 0) {
1215 nsuffix = the_format;
1216 nsuffix_length = xsltFormatNumberPreSuffix(self,
1217 &the_format, &format_info);
1218 if (nsuffix_length < 0) {
1219 found_error = 1;
1220 goto OUTPUT_NUMBER;
1221 }
1222 }
1223 else
1224 nsuffix_length = 0;
1225 if (*the_format != 0) {
1226 found_error = 1;
1227 goto OUTPUT_NUMBER;
1228 }
1229 /*
1230 * Here's another Java peculiarity:
1231 * if -ve prefix/suffix == +ve ones, discard & use default
1232 */
1233 if ((nprefix_length != prefix_length) ||
1234 (nsuffix_length != suffix_length) ||
1235 ((nprefix_length > 0) &&
1236 (xmlStrncmp(nprefix, prefix, prefix_length) !=0 )) ||
1237 ((nsuffix_length > 0) &&
1238 (xmlStrncmp(nsuffix, suffix, suffix_length) !=0 ))) {
1239 prefix = nprefix;
1240 prefix_length = nprefix_length;
1241 suffix = nsuffix;
1242 suffix_length = nsuffix_length;
1243 } /* else {
1244 default_sign = 1;
1245 }
1246 */
1247 }
1248 }
1249
1250OUTPUT_NUMBER:
1251 if (found_error != 0) {
1253 "xsltFormatNumberConversion : "
1254 "error in format string '%s', using default\n", format);
1255 default_sign = (number < 0.0) ? 1 : 0;
1256 prefix_length = suffix_length = 0;
1257 format_info.integer_hash = 0;
1258 format_info.integer_digits = 1;
1259 format_info.frac_digits = 1;
1260 format_info.frac_hash = 4;
1261 format_info.group = -1;
1262 format_info.multiplier = 1;
1263 format_info.add_decimal = TRUE;
1264 }
1265
1266 /* Apply multiplier */
1267 number *= (double)format_info.multiplier;
1268 switch (xmlXPathIsInf(number)) {
1269 case -1:
1270 if (self->minusSign == NULL)
1271 *result = xmlStrdup(BAD_CAST "-");
1272 else
1273 *result = xmlStrdup(self->minusSign);
1274 /* Intentional fall-through */
1275 case 1:
1276 if ((self == NULL) || (self->infinity == NULL))
1277 *result = xmlStrcat(*result, BAD_CAST "Infinity");
1278 else
1279 *result = xmlStrcat(*result, self->infinity);
1280 return(status);
1281 default:
1282 break;
1283 }
1284
1285 buffer = xmlBufferCreate();
1286 if (buffer == NULL) {
1287 return XPATH_MEMORY_ERROR;
1288 }
1289
1290 /* Ready to output our number. First see if "default sign" is required */
1291 if (default_sign != 0)
1292 xmlBufferAdd(buffer, self->minusSign, xmlUTF8Strsize(self->minusSign, 1));
1293
1294 /* Put the prefix into the buffer */
1295 for (j = 0; j < prefix_length; ) {
1296 if (*prefix == SYMBOL_QUOTE)
1297 prefix++;
1299 xmlBufferAdd(buffer, prefix, len);
1300 prefix += len;
1301 j += len;
1302 }
1303
1304 /* Round to n digits */
1305 number = fabs(number);
1306 exp10 = format_info.frac_digits + format_info.frac_hash;
1307 /* DBL_MAX_10_EXP should be 308 on IEEE platforms. */
1308 if (exp10 > DBL_MAX_10_EXP) {
1309 if (format_info.frac_digits > DBL_MAX_10_EXP) {
1310 format_info.frac_digits = DBL_MAX_10_EXP;
1311 format_info.frac_hash = 0;
1312 } else {
1313 format_info.frac_hash = DBL_MAX_10_EXP - format_info.frac_digits;
1314 }
1315 exp10 = DBL_MAX_10_EXP;
1316 }
1317 scale = pow(10.0, (double) exp10);
1318 number += .5 / scale;
1319 number -= fmod(number, 1 / scale);
1320
1321 /* Next do the integer part of the number */
1322 if ((self->grouping != NULL) &&
1323 (self->grouping[0] != 0)) {
1324 int gchar;
1325
1326 len = xmlStrlen(self->grouping);
1327 gchar = xsltGetUTF8Char(self->grouping, &len);
1329 format_info.integer_digits,
1330 format_info.group,
1331 gchar, len);
1332 } else
1334 format_info.integer_digits,
1335 format_info.group,
1336 ',', 1);
1337
1338 /* Special case: java treats '.#' like '.0', '.##' like '.0#', etc. */
1339 if ((format_info.integer_digits + format_info.integer_hash +
1340 format_info.frac_digits == 0) && (format_info.frac_hash > 0)) {
1341 ++format_info.frac_digits;
1342 --format_info.frac_hash;
1343 }
1344
1345 /* Add leading zero, if required */
1346 if ((floor(number) == 0) &&
1347 (format_info.integer_digits + format_info.frac_digits == 0)) {
1348 xmlBufferAdd(buffer, self->zeroDigit, xmlUTF8Strsize(self->zeroDigit, 1));
1349 }
1350
1351 /* Next the fractional part, if required */
1352 if (format_info.frac_digits + format_info.frac_hash == 0) {
1353 if (format_info.add_decimal)
1354 xmlBufferAdd(buffer, self->decimalPoint,
1355 xmlUTF8Strsize(self->decimalPoint, 1));
1356 }
1357 else {
1358 number -= floor(number);
1359 if ((number != 0) || (format_info.frac_digits != 0)) {
1360 xmlBufferAdd(buffer, self->decimalPoint,
1361 xmlUTF8Strsize(self->decimalPoint, 1));
1362 number = floor(scale * number + 0.5);
1363 for (j = format_info.frac_hash; j > 0; j--) {
1364 if (fmod(number, 10.0) >= 1.0)
1365 break; /* for */
1366 number /= 10.0;
1367 }
1369 format_info.frac_digits + j,
1370 0, 0, 0);
1371 }
1372 }
1373 /* Put the suffix into the buffer */
1374 for (j = 0; j < suffix_length; ) {
1375 if (*suffix == SYMBOL_QUOTE)
1376 suffix++;
1377 len = xmlUTF8Strsize(suffix, 1);
1378 xmlBufferAdd(buffer, suffix, len);
1379 suffix += len;
1380 j += len;
1381 }
1382
1383 *result = xmlStrdup(xmlBufferContent(buffer));
1384 xmlBufferFree(buffer);
1385 return status;
1386}
1387
#define MAX_TOKENS
Definition: numbers.c:42
static char alpha_lower_list[]
Definition: numbers.c:62
static int xsltTestCompMatchCount(xsltTransformContextPtr context, xmlNodePtr node, xsltCompMatchPtr countPat, xmlNodePtr cur)
Definition: numbers.c:559
#define SYMBOL_QUOTE
Definition: numbers.c:37
static int xsltIsDigitZero(int ch)
Definition: numbers.c:119
static void xsltNumberFormatInsertNumbers(xsltNumberDataPtr data, double *numbers, int numbers_max, xsltFormatPtr tokens, xmlBufferPtr buffer)
Definition: numbers.c:443
static int xsltNumberFormatGetMultipleLevel(xsltTransformContextPtr context, xmlNodePtr node, xsltCompMatchPtr countPat, xsltCompMatchPtr fromPat, double *array, int max)
Definition: numbers.c:650
#define IS_DIGIT_ZERO(x)
Definition: numbers.c:115
static char alpha_upper_list[]
Definition: numbers.c:61
static xsltFormatToken default_token
Definition: numbers.c:63
static int xsltNumberFormatGetValue(xmlXPathContextPtr context, xmlNodePtr node, const xmlChar *value, double *number)
Definition: numbers.c:708
#define DEFAULT_TOKEN
Definition: numbers.c:39
static void xsltNumberFormatDecimal(xmlBufferPtr buffer, double number, int digit_zero, int width, int digitsPerGroup, int groupingCharacter, int groupingCharacterLen)
Definition: numbers.c:139
xsltFormat * xsltFormatPtr
Definition: numbers.c:53
static void xsltNumberFormatRoman(xsltNumberDataPtr data, xmlBufferPtr buffer, double number, int is_upper)
Definition: numbers.c:260
xmlXPathError xsltFormatNumberConversion(xsltDecimalFormatPtr self, xmlChar *format, double number, xmlChar **result)
Definition: numbers.c:957
static int xsltIsLetterDigit(int val)
Definition: numbers.c:96
#define TRUE
Definition: numbers.c:34
#define FALSE
Definition: numbers.c:33
xsltFormatToken * xsltFormatTokenPtr
Definition: numbers.c:45
#define DEFAULT_SEPARATOR
Definition: numbers.c:40
#define IS_SPECIAL(self, letter)
Definition: numbers.c:108
static void xsltNumberFormatTokenize(const xmlChar *format, xsltFormatPtr tokens)
Definition: numbers.c:335
static int xsltUTF8Charcmp(xmlChar *utf1, xmlChar *utf2)
Definition: numbers.c:82
static int xsltNumberFormatGetAnyLevel(xsltTransformContextPtr context, xmlNodePtr node, xsltCompMatchPtr countPat, xsltCompMatchPtr fromPat, double *array)
Definition: numbers.c:596
static int xsltFormatNumberPreSuffix(xsltDecimalFormatPtr self, xmlChar **format, xsltFormatNumberInfoPtr info)
Definition: numbers.c:865
static void xsltNumberFormatAlpha(xsltNumberDataPtr data, xmlBufferPtr buffer, double number, int is_upper)
Definition: numbers.c:213
#define IS_DIGIT_ONE(x)
Definition: numbers.c:116
void xsltNumberFormat(xsltTransformContextPtr ctxt, xsltNumberDataPtr data, xmlNodePtr node)
Definition: numbers.c:744
#define is_upper(c)
Definition: astoll.c:45
#define xmlIsDigitQ(c)
Definition: chvalid.h:152
#define xmlIsIdeographicQ(c)
Definition: chvalid.h:184
#define xmlIsBaseCharQ(c)
Definition: chvalid.h:76
format_info
#define NULL
Definition: types.h:112
int xsltTestCompMatchList(xsltTransformContextPtr ctxt, xmlNodePtr node, xsltCompMatchPtr comp)
Definition: pattern.c:1132
void xsltCompMatchClearCache(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp)
Definition: pattern.c:1155
xmlNodePtr xsltCopyTextString(xsltTransformContextPtr ctxt, xmlNodePtr target, const xmlChar *string, int noescape)
Definition: transform.c:881
unsigned char ch[4][2]
Definition: console.c:118
#define DBL_MAX_10_EXP
Definition: float.h:22
#define CHAR_BIT
Definition: limits.h:6
_ACRTIMP double __cdecl fabs(double)
_ACRTIMP double __cdecl fmod(double, double)
_ACRTIMP double __cdecl floor(double)
Definition: floor.c:18
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
switch(r->id)
Definition: btrfs.c:3046
double pow(double x, double y)
Definition: freeldr.c:178
FxCollectionEntry * cur
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLint GLint GLsizei width
Definition: gl.h:1546
GLenum GLenum GLenum GLenum GLenum scale
Definition: glext.h:9032
GLuint buffer
Definition: glext.h:5915
GLsizei const GLvoid * pointer
Definition: glext.h:5848
GLubyte * pattern
Definition: glext.h:7787
GLuint GLfloat * val
Definition: glext.h:7180
GLuint64EXT * result
Definition: glext.h:11304
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat token
Definition: glfuncs.h:210
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
if(dx< 0)
Definition: linetemp.h:194
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static unsigned int number
Definition: dsound.c:1479
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
Definition: string.c:91
XMLPUBFUN int xmlCopyCharMultiByte(xmlChar *out, int val)
static unsigned __int64 next
Definition: rand_nt.c:6
xmlFreeFunc xmlFree
Definition: globals.c:184
xmlChar * decimalPoint
xmlChar * patternSeparator
xmlChar * separator
Definition: numbers.c:47
xsltFormatToken tokens[MAX_TOKENS]
Definition: numbers.c:56
xmlChar * start
Definition: numbers.c:55
xmlChar * end
Definition: numbers.c:58
int nTokens
Definition: numbers.c:57
xmlXPathContextPtr xpathCtxt
Definition: undname.c:54
Definition: http.c:7252
Definition: format.c:58
Definition: import.c:81
Definition: ps.c:97
#define max(a, b)
Definition: svc.c:63
xmlChar * xsltEvalAttrValueTemplate(xsltTransformContextPtr ctxt, xmlNodePtr inst, const xmlChar *name, const xmlChar *ns)
Definition: templates.c:410
Character const *const prefix
Definition: tempnam.cpp:195
Definition: dlist.c:348
Definition: pdh_main.c:96
_In_ size_t cnt
Definition: wcstombs.cpp:43
XMLPUBFUN int xmlUTF8Strloc(const xmlChar *utf, const xmlChar *utfchar)
Definition: xmlstring.c:926
XMLPUBFUN xmlChar * xmlStrndup(const xmlChar *cur, int len)
Definition: xmlstring.c:45
XMLPUBFUN int xmlStrlen(const xmlChar *str)
Definition: xmlstring.c:428
XMLPUBFUN const xmlChar * xmlUTF8Strpos(const xmlChar *utf, int pos)
Definition: xmlstring.c:894
XMLPUBFUN int xmlStrncmp(const xmlChar *str1, const xmlChar *str2, int len)
Definition: xmlstring.c:215
XMLPUBFUN xmlChar * xmlStrcat(xmlChar *cur, const xmlChar *add)
Definition: xmlstring.c:524
XMLPUBFUN int xmlUTF8Strsize(const xmlChar *utf, int len)
Definition: xmlstring.c:833
#define BAD_CAST
Definition: xmlstring.h:35
XMLPUBFUN int xmlStrEqual(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:162
unsigned char xmlChar
Definition: xmlstring.h:28
XMLPUBFUN xmlChar * xmlStrdup(const xmlChar *cur)
Definition: xmlstring.c:69
#define XSLT_NAMESPACE
Definition: xslt.h:46
void xsltTransformError(xsltTransformContextPtr ctxt, xsltStylesheetPtr style, xmlNodePtr node, const char *msg,...)
Definition: xsltutils.c:762
xmlGenericErrorFunc xsltGenericError
Definition: xsltutils.c:586
int xsltGetUTF8Char(const unsigned char *utf, int *len)
Definition: xsltutils.c:251
int xsltGetUTF8CharZ(const unsigned char *utf, int *len)
Definition: xsltutils.c:319
void * xsltGenericErrorContext
Definition: xsltutils.c:587