From 819ca3927f6f156d12eeddae4ed84d04d28b7e1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Andr=C3=A9=20Tanner?= Date: Thu, 1 Jan 2015 14:53:28 +0100 Subject: Introduce externally managed marks --- text.c | 35 +++++++++++++++++++++++------------ text.h | 4 ++++ 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/text.c b/text.c index 47310f0..cc438ed 100644 --- a/text.c +++ b/text.c @@ -119,7 +119,7 @@ struct Text { struct stat info; /* stat as proped on load time */ int fd; /* the file descriptor of the original mmap-ed data */ LineCache lines; /* mapping between absolute pos in bytes and logical line breaks */ - const char *marks[32]; /* a mark is a pointer into an underlying buffer */ + Mark marks[32]; /* a mark is a pointer into an underlying buffer */ int newlines; /* 0: unknown, 1: \n, -1: \r\n */ }; @@ -1145,29 +1145,40 @@ size_t text_lineno_by_pos(Text *txt, size_t pos) { return cache->lineno; } -void text_mark_intern_set(Text *txt, MarkIntern mark, size_t pos) { - if (mark < 0 || mark >= LENGTH(txt->marks)) - return; +Mark text_mark_set(Text *txt, size_t pos) { Location loc = piece_get_extern(txt, pos); if (!loc.piece) - return; - txt->marks[mark] = loc.piece->data + loc.off; + return NULL; + return loc.piece->data + loc.off; } -size_t text_mark_intern_get(Text *txt, MarkIntern mark) { - if (mark < 0 || mark >= LENGTH(txt->marks)) - return EPOS; - const char *pos = txt->marks[mark]; +size_t text_mark_get(Text *txt, Mark mark) { size_t cur = 0; + + if (!mark) + return EPOS; + for (Piece *p = txt->begin.next; p->next; p = p->next) { - if (p->data <= pos && pos < p->data + p->len) - return cur + (pos - p->data); + if (p->data <= mark && mark < p->data + p->len) + return cur + (mark - p->data); cur += p->len; } return EPOS; } +void text_mark_intern_set(Text *txt, MarkIntern mark, size_t pos) { + if (mark < 0 || mark >= LENGTH(txt->marks)) + return; + txt->marks[mark] = text_mark_set(txt, pos); +} + +size_t text_mark_intern_get(Text *txt, MarkIntern mark) { + if (mark < 0 || mark >= LENGTH(txt->marks)) + return EPOS; + return text_mark_get(txt, txt->marks[mark]); +} + void text_mark_intern_clear(Text *txt, MarkIntern mark) { if (mark < 0 || mark >= LENGTH(txt->marks)) return; diff --git a/text.h b/text.h index 2a7d2de..df6167c 100644 --- a/text.h +++ b/text.h @@ -75,6 +75,10 @@ bool text_iterator_byte_next(Iterator*, char *b); bool text_iterator_char_next(Iterator*, char *c); bool text_iterator_char_prev(Iterator*, char *c); +typedef const char* Mark; +Mark text_mark_set(Text*, size_t pos); +size_t text_mark_get(Text*, Mark); + typedef int MarkIntern; void text_mark_intern_set(Text*, MarkIntern, size_t pos); size_t text_mark_intern_get(Text*, MarkIntern); -- cgit v1.2.3