txtbuf.c - ledit - Text editor (WIP) | |
git clone git://lumidify.org/ledit.git (fast, but not encrypted) | |
git clone https://lumidify.org/ledit.git (encrypted, but very slow) | |
git clone git://4kcetb7mo7hj6grozzybxtotsub5bempzo4lirzc3437amof2c2impyd.onion/… | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
txtbuf.c (3012B) | |
--- | |
1 #include <stdio.h> | |
2 #include <stdlib.h> | |
3 #include <string.h> | |
4 #include <stdarg.h> | |
5 | |
6 #include "util.h" | |
7 #include "memory.h" | |
8 #include "txtbuf.h" | |
9 #include "assert.h" | |
10 | |
11 txtbuf * | |
12 txtbuf_new(void) { | |
13 txtbuf *buf = ledit_malloc(sizeof(txtbuf)); | |
14 buf->text = NULL; | |
15 buf->cap = buf->len = 0; | |
16 return buf; | |
17 } | |
18 | |
19 txtbuf * | |
20 txtbuf_new_from_char(char *str) { | |
21 txtbuf *buf = ledit_malloc(sizeof(txtbuf)); | |
22 buf->text = ledit_strdup(str); | |
23 buf->len = strlen(str); | |
24 buf->cap = buf->len + 1; | |
25 return buf; | |
26 } | |
27 | |
28 txtbuf * | |
29 txtbuf_new_from_char_len(char *str, size_t len) { | |
30 txtbuf *buf = ledit_malloc(sizeof(txtbuf)); | |
31 buf->text = ledit_strndup(str, len); | |
32 buf->len = len; | |
33 buf->cap = len + 1; | |
34 return buf; | |
35 } | |
36 | |
37 void | |
38 txtbuf_fmt(txtbuf *buf, char *fmt, ...) { | |
39 va_list args; | |
40 va_start(args, fmt); | |
41 int len = vsnprintf(buf->text, buf->cap, fmt, args); | |
42 /* FIXME: len can never be negative, right? */ | |
43 /* FIXME: maybe also shrink here */ | |
44 if ((size_t)len >= buf->cap) { | |
45 va_end(args); | |
46 va_start(args, fmt); | |
47 txtbuf_resize(buf, len); | |
48 vsnprintf(buf->text, buf->cap, fmt, args); | |
49 } | |
50 buf->len = len; | |
51 va_end(args); | |
52 } | |
53 | |
54 void | |
55 txtbuf_set_text(txtbuf *buf, char *text) { | |
56 txtbuf_set_textn(buf, text, strlen(text)); | |
57 } | |
58 | |
59 void | |
60 txtbuf_set_textn(txtbuf *buf, char *text, size_t len) { | |
61 txtbuf_resize(buf, len); | |
62 buf->len = len; | |
63 memmove(buf->text, text, len); | |
64 buf->text[buf->len] = '\0'; | |
65 } | |
66 | |
67 void | |
68 txtbuf_append(txtbuf *buf, char *text) { | |
69 txtbuf_appendn(buf, text, strlen(text)); | |
70 } | |
71 | |
72 /* FIXME: some sort of append that does not resize until there's not eno… | |
73 space so a buffer that will be filled up anyways doesn't have to be | |
74 constantly resized */ | |
75 void | |
76 txtbuf_appendn(txtbuf *buf, char *text, size_t len) { | |
77 txtbuf_resize(buf, add_sz(buf->len, len)); | |
78 memmove(buf->text + buf->len, text, len); | |
79 buf->len += len; | |
80 buf->text[buf->len] = '\0'; | |
81 } | |
82 | |
83 void | |
84 txtbuf_resize(txtbuf *buf, size_t sz) { | |
85 /* always leave room for extra \0 */ | |
86 size_t cap = ideal_array_size(buf->cap, add_sz(sz, 1)); | |
87 if (cap != buf->cap) { | |
88 buf->text = ledit_realloc(buf->text, cap); | |
89 buf->cap = cap; | |
90 } | |
91 } | |
92 | |
93 void | |
94 txtbuf_destroy(txtbuf *buf) { | |
95 if (!buf) | |
96 return; | |
97 free(buf->text); | |
98 free(buf); | |
99 } | |
100 | |
101 void | |
102 txtbuf_copy(txtbuf *dst, txtbuf *src) { | |
103 txtbuf_resize(dst, src->len); | |
104 if (src->text && dst->text) { | |
105 memcpy(dst->text, src->text, src->len); | |
106 dst->text[src->len] = '\0'; | |
107 } | |
108 dst->len = src->len; | |
109 } | |
110 | |
111 txtbuf * | |
112 txtbuf_dup(txtbuf *src) { | |
113 txtbuf *dst = txtbuf_new(); | |
114 txtbuf_copy(dst, src); | |
115 return dst; | |
116 } | |
117 | |
118 int | |
119 txtbuf_cmp(txtbuf *buf1, txtbuf *buf2) { | |
120 /* FIXME: I guess strcmp would be possible as well since it's nu… | |
121 /* FIXME: Test this because I was tired while writing it */ | |
122 int cmp = strncmp(buf1->text, buf2->text, LEDIT_MIN(buf1->len, b… | |
123 if (cmp == 0) { | |
124 if (buf1->len < buf2->len) | |
125 return -1; | |
126 else if (buf1->len > buf2->len) | |
127 return 1; | |
128 } | |
129 return cmp; | |
130 } | |
131 | |
132 int | |
133 txtbuf_eql(txtbuf *buf1, txtbuf *buf2) { | |
134 return txtbuf_cmp(buf1, buf2) == 0; | |
135 } | |
136 | |
137 void | |
138 txtbuf_clear(txtbuf *buf) { | |
139 if (buf->len > 0) { | |
140 buf->len = 0; | |
141 buf->text[0] = '\0'; | |
142 } | |
143 } |