* avoid trying to overwrite values of a constant structure when
  updating the numeric locale data values used by glibc


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38623 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Oliver Tappe 2010-09-12 17:24:38 +00:00
parent 5d46644f18
commit 86932f41cc
3 changed files with 44 additions and 37 deletions

View File

@ -14,6 +14,7 @@
struct lconv;
struct lc_time_t;
struct locale_data; // glibc
namespace BPrivate {
@ -47,14 +48,33 @@ struct LocaleMonetaryDataBridge {
struct LocaleNumericDataBridge {
const char** addrOfGlibcDecimalPoint;
const char** addrOfGlibcThousandsSep;
const char** addrOfGlibcGrouping;
uint32_t* addrOfGlibcWCDecimalPoint;
uint32_t* addrOfGlibcWCThousandsSep;
private:
// struct used by glibc to store numeric locale data
struct GlibcNumericLocale {
const char* name;
const char* filedata;
off_t filesize;
int mmaped;
unsigned int usage_count;
int use_translit;
const char *options;
unsigned int nstrings;
union locale_data_value
{
const uint32_t* wstr;
const char* string;
unsigned int word;
}
values[6];
};
locale_data* originalGlibcLocale;
public:
const struct lconv* posixLocaleConv;
GlibcNumericLocale glibcNumericLocale;
LocaleNumericDataBridge();
~LocaleNumericDataBridge();
};

View File

@ -28,9 +28,9 @@ ICUNumericData::ICUNumericData(struct lconv& localeConv)
void
ICUNumericData::Initialize(LocaleNumericDataBridge* dataBridge)
{
*dataBridge->addrOfGlibcDecimalPoint = fDecimalPoint;
*dataBridge->addrOfGlibcThousandsSep = fThousandsSep;
*dataBridge->addrOfGlibcGrouping = fGrouping;
dataBridge->glibcNumericLocale.values[0].string = fDecimalPoint;
dataBridge->glibcNumericLocale.values[1].string = fThousandsSep;
dataBridge->glibcNumericLocale.values[2].string = fGrouping;
fDataBridge = dataBridge;
}
@ -57,13 +57,13 @@ ICUNumericData::SetTo(const Locale& locale, const char* posixLocaleName)
if (result == B_OK) {
result = _SetLocaleconvEntry(formatSymbols, fDecimalPoint,
DecimalFormatSymbols::kDecimalSeparatorSymbol);
*fDataBridge->addrOfGlibcWCDecimalPoint
fDataBridge->glibcNumericLocale.values[3].word
= (unsigned int)fDecimalPoint[0];
}
if (result == B_OK) {
result = _SetLocaleconvEntry(formatSymbols, fThousandsSep,
DecimalFormatSymbols::kGroupingSeparatorSymbol);
*fDataBridge->addrOfGlibcWCThousandsSep
fDataBridge->glibcNumericLocale.values[4].word
= (unsigned int)fThousandsSep[0];
}
if (result == B_OK) {
@ -99,9 +99,9 @@ ICUNumericData::SetToPosix()
strcpy(fDecimalPoint, fDataBridge->posixLocaleConv->decimal_point);
strcpy(fThousandsSep, fDataBridge->posixLocaleConv->thousands_sep);
strcpy(fGrouping, fDataBridge->posixLocaleConv->grouping);
*fDataBridge->addrOfGlibcWCDecimalPoint
fDataBridge->glibcNumericLocale.values[3].word
= (unsigned int)fDecimalPoint[0];
*fDataBridge->addrOfGlibcWCThousandsSep
fDataBridge->glibcNumericLocale.values[4].word
= (unsigned int)fThousandsSep[0];
}

View File

@ -8,6 +8,7 @@
#include <ctype.h>
#include <langinfo.h>
#include <string.h>
#include <time.h>
#include <PosixCtype.h>
@ -16,26 +17,7 @@
#include <PosixLocaleConv.h>
// struct used by glibc to access locale info
struct locale_data
{
const char* name;
const char* filedata;
off_t filesize;
int mmaped;
unsigned int usage_count;
int use_translit;
const char *options;
unsigned int nstrings;
union locale_data_value
{
const uint32_t* wstr;
const char* string;
unsigned int word;
}
values[];
};
extern struct locale_data _nl_C_LC_NUMERIC;
extern locale_data* _nl_current_LC_NUMERIC;
namespace BPrivate {
@ -69,13 +51,18 @@ LocaleMonetaryDataBridge::LocaleMonetaryDataBridge()
LocaleNumericDataBridge::LocaleNumericDataBridge()
:
addrOfGlibcDecimalPoint(&_nl_C_LC_NUMERIC.values[0].string),
addrOfGlibcThousandsSep(&_nl_C_LC_NUMERIC.values[1].string),
addrOfGlibcGrouping(&_nl_C_LC_NUMERIC.values[2].string),
addrOfGlibcWCDecimalPoint(&_nl_C_LC_NUMERIC.values[3].word),
addrOfGlibcWCThousandsSep(&_nl_C_LC_NUMERIC.values[4].word),
originalGlibcLocale(_nl_current_LC_NUMERIC),
posixLocaleConv(&gPosixLocaleConv)
{
memcpy(&glibcNumericLocale, _nl_current_LC_NUMERIC,
sizeof(glibcNumericLocale));
_nl_current_LC_NUMERIC = (locale_data*)&glibcNumericLocale;
}
LocaleNumericDataBridge::~LocaleNumericDataBridge()
{
_nl_current_LC_NUMERIC = originalGlibcLocale;
}