vis
a vi-like editor based on Plan 9's structural regular expressions
git clone https://9o.is/git/vis.git
commit 539cf1f9342e423296c17a090523eaf135e98053 parent 5834924643789ff3d35e78ab49ddc0c18beb1a5f Author: Marc André Tanner <mat@brain-dump.org> Date: Sun, 19 Jul 2015 13:55:50 +0200 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:
| M | editor.h | | | 1 | + |
| M | text-motions.h | | | 1 | + |
| A | text-regex.c | | | 71 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | text-regex.h | | | 16 | ++++++++++++++++ |
| M | text.c | | | 68 | -------------------------------------------------------------------- |
| M | text.h | | | 9 | --------- |
6 files changed, 89 insertions(+), 77 deletions(-)
diff --git a/editor.h b/editor.h @@ -17,6 +17,7 @@ typedef struct Win Win; #include "syntax.h" #include "ring-buffer.h" #include "map.h" +#include "text-regex.h" typedef union { bool b; diff --git a/text-motions.h b/text-motions.h @@ -7,6 +7,7 @@ #include <stddef.h> #include "text.h" +#include "text-regex.h" size_t text_begin(Text*, size_t pos); size_t text_end(Text*, size_t pos); diff --git a/text-regex.c 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(®ex->regex, string, cflags); + if (r) + regcomp(®ex->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; +} diff --git a/text-regex.h b/text-regex.h @@ -0,0 +1,15 @@ +#ifndef TEXT_REGEX_H +#define TEXT_REGEX_H + +#include "text.h" + +typedef struct Regex Regex; +typedef Filerange RegexMatch; + +Regex *text_regex_new(void); +int text_regex_compile(Regex *r, const char *regex, int cflags); +void text_regex_free(Regex *r); +int text_search_range_forward(Text*, size_t pos, size_t len, Regex *r, size_t nmatch, RegexMatch pmatch[], int eflags); +int text_search_range_backward(Text*, size_t pos, size_t len, Regex *r, size_t nmatch, RegexMatch pmatch[], int eflags); + +#endif +\ No newline at end of file diff --git a/text.c b/text.c @@ -20,7 +20,6 @@ #include <time.h> #include <fcntl.h> #include <errno.h> -#include <regex.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/mman.h> @@ -41,11 +40,6 @@ * results in havoc. */ #define BUFFER_MMAP_SIZE (1 << 23) -struct Regex { - const char *string; - regex_t regex; -}; - /* Buffer holding the file content, either readonly mmap(2)-ed from the original * file or heap allocated to store the modifications. */ @@ -1465,68 +1459,6 @@ size_t text_history_get(Text *txt, size_t index) { return EPOS; } -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(®ex->regex, string, cflags); - if (r) - regcomp(®ex->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; -} - bool text_range_valid(Filerange *r) { return r->start != EPOS && r->end != EPOS && r->start <= r->end; } diff --git a/text.h b/text.h @@ -129,13 +129,4 @@ ssize_t text_range_write(Text*, Filerange*, int fd); /* release all ressources associated with this text instance */ void text_free(Text*); -typedef struct Regex Regex; -typedef Filerange RegexMatch; - -Regex *text_regex_new(void); -int text_regex_compile(Regex *r, const char *regex, int cflags); -void text_regex_free(Regex *r); -int text_search_range_forward(Text*, size_t pos, size_t len, Regex *r, size_t nmatch, RegexMatch pmatch[], int eflags); -int text_search_range_backward(Text*, size_t pos, size_t len, Regex *r, size_t nmatch, RegexMatch pmatch[], int eflags); - #endif