Try to fix #6581:
* 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:
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
struct lconv;
|
struct lconv;
|
||||||
struct lc_time_t;
|
struct lc_time_t;
|
||||||
|
struct locale_data; // glibc
|
||||||
|
|
||||||
|
|
||||||
namespace BPrivate {
|
namespace BPrivate {
|
||||||
@@ -47,14 +48,33 @@ struct LocaleMonetaryDataBridge {
|
|||||||
|
|
||||||
|
|
||||||
struct LocaleNumericDataBridge {
|
struct LocaleNumericDataBridge {
|
||||||
const char** addrOfGlibcDecimalPoint;
|
private:
|
||||||
const char** addrOfGlibcThousandsSep;
|
// struct used by glibc to store numeric locale data
|
||||||
const char** addrOfGlibcGrouping;
|
struct GlibcNumericLocale {
|
||||||
uint32_t* addrOfGlibcWCDecimalPoint;
|
const char* name;
|
||||||
uint32_t* addrOfGlibcWCThousandsSep;
|
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;
|
const struct lconv* posixLocaleConv;
|
||||||
|
GlibcNumericLocale glibcNumericLocale;
|
||||||
|
|
||||||
LocaleNumericDataBridge();
|
LocaleNumericDataBridge();
|
||||||
|
~LocaleNumericDataBridge();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -28,9 +28,9 @@ ICUNumericData::ICUNumericData(struct lconv& localeConv)
|
|||||||
void
|
void
|
||||||
ICUNumericData::Initialize(LocaleNumericDataBridge* dataBridge)
|
ICUNumericData::Initialize(LocaleNumericDataBridge* dataBridge)
|
||||||
{
|
{
|
||||||
*dataBridge->addrOfGlibcDecimalPoint = fDecimalPoint;
|
dataBridge->glibcNumericLocale.values[0].string = fDecimalPoint;
|
||||||
*dataBridge->addrOfGlibcThousandsSep = fThousandsSep;
|
dataBridge->glibcNumericLocale.values[1].string = fThousandsSep;
|
||||||
*dataBridge->addrOfGlibcGrouping = fGrouping;
|
dataBridge->glibcNumericLocale.values[2].string = fGrouping;
|
||||||
fDataBridge = dataBridge;
|
fDataBridge = dataBridge;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,13 +57,13 @@ ICUNumericData::SetTo(const Locale& locale, const char* posixLocaleName)
|
|||||||
if (result == B_OK) {
|
if (result == B_OK) {
|
||||||
result = _SetLocaleconvEntry(formatSymbols, fDecimalPoint,
|
result = _SetLocaleconvEntry(formatSymbols, fDecimalPoint,
|
||||||
DecimalFormatSymbols::kDecimalSeparatorSymbol);
|
DecimalFormatSymbols::kDecimalSeparatorSymbol);
|
||||||
*fDataBridge->addrOfGlibcWCDecimalPoint
|
fDataBridge->glibcNumericLocale.values[3].word
|
||||||
= (unsigned int)fDecimalPoint[0];
|
= (unsigned int)fDecimalPoint[0];
|
||||||
}
|
}
|
||||||
if (result == B_OK) {
|
if (result == B_OK) {
|
||||||
result = _SetLocaleconvEntry(formatSymbols, fThousandsSep,
|
result = _SetLocaleconvEntry(formatSymbols, fThousandsSep,
|
||||||
DecimalFormatSymbols::kGroupingSeparatorSymbol);
|
DecimalFormatSymbols::kGroupingSeparatorSymbol);
|
||||||
*fDataBridge->addrOfGlibcWCThousandsSep
|
fDataBridge->glibcNumericLocale.values[4].word
|
||||||
= (unsigned int)fThousandsSep[0];
|
= (unsigned int)fThousandsSep[0];
|
||||||
}
|
}
|
||||||
if (result == B_OK) {
|
if (result == B_OK) {
|
||||||
@@ -99,9 +99,9 @@ ICUNumericData::SetToPosix()
|
|||||||
strcpy(fDecimalPoint, fDataBridge->posixLocaleConv->decimal_point);
|
strcpy(fDecimalPoint, fDataBridge->posixLocaleConv->decimal_point);
|
||||||
strcpy(fThousandsSep, fDataBridge->posixLocaleConv->thousands_sep);
|
strcpy(fThousandsSep, fDataBridge->posixLocaleConv->thousands_sep);
|
||||||
strcpy(fGrouping, fDataBridge->posixLocaleConv->grouping);
|
strcpy(fGrouping, fDataBridge->posixLocaleConv->grouping);
|
||||||
*fDataBridge->addrOfGlibcWCDecimalPoint
|
fDataBridge->glibcNumericLocale.values[3].word
|
||||||
= (unsigned int)fDecimalPoint[0];
|
= (unsigned int)fDecimalPoint[0];
|
||||||
*fDataBridge->addrOfGlibcWCThousandsSep
|
fDataBridge->glibcNumericLocale.values[4].word
|
||||||
= (unsigned int)fThousandsSep[0];
|
= (unsigned int)fThousandsSep[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <langinfo.h>
|
#include <langinfo.h>
|
||||||
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include <PosixCtype.h>
|
#include <PosixCtype.h>
|
||||||
@@ -16,26 +17,7 @@
|
|||||||
#include <PosixLocaleConv.h>
|
#include <PosixLocaleConv.h>
|
||||||
|
|
||||||
|
|
||||||
// struct used by glibc to access locale info
|
extern locale_data* _nl_current_LC_NUMERIC;
|
||||||
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;
|
|
||||||
|
|
||||||
|
|
||||||
namespace BPrivate {
|
namespace BPrivate {
|
||||||
@@ -69,13 +51,18 @@ LocaleMonetaryDataBridge::LocaleMonetaryDataBridge()
|
|||||||
|
|
||||||
LocaleNumericDataBridge::LocaleNumericDataBridge()
|
LocaleNumericDataBridge::LocaleNumericDataBridge()
|
||||||
:
|
:
|
||||||
addrOfGlibcDecimalPoint(&_nl_C_LC_NUMERIC.values[0].string),
|
originalGlibcLocale(_nl_current_LC_NUMERIC),
|
||||||
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),
|
|
||||||
posixLocaleConv(&gPosixLocaleConv)
|
posixLocaleConv(&gPosixLocaleConv)
|
||||||
{
|
{
|
||||||
|
memcpy(&glibcNumericLocale, _nl_current_LC_NUMERIC,
|
||||||
|
sizeof(glibcNumericLocale));
|
||||||
|
_nl_current_LC_NUMERIC = (locale_data*)&glibcNumericLocale;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LocaleNumericDataBridge::~LocaleNumericDataBridge()
|
||||||
|
{
|
||||||
|
_nl_current_LC_NUMERIC = originalGlibcLocale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user