Imported Upstream version 17.12.0
[platform/upstream/libzypp.git] / zypp / base / Regex.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/base/Regex.cc
10  *
11 */
12 #include <cstdio>
13 #include <cstdarg>
14
15 #include <iostream>
16
17 #include "zypp/base/Regex.h"
18
19 using namespace zypp;
20 using namespace zypp::str;
21
22 regex::regex()
23   : m_flags(match_extended)
24   , m_valid(false)
25 {
26
27 }
28
29 void regex::assign(const std::string& str,int flags)
30 {
31   m_valid = true;
32   m_str = str;
33   m_flags = flags;
34   int err;
35   char errbuff[100];
36   static const int normal = 1<<16; // deprecated legacy, use match_extended
37   if (!(flags & normal)) {
38     flags |= match_extended;
39     flags &= ~(normal);
40   }
41
42   if ((err = regcomp(&m_preg, str.c_str(), flags))) {
43     m_valid = false;
44     regerror(err, &m_preg, errbuff, sizeof(errbuff));
45     ZYPP_THROW(regex_error(std::string(errbuff)));
46   }
47 }
48
49 regex::regex(const std::string& str, int flags)
50 {
51   assign(str, flags);
52 }
53
54 regex::~regex() throw()
55 {
56   if (m_valid)
57     regfree(&m_preg);
58 }
59
60 bool zypp::str::regex_match(const char * s, smatch& matches, const regex& regex)
61 {
62   bool r = s && regex.m_valid && !regexec(&regex.m_preg, s, 12, &matches.pmatch[0], 0);
63   if (r)
64     matches.match_str = s;
65   return r;
66 }
67
68 bool zypp::str::regex_match(const char * s,  const regex& regex)
69 {
70   return s && !regexec(&regex.m_preg, s, 0, NULL, 0);
71 }
72
73 smatch::smatch()
74 {
75   memset(&pmatch, -1, sizeof(pmatch));
76 }
77
78 std::string smatch::operator[](unsigned i) const
79 {
80   if ( i < sizeof(pmatch)/sizeof(*pmatch) && pmatch[i].rm_so != -1 )
81     return match_str.substr( pmatch[i].rm_so, pmatch[i].rm_eo-pmatch[i].rm_so );
82
83   return std::string();
84 }
85
86 std::string::size_type smatch::begin( unsigned i ) const
87 { return( i < sizeof(pmatch)/sizeof(*pmatch) && pmatch[i].rm_so != -1 ? pmatch[i].rm_so : std::string::npos ); }
88
89 std::string::size_type smatch::end( unsigned i ) const
90 { return( i < sizeof(pmatch)/sizeof(*pmatch) && pmatch[i].rm_so != -1 ? pmatch[i].rm_eo : std::string::npos ); }
91
92 std::string::size_type smatch::size( unsigned i ) const
93 { return( i < sizeof(pmatch)/sizeof(*pmatch) && pmatch[i].rm_so != -1 ? pmatch[i].rm_eo-pmatch[i].rm_so : std::string::npos ); }
94
95 unsigned smatch::size() const
96 {
97   unsigned matches = unsigned(-1);
98   // Get highest (pmatch[i].rm_so != -1). Just looking for the 1st
99   // (pmatch[i].rm_so == -1) is wrong as optional mayches "()?"
100   // may be embeded.
101   for ( unsigned i = 0; i < sizeof(pmatch)/sizeof(*pmatch); ++i )
102   {
103     if ( pmatch[i].rm_so != -1 )
104       matches = i;
105   }
106   return ++matches;
107 }