From 83e4cb0e54a64f2a366e2f312be773afc8e02aa2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Andr=C3=A9=20Tanner?= Date: Wed, 13 Aug 2014 21:38:14 +0200 Subject: Add search functionality --- editor.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ editor.h | 13 +++++++++++ 2 files changed, 94 insertions(+) diff --git a/editor.c b/editor.c index d1c8d62..f1d89fb 100644 --- a/editor.c +++ b/editor.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -21,6 +22,11 @@ /* is c the start of a utf8 sequence? */ #define isutf8(c) (((c)&0xC0)!=0x80) +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. */ @@ -1008,6 +1014,81 @@ size_t editor_lineno_by_pos(Editor *ed, size_t pos) { return cache->lineno; } +void editor_mark_set(Editor *ed, Mark mark, size_t pos) { + if (mark < 0 || mark >= LENGTH(ed->marks) || pos >= ed->size) + return; + ed->marks[mark] = pos; +} + +size_t editor_mark_get(Editor *ed, Mark mark) { + if (mark < 0 || mark >= LENGTH(ed->marks)) + return -1; + return ed->marks[mark]; +} + +void editor_mark_clear(Editor *ed, Mark mark) { + if (mark < 0 || mark >= LENGTH(ed->marks)) + return; + ed->marks[mark] = -1; +} + +void editor_mark_clear_all(Editor *ed) { + for (Mark mark = 0; mark < LENGTH(ed->marks); mark++) + editor_mark_clear(ed, mark); +} + const char *editor_filename(Editor *ed) { return ed->filename; } + +Regex *editor_regex_new(void) { + return calloc(1, sizeof(Regex)); +} + +int editor_regex_compile(Regex *regex, const char *string, int cflags) { + regex->string = string; + return regcomp(®ex->regex, string, cflags); +} + +void editor_regex_free(Regex *r) { + regfree(&r->regex); +} + +int editor_search_forward(Editor *ed, 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 = editor_bytes_get(ed, 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 ? (size_t)-1 : pos + match[i].rm_so; + pmatch[i].end = match[i].rm_eo == -1 ? (size_t)-1 : pos + match[i].rm_eo; + } + } + free(buf); + return ret; +} + +int editor_search_backward(Editor *ed, 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 = editor_bytes_get(ed, 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 ? (size_t)-1 : pos + (size_t)(cur - buf) + match[i].rm_so; + pmatch[i].end = match[i].rm_eo == -1 ? (size_t)-1 : pos + (size_t)(cur - buf) + match[i].rm_eo; + } + cur += match[0].rm_eo; + } + free(buf); + return ret; +} diff --git a/editor.h b/editor.h index c10577d..114cc0b 100644 --- a/editor.h +++ b/editor.h @@ -55,5 +55,18 @@ bool editor_modified(Editor*); int editor_save(Editor*, const char *file); void editor_free(Editor *ed); +typedef struct Regex Regex; + +typedef struct { + size_t start; /* start of match in bytes from start of file or -1 if unused */ + size_t end; /* end of match in bytes from start of file or -1 if unused */ +} RegexMatch; + +Regex *editor_regex_new(void); +int editor_regex_compile(Regex *r, const char *regex, int cflags); +void editor_regex_free(Regex *r); +int editor_search_forward(Editor*, size_t pos, size_t len, Regex *r, size_t nmatch, RegexMatch pmatch[], int eflags); +int editor_search_backward(Editor*, size_t pos, size_t len, Regex *r, size_t nmatch, RegexMatch pmatch[], int eflags); + // TMP void editor_debug(Editor *ed); -- cgit v1.2.3