mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-19 13:40:49 +03:00
0022898: IGES import fails in german environment
Added DRAW command dlocale to set and query current locale of the C subsystem Equivalents of C functions working with conversions of strings to/from reals added in Standard_CString, providing locale-independent behavior (using always "C" locale) In DRAW packages, calls to atof() and atoi() are replaced by direct calls to Draw::Atof() and Draw::Atoi(), respectively, instead of substituting by #define Use of atof(), strtod(), and *scanf() involving floating point conversions in OCCT code replaced by locale-independent Atof() and Strtod() Calls to sprintf() involving floating point in OCCT code are replaced by call to locale-independent Sprintf(), except a few places where converted strings are used immediately for display in the 3d viewer Changes of global locale are eliminated throughout OCCT code Proposed correction for GNU libC where v*printf_l functions are absent Added test case (bugs xde bug22898) for data exchange operations with non-standard locale Use xlocale on Mac OS X and within glibc Corrected strtod_l wrapper Generate error rather than warning Introduce Standard_CLocaleSentry replacement for removed OSD_Localizer Standard_CLocaleSentry - copy locale string Standard_CLocaleSentry - use _configthreadlocale on Windows Standard_CLocaleSentry::GetCLocale() - return locale_t rather than void* Corrected misprint in ~Standard_CLocaleSentry() Use French locale in bug22898 test case Mark test case as skipped if locale is unavailable on tested system. Use fr_FR locale for tests on Mac OS X
This commit is contained in:
@@ -21,6 +21,8 @@ Standard_Boolean.cxx
|
||||
Standard_Boolean.hxx
|
||||
Standard_Byte.hxx
|
||||
Standard_PByte.hxx
|
||||
Standard_CLocaleSentry.hxx
|
||||
Standard_CLocaleSentry.cxx
|
||||
Standard_CString.cxx
|
||||
Standard_CString.hxx
|
||||
Standard_Character.cxx
|
||||
|
@@ -29,8 +29,9 @@
|
||||
#include <Standard_MMgrTBBalloc.hxx>
|
||||
|
||||
#if(defined(_WIN32) || defined(__WIN32__))
|
||||
#include <windows.h>
|
||||
#include <malloc.h>
|
||||
#include <windows.h>
|
||||
#include <malloc.h>
|
||||
#include <locale.h>
|
||||
#endif
|
||||
|
||||
#ifndef OCCT_MMGT_OPT_DEFAULT
|
||||
@@ -63,12 +64,23 @@ class Standard_MMgrFactory {
|
||||
Standard_MMgrFactory::Standard_MMgrFactory()
|
||||
: myFMMgr (NULL)
|
||||
{
|
||||
/*#if defined(_MSC_VER) && (_MSC_VER > 1400)
|
||||
// Turn ON thread-safe C locale globally to avoid side effects by setlocale() calls between threads.
|
||||
// After this call all following _configthreadlocale() will be ignored assuming
|
||||
// Notice that this is MSVCRT feature - on POSIX systems xlocale API (uselocale instead of setlocale)
|
||||
// should be used explicitly to ensure thread-safety!
|
||||
|
||||
// This is not well documented call because _ENABLE_PER_THREAD_LOCALE_GLOBAL flag is defined but not implemented for some reason.
|
||||
// -1 will set global locale flag to force _ENABLE_PER_THREAD_LOCALE_GLOBAL + _ENABLE_PER_THREAD_LOCALE_NEW behaviour
|
||||
// although there NO way to turn it off again and following calls will have no effect (locale will be changed only for current thread).
|
||||
_configthreadlocale (-1);
|
||||
#endif*/
|
||||
|
||||
char* aVar;
|
||||
Standard_Integer anAllocId = (aVar = getenv ("MMGT_OPT" )) ? atoi (aVar) :
|
||||
(OCCT_MMGT_OPT_DEFAULT);
|
||||
Standard_Boolean toClear = (aVar = getenv ("MMGT_CLEAR" )) ? (atoi (aVar) != 0) : Standard_True;
|
||||
|
||||
|
||||
// on Windows (actual for XP and 2000) activate low fragmentation heap
|
||||
// for CRT heap in order to get best performance.
|
||||
// Environment variable MMGT_LFH can be used to switch off this action (if set to 0)
|
||||
|
128
src/Standard/Standard_CLocaleSentry.cxx
Normal file
128
src/Standard/Standard_CLocaleSentry.cxx
Normal file
@@ -0,0 +1,128 @@
|
||||
// Created on: 2013-01-17
|
||||
// Created by: Kirill GAVRILOV
|
||||
// Copyright (c) 2013 OPEN CASCADE SAS
|
||||
//
|
||||
// The content of this file is subject to the Open CASCADE Technology Public
|
||||
// License Version 6.5 (the "License"). You may not use the content of this file
|
||||
// except in compliance with the License. Please obtain a copy of the License
|
||||
// at http://www.opencascade.org and read it completely before using this file.
|
||||
//
|
||||
// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
|
||||
// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
|
||||
//
|
||||
// The Original Code and all software distributed under the License is
|
||||
// distributed on an "AS IS" basis, without warranty of any kind, and the
|
||||
// Initial Developer hereby disclaims all such warranties, including without
|
||||
// limitation, any warranties of merchantability, fitness for a particular
|
||||
// purpose or non-infringement. Please see the License for the specific terms
|
||||
// and conditions governing the rights and limitations under the License.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <Standard_CLocaleSentry.hxx>
|
||||
|
||||
#include <Standard_TypeDef.hxx>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
//! CLocalePtr - static object representing C locale
|
||||
class CLocalePtr
|
||||
{
|
||||
public:
|
||||
|
||||
CLocalePtr()
|
||||
#ifdef HAVE_XLOCALE_H
|
||||
: myLocale (newlocale (LC_ALL_MASK, "C", NULL))
|
||||
#elif defined(_WIN32)
|
||||
: myLocale (_create_locale (LC_ALL, "C"))
|
||||
#else
|
||||
: myLocale (NULL)
|
||||
#endif
|
||||
{}
|
||||
|
||||
~CLocalePtr()
|
||||
{
|
||||
#ifdef HAVE_XLOCALE_H
|
||||
freelocale (myLocale);
|
||||
#elif defined(_WIN32)
|
||||
_free_locale (myLocale);
|
||||
#endif
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Standard_CLocaleSentry::clocale_t myLocale;
|
||||
|
||||
};
|
||||
|
||||
static CLocalePtr theCLocale;
|
||||
|
||||
};
|
||||
|
||||
// =======================================================================
|
||||
// function : GetCLocale
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_CLocaleSentry::clocale_t Standard_CLocaleSentry::GetCLocale()
|
||||
{
|
||||
return theCLocale.myLocale;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Standard_CLocaleSentry
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_CLocaleSentry::Standard_CLocaleSentry()
|
||||
#ifdef HAVE_XLOCALE_H
|
||||
: myPrevLocale (uselocale (theCLocale.myLocale)) // switch to C locale within this thread only using xlocale API
|
||||
#else
|
||||
: myPrevLocale (setlocale (LC_ALL, 0))
|
||||
#if defined(_MSC_VER) && (_MSC_VER > 1400)
|
||||
, myPrevTLocaleState (_configthreadlocale (_ENABLE_PER_THREAD_LOCALE))
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
#ifndef HAVE_XLOCALE_H
|
||||
const char* aPrevLocale = (const char* )myPrevLocale;
|
||||
if (aPrevLocale[0] == 'C' && aPrevLocale[1] == '\0')
|
||||
{
|
||||
myPrevLocale = NULL; // already C locale
|
||||
return;
|
||||
}
|
||||
// copy string as following setlocale calls may invalidate returned pointer
|
||||
Standard_Size aLen = std::strlen (aPrevLocale) + 1;
|
||||
myPrevLocale = new char[aLen];
|
||||
memcpy (myPrevLocale, aPrevLocale, aLen);
|
||||
|
||||
setlocale (LC_ALL, "C");
|
||||
#endif
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : ~Standard_CLocaleSentry
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_CLocaleSentry::~Standard_CLocaleSentry()
|
||||
{
|
||||
#ifdef HAVE_XLOCALE_H
|
||||
uselocale ((locale_t )myPrevLocale);
|
||||
#else
|
||||
if (myPrevLocale != NULL)
|
||||
{
|
||||
const char* aPrevLocale = (const char* )myPrevLocale;
|
||||
setlocale (LC_ALL, aPrevLocale);
|
||||
delete[] aPrevLocale;
|
||||
}
|
||||
#if defined(_MSC_VER) && (_MSC_VER > 1400)
|
||||
if (myPrevTLocaleState != _ENABLE_PER_THREAD_LOCALE)
|
||||
{
|
||||
_configthreadlocale (myPrevTLocaleState);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
88
src/Standard/Standard_CLocaleSentry.hxx
Normal file
88
src/Standard/Standard_CLocaleSentry.hxx
Normal file
@@ -0,0 +1,88 @@
|
||||
// Created on: 2013-01-17
|
||||
// Created by: Kirill GAVRILOV
|
||||
// Copyright (c) 2013 OPEN CASCADE SAS
|
||||
//
|
||||
// The content of this file is subject to the Open CASCADE Technology Public
|
||||
// License Version 6.5 (the "License"). You may not use the content of this file
|
||||
// except in compliance with the License. Please obtain a copy of the License
|
||||
// at http://www.opencascade.org and read it completely before using this file.
|
||||
//
|
||||
// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
|
||||
// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
|
||||
//
|
||||
// The Original Code and all software distributed under the License is
|
||||
// distributed on an "AS IS" basis, without warranty of any kind, and the
|
||||
// Initial Developer hereby disclaims all such warranties, including without
|
||||
// limitation, any warranties of merchantability, fitness for a particular
|
||||
// purpose or non-infringement. Please see the License for the specific terms
|
||||
// and conditions governing the rights and limitations under the License.
|
||||
|
||||
#ifndef _Standard_CLocaleSentry_H__
|
||||
#define _Standard_CLocaleSentry_H__
|
||||
|
||||
#include <Standard_Macro.hxx>
|
||||
|
||||
#include <locale.h>
|
||||
|
||||
//! "xlocale.h" available in Mac OS X and glibc (Linux) for a long time as an extension
|
||||
//! and become part of POSIX since '2008.
|
||||
//! Notice that this is impossible to test (_POSIX_C_SOURCE >= 200809L)
|
||||
//! since POSIX didn't declared such identifier.
|
||||
//! We check _GNU_SOURCE for glibc extensions here and it is always defined by g++ compiler.
|
||||
#if defined(__APPLE__) || defined(_GNU_SOURCE) || defined(HAVE_XLOCALE_H)
|
||||
#include <xlocale.h>
|
||||
#ifndef HAVE_XLOCALE_H
|
||||
#define HAVE_XLOCALE_H
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//! This class intended to temporary switch C locale and logically equivalent to setlocale(LC_ALL, "C").
|
||||
//! It is intended to format text regardless of user locale settings (for import/export functionality).
|
||||
//! Thus following calls to sprintf, atoi and other functions will use "C" locale.
|
||||
//! Destructor of this class will return original locale.
|
||||
//!
|
||||
//! Notice that this functionality is platfrom dependent and intended only to workaround alien code
|
||||
//! that doesn't setup locale correctly.
|
||||
//!
|
||||
//! Internally you should prefer more portable C++ locale interfaces
|
||||
//! or OCCT wrappers to some C functions like Sprintf, Atof, Strtod.
|
||||
class Standard_CLocaleSentry
|
||||
{
|
||||
public:
|
||||
|
||||
//! Setup current C locale to "C".
|
||||
Standard_EXPORT Standard_CLocaleSentry();
|
||||
|
||||
//! Restore previous locale.
|
||||
Standard_EXPORT virtual ~Standard_CLocaleSentry();
|
||||
|
||||
public:
|
||||
|
||||
#ifdef HAVE_XLOCALE_H
|
||||
typedef locale_t clocale_t;
|
||||
#elif defined(_WIN32)
|
||||
typedef _locale_t clocale_t;
|
||||
#else
|
||||
typedef void* clocale_t;
|
||||
#endif
|
||||
|
||||
//! @return locale "C" instance (locale_t within xlocale or _locale_t within Windows)
|
||||
//! to be used for _l functions with locale argument.
|
||||
static Standard_EXPORT clocale_t GetCLocale();
|
||||
|
||||
private:
|
||||
|
||||
void* myPrevLocale; //!< previous locale, platform-dependent pointer!
|
||||
#ifdef _WIN32
|
||||
int myPrevTLocaleState; //!< previous thread-locale state, MSVCRT-specific
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
//! Copying disallowed
|
||||
Standard_CLocaleSentry (const Standard_CLocaleSentry& );
|
||||
Standard_CLocaleSentry& operator= (const Standard_CLocaleSentry& );
|
||||
|
||||
};
|
||||
|
||||
#endif // _Standard_CLocaleSentry_H__
|
@@ -1,5 +1,5 @@
|
||||
// Copyright (c) 1998-1999 Matra Datavision
|
||||
// Copyright (c) 1999-2012 OPEN CASCADE SAS
|
||||
// Copyright (c) 1999-2013 OPEN CASCADE SAS
|
||||
//
|
||||
// The content of this file is subject to the Open CASCADE Technology Public
|
||||
// License Version 6.5 (the "License"). You may not use the content of this file
|
||||
@@ -30,9 +30,9 @@
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include <Standard_CLocaleSentry.hxx>
|
||||
#include <Standard_CString.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
#include <Standard_OStream.hxx>
|
||||
|
||||
#if OptJr
|
||||
@@ -51,13 +51,14 @@ static const Standard_Integer static_MaskEndIntegerString[4] = { 0x00000000 ,
|
||||
|
||||
#include <Standard_String.hxx>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
//============================================================================
|
||||
//====
|
||||
//====
|
||||
//============================================================================
|
||||
const Handle_Standard_Type& Standard_CString_Type_()
|
||||
const Handle_Standard_Type& Standard_CString_Type_()
|
||||
{
|
||||
static Handle_Standard_Type _aType =
|
||||
static Handle_Standard_Type _aType =
|
||||
new Standard_Type("Standard_CString",sizeof(Standard_CString),0,NULL);
|
||||
|
||||
return _aType;
|
||||
@@ -72,7 +73,7 @@ Standard_EXPORT void ShallowDump (const Standard_CString Value, Standard_OStream
|
||||
//============================================================================
|
||||
//==== HashCode of a CString
|
||||
//============================================================================
|
||||
Standard_Integer HashCode (const Standard_CString Value,
|
||||
Standard_Integer HashCode (const Standard_CString Value,
|
||||
const Standard_Integer Upper )
|
||||
{
|
||||
Standard_Integer aLen ;
|
||||
@@ -113,7 +114,7 @@ Standard_Integer HashCodes (const Standard_CString Value ,
|
||||
*tmphash;
|
||||
char tabchar[20];
|
||||
#endif
|
||||
|
||||
|
||||
if (Value != NULL) {
|
||||
|
||||
#if !OptJr
|
||||
@@ -124,7 +125,7 @@ Standard_Integer HashCodes (const Standard_CString Value ,
|
||||
else tabchar[count] = charPtr[pos + count];
|
||||
i++;
|
||||
}
|
||||
tmphash = (Standard_Integer *)tabchar;
|
||||
tmphash = (Standard_Integer *)tabchar;
|
||||
aHashCode = aHashCode ^ *tmphash;
|
||||
}
|
||||
}
|
||||
@@ -256,4 +257,67 @@ Standard_Boolean ISSIMILAR(const Standard_CString One ,
|
||||
return Standard_True ;
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
// There are a lot of *_l functions availalbe on Mac OS X - we use them
|
||||
#define SAVE_TL()
|
||||
#elif defined(_WIN32)
|
||||
// MSVCRT has equivalents with slightly different syntax
|
||||
#define SAVE_TL()
|
||||
#define strtod_l(thePtr, theNextPtr, theLocale) _strtod_l(thePtr, theNextPtr, theLocale)
|
||||
#define vprintf_l(theLocale, theFormat, theArgPtr) _vprintf_l(theFormat, theLocale, theArgPtr)
|
||||
#define vsprintf_l(theBuffer, theLocale, theFormat, theArgPtr) _vsprintf_l(theBuffer, theFormat, theLocale, theArgPtr)
|
||||
#define vfprintf_l(theFile, theLocale, theFormat, theArgPtr) _vfprintf_l(theFile, theFormat, theLocale, theArgPtr)
|
||||
#else
|
||||
// glibc provides only limited xlocale implementation:
|
||||
// strtod_l/strtol_l/strtoll_l functions with explicitly specified locale
|
||||
// and newlocale/uselocale/freelocale to switch locale within current thread only.
|
||||
// So we switch to C locale temporarily
|
||||
#define SAVE_TL() Standard_CLocaleSentry aLocaleSentry;
|
||||
#ifndef HAVE_XLOCALE_H
|
||||
#error System does not support xlocale. Import/export could be broken if C locale did not specified by application.
|
||||
#define strtod_l(thePtr, theNextPtr, theLocale) strtod(thePtr, theNextPtr)
|
||||
#endif
|
||||
#define vprintf_l(theLocale, theFormat, theArgPtr) vprintf(theFormat, theArgPtr)
|
||||
#define vsprintf_l(theBuffer, theLocale, theFormat, theArgPtr) vsprintf(theBuffer, theFormat, theArgPtr)
|
||||
#define vfprintf_l(theFile, theLocale, theFormat, theArgPtr) vfprintf(theFile, theFormat, theArgPtr)
|
||||
#endif
|
||||
|
||||
double Strtod (const char* theStr, char** theNextPtr)
|
||||
{
|
||||
return strtod_l (theStr, theNextPtr, Standard_CLocaleSentry::GetCLocale());
|
||||
}
|
||||
|
||||
double Atof (const char* theStr)
|
||||
{
|
||||
return Strtod (theStr, NULL);
|
||||
}
|
||||
|
||||
int Printf (const Standard_CString theFormat, ...)
|
||||
{
|
||||
SAVE_TL();
|
||||
va_list argp;
|
||||
va_start(argp, theFormat);
|
||||
int result = vprintf_l (Standard_CLocaleSentry::GetCLocale(), theFormat, argp);
|
||||
va_end(argp);
|
||||
return result;
|
||||
}
|
||||
|
||||
int Fprintf (FILE* theFile, const char* theFormat, ...)
|
||||
{
|
||||
SAVE_TL();
|
||||
va_list argp;
|
||||
va_start(argp, theFormat);
|
||||
int result = vfprintf_l(theFile, Standard_CLocaleSentry::GetCLocale(), theFormat, argp);
|
||||
va_end(argp);
|
||||
return result;
|
||||
}
|
||||
|
||||
int Sprintf (char* theBuffer, const char* theFormat, ...)
|
||||
{
|
||||
SAVE_TL();
|
||||
va_list argp;
|
||||
va_start(argp, theFormat);
|
||||
int result = vsprintf_l(theBuffer, Standard_CLocaleSentry::GetCLocale(), theFormat, argp);
|
||||
va_end(argp);
|
||||
return result;
|
||||
}
|
||||
|
22
src/Standard/Standard_CString.hxx
Executable file → Normal file
22
src/Standard/Standard_CString.hxx
Executable file → Normal file
@@ -19,7 +19,7 @@
|
||||
//============================================================================
|
||||
//==== Titre: Standard_CString.hxx
|
||||
//==== Role : The headr file of primitve type "CString" from package "Standard"
|
||||
//====
|
||||
//====
|
||||
//==== Implementation: This is a primitive type implementadef with typedef
|
||||
//==== typedef char* Standard_CString;
|
||||
//============================================================================
|
||||
@@ -31,11 +31,12 @@
|
||||
# include <Standard_TypeDef.hxx>
|
||||
# endif
|
||||
|
||||
# ifdef WNT
|
||||
# ifdef _MSC_VER
|
||||
# define strcasecmp _stricmp
|
||||
# endif
|
||||
|
||||
# include <string.h>
|
||||
# include <stdio.h>
|
||||
|
||||
# ifndef _Standard_Integer_HeaderFile
|
||||
# include <Standard_Integer.hxx>
|
||||
@@ -79,6 +80,13 @@ inline Standard_Integer HASHCODE (const Standard_CString,
|
||||
__Standard_API Standard_Integer HASHCODES (const Standard_CString,
|
||||
const Standard_Integer);
|
||||
|
||||
//! Equivalents of functions from standard C library that use always C locale
|
||||
__Standard_API double Atof (const char* theStr);
|
||||
__Standard_API double Strtod (const char* theStr, char** theNextPtr);
|
||||
__Standard_API int Printf (const char* theFormat, ...);
|
||||
__Standard_API int Fprintf (FILE* theFile, const char* theFormat, ...);
|
||||
__Standard_API int Sprintf (char* theBuffer, const char* theFormat, ...);
|
||||
|
||||
//============================================================================
|
||||
//==== ShallowCopy: Returns a CString
|
||||
//============================================================================
|
||||
@@ -92,7 +100,7 @@ inline Standard_CString ShallowCopy (const Standard_CString Value)
|
||||
//============================================================================
|
||||
inline Standard_Boolean IsSimilar(const Standard_CString One
|
||||
,const Standard_CString Two)
|
||||
{
|
||||
{
|
||||
return (strcmp(One,Two) == 0);
|
||||
}
|
||||
|
||||
@@ -101,7 +109,7 @@ inline Standard_Boolean IsSimilar(const Standard_CString One
|
||||
//==== the HashCode % Upper
|
||||
//============================================================================
|
||||
inline Standard_Integer HashCode (const Standard_CString Value,
|
||||
const Standard_Integer Len ,
|
||||
const Standard_Integer Len ,
|
||||
const Standard_Integer Upper ,
|
||||
Standard_Integer& aHashCode )
|
||||
{
|
||||
@@ -127,7 +135,7 @@ inline Standard_Integer HashCode (const Standard_CString Value,
|
||||
//==== and the HashCode % Upper
|
||||
//============================================================================
|
||||
inline Standard_Integer HASHCODE (const Standard_CString Value,
|
||||
const Standard_Integer Len ,
|
||||
const Standard_Integer Len ,
|
||||
const Standard_Integer Upper ,
|
||||
Standard_Integer& aHashCode )
|
||||
{
|
||||
@@ -140,7 +148,7 @@ inline Standard_Integer HASHCODE (const Standard_CString Value,
|
||||
//==== HashCode of a CString converted to uppercase
|
||||
//============================================================================
|
||||
inline Standard_Integer HASHCODE (const Standard_CString Value,
|
||||
const Standard_Integer Len ,
|
||||
const Standard_Integer Len ,
|
||||
const Standard_Integer Upper)
|
||||
{
|
||||
// return (Abs( HASHCODES( Value , Len ) ) % Upper ) + 1 ;
|
||||
@@ -159,7 +167,7 @@ inline Standard_Boolean ISEQUAL(const Standard_CString One ,
|
||||
const Standard_Integer LenOne ,
|
||||
const Standard_CString Two,
|
||||
const Standard_Integer LenTwo )
|
||||
{
|
||||
{
|
||||
|
||||
if ( One == Two )
|
||||
return Standard_True ;
|
||||
|
Reference in New Issue
Block a user