ucommon  7.0.0
About: GNU uCommon C++ is a portable and optimized class framework for writing C++ applications that need to use threads and support concurrent synchronization, and that use sockets, XML parsing, object serialization, thread-optimized string and data structure classes, etc..
  Fossies Dox: ucommon-7.0.0.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

regex.cpp
Go to the documentation of this file.
1 // Copyright (C) 2006-2014 David Sugar, Tycho Softworks.
2 // Copyright (C) 2015 Cherokees of Idaho.
3 //
4 // This file is part of GNU uCommon C++.
5 //
6 // GNU uCommon C++ is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU Lesser General Public License as published
8 // by the Free Software Foundation, either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // GNU uCommon C++ is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public License
17 // along with GNU uCommon C++. If not, see <http://www.gnu.org/licenses/>.
18 
19 #include <ucommon-config.h>
20 #include <ucommon/export.h>
21 #include <ucommon/string.h>
22 #include <ucommon/memory.h>
23 #include <stdarg.h>
24 #include <ctype.h>
25 #include <stdio.h>
26 #ifdef HAVE_FCNTL_H
27 #include <fcntl.h>
28 #endif
29 #include <limits.h>
30 #ifdef HAVE_REGEX_H
31 #include <regex.h>
32 #endif
33 
34 namespace ucommon {
35 
36 String::regex::regex(const char *pattern, size_t size)
37 {
38 #ifdef HAVE_REGEX_H
39  regex_t *r = (regex_t *)malloc(sizeof(regex_t));
40  if(regcomp(r, pattern, 0)) {
41  regfree(r);
42  free(r);
43  r = NULL;
44  }
45  object = r;
46  count = size;
47  results = (regmatch_t *)malloc(sizeof(regmatch_t) * size);
48 #else
49  object = results = NULL;
50  count = 0;
51 #endif
52 }
53 
55 {
56 #ifdef HAVE_REGEX_H
57  count = size;
58  results = (regmatch_t *)malloc(sizeof(regmatch_t) * size);
59  object = NULL;
60 #else
61  object = results = NULL;
62  count = 0;
63 #endif
64 }
65 
67 {
68 #ifdef HAVE_REGEX_H
69  if(object) {
70  regfree((regex_t *)object);
71  free(object);
72  }
73  regex_t *r = (regex_t *)malloc(sizeof(regex_t));
74  if(regcomp(r, pattern, 0)) {
75  regfree(r);
76  free(r);
77  r = NULL;
78  }
79  object = r;
80 #endif
81  return *this;
82 }
83 
84 bool String::regex::operator*=(const char *text)
85 {
86  return match(text);
87 }
88 
90 {
91 #ifdef HAVE_REGEX_H
92  if(object) {
93  regfree((regex_t *)object);
94  free(object);
95  }
96  if(results)
97  free(results);
98  object = results = NULL;
99 #endif
100 }
101 
102 size_t String::regex::offset(unsigned member)
103 {
104 #ifdef HAVE_REGEX_H
105  if(!results)
106  return (size_t)-1;
107 
108  regmatch_t *r = (regmatch_t *)results;
109 
110  if(member >= count)
111  return (size_t)-1;
112  return (size_t)r[member].rm_so;
113 #else
114  return (size_t)-1;
115 #endif
116 }
117 
118 size_t String::regex::size(unsigned member)
119 {
120 #ifdef HAVE_REGEX_H
121  if(!results)
122  return 0;
123 
124  regmatch_t *r = (regmatch_t *)results;
125 
126  if(member >= count)
127  return (size_t)-1;
128 
129  if(r[member].rm_so == -1)
130  return 0;
131 
132  return (size_t)(r[member].rm_eo - r[member].rm_so);
133 #else
134  return (size_t)0;
135 #endif
136 }
137 
138 bool String::regex::match(const char *text, unsigned mode)
139 {
140 #ifdef HAVE_REGEX_H
141  int flags = 0;
142 
143  if((mode & 0x01) == INSENSITIVE)
144  flags |= REG_ICASE;
145 
146  if(!text || !object || !results)
147  return false;
148 
149  if(regexec((regex_t *)object, text, count, (regmatch_t *)results, flags))
150  return false;
151 
152  return true;
153 #else
154  return false;
155 #endif
156 }
157 
158 const char *String::search(regex& expr, unsigned member, unsigned flags) const
159 {
160  if(!str)
161  return NULL;
162 
163 #ifdef HAVE_REGEX_H
164  if(expr.match(str->text, flags))
165  return NULL;
166 
167  if(member >= expr.members())
168  return NULL;
169 
170  if(expr.size(member) == 0)
171  return NULL;
172 
173  return str->text + expr.offset(member);
174 #else
175  return NULL;
176 #endif
177 }
178 
179 unsigned String::replace(regex& expr, const char *cp, unsigned flags)
180 {
181 #ifdef HAVE_REGEX_H
182  size_t cpl = 0;
183 
184  if(cp)
185  cpl = strlen(cp);
186 
187  if(!str || str->len == 0)
188  return 0;
189 
190  if(expr.match(str->text, flags))
191  return 0;
192 
193  ssize_t adjust = 0;
194  unsigned member = 0;
195 
196  while(member < expr.members()) {
197  ssize_t tcl = expr.size(member);
198  ssize_t offset = (expr.offset(member) + adjust);
199  if(!tcl)
200  break;
201 
202  ++member;
203  cut(offset, tcl);
204  if(cpl) {
205  paste(offset, cp);
206  adjust += (cpl - tcl);
207  }
208  }
209  return member;
210 #else
211  return 0;
212 #endif
213 }
214 
216 {
217  if(search(expr))
218  return true;
219 
220  return false;
221 }
222 
223 unsigned StringPager::split(stringex_t& expr, const char *string, unsigned flags)
224 {
225  strdup_t tmp = String::dup(string);
226  int prior = 0, match = 0;
227  size_t tcl = strlen(string);
228  unsigned count = 0, member = 0;
229 
230  if(!expr.match(string, flags))
231  return 0;
232 
233  while(member < expr.members()) {
234  if(!expr.size(member))
235  break;
236  match = (int)expr.offset(member++);
237  if(match > prior) {
238  tmp[match] = 0;
239  add(tmp + (size_t)prior);
240  ++count;
241  }
242  prior = (int)(match + tcl);
243  }
244  if(tmp[prior]) {
245  add(tmp + (size_t)prior);
246  ++count;
247  }
248  return count;
249 }
250 
251 } // namespace ucommon
ucommon::String::cut
void cut(size_t offset, size_t size=0)
Definition: string.cpp:849
export.h
ucommon::String::offset
size_t offset(const char *pointer) const
Definition: string.cpp:604
ucommon
Definition: access.cpp:23
ucommon::String::regex::match
bool match(const char *text, unsigned flags=0)
Definition: regex.cpp:138
ucommon::String::regex::operator*=
bool operator*=(const char *string)
Definition: regex.cpp:84
ucommon::String::replace
unsigned replace(const char *string, const char *text=NULL, unsigned flags=0)
Definition: string.cpp:477
ucommon::String::str
cstring * str
Definition: string.h:209
ucommon::String::search
const char * search(const char *string, unsigned instance=0, unsigned flags=0) const
Definition: string.cpp:521
ucommon::String::regex::count
size_t count
Definition: string.h:103
ucommon::String::regex::operator=
regex & operator=(const char *string)
Definition: regex.cpp:66
ucommon::strdup_t
Definition: string.h:1750
ucommon::String::cstring::text
char text[1]
Definition: string.h:146
ucommon::String::cstring::len
size_t len
Definition: string.h:145
ucommon::String::INSENSITIVE
Definition: string.h:95
ucommon::String::size
size_t size(void) const
Definition: string.cpp:137
ucommon::StringPager::member
Definition: memory.h:423
ucommon::String::regex::offset
size_t offset(unsigned member)
Definition: regex.cpp:102
ucommon::StringPager::split
unsigned split(const char *text, const char *string, unsigned flags=0)
Definition: memory.cpp:555
ucommon::String::regex
Definition: string.h:98
ucommon::String::regex::regex
regex(const char *pattern, size_t size=1)
Definition: regex.cpp:36
ucommon::String::regex::results
void * results
Definition: string.h:102
ucommon::String::add
void add(const char *text)
Definition: string.cpp:992
string.h
ucommon::String::regex::size
size_t size(unsigned member)
Definition: regex.cpp:118
ucommon::String::regex::~regex
~regex()
Definition: regex.cpp:89
ucommon::String::regex::members
size_t members(void) const
Definition: string.h:115
ucommon::String::paste
void paste(size_t offset, const char *text, size_t size=0)
Definition: string.cpp:818
ucommon::String::dup
static char * dup(const char *text)
Definition: string.cpp:1390
ucommon::String::operator*=
bool operator*=(const char *substring)
Definition: string.cpp:1097
ucommon::String::count
size_t count(void) const
Definition: string.cpp:618
memory.h