Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/regex/src/w32_regex_traits.cpp @ 33

Last change on this file since 33 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

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