ReactOS  0.4.10-dev-244-gb941574
numbers.c File Reference
#include "precomp.h"
Include dependency graph for numbers.c:

Go to the source code of this file.

Classes

struct  _xsltFormatToken
 
struct  _xsltFormat
 

Macros

#define FALSE   (0 == 1)
 
#define TRUE   (1 == 1)
 
#define SYMBOL_QUOTE   ((xmlChar)'\'')
 
#define DEFAULT_TOKEN   (xmlChar)'0'
 
#define DEFAULT_SEPARATOR   "."
 
#define MAX_TOKENS   1024
 
#define IS_SPECIAL(self, letter)
 
#define IS_DIGIT_ZERO(x)   xsltIsDigitZero(x)
 
#define IS_DIGIT_ONE(x)   xsltIsDigitZero((xmlChar)(x)-1)
 

Typedefs

typedef struct _xsltFormatToken xsltFormatToken
 
typedef xsltFormatTokenxsltFormatTokenPtr
 
typedef struct _xsltFormat xsltFormat
 
typedef xsltFormatxsltFormatPtr
 

Functions

static int xsltUTF8Charcmp (xmlChar *utf1, xmlChar *utf2)
 
static int xsltIsDigitZero (unsigned int ch)
 
static void xsltNumberFormatDecimal (xmlBufferPtr buffer, double number, int digit_zero, int width, int digitsPerGroup, int groupingCharacter, int groupingCharacterLen)
 
static void xsltNumberFormatAlpha (xsltNumberDataPtr data, xmlBufferPtr buffer, double number, int is_upper)
 
static void xsltNumberFormatRoman (xsltNumberDataPtr data, xmlBufferPtr buffer, double number, int is_upper)
 
static void xsltNumberFormatTokenize (const xmlChar *format, xsltFormatPtr tokens)
 
static void xsltNumberFormatInsertNumbers (xsltNumberDataPtr data, double *numbers, int numbers_max, xsltFormatPtr tokens, xmlBufferPtr buffer)
 
static int xsltTestCompMatchCount (xsltTransformContextPtr context, xmlNodePtr node, xsltCompMatchPtr countPat, xmlNodePtr cur)
 
static int xsltNumberFormatGetAnyLevel (xsltTransformContextPtr context, xmlNodePtr node, xsltCompMatchPtr countPat, xsltCompMatchPtr fromPat, double *array)
 
static int xsltNumberFormatGetMultipleLevel (xsltTransformContextPtr context, xmlNodePtr node, xsltCompMatchPtr countPat, xsltCompMatchPtr fromPat, double *array, int max)
 
static int xsltNumberFormatGetValue (xmlXPathContextPtr context, xmlNodePtr node, const xmlChar *value, double *number)
 
void xsltNumberFormat (xsltTransformContextPtr ctxt, xsltNumberDataPtr data, xmlNodePtr node)
 
static int xsltFormatNumberPreSuffix (xsltDecimalFormatPtr self, xmlChar **format, xsltFormatNumberInfoPtr info)
 
xmlXPathError xsltFormatNumberConversion (xsltDecimalFormatPtr self, xmlChar *format, double number, xmlChar **result)
 

Variables

static char alpha_upper_list [] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
 
static char alpha_lower_list [] = "abcdefghijklmnopqrstuvwxyz"
 
static xsltFormatToken default_token
 

Macro Definition Documentation

#define DEFAULT_SEPARATOR   "."

Definition at line 23 of file numbers.c.

Referenced by xsltNumberFormatInsertNumbers(), and xsltNumberFormatTokenize().

#define DEFAULT_TOKEN   (xmlChar)'0'

Definition at line 22 of file numbers.c.

Referenced by xsltNumberFormatTokenize().

#define IS_DIGIT_ONE (   x)    xsltIsDigitZero((xmlChar)(x)-1)

Definition at line 93 of file numbers.c.

Referenced by xsltNumberFormatTokenize().

#define IS_DIGIT_ZERO (   x)    xsltIsDigitZero(x)

Definition at line 92 of file numbers.c.

Referenced by xsltNumberFormatInsertNumbers(), and xsltNumberFormatTokenize().

#define IS_SPECIAL (   self,
  letter 
)
Value:
((xsltUTF8Charcmp((letter), (self)->zeroDigit) == 0) || \
(xsltUTF8Charcmp((letter), (self)->digit) == 0) || \
(xsltUTF8Charcmp((letter), (self)->decimalPoint) == 0) || \
(xsltUTF8Charcmp((letter), (self)->grouping) == 0) || \
(xsltUTF8Charcmp((letter), (self)->patternSeparator) == 0))
static int xsltUTF8Charcmp(xmlChar *utf1, xmlChar *utf2)
Definition: numbers.c:65

Definition at line 85 of file numbers.c.

Referenced by xsltFormatNumberConversion(), and xsltFormatNumberPreSuffix().

#define MAX_TOKENS   1024

Definition at line 25 of file numbers.c.

Referenced by xsltNumberFormatTokenize().

#define SYMBOL_QUOTE   ((xmlChar)'\'')

Definition at line 20 of file numbers.c.

Referenced by xsltFormatNumberConversion(), and xsltFormatNumberPreSuffix().

Typedef Documentation

Definition at line 35 of file numbers.c.

Definition at line 36 of file numbers.c.

Definition at line 27 of file numbers.c.

Definition at line 28 of file numbers.c.

Function Documentation

xmlXPathError xsltFormatNumberConversion ( xsltDecimalFormatPtr  self,
xmlChar format,
double  number,
xmlChar **  result 
)

xsltFormatNumberConversion: : the decimal format : the format requested : the value to format

Returns
: the place to ouput the result

format-number() uses the JDK 1.1 DecimalFormat class:

http://java.sun.com/products/jdk/1.1/docs/api/java.text.DecimalFormat.html

Structure:

pattern := subpattern{;subpattern} subpattern := {prefix}integer{.fraction}{suffix} prefix := '\u0000'..'\uFFFD' - specialCharacters suffix := '\u0000'..'\uFFFD' - specialCharacters integer := '#'* '0'* '0' fraction := '0'* '#'*

Notation: X* 0 or more instances of X (X | Y) either X or Y. X..Y any character from X up to Y, inclusive. S - T characters in S, except those in T

Special Characters:

Symbol Meaning 0 a digit

a digit, zero shows as absent

. placeholder for decimal separator , placeholder for grouping separator. ; separates formats.

  • default negative prefix. % multiply by 100 and show as percentage ? multiply by 1000 and show as per mille X any other characters can be used in the prefix or suffix ' used to quote special characters in a prefix or suffix.

Returns a possible XPath error

Definition at line 910 of file numbers.c.

Referenced by xsltFormatNumberFunction().

914 {
915  xmlXPathError status = XPATH_EXPRESSION_OK;
917  xmlChar *the_format, *prefix = NULL, *suffix = NULL;
918  xmlChar *nprefix, *nsuffix = NULL;
919  xmlChar pchar;
920  int prefix_length, suffix_length = 0, nprefix_length, nsuffix_length;
921  double scale;
922  int j, len;
923  int self_grouping_len;
925  /*
926  * delayed_multiplier allows a 'trailing' percent or
927  * permille to be treated as suffix
928  */
929  int delayed_multiplier = 0;
930  /* flag to show no -ve format present for -ve number */
931  char default_sign = 0;
932  /* flag to show error found, should use default format */
933  char found_error = 0;
934 
935  if (xmlStrlen(format) <= 0) {
937  "xsltFormatNumberConversion : "
938  "Invalid format (0-length)\n");
939  }
940  *result = NULL;
941  switch (xmlXPathIsInf(number)) {
942  case -1:
943  if (self->minusSign == NULL)
944  *result = xmlStrdup(BAD_CAST "-");
945  else
946  *result = xmlStrdup(self->minusSign);
947  /* no-break on purpose */
948  case 1:
949  if ((self == NULL) || (self->infinity == NULL))
950  *result = xmlStrcat(*result, BAD_CAST "Infinity");
951  else
952  *result = xmlStrcat(*result, self->infinity);
953  return(status);
954  default:
955  if (xmlXPathIsNaN(number)) {
956  if ((self == NULL) || (self->noNumber == NULL))
957  *result = xmlStrdup(BAD_CAST "NaN");
958  else
959  *result = xmlStrdup(self->noNumber);
960  return(status);
961  }
962  }
963 
964  buffer = xmlBufferCreate();
965  if (buffer == NULL) {
966  return XPATH_MEMORY_ERROR;
967  }
968 
969  format_info.integer_hash = 0;
970  format_info.integer_digits = 0;
971  format_info.frac_digits = 0;
972  format_info.frac_hash = 0;
973  format_info.group = -1;
974  format_info.multiplier = 1;
975  format_info.add_decimal = FALSE;
976  format_info.is_multiplier_set = FALSE;
977  format_info.is_negative_pattern = FALSE;
978 
979  the_format = format;
980 
981  /*
982  * First we process the +ve pattern to get percent / permille,
983  * as well as main format
984  */
985  prefix = the_format;
986  prefix_length = xsltFormatNumberPreSuffix(self, &the_format, &format_info);
987  if (prefix_length < 0) {
988  found_error = 1;
989  goto OUTPUT_NUMBER;
990  }
991 
992  /*
993  * Here we process the "number" part of the format. It gets
994  * a little messy because of the percent/per-mille - if that
995  * appears at the end, it may be part of the suffix instead
996  * of part of the number, so the variable delayed_multiplier
997  * is used to handle it
998  */
999  self_grouping_len = xmlStrlen(self->grouping);
1000  while ((*the_format != 0) &&
1001  (xsltUTF8Charcmp(the_format, self->decimalPoint) != 0) &&
1002  (xsltUTF8Charcmp(the_format, self->patternSeparator) != 0)) {
1003 
1004  if (delayed_multiplier != 0) {
1005  format_info.multiplier = delayed_multiplier;
1006  format_info.is_multiplier_set = TRUE;
1007  delayed_multiplier = 0;
1008  }
1009  if (xsltUTF8Charcmp(the_format, self->digit) == 0) {
1010  if (format_info.integer_digits > 0) {
1011  found_error = 1;
1012  goto OUTPUT_NUMBER;
1013  }
1014  format_info.integer_hash++;
1015  if (format_info.group >= 0)
1016  format_info.group++;
1017  } else if (xsltUTF8Charcmp(the_format, self->zeroDigit) == 0) {
1018  format_info.integer_digits++;
1019  if (format_info.group >= 0)
1020  format_info.group++;
1021  } else if ((self_grouping_len > 0) &&
1022  (!xmlStrncmp(the_format, self->grouping, self_grouping_len))) {
1023  /* Reset group count */
1024  format_info.group = 0;
1025  the_format += self_grouping_len;
1026  continue;
1027  } else if (xsltUTF8Charcmp(the_format, self->percent) == 0) {
1028  if (format_info.is_multiplier_set) {
1029  found_error = 1;
1030  goto OUTPUT_NUMBER;
1031  }
1032  delayed_multiplier = 100;
1033  } else if (xsltUTF8Charcmp(the_format, self->permille) == 0) {
1034  if (format_info.is_multiplier_set) {
1035  found_error = 1;
1036  goto OUTPUT_NUMBER;
1037  }
1038  delayed_multiplier = 1000;
1039  } else
1040  break; /* while */
1041 
1042  if ((len=xmlUTF8Strsize(the_format, 1)) < 1) {
1043  found_error = 1;
1044  goto OUTPUT_NUMBER;
1045  }
1046  the_format += len;
1047 
1048  }
1049 
1050  /* We have finished the integer part, now work on fraction */
1051  if ( (*the_format != 0) &&
1052  (xsltUTF8Charcmp(the_format, self->decimalPoint) == 0) ) {
1053  format_info.add_decimal = TRUE;
1054  if ((len = xmlUTF8Strsize(the_format, 1)) < 1) {
1055  found_error = 1;
1056  goto OUTPUT_NUMBER;
1057  }
1058  the_format += len; /* Skip over the decimal */
1059  }
1060 
1061  while (*the_format != 0) {
1062 
1063  if (xsltUTF8Charcmp(the_format, self->zeroDigit) == 0) {
1064  if (format_info.frac_hash != 0) {
1065  found_error = 1;
1066  goto OUTPUT_NUMBER;
1067  }
1068  format_info.frac_digits++;
1069  } else if (xsltUTF8Charcmp(the_format, self->digit) == 0) {
1070  format_info.frac_hash++;
1071  } else if (xsltUTF8Charcmp(the_format, self->percent) == 0) {
1072  if (format_info.is_multiplier_set) {
1073  found_error = 1;
1074  goto OUTPUT_NUMBER;
1075  }
1076  delayed_multiplier = 100;
1077  if ((len = xmlUTF8Strsize(the_format, 1)) < 1) {
1078  found_error = 1;
1079  goto OUTPUT_NUMBER;
1080  }
1081  the_format += len;
1082  continue; /* while */
1083  } else if (xsltUTF8Charcmp(the_format, self->permille) == 0) {
1084  if (format_info.is_multiplier_set) {
1085  found_error = 1;
1086  goto OUTPUT_NUMBER;
1087  }
1088  delayed_multiplier = 1000;
1089  if ((len = xmlUTF8Strsize(the_format, 1)) < 1) {
1090  found_error = 1;
1091  goto OUTPUT_NUMBER;
1092  }
1093  the_format += len;
1094  continue; /* while */
1095  } else if (xsltUTF8Charcmp(the_format, self->grouping) != 0) {
1096  break; /* while */
1097  }
1098  if ((len = xmlUTF8Strsize(the_format, 1)) < 1) {
1099  found_error = 1;
1100  goto OUTPUT_NUMBER;
1101  }
1102  the_format += len;
1103  if (delayed_multiplier != 0) {
1104  format_info.multiplier = delayed_multiplier;
1105  delayed_multiplier = 0;
1106  format_info.is_multiplier_set = TRUE;
1107  }
1108  }
1109 
1110  /*
1111  * If delayed_multiplier is set after processing the
1112  * "number" part, should be in suffix
1113  */
1114  if (delayed_multiplier != 0) {
1115  the_format -= len;
1116  delayed_multiplier = 0;
1117  }
1118 
1119  suffix = the_format;
1120  suffix_length = xsltFormatNumberPreSuffix(self, &the_format, &format_info);
1121  if ( (suffix_length < 0) ||
1122  ((*the_format != 0) &&
1123  (xsltUTF8Charcmp(the_format, self->patternSeparator) != 0)) ) {
1124  found_error = 1;
1125  goto OUTPUT_NUMBER;
1126  }
1127 
1128  /*
1129  * We have processed the +ve prefix, number part and +ve suffix.
1130  * If the number is -ve, we must substitute the -ve prefix / suffix
1131  */
1132  if (number < 0) {
1133  /*
1134  * Note that j is the number of UTF8 chars before the separator,
1135  * not the number of bytes! (bug 151975)
1136  */
1138  if (j < 0) {
1139  /* No -ve pattern present, so use default signing */
1140  default_sign = 1;
1141  }
1142  else {
1143  /* Skip over pattern separator (accounting for UTF8) */
1144  the_format = (xmlChar *)xmlUTF8Strpos(format, j + 1);
1145  /*
1146  * Flag changes interpretation of percent/permille
1147  * in -ve pattern
1148  */
1149  format_info.is_negative_pattern = TRUE;
1150  format_info.is_multiplier_set = FALSE;
1151 
1152  /* First do the -ve prefix */
1153  nprefix = the_format;
1154  nprefix_length = xsltFormatNumberPreSuffix(self,
1155  &the_format, &format_info);
1156  if (nprefix_length<0) {
1157  found_error = 1;
1158  goto OUTPUT_NUMBER;
1159  }
1160 
1161  while (*the_format != 0) {
1162  if ( (xsltUTF8Charcmp(the_format, (self)->percent) == 0) ||
1163  (xsltUTF8Charcmp(the_format, (self)->permille)== 0) ) {
1164  if (format_info.is_multiplier_set) {
1165  found_error = 1;
1166  goto OUTPUT_NUMBER;
1167  }
1168  format_info.is_multiplier_set = TRUE;
1169  delayed_multiplier = 1;
1170  }
1171  else if (IS_SPECIAL(self, the_format))
1172  delayed_multiplier = 0;
1173  else
1174  break; /* while */
1175  if ((len = xmlUTF8Strsize(the_format, 1)) < 1) {
1176  found_error = 1;
1177  goto OUTPUT_NUMBER;
1178  }
1179  the_format += len;
1180  }
1181  if (delayed_multiplier != 0) {
1182  format_info.is_multiplier_set = FALSE;
1183  the_format -= len;
1184  }
1185 
1186  /* Finally do the -ve suffix */
1187  if (*the_format != 0) {
1188  nsuffix = the_format;
1189  nsuffix_length = xsltFormatNumberPreSuffix(self,
1190  &the_format, &format_info);
1191  if (nsuffix_length < 0) {
1192  found_error = 1;
1193  goto OUTPUT_NUMBER;
1194  }
1195  }
1196  else
1197  nsuffix_length = 0;
1198  if (*the_format != 0) {
1199  found_error = 1;
1200  goto OUTPUT_NUMBER;
1201  }
1202  /*
1203  * Here's another Java peculiarity:
1204  * if -ve prefix/suffix == +ve ones, discard & use default
1205  */
1206  if ((nprefix_length != prefix_length) ||
1207  (nsuffix_length != suffix_length) ||
1208  ((nprefix_length > 0) &&
1209  (xmlStrncmp(nprefix, prefix, prefix_length) !=0 )) ||
1210  ((nsuffix_length > 0) &&
1211  (xmlStrncmp(nsuffix, suffix, suffix_length) !=0 ))) {
1212  prefix = nprefix;
1213  prefix_length = nprefix_length;
1214  suffix = nsuffix;
1215  suffix_length = nsuffix_length;
1216  } /* else {
1217  default_sign = 1;
1218  }
1219  */
1220  }
1221  }
1222 
1223 OUTPUT_NUMBER:
1224  if (found_error != 0) {
1226  "xsltFormatNumberConversion : "
1227  "error in format string '%s', using default\n", format);
1228  default_sign = (number < 0.0) ? 1 : 0;
1229  prefix_length = suffix_length = 0;
1230  format_info.integer_hash = 0;
1231  format_info.integer_digits = 1;
1232  format_info.frac_digits = 1;
1233  format_info.frac_hash = 4;
1234  format_info.group = -1;
1235  format_info.multiplier = 1;
1236  format_info.add_decimal = TRUE;
1237  }
1238 
1239  /* Ready to output our number. First see if "default sign" is required */
1240  if (default_sign != 0)
1241  xmlBufferAdd(buffer, self->minusSign, xmlUTF8Strsize(self->minusSign, 1));
1242 
1243  /* Put the prefix into the buffer */
1244  for (j = 0; j < prefix_length; j++) {
1245  if ((pchar = *prefix++) == SYMBOL_QUOTE) {
1246  len = xmlUTF8Strsize(prefix, 1);
1247  xmlBufferAdd(buffer, prefix, len);
1248  prefix += len;
1249  j += len - 1; /* length of symbol less length of quote */
1250  } else
1251  xmlBufferAdd(buffer, &pchar, 1);
1252  }
1253 
1254  /* Next do the integer part of the number */
1255  number = fabs(number) * (double)format_info.multiplier;
1256  scale = pow(10.0, (double)(format_info.frac_digits + format_info.frac_hash));
1257  number = floor((scale * number + 0.5)) / scale;
1258  if ((self->grouping != NULL) &&
1259  (self->grouping[0] != 0)) {
1260 
1261  len = xmlStrlen(self->grouping);
1262  pchar = xsltGetUTF8Char(self->grouping, &len);
1263  xsltNumberFormatDecimal(buffer, floor(number), self->zeroDigit[0],
1264  format_info.integer_digits,
1265  format_info.group,
1266  pchar, len);
1267  } else
1268  xsltNumberFormatDecimal(buffer, floor(number), self->zeroDigit[0],
1269  format_info.integer_digits,
1270  format_info.group,
1271  ',', 1);
1272 
1273  /* Special case: java treats '.#' like '.0', '.##' like '.0#', etc. */
1274  if ((format_info.integer_digits + format_info.integer_hash +
1275  format_info.frac_digits == 0) && (format_info.frac_hash > 0)) {
1276  ++format_info.frac_digits;
1277  --format_info.frac_hash;
1278  }
1279 
1280  /* Add leading zero, if required */
1281  if ((floor(number) == 0) &&
1282  (format_info.integer_digits + format_info.frac_digits == 0)) {
1283  xmlBufferAdd(buffer, self->zeroDigit, xmlUTF8Strsize(self->zeroDigit, 1));
1284  }
1285 
1286  /* Next the fractional part, if required */
1287  if (format_info.frac_digits + format_info.frac_hash == 0) {
1288  if (format_info.add_decimal)
1289  xmlBufferAdd(buffer, self->decimalPoint,
1290  xmlUTF8Strsize(self->decimalPoint, 1));
1291  }
1292  else {
1293  number -= floor(number);
1294  if ((number != 0) || (format_info.frac_digits != 0)) {
1295  xmlBufferAdd(buffer, self->decimalPoint,
1296  xmlUTF8Strsize(self->decimalPoint, 1));
1297  number = floor(scale * number + 0.5);
1298  for (j = format_info.frac_hash; j > 0; j--) {
1299  if (fmod(number, 10.0) >= 1.0)
1300  break; /* for */
1301  number /= 10.0;
1302  }
1303  xsltNumberFormatDecimal(buffer, floor(number), self->zeroDigit[0],
1304  format_info.frac_digits + j,
1305  0, 0, 0);
1306  }
1307  }
1308  /* Put the suffix into the buffer */
1309  for (j = 0; j < suffix_length; j++) {
1310  if ((pchar = *suffix++) == SYMBOL_QUOTE) {
1311  len = xmlUTF8Strsize(suffix, 1);
1312  xmlBufferAdd(buffer, suffix, len);
1313  suffix += len;
1314  j += len - 1; /* length of symbol less length of escape */
1315  } else
1316  xmlBufferAdd(buffer, &pchar, 1);
1317  }
1318 
1319  *result = xmlStrdup(xmlBufferContent(buffer));
1320  xmlBufferFree(buffer);
1321  return status;
1322 }
#define SYMBOL_QUOTE
Definition: numbers.c:20
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint 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 GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble const GLfloat const GLdouble const GLfloat GLenum GLint GLint GLint GLint GLint GLint j
Definition: glfuncs.h:98
XMLPUBFUN const xmlChar *XMLCALL xmlBufferContent(const xmlBuffer *buf)
static int xsltUTF8Charcmp(xmlChar *utf1, xmlChar *utf2)
Definition: numbers.c:65
XMLPUBFUN const xmlChar *XMLCALL xmlUTF8Strpos(const xmlChar *utf, int pos)
Definition: xmlstring.c:895
XMLPUBFUN int XMLCALL xmlStrlen(const xmlChar *str)
Definition: xmlstring.c:422
XMLPUBFUN void XMLCALL xmlBufferFree(xmlBufferPtr buf)
xmlChar * decimalPoint
#define TRUE
Definition: numbers.c:17
GLuint buffer
Definition: glext.h:5915
XMLPUBFUN xmlBufferPtr XMLCALL xmlBufferCreate(void)
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
format_info
GLfloat scale
Definition: m_xform.h:122
int xsltGetUTF8Char(const unsigned char *utf, int *len)
Definition: xsltutils.c:227
float pow(float __x, int __y)
Definition: _cmath.h:458
static size_t double number
Definition: printf.c:64
XMLPUBFUN xmlChar *XMLCALL xmlStrcat(xmlChar *cur, const xmlChar *add)
Definition: xmlstring.c:526
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
Definition: string.c:80
smooth NULL
Definition: ftsmooth.c:416
#define BAD_CAST
Definition: xmlstring.h:35
XMLPUBFUN int XMLCALL xmlUTF8Strloc(const xmlChar *utf, const xmlChar *utfchar)
Definition: xmlstring.c:927
XMLPUBFUN int XMLCALL xmlUTF8Strsize(const xmlChar *utf, int len)
Definition: xmlstring.c:833
_Check_return_ double __cdecl fmod(_In_ double x, _In_ double y)
XMLPUBFUN int XMLCALL xmlBufferAdd(xmlBufferPtr buf, const xmlChar *str, int len)
static void xsltNumberFormatDecimal(xmlBufferPtr buffer, double number, int digit_zero, int width, int digitsPerGroup, int groupingCharacter, int groupingCharacterLen)
Definition: numbers.c:114
const XML_Char * prefix
Definition: expat.h:380
unsigned char xmlChar
Definition: xmlstring.h:28
XMLPUBFUN int XMLCALL xmlStrncmp(const xmlChar *str1, const xmlChar *str2, int len)
Definition: xmlstring.c:206
GLenum GLsizei len
Definition: glext.h:6722
xmlChar * patternSeparator
_Check_return_ _CRT_JIT_INTRINSIC double __cdecl fabs(_In_ double x)
static int xsltFormatNumberPreSuffix(xsltDecimalFormatPtr self, xmlChar **format, xsltFormatNumberInfoPtr info)
Definition: numbers.c:819
#define FALSE
Definition: numbers.c:16
void xsltTransformError(xsltTransformContextPtr ctxt, xsltStylesheetPtr style, xmlNodePtr node, const char *msg,...)
Definition: xsltutils.c:678
_Check_return_ _CRTIMP double __cdecl floor(_In_ double x)
GLuint64EXT * result
Definition: glext.h:11304
#define IS_SPECIAL(self, letter)
Definition: numbers.c:85
static SERVICE_STATUS status
Definition: service.c:31
XMLPUBFUN xmlChar *XMLCALL xmlStrdup(const xmlChar *cur)
Definition: xmlstring.c:66
Definition: ps.c:97
static int xsltFormatNumberPreSuffix ( xsltDecimalFormatPtr  self,
xmlChar **  format,
xsltFormatNumberInfoPtr  info 
)
static

Definition at line 819 of file numbers.c.

Referenced by xsltFormatNumberConversion().

820 {
821  int count=0; /* will hold total length of prefix/suffix */
822  int len;
823 
824  while (1) {
825  /*
826  * prefix / suffix ends at end of string or at
827  * first 'special' character
828  */
829  if (**format == 0)
830  return count;
831  /* if next character 'escaped' just count it */
832  if (**format == SYMBOL_QUOTE) {
833  if (*++(*format) == 0)
834  return -1;
835  }
836  else if (IS_SPECIAL(self, *format))
837  return count;
838  /*
839  * else treat percent/per-mille as special cases,
840  * depending on whether +ve or -ve
841  */
842  else {
843  /*
844  * for +ve prefix/suffix, allow only a
845  * single occurence of either
846  */
847  if (xsltUTF8Charcmp(*format, self->percent) == 0) {
848  if (info->is_multiplier_set)
849  return -1;
850  info->multiplier = 100;
851  info->is_multiplier_set = TRUE;
852  } else if (xsltUTF8Charcmp(*format, self->permille) == 0) {
853  if (info->is_multiplier_set)
854  return -1;
855  info->multiplier = 1000;
856  info->is_multiplier_set = TRUE;
857  }
858  }
859 
860  if ((len=xmlUTF8Strsize(*format, 1)) < 1)
861  return -1;
862  count += len;
863  *format += len;
864  }
865 }
#define SYMBOL_QUOTE
Definition: numbers.c:20
static int xsltUTF8Charcmp(xmlChar *utf1, xmlChar *utf2)
Definition: numbers.c:65
#define TRUE
Definition: numbers.c:17
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
XMLPUBFUN int XMLCALL xmlUTF8Strsize(const xmlChar *utf, int len)
Definition: xmlstring.c:833
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLenum GLsizei len
Definition: glext.h:6722
#define IS_SPECIAL(self, letter)
Definition: numbers.c:85
static int xsltIsDigitZero ( unsigned int  ch)
static

Definition at line 96 of file numbers.c.

97 {
98  /*
99  * Reference: ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
100  */
101  switch (ch) {
102  case 0x0030: case 0x0660: case 0x06F0: case 0x0966:
103  case 0x09E6: case 0x0A66: case 0x0AE6: case 0x0B66:
104  case 0x0C66: case 0x0CE6: case 0x0D66: case 0x0E50:
105  case 0x0E60: case 0x0F20: case 0x1040: case 0x17E0:
106  case 0x1810: case 0xFF10:
107  return TRUE;
108  default:
109  return FALSE;
110  }
111 }
#define TRUE
Definition: numbers.c:17
#define FALSE
Definition: numbers.c:16
void xsltNumberFormat ( xsltTransformContextPtr  ctxt,
xsltNumberDataPtr  data,
xmlNodePtr  node 
)

xsltNumberFormat: : the XSLT transformation context : the formatting informations : the data to format

Convert one number.

Definition at line 708 of file numbers.c.

Referenced by xsltNumber().

711 {
713  int amount, i;
714  double number;
715  xsltFormat tokens;
716 
717  if (data->format != NULL) {
718  xsltNumberFormatTokenize(data->format, &tokens);
719  }
720  else {
721  xmlChar *format;
722 
723  /* The format needs to be recomputed each time */
724  if (data->has_format == 0)
725  return;
726  format = xsltEvalAttrValueTemplate(ctxt, data->node,
727  (const xmlChar *) "format",
729  if (format == NULL)
730  return;
731  xsltNumberFormatTokenize(format, &tokens);
732  xmlFree(format);
733  }
734 
735  output = xmlBufferCreate();
736  if (output == NULL)
737  goto XSLT_NUMBER_FORMAT_END;
738 
739  /*
740  * Evaluate the XPath expression to find the value(s)
741  */
742  if (data->value) {
743  amount = xsltNumberFormatGetValue(ctxt->xpathCtxt,
744  node,
745  data->value,
746  &number);
747  if (amount == 1) {
749  &number,
750  1,
751  &tokens,
752  output);
753  }
754 
755  } else if (data->level) {
756 
757  if (xmlStrEqual(data->level, (const xmlChar *) "single")) {
758  amount = xsltNumberFormatGetMultipleLevel(ctxt,
759  node,
760  data->countPat,
761  data->fromPat,
762  &number,
763  1);
764  if (amount == 1) {
766  &number,
767  1,
768  &tokens,
769  output);
770  }
771  } else if (xmlStrEqual(data->level, (const xmlChar *) "multiple")) {
772  double numarray[1024];
773  int max = sizeof(numarray)/sizeof(numarray[0]);
774  amount = xsltNumberFormatGetMultipleLevel(ctxt,
775  node,
776  data->countPat,
777  data->fromPat,
778  numarray,
779  max);
780  if (amount > 0) {
782  numarray,
783  amount,
784  &tokens,
785  output);
786  }
787  } else if (xmlStrEqual(data->level, (const xmlChar *) "any")) {
788  amount = xsltNumberFormatGetAnyLevel(ctxt,
789  node,
790  data->countPat,
791  data->fromPat,
792  &number);
793  if (amount > 0) {
795  &number,
796  1,
797  &tokens,
798  output);
799  }
800  }
801  }
802  /* Insert number as text node */
803  xsltCopyTextString(ctxt, ctxt->insert, xmlBufferContent(output), 0);
804 
805  xmlBufferFree(output);
806 
807 XSLT_NUMBER_FORMAT_END:
808  if (tokens.start != NULL)
809  xmlFree(tokens.start);
810  if (tokens.end != NULL)
811  xmlFree(tokens.end);
812  for (i = 0;i < tokens.nTokens;i++) {
813  if (tokens.tokens[i].separator != NULL)
814  xmlFree(tokens.tokens[i].separator);
815  }
816 }
static int xsltNumberFormatGetValue(xmlXPathContextPtr context, xmlNodePtr node, const xmlChar *value, double *number)
Definition: numbers.c:672
#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:416
static UCHAR ULONG UCHAR ULONG UCHAR * output
Definition: bcrypt.c:29
XMLPUBFUN const xmlChar *XMLCALL xmlBufferContent(const xmlBuffer *buf)
xmlChar * separator
Definition: numbers.c:30
XMLPUBFUN void XMLCALL xmlBufferFree(xmlBufferPtr buf)
xmlChar * start
Definition: numbers.c:38
struct _xsltCompMatch * countPat
#define XSLT_NAMESPACE
Definition: xslt.h:46
XMLPUBFUN xmlBufferPtr XMLCALL xmlBufferCreate(void)
xmlChar * xsltEvalAttrValueTemplate(xsltTransformContextPtr ctxt, xmlNodePtr inst, const xmlChar *name, const xmlChar *ns)
Definition: templates.c:384
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
const xmlChar * level
GLenum GLclampf GLint i
Definition: glfuncs.h:14
static size_t double number
Definition: printf.c:64
const xmlChar * format
static int xsltNumberFormatGetMultipleLevel(xsltTransformContextPtr context, xmlNodePtr node, xsltCompMatchPtr countPat, xsltCompMatchPtr fromPat, double *array, int max)
Definition: numbers.c:623
smooth NULL
Definition: ftsmooth.c:416
xmlNodePtr xsltCopyTextString(xsltTransformContextPtr ctxt, xmlNodePtr target, const xmlChar *string, int noescape)
Definition: transform.c:846
const xmlChar * value
xmlXPathContextPtr xpathCtxt
xmlChar * end
Definition: numbers.c:41
XMLPUBVAR xmlFreeFunc xmlFree
Definition: globals.h:251
xsltFormatToken tokens[MAX_TOKENS]
Definition: numbers.c:39
unsigned char xmlChar
Definition: xmlstring.h:28
int nTokens
Definition: numbers.c:40
struct _xsltCompMatch * fromPat
static void xsltNumberFormatTokenize(const xmlChar *format, xsltFormatPtr tokens)
Definition: numbers.c:310
XMLPUBFUN int XMLCALL xmlStrEqual(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:157
static int xsltNumberFormatGetAnyLevel(xsltTransformContextPtr context, xmlNodePtr node, xsltCompMatchPtr countPat, xsltCompMatchPtr fromPat, double *array)
Definition: numbers.c:569
static void xsltNumberFormatAlpha ( xsltNumberDataPtr  data,
xmlBufferPtr  buffer,
double  number,
int  is_upper 
)
static

Definition at line 188 of file numbers.c.

Referenced by xsltNumberFormatInsertNumbers().

192 {
193  char temp_string[sizeof(double) * CHAR_BIT * sizeof(xmlChar) + 1];
194  char *pointer;
195  int i;
196  char *alpha_list;
197  double alpha_size = (double)(sizeof(alpha_upper_list) - 1);
198 
199  /*
200  * XSLT 1.0 isn't clear on how to handle zero, but XSLT 2.0 says:
201  *
202  * For all format tokens other than the first kind above (one that
203  * consists of decimal digits), there may be implementation-defined
204  * lower and upper bounds on the range of numbers that can be
205  * formatted using this format token; indeed, for some numbering
206  * sequences there may be intrinsic limits. [...] Numbers that fall
207  * outside this range must be formatted using the format token 1.
208  *
209  * The "a" token has an intrinsic lower limit of 1.
210  */
211  if (number < 1.0) {
212  xsltNumberFormatDecimal(buffer, number, '0', 1,
213  data->digitsPerGroup,
214  data->groupingCharacter,
215  data->groupingCharacterLen);
216  return;
217  }
218 
219  /* Build buffer from back */
220  pointer = &temp_string[sizeof(temp_string)];
221  *(--pointer) = 0;
222  alpha_list = (is_upper) ? alpha_upper_list : alpha_lower_list;
223 
224  for (i = 1; i < (int)sizeof(temp_string); i++) {
225  number--;
226  *(--pointer) = alpha_list[((int)fmod(number, alpha_size))];
227  number /= alpha_size;
228  if (number < 1.0)
229  break; /* for */
230  }
231  xmlBufferCCat(buffer, pointer);
232 }
GLsizei const GLvoid * pointer
Definition: glext.h:5848
#define CHAR_BIT
Definition: urlcache.c:57
XMLPUBFUN int XMLCALL xmlBufferCCat(xmlBufferPtr buf, const char *str)
GLenum GLclampf GLint i
Definition: glfuncs.h:14
static size_t double number
Definition: printf.c:64
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
Definition: string.c:80
_Check_return_ double __cdecl fmod(_In_ double x, _In_ double y)
static void xsltNumberFormatDecimal(xmlBufferPtr buffer, double number, int digit_zero, int width, int digitsPerGroup, int groupingCharacter, int groupingCharacterLen)
Definition: numbers.c:114
unsigned char xmlChar
Definition: xmlstring.h:28
#define is_upper(c)
Definition: astoll.c:45
static char alpha_upper_list[]
Definition: numbers.c:44
static char alpha_lower_list[]
Definition: numbers.c:45
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:29
static void xsltNumberFormatDecimal ( xmlBufferPtr  buffer,
double  number,
int  digit_zero,
int  width,
int  digitsPerGroup,
int  groupingCharacter,
int  groupingCharacterLen 
)
static

Definition at line 114 of file numbers.c.

Referenced by xsltFormatNumberConversion(), xsltNumberFormatAlpha(), xsltNumberFormatInsertNumbers(), and xsltNumberFormatRoman().

121 {
122  /*
123  * This used to be
124  * xmlChar temp_string[sizeof(double) * CHAR_BIT * sizeof(xmlChar) + 4];
125  * which would be length 68 on x86 arch. It was changed to be a longer,
126  * fixed length in order to try to cater for (reasonable) UTF8
127  * separators and numeric characters. The max UTF8 char size will be
128  * 6 or less, so the value used [500] should be *much* larger than needed
129  */
130  xmlChar temp_string[500];
131  xmlChar *pointer;
132  xmlChar temp_char[6];
133  int i;
134  int val;
135  int len;
136 
137  /* Build buffer from back */
138  pointer = &temp_string[sizeof(temp_string)] - 1; /* last char */
139  *pointer = 0;
140  i = 0;
141  while (pointer > temp_string) {
142  if ((i >= width) && (fabs(number) < 1.0))
143  break; /* for */
144  if ((i > 0) && (groupingCharacter != 0) &&
145  (digitsPerGroup > 0) &&
146  ((i % digitsPerGroup) == 0)) {
147  if (pointer - groupingCharacterLen < temp_string) {
148  i = -1; /* flag error */
149  break;
150  }
151  pointer -= groupingCharacterLen;
152  xmlCopyCharMultiByte(pointer, groupingCharacter);
153  }
154 
155  val = digit_zero + (int)fmod(number, 10.0);
156  if (val < 0x80) { /* shortcut if ASCII */
157  if (pointer <= temp_string) { /* Check enough room */
158  i = -1;
159  break;
160  }
161  *(--pointer) = val;
162  }
163  else {
164  /*
165  * Here we have a multibyte character. It's a little messy,
166  * because until we generate the char we don't know how long
167  * it is. So, we generate it into the buffer temp_char, then
168  * copy from there into temp_string.
169  */
170  len = xmlCopyCharMultiByte(temp_char, val);
171  if ( (pointer - len) < temp_string ) {
172  i = -1;
173  break;
174  }
175  pointer -= len;
176  memcpy(pointer, temp_char, len);
177  }
178  number /= 10.0;
179  ++i;
180  }
181  if (i < 0)
183  "xsltNumberFormatDecimal: Internal buffer size exceeded\n");
184  xmlBufferCat(buffer, pointer);
185 }
XMLPUBFUN int XMLCALL xmlCopyCharMultiByte(xmlChar *out, int val)
GLsizei const GLvoid * pointer
Definition: glext.h:5848
GLenum GLclampf GLint i
Definition: glfuncs.h:14
xmlGenericErrorFunc xsltGenericError
Definition: xsltutils.c:502
static size_t double number
Definition: printf.c:64
GLuint GLfloat * val
Definition: glext.h:7180
XMLPUBFUN int XMLCALL xmlBufferCat(xmlBufferPtr buf, const xmlChar *str)
_Check_return_ double __cdecl fmod(_In_ double x, _In_ double y)
GLint GLint GLsizei width
Definition: gl.h:1546
void * xsltGenericErrorContext
Definition: xsltutils.c:503
unsigned char xmlChar
Definition: xmlstring.h:28
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
_Check_return_ _CRT_JIT_INTRINSIC double __cdecl fabs(_In_ double x)
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:29
static int xsltNumberFormatGetAnyLevel ( xsltTransformContextPtr  context,
xmlNodePtr  node,
xsltCompMatchPtr  countPat,
xsltCompMatchPtr  fromPat,
double array 
)
static

Definition at line 569 of file numbers.c.

Referenced by xsltNumberFormat().

574 {
575  int amount = 0;
576  int cnt = 0;
577  xmlNodePtr cur = node;
578 
579  while (cur != NULL) {
580  /* process current node */
581  if (xsltTestCompMatchCount(context, cur, countPat, node))
582  cnt++;
583  if ((fromPat != NULL) &&
584  xsltTestCompMatchList(context, cur, fromPat)) {
585  break; /* while */
586  }
587 
588  /* Skip to next preceding or ancestor */
589  if ((cur->type == XML_DOCUMENT_NODE) ||
590 #ifdef LIBXML_DOCB_ENABLED
591  (cur->type == XML_DOCB_DOCUMENT_NODE) ||
592 #endif
593  (cur->type == XML_HTML_DOCUMENT_NODE))
594  break; /* while */
595 
596  if (cur->type == XML_NAMESPACE_DECL) {
597  /*
598  * The XPath module stores the parent of a namespace node in
599  * the ns->next field.
600  */
601  cur = (xmlNodePtr) ((xmlNsPtr) cur)->next;
602  } else if (cur->type == XML_ATTRIBUTE_NODE) {
603  cur = cur->parent;
604  } else {
605  while ((cur->prev != NULL) && ((cur->prev->type == XML_DTD_NODE) ||
606  (cur->prev->type == XML_XINCLUDE_START) ||
607  (cur->prev->type == XML_XINCLUDE_END)))
608  cur = cur->prev;
609  if (cur->prev != NULL) {
610  for (cur = cur->prev; cur->last != NULL; cur = cur->last);
611  } else {
612  cur = cur->parent;
613  }
614  }
615  }
616 
617  array[amount++] = (double) cnt;
618 
619  return(amount);
620 }
static int xsltTestCompMatchCount(xsltTransformContextPtr context, xmlNodePtr node, xsltCompMatchPtr countPat, xmlNodePtr cur)
Definition: numbers.c:532
struct _xmlNode * prev
Definition: tree.h:497
Definition: tree.h:389
struct node node
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
Definition: string.c:80
struct _xmlNode * last
Definition: tree.h:494
smooth NULL
Definition: ftsmooth.c:416
xmlNode * xmlNodePtr
Definition: tree.h:488
struct _xmlNode * parent
Definition: tree.h:495
int xsltTestCompMatchList(xsltTransformContextPtr ctxt, xmlNodePtr node, xsltCompMatchPtr comp)
Definition: pattern.c:1207
if(!(yy_init))
Definition: macro.lex.yy.c:717
Definition: tree.h:489
#define LIBXML_DOCB_ENABLED
Definition: xmlversion.h:241
xmlElementType type
Definition: tree.h:491
static unsigned __int64 next
Definition: rand_nt.c:6
static int xsltNumberFormatGetMultipleLevel ( xsltTransformContextPtr  context,
xmlNodePtr  node,
xsltCompMatchPtr  countPat,
xsltCompMatchPtr  fromPat,
double array,
int  max 
)
static

Definition at line 623 of file numbers.c.

Referenced by xsltNumberFormat().

629 {
630  int amount = 0;
631  int cnt;
632  xmlNodePtr ancestor;
633  xmlNodePtr preceding;
634  xmlXPathParserContextPtr parser;
635 
636  context->xpathCtxt->node = node;
637  parser = xmlXPathNewParserContext(NULL, context->xpathCtxt);
638  if (parser) {
639  /* ancestor-or-self::*[count] */
640  for (ancestor = node;
641  (ancestor != NULL) && (ancestor->type != XML_DOCUMENT_NODE);
642  ancestor = xmlXPathNextAncestor(parser, ancestor)) {
643 
644  if ((fromPat != NULL) &&
645  xsltTestCompMatchList(context, ancestor, fromPat))
646  break; /* for */
647 
648  if (xsltTestCompMatchCount(context, ancestor, countPat, node)) {
649  /* count(preceding-sibling::*) */
650  cnt = 1;
651  for (preceding =
652  xmlXPathNextPrecedingSibling(parser, ancestor);
653  preceding != NULL;
654  preceding =
655  xmlXPathNextPrecedingSibling(parser, preceding)) {
656 
657  if (xsltTestCompMatchCount(context, preceding, countPat,
658  node))
659  cnt++;
660  }
661  array[amount++] = (double)cnt;
662  if (amount >= max)
663  break; /* for */
664  }
665  }
666  xmlXPathFreeParserContext(parser);
667  }
668  return amount;
669 }
#define max(a, b)
Definition: svc.c:63
static int xsltTestCompMatchCount(xsltTransformContextPtr context, xmlNodePtr node, xsltCompMatchPtr countPat, xmlNodePtr cur)
Definition: numbers.c:532
struct node node
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
Definition: string.c:80
smooth NULL
Definition: ftsmooth.c:416
xmlXPathContextPtr xpathCtxt
int xsltTestCompMatchList(xsltTransformContextPtr ctxt, xmlNodePtr node, xsltCompMatchPtr comp)
Definition: pattern.c:1207
Definition: tree.h:489
xmlElementType type
Definition: tree.h:491
Definition: import.c:86
static int xsltNumberFormatGetValue ( xmlXPathContextPtr  context,
xmlNodePtr  node,
const xmlChar value,
double number 
)
static

Definition at line 672 of file numbers.c.

Referenced by xsltNumberFormat().

676 {
677  int amount = 0;
679  xmlXPathObjectPtr obj;
680 
681  pattern = xmlBufferCreate();
682  if (pattern != NULL) {
683  xmlBufferCCat(pattern, "number(");
684  xmlBufferCat(pattern, value);
685  xmlBufferCCat(pattern, ")");
686  context->node = node;
687  obj = xmlXPathEvalExpression(xmlBufferContent(pattern),
688  context);
689  if (obj != NULL) {
690  *number = obj->floatval;
691  amount++;
692  xmlXPathFreeObject(obj);
693  }
694  xmlBufferFree(pattern);
695  }
696  return amount;
697 }
Definition: get.c:139
XMLPUBFUN const xmlChar *XMLCALL xmlBufferContent(const xmlBuffer *buf)
Definition: http.c:6587
XMLPUBFUN void XMLCALL xmlBufferFree(xmlBufferPtr buf)
XMLPUBFUN xmlBufferPtr XMLCALL xmlBufferCreate(void)
GLsizei GLsizei GLuint * obj
Definition: glext.h:6042
struct node node
XMLPUBFUN int XMLCALL xmlBufferCCat(xmlBufferPtr buf, const char *str)
static size_t double number
Definition: printf.c:64
smooth NULL
Definition: ftsmooth.c:416
XMLPUBFUN int XMLCALL xmlBufferCat(xmlBufferPtr buf, const xmlChar *str)
GLubyte * pattern
Definition: glext.h:7787
static void xsltNumberFormatInsertNumbers ( xsltNumberDataPtr  data,
double numbers,
int  numbers_max,
xsltFormatPtr  tokens,
xmlBufferPtr  buffer 
)
static

Definition at line 416 of file numbers.c.

Referenced by xsltNumberFormat().

421 {
422  int i = 0;
423  double number;
425 
426  /*
427  * Handle initial non-alphanumeric token
428  */
429  if (tokens->start != NULL)
430  xmlBufferCat(buffer, tokens->start);
431 
432  for (i = 0; i < numbers_max; i++) {
433  /* Insert number */
434  number = numbers[(numbers_max - 1) - i];
435  /* Round to nearest like XSLT 2.0 */
436  number = floor(number + 0.5);
437  /*
438  * XSLT 1.0 isn't clear on how to handle negative numbers, but XSLT
439  * 2.0 says:
440  *
441  * It is a non-recoverable dynamic error if any undiscarded item
442  * in the atomized sequence supplied as the value of the value
443  * attribute of xsl:number cannot be converted to an integer, or
444  * if the resulting integer is less than 0 (zero).
445  */
446  if (number < 0.0) {
448  "xsl-number : negative value\n");
449  /* Recover by treating negative values as zero. */
450  number = 0.0;
451  }
452  if (i < tokens->nTokens) {
453  /*
454  * The "n"th format token will be used to format the "n"th
455  * number in the list
456  */
457  token = &(tokens->tokens[i]);
458  } else if (tokens->nTokens > 0) {
459  /*
460  * If there are more numbers than format tokens, then the
461  * last format token will be used to format the remaining
462  * numbers.
463  */
464  token = &(tokens->tokens[tokens->nTokens - 1]);
465  } else {
466  /*
467  * If there are no format tokens, then a format token of
468  * 1 is used to format all numbers.
469  */
470  token = &default_token;
471  }
472 
473  /* Print separator, except for the first number */
474  if (i > 0) {
475  if (token->separator != NULL)
476  xmlBufferCat(buffer, token->separator);
477  else
479  }
480 
481  switch (xmlXPathIsInf(number)) {
482  case -1:
483  xmlBufferCCat(buffer, "-Infinity");
484  break;
485  case 1:
486  xmlBufferCCat(buffer, "Infinity");
487  break;
488  default:
489  if (xmlXPathIsNaN(number)) {
490  xmlBufferCCat(buffer, "NaN");
491  } else {
492 
493  switch (token->token) {
494  case 'A':
495  xsltNumberFormatAlpha(data, buffer, number, TRUE);
496  break;
497  case 'a':
498  xsltNumberFormatAlpha(data, buffer, number, FALSE);
499  break;
500  case 'I':
501  xsltNumberFormatRoman(data, buffer, number, TRUE);
502  break;
503  case 'i':
504  xsltNumberFormatRoman(data, buffer, number, FALSE);
505  break;
506  default:
507  if (IS_DIGIT_ZERO(token->token)) {
509  number,
510  token->token,
511  token->width,
512  data->digitsPerGroup,
513  data->groupingCharacter,
514  data->groupingCharacterLen);
515  }
516  break;
517  }
518  }
519 
520  }
521  }
522 
523  /*
524  * Handle final non-alphanumeric token
525  */
526  if (tokens->end != NULL)
527  xmlBufferCat(buffer, tokens->end);
528 
529 }
#define IS_DIGIT_ZERO(x)
Definition: numbers.c:92
xmlChar * separator
Definition: numbers.c:30
xmlChar * start
Definition: numbers.c:38
#define TRUE
Definition: numbers.c:17
xmlChar token
Definition: numbers.c:31
static xsltFormatToken default_token
Definition: numbers.c:46
XMLPUBFUN int XMLCALL xmlBufferCCat(xmlBufferPtr buf, const char *str)
GLenum GLclampf GLint i
Definition: glfuncs.h:14
static void xsltNumberFormatAlpha(xsltNumberDataPtr data, xmlBufferPtr buffer, double number, int is_upper)
Definition: numbers.c:188
static size_t double number
Definition: printf.c:64
smooth NULL
Definition: ftsmooth.c:416
xmlChar * end
Definition: numbers.c:41
XMLPUBFUN int XMLCALL xmlBufferCat(xmlBufferPtr buf, const xmlChar *str)
#define DEFAULT_SEPARATOR
Definition: numbers.c:23
int token
Definition: lex.c:71
xsltFormatToken tokens[MAX_TOKENS]
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:114
static void xsltNumberFormatRoman(xsltNumberDataPtr data, xmlBufferPtr buffer, double number, int is_upper)
Definition: numbers.c:235
int nTokens
Definition: numbers.c:40
#define FALSE
Definition: numbers.c:16
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 void xsltNumberFormatRoman ( xsltNumberDataPtr  data,
xmlBufferPtr  buffer,
double  number,
int  is_upper 
)
static

Definition at line 235 of file numbers.c.

Referenced by xsltNumberFormatInsertNumbers().

239 {
240  /*
241  * See discussion in xsltNumberFormatAlpha. Also use a reasonable upper
242  * bound to avoid denial of service.
243  */
244  if (number < 1.0 || number > 5000.0) {
245  xsltNumberFormatDecimal(buffer, number, '0', 1,
246  data->digitsPerGroup,
247  data->groupingCharacter,
248  data->groupingCharacterLen);
249  return;
250  }
251 
252  /*
253  * Based on an example by Jim Walsh
254  */
255  while (number >= 1000.0) {
256  xmlBufferCCat(buffer, (is_upper) ? "M" : "m");
257  number -= 1000.0;
258  }
259  if (number >= 900.0) {
260  xmlBufferCCat(buffer, (is_upper) ? "CM" : "cm");
261  number -= 900.0;
262  }
263  while (number >= 500.0) {
264  xmlBufferCCat(buffer, (is_upper) ? "D" : "d");
265  number -= 500.0;
266  }
267  if (number >= 400.0) {
268  xmlBufferCCat(buffer, (is_upper) ? "CD" : "cd");
269  number -= 400.0;
270  }
271  while (number >= 100.0) {
272  xmlBufferCCat(buffer, (is_upper) ? "C" : "c");
273  number -= 100.0;
274  }
275  if (number >= 90.0) {
276  xmlBufferCCat(buffer, (is_upper) ? "XC" : "xc");
277  number -= 90.0;
278  }
279  while (number >= 50.0) {
280  xmlBufferCCat(buffer, (is_upper) ? "L" : "l");
281  number -= 50.0;
282  }
283  if (number >= 40.0) {
284  xmlBufferCCat(buffer, (is_upper) ? "XL" : "xl");
285  number -= 40.0;
286  }
287  while (number >= 10.0) {
288  xmlBufferCCat(buffer, (is_upper) ? "X" : "x");
289  number -= 10.0;
290  }
291  if (number >= 9.0) {
292  xmlBufferCCat(buffer, (is_upper) ? "IX" : "ix");
293  number -= 9.0;
294  }
295  while (number >= 5.0) {
296  xmlBufferCCat(buffer, (is_upper) ? "V" : "v");
297  number -= 5.0;
298  }
299  if (number >= 4.0) {
300  xmlBufferCCat(buffer, (is_upper) ? "IV" : "iv");
301  number -= 4.0;
302  }
303  while (number >= 1.0) {
304  xmlBufferCCat(buffer, (is_upper) ? "I" : "i");
305  number--;
306  }
307 }
XMLPUBFUN int XMLCALL xmlBufferCCat(xmlBufferPtr buf, const char *str)
static size_t double number
Definition: printf.c:64
static void xsltNumberFormatDecimal(xmlBufferPtr buffer, double number, int digit_zero, int width, int digitsPerGroup, int groupingCharacter, int groupingCharacterLen)
Definition: numbers.c:114
#define is_upper(c)
Definition: astoll.c:45
static void xsltNumberFormatTokenize ( const xmlChar format,
xsltFormatPtr  tokens 
)
static

Definition at line 310 of file numbers.c.

Referenced by xsltNumberFormat().

312 {
313  int ix = 0;
314  int j;
315  int val;
316  int len;
317 
319  default_token.width = 1;
321 
322 
323  tokens->start = NULL;
324  tokens->tokens[0].separator = NULL;
325  tokens->end = NULL;
326 
327  /*
328  * Insert initial non-alphanumeric token.
329  * There is always such a token in the list, even if NULL
330  */
331  while (! (IS_LETTER(val=xmlStringCurrentChar(NULL, format+ix, &len)) ||
332  IS_DIGIT(val)) ) {
333  if (format[ix] == 0) /* if end of format string */
334  break; /* while */
335  ix += len;
336  }
337  if (ix > 0)
338  tokens->start = xmlStrndup(format, ix);
339 
340 
341  for (tokens->nTokens = 0; tokens->nTokens < MAX_TOKENS;
342  tokens->nTokens++) {
343  if (format[ix] == 0)
344  break; /* for */
345 
346  /*
347  * separator has already been parsed (except for the first
348  * number) in tokens->end, recover it.
349  */
350  if (tokens->nTokens > 0) {
351  tokens->tokens[tokens->nTokens].separator = tokens->end;
352  tokens->end = NULL;
353  }
354 
355  val = xmlStringCurrentChar(NULL, format+ix, &len);
356  if (IS_DIGIT_ONE(val) ||
357  IS_DIGIT_ZERO(val)) {
358  tokens->tokens[tokens->nTokens].width = 1;
359  while (IS_DIGIT_ZERO(val)) {
360  tokens->tokens[tokens->nTokens].width++;
361  ix += len;
362  val = xmlStringCurrentChar(NULL, format+ix, &len);
363  }
364  if (IS_DIGIT_ONE(val)) {
365  tokens->tokens[tokens->nTokens].token = val - 1;
366  ix += len;
367  val = xmlStringCurrentChar(NULL, format+ix, &len);
368  }
369  } else if ( (val == (xmlChar)'A') ||
370  (val == (xmlChar)'a') ||
371  (val == (xmlChar)'I') ||
372  (val == (xmlChar)'i') ) {
373  tokens->tokens[tokens->nTokens].token = val;
374  ix += len;
375  val = xmlStringCurrentChar(NULL, format+ix, &len);
376  } else {
377  /* XSLT section 7.7
378  * "Any other format token indicates a numbering sequence
379  * that starts with that token. If an implementation does
380  * not support a numbering sequence that starts with that
381  * token, it must use a format token of 1."
382  */
383  tokens->tokens[tokens->nTokens].token = (xmlChar)'0';
384  tokens->tokens[tokens->nTokens].width = 1;
385  }
386  /*
387  * Skip over remaining alphanumeric characters from the Nd
388  * (Number, decimal digit), Nl (Number, letter), No (Number,
389  * other), Lu (Letter, uppercase), Ll (Letter, lowercase), Lt
390  * (Letters, titlecase), Lm (Letters, modifiers), and Lo
391  * (Letters, other (uncased)) Unicode categories. This happens
392  * to correspond to the Letter and Digit classes from XML (and
393  * one wonders why XSLT doesn't refer to these instead).
394  */
395  while (IS_LETTER(val) || IS_DIGIT(val)) {
396  ix += len;
397  val = xmlStringCurrentChar(NULL, format+ix, &len);
398  }
399 
400  /*
401  * Insert temporary non-alphanumeric final tooken.
402  */
403  j = ix;
404  while (! (IS_LETTER(val) || IS_DIGIT(val))) {
405  if (val == 0)
406  break; /* while */
407  ix += len;
408  val = xmlStringCurrentChar(NULL, format+ix, &len);
409  }
410  if (ix > j)
411  tokens->end = xmlStrndup(&format[j], ix - j);
412  }
413 }
#define IS_DIGIT_ZERO(x)
Definition: numbers.c:92
#define MAX_TOKENS
Definition: numbers.c:25
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint 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 GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble const GLfloat const GLdouble const GLfloat GLenum GLint GLint GLint GLint GLint GLint j
Definition: glfuncs.h:98
xmlChar * separator
Definition: numbers.c:30
#define DEFAULT_TOKEN
Definition: numbers.c:22
XMLPUBFUN xmlChar *XMLCALL xmlStrndup(const xmlChar *cur, int len)
Definition: xmlstring.c:41
xmlChar * start
Definition: numbers.c:38
xmlChar token
Definition: numbers.c:31
XMLPUBFUN int XMLCALL xmlStringCurrentChar(xmlParserCtxtPtr ctxt, const xmlChar *cur, int *len)
static xsltFormatToken default_token
Definition: numbers.c:46
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
smooth NULL
Definition: ftsmooth.c:416
#define BAD_CAST
Definition: xmlstring.h:35
xmlChar * end
Definition: numbers.c:41
GLuint GLfloat * val
Definition: glext.h:7180
#define DEFAULT_SEPARATOR
Definition: numbers.c:23
xsltFormatToken tokens[MAX_TOKENS]
Definition: numbers.c:39
unsigned char xmlChar
Definition: xmlstring.h:28
GLenum GLsizei len
Definition: glext.h:6722
#define IS_DIGIT_ONE(x)
Definition: numbers.c:93
#define IS_LETTER(c)
int nTokens
Definition: numbers.c:40
#define IS_DIGIT(c)
static int xsltTestCompMatchCount ( xsltTransformContextPtr  context,
xmlNodePtr  node,
xsltCompMatchPtr  countPat,
xmlNodePtr  cur 
)
static

Definition at line 532 of file numbers.c.

Referenced by xsltNumberFormatGetAnyLevel(), and xsltNumberFormatGetMultipleLevel().

536 {
537  if (countPat != NULL) {
538  return xsltTestCompMatchList(context, node, countPat);
539  }
540  else {
541  /*
542  * 7.7 Numbering
543  *
544  * If count attribute is not specified, then it defaults to the
545  * pattern that matches any node with the same node type as the
546  * current node and, if the current node has an expanded-name, with
547  * the same expanded-name as the current node.
548  */
549  if (node->type != cur->type)
550  return 0;
551  if (node->type == XML_NAMESPACE_DECL)
552  /*
553  * Namespace nodes have no preceding siblings and no parents
554  * that are namespace nodes. This means that node == cur.
555  */
556  return 1;
557  /* TODO: Skip node types without expanded names like text nodes. */
558  if (!xmlStrEqual(node->name, cur->name))
559  return 0;
560  if (node->ns == cur->ns)
561  return 1;
562  if ((node->ns == NULL) || (cur->ns == NULL))
563  return 0;
564  return (xmlStrEqual(node->ns->href, cur->ns->href));
565  }
566 }
const xmlChar * name
Definition: tree.h:492
smooth NULL
Definition: ftsmooth.c:416
int xsltTestCompMatchList(xsltTransformContextPtr ctxt, xmlNodePtr node, xsltCompMatchPtr comp)
Definition: pattern.c:1207
xmlElementType type
Definition: tree.h:491
xmlNs * ns
Definition: tree.h:501
XMLPUBFUN int XMLCALL xmlStrEqual(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:157
const xmlChar * href
Definition: tree.h:392
static int xsltUTF8Charcmp ( xmlChar utf1,
xmlChar utf2 
)
static

xsltUTF8Charcmp : pointer to first UTF8 char : pointer to second UTF8 char

returns result of comparing the two UCS4 values as with xmlStrncmp

Definition at line 65 of file numbers.c.

Referenced by xsltFormatNumberConversion(), and xsltFormatNumberPreSuffix().

65  {
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 }
smooth NULL
Definition: ftsmooth.c:416
XMLPUBFUN int XMLCALL xmlUTF8Strsize(const xmlChar *utf, int len)
Definition: xmlstring.c:833
XMLPUBFUN int XMLCALL xmlStrncmp(const xmlChar *str1, const xmlChar *str2, int len)
Definition: xmlstring.c:206
GLenum GLsizei len
Definition: glext.h:6722

Variable Documentation

char alpha_lower_list[] = "abcdefghijklmnopqrstuvwxyz"
static

Definition at line 45 of file numbers.c.

Referenced by xsltNumberFormatAlpha().

char alpha_upper_list[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
static

Definition at line 44 of file numbers.c.

Referenced by xsltNumberFormatAlpha().

xsltFormatToken default_token
static

Definition at line 46 of file numbers.c.

Referenced by xsltNumberFormatInsertNumbers().