1//
2// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
3//
4// Distributed under the Boost Software License, Version 1.0.
5// https://www.boost.org/LICENSE_1_0.txt
6
7#ifndef BOOST_LOCLAE_GNU_GETTEXT_HPP
8#define BOOST_LOCLAE_GNU_GETTEXT_HPP
9
10#include <boost/locale/detail/is_supported_char.hpp>
11#include <boost/locale/message.hpp>
12#include <functional>
13#include <stdexcept>
14#include <type_traits>
15#include <vector>
16
17#ifdef BOOST_MSVC
18# pragma warning(push)
19# pragma warning(disable : 4251) // "identifier" : class "type" needs to have dll-interface...
20#endif
21
22namespace boost { namespace locale {
23 /// \addtogroup message
24 /// @{
25
26 /// \brief This namespace holds classes that provide GNU Gettext message catalogs support.
27 namespace gnu_gettext {
28
29 /// \brief This structure holds all information required for creating gnu-gettext message catalogs,
30 ///
31 /// The user is expected to set its parameters to load these catalogs correctly. This structure
32 /// also allows providing functions for charset conversion. Note, you need to provide them,
33 /// so this structure is not useful for wide characters without subclassing and it will also
34 /// ignore gettext catalogs that use a charset different from \a encoding.
35 struct BOOST_LOCALE_DECL messages_info {
36 messages_info() : language("C"), locale_category("LC_MESSAGES") {}
37
38 std::string language; ///< The language we load the catalog for, like "ru", "en", "de"
39 std::string country; ///< The country we load the catalog for, like "US", "IL"
40 std::string variant; ///< Language variant, like "euro" so it would look for catalog like de_DE\@euro
41 std::string encoding; ///< Required target charset encoding. Ignored for wide characters.
42 ///< For narrow, should specify the correct encoding required for this catalog
43 std::string locale_category; ///< Locale category, is set by default to LC_MESSAGES, but may be changed
44 ///
45 /// \brief This type represents GNU Gettext domain name for the messages.
46 ///
47 /// It consists of two parameters:
48 ///
49 /// - name - the name of the domain - used for opening the file name
50 /// - encoding - the encoding of the keys in the sources, default - UTF-8
51 ///
52 struct domain {
53 std::string name; ///< The name of the domain
54 std::string encoding; ///< The character encoding for the domain
55 domain() = default;
56
57 /// Create a domain object from the name that can hold an encoding after symbol "/"
58 /// such that if n is "hello/cp1255" then the name would be "hello" and "encoding" would
59 /// be "cp1255" and if n is "hello" then the name would be the same but encoding would be
60 /// "UTF-8"
61 domain(const std::string& n)
62 {
63 const size_t pos = n.find(c: '/');
64 if(pos == std::string::npos) {
65 name = n;
66 encoding = "UTF-8";
67 } else {
68 name = n.substr(pos: 0, n: pos);
69 encoding = n.substr(pos: pos + 1);
70 }
71 }
72
73 /// Check whether two objects are equivalent, only names are compared, encoding is ignored
74 bool operator==(const domain& other) const { return name == other.name; }
75 /// Check whether two objects are distinct, only names are compared, encoding is ignored
76 bool operator!=(const domain& other) const { return !(*this == other); }
77 };
78
79 typedef std::vector<domain> domains_type; ///< Type that defines a list of domains that are loaded
80 ///< The first one is the default one
81 domains_type domains; ///< Message domains - application name, like my_app. So files named my_app.mo
82 ///< would be loaded
83 std::vector<std::string> paths; ///< Paths to search files in. Under MS Windows it uses encoding
84 ///< parameter to convert them to wide OS specific paths.
85
86 /// The callback for custom file system support. This callback should read the file named \a file_name
87 /// encoded in \a encoding character set into std::vector<char> and return it.
88 ///
89 /// - If the file does not exist, it should return an empty vector.
90 /// - If an error occurs during file read it should throw an exception.
91 ///
92 /// \note The user should support only the encodings the locales are created for. So if the user
93 /// uses only one encoding or the file system is encoding agnostic, he may ignore the \a encoding parameter.
94 typedef std::function<std::vector<char>(const std::string& file_name, const std::string& encoding)>
95 callback_type;
96
97 /// The callback for handling custom file systems, if it is empty, the real OS file-system
98 /// is being used.
99 callback_type callback;
100
101 /// Get paths to folders which may contain catalog files
102 std::vector<std::string> get_catalog_paths() const;
103
104 private:
105 /// Get a list of folder names for the language, country and variant
106 std::vector<std::string> get_lang_folders() const;
107 };
108
109 /// Create a message_format facet using GNU Gettext catalogs. It uses \a info structure to get
110 /// information about where to read them from and uses it for character set conversion (if needed)
111 template<typename CharType, class = boost::locale::detail::enable_if_is_supported_char<CharType>>
112 BOOST_LOCALE_DECL message_format<CharType>* create_messages_facet(const messages_info& info);
113
114 } // namespace gnu_gettext
115
116 /// @}
117
118}} // namespace boost::locale
119
120#ifdef BOOST_MSVC
121# pragma warning(pop)
122#endif
123
124#endif
125

source code of boost/libs/locale/include/boost/locale/gnu_gettext.hpp