aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2014-08-13 21:38:14 +0200
committerMarc André Tanner <mat@brain-dump.org>2014-08-13 21:38:14 +0200
commit83e4cb0e54a64f2a366e2f312be773afc8e02aa2 (patch)
tree258035d95c01cb971cbb8a84812502cf6780b884
parentef876ce4eaf3ef5f8e406205b2d797efccea293f (diff)
downloadvis-83e4cb0e54a64f2a366e2f312be773afc8e02aa2.tar.gz
vis-83e4cb0e54a64f2a366e2f312be773afc8e02aa2.tar.xz
Add search functionality
-rw-r--r--editor.c81
-rw-r--r--editor.h13
2 files changed, 94 insertions, 0 deletions
diff --git a/editor.c b/editor.c
index d1c8d62..f1d89fb 100644
--- a/editor.c
+++ b/editor.c
@@ -6,6 +6,7 @@
#include <time.h>
#include <fcntl.h>
#include <errno.h>
+#include <regex.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
@@ -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(&regex->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);