1
0
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:
abv
2013-02-01 18:41:16 +04:00
parent 3bea4c165c
commit 91322f44fd
203 changed files with 2707 additions and 2807 deletions

View File

@@ -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

View File

@@ -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)

View 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
}

View 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__

View File

@@ -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
View 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 ;