vis

a vi-like editor based on Plan 9's structural regular expressions

git clone https://9o.is/git/vis.git

commit fd087f7fedaf131315b679e00104c03587761e50
parent 294da138e492d9fff8ee35a9271021cf8030910f
Author: Marc André Tanner <mat@brain-dump.org>
Date:   Fri,  9 Oct 2020 12:28:26 +0200

text: move higher level utility functions to separate file

The moved functions do not need access to internals of text.c, but
instead use the public interfaces. Splitting them out should facilitate
experimentation with different core text management data structures.

Diffstat:
MMakefile | 1+
Atext-common.c | 72++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtext.c | 68--------------------------------------------------------------------
3 files changed, 73 insertions(+), 68 deletions(-)

diff --git a/Makefile b/Makefile @@ -9,6 +9,7 @@ SRC = array.c \ map.c \ sam.c \ text.c \ + text-common.c \ text-io.c \ text-iterator.c \ text-motions.c \ diff --git a/text-common.c b/text-common.c @@ -0,0 +1,72 @@ +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include "text.h" + +static bool text_vprintf(Text *txt, size_t pos, const char *format, va_list ap) { + va_list ap_save; + va_copy(ap_save, ap); + int len = vsnprintf(NULL, 0, format, ap); + if (len == -1) { + va_end(ap_save); + return false; + } + char *buf = malloc(len+1); + bool ret = buf && (vsnprintf(buf, len+1, format, ap_save) == len) && text_insert(txt, pos, buf, len); + free(buf); + va_end(ap_save); + return ret; +} + +bool text_appendf(Text *txt, const char *format, ...) { + va_list ap; + va_start(ap, format); + bool ret = text_vprintf(txt, text_size(txt), format, ap); + va_end(ap); + return ret; +} + +bool text_printf(Text *txt, size_t pos, const char *format, ...) { + va_list ap; + va_start(ap, format); + bool ret = text_vprintf(txt, pos, format, ap); + va_end(ap); + return ret; +} + +bool text_byte_get(const Text *txt, size_t pos, char *byte) { + return text_bytes_get(txt, pos, 1, byte); +} + +size_t text_bytes_get(const Text *txt, size_t pos, size_t len, char *buf) { + if (!buf) + return 0; + char *cur = buf; + size_t rem = len; + for (Iterator it = text_iterator_get(txt, pos); + text_iterator_valid(&it); + text_iterator_next(&it)) { + if (rem == 0) + break; + size_t piece_len = it.end - it.text; + if (piece_len > rem) + piece_len = rem; + if (piece_len) { + memcpy(cur, it.text, piece_len); + cur += piece_len; + rem -= piece_len; + } + } + return len - rem; +} + +char *text_bytes_alloc0(const Text *txt, size_t pos, size_t len) { + if (len == SIZE_MAX) + return NULL; + char *buf = malloc(len+1); + if (!buf) + return NULL; + len = text_bytes_get(txt, pos, len, buf); + buf[len] = '\0'; + return buf; +} diff --git a/text.c b/text.c @@ -470,37 +470,6 @@ bool text_insert(Text *txt, size_t pos, const char *data, size_t len) { return true; } -static bool text_vprintf(Text *txt, size_t pos, const char *format, va_list ap) { - va_list ap_save; - va_copy(ap_save, ap); - int len = vsnprintf(NULL, 0, format, ap); - if (len == -1) { - va_end(ap_save); - return false; - } - char *buf = malloc(len+1); - bool ret = buf && (vsnprintf(buf, len+1, format, ap_save) == len) && text_insert(txt, pos, buf, len); - free(buf); - va_end(ap_save); - return ret; -} - -bool text_appendf(Text *txt, const char *format, ...) { - va_list ap; - va_start(ap, format); - bool ret = text_vprintf(txt, text_size(txt), format, ap); - va_end(ap); - return ret; -} - -bool text_printf(Text *txt, size_t pos, const char *format, ...) { - va_list ap; - va_start(ap, format); - bool ret = text_vprintf(txt, pos, format, ap); - va_end(ap); - return ret; -} - static size_t revision_undo(Text *txt, Revision *rev) { size_t pos = EPOS; for (Change *c = rev->change; c; c = c->next) { @@ -880,43 +849,6 @@ bool text_iterator_has_prev(const Iterator *it) { return it->piece && it->piece->prev; } -bool text_byte_get(const Text *txt, size_t pos, char *byte) { - return text_bytes_get(txt, pos, 1, byte); -} - -size_t text_bytes_get(const Text *txt, size_t pos, size_t len, char *buf) { - if (!buf) - return 0; - char *cur = buf; - size_t rem = len; - for (Iterator it = text_iterator_get(txt, pos); - text_iterator_valid(&it); - text_iterator_next(&it)) { - if (rem == 0) - break; - size_t piece_len = it.end - it.text; - if (piece_len > rem) - piece_len = rem; - if (piece_len) { - memcpy(cur, it.text, piece_len); - cur += piece_len; - rem -= piece_len; - } - } - return len - rem; -} - -char *text_bytes_alloc0(const Text *txt, size_t pos, size_t len) { - if (len == SIZE_MAX) - return NULL; - char *buf = malloc(len+1); - if (!buf) - return NULL; - len = text_bytes_get(txt, pos, len, buf); - buf[len] = '\0'; - return buf; -} - size_t text_size(const Text *txt) { return txt->size; }