## src/posix_api.cpp

72.6% Lines (82/113) 100.0% List of functions (4/4)
posix_api.cpp
f(x) Functions (4)
Function Calls Lines Blocks
regcompA :73 16384x 64.1% 75.0% regerrorA :151 10476x 67.5% 64.0% regexecA :215 16304x 86.2% 89.0% regfreeA :281 16384x 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: posix_api.cpp
15 |  |  | * VERSION: see <boost/version.hpp>
16 |  |  | * DESCRIPTION: Implements the Posix API wrappers.
17 |  |  | */
18 |  |  |
19 |  |  | #define BOOST_REGEX_SOURCE
20 |  |  |
21 |  |  | #include <boost/regex.hpp>
22 |  |  | #include <boost/cregex.hpp>
23 |  |  | #include <cstdio>
24 |  |  |
25 |  |  | #ifndef BOOST_WORKAROUND
26 |  |  | #define BOOST_WORKAROUND(x, y) false
27 |  |  | #endif
28 |  |  |
29 |  |  | #ifndef BOOST_REGEX_STANDALONE
30 |  |  | #include <boost/core/snprintf.hpp>
31 |  |  | #else
32 |  |  | namespace boost { namespace core { using std::snprintf; } }
33 |  |  | #endif
34 |  |  |
35 |  |  | namespace boost{
36 |  |  |
37 |  |  | namespace{
38 |  |  |
39 |  |  | unsigned int magic_value = 25631;
40 |  |  |
41 |  |  | const char* names[] = {
42 |  |  | "REG_NOERROR",
43 |  |  | "REG_NOMATCH",
44 |  |  | "REG_BADPAT",
45 |  |  | "REG_ECOLLATE",
46 |  |  | "REG_ECTYPE",
47 |  |  | "REG_EESCAPE",
48 |  |  | "REG_ESUBREG",
49 |  |  | "REG_EBRACK",
50 |  |  | "REG_EPAREN",
51 |  |  | "REG_EBRACE",
52 |  |  | "REG_BADBR",
53 |  |  | "REG_ERANGE",
54 |  |  | "REG_ESPACE",
55 |  |  | "REG_BADRPT",
56 |  |  | "REG_EEND",
57 |  |  | "REG_ESIZE",
58 |  |  | "REG_ERPAREN",
59 |  |  | "REG_EMPTY",
60 |  |  | "REG_ECOMPLEXITY",
61 |  |  | "REG_ESTACK",
62 |  |  | "REG_E_PERL",
63 |  |  | "REG_E_UNKNOWN",
64 |  |  | };
65 |  |  | } // namespace
66 |  |  |
67 |  |  | typedef boost::basic_regex<char, c_regex_traits<char> > c_regex_type;
68 |  |  |
69 |  |  | #ifdef BOOST_MSVC
70 |  |  | # pragma warning(push)
71 |  |  | #pragma warning(disable:26812)
72 |  |  | #endif
73 |  | 16384x | BOOST_REGEX_DECL int BOOST_REGEX_CCALL regcompA(regex_tA* expression, const char* ptr, int f)
74 |  |  | {
75 |  |  | #ifndef BOOST_NO_EXCEPTIONS
76 |  |  | try{
77 |  |  | #endif
78 |  | 16384x | expression->guts = new c_regex_type();
79 |  |  | #ifndef BOOST_NO_EXCEPTIONS
80 |  | ✗ | } catch(...)
81 |  |  | {
82 |  | ✗ | expression->guts = 0;
83 |  | ✗ | return REG_ESPACE;
84 |  | ✗ | }
85 |  |  | #else
86 |  | 1365x | if(0 == expression->guts)
87 |  | ✗ | return REG_E_MEMORY;
88 |  |  | #endif
89 |  |  | // set default flags:
90 |  | 16384x | unsigned flags = (f & REG_PERLEX) ? 0 : ((f & REG_EXTENDED) ? regex::extended : regex::basic);
91 |  | 16384x | expression->eflags = (f & REG_NEWLINE) ? match_not_dot_newline : match_default;
92 |  |  | // and translate those that are actually set:
93 |  |  |
94 |  | 16384x | if(f & REG_NOCOLLATE)
95 |  |  | {
96 |  | 16382x | flags |= regex::nocollate;
97 |  |  | #ifndef BOOST_REGEX_V3
98 |  | 16382x | flags &= ~regex::collate;
99 |  |  | #endif
100 |  |  | }
101 |  |  |
102 |  | 16384x | if(f & REG_NOSUB)
103 |  |  | {
104 |  |  | //expression->eflags |= match_any;
105 |  | 624x | flags |= regex::nosubs;
106 |  |  | }
107 |  |  |
108 |  | 16384x | if(f & REG_NOSPEC)
109 |  | ✗ | flags |= regex::literal;
110 |  | 16384x | if(f & REG_ICASE)
111 |  | 1176x | flags |= regex::icase;
112 |  | 16384x | if(f & REG_ESCAPE_IN_LISTS)
113 |  | 16384x | flags &= ~regex::no_escape_in_lists;
114 |  | 16384x | if(f & REG_NEWLINE_ALT)
115 |  | ✗ | flags |= regex::newline_alt;
116 |  |  |
117 |  |  | const char* p2;
118 |  | 16384x | if(f & REG_PEND)
119 |  | ✗ | p2 = expression->re_endp;
120 |  | 16384x | else p2 = ptr + std::strlen(ptr);
121 |  |  |
122 |  |  | int result;
123 |  |  |
124 |  |  | #ifndef BOOST_NO_EXCEPTIONS
125 |  |  | try{
126 |  |  | #endif
127 |  | 16384x | expression->re_magic = magic_value;
128 |  | 16384x | static_cast<c_regex_type*>(expression->guts)->set_expression(ptr, p2, flags);
129 |  | 16384x | expression->re_nsub = static_cast<c_regex_type*>(expression->guts)->mark_count();
130 |  | 16384x | result = static_cast<c_regex_type*>(expression->guts)->error_code();
131 |  |  | #ifndef BOOST_NO_EXCEPTIONS
132 |  |  | }
133 |  | ✗ | catch(const boost::regex_error& be)
134 |  |  | {
135 |  | ✗ | result = be.code();
136 |  | ✗ | }
137 |  | ✗ | catch(...)
138 |  |  | {
139 |  | ✗ | result = REG_E_UNKNOWN;
140 |  | ✗ | }
141 |  |  | #endif
142 |  | 16384x | if(result)
143 |  | 2100x | regfreeA(expression);
144 |  | 16384x | return result;
145 |  |  |
146 |  |  | }
147 |  |  | #ifdef BOOST_MSVC
148 |  |  | # pragma warning(pop)
149 |  |  | #endif
150 |  |  |
151 |  | 10476x | BOOST_REGEX_DECL regsize_t BOOST_REGEX_CCALL regerrorA(int code, const regex_tA* e, char* buf, regsize_t buf_size)
152 |  |  | {
153 |  | 10476x | std::size_t result = 0;
154 |  | 10476x | if(code & REG_ITOA)
155 |  |  | {
156 |  | 4200x | code &= ~REG_ITOA;
157 |  | 4200x | if(code <= (int)REG_E_UNKNOWN)
158 |  |  | {
159 |  | 4200x | result = std::strlen(names[code]) + 1;
160 |  | 4200x | if(buf_size >= result)
161 |  | 2100x | BOOST_REGEX_DETAIL_NS::strcpy_s(buf, buf_size, names[code]);
162 |  | 4200x | return result;
163 |  |  | }
164 |  | ✗ | return result;
165 |  |  | }
166 |  | 6276x | if(code == REG_ATOI)
167 |  |  | {
168 |  |  | char localbuf[5];
169 |  | 2100x | if(e == 0)
170 |  | ✗ | return 0;
171 |  | 24384x | for(int i = 0; i <= (int)REG_E_UNKNOWN; ++i)
172 |  |  | {
173 |  | 24384x | if(std::strcmp(e->re_endp, names[i]) == 0)
174 |  |  | {
175 |  |  | //
176 |  |  | // We're converting an integer i to a string, and since i <= REG_E_UNKNOWN
177 |  |  | // a five character string is *always* large enough:
178 |  |  | //
179 |  | 2100x | int r = (boost::core::snprintf)(localbuf, 5, "%d", i);
180 |  | 2100x | if(r < 0)
181 |  | ✗ | return 0; // sprintf failed
182 |  | 2100x | if(std::strlen(localbuf) < buf_size)
183 |  | 2100x | BOOST_REGEX_DETAIL_NS::strcpy_s(buf, buf_size, localbuf);
184 |  | 2100x | return std::strlen(localbuf) + 1;
185 |  |  | }
186 |  |  | }
187 |  | ✗ | int r = (boost::core::snprintf)(localbuf, 5, "%d", 0);
188 |  | ✗ | if(r < 0)
189 |  | ✗ | return 0; // sprintf failed
190 |  | ✗ | if(std::strlen(localbuf) < buf_size)
191 |  | ✗ | BOOST_REGEX_DETAIL_NS::strcpy_s(buf, buf_size, localbuf);
192 |  | ✗ | return std::strlen(localbuf) + 1;
193 |  |  | }
194 |  | 4176x | if(code <= (int)REG_E_UNKNOWN)
195 |  |  | {
196 |  | 4176x | std::string p;
197 |  | 4176x | if((e) && (e->re_magic == magic_value))
198 |  | ✗ | p = static_cast<c_regex_type*>(e->guts)->get_traits().error_string(static_cast< ::boost::regex_constants::error_type>(code));
199 |  |  | else
200 |  |  | {
201 |  | 4176x | p = BOOST_REGEX_DETAIL_NS::get_default_error_string(static_cast< ::boost::regex_constants::error_type>(code));
202 |  |  | }
203 |  | 4176x | std::size_t len = p.size();
204 |  | 4176x | if(len < buf_size)
205 |  |  | {
206 |  | 2076x | BOOST_REGEX_DETAIL_NS::strcpy_s(buf, buf_size, p.c_str());
207 |  |  | }
208 |  | 4176x | return len + 1;
209 |  | 4176x | }
210 |  | ✗ | if(buf_size)
211 |  | ✗ | *buf = 0;
212 |  | ✗ | return 0;
213 |  |  | }
214 |  |  |
215 |  | 16304x | BOOST_REGEX_DECL int BOOST_REGEX_CCALL regexecA(const regex_tA* expression, const char* buf, regsize_t n, regmatch_t* array, int eflags)
216 |  |  | {
217 |  |  | #ifdef BOOST_MSVC
218 |  |  | #pragma warning(push)
219 |  |  | #pragma warning(disable:4267)
220 |  |  | #endif
221 |  | 16304x | bool result = false;
222 |  | 16304x | match_flag_type flags = match_default | expression->eflags;
223 |  |  | const char* end;
224 |  |  | const char* start;
225 |  | 16304x | cmatch m;
226 |  |  |
227 |  | 16304x | if(eflags & REG_NOTBOL)
228 |  | 2x | flags |= match_not_bol;
229 |  | 16304x | if(eflags & REG_NOTEOL)
230 |  | 2x | flags |= match_not_eol;
231 |  | 16304x | if(eflags & REG_STARTEND)
232 |  |  | {
233 |  | 2x | start = buf + array[0].rm_so;
234 |  | 2x | end = buf + array[0].rm_eo;
235 |  |  | }
236 |  |  | else
237 |  |  | {
238 |  | 16302x | start = buf;
239 |  | 16302x | end = buf + std::strlen(buf);
240 |  |  | }
241 |  |  |
242 |  |  | #ifndef BOOST_NO_EXCEPTIONS
243 |  |  | try{
244 |  |  | #endif
245 |  | 16304x | if(expression->re_magic == magic_value)
246 |  |  | {
247 |  | 16304x | result = regex_search(start, end, m, *static_cast<c_regex_type*>(expression->guts), flags);
248 |  |  | }
249 |  |  | else
250 |  | ✗ | return result;
251 |  |  | #ifndef BOOST_NO_EXCEPTIONS
252 |  | ✗ | } catch(...)
253 |  |  | {
254 |  | ✗ | return REG_E_UNKNOWN;
255 |  | ✗ | }
256 |  |  | #endif
257 |  |  |
258 |  | 16304x | if(result)
259 |  |  | {
260 |  |  | // extract what matched:
261 |  |  | std::size_t i;
262 |  | 38881x | for(i = 0; (i < n) && (i < expression->re_nsub + 1); ++i)
263 |  |  | {
264 |  | 25637x | array[i].rm_so = m[i].matched ? (m[i].first - buf) : -1;
265 |  | 25637x | array[i].rm_eo = m[i].matched ? (m[i].second - buf) : -1;
266 |  |  | }
267 |  |  | // and set anything else to -1:
268 |  | 1114664x | for(i = expression->re_nsub + 1; i < n; ++i)
269 |  |  | {
270 |  | 1101420x | array[i].rm_so = -1;
271 |  | 1101420x | array[i].rm_eo = -1;
272 |  |  | }
273 |  | 13244x | return 0;
274 |  |  | }
275 |  | 3060x | return REG_NOMATCH;
276 |  |  | #ifdef BOOST_MSVC
277 |  |  | #pragma warning(pop)
278 |  |  | #endif
279 |  | 16304x | }
280 |  |  |
281 |  | 16384x | BOOST_REGEX_DECL void BOOST_REGEX_CCALL regfreeA(regex_tA* expression)
282 |  |  | {
283 |  | 16384x | if(expression->re_magic == magic_value)
284 |  |  | {
285 |  | 16384x | delete static_cast<c_regex_type*>(expression->guts);
286 |  |  | }
287 |  | 16384x | expression->re_magic = 0;
288 |  | 16384x | }
289 |  |  |
290 |  |  | } // namespace boost
291 |  |  |