Skip to content

Commit 0ecef35

Browse files
committed
use class to temporary override locale to C
1 parent b4fc413 commit 0ecef35

8 files changed

+118
-54
lines changed

src/core/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ SET(QGIS_CORE_SRCS
186186
qgsvectorsimplifymethod.cpp
187187
qgsxmlutils.cpp
188188
qgsslconnect.cpp
189+
qgslocalec.cpp
189190

190191
composer/qgsaddremoveitemcommand.cpp
191192
composer/qgsaddremovemultiframecommand.cpp
@@ -603,6 +604,7 @@ SET(QGIS_CORE_HDRS
603604
qgswebpage.h
604605
qgswebframe.h
605606
qgswebview.h
607+
qgslocalec.h
606608

607609
diagram/qgsdiagram.h
608610
diagram/qgspiediagram.h

src/core/qgscoordinatereferencesystem.cpp

+4-11
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "qgslogger.h"
3535
#include "qgsmessagelog.h"
3636
#include "qgis.h" //const vals declared here
37+
#include "qgslocalec.h"
3738

3839
#include <sqlite3.h>
3940
#include <proj_api.h>
@@ -921,26 +922,18 @@ void QgsCoordinateReferenceSystem::setDescription( QString theDescription )
921922
void QgsCoordinateReferenceSystem::setProj4String( QString theProj4String )
922923
{
923924
mProj4 = theProj4String;
924-
char *oldlocale = setlocale( LC_NUMERIC, NULL );
925-
/* the next setlocale() invalides the return of previous setlocale() */
926-
if ( oldlocale )
927-
oldlocale = strdup( oldlocale );
928925

929-
setlocale( LC_NUMERIC, "C" );
926+
QgsLocaleNumC l;
927+
930928
OSRDestroySpatialReference( mCRS );
931929
mCRS = OSRNewSpatialReference( NULL );
932-
mIsValidFlag =
933-
OSRImportFromProj4( mCRS, theProj4String.trimmed().toLatin1().constData() )
934-
== OGRERR_NONE;
930+
mIsValidFlag = OSRImportFromProj4( mCRS, theProj4String.trimmed().toLatin1().constData() ) == OGRERR_NONE;
935931
mWkt.clear();
936932
setMapUnits();
937933

938934
#if defined(QGISDEBUG) && QGISDEBUG>=3
939935
debugPrint();
940936
#endif
941-
942-
setlocale( LC_NUMERIC, oldlocale );
943-
free( oldlocale );
944937
}
945938
void QgsCoordinateReferenceSystem::setGeographicFlag( bool theGeoFlag )
946939
{

src/core/qgslocalec.cpp

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/***************************************************************************
2+
qgslocalec.h - temporary C numeric locale
3+
-------------------
4+
begin : Jun 15th 2015
5+
copyright : (C) 2015 by Juergen E. Fischer
6+
email : jef at norbit dot de
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
* *
11+
* This program is free software; you can redistribute it and/or modify *
12+
* it under the terms of the GNU General Public License as published by *
13+
* the Free Software Foundation; either version 2 of the License, or *
14+
* (at your option) any later version. *
15+
* *
16+
***************************************************************************/
17+
18+
#include <qgslocalec.h>
19+
20+
#include <locale.h>
21+
#include <QByteArray>
22+
23+
QMutex QgsLocaleNumC::sLocaleLock;
24+
25+
QgsLocaleNumC::QgsLocaleNumC()
26+
{
27+
sLocaleLock.lock();
28+
29+
mOldlocale = setlocale( LC_NUMERIC, NULL );
30+
if ( mOldlocale )
31+
mOldlocale = qstrdup( mOldlocale );
32+
33+
setlocale( LC_NUMERIC, "C" );
34+
}
35+
36+
QgsLocaleNumC::~QgsLocaleNumC()
37+
{
38+
setlocale( LC_NUMERIC, mOldlocale );
39+
if ( mOldlocale )
40+
delete [] mOldlocale;
41+
42+
sLocaleLock.unlock();
43+
}

src/core/qgslocalec.h

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/***************************************************************************
2+
qgslocalec.h - temporary C numeric locale
3+
-------------------
4+
begin : Jun 15th 2015
5+
copyright : (C) 2015 by Juergen E. Fischer
6+
email : jef at norbit dot de
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
* *
11+
* This program is free software; you can redistribute it and/or modify *
12+
* it under the terms of the GNU General Public License as published by *
13+
* the Free Software Foundation; either version 2 of the License, or *
14+
* (at your option) any later version. *
15+
* *
16+
***************************************************************************/
17+
18+
#ifndef QGSLOCALENUMC_H
19+
#define QGSLOCALENUMC_H
20+
21+
#include <QMutex>
22+
23+
class CORE_EXPORT QgsLocaleNumC
24+
{
25+
char *mOldlocale;
26+
static QMutex sLocaleLock;
27+
28+
public:
29+
QgsLocaleNumC();
30+
~QgsLocaleNumC();
31+
32+
};
33+
34+
#endif // QGSLOCALENUMC_H

src/core/qgsvectorfilewriter.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "qgsrendererv2.h"
2828
#include "qgssymbollayerv2.h"
2929
#include "qgsvectordataprovider.h"
30+
#include "qgslocalec.h"
3031

3132
#include <QFile>
3233
#include <QSettings>
@@ -1625,6 +1626,8 @@ bool QgsVectorFileWriter::addFeature( QgsFeature& feature, QgsFeatureRendererV2*
16251626

16261627
OGRFeatureH QgsVectorFileWriter::createFeature( QgsFeature& feature )
16271628
{
1629+
QgsLocaleNumC l;
1630+
16281631
OGRFeatureH poFeature = OGR_F_Create( OGR_L_GetLayerDefn( mLayer ) );
16291632

16301633
qint64 fid = FID_TO_NUMBER( feature.id() );

src/plugins/grass/qgsgrassnewmapset.cpp

+7-4
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "qgsmapcanvas.h"
2626
#include "qgsproject.h"
2727
#include "qgsprojectionselector.h"
28+
#include "qgslocalec.h"
2829

2930
#include <QCloseEvent>
3031
#include <QFileDialog>
@@ -427,10 +428,12 @@ void QgsGrassNewMapset::setGrassProjection()
427428
OGRSpatialReferenceH hCRS = NULL;
428429
hCRS = OSRNewSpatialReference( NULL );
429430
int errcode;
430-
const char *oldlocale = setlocale( LC_NUMERIC, NULL );
431-
setlocale( LC_NUMERIC, "C" );
432-
errcode = OSRImportFromProj4( hCRS, proj4.toUtf8() );
433-
setlocale( LC_NUMERIC, oldlocale );
431+
432+
{
433+
QgsLocaleNumC l;
434+
errcode = OSRImportFromProj4( hCRS, proj4.toUtf8() );
435+
}
436+
434437
if ( errcode != OGRERR_NONE )
435438
{
436439
QgsDebugMsg( QString( "OGR can't parse PROJ.4-style parameter string:\n%1\nOGR Error code was %2" ).arg( proj4 ).arg( errcode ) );

src/providers/grass/qgsgrass.cpp

+21-22
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "qgsfield.h"
3030
#include "qgsrectangle.h"
3131
#include "qgsconfig.h"
32+
#include "qgslocalec.h"
3233

3334
#include <QFileDialog>
3435
#include <QMessageBox>
@@ -1723,31 +1724,29 @@ QgsCoordinateReferenceSystem GRASS_LIB_EXPORT QgsGrass::crsDirect( const QString
17231724
QgsGrass::resetError();
17241725
QgsGrass::setLocation( gisdbase, location );
17251726

1726-
const char *oldlocale = setlocale( LC_NUMERIC, NULL );
1727-
setlocale( LC_NUMERIC, "C" );
1728-
1729-
G_TRY
1730-
{
1731-
G_get_default_window( &cellhd );
1732-
}
1733-
G_CATCH( QgsGrass::Exception &e )
17341727
{
1735-
Q_UNUSED( e );
1736-
setlocale( LC_NUMERIC, oldlocale );
1737-
QgsDebugMsg( QString( "Cannot get default window: %1" ).arg( e.what() ) );
1738-
return QgsCoordinateReferenceSystem();
1739-
}
1728+
QgsLocaleNumC l;
17401729

1741-
if ( cellhd.proj != PROJECTION_XY )
1742-
{
1743-
struct Key_Value *projinfo = G_get_projinfo();
1744-
struct Key_Value *projunits = G_get_projunits();
1745-
char *wkt = GPJ_grass_to_wkt( projinfo, projunits, 0, 0 );
1746-
Wkt = QString( wkt );
1747-
G_free( wkt );
1748-
}
1730+
G_TRY
1731+
{
1732+
G_get_default_window( &cellhd );
1733+
}
1734+
G_CATCH( QgsGrass::Exception &e )
1735+
{
1736+
Q_UNUSED( e );
1737+
QgsDebugMsg( QString( "Cannot get default window: %1" ).arg( e.what() ) );
1738+
return QgsCoordinateReferenceSystem();
1739+
}
17491740

1750-
setlocale( LC_NUMERIC, oldlocale );
1741+
if ( cellhd.proj != PROJECTION_XY )
1742+
{
1743+
struct Key_Value *projinfo = G_get_projinfo();
1744+
struct Key_Value *projunits = G_get_projunits();
1745+
char *wkt = GPJ_grass_to_wkt( projinfo, projunits, 0, 0 );
1746+
Wkt = QString( wkt );
1747+
G_free( wkt );
1748+
}
1749+
}
17511750

17521751
QgsCoordinateReferenceSystem srs;
17531752
srs.createFromWkt( Wkt );

src/providers/ogr/qgsogrprovider.cpp

+4-17
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ email : sherman at mrcc.com
1919
#include "qgsogrfeatureiterator.h"
2020
#include "qgslogger.h"
2121
#include "qgsmessagelog.h"
22+
#include "qgslocalec.h"
2223

2324
#define CPL_SUPRESS_CPLUSPLUS
2425
#include <gdal.h> // to collect version information
@@ -45,6 +46,7 @@ email : sherman at mrcc.com
4546
#include "qgsgeometry.h"
4647
#include "qgscoordinatereferencesystem.h"
4748
#include "qgsvectorlayerimport.h"
49+
#include "qgslocalec.h"
4850

4951
static const QString TEXT_PROVIDER_KEY = "ogr";
5052
static const QString TEXT_PROVIDER_DESCRIPTION =
@@ -1001,11 +1003,7 @@ bool QgsOgrProvider::addFeature( QgsFeature& f )
10011003

10021004
QgsAttributes attrs = f.attributes();
10031005

1004-
char *oldlocale = setlocale( LC_NUMERIC, NULL );
1005-
if ( oldlocale )
1006-
oldlocale = strdup( oldlocale );
1007-
1008-
setlocale( LC_NUMERIC, "C" );
1006+
QgsLocaleNumC l;
10091007

10101008
//add possible attribute information
10111009
for ( int targetAttributeId = 0; targetAttributeId < attrs.count(); ++targetAttributeId )
@@ -1084,10 +1082,6 @@ bool QgsOgrProvider::addFeature( QgsFeature& f )
10841082
}
10851083
OGR_F_Destroy( feature );
10861084

1087-
setlocale( LC_NUMERIC, oldlocale );
1088-
if ( oldlocale )
1089-
free( oldlocale );
1090-
10911085
return returnValue;
10921086
}
10931087

@@ -1222,10 +1216,7 @@ bool QgsOgrProvider::changeAttributeValues( const QgsChangedAttributesMap &attr_
12221216
continue;
12231217
}
12241218

1225-
char *oldlocale = setlocale( LC_NUMERIC, NULL );
1226-
if ( oldlocale )
1227-
oldlocale = strdup( oldlocale );
1228-
setlocale( LC_NUMERIC, "C" );
1219+
QgsLocaleNumC l;
12291220

12301221
for ( QgsAttributeMap::const_iterator it2 = attr.begin(); it2 != attr.end(); ++it2 )
12311222
{
@@ -1287,10 +1278,6 @@ bool QgsOgrProvider::changeAttributeValues( const QgsChangedAttributesMap &attr_
12871278
{
12881279
pushError( tr( "OGR error setting feature %1: %2" ).arg( fid ).arg( CPLGetLastErrorMsg() ) );
12891280
}
1290-
1291-
setlocale( LC_NUMERIC, oldlocale );
1292-
if ( oldlocale )
1293-
free( oldlocale );
12941281
}
12951282

12961283
if ( OGR_L_SyncToDisk( ogrLayer ) != OGRERR_NONE )

0 commit comments

Comments
 (0)