1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
#include <pcre2.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../logger.h"
#include "utils.h"
int regex_match(const char *subject, str_array_t patterns,
str_array_t *results) {
pcre2_code *re;
int errornumber;
int rc = PCRE2_ERROR_NOMATCH;
PCRE2_SIZE subject_len = strlen(subject);
PCRE2_SIZE offset = 0, erroroffset;
PCRE2_SIZE *ovector;
pcre2_match_data *match_data;
for (unsigned short i = 0; i < patterns.n; i++) {
DEBUG_PRINT("Gets pattern: %s\n", patterns.str[i]);
re = pcre2_compile((PCRE2_SPTR)patterns.str[i], PCRE2_ZERO_TERMINATED, 0,
&errornumber, &erroroffset, NULL);
if (re == NULL) {
PCRE2_UCHAR buffer[256];
pcre2_get_error_message(errornumber, buffer, sizeof(buffer));
LOG("PCRE2", "compilation failed at offset %d: %s\n", (int)erroroffset,
buffer);
return 1;
}
match_data = pcre2_match_data_create_from_pattern(re, NULL);
unsigned char i = 0;
while (offset < subject_len &&
(rc = pcre2_match(re, (PCRE2_SPTR)subject, (PCRE2_SIZE)subject_len,
offset, 0, match_data, NULL)) > 0) {
// results->str = realloc(results->str, sizeof(char *) * (rc +
// results->n));
resize_str_array(results, rc + i);
ovector = pcre2_get_ovector_pointer(match_data);
DEBUG_PRINT("Get %d captures.\n", rc - 1);
DEBUG_PRINT("Match succeeded at offset %d.\n", (int)ovector[0]);
for (unsigned short j = 1; j < rc; j++) {
PCRE2_SIZE substring_length = ovector[2 * j + 1] - ovector[2 * j];
PCRE2_SPTR substring = (PCRE2_SPTR)subject + ovector[2 * j];
/* Here we need to manually control the str array,
* as PCRE2_SPTR == const unsigned char
* (which cannot be directly casted) */
results->str[j] = malloc(substring_length + 1);
sprintf(results->str[j], "%.*s", (int)substring_length, substring);
DEBUG_PRINT("index: %2d, substring_length: %d\n", j,
(int)substring_length);
}
offset = ovector[1];
DEBUG_PRINT("offset: %zu, subject_len: %zu\n", offset, subject_len);
i++;
}
pcre2_match_data_free(match_data);
pcre2_code_free(re);
if (rc <= 0) {
switch (rc) {
case PCRE2_ERROR_NOMATCH:
DEBUG_PRINT("No match found.\n");
return 0;
break;
case 0:
LOG("PCRE2",
"ovector was not big enough for all the captured substrings\n");
break;
default:
LOG("PCRE2", "Matching error %d\n", rc);
return 1;
}
}
}
return 0;
}
int repchr(char *str, char t, char r) {
int c = 0;
for (size_t i = 0; str[i] != '\0'; i++) {
if (str[i] == t) {
str[i] = r;
c++;
}
}
return c;
}
void free_and_nullify(void *p) {
if (p) {
free(p);
p = NULL;
}
}
|