diff --git a/editor.h b/editor.h index a2ab3f5af..76a3136e2 100644 --- 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 index 0f99076cd..3c7c9c5e0 100644 --- a/text-motions.h +++ b/text-motions.h @@ -7,6 +7,7 @@ #include #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 new file mode 100644 index 000000000..cff858761 --- /dev/null +++ b/text-regex.c @@ -0,0 +1,71 @@ +#include +#include + +#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 new file mode 100644 index 000000000..d304d5785 --- /dev/null +++ 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 index fee7aefc7..be9a8f56f 100644 --- a/text.c +++ b/text.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -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 index 3b6344b24..c322a10cd 100644 --- 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