]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/locale/src/posix/posix_backend.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / locale / src / posix / posix_backend.cpp
1 //
2 // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See
5 // accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7 //
8 #define BOOST_LOCALE_SOURCE
9 #if defined(__FreeBSD__)
10 #include <xlocale.h>
11 #endif
12 #include <boost/locale/localization_backend.hpp>
13 #include <boost/locale/gnu_gettext.hpp>
14 #include <boost/locale/info.hpp>
15 #include "all_generator.hpp"
16 #include "posix_backend.hpp"
17
18 #include "../util/locale_data.hpp"
19 #include "../util/gregorian.hpp"
20 #include <boost/locale/util.hpp>
21 #include <algorithm>
22 #include <iterator>
23
24 #include <langinfo.h>
25
26 namespace boost {
27 namespace locale {
28 namespace impl_posix {
29
30 class posix_localization_backend : public localization_backend {
31 public:
32 posix_localization_backend() :
33 invalid_(true)
34 {
35 }
36 posix_localization_backend(posix_localization_backend const &other) :
37 localization_backend(),
38 paths_(other.paths_),
39 domains_(other.domains_),
40 locale_id_(other.locale_id_),
41 invalid_(true)
42 {
43 }
44 virtual posix_localization_backend *clone() const
45 {
46 return new posix_localization_backend(*this);
47 }
48
49 void set_option(std::string const &name,std::string const &value)
50 {
51 invalid_ = true;
52 if(name=="locale")
53 locale_id_ = value;
54 else if(name=="message_path")
55 paths_.push_back(value);
56 else if(name=="message_application")
57 domains_.push_back(value);
58
59 }
60 void clear_options()
61 {
62 invalid_ = true;
63 locale_id_.clear();
64 paths_.clear();
65 domains_.clear();
66 }
67
68 static void free_locale_by_ptr(locale_t *lc)
69 {
70 freelocale(*lc);
71 delete lc;
72 }
73
74 void prepare_data()
75 {
76 if(!invalid_)
77 return;
78 invalid_ = false;
79 lc_.reset();
80 real_id_ = locale_id_;
81 if(real_id_.empty())
82 real_id_ = util::get_system_locale();
83
84 locale_t tmp = newlocale(LC_ALL_MASK,real_id_.c_str(),0);
85
86 if(!tmp) {
87 tmp=newlocale(LC_ALL_MASK,"C",0);
88 }
89 if(!tmp) {
90 throw std::runtime_error("newlocale failed");
91 }
92
93 locale_t *tmp_p = 0;
94
95 try {
96 tmp_p = new locale_t();
97 }
98 catch(...) {
99 freelocale(tmp);
100 throw;
101 }
102
103 *tmp_p = tmp;
104 lc_ = boost::shared_ptr<locale_t>(tmp_p,free_locale_by_ptr);
105 }
106
107 virtual std::locale install(std::locale const &base,
108 locale_category_type category,
109 character_facet_type type = nochar_facet)
110 {
111 prepare_data();
112
113 switch(category) {
114 case convert_facet:
115 return create_convert(base,lc_,type);
116 case collation_facet:
117 return create_collate(base,lc_,type);
118 case formatting_facet:
119 return create_formatting(base,lc_,type);
120 case parsing_facet:
121 return create_parsing(base,lc_,type);
122 case codepage_facet:
123 return create_codecvt(base,nl_langinfo_l(CODESET,*lc_),type);
124 case calendar_facet:
125 {
126 util::locale_data inf;
127 inf.parse(real_id_);
128 return util::install_gregorian_calendar(base,inf.country);
129 }
130 case message_facet:
131 {
132 gnu_gettext::messages_info minf;
133 util::locale_data inf;
134 inf.parse(real_id_);
135 minf.language = inf.language;
136 minf.country = inf.country;
137 minf.variant = inf.variant;
138 minf.encoding = inf.encoding;
139 std::copy(domains_.begin(),domains_.end(),std::back_inserter<gnu_gettext::messages_info::domains_type>(minf.domains));
140 minf.paths = paths_;
141 switch(type) {
142 case char_facet:
143 return std::locale(base,gnu_gettext::create_messages_facet<char>(minf));
144 case wchar_t_facet:
145 return std::locale(base,gnu_gettext::create_messages_facet<wchar_t>(minf));
146 #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
147 case char16_t_facet:
148 return std::locale(base,gnu_gettext::create_messages_facet<char16_t>(minf));
149 #endif
150 #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
151 case char32_t_facet:
152 return std::locale(base,gnu_gettext::create_messages_facet<char32_t>(minf));
153 #endif
154 default:
155 return base;
156 }
157 }
158 case information_facet:
159 return util::create_info(base,real_id_);
160 default:
161 return base;
162 }
163 }
164
165 private:
166
167 std::vector<std::string> paths_;
168 std::vector<std::string> domains_;
169 std::string locale_id_;
170 std::string real_id_;
171
172 bool invalid_;
173 boost::shared_ptr<locale_t> lc_;
174 };
175
176 localization_backend *create_localization_backend()
177 {
178 return new posix_localization_backend();
179 }
180
181 } // impl posix
182 } // locale
183 } // boost
184 // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4