• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  * Copyright (c) 1998-2002
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:        wide_posix_api.cpp
15   *   VERSION:     see <boost/version.hpp>
16   *   DESCRIPTION: Implements the wide character POSIX API wrappers.
17   */
18 
19 #define BOOST_REGEX_SOURCE
20 
21 #include <boost/regex/config.hpp>
22 
23 #ifndef BOOST_NO_WREGEX
24 
25 #include <boost/regex.hpp>
26 #include <boost/cregex.hpp>
27 
28 #include <cwchar>
29 #include <cstring>
30 #include <cstdio>
31 
32 #ifdef BOOST_INTEL
33 #pragma warning(disable:981)
34 #endif
35 
36 #if defined(BOOST_NO_STDC_NAMESPACE) || defined(__NetBSD__)
37 namespace std{
38 #  ifndef BOOST_NO_SWPRINTF
39       using ::swprintf;
40 #  endif
41 }
42 #endif
43 
44 
45 namespace boost{
46 
47 namespace {
48 
49 unsigned int wmagic_value = 28631;
50 
51 const wchar_t* wnames[] = {
52       L"REG_NOERROR",
53       L"REG_NOMATCH",
54       L"REG_BADPAT",
55       L"REG_ECOLLATE",
56       L"REG_ECTYPE",
57       L"REG_EESCAPE",
58       L"REG_ESUBREG",
59       L"REG_EBRACK",
60       L"REG_EPAREN",
61       L"REG_EBRACE",
62       L"REG_BADBR",
63       L"REG_ERANGE",
64       L"REG_ESPACE",
65       L"REG_BADRPT",
66       L"REG_EEND",
67       L"REG_ESIZE",
68       L"REG_ERPAREN",
69       L"REG_EMPTY",
70       L"REG_ECOMPLEXITY",
71       L"REG_ESTACK",
72       L"REG_E_PERL",
73       L"REG_E_UNKNOWN",
74 };
75 }
76 
77 typedef boost::basic_regex<wchar_t, c_regex_traits<wchar_t> > wc_regex_type;
78 
79 #ifdef BOOST_MSVC
80 #  pragma warning(push)
81 #pragma warning(disable:26812)
82 #endif
regcompW(regex_tW * expression,const wchar_t * ptr,int f)83 BOOST_REGEX_DECL int BOOST_REGEX_CCALL regcompW(regex_tW* expression, const wchar_t* ptr, int f)
84 {
85 #ifndef BOOST_NO_EXCEPTIONS
86    try{
87 #endif
88       expression->guts = new wc_regex_type();
89 #ifndef BOOST_NO_EXCEPTIONS
90    } catch(...)
91    {
92       expression->guts = 0;
93       return REG_ESPACE;
94    }
95 #else
96    if(0 == expression->guts)
97       return REG_E_MEMORY;
98 #endif
99    // set default flags:
100    boost::uint_fast32_t flags = (f & REG_PERLEX) ? 0 : ((f & REG_EXTENDED) ? wregex::extended : wregex::basic);
101    expression->eflags = (f & REG_NEWLINE) ? match_not_dot_newline : match_default;
102 
103    // and translate those that are actually set:
104    if(f & REG_NOCOLLATE)
105    {
106       flags |= wregex::nocollate;
107 #ifndef BOOST_REGEX_V3
108       flags &= ~wregex::collate;
109 #endif
110    }
111 
112    if(f & REG_NOSUB)
113    {
114       //expression->eflags |= match_any;
115       flags |= wregex::nosubs;
116    }
117 
118    if(f & REG_NOSPEC)
119       flags |= wregex::literal;
120    if(f & REG_ICASE)
121       flags |= wregex::icase;
122    if(f & REG_ESCAPE_IN_LISTS)
123       flags &= ~wregex::no_escape_in_lists;
124    if(f & REG_NEWLINE_ALT)
125       flags |= wregex::newline_alt;
126 
127    const wchar_t* p2;
128    if(f & REG_PEND)
129       p2 = expression->re_endp;
130    else p2 = ptr + std::wcslen(ptr);
131 
132    int result;
133 
134 #ifndef BOOST_NO_EXCEPTIONS
135    try{
136 #endif
137       expression->re_magic = wmagic_value;
138       static_cast<wc_regex_type*>(expression->guts)->set_expression(ptr, p2, flags);
139       expression->re_nsub = static_cast<wc_regex_type*>(expression->guts)->mark_count();
140       result = static_cast<wc_regex_type*>(expression->guts)->error_code();
141 #ifndef BOOST_NO_EXCEPTIONS
142    }
143    catch(const boost::regex_error& be)
144    {
145       result = be.code();
146    }
147    catch(...)
148    {
149       result = REG_E_UNKNOWN;
150    }
151 #endif
152    if(result)
153       regfreeW(expression);
154    return result;
155 
156 }
157 #ifdef BOOST_MSVC
158 #  pragma warning(pop)
159 #endif
160 
regerrorW(int code,const regex_tW * e,wchar_t * buf,regsize_t buf_size)161 BOOST_REGEX_DECL regsize_t BOOST_REGEX_CCALL regerrorW(int code, const regex_tW* e, wchar_t* buf, regsize_t buf_size)
162 {
163    std::size_t result = 0;
164    if(code & REG_ITOA)
165    {
166       code &= ~REG_ITOA;
167       if((code <= (int)REG_E_UNKNOWN) && (code >= 0))
168       {
169          result = std::wcslen(wnames[code]) + 1;
170          if(buf_size >= result)
171 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(_WIN32_WCE) && !defined(UNDER_CE)
172             ::wcscpy_s(buf, buf_size, wnames[code]);
173 #else
174             std::wcscpy(buf, wnames[code]);
175 #endif
176          return result;
177       }
178       return result;
179    }
180 #if !defined(BOOST_NO_SWPRINTF)
181    if(code == REG_ATOI)
182    {
183       wchar_t localbuf[5];
184       if(e == 0)
185          return 0;
186       for(int i = 0; i <= (int)REG_E_UNKNOWN; ++i)
187       {
188          if(std::wcscmp(e->re_endp, wnames[i]) == 0)
189          {
190 #if defined(_WIN32_WCE) && !defined(UNDER_CE)
191             (std::swprintf)(localbuf, L"%d", i);
192 #else
193             (std::swprintf)(localbuf, 5, L"%d", i);
194 #endif
195             if(std::wcslen(localbuf) < buf_size)
196 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(_WIN32_WCE) && !defined(UNDER_CE)
197                ::wcscpy_s(buf, buf_size, localbuf);
198 #else
199                std::wcscpy(buf, localbuf);
200 #endif
201             return std::wcslen(localbuf) + 1;
202          }
203       }
204 #if defined(_WIN32_WCE) && !defined(UNDER_CE)
205       (std::swprintf)(localbuf, L"%d", 0);
206 #else
207       (std::swprintf)(localbuf, 5, L"%d", 0);
208 #endif
209       if(std::wcslen(localbuf) < buf_size)
210 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(_WIN32_WCE) && !defined(UNDER_CE)
211          ::wcscpy_s(buf, buf_size, localbuf);
212 #else
213          std::wcscpy(buf, localbuf);
214 #endif
215       return std::wcslen(localbuf) + 1;
216    }
217 #endif
218    if(code <= (int)REG_E_UNKNOWN)
219    {
220       std::string p;
221       if((e) && (e->re_magic == wmagic_value))
222          p = static_cast<wc_regex_type*>(e->guts)->get_traits().error_string(static_cast< ::boost::regex_constants::error_type>(code));
223       else
224       {
225          p = BOOST_REGEX_DETAIL_NS::get_default_error_string(static_cast< ::boost::regex_constants::error_type>(code));
226       }
227       std::size_t len = p.size();
228       if(len < buf_size)
229       {
230          BOOST_REGEX_DETAIL_NS::copy(p.c_str(), p.c_str() + p.size() + 1, buf);
231       }
232       return len + 1;
233    }
234    if(buf_size)
235       *buf = 0;
236    return 0;
237 }
238 
regexecW(const regex_tW * expression,const wchar_t * buf,regsize_t n,regmatch_t * array,int eflags)239 BOOST_REGEX_DECL int BOOST_REGEX_CCALL regexecW(const regex_tW* expression, const wchar_t* buf, regsize_t n, regmatch_t* array, int eflags)
240 {
241 #ifdef BOOST_MSVC
242 #pragma warning(push)
243 #pragma warning(disable:4267)
244 #endif
245    bool result = false;
246    match_flag_type flags = match_default | expression->eflags;
247    const wchar_t* end;
248    const wchar_t* start;
249    wcmatch m;
250 
251    if(eflags & REG_NOTBOL)
252       flags |= match_not_bol;
253    if(eflags & REG_NOTEOL)
254       flags |= match_not_eol;
255    if(eflags & REG_STARTEND)
256    {
257       start = buf + array[0].rm_so;
258       end = buf + array[0].rm_eo;
259    }
260    else
261    {
262       start = buf;
263       end = buf + std::wcslen(buf);
264    }
265 
266 #ifndef BOOST_NO_EXCEPTIONS
267    try{
268 #endif
269    if(expression->re_magic == wmagic_value)
270    {
271       result = regex_search(start, end, m, *static_cast<wc_regex_type*>(expression->guts), flags);
272    }
273    else
274       return result;
275 #ifndef BOOST_NO_EXCEPTIONS
276    } catch(...)
277    {
278       return REG_E_UNKNOWN;
279    }
280 #endif
281    if(result)
282    {
283       // extract what matched:
284       std::size_t i;
285       for(i = 0; (i < n) && (i < expression->re_nsub + 1); ++i)
286       {
287          array[i].rm_so = (m[i].matched == false) ? -1 : (m[i].first - buf);
288          array[i].rm_eo = (m[i].matched == false) ? -1 : (m[i].second - buf);
289       }
290       // and set anything else to -1:
291       for(i = expression->re_nsub + 1; i < n; ++i)
292       {
293          array[i].rm_so = -1;
294          array[i].rm_eo = -1;
295       }
296       return 0;
297    }
298    return REG_NOMATCH;
299 #ifdef BOOST_MSVC
300 #pragma warning(pop)
301 #endif
302 }
303 
regfreeW(regex_tW * expression)304 BOOST_REGEX_DECL void BOOST_REGEX_CCALL regfreeW(regex_tW* expression)
305 {
306    if(expression->re_magic == wmagic_value)
307    {
308       delete static_cast<wc_regex_type*>(expression->guts);
309    }
310    expression->re_magic = 0;
311 }
312 
313 } // namespace boost;
314 
315 #endif
316 
317 
318 
319 
320