From 87be2e1427ba2b1b7697c9332487862917897dca Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 6 Feb 2015 13:09:37 -0500 Subject: [PATCH 1/2] Do not call setlocale() globally in CMake applications (#15377) Revert the changes made by commit v3.1.0-rc1~406^2~1 (Encoding: Add setlocale() to applications, 2014-05-30) and commit v3.1.0-rc1~406^2 (Encoding: Change to only set LC_CTYPE, 2014-06-11), and other setlocale calls added later in their spirit. CMake has not been taught how to deal with non-C locales everywhere. We do not define any functionality for character conversions for non-ASCII strings. Another solution will be needed to address the original problem motivating addition of setlocale() calls. --- Source/CPack/cpack.cxx | 2 -- Source/CursesDialog/ccmake.cxx | 3 --- Source/cmakemain.cxx | 2 -- Source/ctest.cxx | 3 --- Tests/CTestTestMemcheck/memtester.cxx.in | 2 -- 5 files changed, 12 deletions(-) diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx index c57028ddd..0173361ce 100644 --- a/Source/CPack/cpack.cxx +++ b/Source/CPack/cpack.cxx @@ -26,7 +26,6 @@ #include #include #include -#include //---------------------------------------------------------------------------- static const char * cmDocumentationName[][2] = @@ -101,7 +100,6 @@ int cpackDefinitionArgument(const char* argument, const char* cValue, // this is CPack. int main (int argc, char const* const* argv) { - setlocale(LC_CTYPE, ""); cmsys::Encoding::CommandLineArguments args = cmsys::Encoding::CommandLineArguments::Main(argc, argv); argc = args.argc(); diff --git a/Source/CursesDialog/ccmake.cxx b/Source/CursesDialog/ccmake.cxx index 28f3d9b78..3d92a2dfd 100644 --- a/Source/CursesDialog/ccmake.cxx +++ b/Source/CursesDialog/ccmake.cxx @@ -16,7 +16,6 @@ #include #include -#include #include "cmCursesMainForm.h" #include "cmCursesStandardIncludes.h" @@ -95,8 +94,6 @@ void CMakeMessageHandler(const char* message, const char* title, bool&, int main(int argc, char const* const* argv) { - setlocale(LC_CTYPE, ""); - cmsys::Encoding::CommandLineArguments encoding_args = cmsys::Encoding::CommandLineArguments::Main(argc, argv); argc = encoding_args.argc(); diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index 61b175e13..e825f1f1f 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -25,7 +25,6 @@ #include "cmLocalGenerator.h" #include "cmMakefile.h" #include -#include #ifdef CMAKE_BUILD_WITH_CMAKE //---------------------------------------------------------------------------- @@ -175,7 +174,6 @@ static void cmakemainProgressCallback(const char *m, float prog, int main(int ac, char const* const* av) { - setlocale(LC_CTYPE, ""); cmsys::Encoding::CommandLineArguments args = cmsys::Encoding::CommandLineArguments::Main(ac, av); ac = args.argc(); diff --git a/Source/ctest.cxx b/Source/ctest.cxx index fb97af606..3fe31cab1 100644 --- a/Source/ctest.cxx +++ b/Source/ctest.cxx @@ -19,7 +19,6 @@ #include "CTest/cmCTestScriptHandler.h" #include "CTest/cmCTestLaunch.h" #include "cmsys/Encoding.hxx" -#include //---------------------------------------------------------------------------- static const char * cmDocumentationName[][2] = @@ -117,8 +116,6 @@ static const char * cmDocumentationOptions[][2] = // this is a test driver program for cmCTest. int main (int argc, char const* const* argv) { - setlocale(LC_CTYPE, ""); - cmsys::Encoding::CommandLineArguments encoding_args = cmsys::Encoding::CommandLineArguments::Main(argc, argv); argc = encoding_args.argc(); diff --git a/Tests/CTestTestMemcheck/memtester.cxx.in b/Tests/CTestTestMemcheck/memtester.cxx.in index 43c0ba7a1..c018e0862 100644 --- a/Tests/CTestTestMemcheck/memtester.cxx.in +++ b/Tests/CTestTestMemcheck/memtester.cxx.in @@ -1,14 +1,12 @@ #include #include #include -#include #define RETVAL @_retval@ int main(int ac, char **av) { - setlocale(LC_CTYPE, ""); cmsys::Encoding::CommandLineArguments args = cmsys::Encoding::CommandLineArguments::Main(ac, av); int argc = args.argc(); From cd408d93fdf347ff63a8062f75f1f4ee3e898b17 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 6 Feb 2015 13:23:07 -0500 Subject: [PATCH 2/2] Add setlocale() calls around use of libarchive APIs (#14934, #15377) The libarchive APIs use nl_langinfo(CODESET) for iconv so they need the locale to be set for LC_CTYPE. However, the rest of CMake does not define any behavior for non-ASCII character classification/conversion so we do not want to setlocale() globally. Add a RAII class to save, set, and restore the locale around calls to libarchive APIs. Inspired-by: Clinton Stimpson --- Source/CMakeLists.txt | 1 + Source/cmArchiveWrite.cxx | 4 ++++ Source/cmLocale.h | 31 +++++++++++++++++++++++++++++++ Source/cmSystemTools.cxx | 3 +++ 4 files changed, 39 insertions(+) create mode 100644 Source/cmLocale.h diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index f9405b364..1ff1c1637 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -261,6 +261,7 @@ set(SRCS cmLocalGenerator.cxx cmLocalGenerator.h cmLocalUnixMakefileGenerator3.cxx + cmLocale.h cmMakeDepend.cxx cmMakeDepend.h cmMakefile.cxx diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx index a2aecac00..9f28d42b8 100644 --- a/Source/cmArchiveWrite.cxx +++ b/Source/cmArchiveWrite.cxx @@ -12,6 +12,7 @@ #include "cmArchiveWrite.h" #include "cmSystemTools.h" +#include "cmLocale.h" #include #include #include @@ -259,6 +260,9 @@ bool cmArchiveWrite::AddFile(const char* file, } const char* out = file + skip; + cmLocaleRAII localeRAII; + static_cast(localeRAII); + // Meta-data. std::string dest = prefix? prefix : ""; dest += out; diff --git a/Source/cmLocale.h b/Source/cmLocale.h new file mode 100644 index 000000000..727f0f5d4 --- /dev/null +++ b/Source/cmLocale.h @@ -0,0 +1,31 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2015 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmLocale_h +#define cmLocale_h + +#include + +class cmLocaleRAII +{ + const char* OldLocale; +public: + cmLocaleRAII(): OldLocale(setlocale(LC_CTYPE, 0)) + { + setlocale(LC_CTYPE, ""); + } + ~cmLocaleRAII() + { + setlocale(LC_CTYPE, this->OldLocale); + } +}; + +#endif diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index fbb44160c..89efdc7c0 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -28,6 +28,7 @@ #include #if defined(CMAKE_BUILD_WITH_CMAKE) # include "cmArchiveWrite.h" +# include "cmLocale.h" # include # include #endif @@ -1691,6 +1692,8 @@ long copy_data(struct archive *ar, struct archive *aw) bool extract_tar(const char* outFileName, bool verbose, bool extract) { + cmLocaleRAII localeRAII; + static_cast(localeRAII); struct archive* a = archive_read_new(); struct archive *ext = archive_write_disk_new(); archive_read_support_compression_all(a);