1 ///////////////////////////////////////////////////////////////
2 // Copyright 2015 John Maddock. Distributed under the Boost
3 // Software License, Version 1.0. (See accompanying file
4 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_
5 //
6
7 #ifdef TEST_POSIX
8
9 #include "performance.hpp"
10 #include <boost/lexical_cast.hpp>
11
12 #include <regex.h>
13
14 struct posix_regex : public abstract_regex
15 {
16 private:
17 regex_t pe, pe2;
18 bool init;
19 public:
posix_regexposix_regex20 posix_regex() : init(false) {}
~posix_regexposix_regex21 ~posix_regex()
22 {
23 if(init)
24 {
25 regfree(&pe);
26 regfree(&pe2);
27 }
28 }
set_expressionposix_regex29 virtual bool set_expression(const char* pat, bool isperl)
30 {
31 if(isperl)
32 return false;
33 if(init)
34 {
35 regfree(&pe);
36 regfree(&pe2);
37 }
38 else
39 init = true;
40 int r = regcomp(&pe, pat, REG_EXTENDED);
41 std::string s(pat);
42 if(s.size() && (s[0] != '^'))
43 s.insert(0, 1, '^');
44 if(s.size() && (*s.rbegin() != '$'))
45 s.append("$");
46 r |= regcomp(&pe2, s.c_str(), REG_EXTENDED);
47 return r ? false : true;
48 }
49 virtual bool match_test(const char* text);
50 virtual unsigned find_all(const char* text);
51 virtual std::string name();
52
53 struct initializer
54 {
initializerposix_regex::initializer55 initializer()
56 {
57 posix_regex::register_instance(boost::shared_ptr<abstract_regex>(new posix_regex));
58 }
do_nothingposix_regex::initializer59 void do_nothing()const {}
60 };
61 static const initializer init2;
62 };
63
64 const posix_regex::initializer posix_regex::init2;
65
66
match_test(const char * text)67 bool posix_regex::match_test(const char * text)
68 {
69 regmatch_t m[30];
70 int r = regexec(&pe2, text, 30, m, 0);
71 return r == 0;
72 }
73
find_all(const char * text)74 unsigned posix_regex::find_all(const char * text)
75 {
76 unsigned count = 0;
77 regmatch_t m[30];
78 int flags = 0;
79 while(regexec(&pe, text, 30, m, flags) == 0)
80 {
81 ++count;
82 text += m[0].rm_eo;
83 if(m[0].rm_eo - m[0].rm_so)
84 flags = *(text - 1) == '\n' ? 0 : REG_NOTBOL;
85 else
86 flags = 0;
87 }
88 return 0;
89 }
90
name()91 std::string posix_regex::name()
92 {
93 init2.do_nothing();
94 return "POSIX";
95 }
96
97 #endif
98