Make ns[C]String::AppendFloat locale-independent. b=209569 r=jag sr=bzbarsky

This commit is contained in:
dbaron%dbaron.org 2003-07-09 06:53:44 +00:00
parent 281e80fc6b
commit 7f9ed75392
8 changed files with 202 additions and 12 deletions

View File

@ -45,6 +45,7 @@
#include "nsStr.h"
#include "bufferRoutines.h"
#include <stdio.h> //only used for printf
#include "prdtoa.h"
/******************************************************************************************
MODULE NOTES:
@ -1126,6 +1127,97 @@ nsStrPrivate::HashCode(const nsStr& aDest)
}
}
/**
* This is a copy of |PR_cnvtf| with a bug fixed. (The second argument
* of PR_dtoa is 2 rather than 1.)
*/
void
nsStrPrivate::cnvtf(char *buf, int bufsz, int prcsn, double fval)
{
PRIntn decpt, sign, numdigits;
char *num, *nump;
char *bufp = buf;
char *endnum;
/* If anything fails, we store an empty string in 'buf' */
num = (char*)PR_MALLOC(bufsz);
if (num == NULL) {
buf[0] = '\0';
return;
}
if (PR_dtoa(fval, 2, prcsn, &decpt, &sign, &endnum, num, bufsz)
== PR_FAILURE) {
buf[0] = '\0';
goto done;
}
numdigits = endnum - num;
nump = num;
/*
* The NSPR code had a fancy way of checking that we weren't dealing
* with -0.0 or -NaN, but I'll just use < instead.
* XXX Should we check !isnan(fval) as well? Is it portable? We
* probably don't need to bother since NAN isn't portable.
*/
if (sign && fval < 0.0f) {
*bufp++ = '-';
}
if (decpt == 9999) {
while ((*bufp++ = *nump++) != 0) {} /* nothing to execute */
goto done;
}
if (decpt > (prcsn+1) || decpt < -(prcsn-1) || decpt < -5) {
*bufp++ = *nump++;
if (numdigits != 1) {
*bufp++ = '.';
}
while (*nump != '\0') {
*bufp++ = *nump++;
}
*bufp++ = 'e';
PR_snprintf(bufp, bufsz - (bufp - buf), "%+d", decpt-1);
}
else if (decpt >= 0) {
if (decpt == 0) {
*bufp++ = '0';
}
else {
while (decpt--) {
if (*nump != '\0') {
*bufp++ = *nump++;
}
else {
*bufp++ = '0';
}
}
}
if (*nump != '\0') {
*bufp++ = '.';
while (*nump != '\0') {
*bufp++ = *nump++;
}
}
*bufp++ = '\0';
}
else if (decpt < 0) {
*bufp++ = '0';
*bufp++ = '.';
while (decpt++) {
*bufp++ = '0';
}
while (*nump != '\0') {
*bufp++ = *nump++;
}
*bufp++ = '\0';
}
done:
PR_DELETE(num);
}
#ifdef NS_STR_STATS
#include <ctype.h>

View File

@ -269,6 +269,9 @@ class nsStrPrivate {
*/
static PRUint32 HashCode(const nsStr& aDest);
// A copy of PR_cnvtf with a bug fixed.
static void cnvtf(char *buf, int bufsz, int prcsn, double fval);
#ifdef NS_STR_STATS
/**
* Prints an nsStr. If truncate is true, the string is only printed up to

View File

@ -755,9 +755,9 @@ void nsCString::AppendInt(PRInt32 anInteger,PRInt32 aRadix) {
*/
void nsCString::AppendFloat( double aFloat ){
char buf[40];
// *** XX UNCOMMENT THIS LINE
//PR_snprintf(buf, sizeof(buf), "%g", aFloat);
sprintf(buf,"%g",aFloat);
// Use nsStrPrivate::cnvtf, which is locale-insensitive, instead of the
// locale-sensitive PR_snprintf or sprintf(3)
nsStrPrivate::cnvtf(buf, sizeof(buf), 6, aFloat);
Append(buf);
}

View File

@ -773,9 +773,9 @@ void nsString::AppendInt(PRInt32 anInteger,PRInt32 aRadix) {
*/
void nsString::AppendFloat(double aFloat){
char buf[40];
// *** XX UNCOMMENT THIS LINE
//PR_snprintf(buf, sizeof(buf), "%g", aFloat);
sprintf(buf,"%g",aFloat);
// Use nsStrPrivate::cnvtf, which is locale-insensitive, instead of the
// locale-sensitive PR_snprintf or sprintf(3)
nsStrPrivate::cnvtf(buf, sizeof(buf), 6, aFloat);
AppendWithConversion(buf);
}

View File

@ -45,6 +45,7 @@
#include "nsStr.h"
#include "bufferRoutines.h"
#include <stdio.h> //only used for printf
#include "prdtoa.h"
/******************************************************************************************
MODULE NOTES:
@ -1126,6 +1127,97 @@ nsStrPrivate::HashCode(const nsStr& aDest)
}
}
/**
* This is a copy of |PR_cnvtf| with a bug fixed. (The second argument
* of PR_dtoa is 2 rather than 1.)
*/
void
nsStrPrivate::cnvtf(char *buf, int bufsz, int prcsn, double fval)
{
PRIntn decpt, sign, numdigits;
char *num, *nump;
char *bufp = buf;
char *endnum;
/* If anything fails, we store an empty string in 'buf' */
num = (char*)PR_MALLOC(bufsz);
if (num == NULL) {
buf[0] = '\0';
return;
}
if (PR_dtoa(fval, 2, prcsn, &decpt, &sign, &endnum, num, bufsz)
== PR_FAILURE) {
buf[0] = '\0';
goto done;
}
numdigits = endnum - num;
nump = num;
/*
* The NSPR code had a fancy way of checking that we weren't dealing
* with -0.0 or -NaN, but I'll just use < instead.
* XXX Should we check !isnan(fval) as well? Is it portable? We
* probably don't need to bother since NAN isn't portable.
*/
if (sign && fval < 0.0f) {
*bufp++ = '-';
}
if (decpt == 9999) {
while ((*bufp++ = *nump++) != 0) {} /* nothing to execute */
goto done;
}
if (decpt > (prcsn+1) || decpt < -(prcsn-1) || decpt < -5) {
*bufp++ = *nump++;
if (numdigits != 1) {
*bufp++ = '.';
}
while (*nump != '\0') {
*bufp++ = *nump++;
}
*bufp++ = 'e';
PR_snprintf(bufp, bufsz - (bufp - buf), "%+d", decpt-1);
}
else if (decpt >= 0) {
if (decpt == 0) {
*bufp++ = '0';
}
else {
while (decpt--) {
if (*nump != '\0') {
*bufp++ = *nump++;
}
else {
*bufp++ = '0';
}
}
}
if (*nump != '\0') {
*bufp++ = '.';
while (*nump != '\0') {
*bufp++ = *nump++;
}
}
*bufp++ = '\0';
}
else if (decpt < 0) {
*bufp++ = '0';
*bufp++ = '.';
while (decpt++) {
*bufp++ = '0';
}
while (*nump != '\0') {
*bufp++ = *nump++;
}
*bufp++ = '\0';
}
done:
PR_DELETE(num);
}
#ifdef NS_STR_STATS
#include <ctype.h>

View File

@ -269,6 +269,9 @@ class nsStrPrivate {
*/
static PRUint32 HashCode(const nsStr& aDest);
// A copy of PR_cnvtf with a bug fixed.
static void cnvtf(char *buf, int bufsz, int prcsn, double fval);
#ifdef NS_STR_STATS
/**
* Prints an nsStr. If truncate is true, the string is only printed up to

View File

@ -755,9 +755,9 @@ void nsCString::AppendInt(PRInt32 anInteger,PRInt32 aRadix) {
*/
void nsCString::AppendFloat( double aFloat ){
char buf[40];
// *** XX UNCOMMENT THIS LINE
//PR_snprintf(buf, sizeof(buf), "%g", aFloat);
sprintf(buf,"%g",aFloat);
// Use nsStrPrivate::cnvtf, which is locale-insensitive, instead of the
// locale-sensitive PR_snprintf or sprintf(3)
nsStrPrivate::cnvtf(buf, sizeof(buf), 6, aFloat);
Append(buf);
}

View File

@ -773,9 +773,9 @@ void nsString::AppendInt(PRInt32 anInteger,PRInt32 aRadix) {
*/
void nsString::AppendFloat(double aFloat){
char buf[40];
// *** XX UNCOMMENT THIS LINE
//PR_snprintf(buf, sizeof(buf), "%g", aFloat);
sprintf(buf,"%g",aFloat);
// Use nsStrPrivate::cnvtf, which is locale-insensitive, instead of the
// locale-sensitive PR_snprintf or sprintf(3)
nsStrPrivate::cnvtf(buf, sizeof(buf), 6, aFloat);
AppendWithConversion(buf);
}