ReactOS  r75214
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 xsltUTF8Size (xmlChar *utf)
 
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 118 of file numbers.c.

Referenced by xsltNumberFormatTokenize().

#define IS_DIGIT_ZERO (   x)    xsltIsDigitZero(x)

Definition at line 117 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:93

Definition at line 110 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 944 of file numbers.c.

Referenced by xsltFormatNumberFunction().

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

Referenced by xsltFormatNumberConversion().

854 {
855  int count=0; /* will hold total length of prefix/suffix */
856  int len;
857 
858  while (1) {
859  /*
860  * prefix / suffix ends at end of string or at
861  * first 'special' character
862  */
863  if (**format == 0)
864  return count;
865  /* if next character 'escaped' just count it */
866  if (**format == SYMBOL_QUOTE) {
867  if (*++(*format) == 0)
868  return -1;
869  }
870  else if (IS_SPECIAL(self, *format))
871  return count;
872  /*
873  * else treat percent/per-mille as special cases,
874  * depending on whether +ve or -ve
875  */
876  else {
877  /*
878  * for +ve prefix/suffix, allow only a
879  * single occurence of either
880  */
881  if (xsltUTF8Charcmp(*format, self->percent) == 0) {
882  if (info->is_multiplier_set)
883  return -1;
884  info->multiplier = 100;
885  info->is_multiplier_set = TRUE;
886  } else if (xsltUTF8Charcmp(*format, self->permille) == 0) {
887  if (info->is_multiplier_set)
888  return -1;
889  info->multiplier = 1000;
890  info->is_multiplier_set = TRUE;
891  }
892  }
893 
894  if ((len=xsltUTF8Size(*format)) < 1)
895  return -1;
896  count += len;
897  *format += len;
898  }
899 }
#define SYMBOL_QUOTE
Definition: numbers.c:20
static int xsltUTF8Charcmp(xmlChar *utf1, xmlChar *utf2)
Definition: numbers.c:93
#define TRUE
Definition: numbers.c:17
static int xsltUTF8Size(xmlChar *utf)
Definition: numbers.c:63
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLenum GLsizei len
Definition: glext.h:6722
#define IS_SPECIAL(self, letter)
Definition: numbers.c:110
static int xsltIsDigitZero ( unsigned int  ch)
static

Definition at line 121 of file numbers.c.

122 {
123  /*
124  * Reference: ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
125  */
126  switch (ch) {
127  case 0x0030: case 0x0660: case 0x06F0: case 0x0966:
128  case 0x09E6: case 0x0A66: case 0x0AE6: case 0x0B66:
129  case 0x0C66: case 0x0CE6: case 0x0D66: case 0x0E50:
130  case 0x0E60: case 0x0F20: case 0x1040: case 0x17E0:
131  case 0x1810: case 0xFF10:
132  return TRUE;
133  default:
134  return FALSE;
135  }
136 }
#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 742 of file numbers.c.

Referenced by xsltNumber().

745 {
747  int amount, i;
748  double number;
749  xsltFormat tokens;
750 
751  if (data->format != NULL) {
752  xsltNumberFormatTokenize(data->format, &tokens);
753  }
754  else {
755  xmlChar *format;
756 
757  /* The format needs to be recomputed each time */
758  if (data->has_format == 0)
759  return;
760  format = xsltEvalAttrValueTemplate(ctxt, data->node,
761  (const xmlChar *) "format",
763  if (format == NULL)
764  return;
765  xsltNumberFormatTokenize(format, &tokens);
766  xmlFree(format);
767  }
768 
769  output = xmlBufferCreate();
770  if (output == NULL)
771  goto XSLT_NUMBER_FORMAT_END;
772 
773  /*
774  * Evaluate the XPath expression to find the value(s)
775  */
776  if (data->value) {
777  amount = xsltNumberFormatGetValue(ctxt->xpathCtxt,
778  node,
779  data->value,
780  &number);
781  if (amount == 1) {
783  &number,
784  1,
785  &tokens,
786  output);
787  }
788 
789  } else if (data->level) {
790 
791  if (xmlStrEqual(data->level, (const xmlChar *) "single")) {
792  amount = xsltNumberFormatGetMultipleLevel(ctxt,
793  node,
794  data->countPat,
795  data->fromPat,
796  &number,
797  1);
798  if (amount == 1) {
800  &number,
801  1,
802  &tokens,
803  output);
804  }
805  } else if (xmlStrEqual(data->level, (const xmlChar *) "multiple")) {
806  double numarray[1024];
807  int max = sizeof(numarray)/sizeof(numarray[0]);
808  amount = xsltNumberFormatGetMultipleLevel(ctxt,
809  node,
810  data->countPat,
811  data->fromPat,
812  numarray,
813  max);
814  if (amount > 0) {
816  numarray,
817  amount,
818  &tokens,
819  output);
820  }
821  } else if (xmlStrEqual(data->level, (const xmlChar *) "any")) {
822  amount = xsltNumberFormatGetAnyLevel(ctxt,
823  node,
824  data->countPat,
825  data->fromPat,
826  &number);
827  if (amount > 0) {
829  &number,
830  1,
831  &tokens,
832  output);
833  }
834  }
835  }
836  /* Insert number as text node */
837  xsltCopyTextString(ctxt, ctxt->insert, xmlBufferContent(output), 0);
838 
839  xmlBufferFree(output);
840 
841 XSLT_NUMBER_FORMAT_END:
842  if (tokens.start != NULL)
843  xmlFree(tokens.start);
844  if (tokens.end != NULL)
845  xmlFree(tokens.end);
846  for (i = 0;i < tokens.nTokens;i++) {
847  if (tokens.tokens[i].separator != NULL)
848  xmlFree(tokens.tokens[i].separator);
849  }
850 }
static int xsltNumberFormatGetValue(xmlXPathContextPtr context, xmlNodePtr node, const xmlChar *value, double *number)
Definition: numbers.c:706
#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:441
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:371
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:657
smooth NULL
Definition: ftsmooth.c:513
xmlNodePtr xsltCopyTextString(xsltTransformContextPtr ctxt, xmlNodePtr target, const xmlChar *string, int noescape)
Definition: transform.c:830
const xmlChar * value
xmlXPathContextPtr xpathCtxt
xmlChar * end
Definition: numbers.c:41
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
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:335
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:594
static void xsltNumberFormatAlpha ( xsltNumberDataPtr  data,
xmlBufferPtr  buffer,
double  number,
int  is_upper 
)
static

Definition at line 213 of file numbers.c.

Referenced by xsltNumberFormatInsertNumbers().

217 {
218  char temp_string[sizeof(double) * CHAR_BIT * sizeof(xmlChar) + 1];
219  char *pointer;
220  int i;
221  char *alpha_list;
222  double alpha_size = (double)(sizeof(alpha_upper_list) - 1);
223 
224  /*
225  * XSLT 1.0 isn't clear on how to handle zero, but XSLT 2.0 says:
226  *
227  * For all format tokens other than the first kind above (one that
228  * consists of decimal digits), there may be implementation-defined
229  * lower and upper bounds on the range of numbers that can be
230  * formatted using this format token; indeed, for some numbering
231  * sequences there may be intrinsic limits. [...] Numbers that fall
232  * outside this range must be formatted using the format token 1.
233  *
234  * The "a" token has an intrinsic lower limit of 1.
235  */
236  if (number < 1.0) {
237  xsltNumberFormatDecimal(buffer, number, '0', 1,
238  data->digitsPerGroup,
239  data->groupingCharacter,
240  data->groupingCharacterLen);
241  return;
242  }
243 
244  /* Build buffer from back */
245  pointer = &temp_string[sizeof(temp_string)];
246  *(--pointer) = 0;
247  alpha_list = (is_upper) ? alpha_upper_list : alpha_lower_list;
248 
249  for (i = 1; i < (int)sizeof(temp_string); i++) {
250  number--;
251  *(--pointer) = alpha_list[((int)fmod(number, alpha_size))];
252  number /= alpha_size;
253  if (number < 1.0)
254  break; /* for */
255  }
256  xmlBufferCCat(buffer, pointer);
257 }
GLsizei const GLvoid * pointer
Definition: glext.h:5848
#define CHAR_BIT
Definition: urlcache.c:34
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
_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:139
unsigned char xmlChar
Definition: xmlstring.h:28
#define is_upper(c)
Definition: astoll.c:45
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
Definition: string.c:79
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 139 of file numbers.c.

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

146 {
147  /*
148  * This used to be
149  * xmlChar temp_string[sizeof(double) * CHAR_BIT * sizeof(xmlChar) + 4];
150  * which would be length 68 on x86 arch. It was changed to be a longer,
151  * fixed length in order to try to cater for (reasonable) UTF8
152  * separators and numeric characters. The max UTF8 char size will be
153  * 6 or less, so the value used [500] should be *much* larger than needed
154  */
155  xmlChar temp_string[500];
156  xmlChar *pointer;
157  xmlChar temp_char[6];
158  int i;
159  int val;
160  int len;
161 
162  /* Build buffer from back */
163  pointer = &temp_string[sizeof(temp_string)] - 1; /* last char */
164  *pointer = 0;
165  i = 0;
166  while (pointer > temp_string) {
167  if ((i >= width) && (fabs(number) < 1.0))
168  break; /* for */
169  if ((i > 0) && (groupingCharacter != 0) &&
170  (digitsPerGroup > 0) &&
171  ((i % digitsPerGroup) == 0)) {
172  if (pointer - groupingCharacterLen < temp_string) {
173  i = -1; /* flag error */
174  break;
175  }
176  pointer -= groupingCharacterLen;
177  xmlCopyCharMultiByte(pointer, groupingCharacter);
178  }
179 
180  val = digit_zero + (int)fmod(number, 10.0);
181  if (val < 0x80) { /* shortcut if ASCII */
182  if (pointer <= temp_string) { /* Check enough room */
183  i = -1;
184  break;
185  }
186  *(--pointer) = val;
187  }
188  else {
189  /*
190  * Here we have a multibyte character. It's a little messy,
191  * because until we generate the char we don't know how long
192  * it is. So, we generate it into the buffer temp_char, then
193  * copy from there into temp_string.
194  */
195  len = xmlCopyCharMultiByte(temp_char, val);
196  if ( (pointer - len) < temp_string ) {
197  i = -1;
198  break;
199  }
200  pointer -= len;
201  memcpy(pointer, temp_char, len);
202  }
203  number /= 10.0;
204  ++i;
205  }
206  if (i < 0)
208  "xsltNumberFormatDecimal: Internal buffer size exceeded");
209  xmlBufferCat(buffer, pointer);
210 }
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:510
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:511
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 594 of file numbers.c.

Referenced by xsltNumberFormat().

599 {
600  int amount = 0;
601  int cnt = 0;
602  xmlNodePtr cur;
603 
604  /* select the starting node */
605  switch (node->type) {
606  case XML_ELEMENT_NODE:
607  cur = node;
608  break;
609  case XML_ATTRIBUTE_NODE:
610  cur = ((xmlAttrPtr) node)->parent;
611  break;
612  case XML_TEXT_NODE:
613  case XML_PI_NODE:
614  case XML_COMMENT_NODE:
615  cur = node->parent;
616  break;
617  default:
618  cur = NULL;
619  break;
620  }
621 
622  while (cur != NULL) {
623  /* process current node */
624  if (xsltTestCompMatchCount(context, cur, countPat, node))
625  cnt++;
626  if ((fromPat != NULL) &&
627  xsltTestCompMatchList(context, cur, fromPat)) {
628  break; /* while */
629  }
630 
631  /* Skip to next preceding or ancestor */
632  if ((cur->type == XML_DOCUMENT_NODE) ||
633 #ifdef LIBXML_DOCB_ENABLED
634  (cur->type == XML_DOCB_DOCUMENT_NODE) ||
635 #endif
636  (cur->type == XML_HTML_DOCUMENT_NODE))
637  break; /* while */
638 
639  while ((cur->prev != NULL) && ((cur->prev->type == XML_DTD_NODE) ||
640  (cur->prev->type == XML_XINCLUDE_START) ||
641  (cur->prev->type == XML_XINCLUDE_END)))
642  cur = cur->prev;
643  if (cur->prev != NULL) {
644  for (cur = cur->prev; cur->last != NULL; cur = cur->last);
645  } else {
646  cur = cur->parent;
647  }
648 
649  }
650 
651  array[amount++] = (double) cnt;
652 
653  return(amount);
654 }
static int xsltTestCompMatchCount(xsltTransformContextPtr context, xmlNodePtr node, xsltCompMatchPtr countPat, xmlNodePtr cur)
Definition: numbers.c:557
struct _xmlNode * prev
Definition: tree.h:497
struct node node
struct _xmlNode * last
Definition: tree.h:494
smooth NULL
Definition: ftsmooth.c:513
struct _xmlNode * parent
Definition: tree.h:495
int xsltTestCompMatchList(xsltTransformContextPtr ctxt, xmlNodePtr node, xsltCompMatchPtr comp)
Definition: pattern.c:1202
if(!(yy_init))
Definition: macro.lex.yy.c:704
Definition: tree.h:489
xmlAttr * xmlAttrPtr
Definition: tree.h:433
xmlElementType type
Definition: tree.h:491
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
Definition: string.c:79
static int xsltNumberFormatGetMultipleLevel ( xsltTransformContextPtr  context,
xmlNodePtr  node,
xsltCompMatchPtr  countPat,
xsltCompMatchPtr  fromPat,
double array,
int  max 
)
static

Definition at line 657 of file numbers.c.

Referenced by xsltNumberFormat().

663 {
664  int amount = 0;
665  int cnt;
666  xmlNodePtr ancestor;
667  xmlNodePtr preceding;
668  xmlXPathParserContextPtr parser;
669 
670  context->xpathCtxt->node = node;
671  parser = xmlXPathNewParserContext(NULL, context->xpathCtxt);
672  if (parser) {
673  /* ancestor-or-self::*[count] */
674  for (ancestor = node;
675  (ancestor != NULL) && (ancestor->type != XML_DOCUMENT_NODE);
676  ancestor = xmlXPathNextAncestor(parser, ancestor)) {
677 
678  if ((fromPat != NULL) &&
679  xsltTestCompMatchList(context, ancestor, fromPat))
680  break; /* for */
681 
682  if (xsltTestCompMatchCount(context, ancestor, countPat, node)) {
683  /* count(preceding-sibling::*) */
684  cnt = 1;
685  for (preceding =
686  xmlXPathNextPrecedingSibling(parser, ancestor);
687  preceding != NULL;
688  preceding =
689  xmlXPathNextPrecedingSibling(parser, preceding)) {
690 
691  if (xsltTestCompMatchCount(context, preceding, countPat,
692  node))
693  cnt++;
694  }
695  array[amount++] = (double)cnt;
696  if (amount >= max)
697  break; /* for */
698  }
699  }
700  xmlXPathFreeParserContext(parser);
701  }
702  return amount;
703 }
#define max(a, b)
Definition: svc.c:63
static int xsltTestCompMatchCount(xsltTransformContextPtr context, xmlNodePtr node, xsltCompMatchPtr countPat, xmlNodePtr cur)
Definition: numbers.c:557
struct node node
smooth NULL
Definition: ftsmooth.c:513
xmlXPathContextPtr xpathCtxt
int xsltTestCompMatchList(xsltTransformContextPtr ctxt, xmlNodePtr node, xsltCompMatchPtr comp)
Definition: pattern.c:1202
Definition: tree.h:489
xmlElementType type
Definition: tree.h:491
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
Definition: string.c:79
static int xsltNumberFormatGetValue ( xmlXPathContextPtr  context,
xmlNodePtr  node,
const xmlChar value,
double number 
)
static

Definition at line 706 of file numbers.c.

Referenced by xsltNumberFormat().

710 {
711  int amount = 0;
713  xmlXPathObjectPtr obj;
714 
715  pattern = xmlBufferCreate();
716  if (pattern != NULL) {
717  xmlBufferCCat(pattern, "number(");
718  xmlBufferCat(pattern, value);
719  xmlBufferCCat(pattern, ")");
720  context->node = node;
721  obj = xmlXPathEvalExpression(xmlBufferContent(pattern),
722  context);
723  if (obj != NULL) {
724  *number = obj->floatval;
725  amount++;
726  xmlXPathFreeObject(obj);
727  }
728  xmlBufferFree(pattern);
729  }
730  return amount;
731 }
Definition: get.c:139
XMLPUBFUN const xmlChar *XMLCALL xmlBufferContent(const xmlBuffer *buf)
Definition: http.c:6303
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:513
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 441 of file numbers.c.

Referenced by xsltNumberFormat().

446 {
447  int i = 0;
448  double number;
450 
451  /*
452  * Handle initial non-alphanumeric token
453  */
454  if (tokens->start != NULL)
455  xmlBufferCat(buffer, tokens->start);
456 
457  for (i = 0; i < numbers_max; i++) {
458  /* Insert number */
459  number = numbers[(numbers_max - 1) - i];
460  /* Round to nearest like XSLT 2.0 */
461  number = floor(number + 0.5);
462  /*
463  * XSLT 1.0 isn't clear on how to handle negative numbers, but XSLT
464  * 2.0 says:
465  *
466  * It is a non-recoverable dynamic error if any undiscarded item
467  * in the atomized sequence supplied as the value of the value
468  * attribute of xsl:number cannot be converted to an integer, or
469  * if the resulting integer is less than 0 (zero).
470  */
471  if (number < 0.0) {
473  "xsl-number : negative value\n");
474  /* Recover by treating negative values as zero. */
475  number = 0.0;
476  }
477  if (i < tokens->nTokens) {
478  /*
479  * The "n"th format token will be used to format the "n"th
480  * number in the list
481  */
482  token = &(tokens->tokens[i]);
483  } else if (tokens->nTokens > 0) {
484  /*
485  * If there are more numbers than format tokens, then the
486  * last format token will be used to format the remaining
487  * numbers.
488  */
489  token = &(tokens->tokens[tokens->nTokens - 1]);
490  } else {
491  /*
492  * If there are no format tokens, then a format token of
493  * 1 is used to format all numbers.
494  */
495  token = &default_token;
496  }
497 
498  /* Print separator, except for the first number */
499  if (i > 0) {
500  if (token->separator != NULL)
501  xmlBufferCat(buffer, token->separator);
502  else
504  }
505 
506  switch (xmlXPathIsInf(number)) {
507  case -1:
508  xmlBufferCCat(buffer, "-Infinity");
509  break;
510  case 1:
511  xmlBufferCCat(buffer, "Infinity");
512  break;
513  default:
514  if (xmlXPathIsNaN(number)) {
515  xmlBufferCCat(buffer, "NaN");
516  } else {
517 
518  switch (token->token) {
519  case 'A':
520  xsltNumberFormatAlpha(data, buffer, number, TRUE);
521  break;
522  case 'a':
523  xsltNumberFormatAlpha(data, buffer, number, FALSE);
524  break;
525  case 'I':
526  xsltNumberFormatRoman(data, buffer, number, TRUE);
527  break;
528  case 'i':
529  xsltNumberFormatRoman(data, buffer, number, FALSE);
530  break;
531  default:
532  if (IS_DIGIT_ZERO(token->token)) {
534  number,
535  token->token,
536  token->width,
537  data->digitsPerGroup,
538  data->groupingCharacter,
539  data->groupingCharacterLen);
540  }
541  break;
542  }
543  }
544 
545  }
546  }
547 
548  /*
549  * Handle final non-alphanumeric token
550  */
551  if (tokens->end != NULL)
552  xmlBufferCat(buffer, tokens->end);
553 
554 }
#define IS_DIGIT_ZERO(x)
Definition: numbers.c:117
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:213
static size_t double number
Definition: printf.c:64
smooth NULL
Definition: ftsmooth.c:513
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:57
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:139
static void xsltNumberFormatRoman(xsltNumberDataPtr data, xmlBufferPtr buffer, double number, int is_upper)
Definition: numbers.c:260
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:685
_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 260 of file numbers.c.

Referenced by xsltNumberFormatInsertNumbers().

264 {
265  /*
266  * See discussion in xsltNumberFormatAlpha. Also use a reasonable upper
267  * bound to avoid denial of service.
268  */
269  if (number < 1.0 || number > 5000.0) {
270  xsltNumberFormatDecimal(buffer, number, '0', 1,
271  data->digitsPerGroup,
272  data->groupingCharacter,
273  data->groupingCharacterLen);
274  return;
275  }
276 
277  /*
278  * Based on an example by Jim Walsh
279  */
280  while (number >= 1000.0) {
281  xmlBufferCCat(buffer, (is_upper) ? "M" : "m");
282  number -= 1000.0;
283  }
284  if (number >= 900.0) {
285  xmlBufferCCat(buffer, (is_upper) ? "CM" : "cm");
286  number -= 900.0;
287  }
288  while (number >= 500.0) {
289  xmlBufferCCat(buffer, (is_upper) ? "D" : "d");
290  number -= 500.0;
291  }
292  if (number >= 400.0) {
293  xmlBufferCCat(buffer, (is_upper) ? "CD" : "cd");
294  number -= 400.0;
295  }
296  while (number >= 100.0) {
297  xmlBufferCCat(buffer, (is_upper) ? "C" : "c");
298  number -= 100.0;
299  }
300  if (number >= 90.0) {
301  xmlBufferCCat(buffer, (is_upper) ? "XC" : "xc");
302  number -= 90.0;
303  }
304  while (number >= 50.0) {
305  xmlBufferCCat(buffer, (is_upper) ? "L" : "l");
306  number -= 50.0;
307  }
308  if (number >= 40.0) {
309  xmlBufferCCat(buffer, (is_upper) ? "XL" : "xl");
310  number -= 40.0;
311  }
312  while (number >= 10.0) {
313  xmlBufferCCat(buffer, (is_upper) ? "X" : "x");
314  number -= 10.0;
315  }
316  if (number >= 9.0) {
317  xmlBufferCCat(buffer, (is_upper) ? "IX" : "ix");
318  number -= 9.0;
319  }
320  while (number >= 5.0) {
321  xmlBufferCCat(buffer, (is_upper) ? "V" : "v");
322  number -= 5.0;
323  }
324  if (number >= 4.0) {
325  xmlBufferCCat(buffer, (is_upper) ? "IV" : "iv");
326  number -= 4.0;
327  }
328  while (number >= 1.0) {
329  xmlBufferCCat(buffer, (is_upper) ? "I" : "i");
330  number--;
331  }
332 }
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:139
#define is_upper(c)
Definition: astoll.c:45
static void xsltNumberFormatTokenize ( const xmlChar format,
xsltFormatPtr  tokens 
)
static

Definition at line 335 of file numbers.c.

Referenced by xsltNumberFormat().

337 {
338  int ix = 0;
339  int j;
340  int val;
341  int len;
342 
344  default_token.width = 1;
346 
347 
348  tokens->start = NULL;
349  tokens->tokens[0].separator = NULL;
350  tokens->end = NULL;
351 
352  /*
353  * Insert initial non-alphanumeric token.
354  * There is always such a token in the list, even if NULL
355  */
356  while (! (IS_LETTER(val=xmlStringCurrentChar(NULL, format+ix, &len)) ||
357  IS_DIGIT(val)) ) {
358  if (format[ix] == 0) /* if end of format string */
359  break; /* while */
360  ix += len;
361  }
362  if (ix > 0)
363  tokens->start = xmlStrndup(format, ix);
364 
365 
366  for (tokens->nTokens = 0; tokens->nTokens < MAX_TOKENS;
367  tokens->nTokens++) {
368  if (format[ix] == 0)
369  break; /* for */
370 
371  /*
372  * separator has already been parsed (except for the first
373  * number) in tokens->end, recover it.
374  */
375  if (tokens->nTokens > 0) {
376  tokens->tokens[tokens->nTokens].separator = tokens->end;
377  tokens->end = NULL;
378  }
379 
380  val = xmlStringCurrentChar(NULL, format+ix, &len);
381  if (IS_DIGIT_ONE(val) ||
382  IS_DIGIT_ZERO(val)) {
383  tokens->tokens[tokens->nTokens].width = 1;
384  while (IS_DIGIT_ZERO(val)) {
385  tokens->tokens[tokens->nTokens].width++;
386  ix += len;
387  val = xmlStringCurrentChar(NULL, format+ix, &len);
388  }
389  if (IS_DIGIT_ONE(val)) {
390  tokens->tokens[tokens->nTokens].token = val - 1;
391  ix += len;
392  val = xmlStringCurrentChar(NULL, format+ix, &len);
393  }
394  } else if ( (val == (xmlChar)'A') ||
395  (val == (xmlChar)'a') ||
396  (val == (xmlChar)'I') ||
397  (val == (xmlChar)'i') ) {
398  tokens->tokens[tokens->nTokens].token = val;
399  ix += len;
400  val = xmlStringCurrentChar(NULL, format+ix, &len);
401  } else {
402  /* XSLT section 7.7
403  * "Any other format token indicates a numbering sequence
404  * that starts with that token. If an implementation does
405  * not support a numbering sequence that starts with that
406  * token, it must use a format token of 1."
407  */
408  tokens->tokens[tokens->nTokens].token = (xmlChar)'0';
409  tokens->tokens[tokens->nTokens].width = 1;
410  }
411  /*
412  * Skip over remaining alphanumeric characters from the Nd
413  * (Number, decimal digit), Nl (Number, letter), No (Number,
414  * other), Lu (Letter, uppercase), Ll (Letter, lowercase), Lt
415  * (Letters, titlecase), Lm (Letters, modifiers), and Lo
416  * (Letters, other (uncased)) Unicode categories. This happens
417  * to correspond to the Letter and Digit classes from XML (and
418  * one wonders why XSLT doesn't refer to these instead).
419  */
420  while (IS_LETTER(val) || IS_DIGIT(val)) {
421  ix += len;
422  val = xmlStringCurrentChar(NULL, format+ix, &len);
423  }
424 
425  /*
426  * Insert temporary non-alphanumeric final tooken.
427  */
428  j = ix;
429  while (! (IS_LETTER(val) || IS_DIGIT(val))) {
430  if (val == 0)
431  break; /* while */
432  ix += len;
433  val = xmlStringCurrentChar(NULL, format+ix, &len);
434  }
435  if (ix > j)
436  tokens->end = xmlStrndup(&format[j], ix - j);
437  }
438 }
#define IS_DIGIT_ZERO(x)
Definition: numbers.c:117
#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
smooth NULL
Definition: ftsmooth.c:513
#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
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
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:118
#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 557 of file numbers.c.

Referenced by xsltNumberFormatGetAnyLevel(), and xsltNumberFormatGetMultipleLevel().

561 {
562  if (countPat != NULL) {
563  return xsltTestCompMatchList(context, node, countPat);
564  }
565  else {
566  /*
567  * 7.7 Numbering
568  *
569  * If count attribute is not specified, then it defaults to the
570  * pattern that matches any node with the same node type as the
571  * current node and, if the current node has an expanded-name, with
572  * the same expanded-name as the current node.
573  */
574  if (node->type != cur->type)
575  return 0;
576  if (node->type == XML_NAMESPACE_DECL)
577  /*
578  * Namespace nodes have no preceding siblings and no parents
579  * that are namespace nodes. This means that node == cur.
580  */
581  return 1;
582  /* TODO: Skip node types without expanded names like text nodes. */
583  if (!xmlStrEqual(node->name, cur->name))
584  return 0;
585  if (node->ns == cur->ns)
586  return 1;
587  if ((node->ns == NULL) || (cur->ns == NULL))
588  return 0;
589  return (xmlStrEqual(node->ns->href, cur->ns->href));
590  }
591 }
const xmlChar * name
Definition: tree.h:492
smooth NULL
Definition: ftsmooth.c:513
int xsltTestCompMatchList(xsltTransformContextPtr ctxt, xmlNodePtr node, xsltCompMatchPtr comp)
Definition: pattern.c:1202
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 93 of file numbers.c.

Referenced by xsltFormatNumberConversion(), and xsltFormatNumberPreSuffix().

93  {
94 
95  if (utf1 == NULL ) {
96  if (utf2 == NULL)
97  return 0;
98  return -1;
99  }
100  return xmlStrncmp(utf1, utf2, xsltUTF8Size(utf1));
101 }
static int xsltUTF8Size(xmlChar *utf)
Definition: numbers.c:63
smooth NULL
Definition: ftsmooth.c:513
XMLPUBFUN int XMLCALL xmlStrncmp(const xmlChar *str1, const xmlChar *str2, int len)
Definition: xmlstring.c:206
static int xsltUTF8Size ( xmlChar utf)
static

xsltUTF8Size: : pointer to the UTF8 character

returns the numbers of bytes in the character, -1 on format error

Definition at line 63 of file numbers.c.

Referenced by xsltFormatNumberConversion(), xsltFormatNumberPreSuffix(), and xsltUTF8Charcmp().

63  {
64  xmlChar mask;
65  int len;
66 
67  if (utf == NULL)
68  return -1;
69  if (*utf < 0x80)
70  return 1;
71  /* check valid UTF8 character */
72  if (!(*utf & 0x40))
73  return -1;
74  /* determine number of bytes in char */
75  len = 2;
76  for (mask=0x20; mask != 0; mask>>=1) {
77  if (!(*utf & mask))
78  return len;
79  len++;
80  }
81  return -1;
82 }
GLuint const GLubyte mask[]
Definition: s_context.h:57
smooth NULL
Definition: ftsmooth.c:513
unsigned char xmlChar
Definition: xmlstring.h:28
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().