diff options
| author | Marc André Tanner <mat@brain-dump.org> | 2020-10-09 12:28:26 +0200 |
|---|---|---|
| committer | Marc André Tanner <mat@brain-dump.org> | 2020-10-10 11:40:35 +0200 |
| commit | 7abe45b5ea0e051b0510a5efc56b1a3d5f22da6a (patch) | |
| tree | 09470fb0de24ee63d28a80f1d5be929623e7e433 /text-common.c | |
| parent | dc73a99a0cdc6370e3428c39cab28e97aac745a4 (diff) | |
| download | vis-7abe45b5ea0e051b0510a5efc56b1a3d5f22da6a.tar.gz vis-7abe45b5ea0e051b0510a5efc56b1a3d5f22da6a.tar.xz | |
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 (limited to 'text-common.c')
| -rw-r--r-- | text-common.c | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/text-common.c b/text-common.c new file mode 100644 index 0000000..6225dad --- /dev/null +++ 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; +} |
