annotate src/libmlk-core/core/buf.c @ 423:63ebfa352ae1

core: use err.h in font
author David Demelier <markand@malikania.fr>
date Sat, 15 Oct 2022 14:00:38 +0200
parents 460c78706989
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
347
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
1 /*
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
2 * buf.c -- simple string buffer for C
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
3 *
378
460c78706989 misc: update copyright years
David Demelier <markand@malikania.fr>
parents: 347
diff changeset
4 * Copyright (c) 2019-2022 David Demelier <markand@malikania.fr>
347
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
5 *
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
6 * Permission to use, copy, modify, and/or distribute this software for any
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
7 * purpose with or without fee is hereby granted, provided that the above
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
8 * copyright notice and this permission notice appear in all copies.
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
9 *
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
17 */
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
18
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
19 #include <assert.h>
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
20 #include <errno.h>
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
21 #include <stdint.h>
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
22 #include <stdlib.h>
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
23 #include <stdio.h>
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
24 #include <string.h>
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
25
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
26 #include "buf.h"
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
27
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
28 /*
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
29 * Try to increase the buffer length by a power of two until we have enough
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
30 * space to fit `desired'.
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
31 *
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
32 * Detects overflow and return -1 if happened or reallocation could not
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
33 * occur.
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
34 */
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
35 static int
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
36 growdbl(struct buf *b, size_t desired)
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
37 {
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
38 size_t newcap = b->capacity;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
39 void *newptr;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
40
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
41 while (desired > newcap - b->length) {
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
42 const size_t r = newcap * 2;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
43
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
44 /* Overflow occured. */
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
45 if (r / newcap != 2) {
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
46 #if defined(ENOMEM)
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
47 errno = ENOMEM;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
48 #endif
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
49 return -1;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
50 }
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
51
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
52 newcap = r;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
53 }
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
54
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
55 /* At this step we must have enough room. */
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
56 assert(newcap - b->length >= desired);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
57
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
58 /* Pretty much impossible to reach but always assume it's possible. */
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
59 if (newcap == SIZE_MAX) {
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
60 #if defined(ENOMEM)
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
61 errno = ENOMEM;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
62 #endif
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
63 return -1;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
64 }
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
65
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
66 if (!(newptr = BUF_REALLOC(b->data, newcap + 1)))
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
67 return -1;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
68
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
69 b->data = newptr;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
70 b->capacity = newcap;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
71
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
72 return 0;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
73 }
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
74
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
75 /*
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
76 * Try to allocate just enough space for the `desired' amount of space. This is
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
77 * only used when the buffer is already too large but hasn't reached SIZE_MAX
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
78 * yet.
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
79 *
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
80 * Returns -1 if allocation failed.
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
81 */
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
82 static int
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
83 growmin(struct buf *b, size_t desired)
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
84 {
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
85 size_t newcap;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
86 void *newptr;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
87
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
88 if (desired >= SIZE_MAX - b->length) {
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
89 #if defined(ENOMEM)
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
90 errno = ENOMEM;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
91 #endif
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
92 return -1;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
93 }
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
94
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
95 /* Don't forget to keep what's remaining between capacity and length. */
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
96 newcap = b->capacity + (desired - (b->capacity - b->length));
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
97
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
98 /* Try to reallocate. */
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
99 if (!(newptr = BUF_REALLOC(b->data, newcap + 1)))
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
100 return -1;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
101
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
102 b->data = newptr;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
103 b->capacity = newcap;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
104
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
105 return 0;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
106 }
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
107
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
108 /*
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
109 * Entry point for reallocating data. Will try to allocate twice until we have
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
110 * enough room and then only the minimal amount.
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
111 */
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
112 static int
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
113 grow(struct buf *b, size_t desired)
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
114 {
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
115 const size_t avail = b->capacity - b->length;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
116
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
117 if (avail >= desired)
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
118 return 0;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
119
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
120 if (!b->capacity) {
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
121 if (!(b->data = BUF_MALLOC(desired + 1)))
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
122 return -1;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
123
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
124 b->capacity = desired;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
125 } else if (growdbl(b, desired) < 0 && growmin(b, desired) < 0)
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
126 return -1;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
127
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
128 return 0;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
129 }
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
130
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
131 void
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
132 buf_init(struct buf *b)
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
133 {
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
134 assert(b);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
135
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
136 memset(b, 0, sizeof (*b));
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
137 }
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
138
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
139 int
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
140 buf_reserve(struct buf *b, size_t amount)
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
141 {
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
142 assert(b);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
143
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
144 if (grow(b, amount) < 0)
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
145 return -1;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
146
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
147 return 0;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
148 }
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
149
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
150 int
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
151 buf_resize(struct buf *b, size_t size, char ch)
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
152 {
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
153 assert(b);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
154
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
155 /* New size is smaller than curren't length, just update it. */
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
156 if (size < b->length) {
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
157 b->data[b->length = size] = 0;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
158 return 0;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
159 }
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
160
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
161 /* New size is bigger, data may be reallocated. */
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
162 if (grow(b, size - b->length) < 0)
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
163 return -1;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
164
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
165 memset(&b->data[b->length], ch, size - b->length);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
166 b->length = size;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
167 b->data[b->length] = 0;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
168
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
169 return 0;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
170 }
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
171
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
172 int
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
173 buf_shrink(struct buf *b)
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
174 {
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
175 assert(b);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
176
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
177 void *newptr;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
178
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
179 if (b->length == 0) {
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
180 free(b->data);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
181 b->data = NULL;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
182 b->length = b->capacity = 0;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
183 return 0;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
184 }
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
185
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
186 if (!(newptr = BUF_REALLOC(b->data, b->length + 1)))
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
187 return -1;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
188
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
189 b->data = newptr;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
190 b->capacity = b->length;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
191
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
192 return 0;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
193 }
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
194
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
195 void
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
196 buf_erase(struct buf *b, size_t pos, size_t count)
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
197 {
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
198 assert(b);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
199 assert(pos <= b->length);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
200
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
201 if (count > b->length - pos) {
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
202 /* Optimize whole erase at pos. */
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
203 b->data[pos] = 0;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
204 b->length = pos;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
205 } else {
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
206 memmove(&b->data[pos], &b->data[pos + count], b->length - count);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
207 b->length -= count;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
208 }
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
209 }
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
210
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
211 int
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
212 buf_putc(struct buf *b, char c)
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
213 {
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
214 assert(b);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
215
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
216 if (grow(b, 1) < 0)
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
217 return -1;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
218
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
219 b->data[b->length++] = c;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
220 b->data[b->length] = 0;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
221
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
222 return 0;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
223 }
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
224
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
225 int
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
226 buf_puts(struct buf *b, const char *s)
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
227 {
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
228 assert(b);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
229 assert(s);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
230
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
231 const size_t len = strlen(s);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
232
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
233 if (grow(b, len) < 0)
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
234 return -1;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
235
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
236 memcpy(&b->data[b->length], s, len + 1);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
237 b->length += len;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
238
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
239 return 0;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
240 }
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
241
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
242 int
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
243 buf_printf(struct buf *b, const char *fmt, ...)
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
244 {
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
245 assert(b);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
246 assert(fmt);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
247
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
248 va_list ap;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
249 int ret;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
250
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
251 va_start(ap, fmt);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
252 ret = buf_vprintf(b, fmt, ap);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
253 va_end(ap);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
254
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
255 return ret;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
256 }
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
257
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
258 int
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
259 buf_vprintf(struct buf *b, const char *fmt, va_list args)
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
260 {
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
261 assert(b);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
262 assert(fmt);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
263
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
264 va_list ap;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
265 int amount;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
266
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
267 /* Determine length. */
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
268 va_copy(ap, args);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
269 amount = vsnprintf(NULL, 0, fmt, ap);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
270 va_end(ap);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
271
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
272 if (amount < 0)
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
273 return -1;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
274
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
275 /* Do actual copy. */
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
276 if (grow(b, amount) < 0)
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
277 return -1;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
278
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
279 va_copy(ap, args);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
280 amount = vsprintf(&b->data[b->length], fmt, ap);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
281 va_end(ap);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
282
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
283 if (amount < 0)
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
284 return -1;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
285
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
286 b->length += amount;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
287
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
288 return 0;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
289 }
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
290
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
291 int
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
292 buf_sub(struct buf *b, const struct buf *src, size_t pos, size_t count)
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
293 {
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
294 assert(b);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
295 assert(src);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
296 assert(pos <= src->length);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
297
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
298 if (count >= src->length)
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
299 count = src->length - pos;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
300 if (!(b->data = BUF_MALLOC(count + 1)))
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
301 return -1;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
302
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
303 strncpy(b->data, &src->data[pos], count);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
304 b->length = count;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
305 b->capacity = count;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
306 b->data[b->length] = 0;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
307
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
308 return 0;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
309 }
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
310
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
311 int
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
312 buf_dup(struct buf *b, const struct buf *src)
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
313 {
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
314 assert(b);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
315 assert(src);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
316
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
317 if (!src->data)
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
318 return 0;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
319 if (!(b->data = BUF_MALLOC(src->length + 1)))
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
320 return -1;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
321
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
322 memcpy(b->data, src->data, src->length + 1);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
323 b->capacity = src->length;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
324 b->length = src->length;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
325
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
326 return 0;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
327 }
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
328
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
329 void
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
330 buf_clear(struct buf *b)
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
331 {
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
332 assert(b);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
333
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
334 if (b->data)
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
335 b->data[b->length = 0] = 0;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
336 }
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
337
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
338 void
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
339 buf_finish(struct buf *b)
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
340 {
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
341 assert(b);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
342
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
343 BUF_FREE(b->data);
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
344 b->data = NULL;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
345 b->capacity = b->length = 0;
0969931b98e4 core: start removing POSIX APIs
David Demelier <markand@malikania.fr>
parents:
diff changeset
346 }