annotate DEPENDENCIES/generic/include/boost/regex/v4/w32_regex_traits.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 /*
Chris@16 2 *
Chris@16 3 * Copyright (c) 2004
Chris@16 4 * John Maddock
Chris@16 5 *
Chris@16 6 * Use, modification and distribution are subject to the
Chris@16 7 * Boost Software License, Version 1.0. (See accompanying file
Chris@16 8 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 9 *
Chris@16 10 */
Chris@16 11
Chris@16 12 /*
Chris@16 13 * LOCATION: see http://www.boost.org for most recent version.
Chris@16 14 * FILE w32_regex_traits.hpp
Chris@16 15 * VERSION see <boost/version.hpp>
Chris@16 16 * DESCRIPTION: Declares regular expression traits class w32_regex_traits.
Chris@16 17 */
Chris@16 18
Chris@16 19 #ifndef BOOST_W32_REGEX_TRAITS_HPP_INCLUDED
Chris@16 20 #define BOOST_W32_REGEX_TRAITS_HPP_INCLUDED
Chris@16 21
Chris@16 22 #ifndef BOOST_RE_PAT_EXCEPT_HPP
Chris@16 23 #include <boost/regex/pattern_except.hpp>
Chris@16 24 #endif
Chris@16 25 #ifndef BOOST_REGEX_TRAITS_DEFAULTS_HPP_INCLUDED
Chris@16 26 #include <boost/regex/v4/regex_traits_defaults.hpp>
Chris@16 27 #endif
Chris@16 28 #ifdef BOOST_HAS_THREADS
Chris@16 29 #include <boost/regex/pending/static_mutex.hpp>
Chris@16 30 #endif
Chris@16 31 #ifndef BOOST_REGEX_PRIMARY_TRANSFORM
Chris@16 32 #include <boost/regex/v4/primary_transform.hpp>
Chris@16 33 #endif
Chris@16 34 #ifndef BOOST_REGEX_OBJECT_CACHE_HPP
Chris@16 35 #include <boost/regex/pending/object_cache.hpp>
Chris@16 36 #endif
Chris@16 37
Chris@16 38 #ifdef BOOST_MSVC
Chris@16 39 #pragma warning(push)
Chris@16 40 #pragma warning(disable: 4103)
Chris@16 41 #endif
Chris@16 42 #ifdef BOOST_HAS_ABI_HEADERS
Chris@16 43 # include BOOST_ABI_PREFIX
Chris@16 44 #endif
Chris@16 45 #ifdef BOOST_MSVC
Chris@16 46 #pragma warning(pop)
Chris@16 47 #endif
Chris@16 48
Chris@16 49 #ifdef BOOST_MSVC
Chris@16 50 #pragma warning(push)
Chris@16 51 #pragma warning(disable:4786)
Chris@16 52 #pragma warning(disable:4800)
Chris@16 53 #endif
Chris@16 54
Chris@16 55 namespace boost{
Chris@16 56
Chris@16 57 //
Chris@16 58 // forward declaration is needed by some compilers:
Chris@16 59 //
Chris@16 60 template <class charT>
Chris@16 61 class w32_regex_traits;
Chris@16 62
Chris@16 63 namespace re_detail{
Chris@16 64
Chris@16 65 //
Chris@16 66 // start by typedeffing the types we'll need:
Chris@16 67 //
Chris@16 68 typedef ::boost::uint32_t lcid_type; // placeholder for LCID.
Chris@16 69 typedef ::boost::shared_ptr<void> cat_type; // placeholder for dll HANDLE.
Chris@16 70
Chris@16 71 //
Chris@16 72 // then add wrappers around the actual Win32 API's (ie implementation hiding):
Chris@16 73 //
Chris@16 74 BOOST_REGEX_DECL lcid_type BOOST_REGEX_CALL w32_get_default_locale();
Chris@16 75 BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_lower(char, lcid_type);
Chris@16 76 #ifndef BOOST_NO_WREGEX
Chris@16 77 BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_lower(wchar_t, lcid_type);
Chris@16 78 #ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
Chris@16 79 BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_lower(unsigned short ca, lcid_type state_id);
Chris@16 80 #endif
Chris@16 81 #endif
Chris@16 82 BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_upper(char, lcid_type);
Chris@16 83 #ifndef BOOST_NO_WREGEX
Chris@16 84 BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_upper(wchar_t, lcid_type);
Chris@16 85 #ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
Chris@16 86 BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_upper(unsigned short ca, lcid_type state_id);
Chris@16 87 #endif
Chris@16 88 #endif
Chris@16 89 BOOST_REGEX_DECL cat_type BOOST_REGEX_CALL w32_cat_open(const std::string& name);
Chris@16 90 BOOST_REGEX_DECL std::string BOOST_REGEX_CALL w32_cat_get(const cat_type& cat, lcid_type state_id, int i, const std::string& def);
Chris@16 91 #ifndef BOOST_NO_WREGEX
Chris@16 92 BOOST_REGEX_DECL std::wstring BOOST_REGEX_CALL w32_cat_get(const cat_type& cat, lcid_type state_id, int i, const std::wstring& def);
Chris@16 93 #ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
Chris@16 94 BOOST_REGEX_DECL std::basic_string<unsigned short> BOOST_REGEX_CALL w32_cat_get(const cat_type& cat, lcid_type, int i, const std::basic_string<unsigned short>& def);
Chris@16 95 #endif
Chris@16 96 #endif
Chris@16 97 BOOST_REGEX_DECL std::string BOOST_REGEX_CALL w32_transform(lcid_type state_id, const char* p1, const char* p2);
Chris@16 98 #ifndef BOOST_NO_WREGEX
Chris@16 99 BOOST_REGEX_DECL std::wstring BOOST_REGEX_CALL w32_transform(lcid_type state_id, const wchar_t* p1, const wchar_t* p2);
Chris@16 100 #ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
Chris@16 101 BOOST_REGEX_DECL std::basic_string<unsigned short> BOOST_REGEX_CALL w32_transform(lcid_type state_id, const unsigned short* p1, const unsigned short* p2);
Chris@16 102 #endif
Chris@16 103 #endif
Chris@16 104 BOOST_REGEX_DECL char BOOST_REGEX_CALL w32_tolower(char c, lcid_type);
Chris@16 105 #ifndef BOOST_NO_WREGEX
Chris@16 106 BOOST_REGEX_DECL wchar_t BOOST_REGEX_CALL w32_tolower(wchar_t c, lcid_type);
Chris@16 107 #ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
Chris@16 108 BOOST_REGEX_DECL unsigned short BOOST_REGEX_CALL w32_tolower(unsigned short c, lcid_type state_id);
Chris@16 109 #endif
Chris@16 110 #endif
Chris@16 111 BOOST_REGEX_DECL char BOOST_REGEX_CALL w32_toupper(char c, lcid_type);
Chris@16 112 #ifndef BOOST_NO_WREGEX
Chris@16 113 BOOST_REGEX_DECL wchar_t BOOST_REGEX_CALL w32_toupper(wchar_t c, lcid_type);
Chris@16 114 #endif
Chris@16 115 BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is(lcid_type, boost::uint32_t mask, char c);
Chris@16 116 #ifndef BOOST_NO_WREGEX
Chris@16 117 BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is(lcid_type, boost::uint32_t mask, wchar_t c);
Chris@16 118 #ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
Chris@16 119 BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is(lcid_type state_id, boost::uint32_t m, unsigned short c);
Chris@16 120 #endif
Chris@16 121 #endif
Chris@16 122 //
Chris@16 123 // class w32_regex_traits_base:
Chris@16 124 // acts as a container for locale and the facets we are using.
Chris@16 125 //
Chris@16 126 template <class charT>
Chris@16 127 struct w32_regex_traits_base
Chris@16 128 {
Chris@16 129 w32_regex_traits_base(lcid_type l)
Chris@16 130 { imbue(l); }
Chris@16 131 lcid_type imbue(lcid_type l);
Chris@16 132
Chris@16 133 lcid_type m_locale;
Chris@16 134 };
Chris@16 135
Chris@16 136 template <class charT>
Chris@16 137 inline lcid_type w32_regex_traits_base<charT>::imbue(lcid_type l)
Chris@16 138 {
Chris@16 139 lcid_type result(m_locale);
Chris@16 140 m_locale = l;
Chris@16 141 return result;
Chris@16 142 }
Chris@16 143
Chris@16 144 //
Chris@16 145 // class w32_regex_traits_char_layer:
Chris@16 146 // implements methods that require specialisation for narrow characters:
Chris@16 147 //
Chris@16 148 template <class charT>
Chris@16 149 class w32_regex_traits_char_layer : public w32_regex_traits_base<charT>
Chris@16 150 {
Chris@16 151 typedef std::basic_string<charT> string_type;
Chris@16 152 typedef std::map<charT, regex_constants::syntax_type> map_type;
Chris@16 153 typedef typename map_type::const_iterator map_iterator_type;
Chris@16 154 public:
Chris@16 155 w32_regex_traits_char_layer(const lcid_type l);
Chris@16 156
Chris@16 157 regex_constants::syntax_type syntax_type(charT c)const
Chris@16 158 {
Chris@16 159 map_iterator_type i = m_char_map.find(c);
Chris@16 160 return ((i == m_char_map.end()) ? 0 : i->second);
Chris@16 161 }
Chris@16 162 regex_constants::escape_syntax_type escape_syntax_type(charT c) const
Chris@16 163 {
Chris@16 164 map_iterator_type i = m_char_map.find(c);
Chris@16 165 if(i == m_char_map.end())
Chris@16 166 {
Chris@16 167 if(::boost::re_detail::w32_is_lower(c, this->m_locale)) return regex_constants::escape_type_class;
Chris@16 168 if(::boost::re_detail::w32_is_upper(c, this->m_locale)) return regex_constants::escape_type_not_class;
Chris@16 169 return 0;
Chris@16 170 }
Chris@16 171 return i->second;
Chris@16 172 }
Chris@16 173 charT tolower(charT c)const
Chris@16 174 {
Chris@16 175 return ::boost::re_detail::w32_tolower(c, this->m_locale);
Chris@16 176 }
Chris@16 177 bool isctype(boost::uint32_t mask, charT c)const
Chris@16 178 {
Chris@16 179 return ::boost::re_detail::w32_is(this->m_locale, mask, c);
Chris@16 180 }
Chris@16 181
Chris@16 182 private:
Chris@16 183 string_type get_default_message(regex_constants::syntax_type);
Chris@16 184 // TODO: use a hash table when available!
Chris@16 185 map_type m_char_map;
Chris@16 186 };
Chris@16 187
Chris@16 188 template <class charT>
Chris@16 189 w32_regex_traits_char_layer<charT>::w32_regex_traits_char_layer(::boost::re_detail::lcid_type l)
Chris@16 190 : w32_regex_traits_base<charT>(l)
Chris@16 191 {
Chris@16 192 // we need to start by initialising our syntax map so we know which
Chris@16 193 // character is used for which purpose:
Chris@16 194 cat_type cat;
Chris@16 195 std::string cat_name(w32_regex_traits<charT>::get_catalog_name());
Chris@16 196 if(cat_name.size())
Chris@16 197 {
Chris@16 198 cat = ::boost::re_detail::w32_cat_open(cat_name);
Chris@16 199 if(!cat)
Chris@16 200 {
Chris@16 201 std::string m("Unable to open message catalog: ");
Chris@16 202 std::runtime_error err(m + cat_name);
Chris@16 203 boost::re_detail::raise_runtime_error(err);
Chris@16 204 }
Chris@16 205 }
Chris@16 206 //
Chris@16 207 // if we have a valid catalog then load our messages:
Chris@16 208 //
Chris@16 209 if(cat)
Chris@16 210 {
Chris@16 211 for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
Chris@16 212 {
Chris@16 213 string_type mss = ::boost::re_detail::w32_cat_get(cat, this->m_locale, i, get_default_message(i));
Chris@16 214 for(typename string_type::size_type j = 0; j < mss.size(); ++j)
Chris@16 215 {
Chris@16 216 this->m_char_map[mss[j]] = i;
Chris@16 217 }
Chris@16 218 }
Chris@16 219 }
Chris@16 220 else
Chris@16 221 {
Chris@16 222 for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
Chris@16 223 {
Chris@16 224 const char* ptr = get_default_syntax(i);
Chris@16 225 while(ptr && *ptr)
Chris@16 226 {
Chris@16 227 this->m_char_map[static_cast<charT>(*ptr)] = i;
Chris@16 228 ++ptr;
Chris@16 229 }
Chris@16 230 }
Chris@16 231 }
Chris@16 232 }
Chris@16 233
Chris@16 234 template <class charT>
Chris@16 235 typename w32_regex_traits_char_layer<charT>::string_type
Chris@16 236 w32_regex_traits_char_layer<charT>::get_default_message(regex_constants::syntax_type i)
Chris@16 237 {
Chris@16 238 const char* ptr = get_default_syntax(i);
Chris@16 239 string_type result;
Chris@16 240 while(ptr && *ptr)
Chris@16 241 {
Chris@16 242 result.append(1, static_cast<charT>(*ptr));
Chris@16 243 ++ptr;
Chris@16 244 }
Chris@16 245 return result;
Chris@16 246 }
Chris@16 247
Chris@16 248 //
Chris@16 249 // specialised version for narrow characters:
Chris@16 250 //
Chris@16 251 template <>
Chris@16 252 class BOOST_REGEX_DECL w32_regex_traits_char_layer<char> : public w32_regex_traits_base<char>
Chris@16 253 {
Chris@16 254 typedef std::string string_type;
Chris@16 255 public:
Chris@16 256 w32_regex_traits_char_layer(::boost::re_detail::lcid_type l)
Chris@16 257 : w32_regex_traits_base<char>(l)
Chris@16 258 {
Chris@16 259 init();
Chris@16 260 }
Chris@16 261
Chris@16 262 regex_constants::syntax_type syntax_type(char c)const
Chris@16 263 {
Chris@16 264 return m_char_map[static_cast<unsigned char>(c)];
Chris@16 265 }
Chris@16 266 regex_constants::escape_syntax_type escape_syntax_type(char c) const
Chris@16 267 {
Chris@16 268 return m_char_map[static_cast<unsigned char>(c)];
Chris@16 269 }
Chris@16 270 char tolower(char c)const
Chris@16 271 {
Chris@16 272 return m_lower_map[static_cast<unsigned char>(c)];
Chris@16 273 }
Chris@16 274 bool isctype(boost::uint32_t mask, char c)const
Chris@16 275 {
Chris@16 276 return m_type_map[static_cast<unsigned char>(c)] & mask;
Chris@16 277 }
Chris@16 278
Chris@16 279 private:
Chris@16 280 regex_constants::syntax_type m_char_map[1u << CHAR_BIT];
Chris@16 281 char m_lower_map[1u << CHAR_BIT];
Chris@16 282 boost::uint16_t m_type_map[1u << CHAR_BIT];
Chris@16 283 void init();
Chris@16 284 };
Chris@16 285
Chris@16 286 //
Chris@16 287 // class w32_regex_traits_implementation:
Chris@16 288 // provides pimpl implementation for w32_regex_traits.
Chris@16 289 //
Chris@16 290 template <class charT>
Chris@16 291 class w32_regex_traits_implementation : public w32_regex_traits_char_layer<charT>
Chris@16 292 {
Chris@16 293 public:
Chris@16 294 typedef typename w32_regex_traits<charT>::char_class_type char_class_type;
Chris@16 295 BOOST_STATIC_CONSTANT(char_class_type, mask_word = 0x0400); // must be C1_DEFINED << 1
Chris@16 296 BOOST_STATIC_CONSTANT(char_class_type, mask_unicode = 0x0800); // must be C1_DEFINED << 2
Chris@16 297 BOOST_STATIC_CONSTANT(char_class_type, mask_horizontal = 0x1000); // must be C1_DEFINED << 3
Chris@16 298 BOOST_STATIC_CONSTANT(char_class_type, mask_vertical = 0x2000); // must be C1_DEFINED << 4
Chris@16 299 BOOST_STATIC_CONSTANT(char_class_type, mask_base = 0x3ff); // all the masks used by the CT_CTYPE1 group
Chris@16 300
Chris@16 301 typedef std::basic_string<charT> string_type;
Chris@16 302 typedef charT char_type;
Chris@16 303 w32_regex_traits_implementation(::boost::re_detail::lcid_type l);
Chris@16 304 std::string error_string(regex_constants::error_type n) const
Chris@16 305 {
Chris@16 306 if(!m_error_strings.empty())
Chris@16 307 {
Chris@16 308 std::map<int, std::string>::const_iterator p = m_error_strings.find(n);
Chris@16 309 return (p == m_error_strings.end()) ? std::string(get_default_error_string(n)) : p->second;
Chris@16 310 }
Chris@16 311 return get_default_error_string(n);
Chris@16 312 }
Chris@16 313 char_class_type lookup_classname(const charT* p1, const charT* p2) const
Chris@16 314 {
Chris@16 315 char_class_type result = lookup_classname_imp(p1, p2);
Chris@16 316 if(result == 0)
Chris@16 317 {
Chris@16 318 typedef typename string_type::size_type size_type;
Chris@16 319 string_type temp(p1, p2);
Chris@16 320 for(size_type i = 0; i < temp.size(); ++i)
Chris@16 321 temp[i] = this->tolower(temp[i]);
Chris@16 322 result = lookup_classname_imp(&*temp.begin(), &*temp.begin() + temp.size());
Chris@16 323 }
Chris@16 324 return result;
Chris@16 325 }
Chris@16 326 string_type lookup_collatename(const charT* p1, const charT* p2) const;
Chris@16 327 string_type transform_primary(const charT* p1, const charT* p2) const;
Chris@16 328 string_type transform(const charT* p1, const charT* p2) const
Chris@16 329 {
Chris@16 330 return ::boost::re_detail::w32_transform(this->m_locale, p1, p2);
Chris@16 331 }
Chris@16 332 private:
Chris@16 333 std::map<int, std::string> m_error_strings; // error messages indexed by numberic ID
Chris@16 334 std::map<string_type, char_class_type> m_custom_class_names; // character class names
Chris@16 335 std::map<string_type, string_type> m_custom_collate_names; // collating element names
Chris@16 336 unsigned m_collate_type; // the form of the collation string
Chris@16 337 charT m_collate_delim; // the collation group delimiter
Chris@16 338 //
Chris@16 339 // helpers:
Chris@16 340 //
Chris@16 341 char_class_type lookup_classname_imp(const charT* p1, const charT* p2) const;
Chris@16 342 };
Chris@16 343
Chris@16 344 template <class charT>
Chris@16 345 typename w32_regex_traits_implementation<charT>::string_type
Chris@16 346 w32_regex_traits_implementation<charT>::transform_primary(const charT* p1, const charT* p2) const
Chris@16 347 {
Chris@16 348 string_type result;
Chris@16 349 //
Chris@16 350 // What we do here depends upon the format of the sort key returned by
Chris@16 351 // sort key returned by this->transform:
Chris@16 352 //
Chris@16 353 switch(m_collate_type)
Chris@16 354 {
Chris@16 355 case sort_C:
Chris@16 356 case sort_unknown:
Chris@16 357 // the best we can do is translate to lower case, then get a regular sort key:
Chris@16 358 {
Chris@16 359 result.assign(p1, p2);
Chris@16 360 typedef typename string_type::size_type size_type;
Chris@16 361 for(size_type i = 0; i < result.size(); ++i)
Chris@16 362 result[i] = this->tolower(result[i]);
Chris@16 363 result = this->transform(&*result.begin(), &*result.begin() + result.size());
Chris@16 364 break;
Chris@16 365 }
Chris@16 366 case sort_fixed:
Chris@16 367 {
Chris@16 368 // get a regular sort key, and then truncate it:
Chris@16 369 result.assign(this->transform(p1, p2));
Chris@16 370 result.erase(this->m_collate_delim);
Chris@16 371 break;
Chris@16 372 }
Chris@16 373 case sort_delim:
Chris@16 374 // get a regular sort key, and then truncate everything after the delim:
Chris@16 375 result.assign(this->transform(p1, p2));
Chris@16 376 std::size_t i;
Chris@16 377 for(i = 0; i < result.size(); ++i)
Chris@16 378 {
Chris@16 379 if(result[i] == m_collate_delim)
Chris@16 380 break;
Chris@16 381 }
Chris@16 382 result.erase(i);
Chris@16 383 break;
Chris@16 384 }
Chris@16 385 if(result.empty())
Chris@16 386 result = string_type(1, charT(0));
Chris@16 387 return result;
Chris@16 388 }
Chris@16 389
Chris@16 390 template <class charT>
Chris@16 391 typename w32_regex_traits_implementation<charT>::string_type
Chris@16 392 w32_regex_traits_implementation<charT>::lookup_collatename(const charT* p1, const charT* p2) const
Chris@16 393 {
Chris@16 394 typedef typename std::map<string_type, string_type>::const_iterator iter_type;
Chris@16 395 if(m_custom_collate_names.size())
Chris@16 396 {
Chris@16 397 iter_type pos = m_custom_collate_names.find(string_type(p1, p2));
Chris@16 398 if(pos != m_custom_collate_names.end())
Chris@16 399 return pos->second;
Chris@16 400 }
Chris@16 401 #if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)\
Chris@16 402 && !BOOST_WORKAROUND(__BORLANDC__, <= 0x0551)
Chris@16 403 std::string name(p1, p2);
Chris@16 404 #else
Chris@16 405 std::string name;
Chris@16 406 const charT* p0 = p1;
Chris@16 407 while(p0 != p2)
Chris@16 408 name.append(1, char(*p0++));
Chris@16 409 #endif
Chris@16 410 name = lookup_default_collate_name(name);
Chris@16 411 #if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)\
Chris@16 412 && !BOOST_WORKAROUND(__BORLANDC__, <= 0x0551)
Chris@16 413 if(name.size())
Chris@16 414 return string_type(name.begin(), name.end());
Chris@16 415 #else
Chris@16 416 if(name.size())
Chris@16 417 {
Chris@16 418 string_type result;
Chris@16 419 typedef std::string::const_iterator iter;
Chris@16 420 iter b = name.begin();
Chris@16 421 iter e = name.end();
Chris@16 422 while(b != e)
Chris@16 423 result.append(1, charT(*b++));
Chris@16 424 return result;
Chris@16 425 }
Chris@16 426 #endif
Chris@16 427 if(p2 - p1 == 1)
Chris@16 428 return string_type(1, *p1);
Chris@16 429 return string_type();
Chris@16 430 }
Chris@16 431
Chris@16 432 template <class charT>
Chris@16 433 w32_regex_traits_implementation<charT>::w32_regex_traits_implementation(::boost::re_detail::lcid_type l)
Chris@16 434 : w32_regex_traits_char_layer<charT>(l)
Chris@16 435 {
Chris@16 436 cat_type cat;
Chris@16 437 std::string cat_name(w32_regex_traits<charT>::get_catalog_name());
Chris@16 438 if(cat_name.size())
Chris@16 439 {
Chris@16 440 cat = ::boost::re_detail::w32_cat_open(cat_name);
Chris@16 441 if(!cat)
Chris@16 442 {
Chris@16 443 std::string m("Unable to open message catalog: ");
Chris@16 444 std::runtime_error err(m + cat_name);
Chris@16 445 boost::re_detail::raise_runtime_error(err);
Chris@16 446 }
Chris@16 447 }
Chris@16 448 //
Chris@16 449 // if we have a valid catalog then load our messages:
Chris@16 450 //
Chris@16 451 if(cat)
Chris@16 452 {
Chris@16 453 //
Chris@16 454 // Error messages:
Chris@16 455 //
Chris@16 456 for(boost::regex_constants::error_type i = static_cast<boost::regex_constants::error_type>(0);
Chris@16 457 i <= boost::regex_constants::error_unknown;
Chris@16 458 i = static_cast<boost::regex_constants::error_type>(i + 1))
Chris@16 459 {
Chris@16 460 const char* p = get_default_error_string(i);
Chris@16 461 string_type default_message;
Chris@16 462 while(*p)
Chris@16 463 {
Chris@16 464 default_message.append(1, static_cast<charT>(*p));
Chris@16 465 ++p;
Chris@16 466 }
Chris@16 467 string_type s = ::boost::re_detail::w32_cat_get(cat, this->m_locale, i+200, default_message);
Chris@16 468 std::string result;
Chris@16 469 for(std::string::size_type j = 0; j < s.size(); ++j)
Chris@16 470 {
Chris@16 471 result.append(1, static_cast<char>(s[j]));
Chris@16 472 }
Chris@16 473 m_error_strings[i] = result;
Chris@16 474 }
Chris@16 475 //
Chris@16 476 // Custom class names:
Chris@16 477 //
Chris@16 478 static const char_class_type masks[14] =
Chris@16 479 {
Chris@16 480 0x0104u, // C1_ALPHA | C1_DIGIT
Chris@16 481 0x0100u, // C1_ALPHA
Chris@16 482 0x0020u, // C1_CNTRL
Chris@16 483 0x0004u, // C1_DIGIT
Chris@16 484 (~(0x0020u|0x0008u) & 0x01ffu) | 0x0400u, // not C1_CNTRL or C1_SPACE
Chris@16 485 0x0002u, // C1_LOWER
Chris@16 486 (~0x0020u & 0x01ffu) | 0x0400, // not C1_CNTRL
Chris@16 487 0x0010u, // C1_PUNCT
Chris@16 488 0x0008u, // C1_SPACE
Chris@16 489 0x0001u, // C1_UPPER
Chris@16 490 0x0080u, // C1_XDIGIT
Chris@16 491 0x0040u, // C1_BLANK
Chris@16 492 w32_regex_traits_implementation<charT>::mask_word,
Chris@16 493 w32_regex_traits_implementation<charT>::mask_unicode,
Chris@16 494 };
Chris@16 495 static const string_type null_string;
Chris@16 496 for(unsigned int j = 0; j <= 13; ++j)
Chris@16 497 {
Chris@16 498 string_type s(::boost::re_detail::w32_cat_get(cat, this->m_locale, j+300, null_string));
Chris@16 499 if(s.size())
Chris@16 500 this->m_custom_class_names[s] = masks[j];
Chris@16 501 }
Chris@16 502 }
Chris@16 503 //
Chris@16 504 // get the collation format used by m_pcollate:
Chris@16 505 //
Chris@16 506 m_collate_type = re_detail::find_sort_syntax(this, &m_collate_delim);
Chris@16 507 }
Chris@16 508
Chris@16 509 template <class charT>
Chris@16 510 typename w32_regex_traits_implementation<charT>::char_class_type
Chris@16 511 w32_regex_traits_implementation<charT>::lookup_classname_imp(const charT* p1, const charT* p2) const
Chris@16 512 {
Chris@16 513 static const char_class_type masks[22] =
Chris@16 514 {
Chris@16 515 0,
Chris@16 516 0x0104u, // C1_ALPHA | C1_DIGIT
Chris@16 517 0x0100u, // C1_ALPHA
Chris@16 518 0x0040u, // C1_BLANK
Chris@16 519 0x0020u, // C1_CNTRL
Chris@16 520 0x0004u, // C1_DIGIT
Chris@16 521 0x0004u, // C1_DIGIT
Chris@16 522 (~(0x0020u|0x0008u|0x0040) & 0x01ffu) | 0x0400u, // not C1_CNTRL or C1_SPACE or C1_BLANK
Chris@16 523 w32_regex_traits_implementation<charT>::mask_horizontal,
Chris@16 524 0x0002u, // C1_LOWER
Chris@16 525 0x0002u, // C1_LOWER
Chris@16 526 (~0x0020u & 0x01ffu) | 0x0400, // not C1_CNTRL
Chris@16 527 0x0010u, // C1_PUNCT
Chris@16 528 0x0008u, // C1_SPACE
Chris@16 529 0x0008u, // C1_SPACE
Chris@16 530 0x0001u, // C1_UPPER
Chris@16 531 w32_regex_traits_implementation<charT>::mask_unicode,
Chris@16 532 0x0001u, // C1_UPPER
Chris@16 533 w32_regex_traits_implementation<charT>::mask_vertical,
Chris@16 534 0x0104u | w32_regex_traits_implementation<charT>::mask_word,
Chris@16 535 0x0104u | w32_regex_traits_implementation<charT>::mask_word,
Chris@16 536 0x0080u, // C1_XDIGIT
Chris@16 537 };
Chris@16 538 if(m_custom_class_names.size())
Chris@16 539 {
Chris@16 540 typedef typename std::map<std::basic_string<charT>, char_class_type>::const_iterator map_iter;
Chris@16 541 map_iter pos = m_custom_class_names.find(string_type(p1, p2));
Chris@16 542 if(pos != m_custom_class_names.end())
Chris@16 543 return pos->second;
Chris@16 544 }
Chris@16 545 std::size_t state_id = 1 + re_detail::get_default_class_id(p1, p2);
Chris@16 546 if(state_id < sizeof(masks) / sizeof(masks[0]))
Chris@16 547 return masks[state_id];
Chris@16 548 return masks[0];
Chris@16 549 }
Chris@16 550
Chris@16 551
Chris@16 552 template <class charT>
Chris@101 553 boost::shared_ptr<const w32_regex_traits_implementation<charT> > create_w32_regex_traits(::boost::re_detail::lcid_type l)
Chris@16 554 {
Chris@16 555 // TODO: create a cache for previously constructed objects.
Chris@16 556 return boost::object_cache< ::boost::re_detail::lcid_type, w32_regex_traits_implementation<charT> >::get(l, 5);
Chris@16 557 }
Chris@16 558
Chris@16 559 } // re_detail
Chris@16 560
Chris@16 561 template <class charT>
Chris@16 562 class w32_regex_traits
Chris@16 563 {
Chris@16 564 public:
Chris@16 565 typedef charT char_type;
Chris@16 566 typedef std::size_t size_type;
Chris@16 567 typedef std::basic_string<char_type> string_type;
Chris@16 568 typedef ::boost::re_detail::lcid_type locale_type;
Chris@16 569 typedef boost::uint_least32_t char_class_type;
Chris@16 570
Chris@16 571 struct boost_extensions_tag{};
Chris@16 572
Chris@16 573 w32_regex_traits()
Chris@16 574 : m_pimpl(re_detail::create_w32_regex_traits<charT>(::boost::re_detail::w32_get_default_locale()))
Chris@16 575 { }
Chris@16 576 static size_type length(const char_type* p)
Chris@16 577 {
Chris@16 578 return std::char_traits<charT>::length(p);
Chris@16 579 }
Chris@16 580 regex_constants::syntax_type syntax_type(charT c)const
Chris@16 581 {
Chris@16 582 return m_pimpl->syntax_type(c);
Chris@16 583 }
Chris@16 584 regex_constants::escape_syntax_type escape_syntax_type(charT c) const
Chris@16 585 {
Chris@16 586 return m_pimpl->escape_syntax_type(c);
Chris@16 587 }
Chris@16 588 charT translate(charT c) const
Chris@16 589 {
Chris@16 590 return c;
Chris@16 591 }
Chris@16 592 charT translate_nocase(charT c) const
Chris@16 593 {
Chris@16 594 return this->m_pimpl->tolower(c);
Chris@16 595 }
Chris@16 596 charT translate(charT c, bool icase) const
Chris@16 597 {
Chris@16 598 return icase ? this->m_pimpl->tolower(c) : c;
Chris@16 599 }
Chris@16 600 charT tolower(charT c) const
Chris@16 601 {
Chris@16 602 return this->m_pimpl->tolower(c);
Chris@16 603 }
Chris@16 604 charT toupper(charT c) const
Chris@16 605 {
Chris@16 606 return ::boost::re_detail::w32_toupper(c, this->m_pimpl->m_locale);
Chris@16 607 }
Chris@16 608 string_type transform(const charT* p1, const charT* p2) const
Chris@16 609 {
Chris@16 610 return ::boost::re_detail::w32_transform(this->m_pimpl->m_locale, p1, p2);
Chris@16 611 }
Chris@16 612 string_type transform_primary(const charT* p1, const charT* p2) const
Chris@16 613 {
Chris@16 614 return m_pimpl->transform_primary(p1, p2);
Chris@16 615 }
Chris@16 616 char_class_type lookup_classname(const charT* p1, const charT* p2) const
Chris@16 617 {
Chris@16 618 return m_pimpl->lookup_classname(p1, p2);
Chris@16 619 }
Chris@16 620 string_type lookup_collatename(const charT* p1, const charT* p2) const
Chris@16 621 {
Chris@16 622 return m_pimpl->lookup_collatename(p1, p2);
Chris@16 623 }
Chris@16 624 bool isctype(charT c, char_class_type f) const
Chris@16 625 {
Chris@16 626 if((f & re_detail::w32_regex_traits_implementation<charT>::mask_base)
Chris@16 627 && (this->m_pimpl->isctype(f & re_detail::w32_regex_traits_implementation<charT>::mask_base, c)))
Chris@16 628 return true;
Chris@16 629 else if((f & re_detail::w32_regex_traits_implementation<charT>::mask_unicode) && re_detail::is_extended(c))
Chris@16 630 return true;
Chris@16 631 else if((f & re_detail::w32_regex_traits_implementation<charT>::mask_word) && (c == '_'))
Chris@16 632 return true;
Chris@16 633 else if((f & re_detail::w32_regex_traits_implementation<charT>::mask_vertical)
Chris@16 634 && (::boost::re_detail::is_separator(c) || (c == '\v')))
Chris@16 635 return true;
Chris@16 636 else if((f & re_detail::w32_regex_traits_implementation<charT>::mask_horizontal)
Chris@16 637 && this->isctype(c, 0x0008u) && !this->isctype(c, re_detail::w32_regex_traits_implementation<charT>::mask_vertical))
Chris@16 638 return true;
Chris@16 639 return false;
Chris@16 640 }
Chris@16 641 int toi(const charT*& p1, const charT* p2, int radix)const
Chris@16 642 {
Chris@16 643 return ::boost::re_detail::global_toi(p1, p2, radix, *this);
Chris@16 644 }
Chris@16 645 int value(charT c, int radix)const
Chris@16 646 {
Chris@16 647 int result = ::boost::re_detail::global_value(c);
Chris@16 648 return result < radix ? result : -1;
Chris@16 649 }
Chris@16 650 locale_type imbue(locale_type l)
Chris@16 651 {
Chris@16 652 ::boost::re_detail::lcid_type result(getloc());
Chris@16 653 m_pimpl = re_detail::create_w32_regex_traits<charT>(l);
Chris@16 654 return result;
Chris@16 655 }
Chris@16 656 locale_type getloc()const
Chris@16 657 {
Chris@16 658 return m_pimpl->m_locale;
Chris@16 659 }
Chris@16 660 std::string error_string(regex_constants::error_type n) const
Chris@16 661 {
Chris@16 662 return m_pimpl->error_string(n);
Chris@16 663 }
Chris@16 664
Chris@16 665 //
Chris@16 666 // extension:
Chris@16 667 // set the name of the message catalog in use (defaults to "boost_regex").
Chris@16 668 //
Chris@16 669 static std::string catalog_name(const std::string& name);
Chris@16 670 static std::string get_catalog_name();
Chris@16 671
Chris@16 672 private:
Chris@16 673 boost::shared_ptr<const re_detail::w32_regex_traits_implementation<charT> > m_pimpl;
Chris@16 674 //
Chris@16 675 // catalog name handler:
Chris@16 676 //
Chris@16 677 static std::string& get_catalog_name_inst();
Chris@16 678
Chris@16 679 #ifdef BOOST_HAS_THREADS
Chris@16 680 static static_mutex& get_mutex_inst();
Chris@16 681 #endif
Chris@16 682 };
Chris@16 683
Chris@16 684 template <class charT>
Chris@16 685 std::string w32_regex_traits<charT>::catalog_name(const std::string& name)
Chris@16 686 {
Chris@16 687 #ifdef BOOST_HAS_THREADS
Chris@16 688 static_mutex::scoped_lock lk(get_mutex_inst());
Chris@16 689 #endif
Chris@16 690 std::string result(get_catalog_name_inst());
Chris@16 691 get_catalog_name_inst() = name;
Chris@16 692 return result;
Chris@16 693 }
Chris@16 694
Chris@16 695 template <class charT>
Chris@16 696 std::string& w32_regex_traits<charT>::get_catalog_name_inst()
Chris@16 697 {
Chris@16 698 static std::string s_name;
Chris@16 699 return s_name;
Chris@16 700 }
Chris@16 701
Chris@16 702 template <class charT>
Chris@16 703 std::string w32_regex_traits<charT>::get_catalog_name()
Chris@16 704 {
Chris@16 705 #ifdef BOOST_HAS_THREADS
Chris@16 706 static_mutex::scoped_lock lk(get_mutex_inst());
Chris@16 707 #endif
Chris@16 708 std::string result(get_catalog_name_inst());
Chris@16 709 return result;
Chris@16 710 }
Chris@16 711
Chris@16 712 #ifdef BOOST_HAS_THREADS
Chris@16 713 template <class charT>
Chris@16 714 static_mutex& w32_regex_traits<charT>::get_mutex_inst()
Chris@16 715 {
Chris@16 716 static static_mutex s_mutex = BOOST_STATIC_MUTEX_INIT;
Chris@16 717 return s_mutex;
Chris@16 718 }
Chris@16 719 #endif
Chris@16 720
Chris@16 721
Chris@16 722 } // boost
Chris@16 723
Chris@16 724 #ifdef BOOST_MSVC
Chris@16 725 #pragma warning(pop)
Chris@16 726 #endif
Chris@16 727
Chris@16 728 #ifdef BOOST_MSVC
Chris@16 729 #pragma warning(push)
Chris@16 730 #pragma warning(disable: 4103)
Chris@16 731 #endif
Chris@16 732 #ifdef BOOST_HAS_ABI_HEADERS
Chris@16 733 # include BOOST_ABI_SUFFIX
Chris@16 734 #endif
Chris@16 735 #ifdef BOOST_MSVC
Chris@16 736 #pragma warning(pop)
Chris@16 737 #endif
Chris@16 738
Chris@16 739 #endif