Branch data Line data Source code
1 : : /********************************************************************\ 2 : : * gnc-locale-utils.cpp -- provide a default locale for C++ * 3 : : * Copyright (C) 2019 John Ralls <jralls@ceridwen.us * 4 : : * * 5 : : * This program is free software; you can redistribute it and/or * 6 : : * modify it under the terms of the GNU General Public License as * 7 : : * published by the Free Software Foundation; either version 2 of * 8 : : * the License, or (at your option) any later version. * 9 : : * * 10 : : * This program is distributed in the hope that it will be useful, * 11 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 : : * GNU General Public License for more details. * 14 : : * * 15 : : * You should have received a copy of the GNU General Public License* 16 : : * along with this program; if not, contact: * 17 : : * * 18 : : * Free Software Foundation Voice: +1-617-542-5942 * 19 : : * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 * 20 : : * Boston, MA 02110-1301, USA gnu@gnu.org * 21 : : \********************************************************************/ 22 : : #include <glib.h> 23 : : #include <clocale> 24 : : #include <boost/locale.hpp> 25 : : #include "gnc-locale-utils.hpp" 26 : : #include <config.h> 27 : : 28 : : /** Cache the UI locale 29 : : * 30 : : * We don't want to set the default locale because we need 31 : : * std::locale::classic for consistency in stored data. We also don't 32 : : * want to call std::locale("") more than once, it's slow... and we 33 : : * don't want to call it on MinGW32 at all because that supports only 34 : : * std::locale::classic and throws if you try to construct anything 35 : : * else. Boost::locale doesn't support std::locale::facet required by 36 : : * boost::datetime (go figure). 37 : : * 38 : : * @return a copy of std::locale::classic() on MinGW32 and a copy of 39 : : * the cached result of std::locale("") otherwise. 40 : : */ 41 : : const std::locale& 42 : 11834 : gnc_get_locale() 43 : : { 44 : : #ifdef __MINGW32__ 45 : : return std::locale::classic(); // Nothing else supported. 46 : : #else 47 : 11834 : static std::locale cached; 48 : : static bool tried_already = false; 49 : 11834 : if (!tried_already) 50 : : { 51 : 26 : tried_already = true; 52 : : try 53 : : { 54 : 26 : cached = std::locale(""); 55 : : } 56 : 0 : catch (const std::runtime_error& err) 57 : : { 58 : 0 : char* locale = g_strdup(setlocale(LC_ALL, "")); 59 : : 60 : 0 : g_log(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, 61 : : "Failed to create C++ default locale from " 62 : : "%s because %s. Using the 'C' locale for C++.", 63 : 0 : locale, err.what()); 64 : 0 : g_free(locale); 65 : 0 : cached = std::locale::classic(); 66 : 0 : } 67 : : } 68 : 11834 : return cached; 69 : : #endif 70 : : } 71 : : 72 : : 73 : : static std::locale boost_cached; 74 : : static bool tried_boost_already = false; 75 : : 76 : : void 77 : 0 : gnc_init_boost_locale (const std::string& messages_path) 78 : : { 79 : 0 : if (!tried_boost_already) 80 : : { 81 : 0 : tried_boost_already = true; 82 : : 83 : : try 84 : : { 85 : 0 : boost::locale::generator gen; 86 : 0 : if (!messages_path.empty()) 87 : 0 : gen.add_messages_path(messages_path); 88 : : else 89 : 0 : g_log(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, 90 : : "Attempt to initialize boost_locale without a message_path. " 91 : : "If message catalogs are not installed in the system's default locations " 92 : : "user interface strings will not be translated."); 93 : 0 : gen.add_messages_domain(PROJECT_NAME); 94 : 0 : boost_cached = gen (""); 95 : 0 : } 96 : 0 : catch (const std::runtime_error& err) 97 : : { 98 : 0 : char* locale = g_strdup(setlocale(LC_ALL, "")); 99 : : 100 : 0 : g_log(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, 101 : : "Failed to create C++ default locale from" 102 : : "%s because %s. Using the 'C' locale for C++.", 103 : 0 : locale, err.what()); 104 : 0 : boost_cached = std::locale::classic(); 105 : 0 : } 106 : : } 107 : 0 : } 108 : : 109 : : 110 : : 111 : : const std::locale& 112 : 3 : gnc_get_boost_locale() 113 : : { 114 : 3 : return boost_cached; 115 : : } 116 : : 117 : :