Ejemplo n.º 1
0
/**
 * exsltStrAlignFunction:
 * @ctxt: an XPath parser context
 * @nargs: the number of arguments
 *
 * Aligns a string within another string.
 */
static void
exsltStrAlignFunction (xmlXPathParserContextPtr ctxt, int nargs) {
    xmlChar *str, *padding, *alignment, *ret;
    int str_l, padding_l;

    if ((nargs < 2) || (nargs > 3)) {
	xmlXPathSetArityError(ctxt);
	return;
    }

    if (nargs == 3)
	alignment = xmlXPathPopString(ctxt);
    else
	alignment = NULL;

    padding = xmlXPathPopString(ctxt);
    str = xmlXPathPopString(ctxt);

    str_l = xmlUTF8Strlen (str);
    padding_l = xmlUTF8Strlen (padding);

    if (str_l == padding_l) {
	xmlXPathReturnString (ctxt, str);
	xmlFree(padding);
	xmlFree(alignment);
	return;
    }

    if (str_l > padding_l) {
	ret = xmlUTF8Strndup (str, padding_l);
    } else {
	if (xmlStrEqual(alignment, (const xmlChar *) "right")) {
	    ret = xmlUTF8Strndup (padding, padding_l - str_l);
	    ret = xmlStrcat (ret, str);
	} else if (xmlStrEqual(alignment, (const xmlChar *) "center")) {
	    int left = (padding_l - str_l) / 2;
	    int right_start;

	    ret = xmlUTF8Strndup (padding, left);
	    ret = xmlStrcat (ret, str);

	    right_start = xmlUTF8Strsize (padding, left + str_l);
	    ret = xmlStrcat (ret, padding + right_start);
	} else {
	    int str_s;

	    str_s = xmlUTF8Strsize(padding, str_l);
	    ret = xmlStrdup (str);
	    ret = xmlStrcat (ret, padding + str_s);
	}
    }

    xmlXPathReturnString (ctxt, ret);

    xmlFree(str);
    xmlFree(padding);
    xmlFree(alignment);
}
Ejemplo n.º 2
0
/**
 * xmlUTF8Strloc:
 * @utf:  the input UTF8 *
 * @utfchar:  the UTF8 character to be found
 *
 * a function to provide the relative location of a UTF8 char
 *
 * Returns the relative character position of the desired char
 * or -1 if not found
 */
int
xmlUTF8Strloc(const xmlChar *utf, const xmlChar *utfchar)
{
  int i, size;
  xmlChar ch;

  if (utf==NULL || utfchar==NULL) return -1;
  size = xmlUTF8Strsize(utfchar, 1);
  for (i=0; (ch=*utf) != 0; i++)
  {
    if (xmlStrncmp(utf, utfchar, size)==0)
      return(i);
    utf++;
    if ( ch & 0x80 )
    {
      /* if not simple ascii, verify proper format */
      if ( (ch & 0xc0) != 0xc0 )
        return(-1);
      /* then skip over remaining bytes for this char */
      while ( (ch <<= 1) & 0x80 )
        if ( (*utf++ & 0xc0) != 0x80 )
          return(-1);
    }
  }

  return(-1);
}
Ejemplo n.º 3
0
/**
 * exsltCryptoRc4DecryptFunction:
 * @ctxt: an XPath parser context
 * @nargs: the number of arguments
 *
 * computes the sha1 hash of a string and returns as hex
 */
static void
exsltCryptoRc4DecryptFunction (xmlXPathParserContextPtr ctxt, int nargs) {

    int key_len = 0, key_size = 0;
    int str_len = 0, bin_len = 0, ret_len = 0;
    xmlChar *key = NULL, *str = NULL, *padkey = NULL, *bin =
	NULL, *ret = NULL;

    if ((nargs < 1) || (nargs > 3)) {
	xmlXPathSetArityError (ctxt);
	return;
    }

    str = xmlXPathPopString (ctxt);
    str_len = xmlUTF8Strlen (str);

    if (str_len == 0) {
	xmlXPathReturnEmptyString (ctxt);
	xmlFree (str);
	return;
    }

    key = xmlXPathPopString (ctxt);
    key_len = xmlUTF8Strlen (str);

    if (key_len == 0) {
	xmlXPathReturnEmptyString (ctxt);
	xmlFree (key);
	xmlFree (str);
	return;
    }

    padkey = xmlMallocAtomic (RC4_KEY_LENGTH);
    key_size = xmlUTF8Strsize (key, key_len);
    memcpy (padkey, key, key_size);
    memset (padkey + key_size, '\0', sizeof (padkey));

/* decode hex to binary */
    bin_len = str_len;
    bin = xmlMallocAtomic (bin_len);
    ret_len = exsltCryptoHex2Bin (str, str_len, bin, bin_len);

/* decrypt the binary blob */
    ret = xmlMallocAtomic (ret_len);
    PLATFORM_RC4_DECRYPT (ctxt, padkey, bin, ret_len, ret, ret_len);

    xmlXPathReturnString (ctxt, ret);

    if (key != NULL)
	xmlFree (key);
    if (str != NULL)
	xmlFree (str);
    if (padkey != NULL)
	xmlFree (padkey);
    if (bin != NULL)
	xmlFree (bin);
}
Ejemplo n.º 4
0
/**
 * xsltUTF8Charcmp
 * @utf1: pointer to first UTF8 char
 * @utf2: pointer to second UTF8 char
 *
 * returns result of comparing the two UCS4 values
 * as with xmlStrncmp
 */
static int
xsltUTF8Charcmp(xmlChar *utf1, xmlChar *utf2) {
    int len = xmlUTF8Strsize(utf1, 1);

    if (len < 1)
        return -1;
    if (utf1 == NULL ) {
        if (utf2 == NULL)
            return 0;
        return -1;
    }
    return xmlStrncmp(utf1, utf2, len);
}
Ejemplo n.º 5
0
static int
xsltFormatNumberPreSuffix(xsltDecimalFormatPtr self, xmlChar **format, xsltFormatNumberInfoPtr info)
{
    int	count=0;	/* will hold total length of prefix/suffix */
    int len;

    while (1) {
	/*
	 * prefix / suffix ends at end of string or at
	 * first 'special' character
	 */
	if (**format == 0)
	    return count;
	/* if next character 'escaped' just count it */
	if (**format == SYMBOL_QUOTE) {
	    if (*++(*format) == 0)
		return -1;
	}
	else if (IS_SPECIAL(self, *format))
	    return count;
	/*
	 * else treat percent/per-mille as special cases,
	 * depending on whether +ve or -ve
	 */
	else {
	    /*
	     * for +ve prefix/suffix, allow only a
	     * single occurence of either
	     */
	    if (xsltUTF8Charcmp(*format, self->percent) == 0) {
		if (info->is_multiplier_set)
		    return -1;
		info->multiplier = 100;
		info->is_multiplier_set = TRUE;
	    } else if (xsltUTF8Charcmp(*format, self->permille) == 0) {
		if (info->is_multiplier_set)
		    return -1;
		info->multiplier = 1000;
		info->is_multiplier_set = TRUE;
	    }
	}

	if ((len=xmlUTF8Strsize(*format, 1)) < 1)
	    return -1;
	count += len;
	*format += len;
    }
}
Ejemplo n.º 6
0
/**
 * xmlUTF8Strndup:
 * @utf:  the input UTF8 *
 * @len:  the len of @utf (in chars)
 *
 * a strndup for array of UTF8's
 *
 * Returns a new UTF8 * or NULL
 */
xmlChar *
xmlUTF8Strndup(const xmlChar *utf, int len) {
    xmlChar *ret;
    int i;

    if ((utf == NULL) || (len < 0)) return(NULL);
    i = xmlUTF8Strsize(utf, len);
    ret = (xmlChar *) xmlMallocAtomic((i + 1) * sizeof(xmlChar));
    if (ret == NULL) {
        xmlGenericError(xmlGenericErrorContext,
                "malloc of %ld byte failed\n",
                (len + 1) * (long)sizeof(xmlChar));
        return(NULL);
    }
    memcpy(ret, utf, i * sizeof(xmlChar));
    ret[i] = 0;
    return(ret);
}
Ejemplo n.º 7
0
/**
 * exsltStrPaddingFunction:
 * @ctxt: an XPath parser context
 * @nargs: the number of arguments
 *
 * Creates a padding string of a certain length.
 */
static void
exsltStrPaddingFunction (xmlXPathParserContextPtr ctxt, int nargs) {
    int number, str_len = 0, str_size = 0;
    xmlChar *str = NULL, *ret = NULL;

    if ((nargs < 1) || (nargs > 2)) {
	xmlXPathSetArityError(ctxt);
	return;
    }

    if (nargs == 2) {
	str = xmlXPathPopString(ctxt);
	str_len = xmlUTF8Strlen(str);
	str_size = xmlStrlen(str);
    }
    if (str_len == 0) {
	if (str != NULL) xmlFree(str);
	str = xmlStrdup((const xmlChar *) " ");
	str_len = 1;
	str_size = 1;
    }

    number = (int) xmlXPathPopNumber(ctxt);

    if (number <= 0) {
	xmlXPathReturnEmptyString(ctxt);
	xmlFree(str);
	return;
    }

    while (number >= str_len) {
	ret = xmlStrncat(ret, str, str_size);
	number -= str_len;
    }
    if (number > 0) {
	str_size = xmlUTF8Strsize(str, number);
	ret = xmlStrncat(ret, str, str_size);
    }

    xmlXPathReturnString(ctxt, ret);

    if (str != NULL)
	xmlFree(str);
}
Ejemplo n.º 8
0
/**
 * exsltCryptoRc4DecryptFunction:
 * @ctxt: an XPath parser context
 * @nargs: the number of arguments
 *
 * computes the sha1 hash of a string and returns as hex
 */
static void
exsltCryptoRc4DecryptFunction (xmlXPathParserContextPtr ctxt, int nargs) {

    int key_len = 0, key_size = 0;
    int str_len = 0, bin_len = 0, ret_len = 0;
    xmlChar *key = NULL, *str = NULL, *padkey = NULL, *bin =
	NULL, *ret = NULL;
    xsltTransformContextPtr tctxt = NULL;

    if (nargs != 2) {
	xmlXPathSetArityError (ctxt);
	return;
    }
    tctxt = xsltXPathGetTransformContext(ctxt);

    str = xmlXPathPopString (ctxt);
    str_len = xmlUTF8Strlen (str);

    if (str_len == 0) {
	xmlXPathReturnEmptyString (ctxt);
	xmlFree (str);
	return;
    }

    key = xmlXPathPopString (ctxt);
    key_len = xmlUTF8Strlen (key);

    if (key_len == 0) {
	xmlXPathReturnEmptyString (ctxt);
	xmlFree (key);
	xmlFree (str);
	return;
    }

    padkey = xmlMallocAtomic (RC4_KEY_LENGTH + 1);
    if (padkey == NULL) {
	xsltTransformError(tctxt, NULL, tctxt->inst,
	    "exsltCryptoRc4EncryptFunction: Failed to allocate padkey\n");
	tctxt->state = XSLT_STATE_STOPPED;
	xmlXPathReturnEmptyString (ctxt);
	goto done;
    }
    memset(padkey, 0, RC4_KEY_LENGTH + 1);
    key_size = xmlUTF8Strsize (key, key_len);
    if ((key_size > RC4_KEY_LENGTH) || (key_size < 0)) {
	xsltTransformError(tctxt, NULL, tctxt->inst,
	    "exsltCryptoRc4EncryptFunction: key size too long or key broken\n");
	tctxt->state = XSLT_STATE_STOPPED;
	xmlXPathReturnEmptyString (ctxt);
	goto done;
    }
    memcpy (padkey, key, key_size);

/* decode hex to binary */
    bin_len = str_len;
    bin = xmlMallocAtomic (bin_len);
    if (bin == NULL) {
	xsltTransformError(tctxt, NULL, tctxt->inst,
	    "exsltCryptoRc4EncryptFunction: Failed to allocate string\n");
	tctxt->state = XSLT_STATE_STOPPED;
	xmlXPathReturnEmptyString (ctxt);
	goto done;
    }
    ret_len = exsltCryptoHex2Bin (str, str_len, bin, bin_len);

/* decrypt the binary blob */
    ret = xmlMallocAtomic (ret_len);
    if (ret == NULL) {
	xsltTransformError(tctxt, NULL, tctxt->inst,
	    "exsltCryptoRc4EncryptFunction: Failed to allocate result\n");
	tctxt->state = XSLT_STATE_STOPPED;
	xmlXPathReturnEmptyString (ctxt);
	goto done;
    }
    PLATFORM_RC4_DECRYPT (ctxt, padkey, bin, ret_len, ret, ret_len);

    xmlXPathReturnString (ctxt, ret);

done:
    if (key != NULL)
	xmlFree (key);
    if (str != NULL)
	xmlFree (str);
    if (padkey != NULL)
	xmlFree (padkey);
    if (bin != NULL)
	xmlFree (bin);
}
Ejemplo n.º 9
0
int LireDictionnaireCMC(char *fichierXML)
{
int i, j, k;
 
 char buf[BUFSIZ];
 char *home;
 char dtdfile[256];
 int done;
 int inlen, outlen;
 unsigned char *inbuffer,*outbuffer;
 
 extern int xmlDoValidityCheckingDefaultValue;


xmlDocPtr    doc;
xmlNsPtr     ns;
xmlNodePtr   cur;
MetvarPtr    Metvar;
xmlDtdPtr    dtd ;
xmlValidCtxt ctxt;
FILE *fh;

LIBXML_TEST_VERSION xmlKeepBlanksDefault(0);

/*
 * build an XML tree from the file;
 */
doc = xmlParseFile(fichierXML);
if (doc == NULL) return(1);

/* -----------------------------------------  */
/*  Check the document is of the right kind   */
/* ------------------------------------------ */

 inbuffer=(unsigned char *) malloc(256*sizeof(unsigned char)); 
 outbuffer=(unsigned char *) malloc(256*sizeof(unsigned char)); 

cur = xmlDocGetRootElement(doc);
if (cur == NULL ) 
{
 fprintf(stderr,"empty document\n");
 xmlFreeDoc(doc);
 return(1);
}
 
 printf("root:%s\n",cur->name);
 
 /* ---------------------- */
 /*  Parse the DTD!   */
 /* ---------------------- */
 
 home = (char *) getenv ("AFSISIO");
 strcpy(dtdfile, home);
 strcat(dtdfile, "/datafiles/constants/dict.dtd");
 dtd = xmlParseDTD(NULL,dtdfile); 
 if (! dtd ) 
   { 
   printf("Error Parsing DTD\n");
   return (1);
   }
 else
   {
   printf ("dtd->name:%s\n",dtd->name);  
   }

 /* ----------------------------------------------------------- */
 /*   Set up xmlValidCtxt for error reporting when validating   */
 /* ----------------------------------------------------------- */
 
 ctxt.userData = stderr; 
 ctxt.error    = (xmlValidityErrorFunc) fprintf;   /* register error function */ 
 ctxt.warning  = (xmlValidityWarningFunc) fprintf; /* register warning function */ 
 
 
 if ( xmlValidateDtd(&ctxt,doc,dtd) )
   {
   printf("=========Validation Ok!============\n");
   }
 else 
   {
   printf("========Validation error!===========\n");
   return (1);
   }
 
 
 /*
  * Now, walk the tree.
  */
 
 
 cur = cur->children; 
 while (cur != NULL) 
   {
   Metvar = parseMetvar(doc, ns, cur);  	   
   cur = cur->next;
   }

 for (i=0; i < nbChampsDict; i++)
   {
   printf("*--------------------------------------------------------------\n");
   strcpy(inbuffer, infoChamps[i].identifVar[FRANCAIS]);
   inlen = xmlUTF8Strsize(inbuffer, 256);
   outlen=256;
   UTF8Toisolat1(outbuffer,&outlen,inbuffer ,&inlen);
   outbuffer[outlen]='\0';
   strcpy(infoChamps[i].identifVar[FRANCAIS], outbuffer);
   printf("Champ %03d de %03d\n", i, nbChampsDict);
   printf("nomvar: %s\n", infoChamps[i].nomVar);
   printf("\tdesc fr:%s\n", infoChamps[i].identifVar[FRANCAIS]);
   printf("\tdesc en:%s\n", infoChamps[i].identifVar[ENGLISH]);
   printf("\tunites:%s\n",  infoChamps[i].unitesVar);
   
   }
 
 xmlFreeDtd(dtd);
 xmlFreeDoc(doc);
 return(0);
 
}
Ejemplo n.º 10
0
/**
 * exsltCryptoRc4EncryptFunction:
 * @ctxt: an XPath parser context
 * @nargs: the number of arguments
 *
 * computes the sha1 hash of a string and returns as hex
 */
static void
exsltCryptoRc4EncryptFunction (xmlXPathParserContextPtr ctxt, int nargs) {

    int key_len = 0, key_size = 0;
    int str_len = 0, bin_len = 0, hex_len = 0;
    xmlChar *key = NULL, *str = NULL, *padkey = NULL;
    xmlChar *bin = NULL, *hex = NULL;

    if ((nargs < 1) || (nargs > 3)) {
	xmlXPathSetArityError (ctxt);
	return;
    }

    str = xmlXPathPopString (ctxt);
    str_len = xmlUTF8Strlen (str);

    if (str_len == 0) {
	xmlXPathReturnEmptyString (ctxt);
	xmlFree (str);
	return;
    }

    key = xmlXPathPopString (ctxt);
    key_len = xmlUTF8Strlen (str);

    if (key_len == 0) {
	xmlXPathReturnEmptyString (ctxt);
	xmlFree (key);
	xmlFree (str);
	return;
    }

    padkey = xmlMallocAtomic (RC4_KEY_LENGTH);
    key_size = xmlUTF8Strsize (key, key_len);
    memcpy (padkey, key, key_size);
    memset (padkey + key_size, '\0', sizeof (padkey));

/* encrypt it */
    bin_len = str_len;
    bin = xmlStrdup (str);
    if (bin == NULL) {
	xmlXPathReturnEmptyString (ctxt);
	goto done;
    }
    PLATFORM_RC4_ENCRYPT (ctxt, padkey, str, str_len, bin, bin_len);

/* encode it */
    hex_len = str_len * 2 + 1;
    hex = xmlMallocAtomic (hex_len);
    if (hex == NULL) {
	xmlXPathReturnEmptyString (ctxt);
	goto done;
    }

    exsltCryptoBin2Hex (bin, str_len, hex, hex_len);
    xmlXPathReturnString (ctxt, hex);

done:
    if (key != NULL)
	xmlFree (key);
    if (str != NULL)
	xmlFree (str);
    if (padkey != NULL)
	xmlFree (padkey);
    if (bin != NULL)
	xmlFree (bin);
}
Ejemplo n.º 11
0
/**
 * xsltFormatNumberConversion:
 * @self: the decimal format
 * @format: the format requested
 * @number: the value to format
 * @result: 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
 */
xmlXPathError
xsltFormatNumberConversion(xsltDecimalFormatPtr self,
			   xmlChar *format,
			   double number,
			   xmlChar **result)
{
    xmlXPathError status = XPATH_EXPRESSION_OK;
    xmlBufferPtr buffer;
    xmlChar *the_format, *prefix = NULL, *suffix = NULL;
    xmlChar *nprefix, *nsuffix = NULL;
    xmlChar pchar;
    int	    prefix_length, suffix_length = 0, nprefix_length, nsuffix_length;
    double  scale;
    int	    j, len;
    int     self_grouping_len;
    xsltFormatNumberInfo format_info;
    /*
     * delayed_multiplier allows a 'trailing' percent or
     * permille to be treated as suffix
     */
    int		delayed_multiplier = 0;
    /* flag to show no -ve format present for -ve number */
    char	default_sign = 0;
    /* flag to show error found, should use default format */
    char	found_error = 0;

    if (xmlStrlen(format) <= 0) {
	xsltTransformError(NULL, NULL, NULL,
                "xsltFormatNumberConversion : "
		"Invalid format (0-length)\n");
    }
    *result = NULL;
    switch (xmlXPathIsInf(number)) {
	case -1:
	    if (self->minusSign == NULL)
		*result = xmlStrdup(BAD_CAST "-");
	    else
		*result = xmlStrdup(self->minusSign);
	    /* no-break on purpose */
	case 1:
	    if ((self == NULL) || (self->infinity == NULL))
		*result = xmlStrcat(*result, BAD_CAST "Infinity");
	    else
		*result = xmlStrcat(*result, self->infinity);
	    return(status);
	default:
	    if (xmlXPathIsNaN(number)) {
		if ((self == NULL) || (self->noNumber == NULL))
		    *result = xmlStrdup(BAD_CAST "NaN");
		else
		    *result = xmlStrdup(self->noNumber);
		return(status);
	    }
    }

    buffer = xmlBufferCreate();
    if (buffer == NULL) {
	return XPATH_MEMORY_ERROR;
    }

    format_info.integer_hash = 0;
    format_info.integer_digits = 0;
    format_info.frac_digits = 0;
    format_info.frac_hash = 0;
    format_info.group = -1;
    format_info.multiplier = 1;
    format_info.add_decimal = FALSE;
    format_info.is_multiplier_set = FALSE;
    format_info.is_negative_pattern = FALSE;

    the_format = format;

    /*
     * First we process the +ve pattern to get percent / permille,
     * as well as main format
     */
    prefix = the_format;
    prefix_length = xsltFormatNumberPreSuffix(self, &the_format, &format_info);
    if (prefix_length < 0) {
	found_error = 1;
	goto OUTPUT_NUMBER;
    }

    /*
     * Here we process the "number" part of the format.  It gets
     * a little messy because of the percent/per-mille - if that
     * appears at the end, it may be part of the suffix instead
     * of part of the number, so the variable delayed_multiplier
     * is used to handle it
     */
    self_grouping_len = xmlStrlen(self->grouping);
    while ((*the_format != 0) &&
	   (xsltUTF8Charcmp(the_format, self->decimalPoint) != 0) &&
	   (xsltUTF8Charcmp(the_format, self->patternSeparator) != 0)) {

	if (delayed_multiplier != 0) {
	    format_info.multiplier = delayed_multiplier;
	    format_info.is_multiplier_set = TRUE;
	    delayed_multiplier = 0;
	}
	if (xsltUTF8Charcmp(the_format, self->digit) == 0) {
	    if (format_info.integer_digits > 0) {
		found_error = 1;
		goto OUTPUT_NUMBER;
	    }
	    format_info.integer_hash++;
	    if (format_info.group >= 0)
		format_info.group++;
	} else if (xsltUTF8Charcmp(the_format, self->zeroDigit) == 0) {
	    format_info.integer_digits++;
	    if (format_info.group >= 0)
		format_info.group++;
	} else if ((self_grouping_len > 0) &&
	    (!xmlStrncmp(the_format, self->grouping, self_grouping_len))) {
	    /* Reset group count */
	    format_info.group = 0;
	    the_format += self_grouping_len;
	    continue;
	} else if (xsltUTF8Charcmp(the_format, self->percent) == 0) {
	    if (format_info.is_multiplier_set) {
		found_error = 1;
		goto OUTPUT_NUMBER;
	    }
	    delayed_multiplier = 100;
	} else  if (xsltUTF8Charcmp(the_format, self->permille) == 0) {
	    if (format_info.is_multiplier_set) {
		found_error = 1;
		goto OUTPUT_NUMBER;
	    }
	    delayed_multiplier = 1000;
	} else
	    break; /* while */

	if ((len=xmlUTF8Strsize(the_format, 1)) < 1) {
	    found_error = 1;
	    goto OUTPUT_NUMBER;
	}
	the_format += len;

    }

    /* We have finished the integer part, now work on fraction */
    if ( (*the_format != 0) &&
         (xsltUTF8Charcmp(the_format, self->decimalPoint) == 0) ) {
        format_info.add_decimal = TRUE;
        if ((len = xmlUTF8Strsize(the_format, 1)) < 1) {
            found_error = 1;
            goto OUTPUT_NUMBER;
        }
	the_format += len;	/* Skip over the decimal */
    }

    while (*the_format != 0) {

	if (xsltUTF8Charcmp(the_format, self->zeroDigit) == 0) {
	    if (format_info.frac_hash != 0) {
		found_error = 1;
		goto OUTPUT_NUMBER;
	    }
	    format_info.frac_digits++;
	} else if (xsltUTF8Charcmp(the_format, self->digit) == 0) {
	    format_info.frac_hash++;
	} else if (xsltUTF8Charcmp(the_format, self->percent) == 0) {
	    if (format_info.is_multiplier_set) {
		found_error = 1;
		goto OUTPUT_NUMBER;
	    }
	    delayed_multiplier = 100;
	    if ((len = xmlUTF8Strsize(the_format, 1)) < 1) {
	        found_error = 1;
		goto OUTPUT_NUMBER;
	    }
	    the_format += len;
	    continue; /* while */
	} else if (xsltUTF8Charcmp(the_format, self->permille) == 0) {
	    if (format_info.is_multiplier_set) {
		found_error = 1;
		goto OUTPUT_NUMBER;
	    }
	    delayed_multiplier = 1000;
	    if  ((len = xmlUTF8Strsize(the_format, 1)) < 1) {
	        found_error = 1;
		goto OUTPUT_NUMBER;
	    }
	    the_format += len;
	    continue; /* while */
	} else if (xsltUTF8Charcmp(the_format, self->grouping) != 0) {
	    break; /* while */
	}
	if ((len = xmlUTF8Strsize(the_format, 1)) < 1) {
	    found_error = 1;
	    goto OUTPUT_NUMBER;
	}
	the_format += len;
	if (delayed_multiplier != 0) {
	    format_info.multiplier = delayed_multiplier;
	    delayed_multiplier = 0;
	    format_info.is_multiplier_set = TRUE;
	}
    }

    /*
     * If delayed_multiplier is set after processing the
     * "number" part, should be in suffix
     */
    if (delayed_multiplier != 0) {
	the_format -= len;
	delayed_multiplier = 0;
    }

    suffix = the_format;
    suffix_length = xsltFormatNumberPreSuffix(self, &the_format, &format_info);
    if ( (suffix_length < 0) ||
	 ((*the_format != 0) &&
	  (xsltUTF8Charcmp(the_format, self->patternSeparator) != 0)) ) {
	found_error = 1;
	goto OUTPUT_NUMBER;
    }

    /*
     * We have processed the +ve prefix, number part and +ve suffix.
     * If the number is -ve, we must substitute the -ve prefix / suffix
     */
    if (number < 0) {
        /*
	 * Note that j is the number of UTF8 chars before the separator,
	 * not the number of bytes! (bug 151975)
	 */
        j =  xmlUTF8Strloc(format, self->patternSeparator);
	if (j < 0) {
	/* No -ve pattern present, so use default signing */
	    default_sign = 1;
	}
	else {
	    /* Skip over pattern separator (accounting for UTF8) */
	    the_format = (xmlChar *)xmlUTF8Strpos(format, j + 1);
	    /*
	     * Flag changes interpretation of percent/permille
	     * in -ve pattern
	     */
	    format_info.is_negative_pattern = TRUE;
	    format_info.is_multiplier_set = FALSE;

	    /* First do the -ve prefix */
	    nprefix = the_format;
	    nprefix_length = xsltFormatNumberPreSuffix(self,
					&the_format, &format_info);
	    if (nprefix_length<0) {
		found_error = 1;
		goto OUTPUT_NUMBER;
	    }

	    while (*the_format != 0) {
		if ( (xsltUTF8Charcmp(the_format, (self)->percent) == 0) ||
		     (xsltUTF8Charcmp(the_format, (self)->permille)== 0) ) {
		    if (format_info.is_multiplier_set) {
			found_error = 1;
			goto OUTPUT_NUMBER;
		    }
		    format_info.is_multiplier_set = TRUE;
		    delayed_multiplier = 1;
		}
		else if (IS_SPECIAL(self, the_format))
		    delayed_multiplier = 0;
		else
		    break; /* while */
		if ((len = xmlUTF8Strsize(the_format, 1)) < 1) {
		    found_error = 1;
		    goto OUTPUT_NUMBER;
		}
		the_format += len;
	    }
	    if (delayed_multiplier != 0) {
		format_info.is_multiplier_set = FALSE;
		the_format -= len;
	    }

	    /* Finally do the -ve suffix */
	    if (*the_format != 0) {
		nsuffix = the_format;
		nsuffix_length = xsltFormatNumberPreSuffix(self,
					&the_format, &format_info);
		if (nsuffix_length < 0) {
		    found_error = 1;
		    goto OUTPUT_NUMBER;
		}
	    }
	    else
		nsuffix_length = 0;
	    if (*the_format != 0) {
		found_error = 1;
		goto OUTPUT_NUMBER;
	    }
	    /*
	     * Here's another Java peculiarity:
	     * if -ve prefix/suffix == +ve ones, discard & use default
	     */
	    if ((nprefix_length != prefix_length) ||
		(nsuffix_length != suffix_length) ||
		((nprefix_length > 0) &&
		 (xmlStrncmp(nprefix, prefix, prefix_length) !=0 )) ||
		((nsuffix_length > 0) &&
		 (xmlStrncmp(nsuffix, suffix, suffix_length) !=0 ))) {
		prefix = nprefix;
		prefix_length = nprefix_length;
		suffix = nsuffix;
		suffix_length = nsuffix_length;
	    } /* else {
		default_sign = 1;
	    }
	    */
	}
    }

OUTPUT_NUMBER:
    if (found_error != 0) {
	xsltTransformError(NULL, NULL, NULL,
                "xsltFormatNumberConversion : "
		"error in format string '%s', using default\n", format);
	default_sign = (number < 0.0) ? 1 : 0;
	prefix_length = suffix_length = 0;
	format_info.integer_hash = 0;
	format_info.integer_digits = 1;
	format_info.frac_digits = 1;
	format_info.frac_hash = 4;
	format_info.group = -1;
	format_info.multiplier = 1;
	format_info.add_decimal = TRUE;
    }

    /* Ready to output our number.  First see if "default sign" is required */
    if (default_sign != 0)
	xmlBufferAdd(buffer, self->minusSign, xmlUTF8Strsize(self->minusSign, 1));

    /* Put the prefix into the buffer */
    for (j = 0; j < prefix_length; j++) {
	if ((pchar = *prefix++) == SYMBOL_QUOTE) {
	    len = xmlUTF8Strsize(prefix, 1);
	    xmlBufferAdd(buffer, prefix, len);
	    prefix += len;
	    j += len - 1;	/* length of symbol less length of quote */
	} else
	    xmlBufferAdd(buffer, &pchar, 1);
    }

    /* Next do the integer part of the number */
    number = fabs(number) * (double)format_info.multiplier;
    scale = pow(10.0, (double)(format_info.frac_digits + format_info.frac_hash));
    number = floor((scale * number + 0.5)) / scale;
    if ((self->grouping != NULL) &&
        (self->grouping[0] != 0)) {

	len = xmlStrlen(self->grouping);
	pchar = xsltGetUTF8Char(self->grouping, &len);
	xsltNumberFormatDecimal(buffer, floor(number), self->zeroDigit[0],
				format_info.integer_digits,
				format_info.group,
				pchar, len);
    } else
	xsltNumberFormatDecimal(buffer, floor(number), self->zeroDigit[0],
				format_info.integer_digits,
				format_info.group,
				',', 1);

    /* Special case: java treats '.#' like '.0', '.##' like '.0#', etc. */
    if ((format_info.integer_digits + format_info.integer_hash +
	 format_info.frac_digits == 0) && (format_info.frac_hash > 0)) {
        ++format_info.frac_digits;
	--format_info.frac_hash;
    }

    /* Add leading zero, if required */
    if ((floor(number) == 0) &&
	(format_info.integer_digits + format_info.frac_digits == 0)) {
        xmlBufferAdd(buffer, self->zeroDigit, xmlUTF8Strsize(self->zeroDigit, 1));
    }

    /* Next the fractional part, if required */
    if (format_info.frac_digits + format_info.frac_hash == 0) {
        if (format_info.add_decimal)
	    xmlBufferAdd(buffer, self->decimalPoint,
			 xmlUTF8Strsize(self->decimalPoint, 1));
    }
    else {
      number -= floor(number);
	if ((number != 0) || (format_info.frac_digits != 0)) {
	    xmlBufferAdd(buffer, self->decimalPoint,
			 xmlUTF8Strsize(self->decimalPoint, 1));
	    number = floor(scale * number + 0.5);
	    for (j = format_info.frac_hash; j > 0; j--) {
		if (fmod(number, 10.0) >= 1.0)
		    break; /* for */
		number /= 10.0;
	    }
	    xsltNumberFormatDecimal(buffer, floor(number), self->zeroDigit[0],
				format_info.frac_digits + j,
				0, 0, 0);
	}
    }
    /* Put the suffix into the buffer */
    for (j = 0; j < suffix_length; j++) {
	if ((pchar = *suffix++) == SYMBOL_QUOTE) {
            len = xmlUTF8Strsize(suffix, 1);
	    xmlBufferAdd(buffer, suffix, len);
	    suffix += len;
	    j += len - 1;	/* length of symbol less length of escape */
	} else
	    xmlBufferAdd(buffer, &pchar, 1);
    }

    *result = xmlStrdup(xmlBufferContent(buffer));
    xmlBufferFree(buffer);
    return status;
}