Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/libs/regex/src/w32_regex_traits.cpp @ 20

Last change on this file since 20 was 12, checked in by landauf, 18 years ago

added boost

File size: 13.9 KB
Line 
1/*
2 *
3 * Copyright (c) 2004
4 * John Maddock
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         w32_regex_traits.cpp
15  *   VERSION      see <boost/version.hpp>
16  *   DESCRIPTION: Implements w32_regex_traits<char> (and associated helper classes).
17  */
18
19#define BOOST_REGEX_SOURCE
20#include <boost/regex/config.hpp>
21
22#if defined(_WIN32) && !defined(BOOST_REGEX_NO_W32)
23#include <boost/regex/regex_traits.hpp>
24#include <boost/regex/pattern_except.hpp>
25
26#define WIN32_LEAN_AND_MEAN
27#define NOMINMAX
28#define NOGDI
29#include <windows.h>
30
31#ifdef _MSC_VER
32#pragma comment(lib, "user32.lib")
33#endif
34
35#ifdef BOOST_NO_STDC_NAMESPACE
36namespace std{
37   using ::memset;
38}
39#endif
40
41namespace boost{ namespace re_detail{
42
43void w32_regex_traits_char_layer<char>::init() 
44{
45   // we need to start by initialising our syntax map so we know which
46   // character is used for which purpose:
47   std::memset(m_char_map, 0, sizeof(m_char_map));
48   cat_type cat;
49   std::string cat_name(w32_regex_traits<char>::get_catalog_name());
50   if(cat_name.size())
51   {
52      cat = ::boost::re_detail::w32_cat_open(cat_name);
53      if(!cat)
54      {
55         std::string m("Unable to open message catalog: ");
56         std::runtime_error err(m + cat_name);
57         ::boost::re_detail::raise_runtime_error(err);
58      }
59   }
60   //
61   // if we have a valid catalog then load our messages:
62   //
63   if(cat)
64   {
65      for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
66      {
67         string_type mss = ::boost::re_detail::w32_cat_get(cat, this->m_locale, i, get_default_syntax(i));
68         for(string_type::size_type j = 0; j < mss.size(); ++j)
69         {
70            m_char_map[static_cast<unsigned char>(mss[j])] = i;
71         }
72      }
73   }
74   else
75   {
76      for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
77      {
78         const char* ptr = get_default_syntax(i);
79         while(ptr && *ptr)
80         {
81            m_char_map[static_cast<unsigned char>(*ptr)] = i;
82            ++ptr;
83         }
84      }
85   }
86   //
87   // finish off by calculating our escape types:
88   //
89   unsigned char i = 'A';
90   do
91   {
92      if(m_char_map[i] == 0)
93      {
94         if(::boost::re_detail::w32_is(this->m_locale, 0x0002u, (char)i)) 
95            m_char_map[i] = regex_constants::escape_type_class;
96         else if(::boost::re_detail::w32_is(this->m_locale, 0x0001u, (char)i)) 
97            m_char_map[i] = regex_constants::escape_type_not_class;
98      }
99   }while(0xFF != i++);
100
101   //
102   // fill in lower case map:
103   //
104   char char_map[1 << CHAR_BIT];
105   for(int ii = 0; ii < (1 << CHAR_BIT); ++ii)
106      char_map[ii] = static_cast<char>(ii);
107   int r = ::LCMapStringA(this->m_locale, LCMAP_LOWERCASE, char_map, 1 << CHAR_BIT, this->m_lower_map, 1 << CHAR_BIT);
108   BOOST_ASSERT(r != 0);
109   if(r < (1 << CHAR_BIT))
110   {
111      // if we have multibyte characters then not all may have been given
112      // a lower case mapping:
113      for(int jj = r; jj < (1 << CHAR_BIT); ++jj)
114         this->m_lower_map[jj] = static_cast<char>(jj);
115   }
116   r = ::GetStringTypeExA(this->m_locale, CT_CTYPE1, char_map, 1 << CHAR_BIT, this->m_type_map);
117   BOOST_ASSERT(0 != r);
118}
119
120BOOST_REGEX_DECL lcid_type BOOST_REGEX_CALL w32_get_default_locale()
121{
122   return ::GetUserDefaultLCID();
123}
124
125BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_lower(char c, lcid_type id)
126{
127   WORD mask;
128   if(::GetStringTypeExA(id, CT_CTYPE1, &c, 1, &mask) && (mask & C1_LOWER))
129      return true;
130   return false;
131}
132
133BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_lower(wchar_t c, lcid_type id)
134{
135   WORD mask;
136   if(::GetStringTypeExW(id, CT_CTYPE1, &c, 1, &mask) && (mask & C1_LOWER))
137      return true;
138   return false;
139}
140#ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
141BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_lower(unsigned short ca, lcid_type id)
142{
143   WORD mask;
144   wchar_t c = ca;
145   if(::GetStringTypeExW(id, CT_CTYPE1, &c, 1, &mask) && (mask & C1_LOWER))
146      return true;
147   return false;
148}
149#endif
150
151BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_upper(char c, lcid_type id)
152{
153   WORD mask;
154   if(::GetStringTypeExA(id, CT_CTYPE1, &c, 1, &mask) && (mask & C1_UPPER))
155      return true;
156   return false;
157}
158
159BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_upper(wchar_t c, lcid_type id)
160{
161   WORD mask;
162   if(::GetStringTypeExW(id, CT_CTYPE1, &c, 1, &mask) && (mask & C1_UPPER))
163      return true;
164   return false;
165}
166#ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
167BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_upper(unsigned short ca, lcid_type id)
168{
169   WORD mask;
170   wchar_t c = ca;
171   if(::GetStringTypeExW(id, CT_CTYPE1, &c, 1, &mask) && (mask & C1_UPPER))
172      return true;
173   return false;
174}
175#endif
176
177void free_module(void* mod)
178{
179   ::FreeLibrary(static_cast<HMODULE>(mod));
180}
181
182BOOST_REGEX_DECL cat_type BOOST_REGEX_CALL w32_cat_open(const std::string& name)
183{
184   cat_type result(::LoadLibraryA(name.c_str()), &free_module);
185   return result;
186}
187
188BOOST_REGEX_DECL std::string BOOST_REGEX_CALL w32_cat_get(const cat_type& cat, lcid_type, int i, const std::string& def)
189{
190   char buf[256];
191   if(0 == ::LoadStringA(
192      static_cast<HMODULE>(cat.get()),
193      i,
194      buf,
195      256
196   ))
197   {
198      return def;
199   }
200   return std::string(buf);
201}
202
203#ifndef BOOST_NO_WREGEX
204BOOST_REGEX_DECL std::wstring BOOST_REGEX_CALL w32_cat_get(const cat_type& cat, lcid_type, int i, const std::wstring& def)
205{
206   wchar_t buf[256];
207   if(0 == ::LoadStringW(
208      static_cast<HMODULE>(cat.get()),
209      i,
210      buf,
211      256
212   ))
213   {
214      return def;
215   }
216   return std::wstring(buf);
217}
218#ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
219BOOST_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)
220{
221   unsigned short buf[256];
222   if(0 == ::LoadStringW(
223      static_cast<HMODULE>(cat.get()),
224      i,
225      (LPWSTR)buf,
226      256
227   ))
228   {
229      return def;
230   }
231   return std::basic_string<unsigned short>(buf);
232}
233#endif
234#endif
235BOOST_REGEX_DECL std::string BOOST_REGEX_CALL w32_transform(lcid_type id, const char* p1, const char* p2)
236{
237   int bytes = ::LCMapStringA(
238      id,       // locale identifier
239      LCMAP_SORTKEY,  // mapping transformation type
240      p1,  // source string
241      static_cast<int>(p2 - p1),        // number of characters in source string
242      0,  // destination buffer
243      0        // size of destination buffer
244      );
245   if(!bytes)
246      return std::string(p1, p2);
247   std::string result(++bytes, '\0');
248   bytes = ::LCMapStringA(
249      id,       // locale identifier
250      LCMAP_SORTKEY,  // mapping transformation type
251      p1,  // source string
252      static_cast<int>(p2 - p1),        // number of characters in source string
253      &*result.begin(),  // destination buffer
254      bytes        // size of destination buffer
255      );
256   if(bytes > static_cast<int>(result.size()))
257      return std::string(p1, p2);
258   while(result.size() && result[result.size()-1] == '\0')
259   {
260      result.erase(result.size()-1);
261   }
262   return result;
263}
264
265#ifndef BOOST_NO_WREGEX
266BOOST_REGEX_DECL std::wstring BOOST_REGEX_CALL w32_transform(lcid_type id, const wchar_t* p1, const wchar_t* p2)
267{
268   int bytes = ::LCMapStringW(
269      id,       // locale identifier
270      LCMAP_SORTKEY,  // mapping transformation type
271      p1,  // source string
272      static_cast<int>(p2 - p1),        // number of characters in source string
273      0,  // destination buffer
274      0        // size of destination buffer
275      );
276   if(!bytes)
277      return std::wstring(p1, p2);
278   std::string result(++bytes, '\0');
279   bytes = ::LCMapStringW(
280      id,       // locale identifier
281      LCMAP_SORTKEY,  // mapping transformation type
282      p1,  // source string
283      static_cast<int>(p2 - p1),        // number of characters in source string
284      reinterpret_cast<wchar_t*>(&*result.begin()),  // destination buffer *of bytes*
285      bytes        // size of destination buffer
286      );
287   if(bytes > static_cast<int>(result.size()))
288      return std::wstring(p1, p2);
289   while(result.size() && result[result.size()-1] == L'\0')
290   {
291      result.erase(result.size()-1);
292   }
293   std::wstring r2;
294   for(std::string::size_type i = 0; i < result.size(); ++i)
295      r2.append(1, static_cast<wchar_t>(static_cast<unsigned char>(result[i])));
296   return r2;
297}
298#ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
299BOOST_REGEX_DECL std::basic_string<unsigned short> BOOST_REGEX_CALL w32_transform(lcid_type id, const unsigned short* p1, const unsigned short* p2)
300{
301   int bytes = ::LCMapStringW(
302      id,       // locale identifier
303      LCMAP_SORTKEY,  // mapping transformation type
304      (LPCWSTR)p1,  // source string
305      static_cast<int>(p2 - p1),        // number of characters in source string
306      0,  // destination buffer
307      0        // size of destination buffer
308      );
309   if(!bytes)
310      return std::basic_string<unsigned short>(p1, p2);
311   std::string result(++bytes, '\0');
312   bytes = ::LCMapStringW(
313      id,       // locale identifier
314      LCMAP_SORTKEY,  // mapping transformation type
315      (LPCWSTR)p1,  // source string
316      static_cast<int>(p2 - p1),        // number of characters in source string
317      reinterpret_cast<wchar_t*>(&*result.begin()),  // destination buffer *of bytes*
318      bytes        // size of destination buffer
319      );
320   if(bytes > static_cast<int>(result.size()))
321      return std::basic_string<unsigned short>(p1, p2);
322   while(result.size() && result[result.size()-1] == L'\0')
323   {
324      result.erase(result.size()-1);
325   }
326   std::basic_string<unsigned short> r2;
327   for(std::string::size_type i = 0; i < result.size(); ++i)
328      r2.append(1, static_cast<unsigned short>(static_cast<unsigned char>(result[i])));
329   return r2;
330}
331#endif
332#endif
333BOOST_REGEX_DECL char BOOST_REGEX_CALL w32_tolower(char c, lcid_type id)
334{
335   char result[2];
336   int b = ::LCMapStringA(
337      id,       // locale identifier
338      LCMAP_LOWERCASE,  // mapping transformation type
339      &c,  // source string
340      1,        // number of characters in source string
341      result,  // destination buffer
342      1);        // size of destination buffer
343   if(b == 0)
344      return c;
345   return result[0];
346}
347
348#ifndef BOOST_NO_WREGEX
349BOOST_REGEX_DECL wchar_t BOOST_REGEX_CALL w32_tolower(wchar_t c, lcid_type id)
350{
351   wchar_t result[2];
352   int b = ::LCMapStringW(
353      id,       // locale identifier
354      LCMAP_LOWERCASE,  // mapping transformation type
355      &c,  // source string
356      1,        // number of characters in source string
357      result,  // destination buffer
358      1);        // size of destination buffer
359   if(b == 0)
360      return c;
361   return result[0];
362}
363#ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
364BOOST_REGEX_DECL unsigned short BOOST_REGEX_CALL w32_tolower(unsigned short c, lcid_type id)
365{
366   wchar_t result[2];
367   int b = ::LCMapStringW(
368      id,       // locale identifier
369      LCMAP_LOWERCASE,  // mapping transformation type
370      (wchar_t const*)&c,  // source string
371      1,        // number of characters in source string
372      result,  // destination buffer
373      1);        // size of destination buffer
374   if(b == 0)
375      return c;
376   return result[0];
377}
378#endif
379#endif
380BOOST_REGEX_DECL char BOOST_REGEX_CALL w32_toupper(char c, lcid_type id)
381{
382   char result[2];
383   int b = ::LCMapStringA(
384      id,       // locale identifier
385      LCMAP_UPPERCASE,  // mapping transformation type
386      &c,  // source string
387      1,        // number of characters in source string
388      result,  // destination buffer
389      1);        // size of destination buffer
390   if(b == 0)
391      return c;
392   return result[0];
393}
394
395#ifndef BOOST_NO_WREGEX
396BOOST_REGEX_DECL wchar_t BOOST_REGEX_CALL w32_toupper(wchar_t c, lcid_type id)
397{
398   wchar_t result[2];
399   int b = ::LCMapStringW(
400      id,       // locale identifier
401      LCMAP_UPPERCASE,  // mapping transformation type
402      &c,  // source string
403      1,        // number of characters in source string
404      result,  // destination buffer
405      1);        // size of destination buffer
406   if(b == 0)
407      return c;
408   return result[0];
409}
410#ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
411BOOST_REGEX_DECL unsigned short BOOST_REGEX_CALL w32_toupper(unsigned short c, lcid_type id)
412{
413   wchar_t result[2];
414   int b = ::LCMapStringW(
415      id,       // locale identifier
416      LCMAP_UPPERCASE,  // mapping transformation type
417      (wchar_t const*)&c,  // source string
418      1,        // number of characters in source string
419      result,  // destination buffer
420      1);        // size of destination buffer
421   if(b == 0)
422      return c;
423   return result[0];
424}
425#endif
426#endif
427BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is(lcid_type id, boost::uint32_t m, char c)
428{
429   WORD mask;
430   if(::GetStringTypeExA(id, CT_CTYPE1, &c, 1, &mask) && (mask & m & w32_regex_traits_implementation<char>::mask_base))
431      return true;
432   if((m & w32_regex_traits_implementation<char>::mask_word) && (c == '_'))
433      return true;
434   return false;
435}
436
437#ifndef BOOST_NO_WREGEX
438BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is(lcid_type id, boost::uint32_t m, wchar_t c)
439{
440   WORD mask;
441   if(::GetStringTypeExW(id, CT_CTYPE1, &c, 1, &mask) && (mask & m & w32_regex_traits_implementation<wchar_t>::mask_base))
442      return true;
443   if((m & w32_regex_traits_implementation<wchar_t>::mask_word) && (c == '_'))
444      return true;
445   if((m & w32_regex_traits_implementation<wchar_t>::mask_unicode) && (c > 0xff))
446      return true;
447   return false;
448}
449#ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
450BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is(lcid_type id, boost::uint32_t m, unsigned short c)
451{
452   WORD mask;
453   if(::GetStringTypeExW(id, CT_CTYPE1, (wchar_t const*)&c, 1, &mask) && (mask & m & w32_regex_traits_implementation<wchar_t>::mask_base))
454      return true;
455   if((m & w32_regex_traits_implementation<wchar_t>::mask_word) && (c == '_'))
456      return true;
457   if((m & w32_regex_traits_implementation<wchar_t>::mask_unicode) && (c > 0xff))
458      return true;
459   return false;
460}
461#endif
462#endif
463
464} // re_detail
465} // boost
466
467#endif
468
Note: See TracBrowser for help on using the repository browser.