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