Skip to content

Sort out locales for OSL #795

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 28, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/liboslcomp/oslcomp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,7 @@ OSLCompilerImpl::compile_buffer (string_view sourcecode,
m_output_filename = "<buffer>";

std::ostringstream oso_output;
oso_output.imbue (std::locale::classic()); // force C locale
ASSERT (m_osofile == NULL);
m_osofile = &oso_output;

Expand Down
18 changes: 16 additions & 2 deletions src/liboslcomp/osllex.l
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ CPLUSCOMMENT \/\/.*\n
#include <string>

#include <OpenImageIO/thread.h>
#include <OpenImageIO/strutil.h>
#include "oslcomp_pvt.h"

using namespace OSL;
Expand Down Expand Up @@ -351,13 +352,26 @@ bool
OSLCompilerImpl::osl_parse_buffer (const std::string &preprocessed_buffer)
{
// Thread safety with the lexer/parser
static OIIO::mutex oslcompiler_mutex;
OIIO::lock_guard lock (oslcompiler_mutex);
static std::mutex oslcompiler_mutex;
std::lock_guard<std::mutex> lock (oslcompiler_mutex);

#ifndef OIIO_STRUTIL_HAS_STOF
// Force classic "C" locale for correct '.' decimal parsing.
// N.B. This is not safe in a multi-threaded program where another
// application thread is expecting the native locale to work properly.
// This is not necessary for versions of OIIO that have Strutil::stof,
// and we can remove it entirely when OIIO 1.9 is the minimum.
std::locale oldlocale = std::locale::global (std::locale::classic());
#endif

osl_switch_to_buffer (osl_scan_string (preprocessed_buffer.c_str()));
oslcompiler = this;
oslparse ();
bool parseerr = error_encountered();
osl_delete_buffer (YY_CURRENT_BUFFER);
#ifndef OIIO_STRUTIL_HAS_STOF
std::locale::global (oldlocale); // Restore the original locale.
#endif
return parseerr;
}

Expand Down
1 change: 1 addition & 0 deletions src/liboslexec/instance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -805,6 +805,7 @@ std::string
ShaderGroup::serialize () const
{
std::ostringstream out;
out.imbue (std::locale::classic()); // force C locale
out.precision (9);
lock_guard lock (m_mutex);
for (int i = 0, nl = nlayers(); i < nl; ++i) {
Expand Down
25 changes: 22 additions & 3 deletions src/liboslexec/osolex.l
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ namespace pvt { // OSL::pvt


OSOReader * OSOReader::osoreader = NULL;
static OIIO::mutex osoread_mutex;
static std::mutex osoread_mutex;



Expand All @@ -252,7 +252,13 @@ OSOReader::parse_file (const std::string &filename)
{
// The lexer/parser isn't thread-safe, so make sure Only one thread
// can actually be reading a .oso file at a time.
OIIO::lock_guard guard (osoread_mutex);
std::lock_guard<std::mutex> guard (osoread_mutex);

// Force classic "C" locale for correct '.' decimal parsing.
// N.B. This is not safe in a multi-threaded program where another
// application thread is expecting the native locale to work properly.
std::locale oldlocale; // save the previous native locale
std::locale::global (std::locale::classic());

osoin = OIIO::Filesystem::fopen (filename, "r");
if (! osoin) {
Expand All @@ -271,6 +277,7 @@ OSOReader::parse_file (const std::string &filename)
}
oso_delete_buffer (YY_CURRENT_BUFFER);
fclose (osoin);
std::locale::global (oldlocale); // Restore the original locale.

return ok;
}
Expand All @@ -281,7 +288,16 @@ OSOReader::parse_memory (const std::string &buffer)
{
// The lexer/parser isn't thread-safe, so make sure Only one thread
// can actually be reading a .oso file at a time.
OIIO::lock_guard guard (osoread_mutex);
std::lock_guard<std::mutex> guard (osoread_mutex);

#ifndef OIIO_STRUTIL_HAS_STOF
// Force classic "C" locale for correct '.' decimal parsing.
// N.B. This is not safe in a multi-threaded program where another
// application thread is expecting the native locale to work properly.
// This is not necessary for versions of OIIO that have Strutil::stof,
// and we can remove it entirely when OIIO 1.9 is the minimum.
std::locale oldlocale = std::locale::global (std::locale::classic());
#endif

oso_switch_to_buffer (oso_scan_string (buffer.c_str()));
osoreader = this;
Expand All @@ -292,6 +308,9 @@ OSOReader::parse_memory (const std::string &buffer)
m_err.error ("Failed parse of preloaded OSO code");
}
oso_delete_buffer (YY_CURRENT_BUFFER);
#ifndef OIIO_STRUTIL_HAS_STOF
std::locale::global (oldlocale); // Restore the original locale.
#endif

return ok;
}
Expand Down
1 change: 1 addition & 0 deletions src/liboslexec/runtimeoptimize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -807,6 +807,7 @@ OSOProcessorBase::const_value_as_string (const Symbol &A)
TypeDesc type (A.typespec().simpletype());
int n = type.numelements() * type.aggregate;
std::ostringstream s;
s.imbue (std::locale::classic()); // force C locale
if (type.basetype == TypeDesc::FLOAT) {
for (int i = 0; i < n; ++i)
s << (i ? "," : "") << ((const float *)A.data())[i];
Expand Down
1 change: 1 addition & 0 deletions src/liboslexec/shadingsys.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1596,6 +1596,7 @@ ShadingSystemImpl::getstats (int level) const
if (level <= 0)
return "";
std::ostringstream out;
out.imbue (std::locale::classic()); // force C locale
out << "OSL ShadingSystem statistics (" << (void*)this;
out << ") ver " << OSL_LIBRARY_VERSION_STRING
<< ", LLVM " << OSL_LLVM_FULL_VERSION << "\n";
Expand Down
4 changes: 4 additions & 0 deletions src/oslc/oslcmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ static OSLC_ErrorHandler default_oslc_error_handler;
int
main (int argc, const char *argv[])
{
// Globally force classic "C" locale, and turn off all formatting
// internationalization, for the entire oslc application.
std::locale::global (std::locale::classic());

OIIO::Filesystem::convert_native_arguments (argc, (const char **)argv);

std::vector<std::string> args;
Expand Down
4 changes: 4 additions & 0 deletions src/oslinfo/oslinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,10 @@ input_file (int argc, const char *argv[])
int
main (int argc, char *argv[])
{
// Globally force classic "C" locale, and turn off all formatting
// internationalization, for the entire oslinfo application.
std::locale::global (std::locale::classic());

OIIO::Filesystem::convert_native_arguments (argc, (const char **)argv);

OIIO::ArgParse ap (argc, (const char **)argv);
Expand Down