## src/wide_posix_api.cpp

74.3% Lines (81/109) 100.0% List of functions (4/4)
wide_posix_api.cpp
f(x) Functions (4)
Function Calls Lines Blocks
regcompW :85 16597x 64.1% 75.0% regerrorW :163 10476x 72.2% 70.0% regexecW :227 14497x 86.2% 89.0% regfreeW :292 16597x 100.0% 100.0%

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