use C locale for int/float in XML files

This commit is contained in:
Vas Crabb 2018-01-05 17:12:01 +11:00
parent 2f9ea2b4e1
commit bc9d99d58b

View File

@ -18,15 +18,23 @@
#include <cctype> #include <cctype>
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include <iomanip>
#include <locale>
#include <sstream>
namespace util { namespace xml { namespace util { namespace xml {
namespace {
/*************************************************************************** /***************************************************************************
CONSTANTS CONSTANTS
***************************************************************************/ ***************************************************************************/
#define TEMP_BUFFER_SIZE 4096 constexpr unsigned TEMP_BUFFER_SIZE(4096U);
std::locale const f_portable_locale("C");
} // anonymous namespace
@ -577,18 +585,38 @@ const char *data_node::get_attribute_string(const char *attribute, const char *d
int data_node::get_attribute_int(const char *attribute, int defvalue) const int data_node::get_attribute_int(const char *attribute, int defvalue) const
{ {
char const *const string = get_attribute_string(attribute, nullptr); char const *const string = get_attribute_string(attribute, nullptr);
int value; if (!string)
unsigned int uvalue;
if (string == nullptr)
return defvalue; return defvalue;
std::istringstream stream;
stream.imbue(f_portable_locale);
int result;
if (string[0] == '$') if (string[0] == '$')
return (sscanf(&string[1], "%X", &uvalue) == 1) ? uvalue : defvalue; {
if (string[0] == '0' && string[1] == 'x') stream.str(&string[1]);
return (sscanf(&string[2], "%X", &uvalue) == 1) ? uvalue : defvalue; unsigned uvalue;
if (string[0] == '#') stream >> std::hex >> uvalue;
return (sscanf(&string[1], "%d", &value) == 1) ? value : defvalue; result = int(uvalue);
return (sscanf(&string[0], "%d", &value) == 1) ? value : defvalue; }
else if (string[0] == '0' && string[1] == 'x')
{
stream.str(&string[2]);
unsigned uvalue;
stream >> std::hex >> uvalue;
result = int(uvalue);
}
else if (string[0] == '#')
{
stream.str(&string[1]);
stream >> result;
}
else
{
stream.str(&string[0]);
stream >> result;
}
return stream ? result : defvalue;
} }
@ -600,7 +628,6 @@ int data_node::get_attribute_int(const char *attribute, int defvalue) const
data_node::int_format data_node::get_attribute_int_format(const char *attribute) const data_node::int_format data_node::get_attribute_int_format(const char *attribute) const
{ {
char const *const string = get_attribute_string(attribute, nullptr); char const *const string = get_attribute_string(attribute, nullptr);
if (!string) if (!string)
return int_format::DECIMAL; return int_format::DECIMAL;
else if (string[0] == '$') else if (string[0] == '$')
@ -623,11 +650,13 @@ data_node::int_format data_node::get_attribute_int_format(const char *attribute)
float data_node::get_attribute_float(const char *attribute, float defvalue) const float data_node::get_attribute_float(const char *attribute, float defvalue) const
{ {
char const *const string = get_attribute_string(attribute, nullptr); char const *const string = get_attribute_string(attribute, nullptr);
float value; if (!string)
if (string == nullptr || sscanf(string, "%f", &value) != 1)
return defvalue; return defvalue;
return value;
std::istringstream stream(string);
stream.imbue(f_portable_locale);
float result;
return (stream >> result) ? result : defvalue;
} }
@ -663,9 +692,7 @@ void data_node::set_attribute(const char *name, const char *value)
void data_node::set_attribute_int(const char *name, int value) void data_node::set_attribute_int(const char *name, int value)
{ {
char buffer[100]; set_attribute(name, string_format(f_portable_locale, "%d", value).c_str());
sprintf(buffer, "%d", value);
set_attribute(name, buffer);
} }
@ -676,9 +703,7 @@ void data_node::set_attribute_int(const char *name, int value)
void data_node::set_attribute_float(const char *name, float value) void data_node::set_attribute_float(const char *name, float value)
{ {
char buffer[100]; set_attribute(name, string_format(f_portable_locale, "%f", value).c_str());
sprintf(buffer, "%f", (double) value);
set_attribute(name, buffer);
} }
@ -888,6 +913,7 @@ void data_node::add_attribute(const char *name, const char *value)
} }
catch (...) catch (...)
{ {
osd_printf_warning("error adding attribute to XML data node\n");
} }
} }