Skip to content

Commit a728341

Browse files
committed
use class to temporary override locale to C
(cherry picked from commit 0ecef35)
1 parent c980332 commit a728341

8 files changed

+118
-54
lines changed

src/core/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ SET(QGIS_CORE_SRCS
174174
qgsvectorsimplifymethod.cpp
175175
qgsxmlutils.cpp
176176
qgsslconnect.cpp
177+
qgslocalec.cpp
177178

178179
composer/qgsaddremoveitemcommand.cpp
179180
composer/qgsaddremovemultiframecommand.cpp
@@ -552,6 +553,7 @@ SET(QGIS_CORE_HDRS
552553
qgsvectorlayerundocommand.h
553554
qgsvectorsimplifymethod.h
554555
qgsxmlutils.h
556+
qgslocalec.h
555557

556558
diagram/qgsdiagram.h
557559
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>
@@ -1628,6 +1629,8 @@ bool QgsVectorFileWriter::addFeature( QgsFeature& feature, QgsFeatureRendererV2*
16281629

16291630
OGRFeatureH QgsVectorFileWriter::createFeature( QgsFeature& feature )
16301631
{
1632+
QgsLocaleNumC l;
1633+
16311634
OGRFeatureH poFeature = OGR_F_Create( OGR_L_GetLayerDefn( mLayer ) );
16321635

16331636
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
@@ -23,6 +23,7 @@
2323
#include "qgscoordinatereferencesystem.h"
2424
#include "qgsrectangle.h"
2525
#include "qgsconfig.h"
26+
#include "qgslocalec.h"
2627

2728
#include <QFileDialog>
2829
#include <QMessageBox>
@@ -1409,31 +1410,29 @@ QgsCoordinateReferenceSystem GRASS_LIB_EXPORT QgsGrass::crsDirect( QString gisdb
14091410
QgsGrass::resetError();
14101411
QgsGrass::setLocation( gisdbase, location );
14111412

1412-
const char *oldlocale = setlocale( LC_NUMERIC, NULL );
1413-
setlocale( LC_NUMERIC, "C" );
1414-
1415-
G_TRY
1416-
{
1417-
G_get_default_window( &cellhd );
1418-
}
1419-
G_CATCH( QgsGrass::Exception &e )
14201413
{
1421-
Q_UNUSED( e );
1422-
setlocale( LC_NUMERIC, oldlocale );
1423-
QgsDebugMsg( QString( "Cannot get default window: %1" ).arg( e.what() ) );
1424-
return QgsCoordinateReferenceSystem();
1425-
}
1414+
QgsLocaleNumC l;
14261415

1427-
if ( cellhd.proj != PROJECTION_XY )
1428-
{
1429-
struct Key_Value *projinfo = G_get_projinfo();
1430-
struct Key_Value *projunits = G_get_projunits();
1431-
char *wkt = GPJ_grass_to_wkt( projinfo, projunits, 0, 0 );
1432-
Wkt = QString( wkt );
1433-
G_free( wkt );
1434-
}
1416+
G_TRY
1417+
{
1418+
G_get_default_window( &cellhd );
1419+
}
1420+
G_CATCH( QgsGrass::Exception &e )
1421+
{
1422+
Q_UNUSED( e );
1423+
QgsDebugMsg( QString( "Cannot get default window: %1" ).arg( e.what() ) );
1424+
return QgsCoordinateReferenceSystem();
1425+
}
14351426

1436-
setlocale( LC_NUMERIC, oldlocale );
1427+
if ( cellhd.proj != PROJECTION_XY )
1428+
{
1429+
struct Key_Value *projinfo = G_get_projinfo();
1430+
struct Key_Value *projunits = G_get_projunits();
1431+
char *wkt = GPJ_grass_to_wkt( projinfo, projunits, 0, 0 );
1432+
Wkt = QString( wkt );
1433+
G_free( wkt );
1434+
}
1435+
}
14371436

14381437
QgsCoordinateReferenceSystem srs;
14391438
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 =
@@ -1003,11 +1005,7 @@ bool QgsOgrProvider::addFeature( QgsFeature& f )
10031005

10041006
const QgsAttributes& attrs = f.attributes();
10051007

1006-
char *oldlocale = setlocale( LC_NUMERIC, NULL );
1007-
if ( oldlocale )
1008-
oldlocale = strdup( oldlocale );
1009-
1010-
setlocale( LC_NUMERIC, "C" );
1008+
QgsLocaleNumC l;
10111009

10121010
//add possible attribute information
10131011
for ( int targetAttributeId = 0; targetAttributeId < attrs.count(); ++targetAttributeId )
@@ -1086,10 +1084,6 @@ bool QgsOgrProvider::addFeature( QgsFeature& f )
10861084
}
10871085
OGR_F_Destroy( feature );
10881086

1089-
setlocale( LC_NUMERIC, oldlocale );
1090-
if ( oldlocale )
1091-
free( oldlocale );
1092-
10931087
return returnValue;
10941088
}
10951089

@@ -1224,10 +1218,7 @@ bool QgsOgrProvider::changeAttributeValues( const QgsChangedAttributesMap &attr_
12241218
continue;
12251219
}
12261220

1227-
char *oldlocale = setlocale( LC_NUMERIC, NULL );
1228-
if ( oldlocale )
1229-
oldlocale = strdup( oldlocale );
1230-
setlocale( LC_NUMERIC, "C" );
1221+
QgsLocaleNumC l;
12311222

12321223
for ( QgsAttributeMap::const_iterator it2 = attr.begin(); it2 != attr.end(); ++it2 )
12331224
{
@@ -1289,10 +1280,6 @@ bool QgsOgrProvider::changeAttributeValues( const QgsChangedAttributesMap &attr_
12891280
{
12901281
pushError( tr( "OGR error setting feature %1: %2" ).arg( fid ).arg( CPLGetLastErrorMsg() ) );
12911282
}
1292-
1293-
setlocale( LC_NUMERIC, oldlocale );
1294-
if ( oldlocale )
1295-
free( oldlocale );
12961283
}
12971284

12981285
if ( OGR_L_SyncToDisk( ogrLayer ) != OGRERR_NONE )

0 commit comments

Comments
 (0)