cis_config: /root/cis_interface/cis_interface/cis_interface/regex/regex_posix.h Source File

cis_config

regex_posix.h
1
2 #ifndef REGEX_POSIX_H_
3 #define REGEX_POSIX_H_
4
5 #include <regex.h>
6 #include <stdint.h>
7
8 #ifdef __cplusplus /* If this is a C++ compiler, use C linkage */
9 extern "C" {
10 #endif
11
20 static inline
21 int compile_regex (regex_t * r, const char * regex_text)
22 {
23 int status = regcomp (r, regex_text, REG_EXTENDED);//|REG_NEWLINE);
24 if (status != 0) {
25 char error_message[2048];
26 regerror (status, r, error_message, 2048);
27 printf ("Regex error compiling '%s': %s\n",
28 regex_text, error_message);
29 return 1;
30 }
31 return 0;
32 };
33
43 static inline
44 int count_matches(const char *regex_text, const char *to_match) {
45 int ret;
46 int n_match = 0;
47 regex_t r;
48 // Compile
49 ret = compile_regex(&r, regex_text);
50 if (ret)
51 return -1;
52 // Loop until string done
53 const char * p = to_match;
54 const size_t n_sub_matches = 10;
55 regmatch_t m[n_sub_matches];
56 while (1) {
57 int nomatch = regexec(&r, p, n_sub_matches, m, 0);
58 if (nomatch)
59 break;
60 n_match++;
61 p += m[0].rm_eo;
62 }
63 regfree(&r);
64 return n_match;
65 };
66
67
79 static inline
80 int find_match(const char *regex_text, const char *to_match,
81 size_t *sind, size_t *eind) {
82 int ret;
83 int n_match = 0;
84 regex_t r;
85 // Compile
86 ret = compile_regex(&r, regex_text);
87 if (ret)
88 return -1;
89 // Loop until string done
90 const char * p = to_match;
91 const size_t n_sub_matches = 10;
92 regmatch_t m[n_sub_matches];
93 int nomatch = regexec(&r, p, n_sub_matches, m, 0);
94 if (!(nomatch)) {
95 *sind = m[0].rm_so;
96 *eind = m[0].rm_eo;
97 n_match++;
98 }
99 regfree(&r);
100 return n_match;
101 };
102
103
115 static inline
116 int find_matches(const char *regex_text, const char *to_match,
117 size_t **sind, size_t **eind) {
118 int ret;
119 int n_match = 0;
120 regex_t r;
121 // Compile
122 ret = compile_regex(&r, regex_text);
123 if (ret)
124 return -1;
125 // Loop until string done
126 const size_t n_sub_matches = 50;
127 regmatch_t m[n_sub_matches];
128 int nomatch = regexec(&r, to_match, n_sub_matches, m, 0);
129 if (!(nomatch)) {
130 // Count
131 while (n_match < n_sub_matches) {
132 if ((m[n_match].rm_so == -1) && (m[n_match].rm_eo == -1)) {
133 break;
134 }
135 n_match++;
136 }
137 // Realloc
138 *sind = (size_t*)realloc(*sind, n_match*sizeof(size_t));
139 *eind = (size_t*)realloc(*eind, n_match*sizeof(size_t));
140 // Record
141 int i;
142 for (i = 0; i < n_match; i++) {
143 (*sind)[i] = m[i].rm_so;
144 (*eind)[i] = m[i].rm_eo;
145 }
146 }
147 regfree(&r);
148 return n_match;
149 };
150
151
165 static inline
166 int regex_replace_nosub(char *buf, const size_t len_buf,
167 const char *re, const char *rp,
168 const size_t nreplace) {
169 /* printf("regex_replace_nosub(%s, %s, %s)\n", buf, re, rp); */
170 // Compile
171 regex_t r;
172 int ret = compile_regex(&r, re);
173 if (ret)
174 return -1;
175 // Loop making replacements
176 size_t len_rp = strlen(rp);
177 char * p = buf;
178 const size_t ngroups = r.re_nsub + 1;
179 regmatch_t *m = (regmatch_t*)malloc(ngroups * sizeof(regmatch_t));
180 size_t len_m, rem_s, rem_l, delta_siz;
181 size_t cur_pos = 0;
182 size_t cur_siz = strlen(buf);
183 size_t creplace = 0;
184 while (1) {
185 if ((nreplace > 0) && (creplace >= nreplace)) {
186 printf("regex_replace_nosub: Maximum of %d replacements reached\n",
187 (int)creplace);
188 break;
189 }
190 int nomatch = regexec(&r, p, ngroups, m, 0);
191 if (nomatch) {
192 /* printf("regex_replace_nosub: nomatch for %s in %s\n", re, p); */
193 break;
194 }
195 // Ensure replacement will not exceed buffer
196 len_m = m[0].rm_eo - m[0].rm_so;
197 delta_siz = len_rp - len_m;
198 if ((cur_siz + delta_siz + 1) > len_buf) {
199 printf("regex_replace_nosub: Relacement will exceed buffer.\n");
200 cur_siz = -1;
201 break;
202 }
203 // Move trailing
204 rem_l = cur_siz - (cur_pos + m[0].rm_eo);
205 rem_s = m[0].rm_so + len_rp;
206 memmove(p + rem_s, p + m[0].rm_eo, rem_l + 1);
207 // Copy replacement
208 strncpy(p + m[0].rm_so, rp, len_rp);
209 // Advance
210 p += rem_s;
211 cur_pos += rem_s;
212 cur_siz += delta_siz;
213 creplace += 1;
214 }
215 /* printf("regex_replace_nosub() = %s\n", buf); */
216 free(m);
217 regfree(&r);
218 return cur_siz;
219 };
220
221
231 static inline
232 int get_subrefs(const char *buf, size_t **refs) {
233 // Compile
234 regex_t r;
235 int ret = compile_regex(&r, "\\$([[:digit:]])");
236 if (ret)
237 return -1;
238 // Allocate;
239 const size_t ngroups = r.re_nsub + 1;
240 if (ngroups != 2) {
241 printf("ERROR: regex could not find subgroup\n");
242 regfree(&r);
243 return -1;
244 }
245 regmatch_t *m = (regmatch_t*)malloc(ngroups * sizeof(regmatch_t));
246 // Prepare "bitmap"
247 const size_t max_ref = 10; //99;
248 size_t i;
249 uint8_t *ref_bytes = (uint8_t*)malloc((max_ref + 1)*sizeof(uint8_t));
250 for (i = 0; i <= max_ref; i++)
251 ref_bytes[i] = 0;
252 // Locate matches
253 const char *p = buf;
254 const size_t max_grp = 2; // Digits in max_ref
255 size_t igrp_len;
256 char igrp[max_grp];
257 size_t iref;
258 while (1) {
259 int nomatch = regexec(&r, p, ngroups, m, 0);
260 if (nomatch) {
261 break;
262 }
263 // Lone $ without digit
264 /* printf("so = %d, eo = %d\n", m[1].rm_so, m[1].rm_eo); */
265 if ((m[1].rm_so == -1) && (m[1].rm_eo == -1)) {
266 p += m[0].rm_eo;
267 continue;
268 }
269 // Substring
270 igrp_len = m[1].rm_eo - m[1].rm_so;
271 if (igrp_len > max_grp) {
272 printf("Number longer than %d digits unlikely.\n", (int)max_grp);
273 free(m);
274 free(ref_bytes);
275 regfree(&r);
276 return -1;
277 }
278 strncpy(igrp, p + m[1].rm_so, igrp_len);
279 igrp[igrp_len] = 0;
280 // Extract ref number
281 iref = atoi(igrp);
282 if (iref > max_ref) {
283 printf("Reference to substr %d exceeds limit (%d)\n",
284 (int)iref, (int)max_ref);
285 free(m);
286 free(ref_bytes);
287 regfree(&r);
288 return -1;
289 }
290 ref_bytes[iref] = 1;
291 p += m[0].rm_eo;
292 }
293 // Get unique refs
294 int nref = 0;
295 for (i = 0; i <= max_ref; i++) {
296 if (ref_bytes[i])
297 nref++;
298 }
299 *refs = (size_t*)realloc(*refs, nref*sizeof(size_t));
300 size_t ir;
301 for (i = 0, ir = 0; i <= max_ref; i++) {
302 if (ref_bytes[i]) {
303 (*refs)[ir] = i;
304 ir++;
305 }
306 }
307 free(m);
308 free(ref_bytes);
309 regfree(&r);
310 // printf("%d refs in %s\n", nref, buf);
311 return nref;
312 };
313
314
328 static inline
329 int regex_replace_sub(char *buf, const size_t len_buf,
330 const char *re, const char *rp,
331 const size_t nreplace) {
332 // Compile
333 regex_t r;
334 int ret = compile_regex(&r, re);
335 if (ret)
336 return -1;
337 // Loop making replacements
338 char * p = buf;
339 const size_t ngroups = r.re_nsub + 1;
340 regmatch_t *m = (regmatch_t*)malloc(ngroups * sizeof(regmatch_t));
341 char rp_sub[2*len_buf];
342 char re_sub[len_buf];
343 char igrp[len_buf];
344 size_t len_m, rem_s, rem_l, delta_siz, len_rp;
345 size_t cur_pos = 0;
346 size_t cur_siz = strlen(buf);
347 size_t creplace = 0;
348 size_t i;
349 int j;
350 while (1) {
351 if ((nreplace > 0) && (creplace >= nreplace)) {
352 printf("regex_replace_nosub: Maximum of %d replacements reached\n",
353 (int)creplace);
354 break;
355 }
356 int nomatch = regexec(&r, p, ngroups, m, 0);
357 if (nomatch) {
358 /* printf("regex_replace_sub: nomatch for %s in %s\n", re, p); */
359 break;
360 }
361 // Get list of subrefs
362 size_t *refs = NULL;
363 int nref = get_subrefs(rp, &refs);
364 if (nref < 0) {
365 printf("Error gettings subrefs\n");
366 free(m);
367 regfree(&r);
368 return -1;
369 }
370 // For each subref complete replacements
371 strcpy(rp_sub, rp);
372 for (j = 0; j < nref; j++) {
373 i = refs[j];
374 strcpy(igrp, p + m[i].rm_so);
375 igrp[m[i].rm_eo - m[i].rm_so] = 0; // terminate
376 sprintf(re_sub, "\\$%d", (int)i);
377 ret = regex_replace_nosub(rp_sub, 2*len_buf, re_sub, igrp, 0);
378 if (ret < 0) {
379 printf("regex_replace_sub: Error replacing substring $%d.\n", (int)i);
380 free(m);
381 regfree(&r);
382 return -1;
383 }
384 }
385 // Ensure replacement will not exceed buffer
386 len_rp = ret;
387 len_m = m[0].rm_eo - m[0].rm_so;
388 delta_siz = len_rp - len_m;
389 if ((cur_siz + delta_siz + 1) > len_buf) {
390 printf("regex_replace_sub: Relacement will exceed buffer.\n");
391 free(m);
392 regfree(&r);
393 return -1;
394 }
395 // Move trailing
396 rem_l = cur_siz - (cur_pos + m[0].rm_eo);
397 rem_s = m[0].rm_so + len_rp;
398 memmove(p + rem_s, p + m[0].rm_eo, rem_l + 1);
399 // Copy replacement
400 strncpy(p + m[0].rm_so, rp_sub, len_rp);
401 // Advance
402 p += m[0].rm_so + len_rp;
403 cur_pos += m[0].rm_so + len_rp;
404 cur_siz += delta_siz;
405 creplace += 1;
406 }
407 free(m);
408 regfree(&r);
409 return (int)cur_siz;
410 };
411
412 #ifdef __cplusplus /* If this is a C++ compiler, end C linkage */
413 }
414 #endif
415
416 #endif /*REGEX_POSIX_H_*/