Add missing word
[vis.git] / text-regex.c
blobc3d1cb23fa5571b21921f8e551d655ce6e7fad8c
1 #include <stdlib.h>
2 #include <string.h>
3 #include <regex.h>
5 #include "text-regex.h"
7 struct Regex {
8 regex_t regex;
9 };
11 Regex *text_regex_new(void) {
12 Regex *r = calloc(1, sizeof(Regex));
13 if (!r)
14 return NULL;
15 regcomp(&r->regex, "\0\0", 0); /* this should not match anything */
16 return r;
19 int text_regex_compile(Regex *regex, const char *string, int cflags) {
20 int r = regcomp(&regex->regex, string, cflags);
21 if (r)
22 regcomp(&regex->regex, "\0\0", 0);
23 return r;
26 void text_regex_free(Regex *r) {
27 if (!r)
28 return;
29 regfree(&r->regex);
30 free(r);
33 int text_search_range_forward(Text *txt, size_t pos, size_t len, Regex *r, size_t nmatch, RegexMatch pmatch[], int eflags) {
34 char *buf = text_bytes_alloc0(txt, pos, len);
35 if (!buf)
36 return REG_NOMATCH;
37 regmatch_t match[nmatch];
38 int ret = regexec(&r->regex, buf, nmatch, match, eflags);
39 if (!ret) {
40 for (size_t i = 0; i < nmatch; i++) {
41 pmatch[i].start = match[i].rm_so == -1 ? EPOS : pos + match[i].rm_so;
42 pmatch[i].end = match[i].rm_eo == -1 ? EPOS : pos + match[i].rm_eo;
45 free(buf);
46 return ret;
49 int text_search_range_backward(Text *txt, size_t pos, size_t len, Regex *r, size_t nmatch, RegexMatch pmatch[], int eflags) {
50 char *buf = text_bytes_alloc0(txt, pos, len);
51 if (!buf)
52 return REG_NOMATCH;
53 regmatch_t match[nmatch];
54 char *cur = buf;
55 int ret = REG_NOMATCH;
56 while (!regexec(&r->regex, cur, nmatch, match, eflags)) {
57 ret = 0;
58 for (size_t i = 0; i < nmatch; i++) {
59 pmatch[i].start = match[i].rm_so == -1 ? EPOS : pos + (size_t)(cur - buf) + match[i].rm_so;
60 pmatch[i].end = match[i].rm_eo == -1 ? EPOS : pos + (size_t)(cur - buf) + match[i].rm_eo;
62 if (match[0].rm_so == 0 && match[0].rm_eo == 0) {
63 /* empty match at the beginning of cur, advance to next line */
64 if ((cur = strchr(cur, '\n')))
65 cur++;
66 else
67 break;
69 } else {
70 cur += match[0].rm_eo;
73 free(buf);
74 return ret;