tsbuf.c - neatvi - [fork] simple vi-type editor with UTF-8 support
(HTM) git clone git://src.adamsgaard.dk/neatvi
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
---
tsbuf.c (1724B)
---
1 /* variable length string buffer */
2 #include <stdarg.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include "vi.h"
7
8 #define SBUFSZ 128
9 #define ALIGN(n, a) (((n) + (a) - 1) & ~((a) - 1))
10 #define NEXTSZ(o, r) ALIGN(MAX((o) * 2, (o) + (r)), SBUFSZ)
11
12 struct sbuf {
13 char *s; /* allocated buffer */
14 int s_n; /* length of the string stored in s[] */
15 int s_sz; /* size of memory allocated for s[] */
16 };
17
18 static void sbuf_extend(struct sbuf *sbuf, int newsz)
19 {
20 char *s = sbuf->s;
21 sbuf->s_sz = newsz;
22 sbuf->s = malloc(sbuf->s_sz);
23 if (sbuf->s_n)
24 memcpy(sbuf->s, s, sbuf->s_n);
25 free(s);
26 }
27
28 struct sbuf *sbuf_make(void)
29 {
30 struct sbuf *sb = malloc(sizeof(*sb));
31 memset(sb, 0, sizeof(*sb));
32 return sb;
33 }
34
35 char *sbuf_buf(struct sbuf *sb)
36 {
37 if (!sb->s)
38 sbuf_extend(sb, 1);
39 sb->s[sb->s_n] = '\0';
40 return sb->s;
41 }
42
43 char *sbuf_done(struct sbuf *sb)
44 {
45 char *s = sbuf_buf(sb);
46 free(sb);
47 return s;
48 }
49
50 void sbuf_free(struct sbuf *sb)
51 {
52 free(sb->s);
53 free(sb);
54 }
55
56 void sbuf_chr(struct sbuf *sbuf, int c)
57 {
58 if (sbuf->s_n + 2 >= sbuf->s_sz)
59 sbuf_extend(sbuf, NEXTSZ(sbuf->s_sz, 1));
60 sbuf->s[sbuf->s_n++] = c;
61 }
62
63 void sbuf_mem(struct sbuf *sbuf, char *s, int len)
64 {
65 if (sbuf->s_n + len + 1 >= sbuf->s_sz)
66 sbuf_extend(sbuf, NEXTSZ(sbuf->s_sz, len + 1));
67 memcpy(sbuf->s + sbuf->s_n, s, len);
68 sbuf->s_n += len;
69 }
70
71 void sbuf_str(struct sbuf *sbuf, char *s)
72 {
73 sbuf_mem(sbuf, s, strlen(s));
74 }
75
76 int sbuf_len(struct sbuf *sbuf)
77 {
78 return sbuf->s_n;
79 }
80
81 void sbuf_cut(struct sbuf *sb, int len)
82 {
83 if (sb->s_n > len)
84 sb->s_n = len;
85 }
86
87 void sbuf_printf(struct sbuf *sbuf, char *s, ...)
88 {
89 char buf[256];
90 va_list ap;
91 va_start(ap, s);
92 vsnprintf(buf, sizeof(buf), s, ap);
93 va_end(ap);
94 sbuf_str(sbuf, buf);
95 }