ICU-3591 factor uprv_strtod decimal code

X-SVN-Rev: 16791
This commit is contained in:
Steven R. Loomis 2004-11-07 06:42:41 +00:00
parent a34fa030a7
commit 911642fbb7
3 changed files with 70 additions and 43 deletions

View File

@ -22,6 +22,7 @@
#include <stdlib.h>
#include <stdio.h>
#include "unicode/utypes.h"
#include "cmemory.h"
#include "cstring.h"
@ -326,3 +327,38 @@ uprv_strndup(const char *src, int32_t n) {
return dup;
}
static char gDecimal = 0;
U_CAPI double U_EXPORT2
uprv_strtod(const char *start, char **end) {
char *decimal;
char *myEnd;
char buf[30];
double rv;
if (!gDecimal) {
char rep[5];
// For machines that decide to change the decimal on you,
// and try to be too smart with localization.
// This normally should be just a '.'.
sprintf(rep, "%+1.1f", 1.0);
gDecimal = rep[2];
}
if(gDecimal == '.') {
return strtod(start, end); /* fall through to OS */
} else {
uprv_strncpy(buf, start, 29);
buf[29]=0;
decimal = uprv_strchr(buf, '.');
if(decimal) {
*decimal = gDecimal;
} else {
return strtod(start, end); /* no decimal point */
}
rv = strtod(buf, &myEnd);
if(end) {
*end = start+(myEnd-buf);
}
return rv;
}
}

View File

@ -59,8 +59,13 @@ uprv_ebcdictolower(char c);
# error U_CHARSET_FAMILY is not valid
#endif
/**
* always parses using '.' as decimal separator regardless of platform
* behavior.
*/
U_CAPI double U_EXPORT2
uprv_strtod(const char *source, char **end);
#define uprv_strtod(source, end) U_STANDARD_CPP_NAMESPACE strtod(source, end)
#define uprv_strtoul(str, end, base) U_STANDARD_CPP_NAMESPACE strtoul(str, end, base)
#define uprv_strtol(str, end, base) U_STANDARD_CPP_NAMESPACE strtol(str, end, base)
#ifdef WIN32

View File

@ -2816,7 +2816,7 @@ uloc_acceptLanguageFromHTTP(char *result, int32_t resultAvailable, UAcceptResult
UErrorCode *status)
{
_acceptLangItem *j;
_acceptLangItem smallBuffer[30];
_acceptLangItem smallBuffer[30];
char **strs;
char tmp[ULOC_FULLNAME_CAPACITY +1];
int32_t n = 0;
@ -2827,24 +2827,14 @@ uloc_acceptLanguageFromHTTP(char *result, int32_t resultAvailable, UAcceptResult
int32_t res;
int32_t i;
int32_t l = uprv_strlen(httpAcceptLanguage);
int32_t jSize;
static char gDecimal = 0;
j = smallBuffer;
jSize = sizeof(smallBuffer)/sizeof(smallBuffer[0]);
int32_t jSize;
j = smallBuffer;
jSize = sizeof(smallBuffer)/sizeof(smallBuffer[0]);
if(U_FAILURE(*status)) {
return -1;
}
if (!gDecimal) {
char rep[5];
// For machines that decide to change the decimal on you,
// and try to be too smart with localization.
// This normally should be just a '.'.
sprintf(rep, "%+1.1f", 1.0);
gDecimal = rep[2];
}
for(s=httpAcceptLanguage;s&&*s;) {
while(isspace(*s)) /* eat space at the beginning */
s++;
@ -2854,7 +2844,6 @@ uloc_acceptLanguageFromHTTP(char *result, int32_t resultAvailable, UAcceptResult
itemEnd = httpAcceptLanguage+l; /* end of string */
}
if(paramEnd && paramEnd<itemEnd) {
char *decimal;
/* semicolon (;) is closer than end (,) */
t = paramEnd+1;
if(*t=='q') {
@ -2869,9 +2858,6 @@ uloc_acceptLanguageFromHTTP(char *result, int32_t resultAvailable, UAcceptResult
while(isspace(*t)) {
t++;
}
if((decimal=uprv_strchr(t,'.'))<paramEnd) {
*decimal = gDecimal;
}
j[n].q = uprv_strtod(t,NULL);
} else {
/* no semicolon - it's 1.0 */
@ -2896,25 +2882,25 @@ uloc_acceptLanguageFromHTTP(char *result, int32_t resultAvailable, UAcceptResult
s++;
}
if(n>=jSize) {
if(j==smallBuffer) { /* overflowed the small buffer. */
j = uprv_malloc(sizeof(j[0])*(jSize*2));
if(j!=NULL) {
uprv_memcpy(j,smallBuffer,sizeof(j[0])*jSize);
}
if(j==smallBuffer) { /* overflowed the small buffer. */
j = uprv_malloc(sizeof(j[0])*(jSize*2));
if(j!=NULL) {
uprv_memcpy(j,smallBuffer,sizeof(j[0])*jSize);
}
#if defined(ULOC_DEBUG)
fprintf(stderr,"malloced at size %d\n", jSize);
fprintf(stderr,"malloced at size %d\n", jSize);
#endif
} else {
j = uprv_realloc(j, sizeof(j[0])*jSize*2);
} else {
j = uprv_realloc(j, sizeof(j[0])*jSize*2);
#if defined(ULOC_DEBUG)
fprintf(stderr,"re-alloced at size %d\n", jSize);
fprintf(stderr,"re-alloced at size %d\n", jSize);
#endif
}
jSize *= 2;
if(j==NULL) {
*status = U_MEMORY_ALLOCATION_ERROR;
return -1;
}
}
jSize *= 2;
if(j==NULL) {
*status = U_MEMORY_ALLOCATION_ERROR;
return -1;
}
}
}
qsort(j, n, sizeof(j[0]), uloc_acceptLanguageCompare);
@ -2931,12 +2917,12 @@ uloc_acceptLanguageFromHTTP(char *result, int32_t resultAvailable, UAcceptResult
uprv_free(strs[i]);
}
uprv_free(strs);
if(j != smallBuffer) {
if(j != smallBuffer) {
#if defined(ULOC_DEBUG)
fprintf(stderr,"freeing j %p\n", j);
fprintf(stderr,"freeing j %p\n", j);
#endif
uprv_free(j);
}
uprv_free(j);
}
return res;
}
@ -2958,10 +2944,10 @@ uloc_acceptLanguage(char *result, int32_t resultAvailable,
return -1;
}
fallbackList = uprv_malloc((size_t)(sizeof(fallbackList[0])*acceptListCount));
if(fallbackList==NULL) {
*status = U_MEMORY_ALLOCATION_ERROR;
return -1;
}
if(fallbackList==NULL) {
*status = U_MEMORY_ALLOCATION_ERROR;
return -1;
}
for(i=0;i<acceptListCount;i++) {
#if defined(ULOC_DEBUG)
fprintf(stderr,"%02d: %s\n", i, acceptList[i]);