"Fossies" - the Fresh Open Source Software Archive 
Member "leafnode-1.12.0/mastring.c" (28 Dec 2021, 5886 Bytes) of package /linux/misc/leafnode-1.12.0.tar.xz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "mastring.c" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
1.11.12_vs_1.12.0.
1 /* mastring.c -- Implement auto-allocating string functions.
2 *
3 * (C) 2001 - 2003 by Matthias Andree <matthias.andree@gmx.de>
4 *
5 * This library is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as
7 * published by the Free Software Foundation; either version 2 or 2.1 of
8 * the License. See the file COPYING.LGPL for details.
9 *
10 * This library is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18 * USA
19 */
20
21 #include "config.h"
22
23 #include <string.h>
24 #include <stdlib.h>
25 #include <stdarg.h>
26 #include <ctype.h>
27
28 #include "wantassert.h"
29 #include <assert.h>
30
31 #define len PRIVATE__len
32 #define dat PRIVATE__dat
33 #define bufsize PRIVATE__bufsize
34 #include "mastring.h"
35
36 #ifdef WITH_DMALLOC
37 #include <dmalloc.h>
38 #endif
39
40 #include "getline.h"
41
42 static inline /*@exits@*/ void
43 mastr_oom(void)
44 #if defined(MASTR_OOM_ABORT) && defined(__GNUC__)
45 __attribute__ ((noreturn))
46 #endif
47 ;
48
49 /*@noreturn@*/
50 static inline void
51 mastr_oom(void)
52 {
53 #ifdef MASTR_OOM_ABORT
54 abort();
55 #endif
56 }
57
58 #undef min
59 #define min(a,b) ((a < b) ? (a) : (b))
60
61 mastr *
62 mastr_new(size_t size)
63 {
64 mastr *n;
65
66 assert(size != 0);
67
68 n = (mastr *)malloc(sizeof(mastr));
69 if (!n) {
70 mastr_oom();
71 /*@notreached@*/ return NULL;
72 }
73 n->bufsize = size + 1;
74 if (!(n->dat = (char *)malloc(n->bufsize))) {
75 free(n);
76 mastr_oom();
77 /*@notreached@*/ return NULL;
78 }
79 n->dat[0] = '\0';
80 n->len = 0;
81 return n;
82 }
83
84
85 mastr *
86 mastr_newstr(const char *s)
87 {
88 size_t l;
89 mastr *n;
90
91 if (!s)
92 return NULL;
93 n = mastr_new((l = strlen(s)));
94 if (!n)
95 return NULL;
96 memcpy(n->dat, s, l + 1);
97 n->len = l;
98 return n;
99 }
100
101 int
102 mastr_cpy(mastr * m, const char *s)
103 {
104 size_t l;
105
106 if (!m || !s)
107 return 0;
108
109 if ((l = strlen(s)) >= m->bufsize)
110 if (0 == mastr_resizekill(m, l)) {
111 mastr_oom();
112 /*@notreached@*/ return 0;
113 }
114 memcpy(m->dat, s, l + 1);
115 m->len = l;
116 return 1;
117 }
118
119 int
120 mastr_cat(mastr * m, /*@unique@*/ /*@observer@*/ const char *const s)
121 {
122 size_t li;
123
124 if (!m || !s)
125 return 0;
126
127 if ((li = strlen(s)) + m->len >= m->bufsize)
128 if (0 == mastr_resizekeep(m, li + m->len)) {
129 mastr_oom();
130 /*@notreached@*/ return 0;
131 }
132 memcpy(m->dat + m->len, s, li + 1);
133 m->len += li;
134 return 1;
135 }
136
137 void
138 mastr_clear(mastr * m)
139 {
140 if (!m)
141 return;
142 m->len = 0;
143 m->dat[0] = '\0';
144 }
145
146 int
147 mastr_vcat(mastr * m, ...)
148 {
149 long addlen = 0;
150 const char *t;
151 char *u;
152 va_list v;
153
154 if (!m)
155 return 0;
156
157 /* get length */
158 va_start(v, m);
159 while ((t = va_arg(v, const char *))) {
160 addlen += strlen(t);
161 }
162 va_end(v);
163
164 if (m->len + addlen >= m->bufsize) {
165 if (!mastr_resizekeep(m, addlen + m->len)) {
166 mastr_oom();
167 /*@notreached@*/ return 0;
168 }
169 }
170 va_start(v, m);
171 u = m->dat + m->len;
172 while ((t = va_arg(v, const char *))) {
173 while ((*u = *t++))
174 u++;
175 }
176 m->len += addlen;
177 va_end(v);
178 return 1;
179 }
180
181 int
182 mastr_resizekill(mastr * m, size_t l)
183 {
184 char *n;
185
186 if (!m)
187 return 0;
188 n = (char *)malloc(l + 1);
189 if (!n) {
190 mastr_oom();
191 /*@notreached@*/ return 0;
192 }
193 free(m->dat);
194 m->dat = n;
195 m->bufsize = l + 1;
196 m->dat[0] = '\0';
197 m->len = 0;
198 return 1;
199 }
200
201 int
202 mastr_resizekeep(mastr * m, size_t l)
203 {
204 char *n;
205
206 if (!m)
207 return 0;
208 n = (char *)realloc(m->dat, l + 1);
209 if (!n) {
210 free(m->dat);
211 mastr_oom();
212 /*@notreached@*/ return 0;
213 }
214 m->dat = n;
215 m->bufsize = l + 1;
216 m->dat[l] = '\0';
217 if (l < m->len)
218 m->len = l;
219 return 1;
220 }
221
222 void
223 mastr_delete(/*@only@*/ mastr * m)
224 {
225 if (m) {
226 free(m->dat);
227 free(m);
228 }
229 }
230
231 void
232 mastr_triml(mastr * m)
233 {
234 char *p, *q;
235 if (!m)
236 return;
237 p = q = m->dat;
238 while (*p && isspace((unsigned char)*p))
239 p++;
240 if (p != q) {
241 /*@-whileempty@*/
242 while ((*q++ = *p++));
243 /*@=whileempty@*/
244 m->len -= p - q;
245 }
246 }
247
248 void
249 mastr_trimr(mastr * m)
250 {
251 char *p;
252 if (!m)
253 return;
254 p = m->dat + m->len;
255 /*@-whileempty@*/
256 while (--p >= m->dat && isspace((unsigned char)*p));
257 /*@=whileempty@*/
258 *++p = '\0';
259 m->len = (size_t)(p - m->dat);
260 }
261
262 #if LEAFNODE_VERSION > 1
263 ssize_t
264 mastr_getln(mastr * m, FILE * f,
265 ssize_t maxbytes /** if negative: unlimited */ )
266 {
267 /* FIXME: make this overflow safe, size_t vs. ssize_t. */
268 char buf[4096];
269 ssize_t bufsiz = (ssize_t)sizeof buf;
270 ssize_t r;
271
272 mastr_clear(m);
273
274 for (;;) {
275 r = _getline(buf,
276 (size_t)(maxbytes > 0 ? min(bufsiz, maxbytes+1) : bufsiz),
277 f);
278 if (r < 0)
279 return r;
280 if (r == 0)
281 break;
282 if (r + m->len >= m->bufsize)
283 if (!mastr_resizekeep(m, r + m->len)) {
284 mastr_oom();
285 /*@notreached@*/ return 0;
286 }
287 memcpy(m->dat + m->len, buf, (size_t)r); /* FIXME: avoid this copy */
288 if (maxbytes > 0)
289 maxbytes -= r;
290 m->len += r;
291 m->dat[m->len] = '\0';
292 if (memchr(buf, '\n', (size_t)r) != NULL)
293 break;
294 }
295 return (ssize_t)(m->len);
296 }
297 #endif
298
299 /* chop off last character of string */
300 static void
301 choplast(mastr * m)
302 {
303 if (m && m->len) {
304 --m->len;
305 m->dat[m->len] = '\0';
306 }
307 }
308
309 /** chop off trailing LF or CRLF */
310 void
311 mastr_chop(mastr * m)
312 {
313 if (m && m->len && m->dat[m->len - 1] == '\n')
314 choplast(m);
315 if (m && m->len && m->dat[m->len - 1] == '\r')
316 choplast(m);
317 }
318
319 /** return size of buffer */
320 size_t
321 mastr_size(mastr * m)
322 {
323 return m->bufsize - 1;
324 }
325
326 /** return length of buffer */
327 size_t
328 mastr_len(mastr * m)
329 {
330 return m->len;
331 }