Add gemini lexer
[vis.git] / text-common.c
blob6225dadaa7641b0bace7199da6eaf4cad893b8b8
1 #include <stdlib.h>
2 #include <string.h>
3 #include <stdio.h>
4 #include "text.h"
6 static bool text_vprintf(Text *txt, size_t pos, const char *format, va_list ap) {
7 va_list ap_save;
8 va_copy(ap_save, ap);
9 int len = vsnprintf(NULL, 0, format, ap);
10 if (len == -1) {
11 va_end(ap_save);
12 return false;
14 char *buf = malloc(len+1);
15 bool ret = buf && (vsnprintf(buf, len+1, format, ap_save) == len) && text_insert(txt, pos, buf, len);
16 free(buf);
17 va_end(ap_save);
18 return ret;
21 bool text_appendf(Text *txt, const char *format, ...) {
22 va_list ap;
23 va_start(ap, format);
24 bool ret = text_vprintf(txt, text_size(txt), format, ap);
25 va_end(ap);
26 return ret;
29 bool text_printf(Text *txt, size_t pos, const char *format, ...) {
30 va_list ap;
31 va_start(ap, format);
32 bool ret = text_vprintf(txt, pos, format, ap);
33 va_end(ap);
34 return ret;
37 bool text_byte_get(const Text *txt, size_t pos, char *byte) {
38 return text_bytes_get(txt, pos, 1, byte);
41 size_t text_bytes_get(const Text *txt, size_t pos, size_t len, char *buf) {
42 if (!buf)
43 return 0;
44 char *cur = buf;
45 size_t rem = len;
46 for (Iterator it = text_iterator_get(txt, pos);
47 text_iterator_valid(&it);
48 text_iterator_next(&it)) {
49 if (rem == 0)
50 break;
51 size_t piece_len = it.end - it.text;
52 if (piece_len > rem)
53 piece_len = rem;
54 if (piece_len) {
55 memcpy(cur, it.text, piece_len);
56 cur += piece_len;
57 rem -= piece_len;
60 return len - rem;
63 char *text_bytes_alloc0(const Text *txt, size_t pos, size_t len) {
64 if (len == SIZE_MAX)
65 return NULL;
66 char *buf = malloc(len+1);
67 if (!buf)
68 return NULL;
69 len = text_bytes_get(txt, pos, len, buf);
70 buf[len] = '\0';
71 return buf;