include/boost/regex/v5/cpp_regex_traits.hpp

61.7% Lines (211/342) 88.9% List of functions (72/81)
cpp_regex_traits.hpp
f(x) Functions (81)
Function Calls Lines Blocks
boost::re_detail_600::parser_buf<char, std::char_traits<char> >::parser_buf() :73 221186x 100.0% 100.0% boost::re_detail_600::parser_buf<wchar_t, std::char_traits<wchar_t> >::parser_buf() :73 28490x 100.0% 100.0% boost::re_detail_600::parser_buf<char, std::char_traits<char> >::setbuf(char*, long) :86 442372x 100.0% 100.0% boost::re_detail_600::parser_buf<wchar_t, std::char_traits<wchar_t> >::setbuf(wchar_t*, long) :86 56980x 100.0% 100.0% boost::re_detail_600::parser_buf<char, std::char_traits<char> >::seekoff(long, std::_Ios_Seekdir, std::_Ios_Openmode) :94 0 0.0% 0.0% boost::re_detail_600::parser_buf<wchar_t, std::char_traits<wchar_t> >::seekoff(long, std::_Ios_Seekdir, std::_Ios_Openmode) :94 0 0.0% 0.0% boost::re_detail_600::parser_buf<char, std::char_traits<char> >::seekpos(std::fpos<__mbstate_t>, std::_Ios_Openmode) :138 0 0.0% 0.0% boost::re_detail_600::parser_buf<wchar_t, std::char_traits<wchar_t> >::seekpos(std::fpos<__mbstate_t>, std::_Ios_Openmode) :138 0 0.0% 0.0% boost::re_detail_600::cpp_regex_traits_base<char>::cpp_regex_traits_base(std::locale const&) :158 28745x 100.0% 100.0% boost::re_detail_600::cpp_regex_traits_base<wchar_t>::cpp_regex_traits_base(std::locale const&) :158 28787x 100.0% 100.0% boost::re_detail_600::cpp_regex_traits_base<char>::operator<(boost::re_detail_600::cpp_regex_traits_base<char> const&) const :167 57706x 66.7% 67.0% boost::re_detail_600::cpp_regex_traits_base<wchar_t>::operator<(boost::re_detail_600::cpp_regex_traits_base<wchar_t> const&) const :167 57622x 66.7% 67.0% boost::re_detail_600::cpp_regex_traits_base<char>::operator==(boost::re_detail_600::cpp_regex_traits_base<char> const&) const :179 36x 100.0% 86.0% boost::re_detail_600::cpp_regex_traits_base<wchar_t>::operator==(boost::re_detail_600::cpp_regex_traits_base<wchar_t> const&) const :179 8x 100.0% 86.0% boost::re_detail_600::cpp_regex_traits_base<char>::imbue(std::locale const&) :188 28745x 87.5% 90.0% boost::re_detail_600::cpp_regex_traits_base<wchar_t>::imbue(std::locale const&) :188 28787x 87.5% 90.0% boost::re_detail_600::cpp_regex_traits_char_layer<wchar_t>::cpp_regex_traits_char_layer(boost::re_detail_600::cpp_regex_traits_base<wchar_t> const&) :214 8x 100.0% 100.0% boost::re_detail_600::cpp_regex_traits_char_layer<wchar_t>::syntax_type(wchar_t) const :221 993008x 100.0% 100.0% boost::re_detail_600::cpp_regex_traits_char_layer<wchar_t>::escape_syntax_type(wchar_t) const :226 46770x 100.0% 100.0% boost::re_detail_600::cpp_regex_traits_char_layer<wchar_t>::init() :245 8x 40.7% 38.0% boost::re_detail_600::cpp_regex_traits_char_layer<wchar_t>::get_default_message[abi:cxx11](unsigned char) :310 0 0.0% 0.0% boost::re_detail_600::cpp_regex_traits_char_layer<char>::cpp_regex_traits_char_layer(boost::re_detail_600::cpp_regex_traits_base<char> const&) :335 36x 100.0% 100.0% boost::re_detail_600::cpp_regex_traits_char_layer<char>::syntax_type(char) const :341 3314561x 100.0% 100.0% boost::re_detail_600::cpp_regex_traits_char_layer<char>::escape_syntax_type(char) const :345 693035x 100.0% 100.0% boost::re_detail_600::cpp_regex_traits_implementation<char>::cpp_regex_traits_implementation(boost::re_detail_600::cpp_regex_traits_base<char> const&) :380 36x 100.0% 100.0% boost::re_detail_600::cpp_regex_traits_implementation<wchar_t>::cpp_regex_traits_implementation(boost::re_detail_600::cpp_regex_traits_base<wchar_t> const&) :380 8x 100.0% 100.0% boost::re_detail_600::cpp_regex_traits_implementation<char>::error_string[abi:cxx11](boost::regex_constants::error_type) const :385 4619x 60.0% 39.0% boost::re_detail_600::cpp_regex_traits_implementation<wchar_t>::error_string[abi:cxx11](boost::regex_constants::error_type) const :385 4596x 60.0% 39.0% boost::re_detail_600::cpp_regex_traits_implementation<char>::lookup_classname(char const*, char const*) const :394 290842x 100.0% 100.0% boost::re_detail_600::cpp_regex_traits_implementation<wchar_t>::lookup_classname(wchar_t const*, wchar_t const*) const :394 291661x 100.0% 100.0% boost::re_detail_600::cpp_regex_traits_implementation<char>::transform_primary[abi:cxx11](char const*, char const*) const :434 31229x 51.9% 69.0% boost::re_detail_600::cpp_regex_traits_implementation<wchar_t>::transform_primary[abi:cxx11](wchar_t const*, wchar_t const*) const :434 31709x 51.9% 69.0% boost::re_detail_600::cpp_regex_traits_implementation<char>::transform[abi:cxx11](char const*, char const*) const :514 137540x 93.3% 95.0% boost::re_detail_600::cpp_regex_traits_implementation<wchar_t>::transform[abi:cxx11](wchar_t const*, wchar_t const*) const :514 129140x 86.7% 89.0% boost::re_detail_600::cpp_regex_traits_implementation<char>::lookup_collatename[abi:cxx11](char const*, char const*) const :585 3168x 76.9% 68.0% boost::re_detail_600::cpp_regex_traits_implementation<wchar_t>::lookup_collatename[abi:cxx11](wchar_t const*, wchar_t const*) const :585 3168x 76.9% 68.0% boost::re_detail_600::cpp_regex_traits_implementation<char>::init() :604 36x 21.9% 15.0% boost::re_detail_600::cpp_regex_traits_implementation<wchar_t>::init() :604 8x 21.9% 15.0% boost::re_detail_600::cpp_regex_traits_implementation<char>::lookup_classname_imp(char const*, char const*) const :689 292419x 62.5% 30.0% boost::re_detail_600::cpp_regex_traits_implementation<wchar_t>::lookup_classname_imp(wchar_t const*, wchar_t const*) const :689 293228x 62.5% 30.0% std::shared_ptr<boost::re_detail_600::cpp_regex_traits_implementation<char> const> boost::re_detail_600::create_cpp_regex_traits<char>(std::locale const&) :729 28745x 100.0% 100.0% std::shared_ptr<boost::re_detail_600::cpp_regex_traits_implementation<wchar_t> const> boost::re_detail_600::create_cpp_regex_traits<wchar_t>(std::locale const&) :729 28787x 100.0% 100.0% boost::cpp_regex_traits<char>::cpp_regex_traits() :751 28745x 100.0% 100.0% boost::cpp_regex_traits<wchar_t>::cpp_regex_traits() :751 28787x 100.0% 100.0% boost::cpp_regex_traits<char>::length(char const*) :754 526x 100.0% 100.0% boost::cpp_regex_traits<wchar_t>::length(wchar_t const*) :754 578x 100.0% 100.0% boost::cpp_regex_traits<char>::syntax_type(char) const :758 3314561x 100.0% 100.0% boost::cpp_regex_traits<wchar_t>::syntax_type(wchar_t) const :758 993008x 100.0% 100.0% boost::cpp_regex_traits<char>::escape_syntax_type(char) const :762 693035x 100.0% 100.0% boost::cpp_regex_traits<wchar_t>::escape_syntax_type(wchar_t) const :762 46770x 100.0% 100.0% boost::cpp_regex_traits<char>::translate(char, bool) const :774 329623837x 100.0% 100.0% boost::cpp_regex_traits<wchar_t>::translate(wchar_t, bool) const :774 33704576x 100.0% 100.0% boost::cpp_regex_traits<char>::tolower(char) const :778 180x 100.0% 100.0% boost::cpp_regex_traits<wchar_t>::tolower(wchar_t) const :778 180x 100.0% 100.0% boost::cpp_regex_traits<char>::toupper(char) const :782 132x 100.0% 100.0% boost::cpp_regex_traits<wchar_t>::toupper(wchar_t) const :782 132x 100.0% 100.0% boost::cpp_regex_traits<char>::transform[abi:cxx11](char const*, char const*) const :786 137432x 100.0% 100.0% boost::cpp_regex_traits<wchar_t>::transform[abi:cxx11](wchar_t const*, wchar_t const*) const :786 129116x 100.0% 100.0% boost::cpp_regex_traits<char>::transform_primary[abi:cxx11](char const*, char const*) const :790 31229x 100.0% 100.0% boost::cpp_regex_traits<wchar_t>::transform_primary[abi:cxx11](wchar_t const*, wchar_t const*) const :790 31709x 100.0% 100.0% boost::cpp_regex_traits<char>::lookup_classname(char const*, char const*) const :794 290842x 100.0% 100.0% boost::cpp_regex_traits<wchar_t>::lookup_classname(wchar_t const*, wchar_t const*) const :794 291661x 100.0% 100.0% boost::cpp_regex_traits<char>::lookup_collatename[abi:cxx11](char const*, char const*) const :798 3168x 100.0% 100.0% boost::cpp_regex_traits<wchar_t>::lookup_collatename[abi:cxx11](wchar_t const*, wchar_t const*) const :798 3168x 100.0% 100.0% boost::cpp_regex_traits<char>::isctype(char, unsigned int) const :802 4436610x 95.0% 91.0% boost::cpp_regex_traits<wchar_t>::isctype(wchar_t, unsigned int) const :802 6184820x 100.0% 100.0% boost::cpp_regex_traits<char>::imbue(std::locale) :858 0 0.0% 0.0% boost::cpp_regex_traits<wchar_t>::imbue(std::locale) :858 0 0.0% 0.0% boost::cpp_regex_traits<char>::getloc() const :864 0 0.0% 0.0% boost::cpp_regex_traits<wchar_t>::getloc() const :864 0 0.0% 0.0% boost::cpp_regex_traits<char>::error_string[abi:cxx11](boost::regex_constants::error_type) const :868 4619x 100.0% 100.0% boost::cpp_regex_traits<wchar_t>::error_string[abi:cxx11](boost::regex_constants::error_type) const :868 4596x 100.0% 100.0% boost::cpp_regex_traits<char>::toi(char const*&, char const*, int) const :894 221186x 100.0% 100.0% boost::cpp_regex_traits<wchar_t>::toi(wchar_t const*&, wchar_t const*, int) const :894 28490x 100.0% 100.0% boost::cpp_regex_traits<char>::get_catalog_name_inst[abi:cxx11]() :929 72x 100.0% 100.0% boost::cpp_regex_traits<wchar_t>::get_catalog_name_inst[abi:cxx11]() :929 16x 100.0% 100.0% boost::cpp_regex_traits<char>::get_catalog_name[abi:cxx11]() :936 72x 100.0% 100.0% boost::cpp_regex_traits<wchar_t>::get_catalog_name[abi:cxx11]() :936 16x 100.0% 100.0% boost::cpp_regex_traits<char>::get_mutex_inst() :947 72x 100.0% 100.0% boost::cpp_regex_traits<wchar_t>::get_mutex_inst() :947 16x 100.0% 100.0% boost::re_detail_600::cpp_regex_traits_char_layer<char>::init() :956 36x 52.8% 44.0%
Line TLA Hits Source Code
1 /*
2 *
3 * Copyright (c) 2004 John Maddock
4 * Copyright 2011 Garmin Ltd. or its subsidiaries
5 *
6 * Use, modification and distribution are subject to the
7 * Boost Software License, Version 1.0. (See accompanying file
8 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 *
10 */
11
12 /*
13 * LOCATION: see http://www.boost.org for most recent version.
14 * FILE cpp_regex_traits.hpp
15 * VERSION see <boost/version.hpp>
16 * DESCRIPTION: Declares regular expression traits class cpp_regex_traits.
17 */
18
19 #ifndef BOOST_CPP_REGEX_TRAITS_HPP_INCLUDED
20 #define BOOST_CPP_REGEX_TRAITS_HPP_INCLUDED
21
22 #include <boost/regex/config.hpp>
23
24 #ifndef BOOST_REGEX_AS_MODULE
25 #include <cstdint>
26 #include <locale>
27 #include <type_traits>
28 #include <climits>
29 #include <ios>
30 #include <istream>
31 #ifdef BOOST_HAS_THREADS
32 #include <mutex>
33 #endif
34 #endif
35
36 #include <boost/regex/pattern_except.hpp>
37 #include <boost/regex/v5/regex_traits_defaults.hpp>
38
39 #include <boost/regex/v5/primary_transform.hpp>
40 #include <boost/regex/v5/object_cache.hpp>
41
42
43 #ifdef BOOST_REGEX_MSVC
44 #pragma warning(push)
45 #pragma warning(disable:4786 4251)
46 #endif
47
48 namespace boost{
49
50 //
51 // forward declaration is needed by some compilers:
52 //
53 BOOST_REGEX_MODULE_EXPORT template <class charT>
54 class cpp_regex_traits;
55
56 namespace BOOST_REGEX_DETAIL_NS{
57
58 //
59 // class parser_buf:
60 // acts as a stream buffer which wraps around a pair of pointers:
61 //
62 template <class charT,
63 class traits = ::std::char_traits<charT> >
64 class parser_buf : public ::std::basic_streambuf<charT, traits>
65 {
66 typedef ::std::basic_streambuf<charT, traits> base_type;
67 typedef typename base_type::int_type int_type;
68 typedef typename base_type::char_type char_type;
69 typedef typename base_type::pos_type pos_type;
70 typedef ::std::streamsize streamsize;
71 typedef typename base_type::off_type off_type;
72 public:
73 249676x parser_buf() : base_type() { setbuf(0, 0); }
74 const charT* getnext() { return this->gptr(); }
75 protected:
76 std::basic_streambuf<charT, traits>* setbuf(char_type* s, streamsize n) override;
77 typename parser_buf<charT, traits>::pos_type seekpos(pos_type sp, ::std::ios_base::openmode which) override;
78 typename parser_buf<charT, traits>::pos_type seekoff(off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which) override;
79 private:
80 parser_buf& operator=(const parser_buf&);
81 parser_buf(const parser_buf&);
82 };
83
84 template<class charT, class traits>
85 std::basic_streambuf<charT, traits>*
86 499352x parser_buf<charT, traits>::setbuf(char_type* s, streamsize n)
87 {
88 499352x this->setg(s, s, s + n);
89 499352x return this;
90 }
91
92 template<class charT, class traits>
93 typename parser_buf<charT, traits>::pos_type
94 parser_buf<charT, traits>::seekoff(off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which)
95 {
96 if(which & ::std::ios_base::out)
97 return pos_type(off_type(-1));
98 std::ptrdiff_t size = this->egptr() - this->eback();
99 std::ptrdiff_t pos = this->gptr() - this->eback();
100 charT* g = this->eback();
101 switch(static_cast<std::intmax_t>(way))
102 {
103 case ::std::ios_base::beg:
104 if((off < 0) || (off > size))
105 return pos_type(off_type(-1));
106 else
107 this->setg(g, g + off, g + size);
108 break;
109 case ::std::ios_base::end:
110 if((off < 0) || (off > size))
111 return pos_type(off_type(-1));
112 else
113 this->setg(g, g + size - off, g + size);
114 break;
115 case ::std::ios_base::cur:
116 {
117 std::ptrdiff_t newpos = static_cast<std::ptrdiff_t>(pos + off);
118 if((newpos < 0) || (newpos > size))
119 return pos_type(off_type(-1));
120 else
121 this->setg(g, g + newpos, g + size);
122 break;
123 }
124 default: ;
125 }
126 #ifdef BOOST_REGEX_MSVC
127 #pragma warning(push)
128 #pragma warning(disable:4244)
129 #endif
130 return static_cast<pos_type>(this->gptr() - this->eback());
131 #ifdef BOOST_REGEX_MSVC
132 #pragma warning(pop)
133 #endif
134 }
135
136 template<class charT, class traits>
137 typename parser_buf<charT, traits>::pos_type
138 parser_buf<charT, traits>::seekpos(pos_type sp, ::std::ios_base::openmode which)
139 {
140 if(which & ::std::ios_base::out)
141 return pos_type(off_type(-1));
142 off_type size = static_cast<off_type>(this->egptr() - this->eback());
143 charT* g = this->eback();
144 if(off_type(sp) <= size)
145 {
146 this->setg(g, g + off_type(sp), g + size);
147 }
148 return pos_type(off_type(-1));
149 }
150
151 //
152 // class cpp_regex_traits_base:
153 // acts as a container for locale and the facets we are using.
154 //
155 template <class charT>
156 struct cpp_regex_traits_base
157 {
158 57532x cpp_regex_traits_base(const std::locale& l)
159 57532x { (void)imbue(l); }
160 std::locale imbue(const std::locale& l);
161
162 std::locale m_locale;
163 std::ctype<charT> const* m_pctype;
164 std::messages<charT> const* m_pmessages;
165 std::collate<charT> const* m_pcollate;
166
167 115328x bool operator<(const cpp_regex_traits_base& b)const
168 {
169 115328x if(m_pctype == b.m_pctype)
170 {
171 115328x if(m_pmessages == b.m_pmessages)
172 {
173 115328x return m_pcollate < b.m_pcollate;
174 }
175 return m_pmessages < b.m_pmessages;
176 }
177 return m_pctype < b.m_pctype;
178 }
179 44x bool operator==(const cpp_regex_traits_base& b)const
180 {
181 44x return (m_pctype == b.m_pctype)
182 44x && (m_pmessages == b.m_pmessages)
183 88x && (m_pcollate == b.m_pcollate);
184 }
185 };
186
187 template <class charT>
188 57532x std::locale cpp_regex_traits_base<charT>::imbue(const std::locale& l)
189 {
190 57532x std::locale result(m_locale);
191 57532x m_locale = l;
192 57532x m_pctype = &std::use_facet<std::ctype<charT>>(l);
193 57532x m_pmessages = std::has_facet<std::messages<charT> >(l) ? &std::use_facet<std::messages<charT> >(l) : 0;
194 57532x m_pcollate = &std::use_facet<std::collate<charT> >(l);
195 57532x return result;
196 }
197
198 //
199 // class cpp_regex_traits_char_layer:
200 // implements methods that require specialization for narrow characters:
201 //
202 template <class charT>
203 class cpp_regex_traits_char_layer : public cpp_regex_traits_base<charT>
204 {
205 typedef std::basic_string<charT> string_type;
206 typedef std::map<charT, regex_constants::syntax_type> map_type;
207 typedef typename map_type::const_iterator map_iterator_type;
208 public:
209 cpp_regex_traits_char_layer(const std::locale& l)
210 : cpp_regex_traits_base<charT>(l)
211 {
212 init();
213 }
214 8x cpp_regex_traits_char_layer(const cpp_regex_traits_base<charT>& b)
215 8x : cpp_regex_traits_base<charT>(b)
216 {
217 8x init();
218 8x }
219 void init();
220
221 993008x regex_constants::syntax_type syntax_type(charT c)const
222 {
223 993008x map_iterator_type i = m_char_map.find(c);
224 993008x return ((i == m_char_map.end()) ? 0 : i->second);
225 }
226 46770x regex_constants::escape_syntax_type escape_syntax_type(charT c) const
227 {
228 46770x map_iterator_type i = m_char_map.find(c);
229 46770x if(i == m_char_map.end())
230 {
231 10192x if(this->m_pctype->is(std::ctype_base::lower, c)) return regex_constants::escape_type_class;
232 1663x if(this->m_pctype->is(std::ctype_base::upper, c)) return regex_constants::escape_type_not_class;
233 312x return 0;
234 }
235 36578x return i->second;
236 }
237
238 private:
239 string_type get_default_message(regex_constants::syntax_type);
240 // TODO: use a hash table when available!
241 map_type m_char_map;
242 };
243
244 template <class charT>
245 8x void cpp_regex_traits_char_layer<charT>::init()
246 {
247 // we need to start by initialising our syntax map so we know which
248 // character is used for which purpose:
249 #ifndef __IBMCPP__
250 8x typename std::messages<charT>::catalog cat = static_cast<std::messages<char>::catalog>(-1);
251 #else
252 typename std::messages<charT>::catalog cat = reinterpret_cast<std::messages<char>::catalog>(-1);
253 #endif
254 8x std::string cat_name(cpp_regex_traits<charT>::get_catalog_name());
255 8x if((!cat_name.empty()) && (this->m_pmessages != 0))
256 {
257 cat = this->m_pmessages->open(
258 cat_name,
259 this->m_locale);
260 if((int)cat < 0)
261 {
262 std::string m("Unable to open message catalog: ");
263 std::runtime_error err(m + cat_name);
264 boost::BOOST_REGEX_DETAIL_NS::raise_runtime_error(err);
265 }
266 }
267 //
268 // if we have a valid catalog then load our messages:
269 //
270 8x if((int)cat >= 0)
271 {
272 #ifndef BOOST_NO_EXCEPTIONS
273 try{
274 #endif
275 for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
276 {
277 string_type mss = this->m_pmessages->get(cat, 0, i, get_default_message(i));
278 for(typename string_type::size_type j = 0; j < mss.size(); ++j)
279 {
280 m_char_map[mss[j]] = i;
281 }
282 }
283 this->m_pmessages->close(cat);
284 #ifndef BOOST_NO_EXCEPTIONS
285 }
286 catch(...)
287 {
288 if(this->m_pmessages)
289 this->m_pmessages->close(cat);
290 throw;
291 }
292 #endif
293 }
294 else
295 {
296 480x for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
297 {
298 472x const char* ptr = get_default_syntax(i);
299 960x while(ptr && *ptr)
300 {
301 488x m_char_map[this->m_pctype->widen(*ptr)] = i;
302 488x ++ptr;
303 }
304 }
305 }
306 8x }
307
308 template <class charT>
309 typename cpp_regex_traits_char_layer<charT>::string_type
310 cpp_regex_traits_char_layer<charT>::get_default_message(regex_constants::syntax_type i)
311 {
312 const char* ptr = get_default_syntax(i);
313 string_type result;
314 while(ptr && *ptr)
315 {
316 result.append(1, this->m_pctype->widen(*ptr));
317 ++ptr;
318 }
319 return result;
320 }
321
322 //
323 // specialized version for narrow characters:
324 //
325 template <>
326 class cpp_regex_traits_char_layer<char> : public cpp_regex_traits_base<char>
327 {
328 typedef std::string string_type;
329 public:
330 cpp_regex_traits_char_layer(const std::locale& l)
331 : cpp_regex_traits_base<char>(l)
332 {
333 init();
334 }
335 36x cpp_regex_traits_char_layer(const cpp_regex_traits_base<char>& l)
336 36x : cpp_regex_traits_base<char>(l)
337 {
338 36x init();
339 36x }
340
341 3314561x regex_constants::syntax_type syntax_type(char c)const
342 {
343 3314561x return m_char_map[static_cast<unsigned char>(c)];
344 }
345 693035x regex_constants::escape_syntax_type escape_syntax_type(char c) const
346 {
347 693035x return m_char_map[static_cast<unsigned char>(c)];
348 }
349
350 private:
351 regex_constants::syntax_type m_char_map[1u << CHAR_BIT];
352 void init();
353 };
354
355 //
356 // class cpp_regex_traits_implementation:
357 // provides pimpl implementation for cpp_regex_traits.
358 //
359 template <class charT>
360 class cpp_regex_traits_implementation : public cpp_regex_traits_char_layer<charT>
361 {
362 public:
363 typedef typename cpp_regex_traits<charT>::char_class_type char_class_type;
364 typedef typename std::ctype<charT>::mask native_mask_type;
365 typedef typename std::make_unsigned<native_mask_type>::type unsigned_native_mask_type;
366 static const char_class_type mask_blank = 1u << 24;
367 static const char_class_type mask_word = 1u << 25;
368 static const char_class_type mask_unicode = 1u << 26;
369 static const char_class_type mask_horizontal = 1u << 27;
370 static const char_class_type mask_vertical = 1u << 28;
371
372 typedef std::basic_string<charT> string_type;
373 typedef charT char_type;
374 //cpp_regex_traits_implementation();
375 cpp_regex_traits_implementation(const std::locale& l)
376 : cpp_regex_traits_char_layer<charT>(l)
377 {
378 init();
379 }
380 44x cpp_regex_traits_implementation(const cpp_regex_traits_base<charT>& l)
381 44x : cpp_regex_traits_char_layer<charT>(l)
382 {
383 44x init();
384 44x }
385 9215x std::string error_string(regex_constants::error_type n) const
386 {
387 9215x if(!m_error_strings.empty())
388 {
389 std::map<int, std::string>::const_iterator p = m_error_strings.find(n);
390 return (p == m_error_strings.end()) ? std::string(get_default_error_string(n)) : p->second;
391 }
392 18430x return get_default_error_string(n);
393 }
394 582503x char_class_type lookup_classname(const charT* p1, const charT* p2) const
395 {
396 582503x char_class_type result = lookup_classname_imp(p1, p2);
397 582503x if(result == 0)
398 {
399 3144x string_type temp(p1, p2);
400 3144x this->m_pctype->tolower(&*temp.begin(), &*temp.begin() + temp.size());
401 3144x result = lookup_classname_imp(&*temp.begin(), &*temp.begin() + temp.size());
402 3144x }
403 582503x return result;
404 }
405 string_type lookup_collatename(const charT* p1, const charT* p2) const;
406 string_type transform_primary(const charT* p1, const charT* p2) const;
407 string_type transform(const charT* p1, const charT* p2) const;
408 private:
409 std::map<int, std::string> m_error_strings; // error messages indexed by numberic ID
410 std::map<string_type, char_class_type> m_custom_class_names; // character class names
411 std::map<string_type, string_type> m_custom_collate_names; // collating element names
412 unsigned m_collate_type; // the form of the collation string
413 charT m_collate_delim; // the collation group delimiter
414 //
415 // helpers:
416 //
417 char_class_type lookup_classname_imp(const charT* p1, const charT* p2) const;
418 void init();
419 };
420
421 template <class charT>
422 typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_blank;
423 template <class charT>
424 typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_word;
425 template <class charT>
426 typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_unicode;
427 template <class charT>
428 typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_vertical;
429 template <class charT>
430 typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_horizontal;
431
432 template <class charT>
433 typename cpp_regex_traits_implementation<charT>::string_type
434 62938x cpp_regex_traits_implementation<charT>::transform_primary(const charT* p1, const charT* p2) const
435 {
436 //
437 // PRECONDITIONS:
438 //
439 // A bug in gcc 3.2 (and maybe other versions as well) treats
440 // p1 as a null terminated string, for efficiency reasons
441 // we work around this elsewhere, but just assert here that
442 // we adhere to gcc's (buggy) preconditions...
443 //
444 62938x BOOST_REGEX_ASSERT(*p2 == 0);
445 62938x string_type result;
446 #if defined(_CPPLIB_VER)
447 //
448 // A bug in VC11 and 12 causes the program to hang if we pass a null-string
449 // to std::collate::transform, but only for certain locales :-(
450 // Probably effects Intel and Clang or any compiler using the VC std library (Dinkumware).
451 //
452 if(*p1 == 0)
453 {
454 return string_type(1, charT(0));
455 }
456 #endif
457 //
458 // swallowing all exceptions here is a bad idea
459 // however at least one std lib will always throw
460 // std::bad_alloc for certain arguments...
461 //
462 #ifndef BOOST_NO_EXCEPTIONS
463 try{
464 #endif
465 //
466 // What we do here depends upon the format of the sort key returned by
467 // sort key returned by this->transform:
468 //
469 62938x switch(m_collate_type)
470 {
471 62938x case sort_C:
472 case sort_unknown:
473 // the best we can do is translate to lower case, then get a regular sort key:
474 {
475 62938x result.assign(p1, p2);
476 62938x this->m_pctype->tolower(&*result.begin(), &*result.begin() + result.size());
477 62938x result = this->m_pcollate->transform(&*result.begin(), &*result.begin() + result.size());
478 62938x break;
479 }
480 case sort_fixed:
481 {
482 // get a regular sort key, and then truncate it:
483 result.assign(this->m_pcollate->transform(p1, p2));
484 result.erase(this->m_collate_delim);
485 break;
486 }
487 case sort_delim:
488 // get a regular sort key, and then truncate everything after the delim:
489 result.assign(this->m_pcollate->transform(p1, p2));
490 std::size_t i;
491 for(i = 0; i < result.size(); ++i)
492 {
493 if(result[i] == m_collate_delim)
494 break;
495 }
496 result.erase(i);
497 break;
498 }
499 #ifndef BOOST_NO_EXCEPTIONS
500 }catch(...){}
501 #endif
502 63466x while((!result.empty()) && (charT(0) == *result.rbegin()))
503 528x result.erase(result.size() - 1);
504 62938x if(result.empty())
505 {
506 // character is ignorable at the primary level:
507 1056x result = string_type(1, charT(0));
508 }
509 62938x return result;
510 }
511
512 template <class charT>
513 typename cpp_regex_traits_implementation<charT>::string_type
514 266680x cpp_regex_traits_implementation<charT>::transform(const charT* p1, const charT* p2) const
515 {
516 //
517 // PRECONDITIONS:
518 //
519 // A bug in gcc 3.2 (and maybe other versions as well) treats
520 // p1 as a null terminated string, for efficiency reasons
521 // we work around this elsewhere, but just assert here that
522 // we adhere to gcc's (buggy) preconditions...
523 //
524 266680x BOOST_REGEX_ASSERT(*p2 == 0);
525 //
526 // swallowing all exceptions here is a bad idea
527 // however at least one std lib will always throw
528 // std::bad_alloc for certain arguments...
529 //
530 266680x string_type result, result2;
531 #if defined(_CPPLIB_VER)
532 //
533 // A bug in VC11 and 12 causes the program to hang if we pass a null-string
534 // to std::collate::transform, but only for certain locales :-(
535 // Probably effects Intel and Clang or any compiler using the VC std library (Dinkumware).
536 //
537 if(*p1 == 0)
538 {
539 return result;
540 }
541 #endif
542 #ifndef BOOST_NO_EXCEPTIONS
543 try{
544 #endif
545 266680x result = this->m_pcollate->transform(p1, p2);
546 //
547 // some implementations (Dinkumware) append unnecessary trailing \0's:
548 267976x while((!result.empty()) && (charT(0) == *result.rbegin()))
549 1296x result.erase(result.size() - 1);
550 //
551 // We may have NULL's used as separators between sections of the collate string,
552 // an example would be Boost.Locale. We have no way to detect this case via
553 // #defines since this can be used with any compiler/platform combination.
554 // Unfortunately our state machine (which was devised when all implementations
555 // used underlying C language API's) can't cope with that case. One workaround
556 // is to replace each character with 2, fortunately this code isn't used that
557 // much as this is now slower than before :-(
558 //
559 typedef typename std::make_unsigned<charT>::type uchar_type;
560 266680x result2.reserve(result.size() * 2 + 2);
561 532544x for(unsigned i = 0; i < result.size(); ++i)
562 {
563 265864x if(static_cast<uchar_type>(result[i]) == (std::numeric_limits<uchar_type>::max)())
564 {
565 528x result2.append(1, charT((std::numeric_limits<uchar_type>::max)())).append(1, charT('b'));
566 }
567 else
568 {
569 265336x result2.append(1, static_cast<charT>(1 + static_cast<uchar_type>(result[i]))).append(1, charT('b') - 1);
570 }
571 }
572 266680x BOOST_REGEX_ASSERT(std::find(result2.begin(), result2.end(), charT(0)) == result2.end());
573 #ifndef BOOST_NO_EXCEPTIONS
574 }
575 catch(...)
576 {
577 }
578 #endif
579 511143x return result2;
580 266680x }
581
582
583 template <class charT>
584 typename cpp_regex_traits_implementation<charT>::string_type
585 6336x cpp_regex_traits_implementation<charT>::lookup_collatename(const charT* p1, const charT* p2) const
586 {
587 typedef typename std::map<string_type, string_type>::const_iterator iter_type;
588 6336x if(!m_custom_collate_names.empty())
589 {
590 iter_type pos = m_custom_collate_names.find(string_type(p1, p2));
591 if(pos != m_custom_collate_names.end())
592 return pos->second;
593 }
594 6336x std::string name(p1, p2);
595 6336x name = lookup_default_collate_name(name);
596 6336x if(!name.empty())
597 11904x return string_type(name.begin(), name.end());
598 384x if(p2 - p1 == 1)
599 288x return string_type(1, *p1);
600 240x return string_type();
601 6336x }
602
603 template <class charT>
604 44x void cpp_regex_traits_implementation<charT>::init()
605 {
606 #ifndef __IBMCPP__
607 44x typename std::messages<charT>::catalog cat = static_cast<std::messages<char>::catalog>(-1);
608 #else
609 typename std::messages<charT>::catalog cat = reinterpret_cast<std::messages<char>::catalog>(-1);
610 #endif
611 44x std::string cat_name(cpp_regex_traits<charT>::get_catalog_name());
612 44x if((!cat_name.empty()) && (this->m_pmessages != 0))
613 {
614 cat = this->m_pmessages->open(
615 cat_name,
616 this->m_locale);
617 if((int)cat < 0)
618 {
619 std::string m("Unable to open message catalog: ");
620 std::runtime_error err(m + cat_name);
621 boost::BOOST_REGEX_DETAIL_NS::raise_runtime_error(err);
622 }
623 }
624 //
625 // if we have a valid catalog then load our messages:
626 //
627 44x if((int)cat >= 0)
628 {
629 //
630 // Error messages:
631 //
632 for(boost::regex_constants::error_type i = static_cast<boost::regex_constants::error_type>(0);
633 i <= boost::regex_constants::error_unknown;
634 i = static_cast<boost::regex_constants::error_type>(i + 1))
635 {
636 const char* p = get_default_error_string(i);
637 string_type default_message;
638 while(*p)
639 {
640 default_message.append(1, this->m_pctype->widen(*p));
641 ++p;
642 }
643 string_type s = this->m_pmessages->get(cat, 0, i+200, default_message);
644 std::string result;
645 for(std::string::size_type j = 0; j < s.size(); ++j)
646 {
647 result.append(1, this->m_pctype->narrow(s[j], 0));
648 }
649 m_error_strings[i] = result;
650 }
651 //
652 // Custom class names:
653 //
654 static const char_class_type masks[16] =
655 {
656 static_cast<unsigned_native_mask_type>(std::ctype<charT>::alnum),
657 static_cast<unsigned_native_mask_type>(std::ctype<charT>::alpha),
658 static_cast<unsigned_native_mask_type>(std::ctype<charT>::cntrl),
659 static_cast<unsigned_native_mask_type>(std::ctype<charT>::digit),
660 static_cast<unsigned_native_mask_type>(std::ctype<charT>::graph),
661 cpp_regex_traits_implementation<charT>::mask_horizontal,
662 static_cast<unsigned_native_mask_type>(std::ctype<charT>::lower),
663 static_cast<unsigned_native_mask_type>(std::ctype<charT>::print),
664 static_cast<unsigned_native_mask_type>(std::ctype<charT>::punct),
665 static_cast<unsigned_native_mask_type>(std::ctype<charT>::space),
666 static_cast<unsigned_native_mask_type>(std::ctype<charT>::upper),
667 cpp_regex_traits_implementation<charT>::mask_vertical,
668 static_cast<unsigned_native_mask_type>(std::ctype<charT>::xdigit),
669 cpp_regex_traits_implementation<charT>::mask_blank,
670 cpp_regex_traits_implementation<charT>::mask_word,
671 cpp_regex_traits_implementation<charT>::mask_unicode,
672 };
673 static const string_type null_string;
674 for(unsigned int j = 0; j <= 13; ++j)
675 {
676 string_type s(this->m_pmessages->get(cat, 0, j+300, null_string));
677 if(!s.empty())
678 this->m_custom_class_names[s] = masks[j];
679 }
680 }
681 //
682 // get the collation format used by m_pcollate:
683 //
684 44x m_collate_type = BOOST_REGEX_DETAIL_NS::find_sort_syntax(this, &m_collate_delim);
685 44x }
686
687 template <class charT>
688 typename cpp_regex_traits_implementation<charT>::char_class_type
689 585647x cpp_regex_traits_implementation<charT>::lookup_classname_imp(const charT* p1, const charT* p2) const
690 {
691 static const char_class_type masks[22] =
692 {
693 0,
694 static_cast<unsigned_native_mask_type>(std::ctype<char>::alnum),
695 static_cast<unsigned_native_mask_type>(std::ctype<char>::alpha),
696 cpp_regex_traits_implementation<charT>::mask_blank,
697 static_cast<unsigned_native_mask_type>(std::ctype<char>::cntrl),
698 static_cast<unsigned_native_mask_type>(std::ctype<char>::digit),
699 static_cast<unsigned_native_mask_type>(std::ctype<char>::digit),
700 static_cast<unsigned_native_mask_type>(std::ctype<char>::graph),
701 cpp_regex_traits_implementation<charT>::mask_horizontal,
702 static_cast<unsigned_native_mask_type>(std::ctype<char>::lower),
703 static_cast<unsigned_native_mask_type>(std::ctype<char>::lower),
704 static_cast<unsigned_native_mask_type>(std::ctype<char>::print),
705 static_cast<unsigned_native_mask_type>(std::ctype<char>::punct),
706 static_cast<unsigned_native_mask_type>(std::ctype<char>::space),
707 static_cast<unsigned_native_mask_type>(std::ctype<char>::space),
708 static_cast<unsigned_native_mask_type>(std::ctype<char>::upper),
709 cpp_regex_traits_implementation<charT>::mask_unicode,
710 static_cast<unsigned_native_mask_type>(std::ctype<char>::upper),
711 cpp_regex_traits_implementation<charT>::mask_vertical,
712 static_cast<unsigned_native_mask_type>(std::ctype<char>::alnum) | cpp_regex_traits_implementation<charT>::mask_word,
713 static_cast<unsigned_native_mask_type>(std::ctype<char>::alnum) | cpp_regex_traits_implementation<charT>::mask_word,
714 static_cast<unsigned_native_mask_type>(std::ctype<char>::xdigit),
715 };
716 585647x if(!m_custom_class_names.empty())
717 {
718 typedef typename std::map<std::basic_string<charT>, char_class_type>::const_iterator map_iter;
719 map_iter pos = m_custom_class_names.find(string_type(p1, p2));
720 if(pos != m_custom_class_names.end())
721 return pos->second;
722 }
723 585647x std::size_t state_id = 1 + BOOST_REGEX_DETAIL_NS::get_default_class_id(p1, p2);
724 585647x BOOST_REGEX_ASSERT(state_id < sizeof(masks) / sizeof(masks[0]));
725 585647x return masks[state_id];
726 }
727
728 template <class charT>
729 57532x inline std::shared_ptr<const cpp_regex_traits_implementation<charT> > create_cpp_regex_traits(const std::locale& l)
730 {
731 57532x cpp_regex_traits_base<charT> key(l);
732 110276x return ::boost::object_cache<cpp_regex_traits_base<charT>, cpp_regex_traits_implementation<charT> >::get(key, 5);
733 57532x }
734
735 } // BOOST_REGEX_DETAIL_NS
736
737 BOOST_REGEX_MODULE_EXPORT template <class charT>
738 class cpp_regex_traits
739 {
740 private:
741 typedef std::ctype<charT> ctype_type;
742 public:
743 typedef charT char_type;
744 typedef std::size_t size_type;
745 typedef std::basic_string<char_type> string_type;
746 typedef std::locale locale_type;
747 typedef std::uint_least32_t char_class_type;
748
749 struct boost_extensions_tag{};
750
751 57532x cpp_regex_traits()
752 57532x : m_pimpl(BOOST_REGEX_DETAIL_NS::create_cpp_regex_traits<charT>(std::locale()))
753 57532x { }
754 1104x static size_type length(const char_type* p)
755 {
756 1104x return std::char_traits<charT>::length(p);
757 }
758 4307569x regex_constants::syntax_type syntax_type(charT c)const
759 {
760 4307569x return m_pimpl->syntax_type(c);
761 }
762 739805x regex_constants::escape_syntax_type escape_syntax_type(charT c) const
763 {
764 739805x return m_pimpl->escape_syntax_type(c);
765 }
766 charT translate(charT c) const
767 {
768 return c;
769 }
770 charT translate_nocase(charT c) const
771 {
772 return m_pimpl->m_pctype->tolower(c);
773 }
774 363328413x charT translate(charT c, bool icase) const
775 {
776 363328413x return icase ? m_pimpl->m_pctype->tolower(c) : c;
777 }
778 360x charT tolower(charT c) const
779 {
780 360x return m_pimpl->m_pctype->tolower(c);
781 }
782 264x charT toupper(charT c) const
783 {
784 264x return m_pimpl->m_pctype->toupper(c);
785 }
786 266548x string_type transform(const charT* p1, const charT* p2) const
787 {
788 266548x return m_pimpl->transform(p1, p2);
789 }
790 62938x string_type transform_primary(const charT* p1, const charT* p2) const
791 {
792 62938x return m_pimpl->transform_primary(p1, p2);
793 }
794 582503x char_class_type lookup_classname(const charT* p1, const charT* p2) const
795 {
796 582503x return m_pimpl->lookup_classname(p1, p2);
797 }
798 6336x string_type lookup_collatename(const charT* p1, const charT* p2) const
799 {
800 6336x return m_pimpl->lookup_collatename(p1, p2);
801 }
802 10621430x bool isctype(charT c, char_class_type f) const
803 {
804 typedef typename std::ctype<charT>::mask ctype_mask;
805
806 static const ctype_mask mask_base =
807 static_cast<ctype_mask>(
808 std::ctype<charT>::alnum
809 | std::ctype<charT>::alpha
810 | std::ctype<charT>::cntrl
811 | std::ctype<charT>::digit
812 | std::ctype<charT>::graph
813 | std::ctype<charT>::lower
814 | std::ctype<charT>::print
815 | std::ctype<charT>::punct
816 | std::ctype<charT>::space
817 | std::ctype<charT>::upper
818 | std::ctype<charT>::xdigit);
819
820 21242860x if((f & mask_base)
821 18196971x && (m_pimpl->m_pctype->is(
822 7575541x static_cast<ctype_mask>(f & mask_base), c)))
823 2035003x return true;
824 8586427x else if((f & BOOST_REGEX_DETAIL_NS::cpp_regex_traits_implementation<charT>::mask_unicode) && BOOST_REGEX_DETAIL_NS::is_extended(c))
825 156x return true;
826 8586271x else if((f & BOOST_REGEX_DETAIL_NS::cpp_regex_traits_implementation<charT>::mask_word) && (c == '_'))
827 11067x return true;
828 17150408x else if((f & BOOST_REGEX_DETAIL_NS::cpp_regex_traits_implementation<charT>::mask_blank)
829 139720x && m_pimpl->m_pctype->is(std::ctype<charT>::space, c)
830 8714924x && !BOOST_REGEX_DETAIL_NS::is_separator(c))
831 2865x return true;
832 17144678x else if((f & BOOST_REGEX_DETAIL_NS::cpp_regex_traits_implementation<charT>::mask_vertical)
833 8572339x && (::boost::BOOST_REGEX_DETAIL_NS::is_separator(c) || (c == '\v')))
834 2784x return true;
835 17139110x else if((f & BOOST_REGEX_DETAIL_NS::cpp_regex_traits_implementation<charT>::mask_horizontal)
836 8569555x && this->isctype(c, std::ctype<charT>::space) && !this->isctype(c, BOOST_REGEX_DETAIL_NS::cpp_regex_traits_implementation<charT>::mask_vertical))
837 708x return true;
838 #ifdef __CYGWIN__
839 //
840 // Cygwin has a buggy ctype facet, see https://www.cygwin.com/ml/cygwin/2012-08/msg00178.html:
841 //
842 else if((f & std::ctype<charT>::xdigit) == std::ctype<charT>::xdigit)
843 {
844 if((c >= 'a') && (c <= 'f'))
845 return true;
846 if((c >= 'A') && (c <= 'F'))
847 return true;
848 }
849 #endif
850 8568847x return false;
851 }
852 std::intmax_t toi(const charT*& p1, const charT* p2, int radix)const;
853 int value(charT c, int radix)const
854 {
855 const charT* pc = &c;
856 return (int)toi(pc, pc + 1, radix);
857 }
858 locale_type imbue(locale_type l)
859 {
860 std::locale result(getloc());
861 m_pimpl = BOOST_REGEX_DETAIL_NS::create_cpp_regex_traits<charT>(l);
862 return result;
863 }
864 locale_type getloc()const
865 {
866 return m_pimpl->m_locale;
867 }
868 9215x std::string error_string(regex_constants::error_type n) const
869 {
870 9215x return m_pimpl->error_string(n);
871 }
872
873 //
874 // extension:
875 // set the name of the message catalog in use (defaults to "boost_regex").
876 //
877 static std::string catalog_name(const std::string& name);
878 static std::string get_catalog_name();
879
880 private:
881 std::shared_ptr<const BOOST_REGEX_DETAIL_NS::cpp_regex_traits_implementation<charT> > m_pimpl;
882 //
883 // catalog name handler:
884 //
885 static std::string& get_catalog_name_inst();
886
887 #ifdef BOOST_HAS_THREADS
888 static std::mutex& get_mutex_inst();
889 #endif
890 };
891
892
893 template <class charT>
894 249676x std::intmax_t cpp_regex_traits<charT>::toi(const charT*& first, const charT* last, int radix)const
895 {
896 249676x BOOST_REGEX_DETAIL_NS::parser_buf<charT> sbuf; // buffer for parsing numbers.
897 249676x std::basic_istream<charT> is(&sbuf); // stream for parsing numbers.
898
899 // we do NOT want to parse any thousands separators inside the stream:
900 249676x last = std::find(first, last, std::use_facet<std::numpunct<charT>>(is.getloc()).thousands_sep());
901
902 249676x sbuf.pubsetbuf(const_cast<charT*>(static_cast<const charT*>(first)), static_cast<std::streamsize>(last-first));
903 249676x is.clear();
904 249676x if(std::abs(radix) == 16) is >> std::hex;
905 156892x else if(std::abs(radix) == 8) is >> std::oct;
906 56740x else is >> std::dec;
907 std::intmax_t val;
908 249676x if(is >> val)
909 {
910 238034x first = first + ((last - first) - sbuf.in_avail());
911 238034x return val;
912 }
913 else
914 11642x return -1;
915 249676x }
916
917 template <class charT>
918 std::string cpp_regex_traits<charT>::catalog_name(const std::string& name)
919 {
920 #ifdef BOOST_HAS_THREADS
921 std::lock_guard<std::mutex> lk(get_mutex_inst());
922 #endif
923 std::string result(get_catalog_name_inst());
924 get_catalog_name_inst() = name;
925 return result;
926 }
927
928 template <class charT>
929 88x std::string& cpp_regex_traits<charT>::get_catalog_name_inst()
930 {
931 88x static std::string s_name;
932 88x return s_name;
933 }
934
935 template <class charT>
936 88x std::string cpp_regex_traits<charT>::get_catalog_name()
937 {
938 #ifdef BOOST_HAS_THREADS
939 88x std::lock_guard<std::mutex> lk(get_mutex_inst());
940 #endif
941 88x std::string result(get_catalog_name_inst());
942 172x return result;
943 88x }
944
945 #ifdef BOOST_HAS_THREADS
946 template <class charT>
947 88x std::mutex& cpp_regex_traits<charT>::get_mutex_inst()
948 {
949 static std::mutex s_mutex;
950 88x return s_mutex;
951 }
952 #endif
953
954 namespace BOOST_REGEX_DETAIL_NS {
955
956 36x inline void cpp_regex_traits_char_layer<char>::init()
957 {
958 // we need to start by initialising our syntax map so we know which
959 // character is used for which purpose:
960 36x std::memset(m_char_map, 0, sizeof(m_char_map));
961 #ifndef __IBMCPP__
962 36x std::messages<char>::catalog cat = static_cast<std::messages<char>::catalog>(-1);
963 #else
964 std::messages<char>::catalog cat = reinterpret_cast<std::messages<char>::catalog>(-1);
965 #endif
966 36x std::string cat_name(cpp_regex_traits<char>::get_catalog_name());
967 36x if ((!cat_name.empty()) && (m_pmessages != 0))
968 {
969 cat = this->m_pmessages->open(
970 cat_name,
971 this->m_locale);
972 if ((int)cat < 0)
973 {
974 std::string m("Unable to open message catalog: ");
975 std::runtime_error err(m + cat_name);
976 boost::BOOST_REGEX_DETAIL_NS::raise_runtime_error(err);
977 }
978 }
979 //
980 // if we have a valid catalog then load our messages:
981 //
982 36x if ((int)cat >= 0)
983 {
984 #ifndef BOOST_NO_EXCEPTIONS
985 try {
986 #endif
987 for (regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
988 {
989 string_type mss = this->m_pmessages->get(cat, 0, i, get_default_syntax(i));
990 for (string_type::size_type j = 0; j < mss.size(); ++j)
991 {
992 m_char_map[static_cast<unsigned char>(mss[j])] = i;
993 }
994 }
995 this->m_pmessages->close(cat);
996 #ifndef BOOST_NO_EXCEPTIONS
997 }
998 catch (...)
999 {
1000 this->m_pmessages->close(cat);
1001 throw;
1002 }
1003 #endif
1004 }
1005 else
1006 {
1007 2160x for (regex_constants::syntax_type j = 1; j < regex_constants::syntax_max; ++j)
1008 {
1009 2124x const char* ptr = get_default_syntax(j);
1010 4320x while (ptr && *ptr)
1011 {
1012 2196x m_char_map[static_cast<unsigned char>(*ptr)] = j;
1013 2196x ++ptr;
1014 }
1015 }
1016 }
1017 //
1018 // finish off by calculating our escape types:
1019 //
1020 36x unsigned char i = 'A';
1021 do
1022 {
1023 6876x if (m_char_map[i] == 0)
1024 {
1025 5652x if (this->m_pctype->is(std::ctype_base::lower, i))
1026 432x m_char_map[i] = regex_constants::escape_type_class;
1027 5220x else if (this->m_pctype->is(std::ctype_base::upper, i))
1028 504x m_char_map[i] = regex_constants::escape_type_not_class;
1029 }
1030 6876x } while (0xFF != i++);
1031 36x }
1032
1033 } // namespace detail
1034
1035
1036 } // boost
1037
1038 #ifdef BOOST_REGEX_MSVC
1039 #pragma warning(pop)
1040 #endif
1041
1042
1043 #endif
1044