• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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