aboutsummaryrefslogtreecommitdiff
path: root/text-regex.c
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2015-07-19 13:55:50 +0200
committerMarc André Tanner <mat@brain-dump.org>2015-07-19 13:55:50 +0200
commit8129933ca51caf788e0cd7c5fdbcb43fdc64601d (patch)
tree3cb1c6bdce4ff9d0eeff94b9b3716d628f9b5687 /text-regex.c
parent0d6dbfe292c61b935edd3e367c9032b27c850efc (diff)
downloadvis-8129933ca51caf788e0cd7c5fdbcb43fdc64601d.tar.gz
vis-8129933ca51caf788e0cd7c5fdbcb43fdc64601d.tar.xz
text: move regex related functions to separate file
Eventually this should probably be rewritten to use an iternal regex engine, currently it has unacceptable memory usage, it copies the whole text.
Diffstat (limited to 'text-regex.c')
-rw-r--r--text-regex.c71
1 files changed, 71 insertions, 0 deletions
diff --git a/text-regex.c b/text-regex.c
new file mode 100644
index 0000000..cff8587
--- /dev/null
+++ b/text-regex.c
@@ -0,0 +1,71 @@
+#include <stdlib.h>
+#include <regex.h>
+
+#include "text-regex.h"
+
+struct Regex {
+ const char *string;
+ regex_t regex;
+};
+
+Regex *text_regex_new(void) {
+ Regex *r = calloc(1, sizeof(Regex));
+ if (!r)
+ return NULL;
+ regcomp(&r->regex, "\0\0", 0); /* this should not match anything */
+ return r;
+}
+
+int text_regex_compile(Regex *regex, const char *string, int cflags) {
+ regex->string = string;
+ int r = regcomp(&regex->regex, string, cflags);
+ if (r)
+ regcomp(&regex->regex, "\0\0", 0);
+ return r;
+}
+
+void text_regex_free(Regex *r) {
+ if (!r)
+ return;
+ regfree(&r->regex);
+ free(r);
+}
+
+int text_search_range_forward(Text *txt, size_t pos, size_t len, Regex *r, size_t nmatch, RegexMatch pmatch[], int eflags) {
+ char *buf = malloc(len + 1);
+ if (!buf)
+ return REG_NOMATCH;
+ len = text_bytes_get(txt, pos, len, buf);
+ buf[len] = '\0';
+ regmatch_t match[nmatch];
+ int ret = regexec(&r->regex, buf, nmatch, match, eflags);
+ if (!ret) {
+ for (size_t i = 0; i < nmatch; i++) {
+ pmatch[i].start = match[i].rm_so == -1 ? EPOS : pos + match[i].rm_so;
+ pmatch[i].end = match[i].rm_eo == -1 ? EPOS : pos + match[i].rm_eo;
+ }
+ }
+ free(buf);
+ return ret;
+}
+
+int text_search_range_backward(Text *txt, size_t pos, size_t len, Regex *r, size_t nmatch, RegexMatch pmatch[], int eflags) {
+ char *buf = malloc(len + 1);
+ if (!buf)
+ return REG_NOMATCH;
+ len = text_bytes_get(txt, pos, len, buf);
+ buf[len] = '\0';
+ regmatch_t match[nmatch];
+ char *cur = buf;
+ int ret = REG_NOMATCH;
+ while (!regexec(&r->regex, cur, nmatch, match, eflags)) {
+ ret = 0;
+ for (size_t i = 0; i < nmatch; i++) {
+ pmatch[i].start = match[i].rm_so == -1 ? EPOS : pos + (size_t)(cur - buf) + match[i].rm_so;
+ pmatch[i].end = match[i].rm_eo == -1 ? EPOS : pos + (size_t)(cur - buf) + match[i].rm_eo;
+ }
+ cur += match[0].rm_eo;
+ }
+ free(buf);
+ return ret;
+}