vis: s/ops/vis_operators/g
[vis.git] / text-regex.c
blobdbaa5fc5ccabce6b7115932b7849e743456e920a
1 #include <stdlib.h>
2 #include <regex.h>
4 #include "text-regex.h"
6 struct Regex {
7 const char *string;
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 regex->string = string;
21 int r = regcomp(&regex->regex, string, cflags);
22 if (r)
23 regcomp(&regex->regex, "\0\0", 0);
24 return r;
27 void text_regex_free(Regex *r) {
28 if (!r)
29 return;
30 regfree(&r->regex);
31 free(r);
34 int text_search_range_forward(Text *txt, size_t pos, size_t len, Regex *r, size_t nmatch, RegexMatch pmatch[], int eflags) {
35 char *buf = text_bytes_alloc0(txt, pos, len);
36 if (!buf)
37 return REG_NOMATCH;
38 regmatch_t match[nmatch];
39 int ret = regexec(&r->regex, buf, nmatch, match, eflags);
40 if (!ret) {
41 for (size_t i = 0; i < nmatch; i++) {
42 pmatch[i].start = match[i].rm_so == -1 ? EPOS : pos + match[i].rm_so;
43 pmatch[i].end = match[i].rm_eo == -1 ? EPOS : pos + match[i].rm_eo;
46 free(buf);
47 return ret;
50 int text_search_range_backward(Text *txt, size_t pos, size_t len, Regex *r, size_t nmatch, RegexMatch pmatch[], int eflags) {
51 char *buf = text_bytes_alloc0(txt, pos, len);
52 if (!buf)
53 return REG_NOMATCH;
54 regmatch_t match[nmatch];
55 char *cur = buf;
56 int ret = REG_NOMATCH;
57 while (!regexec(&r->regex, cur, nmatch, match, eflags)) {
58 ret = 0;
59 for (size_t i = 0; i < nmatch; i++) {
60 pmatch[i].start = match[i].rm_so == -1 ? EPOS : pos + (size_t)(cur - buf) + match[i].rm_so;
61 pmatch[i].end = match[i].rm_eo == -1 ? EPOS : pos + (size_t)(cur - buf) + match[i].rm_eo;
63 cur += match[0].rm_eo;
65 free(buf);
66 return ret;